diff --git a/Engine/Build/Android/Java/src/com/epicgames/ue4/GameActivity.java.template b/Engine/Build/Android/Java/src/com/epicgames/ue4/GameActivity.java.template index 428284fd9de7..b0e0feab4840 100644 --- a/Engine/Build/Android/Java/src/com/epicgames/ue4/GameActivity.java.template +++ b/Engine/Build/Android/Java/src/com/epicgames/ue4/GameActivity.java.template @@ -174,6 +174,8 @@ import com.epicgames.ue4.GooglePlayLicensing; // Console commands listener, only for debug builds import com.epicgames.ue4.ConsoleCmdReceiver; +import com.epicgames.ue4.MultiChannelMediaEncoder; + import android.os.Build; // TODO: use the resources from the UE4 lib project once we've got the packager up and running @@ -213,7 +215,7 @@ import android.content.BroadcastReceiver; // Java libraries at the startup of the program and store references // to them in this class. -public class GameActivity extends NativeActivity implements SurfaceHolder.Callback2, +public class GameActivity extends $${gameActivitySuperClass}$$ implements SurfaceHolder.Callback2, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, SensorEventListener, @@ -456,8 +458,6 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba private String localNotificationLaunchActivationEvent = ""; private int localNotificationLaunchFireDate = 0; - public int DeviceRotation = -1; - enum EAlertDialogType { None, @@ -518,14 +518,6 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba Configuration config = getResources().getConfiguration(); int rotation = windowManager.getDefaultDisplay().getRotation(); - switch (rotation) - { - case Surface.ROTATION_0: DeviceRotation = 0; break; - case Surface.ROTATION_90: DeviceRotation = 90; break; - case Surface.ROTATION_180: DeviceRotation = 180; break; - case Surface.ROTATION_270: DeviceRotation = 270; break; - } - if ( ((rotation == android.view.Surface.ROTATION_0 || rotation == android.view.Surface.ROTATION_180) && config.orientation == Configuration.ORIENTATION_LANDSCAPE) || ((rotation == android.view.Surface.ROTATION_90 || rotation == android.view.Surface.ROTATION_270) && @@ -539,6 +531,23 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba } } + public int getCurrentDeviceRotationDegree() + { + // onConfigurationChanged won't be called if orientation changes from landscape/portrait to reverse landscape/portrait + // use this function instead of caching DeviceRotation + int orientation = AndroidThunkJava_GetDeviceOrientation(); + + switch (orientation) + { + case Surface.ROTATION_0: return 0; + case Surface.ROTATION_90: return 90; + case Surface.ROTATION_180: return 180; + case Surface.ROTATION_270: return 270; + } + + return 0; + } + private int getResourceId(String VariableName, String ResourceName, String PackageName) { try { @@ -703,7 +712,7 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba } } - private byte[] getByteArrayFromFile(String filename) + public static byte[] getByteArrayFromFile(String filename) { try { @@ -1935,6 +1944,16 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba //$${gameActivityLoggerCallbackAdditions}$$ } + protected View GetMainView() + { + return mainView; + } + + protected FrameLayout GetContainerFrameLayout() + { + return containerFrameLayout; + } + @Override public void onCreate(Bundle savedInstanceState) { @@ -1951,9 +1970,9 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba _extrasBundle = getIntent().getExtras(); if (_extrasBundle != null) { - ShouldHideUI = _extrasBundle.getString("ShouldHideUI") != null; - UseDisplayCutout = _extrasBundle.getString("UseDisplayCutout") != null; - if (_extrasBundle.getString("UseSplashScreen") != null) + ShouldHideUI = _extrasBundle.getBoolean("ShouldHideUI", false); + UseDisplayCutout = _extrasBundle.getBoolean("UseDisplayCutout", false); + if (_extrasBundle.getBoolean("UseSplashScreen", false)) { SplashScreenLaunch = true; try { @@ -3264,14 +3283,6 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba { super.onConfigurationChanged(newConfig); - switch (getWindowManager().getDefaultDisplay().getRotation()) - { - case Surface.ROTATION_0: DeviceRotation = 0; break; - case Surface.ROTATION_90: DeviceRotation = 90; break; - case Surface.ROTATION_180: DeviceRotation = 180; break; - case Surface.ROTATION_270: DeviceRotation = 270; break; - } - // forward the orientation boolean bPortrait = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT; nativeOnConfigurationChanged(bPortrait); @@ -4343,9 +4354,9 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba } } - private int LocalNotificationGetID() + public static int LocalNotificationGetID(Context context) { - SharedPreferences preferences = getApplicationContext().getSharedPreferences("LocalNotificationPreferences", MODE_PRIVATE); + SharedPreferences preferences = context.getSharedPreferences("LocalNotificationPreferences", MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); String notificationIDs = preferences.getString("notificationIDs", ""); @@ -4446,7 +4457,7 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba public void AndroidThunkJava_LocalNotificationScheduleAtTime(String targetDateTime, boolean localTime, String title, String body, String action, String activationEvent) { - int notificationID = LocalNotificationGetID(); + int notificationID = LocalNotificationGetID(this); // Create callback for PendingIntent Intent notificationIntent = new Intent(this, LocalNotificationReceiver.class); @@ -5301,6 +5312,11 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba } + protected List GetExtraIgnoreViews() + { + return null; + } + //check if the new virtual keyboard input has received a MOUSE_DOWN event // or the keyboard animation is playing public boolean AndroidThunkJava_VirtualInputIgnoreClick(int x, int y) @@ -5316,6 +5332,24 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba return true; } } + else + { + List ExtraIgnoreViews = GetExtraIgnoreViews(); + if (ExtraIgnoreViews != null) + { + for (int i = 0; i < ExtraIgnoreViews.size(); i++) + { + Rect r = new Rect(); + ExtraIgnoreViews.get(i).getGlobalVisibleRect(r); + if (r.contains(x, y)) + { + //Log.debug("Webview: AndroidThunkJava_VirtualInputIgnoreClick true"); + return true; + } + } + } + } + //Log.debug("VK: AndroidThunkJava_VirtualInputIgnoreClick false"); return false; } @@ -5447,7 +5481,7 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba return true; } - public void AndroidThunkJava_RestartApplication() + public void AndroidThunkJava_RestartApplication(String RestartExtra) { Context context = getApplicationContext(); @@ -5457,6 +5491,7 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba // make an "restart intent", to be used to re-launch an application's task in its base state intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + intent.putExtra("RestartExtra", RestartExtra); context.startActivity(intent); // kill the current application instance. Undefined behaviour after this! @@ -5479,6 +5514,11 @@ public class GameActivity extends NativeActivity implements SurfaceHolder.Callba return ""; } + public int AndroidThunkJava_GetDeviceOrientation() + { + return getWindowManager().getDefaultDisplay().getRotation(); + } + @SuppressWarnings("deprecation") public boolean AndroidThunkJava_CookieManager_SetCookie(String Url, String Value) { diff --git a/Engine/Build/Android/Java/src/com/epicgames/ue4/LocalNotificationReceiver.java b/Engine/Build/Android/Java/src/com/epicgames/ue4/LocalNotificationReceiver.java index 499b203d8ec1..cfa3a153d461 100644 --- a/Engine/Build/Android/Java/src/com/epicgames/ue4/LocalNotificationReceiver.java +++ b/Engine/Build/Android/Java/src/com/epicgames/ue4/LocalNotificationReceiver.java @@ -1,29 +1,34 @@ // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. - package com.epicgames.ue4; - - import android.app.Notification; - import android.app.NotificationManager; - import android.app.NotificationChannel; - import android.app.PendingIntent; - import android.content.BroadcastReceiver; - import android.content.Context; - import android.content.Intent; - import android.support.v4.app.NotificationCompat; - - public class LocalNotificationReceiver extends BroadcastReceiver - { - private static boolean bChannelExists = false; - private static final String NOTIFICATION_CHANNEL_ID = "ue4-push-notification-channel-id"; - private static final CharSequence NOTICATION_CHANNEL_NAME = "ue4-push-notification-channel"; - - public void onReceive(Context context, Intent intent) - { - int notificationID = intent.getIntExtra("local-notification-ID" , 0); - String title = intent.getStringExtra("local-notification-title"); - String details = intent.getStringExtra("local-notification-body"); - String action = intent.getStringExtra("local-notification-action"); - String activationEvent = intent.getStringExtra("local-notification-activationEvent"); +package com.epicgames.ue4; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.NotificationChannel; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.support.v4.app.NotificationCompat; + +public class LocalNotificationReceiver extends BroadcastReceiver +{ + private static final String NOTIFICATION_CHANNEL_ID = "ue4-push-notification-channel-id"; + private static final CharSequence NOTICATION_CHANNEL_NAME = "ue4-push-notification-channel"; + + public static final String KEY_LOCAL_NOTIFICATION_ID = "local-notification-ID"; + public static final String KEY_LOCAL_NOTIFICATION_TITLE = "local-notification-title"; + public static final String KEY_LOCAL_NOTIFICATION_BODY = "local-notification-body"; + public static final String KEY_LOCAL_NOTIFICATION_ACTION = "local-notification-action"; + public static final String KEY_LOCAL_NOTIFICATION_ACTION_EVENT = "local-notification-activationEvent"; + + public void onReceive(Context context, Intent intent) + { + int notificationID = intent.getIntExtra(KEY_LOCAL_NOTIFICATION_ID , 0); + String title = intent.getStringExtra(KEY_LOCAL_NOTIFICATION_TITLE); + String details = intent.getStringExtra(KEY_LOCAL_NOTIFICATION_BODY); + String action = intent.getStringExtra(KEY_LOCAL_NOTIFICATION_ACTION); + String activationEvent = intent.getStringExtra(KEY_LOCAL_NOTIFICATION_ACTION_EVENT); if(title == null || details == null || action == null || activationEvent == null) { @@ -40,14 +45,11 @@ notificationIntent.putExtra("localNotificationAppLaunched" , true); notificationIntent.putExtra("localNotificationLaunchActivationEvent", activationEvent); - int notificationIconID = context.getResources().getIdentifier("ic_notification", "drawable", context.getPackageName()); - if (notificationIconID == 0) - { - notificationIconID = context.getResources().getIdentifier("icon", "drawable", context.getPackageName()); - } + int notificationIconID = getNotificationIconID(context); PendingIntent pendingNotificationIntent = PendingIntent.getActivity(context, notificationID, notificationIntent, 0); NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + @SuppressWarnings("deprecation") NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) .setSmallIcon(notificationIconID) .setContentIntent(pendingNotificationIntent) @@ -62,13 +64,16 @@ if (android.os.Build.VERSION.SDK_INT >= 26) { - if (!bChannelExists) + if(notificationManager != null) { - NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); - channel.enableVibration(true); - channel.enableLights(true); - notificationManager.createNotificationChannel(channel); - bChannelExists = true; + NotificationChannel channel = notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID); + if (channel == null) + { + channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); + channel.enableVibration(true); + channel.enableLights(true); + notificationManager.createNotificationChannel(channel); + } } } Notification notification = builder.build(); @@ -77,8 +82,20 @@ notification.flags |= Notification.FLAG_AUTO_CANCEL; notification.defaults |= Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE; - // show the notification - notificationManager.notify(notificationID, notification); - } - } - \ No newline at end of file + if(notificationManager != null) + { + // show the notification + notificationManager.notify(notificationID, notification); + } + } + + public static int getNotificationIconID(Context context) + { + int notificationIconID = context.getResources().getIdentifier("ic_notification", "drawable", context.getPackageName()); + if (notificationIconID == 0) + { + notificationIconID = context.getResources().getIdentifier("icon", "drawable", context.getPackageName()); + } + return notificationIconID; + } +} diff --git a/Engine/Build/Android/Java/src/com/epicgames/ue4/Logger.java b/Engine/Build/Android/Java/src/com/epicgames/ue4/Logger.java index 7520d123a433..cbbbaa3270e5 100644 --- a/Engine/Build/Android/Java/src/com/epicgames/ue4/Logger.java +++ b/Engine/Build/Android/Java/src/com/epicgames/ue4/Logger.java @@ -13,13 +13,16 @@ public class Logger private String mTag; private static boolean bAllowLogging = true; + @SuppressWarnings({"FieldCanBeLocal", "unused"}) private static boolean bAllowExceptionLogging = true; + @SuppressWarnings("unused") public static void RegisterCallback(ILoggerCallback callback) { mCallback = callback; } + @SuppressWarnings("WeakerAccess") public static void SuppressLogs () { bAllowLogging = bAllowExceptionLogging = false; @@ -29,7 +32,19 @@ public class Logger { mTag = Tag; } - + + public void verbose(String Message) + { + if (bAllowLogging) + { + Log.v(mTag, Message); + } + if (mCallback != null) + { + mCallback.LoggerCallback("V/", mTag, Message); + } + } + public void debug(String Message) { if (bAllowLogging) @@ -65,4 +80,16 @@ public class Logger mCallback.LoggerCallback("E/", mTag, Message); } } + + public void error(String Message, Throwable Throwable) + { + if (bAllowLogging) + { + Log.e(mTag, Message, Throwable); + } + if (mCallback != null) + { + mCallback.LoggerCallback("E/", mTag, Message); + } + } } \ No newline at end of file diff --git a/Engine/Build/Android/Java/src/com/epicgames/ue4/NativeCalls.java b/Engine/Build/Android/Java/src/com/epicgames/ue4/NativeCalls.java new file mode 100644 index 000000000000..5a29e02a3244 --- /dev/null +++ b/Engine/Build/Android/Java/src/com/epicgames/ue4/NativeCalls.java @@ -0,0 +1,25 @@ +package com.epicgames.ue4; + +public class NativeCalls +{ + @SuppressWarnings("JniMissingFunction") + public static native void HandleCustomTouchEvent(int deviceId, int pointerId, int action, int source, float x, float y); + + @SuppressWarnings("JniMissingFunction") + public static native void CallNativeToEmbedded(String ID, int Priority, String Subsystem, String Command, String[] Params, String RoutingFunction); + + @SuppressWarnings("JniMissingFunction") + public static native void SetNamedObject(String Name, Object Obj); + + @SuppressWarnings("JniMissingFunction") + public static native void KeepAwake(String Requester, boolean bIsForRendering); + + @SuppressWarnings("JniMissingFunction") + public static native void AllowSleep(String Requester); + + @SuppressWarnings("JniMissingFunction") + public static native void WebViewVisible(boolean bShown); + + @SuppressWarnings("JniMissingFunction") + public static native void ForwardNotification(String payload); +} \ No newline at end of file diff --git a/Engine/Build/Android/Java/src/com/epicgames/ue4/SplashActivity.java b/Engine/Build/Android/Java/src/com/epicgames/ue4/SplashActivity.java index 3a0df9b35105..6ed4dfa33c39 100644 --- a/Engine/Build/Android/Java/src/com/epicgames/ue4/SplashActivity.java +++ b/Engine/Build/Android/Java/src/com/epicgames/ue4/SplashActivity.java @@ -2,6 +2,7 @@ package com.epicgames.ue4; +import android.annotation.SuppressLint; import android.os.Bundle; import android.app.Activity; import android.content.Intent; @@ -13,6 +14,9 @@ import android.view.WindowManager; public class SplashActivity extends Activity { + public static Logger Log = new Logger("UE4-SplashActivity"); + + @SuppressLint("ObsoleteSdkInt") @Override protected void onCreate(Bundle savedInstanceState) { @@ -33,11 +37,9 @@ public class SplashActivity extends Activity UseDisplayCutout = bundle.getBoolean("com.epicgames.ue4.GameActivity.bUseDisplayCutout"); } } - catch (NameNotFoundException e) - { - } - catch (NullPointerException e) + catch (NameNotFoundException | NullPointerException e) { + Log.error("Error when accessing application metadata", e); } if (ShouldHideUI) @@ -78,10 +80,10 @@ public class SplashActivity extends Activity Intent intent = new Intent(this, GameActivity.class); intent.putExtras(getIntent()); intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); - intent.putExtra("UseSplashScreen", "true"); + intent.putExtra("UseSplashScreen", true); if (ShouldHideUI) { - intent.putExtra("ShouldHideUI", "true"); + intent.putExtra("ShouldHideUI", true); } if (UseDisplayCutout) { diff --git a/Engine/Build/Android/Java/src/com/epicgames/ue4/WebViewControl.java b/Engine/Build/Android/Java/src/com/epicgames/ue4/WebViewControl.java index a961be23daa4..97b2493fc913 100644 --- a/Engine/Build/Android/Java/src/com/epicgames/ue4/WebViewControl.java +++ b/Engine/Build/Android/Java/src/com/epicgames/ue4/WebViewControl.java @@ -7,6 +7,7 @@ import android.content.Context; import android.view.View; import android.view.ViewGroup; +import android.webkit.ConsoleMessage; import android.webkit.WebView; import android.webkit.WebViewClient; import android.webkit.WebChromeClient; @@ -1681,6 +1682,14 @@ class WebViewControl resultMsg.sendToTarget(); return true; } + + @Override + public boolean onConsoleMessage(ConsoleMessage cm) { + GameActivity.Log.warn(cm.message() + " -- From line " + + cm.lineNumber() + " of " + + cm.sourceId() ); + return true; + } } public long GetNativePtr() { diff --git a/Engine/Build/Android/Java/src/com/google/android/vending/expansion/downloader/Helpers.java b/Engine/Build/Android/Java/src/com/google/android/vending/expansion/downloader/Helpers.java index 5a7e3dee0168..3e7383015592 100644 --- a/Engine/Build/Android/Java/src/com/google/android/vending/expansion/downloader/Helpers.java +++ b/Engine/Build/Android/Java/src/com/google/android/vending/expansion/downloader/Helpers.java @@ -227,7 +227,8 @@ public class Helpers { static public boolean doesFileExistInternal(Context c, File fileForNewFile, long fileSize, boolean deleteFileOnMismatch) { if (fileForNewFile.exists()) { - if (fileForNewFile.length() == fileSize) { + // ignore actual file size if requested filesize is 0 (special case allow any) + if ((fileSize==0) || (fileForNewFile.length() == fileSize)) { return true; } if (deleteFileOnMismatch) { diff --git a/Engine/Build/Commit.gitdeps.xml b/Engine/Build/Commit.gitdeps.xml index a24a3cb285df..e457a5440c2d 100644 --- a/Engine/Build/Commit.gitdeps.xml +++ b/Engine/Build/Commit.gitdeps.xml @@ -10,7 +10,7 @@ - + @@ -5913,12 +5913,12 @@ - - - - - - + + + + + + @@ -5943,9 +5943,9 @@ - + - + @@ -5986,7 +5986,7 @@ - + @@ -31320,6 +31320,7 @@ + @@ -33738,6 +33739,7 @@ + @@ -40028,13 +40030,13 @@ - - - - - - - + + + + + + + @@ -43126,6 +43128,7 @@ + @@ -43307,6 +43310,7 @@ + @@ -43324,6 +43328,7 @@ + @@ -44184,7 +44189,6 @@ - @@ -44708,11 +44712,10 @@ - - + @@ -44929,6 +44932,7 @@ + @@ -46155,6 +46159,7 @@ + @@ -47077,6 +47082,7 @@ + @@ -47995,7 +48001,6 @@ - @@ -48318,6 +48323,7 @@ + @@ -48466,7 +48472,7 @@ - + @@ -49979,7 +49985,6 @@ - @@ -50635,7 +50640,7 @@ - + @@ -50667,6 +50672,7 @@ + @@ -53181,7 +53187,7 @@ - + @@ -54638,6 +54644,7 @@ + @@ -55452,7 +55459,6 @@ - @@ -55639,7 +55645,7 @@ - + @@ -55698,7 +55704,6 @@ - @@ -55990,7 +55995,6 @@ - @@ -56343,7 +56347,6 @@ - @@ -56646,6 +56649,7 @@ + @@ -56725,6 +56729,7 @@ + @@ -57694,7 +57699,6 @@ - @@ -58510,6 +58514,7 @@ + @@ -58574,7 +58579,6 @@ - @@ -58905,7 +58909,7 @@ - + @@ -59231,7 +59235,7 @@ - + @@ -59819,7 +59823,6 @@ - @@ -60483,7 +60486,6 @@ - @@ -61316,6 +61318,7 @@ + @@ -61578,6 +61581,7 @@ + @@ -62366,7 +62370,6 @@ - @@ -63250,6 +63253,7 @@ + @@ -63625,6 +63629,7 @@ + @@ -64047,7 +64052,7 @@ - + @@ -64317,7 +64322,7 @@ - + @@ -65813,7 +65818,7 @@ - + @@ -65967,7 +65972,6 @@ - @@ -66130,7 +66134,7 @@ - + @@ -67841,7 +67845,6 @@ - @@ -68398,7 +68401,6 @@ - @@ -68680,7 +68682,6 @@ - @@ -68917,6 +68918,7 @@ + @@ -69069,6 +69071,7 @@ + @@ -69293,7 +69296,6 @@ - @@ -69865,7 +69867,6 @@ - @@ -69935,6 +69936,7 @@ + @@ -70463,6 +70465,7 @@ + @@ -70470,7 +70473,6 @@ - @@ -70483,7 +70485,6 @@ - @@ -70569,6 +70570,7 @@ + @@ -70615,6 +70617,7 @@ + @@ -71170,6 +71173,7 @@ + @@ -71374,7 +71378,6 @@ - @@ -71426,7 +71429,6 @@ - @@ -71519,6 +71521,7 @@ + @@ -71551,7 +71554,6 @@ - @@ -71695,12 +71697,12 @@ + - @@ -71834,6 +71836,7 @@ + @@ -72020,7 +72023,6 @@ - @@ -72119,6 +72121,7 @@ + @@ -72205,6 +72208,7 @@ + @@ -72261,7 +72265,6 @@ - @@ -72288,6 +72291,7 @@ + diff --git a/Engine/Build/InstalledEngineBuild.xml b/Engine/Build/InstalledEngineBuild.xml index 9dc7fdccbda8..bec84598231f 100644 --- a/Engine/Build/InstalledEngineBuild.xml +++ b/Engine/Build/InstalledEngineBuild.xml @@ -477,6 +477,7 @@ + diff --git a/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/AnimNode_LiveLinkArchiveComponentPose.cpp b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/AnimNode_LiveLinkArchiveComponentPose.cpp new file mode 100644 index 000000000000..6a7db7336221 --- /dev/null +++ b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/AnimNode_LiveLinkArchiveComponentPose.cpp @@ -0,0 +1,81 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "AnimNode_LiveLinkArchiveComponentPose.h" + +#include "AnimationRuntime.h" +#include "Animation/AnimInstanceProxy.h" + +#include "LiveLinkRemapAsset.h" + +FAnimNode_LiveLinkArchiveComponentPose::FAnimNode_LiveLinkArchiveComponentPose() + : RetargetAsset(ULiveLinkRemapAsset::StaticClass()) + , CurrentRetargetAsset(nullptr) + , CurrentLiveLinkArchiveComponent(nullptr) +{ +} + +void FAnimNode_LiveLinkArchiveComponentPose::Initialize_AnyThread(const FAnimationInitializeContext& Context) +{ + CurrentRetargetAsset = nullptr; +} + +void FAnimNode_LiveLinkArchiveComponentPose::PreUpdate(const UAnimInstance* InAnimInstance) +{ + if (!CurrentLiveLinkArchiveComponent) + { + AActor* Actor = InAnimInstance->GetOwningActor(); + if (Actor) + { + const TSet& ActorOwnedComponents = Actor->GetComponents(); + for (UActorComponent* OwnedComponent : ActorOwnedComponents) + { + ULiveLinkArchiveComponent* PotentialArchiveComponent = Cast(OwnedComponent); + if (PotentialArchiveComponent && (PotentialArchiveComponent->ArchiveName.IsEqual(ArchiveNameBinding))) + { + CurrentLiveLinkArchiveComponent = PotentialArchiveComponent; + } + } + } + } +} + +void FAnimNode_LiveLinkArchiveComponentPose::Update_AnyThread(const FAnimationUpdateContext & Context) +{ + GetEvaluateGraphExposedInputs().Execute(Context); + + // Accumulate Delta time from update + CachedDeltaTime += Context.GetDeltaTime(); + + // Protection as a class graph pin does not honour rules on abstract classes and NoClear + if (!RetargetAsset.Get() || RetargetAsset.Get()->HasAnyClassFlags(CLASS_Abstract)) + { + RetargetAsset = ULiveLinkRemapAsset::StaticClass(); + } + + if (!CurrentRetargetAsset || RetargetAsset != CurrentRetargetAsset->GetClass()) + { + CurrentRetargetAsset = NewObject(Context.AnimInstanceProxy->GetAnimInstanceObject(), *RetargetAsset); + CurrentRetargetAsset->Initialize(); + } +} + +void FAnimNode_LiveLinkArchiveComponentPose::Evaluate_AnyThread(FPoseContext& Output) +{ + Output.ResetToRefPose(); + + if (!CurrentRetargetAsset || !CurrentLiveLinkArchiveComponent) + { + return; + } + + const double WorldTime = FPlatformTime::Seconds(); + bool bDidFindArchivedFrame; + FLiveLinkSubjectFrame FoundArchiveFrameCache; + + CurrentLiveLinkArchiveComponent->GetSubjectDataAtWorldTime(WorldTime, bDidFindArchivedFrame, FoundArchiveFrameCache); + if(bDidFindArchivedFrame) + { + CurrentRetargetAsset->BuildPoseForSubject(CachedDeltaTime, FoundArchiveFrameCache, Output.Pose, Output.Curve); + CachedDeltaTime = 0.f; // Reset so that if we evaluate again we don't "create" time inside of the retargeter + } +} \ No newline at end of file diff --git a/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/AnimNode_LiveLinkPose.cpp b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/AnimNode_LiveLinkPose.cpp index 719ab8a1618e..753c2af4b5ca 100644 --- a/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/AnimNode_LiveLinkPose.cpp +++ b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/AnimNode_LiveLinkPose.cpp @@ -26,10 +26,14 @@ void FAnimNode_LiveLinkPose::Initialize_AnyThread(const FAnimationInitializeCont } CurrentRetargetAsset = nullptr; + + InputPose.Initialize(Context); } void FAnimNode_LiveLinkPose::Update_AnyThread(const FAnimationUpdateContext & Context) { + InputPose.Update(Context); + GetEvaluateGraphExposedInputs().Execute(Context); // Accumulate Delta time from update @@ -50,7 +54,7 @@ void FAnimNode_LiveLinkPose::Update_AnyThread(const FAnimationUpdateContext & Co void FAnimNode_LiveLinkPose::Evaluate_AnyThread(FPoseContext& Output) { - Output.ResetToRefPose(); + InputPose.Evaluate(Output); if (!LiveLinkClient || !CurrentRetargetAsset) { @@ -80,3 +84,17 @@ void FAnimNode_LiveLinkPose::OnLiveLinkClientUnregistered(const FName& Type, cla LiveLinkClient = nullptr; } } + +void FAnimNode_LiveLinkPose::CacheBones_AnyThread(const FAnimationCacheBonesContext & Context) +{ + Super::CacheBones_AnyThread(Context); + InputPose.CacheBones(Context); +} + +void FAnimNode_LiveLinkPose::GatherDebugData(FNodeDebugData& DebugData) +{ + FString DebugLine = FString::Printf(TEXT("LiveLink - SubjectName: %s"), *SubjectName.ToString()); + + DebugData.AddDebugItem(DebugLine); + InputPose.GatherDebugData(DebugData); +} \ No newline at end of file diff --git a/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/LiveLinkArchiveComponent.cpp b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/LiveLinkArchiveComponent.cpp new file mode 100644 index 000000000000..0827b540ab06 --- /dev/null +++ b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/LiveLinkArchiveComponent.cpp @@ -0,0 +1,190 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "LiveLinkArchiveComponent.h" +#include "Features/IModularFeatures.h" +#include "GameFramework/Actor.h" + +DEFINE_LOG_CATEGORY(LogLiveLinkArchiveComponent); + + +// Sets default values for this component's properties +ULiveLinkArchiveComponent::ULiveLinkArchiveComponent() + : CaptureRate(60.0f) + , ArchiveName(TEXT("LiveLinkArchive")) + , bInterpolatePlayback(true) + , WorldTimeAtArchivePlayStart(0.0f) +{ + PrimaryComponentTick.bCanEverTick = true; + PrimaryComponentTick.bStartWithTickEnabled = true; + PrimaryComponentTick.TickGroup = ETickingGroup::TG_PrePhysics; + bTickInEditor = true; +} + +void ULiveLinkArchiveComponent::OnRegister() +{ + bIsArchivePlaying = false; + bIsArchivingFrames = false; + Super::OnRegister(); +} + + +// Called every frame +void ULiveLinkArchiveComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) +{ + if (bIsArchivingFrames) + { + CaptureRateTimer -= DeltaTime; + if (CaptureRateTimer <= 0.0f) + { + if (HasLiveLinkClient()) + { + const double CurrentTime = FPlatformTime::Seconds(); + const FLiveLinkSubjectFrame* FoundFrame = LiveLinkClient->GetSubjectDataAtWorldTime(LiveLinkSubjectToArchive, CurrentTime); + + if (FoundFrame) + { + //If we were the first frame, need to save off WorldTimeAtCaptureStart + double TimeSinceCaptureStart = 0; + if (ArchivedFrames.Num() == 0) + { + WorldTimeAtCaptureStart = CurrentTime; + UE_LOG(LogLiveLinkArchiveComponent, Verbose, TEXT("Setting WorldTimeAtCaptureStart: %f"), WorldTimeAtCaptureStart); + } + else + { + TimeSinceCaptureStart = (CurrentTime - WorldTimeAtCaptureStart); + } + + FLiveLinkArchiveFrame NewArchiveFrame(*FoundFrame, TimeSinceCaptureStart); + ArchivedFrames.Add(NewArchiveFrame); + + UE_LOG(LogLiveLinkArchiveComponent, Verbose, TEXT("Adding Frame at index:%d time:%f"), (ArchivedFrames.Num() -1 ), TimeSinceCaptureStart); + } + } + + //Reset capture rate timer + CaptureRateTimer = (1 / CaptureRate); + } + } + + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); +} + +bool ULiveLinkArchiveComponent::HasLiveLinkClient() +{ + if (LiveLinkClient == nullptr) + { + IModularFeatures& ModularFeatures = IModularFeatures::Get(); + if (ModularFeatures.IsModularFeatureAvailable(ILiveLinkClient::ModularFeatureName)) + { + LiveLinkClient = &ModularFeatures.GetModularFeature(ILiveLinkClient::ModularFeatureName); + } + } + + return (LiveLinkClient != nullptr); +} + +void ULiveLinkArchiveComponent::BeginLiveLinkCapture() +{ + ArchivedFrames.Reset(); + bIsArchivingFrames = true; + + //Capture first ticked frame immediately + CaptureRateTimer = 0.0f; + + UE_LOG(LogLiveLinkArchiveComponent, Log, TEXT("Started LiveLinkArchive Capture")); +} + +void ULiveLinkArchiveComponent::StopLiveLinkCapture() +{ + bIsArchivingFrames = false; + + UE_LOG(LogLiveLinkArchiveComponent, Log, TEXT("Stopped LiveLinkArchive Capture")); +} + + +void ULiveLinkArchiveComponent::GetSubjectDataAtWorldTime(const double WorldTimeIn, bool& bSuccess, FLiveLinkSubjectFrame& SubjectFrameHandle) +{ + bSuccess = false; + + //Need to adjust world time so we are looking for + const double AdjustedWorldTime = WorldTimeIn - WorldTimeAtArchivePlayStart; + UE_LOG(LogLiveLinkArchiveComponent, VeryVerbose, TEXT("Adjusting WorldTime. In:%f StartTime:%f Adjusted Time: %f"), WorldTimeIn, WorldTimeAtArchivePlayStart, AdjustedWorldTime); + + if (bIsArchivePlaying && (ArchivedFrames.Num() > 0)) + { + int StartingFrame = FindIndexOfStartingFrame(AdjustedWorldTime); + if (ArchivedFrames.IsValidIndex(StartingFrame)) + { + bSuccess = true; + + //If we aren't interpolating, or we don't have a future frame to interpolate with because we are the most recent frame, just return found frame + if (!bInterpolatePlayback || (StartingFrame == (ArchivedFrames.Num() - 1))) + { + SubjectFrameHandle = ArchivedFrames[StartingFrame].ArchivedFrame; + } + else + { + const FLiveLinkArchiveFrame& PreFrame = ArchivedFrames[StartingFrame]; + const FLiveLinkArchiveFrame& PostFrame = ArchivedFrames[StartingFrame + 1]; + FLiveLinkSubjectFrame OutFrame; + + //Grab all these. They should be the same for Pre and Post frame, so just grab Post Frame + OutFrame.RefSkeleton = PostFrame.ArchivedFrame.RefSkeleton; + OutFrame.RefSkeletonGuid = PostFrame.ArchivedFrame.RefSkeletonGuid; + OutFrame.CurveKeyData = PostFrame.ArchivedFrame.CurveKeyData; + + // Calc blend weight (Amount through frame gap / frame gap). Protected in case we have 2 frames captured at 0.00f + const float BlendWeight = (PostFrame.FrameTime > 0) ? (PreFrame.FrameTime) / (PostFrame.FrameTime) : 1.0f; + + CopyFrameDataBlended(PreFrame.ArchivedFrame, PostFrame.ArchivedFrame, BlendWeight, OutFrame); + SubjectFrameHandle = OutFrame; + } + } + } +} + +int ULiveLinkArchiveComponent::FindIndexOfStartingFrame(const double WorldTime) const +{ + int FoundIndex = INDEX_NONE; + + if (ArchivedFrames.Num() > 0) + { + for (int SearchIndex = 0; SearchIndex < ArchivedFrames.Num(); ++SearchIndex) + { + //If we can't go further in the array, or the next element in the array started after our search time, + //then our current element is the best match for the beginning of the desired frame + if ((!ArchivedFrames.IsValidIndex(SearchIndex + 1)) + || (ArchivedFrames[SearchIndex + 1].FrameTime > WorldTime)) + { + FoundIndex = SearchIndex; + + UE_LOG(LogLiveLinkArchiveComponent, Verbose, TEXT("Found Frame at: %d . Frame Time: %f , World Time: %f"), FoundIndex, ArchivedFrames[SearchIndex].FrameTime, WorldTime); + break; + } + } + } + + return FoundIndex; +} + +void ULiveLinkArchiveComponent::CopyFrameDataBlended(const FLiveLinkSubjectFrame& PreFrame, const FLiveLinkSubjectFrame& PostFrame, float BlendWeight, FLiveLinkSubjectFrame& OutFrame) +{ + LiveLinkArchiveBlendHelpers::Blend(PreFrame.Transforms, PostFrame.Transforms, OutFrame.Transforms, BlendWeight); + LiveLinkArchiveBlendHelpers::Blend(PreFrame.Curves, PostFrame.Curves, OutFrame.Curves, BlendWeight); +} + +void ULiveLinkArchiveComponent::PlayFromArchive() +{ + WorldTimeAtArchivePlayStart = FPlatformTime::Seconds(); + bIsArchivePlaying = true; + + UE_LOG(LogLiveLinkArchiveComponent, Log, TEXT("Started playing LiveLinkArchive at %f"), WorldTimeAtArchivePlayStart); +} + +void ULiveLinkArchiveComponent::StopPlaying() +{ + bIsArchivePlaying = false; + + UE_LOG(LogLiveLinkArchiveComponent, Log, TEXT("Stopped playing LiveLinkArchive")); +} diff --git a/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/LiveLinkClient.cpp b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/LiveLinkClient.cpp index bc7a6bc4e70e..861f3f0632f0 100644 --- a/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/LiveLinkClient.cpp +++ b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/LiveLinkClient.cpp @@ -66,6 +66,7 @@ void Blend(const TArray& A, const TArray& B, TArray& Output, f } } +// MERGE-REVIEW - left as source void FLiveLinkSubject::AddFrame(const FLiveLinkFrameData& FrameData, FGuid FrameSource, bool bSaveFrame) { LastModifier = FrameSource; @@ -849,6 +850,20 @@ const FLiveLinkSubjectFrame* FLiveLinkClient::GetSubjectData(FName SubjectName) return nullptr; } +const TArray* FLiveLinkClient::GetSubjectRawFrames(FName SubjectName) +{ + FLiveLinkSubject* Subject; + FScopeLock Lock(&SubjectDataAccessCriticalSection); + + Subject = LiveSubjectData.Find(SubjectName); + TArray* Frames = nullptr; + if (Subject != nullptr) + { + Frames = &Subject->Frames; + } + return Frames; +} + const FLiveLinkSubjectFrame* FLiveLinkClient::GetSubjectDataAtWorldTime(FName SubjectName, double WorldTime) { FLiveLinkSubjectFrame* OutFrame = nullptr; @@ -898,20 +913,6 @@ const FLiveLinkSubjectFrame* FLiveLinkClient::GetSubjectDataAtSceneTime(FName Su return OutFrame; } -const TArray* FLiveLinkClient::GetSubjectRawFrames(FName SubjectName) -{ - FLiveLinkSubject* Subject; - FScopeLock Lock(&SubjectDataAccessCriticalSection); - - Subject = LiveSubjectData.Find(SubjectName); - TArray* Frames = nullptr; - if (Subject != nullptr) - { - Frames = &Subject->Frames; - } - return Frames; -} - FGuid FLiveLinkClient::StartRecordingLiveLink(const FName& SubjectName) { FGuid Guid = FGuid::NewGuid(); @@ -1374,7 +1375,6 @@ void FLiveLinkClient::RemoveSourceFromSubjectWhiteList(FName SubjectName, FGuid } } } - void FLiveLinkClient::ClearSourceWhiteLists() { FScopeLock Lock(&SubjectDataAccessCriticalSection); diff --git a/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/AnimNode_LiveLinkArchiveComponentPose.h b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/AnimNode_LiveLinkArchiveComponentPose.h new file mode 100644 index 000000000000..9cf7563b34ec --- /dev/null +++ b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/AnimNode_LiveLinkArchiveComponentPose.h @@ -0,0 +1,50 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Animation/AnimNodeBase.h" +#include "LiveLinkRetargetAsset.h" +#include "LiveLinkArchiveComponent.h" + +#include "AnimNode_LiveLinkArchiveComponentPose.generated.h" + + +USTRUCT(BlueprintInternalUseOnly) +struct LIVELINK_API FAnimNode_LiveLinkArchiveComponentPose : public FAnimNode_Base +{ + GENERATED_USTRUCT_BODY() + + /** + * The binding of the component source we want to bind to. + * We will search the owning actor's components to try and find a + * LiveLinkArchiveComponent that matches this binding name. + */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SourceData, meta = (PinShownByDefault)) + FName ArchiveNameBinding; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear, Category = Retarget, meta = (NeverAsPin)) + TSubclassOf RetargetAsset; + + UPROPERTY(transient) + ULiveLinkRetargetAsset* CurrentRetargetAsset; + + UPROPERTY(transient) + ULiveLinkArchiveComponent* CurrentLiveLinkArchiveComponent; + + FAnimNode_LiveLinkArchiveComponentPose(); + + // FAnimNode_Base interface + virtual bool HasPreUpdate() const override { return true; } + virtual void PreUpdate(const UAnimInstance* InAnimInstance) override; + + virtual void Initialize_AnyThread(const FAnimationInitializeContext& Context) override; + virtual void CacheBones_AnyThread(const FAnimationCacheBonesContext & Context) override {} + virtual void Update_AnyThread(const FAnimationUpdateContext & Context) override; + virtual void Evaluate_AnyThread(FPoseContext& Output) override; + // End of FAnimNode_Base interface + +private: + // Delta time from update so that it can be passed to retargeter + float CachedDeltaTime; +}; \ No newline at end of file diff --git a/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/AnimNode_LiveLinkPose.h b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/AnimNode_LiveLinkPose.h index 74f15150e5fb..db9c99355d11 100644 --- a/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/AnimNode_LiveLinkPose.h +++ b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/AnimNode_LiveLinkPose.h @@ -15,6 +15,9 @@ struct LIVELINK_API FAnimNode_LiveLinkPose : public FAnimNode_Base { GENERATED_USTRUCT_BODY() + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Input) + FPoseLink InputPose; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SourceData, meta = (PinShownByDefault)) FName SubjectName; @@ -28,12 +31,10 @@ struct LIVELINK_API FAnimNode_LiveLinkPose : public FAnimNode_Base // FAnimNode_Base interface virtual void Initialize_AnyThread(const FAnimationInitializeContext& Context) override; - - virtual void CacheBones_AnyThread(const FAnimationCacheBonesContext & Context) override {} - + virtual void CacheBones_AnyThread(const FAnimationCacheBonesContext & Context) override; virtual void Update_AnyThread(const FAnimationUpdateContext & Context) override; - virtual void Evaluate_AnyThread(FPoseContext& Output) override; + virtual void GatherDebugData(FNodeDebugData& DebugData) override; // End of FAnimNode_Base interface void OnLiveLinkClientRegistered(const FName& Type, class IModularFeature* ModularFeature); diff --git a/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/LiveLinkArchiveComponent.h b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/LiveLinkArchiveComponent.h new file mode 100644 index 000000000000..6308cd4408d8 --- /dev/null +++ b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/LiveLinkArchiveComponent.h @@ -0,0 +1,137 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "Components/ActorComponent.h" +#include "CoreMinimal.h" +#include "ILiveLinkClient.h" +#include "LiveLinkBlueprintStructs.h" +#include "LiveLinkTypes.h" +#include "LiveLinkArchiveComponent.generated.h" + +DECLARE_LOG_CATEGORY_EXTERN(LogLiveLinkArchiveComponent, Log, All); + +class LiveLinkArchiveBlendHelpers +{ +public: + //Blend Functions stolen from LiveLinkClient + static void BlendItem(const FTransform& A, const FTransform& B, FTransform& Output, float BlendWeight) + { + const ScalarRegister ABlendWeight(1.0f - BlendWeight); + const ScalarRegister BBlendWeight(BlendWeight); + + Output = A * ABlendWeight; + Output.AccumulateWithShortestRotation(B, BBlendWeight); + Output.NormalizeRotation(); + } + + static void BlendItem(const FOptionalCurveElement& A, const FOptionalCurveElement& B, FOptionalCurveElement& Output, float BlendWeight) + { + Output.Value = (A.Value * (1.0f - BlendWeight)) + (B.Value * BlendWeight); + Output.bValid = A.bValid || B.bValid; + } + + template + static void Blend(const TArray& A, const TArray& B, TArray& Output, float BlendWeight) + { + check(A.Num() == B.Num()); + Output.SetNum(A.Num(), false); + + for (int32 BlendIndex = 0; BlendIndex < A.Num(); ++BlendIndex) + { + BlendItem(A[BlendIndex], B[BlendIndex], Output[BlendIndex], BlendWeight); + } + } +}; + +//Helper struct to store off archive information +struct FLiveLinkArchiveFrame +{ + FLiveLinkSubjectFrame ArchivedFrame; + + //Stores world time of when this frame was recorded + //First frame in archive should be 0, if next frame happened .5 seconds later it + //will be .5 and so on + double FrameTime; + + FLiveLinkArchiveFrame(FLiveLinkSubjectFrame FrameIn, double FrameTimeIn) + : ArchivedFrame(FrameIn) + , FrameTime(FrameTimeIn) + { + } +}; + + +// An actor component to enable saving LiveLink data into a Frame Archive and then +// supply those frames from the archive on demand later +UCLASS( ClassGroup=(LiveLink), meta=(BlueprintSpawnableComponent) ) +class LIVELINK_API ULiveLinkArchiveComponent : public UActorComponent +{ + GENERATED_BODY() + +public: + // Sets default values for this component's properties + ULiveLinkArchiveComponent(); + +protected: + virtual void OnRegister() override; + +public: + // Called every frame + virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + + // How frequently we would like to capture LiveLink data and save it in the archive. Value is Frames/Sec so 60.0 = 60 FPS capture. + UPROPERTY(EditAnywhere, Category = "LiveLinkArchive") + float CaptureRate; + + //Name used to look for this component by systems that interact with LiveLinkArchive (Different from LiveLink Subject names!) + UPROPERTY(EditAnywhere, Category = "LiveLinkArchive") + FName ArchiveName; + + //FName corresponding to the LiveLink subject we need to track and archive + UPROPERTY(EditAnywhere, Category = "LiveLinkArchive") + FName LiveLinkSubjectToArchive; + + //Determines if we should interpolate between stored archive frames during playback + UPROPERTY(EditAnywhere, Category = "LiveLinkArchive") + bool bInterpolatePlayback; + + UFUNCTION(BlueprintCallable, Category = "LiveLinkArchive") + void BeginLiveLinkCapture(); + + UFUNCTION(BlueprintCallable, Category = "LiveLinkArchive") + void StopLiveLinkCapture(); + + // When this function is called, this component will reset to the beginning of its archived LiveLink frames and begin playing through them + UFUNCTION(BlueprintCallable, Category = "LiveLinkArchive") + void PlayFromArchive(); + + UFUNCTION(BlueprintCallable, Category = "LiveLinkArchive") + void StopPlaying(); + + // Returns a handle to the current frame of data in LiveLink Archive. PlayFromArchive must be called first, or this will fail + void GetSubjectDataAtWorldTime(const double WorldTime, bool& bSuccess, FLiveLinkSubjectFrame& SubjectFrameHandle); + +private: + + bool HasLiveLinkClient(); + + int FindIndexOfStartingFrame(const double WorldTime) const; + + //Helper function to blend interpolated frame data + void CopyFrameDataBlended(const FLiveLinkSubjectFrame& PreFrame, const FLiveLinkSubjectFrame& PostFrame, float BlendWeight, FLiveLinkSubjectFrame& OutFrame); + + //Used to offset the frame that should be gathered + double WorldTimeAtArchivePlayStart; + + //Used to offset the frame time when looking through archived frames + double WorldTimeAtCaptureStart; + + //Used to track if its time to poll LiveLink for more data + float CaptureRateTimer; + + bool bIsArchivePlaying; + bool bIsArchivingFrames; + TArray ArchivedFrames; + ILiveLinkClient* LiveLinkClient; +}; diff --git a/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/LiveLinkClient.h b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/LiveLinkClient.h index 40b3c595e02a..54f0cac69448 100644 --- a/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/LiveLinkClient.h +++ b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/LiveLinkClient.h @@ -90,7 +90,7 @@ struct FLiveLinkSubject void OnStartSynchronization(const struct FTimeSynchronizationOpenData& OpenData, const int32 FrameOffset); void OnSynchronizationEstablished(const struct FTimeSynchronizationStartData& StartData); void OnStopSynchronization(); - + bool IsTimeSynchronized() { return (GetMode() == ELiveLinkSourceMode::TimeSynchronized && TimeSyncData.IsSet()); } void AddLiveLinkFrameAddedWatcher(const FGuid& InGuid); void RemoveLiveLinkFrameAddedWatcher(const FGuid& InGuid); @@ -163,7 +163,7 @@ private: }; TOptional TimeSyncData; - + // Cache out recent frames TMap RecentAddedFramesMap; }; @@ -233,6 +233,9 @@ public: virtual void ClearSubjectsFrames(FName SubjectName) override; virtual void ClearAllSubjectsFrames() override; + // Get full settings structure for source + virtual ULiveLinkSourceSettings* GetSourceSettingsForEntry(FGuid InEntryGuid); + virtual void AddSourceToSubjectWhiteList(FName SubjectName, FGuid SourceGuid) override; virtual void RemoveSourceFromSubjectWhiteList(FName SubjectName, FGuid SourceGuid) override; virtual void ClearSourceWhiteLists() override; @@ -255,7 +258,7 @@ public: bool GetSaveFrames() const override; bool SetSaveFrames(bool InSave) override; - + FGuid StartRecordingLiveLink(const TArray& SubjectNames) override; FGuid StartRecordingLiveLink(const FName& SubjectName) override; void StopRecordingLiveLinkData(const FGuid &InGuid, const TArray& SubjectNames) override; @@ -292,9 +295,6 @@ public: // Get interpolation settings for a source FLiveLinkInterpolationSettings* GetInterpolationSettingsForEntry(FGuid InEntryGuid); - // Get full settings structure for source - ULiveLinkSourceSettings* GetSourceSettingsForEntry(FGuid InEntryGuid); - void OnPropertyChanged(FGuid InEntryGuid, const FPropertyChangedEvent& PropertyChangedEvent); // Functions for managing sources changed delegate diff --git a/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/LiveLinkRemapAsset.h b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/LiveLinkRemapAsset.h index 34b7b368b7fe..fdb7887d11df 100644 --- a/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/LiveLinkRemapAsset.h +++ b/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/LiveLinkRemapAsset.h @@ -12,6 +12,8 @@ class LIVELINK_API ULiveLinkRemapAsset : public ULiveLinkRetargetAsset { GENERATED_UCLASS_BODY() + virtual ~ULiveLinkRemapAsset() {} + //~ Begin UObject Interface virtual void BeginDestroy() override; //~ End UObject Interface diff --git a/Engine/Plugins/Animation/LiveLink/Source/LiveLinkEditor/Private/AnimGraphNode_LiveLinkArchiveComponentPose.cpp b/Engine/Plugins/Animation/LiveLink/Source/LiveLinkEditor/Private/AnimGraphNode_LiveLinkArchiveComponentPose.cpp new file mode 100644 index 000000000000..b598cd4cf9ef --- /dev/null +++ b/Engine/Plugins/Animation/LiveLink/Source/LiveLinkEditor/Private/AnimGraphNode_LiveLinkArchiveComponentPose.cpp @@ -0,0 +1,27 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "AnimGraphNode_LiveLinkArchiveComponentPose.h" + +#define LOCTEXT_NAMESPACE "LiveLinkArchiveComponentAnimNode" + +UAnimGraphNode_LiveLinkArchiveComponentPose::UAnimGraphNode_LiveLinkArchiveComponentPose(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ +} + +FText UAnimGraphNode_LiveLinkArchiveComponentPose::GetNodeTitle(ENodeTitleType::Type TitleType) const +{ + return LOCTEXT("NodeTitle", "Live Link Archive Component Pose"); +} + +FText UAnimGraphNode_LiveLinkArchiveComponentPose::GetTooltipText() const +{ + return LOCTEXT("NodeTooltip", "Retrieves a pose from a Live Link Archive Component. Looks through owning Actor's components to find a LiveLinkArchive Component with the given name and uses it as a source for pose data."); +} + +FText UAnimGraphNode_LiveLinkArchiveComponentPose::GetMenuCategory() const +{ + return LOCTEXT("NodeCategory", "Live Link"); +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Engine/Plugins/Animation/LiveLink/Source/LiveLinkEditor/Private/AnimGraphNode_LiveLinkArchiveComponentPose.h b/Engine/Plugins/Animation/LiveLink/Source/LiveLinkEditor/Private/AnimGraphNode_LiveLinkArchiveComponentPose.h new file mode 100644 index 000000000000..6cdfa7235c1a --- /dev/null +++ b/Engine/Plugins/Animation/LiveLink/Source/LiveLinkEditor/Private/AnimGraphNode_LiveLinkArchiveComponentPose.h @@ -0,0 +1,22 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "AnimGraphNode_Base.h" +#include "AnimNode_LiveLinkArchiveComponentPose.h" + +#include "AnimGraphNode_LiveLinkArchiveComponentPose.generated.h" +UCLASS() +class UAnimGraphNode_LiveLinkArchiveComponentPose : public UAnimGraphNode_Base +{ + GENERATED_UCLASS_BODY() + + UPROPERTY(EditAnywhere, Category = Settings) + FAnimNode_LiveLinkArchiveComponentPose Node; + + // UEdGraphNode interface + virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override; + virtual FText GetTooltipText() const override; + virtual FText GetMenuCategory() const; + // End of UEdGraphNode +}; \ No newline at end of file diff --git a/Engine/Plugins/Developer/PerforceSourceControl/Source/PerforceSourceControl/Private/PerforceSourceControlProvider.cpp b/Engine/Plugins/Developer/PerforceSourceControl/Source/PerforceSourceControl/Private/PerforceSourceControlProvider.cpp index b1dbea36fe3f..e924e8349061 100644 --- a/Engine/Plugins/Developer/PerforceSourceControl/Source/PerforceSourceControl/Private/PerforceSourceControlProvider.cpp +++ b/Engine/Plugins/Developer/PerforceSourceControl/Source/PerforceSourceControl/Private/PerforceSourceControlProvider.cpp @@ -494,8 +494,13 @@ ECommandResult::Type FPerforceSourceControlProvider::ExecuteSynchronousCommand(F } }; + FText TaskText = Task; // Display the progress dialog - FScopedSourceControlProgress Progress(Task, FSimpleDelegate::CreateStatic(&Local::CancelCommand, &InCommand)); + if (bSuppressResponseMsg) + { + TaskText = FText::GetEmpty(); + } + FScopedSourceControlProgress Progress(TaskText, FSimpleDelegate::CreateStatic(&Local::CancelCommand, &InCommand)); // Perform the command asynchronously IssueCommand( InCommand, false ); diff --git a/Engine/Plugins/Editor/FacialAnimation/Source/FacialAnimation/FacialAnimation.Build.cs b/Engine/Plugins/Editor/FacialAnimation/Source/FacialAnimation/FacialAnimation.Build.cs index 962874099f19..4df17714992a 100644 --- a/Engine/Plugins/Editor/FacialAnimation/Source/FacialAnimation/FacialAnimation.Build.cs +++ b/Engine/Plugins/Editor/FacialAnimation/Source/FacialAnimation/FacialAnimation.Build.cs @@ -11,7 +11,7 @@ namespace UnrealBuildTool.Rules "Core", "CoreUObject", "InputCore", - "Engine", + "Engine" } ); } diff --git a/Engine/Plugins/Enterprise/DatasmithContent/Source/DatasmithContent/Private/ObjectTemplates/DatasmithObjectTemplate.cpp b/Engine/Plugins/Enterprise/DatasmithContent/Source/DatasmithContent/Private/ObjectTemplates/DatasmithObjectTemplate.cpp index 5a8d86eae872..7f4a0c60213f 100644 --- a/Engine/Plugins/Enterprise/DatasmithContent/Source/DatasmithContent/Private/ObjectTemplates/DatasmithObjectTemplate.cpp +++ b/Engine/Plugins/Enterprise/DatasmithContent/Source/DatasmithContent/Private/ObjectTemplates/DatasmithObjectTemplate.cpp @@ -64,6 +64,13 @@ TMap< TSubclassOf< UDatasmithObjectTemplate >, UDatasmithObjectTemplate* >* FDat if (!UserData) { EObjectFlags Flags = RF_Public /*| RF_Transactional*/; // RF_Transactional Disabled as is can cause a crash in the transaction system for blueprints + + if ( Outer->GetClass()->IsChildOf() ) + { + // The outer should never be an actor. (UE-70039) + Outer = static_cast(Outer)->GetRootComponent(); + } + UserData = NewObject< UDatasmithAssetUserData >(Outer, NAME_None, Flags); AssetUserDataInterface->AddAssetUserData(UserData); } diff --git a/Engine/Plugins/Experimental/ControlRig/Source/ControlRig/Private/ControlRigBlueprintGeneratedClass.cpp b/Engine/Plugins/Experimental/ControlRig/Source/ControlRig/Private/ControlRigBlueprintGeneratedClass.cpp index 146681242490..107aa6894021 100644 --- a/Engine/Plugins/Experimental/ControlRig/Source/ControlRig/Private/ControlRigBlueprintGeneratedClass.cpp +++ b/Engine/Plugins/Experimental/ControlRig/Source/ControlRig/Private/ControlRigBlueprintGeneratedClass.cpp @@ -37,3 +37,15 @@ void UControlRigBlueprintGeneratedClass::PurgeClass(bool bRecompilingOnLoad) { Super::PurgeClass(bRecompilingOnLoad); } + +uint8* UControlRigBlueprintGeneratedClass::GetPersistentUberGraphFrame(UObject* Obj, UFunction* FuncToCheck) const +{ + if(!IsInGameThread()) + { + // we cant use the persistent frame if we are executing in parallel (as we could potentially thunk to BP) + return nullptr; + } + + return Super::GetPersistentUberGraphFrame(Obj, FuncToCheck); +} + diff --git a/Engine/Plugins/Experimental/ControlRig/Source/ControlRig/Public/ControlRigBlueprintGeneratedClass.h b/Engine/Plugins/Experimental/ControlRig/Source/ControlRig/Public/ControlRigBlueprintGeneratedClass.h index deaebc357635..1c2dc7dce125 100644 --- a/Engine/Plugins/Experimental/ControlRig/Source/ControlRig/Public/ControlRigBlueprintGeneratedClass.h +++ b/Engine/Plugins/Experimental/ControlRig/Source/ControlRig/Public/ControlRigBlueprintGeneratedClass.h @@ -20,6 +20,7 @@ public: // UClass interface virtual void PurgeClass(bool bRecompilingOnLoad) override; + virtual uint8* GetPersistentUberGraphFrame(UObject* Obj, UFunction* FuncToCheck) const override; public: #if WITH_EDITORONLY_DATA diff --git a/Engine/Plugins/Experimental/Gauntlet/Source/Gauntlet/Private/GauntletModule.cpp b/Engine/Plugins/Experimental/Gauntlet/Source/Gauntlet/Private/GauntletModule.cpp index ed91f21f651c..3c920337348a 100644 --- a/Engine/Plugins/Experimental/Gauntlet/Source/Gauntlet/Private/GauntletModule.cpp +++ b/Engine/Plugins/Experimental/Gauntlet/Source/Gauntlet/Private/GauntletModule.cpp @@ -260,6 +260,17 @@ void FGauntletModuleImpl::InnerPreMapChange(const FString& MapName) void FGauntletModuleImpl::InnerPostMapChange(UWorld* World) { + if (!World) + { + // Failed to load requested map + for (auto Controller : Controllers) + { + Controller->OnPostMapChange(World); + } + + return; + } + CurrentMap = World->GetMapName(); for (auto Controller : Controllers) diff --git a/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheSequencer/Classes/GeometryCacheTrackEditor.cpp b/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheSequencer/Classes/GeometryCacheTrackEditor.cpp index f3bce07e0de9..d23cd78a97c2 100644 --- a/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheSequencer/Classes/GeometryCacheTrackEditor.cpp +++ b/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheSequencer/Classes/GeometryCacheTrackEditor.cpp @@ -52,7 +52,7 @@ static UGeometryCacheComponent* AcquireGeometryCacheFromObjectGuid(const FGuid& } } } - else if(UGeometryCacheComponent* GeometryMeshComp = Cast(BoundObject)) + else if (UGeometryCacheComponent* GeometryMeshComp = Cast(BoundObject)) { if (GeometryMeshComp->GetGeometryCache()) { @@ -64,7 +64,7 @@ static UGeometryCacheComponent* AcquireGeometryCacheFromObjectGuid(const FGuid& } -FGeometryCacheSection::FGeometryCacheSection( UMovieSceneSection& InSection, TWeakPtr InSequencer) +FGeometryCacheSection::FGeometryCacheSection(UMovieSceneSection& InSection, TWeakPtr InSequencer) : Section(*CastChecked(&InSection)) , Sequencer(InSequencer) , InitialStartOffsetDuringResize(0) @@ -73,18 +73,18 @@ FGeometryCacheSection::FGeometryCacheSection( UMovieSceneSection& InSection, TWe UMovieSceneSection* FGeometryCacheSection::GetSectionObject() -{ +{ return &Section; } FText FGeometryCacheSection::GetSectionTitle() const { - if (Section.Params.GeometryCache.ResolveObject() != nullptr ) + if (Section.Params.GeometryCache.Get() != nullptr) { - UGeometryCacheComponent* GeometryCache = Cast(Section.Params.GeometryCache.ResolveObject()); + UGeometryCacheComponent* GeometryCache = Cast(Section.Params.GeometryCache.Get()); if (GeometryCache && GeometryCache->GetOwner() != nullptr) - { + { return FText::FromString(GeometryCache->GetOwner()->GetName()); } } @@ -98,10 +98,10 @@ float FGeometryCacheSection::GetSectionHeight() const } -int32 FGeometryCacheSection::OnPaintSection( FSequencerSectionPainter& Painter ) const +int32 FGeometryCacheSection::OnPaintSection(FSequencerSectionPainter& Painter) const { const ESlateDrawEffect DrawEffects = Painter.bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; - + const FTimeToPixel& TimeToPixelConverter = Painter.GetTimeConverter(); int32 LayerId = Painter.PaintSectionBackground(); @@ -121,9 +121,9 @@ int32 FGeometryCacheSection::OnPaintSection( FSequencerSectionPainter& Painter ) if (!FMath::IsNearlyZero(SeqLength, KINDA_SMALL_NUMBER) && SeqLength > 0) { - float MaxOffset = Section.GetRange().Size() / TickResolution; + float MaxOffset = Section.GetRange().Size() / TickResolution; float OffsetTime = SeqLength; - float StartTime = Section.GetInclusiveStartFrame() / TickResolution; + float StartTime = Section.GetInclusiveStartFrame() / TickResolution; while (OffsetTime < MaxOffset) { @@ -133,7 +133,7 @@ int32 FGeometryCacheSection::OnPaintSection( FSequencerSectionPainter& Painter ) Painter.DrawElements, LayerId, Painter.SectionGeometry.MakeChild( - FVector2D(2.f, Painter.SectionGeometry.Size.Y-2.f), + FVector2D(2.f, Painter.SectionGeometry.Size.Y - 2.f), FSlateLayoutTransform(FVector2D(OffsetPixel, 1.f)) ).ToPaintGeometry(), GenericDivider, @@ -148,14 +148,14 @@ int32 FGeometryCacheSection::OnPaintSection( FSequencerSectionPainter& Painter ) if (Painter.bIsSelected && SequencerPtr.IsValid()) { FFrameTime CurrentTime = SequencerPtr->GetLocalTime().Time; - if (Section.GetRange().Contains(CurrentTime.FrameNumber) && Section.Params.GeometryCache.ResolveObject() != nullptr) + if (Section.GetRange().Contains(CurrentTime.FrameNumber) && Section.Params.GeometryCache.Get() != nullptr) { - const float Time = TimeToPixelConverter.FrameToPixel(CurrentTime); + const float Time = TimeToPixelConverter.FrameToPixel(CurrentTime); - UGeometryCacheComponent* GeometryCache = Cast(Section.Params.GeometryCache.ResolveObject()); + UGeometryCacheComponent* GeometryCache = Cast(Section.Params.GeometryCache.Get()); // Draw the current time next to the scrub handle - const float AnimTime = Section.MapTimeToAnimation(CurrentTime, TickResolution); + const float AnimTime = Section.MapTimeToAnimation(CurrentTime, TickResolution); int32 FrameTime = GeometryCache->GetFrameAtTime(AnimTime); FString FrameString = FString::FromInt(FrameTime); @@ -168,13 +168,13 @@ int32 FGeometryCacheSection::OnPaintSection( FSequencerSectionPainter& Painter ) bool bDrawLeft = (Painter.SectionGeometry.Size.X - Time) < (TextSize.X + 22.f) - TextOffsetPx; float TextPosition = bDrawLeft ? Time - TextSize.X - TextOffsetPx : Time + TextOffsetPx; //handle mirrored labels - const float MajorTickHeight = 9.0f; + const float MajorTickHeight = 9.0f; FVector2D TextOffset(TextPosition, Painter.SectionGeometry.Size.Y - (MajorTickHeight + TextSize.Y)); const FLinearColor DrawColor = FEditorStyle::GetSlateColor("SelectionColor").GetColor(FWidgetStyle()); const FVector2D BoxPadding = FVector2D(4.0f, 2.0f); // draw time string - + FSlateDrawElement::MakeBox( Painter.DrawElements, LayerId + 5, @@ -196,14 +196,14 @@ int32 FGeometryCacheSection::OnPaintSection( FSequencerSectionPainter& Painter ) } } - + return LayerId; } void FGeometryCacheSection::BeginResizeSection() { InitialStartOffsetDuringResize = Section.Params.StartFrameOffset; - InitialStartTimeDuringResize = Section.HasStartFrame() ? Section.GetInclusiveStartFrame() : 0; + InitialStartTimeDuringResize = Section.HasStartFrame() ? Section.GetInclusiveStartFrame() : 0; } void FGeometryCacheSection::ResizeSection(ESequencerSectionResizeMode ResizeMode, FFrameNumber ResizeTime) @@ -256,28 +256,28 @@ void FGeometryCacheSection::SlipSection(FFrameNumber SlipTime) } -FGeometryCacheTrackEditor::FGeometryCacheTrackEditor( TSharedRef InSequencer ) - : FMovieSceneTrackEditor( InSequencer ) +FGeometryCacheTrackEditor::FGeometryCacheTrackEditor(TSharedRef InSequencer) + : FMovieSceneTrackEditor(InSequencer) { } -TSharedRef FGeometryCacheTrackEditor::CreateTrackEditor( TSharedRef InSequencer ) +TSharedRef FGeometryCacheTrackEditor::CreateTrackEditor(TSharedRef InSequencer) { - return MakeShareable( new FGeometryCacheTrackEditor( InSequencer ) ); + return MakeShareable(new FGeometryCacheTrackEditor(InSequencer)); } -bool FGeometryCacheTrackEditor::SupportsType( TSubclassOf Type ) const +bool FGeometryCacheTrackEditor::SupportsType(TSubclassOf Type) const { return Type == UMovieSceneGeometryCacheTrack::StaticClass(); } -TSharedRef FGeometryCacheTrackEditor::MakeSectionInterface( UMovieSceneSection& SectionObject, UMovieSceneTrack& Track, FGuid ObjectBinding ) +TSharedRef FGeometryCacheTrackEditor::MakeSectionInterface(UMovieSceneSection& SectionObject, UMovieSceneTrack& Track, FGuid ObjectBinding) { - check( SupportsType( SectionObject.GetOuter()->GetClass() ) ); - - return MakeShareable( new FGeometryCacheSection(SectionObject, GetSequencer()) ); + check(SupportsType(SectionObject.GetOuter()->GetClass())); + + return MakeShareable(new FGeometryCacheSection(SectionObject, GetSequencer())); } void FGeometryCacheTrackEditor::BuildObjectBindingTrackMenu(FMenuBuilder& MenuBuilder, const FGuid& ObjectBinding, const UClass* ObjectClass) @@ -317,11 +317,11 @@ void FGeometryCacheTrackEditor::BuildGeometryCacheTrack(FGuid ObjectBinding, UGe } } -FKeyPropertyResult FGeometryCacheTrackEditor::AddKeyInternal( FFrameNumber KeyTime, UObject* Object, UGeometryCacheComponent* GeomCacheComp, UMovieSceneTrack* Track) +FKeyPropertyResult FGeometryCacheTrackEditor::AddKeyInternal(FFrameNumber KeyTime, UObject* Object, UGeometryCacheComponent* GeomCacheComp, UMovieSceneTrack* Track) { FKeyPropertyResult KeyPropertyResult; - FFindOrCreateHandleResult HandleResult = FindOrCreateHandleToObject( Object ); + FFindOrCreateHandleResult HandleResult = FindOrCreateHandleToObject(Object); FGuid ObjectHandle = HandleResult.Handle; KeyPropertyResult.bHandleCreated |= HandleResult.bWasCreated; if (ObjectHandle.IsValid()) @@ -336,7 +336,7 @@ FKeyPropertyResult FGeometryCacheTrackEditor::AddKeyInternal( FFrameNumber KeyTi { Track->Modify(); - UMovieSceneSection* NewSection = Cast(Track)->AddNewAnimation( KeyTime, GeomCacheComp ); + UMovieSceneSection* NewSection = Cast(Track)->AddNewAnimation(KeyTime, GeomCacheComp); KeyPropertyResult.bTrackModified = true; GetSequencer()->EmptySelection(); @@ -362,7 +362,7 @@ TSharedPtr FGeometryCacheTrackEditor::BuildOutlinerEditWidget(const FGu FMenuBuilder MenuBuilder(true, nullptr); BuildGeometryCacheTrack(ObjectBinding, GeomMeshComp, Track); - + return MenuBuilder.MakeWidget(); }; @@ -378,7 +378,7 @@ TSharedPtr FGeometryCacheTrackEditor::BuildOutlinerEditWidget(const FGu { return TSharedPtr(); } - + } const FSlateBrush* FGeometryCacheTrackEditor::GetIconBrush() const diff --git a/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Classes/MovieSceneGeometryCacheSection.h b/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Classes/MovieSceneGeometryCacheSection.h index 07083b4ea279..c6339eb8d661 100644 --- a/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Classes/MovieSceneGeometryCacheSection.h +++ b/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Classes/MovieSceneGeometryCacheSection.h @@ -18,42 +18,40 @@ struct FMovieSceneGeometryCacheParams FMovieSceneGeometryCacheParams(); /** Gets the animation duration, modified by play rate */ - float GetDuration() const { return FMath::IsNearlyZero(PlayRate) || GeometryCache.ResolveObject() == nullptr ? 0.f : Cast(GeometryCache.ResolveObject())->GetDuration() / PlayRate; } + float GetDuration() const { return FMath::IsNearlyZero(PlayRate) || GeometryCache.Get() == nullptr ? 0.f : Cast(GeometryCache.Get())->GetDuration() / PlayRate; } /** Gets the animation sequence length, not modified by play rate */ - float GetSequenceLength() const { return GeometryCache.ResolveObject() != nullptr ? Cast(GeometryCache.ResolveObject())->GetDuration() : 0.f; } - - /** The animation this section plays */ - UPROPERTY(EditAnywhere, Category="GeometryCache", meta=(AllowedClasses = "GeometryCacheComponent")) - FSoftObjectPath GeometryCache; + float GetSequenceLength() const { return GeometryCache.Get() != nullptr ? Cast(GeometryCache.Get())->GetDuration() : 0.f; } /** The offset into the beginning of the animation clip */ - UPROPERTY(EditAnywhere, Category="GeometryCache") + UPROPERTY(EditAnywhere, Category = "GeometryCache") FFrameNumber StartFrameOffset; - + /** The offset into the end of the animation clip */ - UPROPERTY(EditAnywhere, Category="GeometryCache") + UPROPERTY(EditAnywhere, Category = "GeometryCache") FFrameNumber EndFrameOffset; - + /** The playback rate of the animation clip */ - UPROPERTY(EditAnywhere, Category="GeometryCache") + UPROPERTY(EditAnywhere, Category = "GeometryCache") float PlayRate; /** Reverse the playback of the animation clip */ - UPROPERTY(EditAnywhere, Category="Animation") - uint32 bReverse:1; + UPROPERTY(EditAnywhere, Category = "Animation") + uint32 bReverse : 1; UPROPERTY() float StartOffset_DEPRECATED; - + UPROPERTY() float EndOffset_DEPRECATED; + + TWeakObjectPtr GeometryCache; }; /** * Movie scene section that control geometry cache playback */ -UCLASS( MinimalAPI ) +UCLASS(MinimalAPI) class UMovieSceneGeometryCacheSection : public UMovieSceneSection { @@ -61,11 +59,11 @@ class UMovieSceneGeometryCacheSection public: - UPROPERTY(EditAnywhere, Category = "Animation", meta=(ShowOnlyInnerProperties)) + UPROPERTY(EditAnywhere, Category = "Animation", meta = (ShowOnlyInnerProperties)) FMovieSceneGeometryCacheParams Params; /** Get Frame Time as Animation Time*/ - virtual float MapTimeToAnimation(FFrameTime InPosition, FFrameRate InFrameRate) const; + virtual float MapTimeToAnimation(FFrameTime InPosition, FFrameRate InFrameRate) const; protected: //~ UMovieSceneSection interface @@ -92,5 +90,4 @@ private: #endif - }; diff --git a/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheSection.cpp b/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheSection.cpp index 7f5f0283cb63..76abbe9e39ee 100644 --- a/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheSection.cpp +++ b/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheSection.cpp @@ -22,8 +22,8 @@ FMovieSceneGeometryCacheParams::FMovieSceneGeometryCacheParams() bReverse = false; } -UMovieSceneGeometryCacheSection::UMovieSceneGeometryCacheSection( const FObjectInitializer& ObjectInitializer ) - : Super( ObjectInitializer ) +UMovieSceneGeometryCacheSection::UMovieSceneGeometryCacheSection(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) { BlendType = EMovieSceneBlendType::Absolute; EvalOptions.EnableAndSetCompletionMode(EMovieSceneCompletionMode::ProjectDefault); @@ -89,10 +89,10 @@ FFrameNumber GetStartOffsetAtTrimTime(FQualifiedFrameTime TrimTime, const FMovie TOptional > UMovieSceneGeometryCacheSection::GetAutoSizeRange() const { FFrameRate FrameRate = GetTypedOuter()->GetTickResolution(); - FFrameTime AnimationLength = Params.GetSequenceLength() * FrameRate; + int32 IFrameNumber = AnimationLength.FrameNumber.Value + (int)(AnimationLength.GetSubFrame() + 0.5f); - return TRange(GetInclusiveStartFrame(), GetInclusiveStartFrame() + AnimationLength.FrameNumber); + return TRange(GetInclusiveStartFrame(), GetInclusiveStartFrame() + IFrameNumber + 1); } @@ -133,11 +133,11 @@ void UMovieSceneGeometryCacheSection::GetSnapTimes(TArray& OutSnap { Super::GetSnapTimes(OutSnapTimes, bGetSectionBorders); - const FFrameRate FrameRate = GetTypedOuter()->GetTickResolution(); + const FFrameRate FrameRate = GetTypedOuter()->GetTickResolution(); const FFrameNumber StartFrame = GetInclusiveStartFrame(); - const FFrameNumber EndFrame = GetExclusiveEndFrame() - 1; // -1 because we don't need to add the end frame twice + const FFrameNumber EndFrame = GetExclusiveEndFrame() - 1; // -1 because we don't need to add the end frame twice - const float AnimPlayRate = FMath::IsNearlyZero(Params.PlayRate) ? 1.0f : Params.PlayRate; + const float AnimPlayRate = FMath::IsNearlyZero(Params.PlayRate) ? 1.0f : Params.PlayRate; const float SeqLengthSeconds = Params.GetSequenceLength() - FrameRate.AsSeconds(Params.StartFrameOffset + Params.EndFrameOffset) / AnimPlayRate; FFrameTime SequenceFrameLength = SeqLengthSeconds * FrameRate; @@ -155,7 +155,7 @@ void UMovieSceneGeometryCacheSection::GetSnapTimes(TArray& OutSnap float UMovieSceneGeometryCacheSection::MapTimeToAnimation(FFrameTime InPosition, FFrameRate InFrameRate) const { - FMovieSceneGeometryCacheSectionTemplateParameters TemplateParams(Params, GetInclusiveStartFrame(), GetExclusiveEndFrame()); + FMovieSceneGeometryCacheSectionTemplateParameters TemplateParams(const_cast (Params), GetInclusiveStartFrame(), GetExclusiveEndFrame()); return TemplateParams.MapTimeToAnimation(InPosition, InFrameRate); } @@ -181,7 +181,7 @@ void UMovieSceneGeometryCacheSection::PostEditChangeProperty(FPropertyChangedEve { float CurrentDuration = MovieScene::DiscreteSize(GetRange()); float NewDuration = CurrentDuration * (PreviousPlayRate / NewPlayRate); - SetEndFrame( GetInclusiveStartFrame() + FMath::FloorToInt(NewDuration) ); + SetEndFrame(GetInclusiveStartFrame() + FMath::FloorToInt(NewDuration)); PreviousPlayRate = NewPlayRate; } diff --git a/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheTemplate.cpp b/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheTemplate.cpp index b4b3d64377b6..1f4079cdf8eb 100644 --- a/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheTemplate.cpp +++ b/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheTemplate.cpp @@ -45,35 +45,67 @@ struct FPreAnimatedGeometryCacheTokenProducer : IMovieScenePreAnimatedTokenProdu /** A movie scene execution token that executes a geometry cache */ struct FGeometryCacheExecutionToken : IMovieSceneExecutionToken - + { - FGeometryCacheExecutionToken(const FMovieSceneGeometryCacheSectionTemplateParameters &InParams): + FGeometryCacheExecutionToken(const FMovieSceneGeometryCacheSectionTemplateParameters &InParams) : Params(InParams) {} + static UGeometryCacheComponent* GeometryMeshComponentFromObject(UObject* BoundObject) + { + if (AActor* Actor = Cast(BoundObject)) + { + for (UActorComponent* Component : Actor->GetComponents()) + { + if (UGeometryCacheComponent* GeometryMeshComp = Cast(Component)) + { + return GeometryMeshComp; + } + } + } + else if (UGeometryCacheComponent* GeometryMeshComp = Cast(BoundObject)) + { + if (GeometryMeshComp->GetGeometryCache()) + { + return GeometryMeshComp; + } + } + return nullptr; + } + /** Execute this token, operating on all objects referenced by 'Operand' */ virtual void Execute(const FMovieSceneContext& Context, const FMovieSceneEvaluationOperand& Operand, FPersistentEvaluationData& PersistentData, IMovieScenePlayer& Player) override { - if (Params.GeometryCache.ResolveObject()) + MOVIESCENE_DETAILED_SCOPE_CYCLE_COUNTER(MovieSceneEval_GeometryCache_TokenExecute) + if (Operand.ObjectBindingID.IsValid()) { - MOVIESCENE_DETAILED_SCOPE_CYCLE_COUNTER(MovieSceneEval_GeometryCache_TokenExecute) - - UGeometryCacheComponent* GeometryCache = Cast(Params.GeometryCache.ResolveObject()); - - Player.SavePreAnimatedState(*GeometryCache, FPreAnimatedGeometryCacheTokenProducer::GetAnimTypeID(), FPreAnimatedGeometryCacheTokenProducer()); - GeometryCache->SetManualTick(true); - // calculate the time at which to evaluate the animation - float EvalTime = Params.MapTimeToAnimation(Context.GetTime(), Context.GetFrameRate()); - GeometryCache->TickAtThisTime(EvalTime, true, Params.bReverse, true); + for (TWeakObjectPtr<> WeakObj : Player.FindBoundObjects(Operand)) + { + if (UObject* Obj = WeakObj.Get()) + { + UGeometryCacheComponent* GeometryCache = GeometryMeshComponentFromObject(Obj); + if (GeometryCache) + { + if (Params.SectionParams->GeometryCache.Get() == nullptr) + { + Params.SectionParams->GeometryCache = GeometryCache; + } + Player.SavePreAnimatedState(*GeometryCache, FPreAnimatedGeometryCacheTokenProducer::GetAnimTypeID(), FPreAnimatedGeometryCacheTokenProducer()); + GeometryCache->SetManualTick(true); + // calculate the time at which to evaluate the animation + float EvalTime = Params.MapTimeToAnimation(Context.GetTime(), Context.GetFrameRate()); + GeometryCache->TickAtThisTime(EvalTime, true, Params.SectionParams->bReverse, true); + } + } + } } - } FMovieSceneGeometryCacheSectionTemplateParameters Params; }; FMovieSceneGeometryCacheSectionTemplate::FMovieSceneGeometryCacheSectionTemplate(const UMovieSceneGeometryCacheSection& InSection) - : Params(InSection.Params, InSection.GetInclusiveStartFrame(), InSection.GetExclusiveEndFrame()) + : Params(const_cast (InSection.Params), InSection.GetInclusiveStartFrame(), InSection.GetExclusiveEndFrame()) { } @@ -82,28 +114,34 @@ FMovieSceneGeometryCacheSectionTemplate::FMovieSceneGeometryCacheSectionTemplate void FMovieSceneGeometryCacheSectionTemplate::Evaluate(const FMovieSceneEvaluationOperand& Operand, const FMovieSceneContext& Context, const FPersistentEvaluationData& PersistentData, FMovieSceneExecutionTokens& ExecutionTokens) const { MOVIESCENE_DETAILED_SCOPE_CYCLE_COUNTER(MovieSceneEval_GeometryCache_Evaluate) - ExecutionTokens.Add(FGeometryCacheExecutionToken(Params)); + ExecutionTokens.Add(FGeometryCacheExecutionToken(Params)); } float FMovieSceneGeometryCacheSectionTemplateParameters::MapTimeToAnimation(FFrameTime InPosition, FFrameRate InFrameRate) const { - InPosition = FMath::Clamp(InPosition, FFrameTime(SectionStartTime), FFrameTime(SectionEndTime-1)); + FFrameTime AnimationLength = SectionParams->GetSequenceLength() * InFrameRate; + int32 LengthInFrames = AnimationLength.FrameNumber.Value + (int)(AnimationLength.GetSubFrame() + 0.5f) + 1; + //we only play end if we are not looping, and assuming we are looping if Length is greater than default length; + bool bLooping = (SectionEndTime.Value - SectionStartTime.Value) > LengthInFrames; - const float SectionPlayRate = PlayRate; + InPosition = FMath::Clamp(InPosition, FFrameTime(SectionStartTime), FFrameTime(SectionEndTime - 1)); + + const float SectionPlayRate = SectionParams->PlayRate; const float AnimPlayRate = FMath::IsNearlyZero(SectionPlayRate) ? 1.0f : SectionPlayRate; - const float SeqLength = GetSequenceLength() - InFrameRate.AsSeconds(StartFrameOffset + EndFrameOffset); + const float SeqLength = SectionParams->GetSequenceLength() - InFrameRate.AsSeconds(SectionParams->StartFrameOffset + SectionParams->EndFrameOffset); float AnimPosition = FFrameTime::FromDecimal((InPosition - SectionStartTime).AsDecimal() * AnimPlayRate) / InFrameRate; - if (SeqLength > 0.f) + if (SeqLength > 0.f && (bLooping || !FMath::IsNearlyEqual(AnimPosition, SeqLength, 1e-4f))) { AnimPosition = FMath::Fmod(AnimPosition, SeqLength); } - AnimPosition += InFrameRate.AsSeconds(StartFrameOffset); - if (bReverse) + AnimPosition += InFrameRate.AsSeconds(SectionParams->StartFrameOffset); + if (SectionParams->bReverse) { - AnimPosition = (SeqLength - (AnimPosition - InFrameRate.AsSeconds(StartFrameOffset))) + InFrameRate.AsSeconds(StartFrameOffset); + AnimPosition = (SeqLength - (AnimPosition - InFrameRate.AsSeconds(SectionParams->StartFrameOffset))) + InFrameRate.AsSeconds(SectionParams->StartFrameOffset); } return AnimPosition; -} + +} \ No newline at end of file diff --git a/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheTemplate.h b/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheTemplate.h index f576c890b5af..4fa8a034482e 100644 --- a/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheTemplate.h +++ b/Engine/Plugins/Experimental/GeometryCache/Source/GeometryCacheTracks/Private/MovieSceneGeometryCacheTemplate.h @@ -9,19 +9,21 @@ #include "MovieSceneGeometryCacheTemplate.generated.h" USTRUCT() -struct FMovieSceneGeometryCacheSectionTemplateParameters : public FMovieSceneGeometryCacheParams +struct FMovieSceneGeometryCacheSectionTemplateParameters { GENERATED_BODY() - FMovieSceneGeometryCacheSectionTemplateParameters() {} - FMovieSceneGeometryCacheSectionTemplateParameters(const FMovieSceneGeometryCacheParams& BaseParams, FFrameNumber InSectionStartTime, FFrameNumber InSectionEndTime) - : FMovieSceneGeometryCacheParams(BaseParams) + FMovieSceneGeometryCacheSectionTemplateParameters() :SectionParams(nullptr) {} + FMovieSceneGeometryCacheSectionTemplateParameters(FMovieSceneGeometryCacheParams& BaseParams, FFrameNumber InSectionStartTime, FFrameNumber InSectionEndTime) + : SectionParams(&BaseParams) , SectionStartTime(InSectionStartTime) , SectionEndTime(InSectionEndTime) {} float MapTimeToAnimation(FFrameTime InPosition, FFrameRate InFrameRate) const; + FMovieSceneGeometryCacheParams* SectionParams; + UPROPERTY() FFrameNumber SectionStartTime; @@ -33,7 +35,7 @@ USTRUCT() struct FMovieSceneGeometryCacheSectionTemplate : public FMovieSceneEvalTemplate { GENERATED_BODY() - + FMovieSceneGeometryCacheSectionTemplate() {} FMovieSceneGeometryCacheSectionTemplate(const UMovieSceneGeometryCacheSection& Section); diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyCore.cpp b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyCore.cpp index 7511a332dc20..d092cfb14b7c 100644 --- a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyCore.cpp +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyCore.cpp @@ -4,6 +4,7 @@ #include "PyGenUtil.h" #include "PyReferenceCollector.h" #include "PyWrapperTypeRegistry.h" +#include "IPythonScriptPlugin.h" #include "PyWrapperBase.h" #include "PyWrapperObject.h" @@ -1009,13 +1010,35 @@ PyTypeObject PyUFunctionDefType = InitializePyUFunctionDefType(); namespace PyCore { +bool ShouldLog(const FString& InLogMessage) +{ + if (InLogMessage.IsEmpty()) + { + return false; + } + + for (const TCHAR LogChar : InLogMessage) + { + if (!FChar::IsWhitespace(LogChar)) + { + return true; + } + } + + return false; +} + PyObject* Log(PyObject* InSelf, PyObject* InArgs) { PyObject* PyObj = nullptr; if (PyArg_ParseTuple(InArgs, "O:log", &PyObj)) { const FString LogMessage = PyUtil::PyObjectToUEString(PyObj); - UE_LOG(LogPython, Log, TEXT("%s"), *LogMessage); + if (ShouldLog(LogMessage)) + { + UE_LOG(LogPython, Log, TEXT("%s"), *LogMessage); + GetPythonLogCapture().Broadcast(EPythonLogOutputType::Info, *LogMessage); + } Py_RETURN_NONE; } @@ -1026,10 +1049,14 @@ PyObject* Log(PyObject* InSelf, PyObject* InArgs) PyObject* LogWarning(PyObject* InSelf, PyObject* InArgs) { PyObject* PyObj = nullptr; - if (PyArg_ParseTuple(InArgs, "O:log", &PyObj)) + if (PyArg_ParseTuple(InArgs, "O:log_warning", &PyObj)) { const FString LogMessage = PyUtil::PyObjectToUEString(PyObj); - UE_LOG(LogPython, Warning, TEXT("%s"), *LogMessage); + if (ShouldLog(LogMessage)) + { + UE_LOG(LogPython, Warning, TEXT("%s"), *LogMessage); + GetPythonLogCapture().Broadcast(EPythonLogOutputType::Warning, *LogMessage); + } Py_RETURN_NONE; } @@ -1040,10 +1067,14 @@ PyObject* LogWarning(PyObject* InSelf, PyObject* InArgs) PyObject* LogError(PyObject* InSelf, PyObject* InArgs) { PyObject* PyObj = nullptr; - if (PyArg_ParseTuple(InArgs, "O:log", &PyObj)) + if (PyArg_ParseTuple(InArgs, "O:log_error", &PyObj)) { const FString LogMessage = PyUtil::PyObjectToUEString(PyObj); - UE_LOG(LogPython, Error, TEXT("%s"), *LogMessage); + if (ShouldLog(LogMessage)) + { + UE_LOG(LogPython, Error, TEXT("%s"), *LogMessage); + GetPythonLogCapture().Broadcast(EPythonLogOutputType::Error, *LogMessage); + } Py_RETURN_NONE; } @@ -1717,6 +1748,12 @@ void InitializeModule() FPyWrapperTypeRegistry::Get().RegisterNativePythonModule(MoveTemp(NativePythonModule)); } +FPythonLogCapture& GetPythonLogCapture() +{ + static FPythonLogCapture PythonLogCapture; + return PythonLogCapture; +} + } #endif // WITH_PYTHON diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyCore.h b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyCore.h index f0ef10ee48a9..84a2134fd375 100644 --- a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyCore.h +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyCore.h @@ -10,9 +10,12 @@ #include "CoreMinimal.h" #include "Misc/EnumClassFlags.h" #include "UObject/UObjectIterator.h" +#include "Delegates/DelegateCombinations.h" #if WITH_PYTHON +enum class EPythonLogOutputType : uint8; + struct FSlowTask; /** Get the object that Python created transient properties should be outered to */ @@ -370,6 +373,9 @@ typedef TPyPtr FPyUFunctionDefPtr; namespace PyCore { void InitializeModule(); + + DECLARE_MULTICAST_DELEGATE_TwoParams(FPythonLogCapture, EPythonLogOutputType, const TCHAR*); + FPythonLogCapture& GetPythonLogCapture(); } #endif // WITH_PYTHON diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyOnlineDocsWriter.cpp b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyOnlineDocsWriter.cpp index 52693a291c98..776e0a2b48f7 100644 --- a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyOnlineDocsWriter.cpp +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyOnlineDocsWriter.cpp @@ -1,7 +1,8 @@ // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. #include "PyOnlineDocsWriter.h" -#include "PythonScriptPlugin.h" +#include "IPythonScriptPlugin.h" +#include "PyUtil.h" #include "PyGenUtil.h" #include "HAL/FileManager.h" #include "Logging/MessageLog.h" @@ -380,7 +381,7 @@ void FPyOnlineDocsWriter::GenerateFiles(const FString& InPythonStubPath) #endif // !NO_LOGGING // Run the Python commands - bool PyRunSuccess = FPythonScriptPlugin::Get()->RunString(*PyCommandStr); + bool PyRunSuccess = IPythonScriptPlugin::Get()->ExecPythonCommand(*PyCommandStr); #if !NO_LOGGING if (!bLogSphinx) diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyUtil.cpp b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyUtil.cpp index ef856cf9aede..c1a726c9fc43 100644 --- a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyUtil.cpp +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyUtil.cpp @@ -90,6 +90,16 @@ FString PyStringToUEString(PyObject* InPyStr) return Str; } +FString PyObjectToUEStringRepr(PyObject* InPyObj) +{ + FPyObjectPtr PyReprObj = FPyObjectPtr::StealReference(PyObject_Repr(InPyObj)); + if (PyReprObj) + { + return PyStringToUEString(PyReprObj); + } + return PyObjectToUEString(InPyObj); +} + FPropValueOnScope::FPropValueOnScope(const UProperty* InProp) : Prop(InProp) , Value(nullptr) @@ -1257,7 +1267,7 @@ FString BuildPythonError() return PythonErrorString; } -void LogPythonError(const bool bInteractive) +FString LogPythonError(const bool bInteractive) { const FString ErrorStr = BuildPythonError(); @@ -1281,9 +1291,11 @@ void LogPythonError(const bool bInteractive) FMessageDialog::Open(EAppMsgType::Ok, FText::AsCultureInvariant(ErrorStr), &DlgTitle); } } + + return ErrorStr; } -void ReThrowPythonError() +FString ReThrowPythonError() { const FString ErrorStr = BuildPythonError(); @@ -1291,6 +1303,8 @@ void ReThrowPythonError() { FFrame::KismetExecutionMessage(*ErrorStr, ELogVerbosity::Error); } + + return ErrorStr; } } diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyUtil.h b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyUtil.h index a518eb84cdb8..a2e52df64197 100644 --- a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyUtil.h +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyUtil.h @@ -57,6 +57,9 @@ namespace PyUtil /** Given a Python string/unicode object, extract the string value into an FString */ FString PyStringToUEString(PyObject* InPyStr); + /** Given a Python object, convert it to its string representation (repr) and extract the string value into an FString */ + FString PyObjectToUEStringRepr(PyObject* InPyObj); + /** Given two values, perform a rich-comparison and return the result */ template PyObject* PyRichCmp(const T& InLHS, const U& InRHS, const int InOp) @@ -368,11 +371,17 @@ namespace PyUtil /** Enable developer warnings (eg, deprecation warnings) */ bool EnableDeveloperWarnings(); - /** Log any pending Python error (will also clear the error) */ - void LogPythonError(const bool bInteractive = false); + /** + * Log any pending Python error (will also clear the error). + * @return The error text that was logged. + */ + FString LogPythonError(const bool bInteractive = false); - /** Re-throw any pending Python error via FFrame::KismetExecutionMessage (will also clear the error) */ - void ReThrowPythonError(); + /** + * Re-throw any pending Python error via FFrame::KismetExecutionMessage (will also clear the error). + * @return The error text that was thrown. + */ + FString ReThrowPythonError(); } #endif // WITH_PYTHON diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyWrapperTypeRegistry.cpp b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyWrapperTypeRegistry.cpp index 64657ee4b46b..e9db42fe5d33 100644 --- a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyWrapperTypeRegistry.cpp +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyWrapperTypeRegistry.cpp @@ -1776,7 +1776,7 @@ PyTypeObject* FPyWrapperTypeRegistry::GenerateWrappedDelegateType(const UFunctio UClass* PythonCallableForDelegateClass = nullptr; { PythonCallableForDelegateClass = NewObject(GetPythonTypeContainer(), *FString::Printf(TEXT("%s__PythonCallable"), *DelegateBaseTypename), RF_Public); - UFunction* PythonCallableForDelegateFunc = (UFunction*)StaticDuplicateObject(InDelegateSignature, PythonCallableForDelegateClass, UPythonCallableForDelegate::GeneratedFuncName, RF_AllFlags, UFunction::StaticClass()); + UFunction* PythonCallableForDelegateFunc = (UFunction*)StaticDuplicateObject(InDelegateSignature, PythonCallableForDelegateClass, UPythonCallableForDelegate::GeneratedFuncName); PythonCallableForDelegateFunc->FunctionFlags = (PythonCallableForDelegateFunc->FunctionFlags | FUNC_Native) & ~(FUNC_Delegate | FUNC_MulticastDelegate); PythonCallableForDelegateFunc->SetNativeFunc(&UPythonCallableForDelegate::CallPythonNative); PythonCallableForDelegateFunc->StaticLink(true); diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptCommandlet.cpp b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptCommandlet.cpp index 67e4646707f5..2ddc4e669265 100644 --- a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptCommandlet.cpp +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptCommandlet.cpp @@ -1,7 +1,8 @@ // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. #include "PythonScriptCommandlet.h" -#include "PythonScriptPlugin.h" +#include "IPythonScriptPlugin.h" +#include "Logging/LogMacros.h" DEFINE_LOG_CATEGORY_STATIC(LogPythonScriptCommandlet, Log, All); @@ -32,8 +33,14 @@ int32 UPythonScriptCommandlet::Main(const FString& Params) } #if WITH_PYTHON - UE_LOG(LogPythonScriptCommandlet, Display, TEXT("Running Python script: %s"), *PythonScript); - FPythonScriptPlugin::Get()->HandlePythonExecCommand(*PythonScript); + { + UE_LOG(LogPythonScriptCommandlet, Display, TEXT("Running Python script: %s"), *PythonScript); + + FPythonCommandEx PythonCommand; + PythonCommand.Flags |= EPythonCommandFlags::Unattended; + PythonCommand.Command = PythonScript; + IPythonScriptPlugin::Get()->ExecPythonCommandEx(PythonCommand); + } #else // WITH_PYTHON UE_LOG(LogPythonScriptCommandlet, Error, TEXT("Python script cannot run as the plugin was built as a stub!")); return -1; diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPlugin.cpp b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPlugin.cpp index e2f6e6732368..9050b326eb1e 100644 --- a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPlugin.cpp +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPlugin.cpp @@ -2,6 +2,7 @@ #include "PythonScriptPlugin.h" #include "PythonScriptPluginSettings.h" +#include "PythonScriptRemoteExecution.h" #include "PyGIL.h" #include "PyCore.h" #include "PySlate.h" @@ -74,7 +75,7 @@ struct FPythonScopedArgv TArray PyCommandLineArgPtrs; }; -FPythonCommandExecutor::FPythonCommandExecutor(FPythonScriptPlugin* InPythonScriptPlugin) +FPythonCommandExecutor::FPythonCommandExecutor(IPythonScriptPlugin* InPythonScriptPlugin) : PythonScriptPlugin(InPythonScriptPlugin) { } @@ -97,12 +98,12 @@ FText FPythonCommandExecutor::GetDisplayName() const FText FPythonCommandExecutor::GetDescription() const { - return LOCTEXT("PythonCommandExecutorDescription", "Execute Python Scripts"); + return LOCTEXT("PythonCommandExecutorDescription", "Execute Python scripts (including files)"); } FText FPythonCommandExecutor::GetHintText() const { - return LOCTEXT("PythonCommandExecutorHintText", "Enter Python Script"); + return LOCTEXT("PythonCommandExecutorHintText", "Enter Python script or a filename to execute"); } void FPythonCommandExecutor::GetAutoCompleteSuggestions(const TCHAR* Input, TArray& Out) @@ -119,7 +120,8 @@ bool FPythonCommandExecutor::Exec(const TCHAR* Input) IConsoleManager::Get().AddConsoleHistoryEntry(TEXT("Python"), Input); UE_LOG(LogPython, Log, TEXT("%s"), Input); - PythonScriptPlugin->HandlePythonExecCommand(Input); + + PythonScriptPlugin->ExecPythonCommand(Input); return true; } @@ -134,6 +136,70 @@ bool FPythonCommandExecutor::AllowMultiLine() const return true; } +FPythonREPLCommandExecutor::FPythonREPLCommandExecutor(IPythonScriptPlugin* InPythonScriptPlugin) + : PythonScriptPlugin(InPythonScriptPlugin) +{ +} + +FName FPythonREPLCommandExecutor::StaticName() +{ + static const FName CmdExecName = TEXT("PythonREPL"); + return CmdExecName; +} + +FName FPythonREPLCommandExecutor::GetName() const +{ + return StaticName(); +} + +FText FPythonREPLCommandExecutor::GetDisplayName() const +{ + return LOCTEXT("PythonREPLCommandExecutorDisplayName", "Python (REPL)"); +} + +FText FPythonREPLCommandExecutor::GetDescription() const +{ + return LOCTEXT("PythonREPLCommandExecutorDescription", "Execute a single Python statement and show its result"); +} + +FText FPythonREPLCommandExecutor::GetHintText() const +{ + return LOCTEXT("PythonREPLCommandExecutorHintText", "Enter a single Python statement"); +} + +void FPythonREPLCommandExecutor::GetAutoCompleteSuggestions(const TCHAR* Input, TArray& Out) +{ +} + +void FPythonREPLCommandExecutor::GetExecHistory(TArray& Out) +{ + IConsoleManager::Get().GetConsoleHistory(TEXT("PythonREPL"), Out); +} + +bool FPythonREPLCommandExecutor::Exec(const TCHAR* Input) +{ + IConsoleManager::Get().AddConsoleHistoryEntry(TEXT("PythonREPL"), Input); + + UE_LOG(LogPython, Log, TEXT("%s"), Input); + + FPythonCommandEx PythonCommand; + PythonCommand.ExecutionMode = EPythonCommandExecutionMode::ExecuteStatement; + PythonCommand.Command = Input; + PythonScriptPlugin->ExecPythonCommandEx(PythonCommand); + + return true; +} + +bool FPythonREPLCommandExecutor::AllowHotKeyClose() const +{ + return false; +} + +bool FPythonREPLCommandExecutor::AllowMultiLine() const +{ + return true; +} + #if WITH_EDITOR class FPythonCommandMenuImpl : public IPythonCommandMenu { @@ -337,6 +403,7 @@ private: FPythonScriptPlugin::FPythonScriptPlugin() #if WITH_PYTHON : CmdExec(this) + , CmdREPLExec(this) , CmdMenu(nullptr) , bInitialized(false) , bHasTicked(false) @@ -350,11 +417,42 @@ bool FPythonScriptPlugin::IsPythonAvailable() const } bool FPythonScriptPlugin::ExecPythonCommand(const TCHAR* InPythonCommand) +{ + FPythonCommandEx PythonCommand; + PythonCommand.Command = InPythonCommand; + return ExecPythonCommandEx(PythonCommand); +} + +bool FPythonScriptPlugin::ExecPythonCommandEx(FPythonCommandEx& InOutPythonCommand) { #if WITH_PYTHON - return HandlePythonExecCommand(InPythonCommand); + if (InOutPythonCommand.ExecutionMode == EPythonCommandExecutionMode::ExecuteFile) + { + // We may have been passed literal code or a file + // To work out which, extract the first token and see if it's a .py file + // If it is, treat the remaining text as arguments to the file + // Otherwise, treat it as literal code + FString ExtractedFilename; + { + const TCHAR* Tmp = *InOutPythonCommand.Command; + ExtractedFilename = FParse::Token(Tmp, false); + } + if (FPaths::GetExtension(ExtractedFilename) == TEXT("py")) + { + return RunFile(*ExtractedFilename, *InOutPythonCommand.Command, InOutPythonCommand); + } + else + { + return RunString(InOutPythonCommand); + } + } + else + { + return RunString(InOutPythonCommand); + } #else // WITH_PYTHON - ensureAlwaysMsgf(false, TEXT("Python is not available!")); + InOutPythonCommand.CommandResult = TEXT("Python is not available!"); + ensureAlwaysMsgf(false, TEXT("%s"), *InOutPythonCommand.CommandResult); return false; #endif // WITH_PYTHON } @@ -374,11 +472,15 @@ void FPythonScriptPlugin::StartupModule() #if WITH_PYTHON InitializePython(); IModularFeatures::Get().RegisterModularFeature(IConsoleCommandExecutor::ModularFeatureName(), &CmdExec); + IModularFeatures::Get().RegisterModularFeature(IConsoleCommandExecutor::ModularFeatureName(), &CmdREPLExec); + + check(!RemoteExecution); + RemoteExecution = MakeUnique(this); #if WITH_EDITOR - check(CmdMenu == nullptr); - CmdMenu = new FPythonCommandMenuImpl(); - CmdMenu->OnStartupMenu(); + check(CmdMenu == nullptr); + CmdMenu = new FPythonCommandMenuImpl(); + CmdMenu->OnStartupMenu(); #endif // WITH_EDITOR FCoreDelegates::OnPreExit.AddRaw(this, &FPythonScriptPlugin::ShutdownPython); @@ -390,6 +492,8 @@ void FPythonScriptPlugin::ShutdownModule() #if WITH_PYTHON FCoreDelegates::OnPreExit.RemoveAll(this); + RemoteExecution.Reset(); + #if WITH_EDITOR check(CmdMenu); CmdMenu->OnShutdownMenu(); @@ -398,6 +502,7 @@ void FPythonScriptPlugin::ShutdownModule() #endif // WITH_EDITOR IModularFeatures::Get().UnregisterModularFeature(IConsoleCommandExecutor::ModularFeatureName(), &CmdExec); + IModularFeatures::Get().UnregisterModularFeature(IConsoleCommandExecutor::ModularFeatureName(), &CmdREPLExec); ShutdownPython(); #endif // WITH_PYTHON } @@ -407,7 +512,7 @@ bool FPythonScriptPlugin::Exec(UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& #if WITH_PYTHON if (FParse::Command(&Cmd, TEXT("PY"))) { - HandlePythonExecCommand(Cmd); + ExecPythonCommand(Cmd); return true; } #endif // WITH_PYTHON @@ -638,12 +743,13 @@ void FPythonScriptPlugin::Tick(const float InDeltaTime) const FString PotentialFilePath = PySysPath / TEXT("init_unreal.py"); if (FPaths::FileExists(PotentialFilePath)) { - RunFile(*PotentialFilePath, nullptr); + // Quote the path in case it contains spaces so that the token parsing will work as expected + ExecPythonCommand(*FString::Printf(TEXT("\"%s\""), *PotentialFilePath)); } } for (const FString& StartupScript : GetDefault()->StartupScripts) { - HandlePythonExecCommand(*StartupScript); + ExecPythonCommand(*StartupScript); } #if WITH_EDITOR @@ -652,9 +758,16 @@ void FPythonScriptPlugin::Tick(const float InDeltaTime) #endif // WITH_EDITOR } + RemoteExecution->Tick(InDeltaTime); + FPyWrapperTypeReinstancer::Get().ProcessPending(); } +void FPythonScriptPlugin::SyncRemoteExecutionToSettings() +{ + RemoteExecution->SyncToSettings(); +} + void FPythonScriptPlugin::ImportUnrealModule(const TCHAR* InModuleName) { const FString PythonModuleName = FString::Printf(TEXT("unreal_%s"), InModuleName); @@ -718,27 +831,6 @@ void FPythonScriptPlugin::ImportUnrealModule(const TCHAR* InModuleName) } } -bool FPythonScriptPlugin::HandlePythonExecCommand(const TCHAR* InPythonCommand) -{ - // We may have been passed literal code or a file - // To work out which, extract the first token and see if it's a .py file - // If it is, treat the remaining text as arguments to the file - // Otherwise, treat it as literal code - FString ExtractedFilename; - { - const TCHAR* Tmp = InPythonCommand; - ExtractedFilename = FParse::Token(Tmp, false); - } - if (FPaths::GetExtension(ExtractedFilename) == TEXT("py")) - { - return RunFile(*ExtractedFilename, InPythonCommand); - } - else - { - return RunString(InPythonCommand); - } -} - PyObject* FPythonScriptPlugin::EvalString(const TCHAR* InStr, const TCHAR* InContext, const int InMode) { return EvalString(InStr, InContext, InMode, PyConsoleGlobalDict, PyConsoleLocalDict); @@ -771,16 +863,41 @@ PyObject* FPythonScriptPlugin::EvalString(const TCHAR* InStr, const TCHAR* InCon return PyEval_EvalCode((PyUtil::FPyCodeObjectType*)PyCodeObj.Get(), InGlobalDict, InLocalDict); } -bool FPythonScriptPlugin::RunString(const TCHAR* InStr) +bool FPythonScriptPlugin::RunString(FPythonCommandEx& InOutPythonCommand) { // Execute Python code within this block { FPyScopedGIL GIL; + TGuardValue UnattendedScriptGuard(GIsRunningUnattendedScript, GIsRunningUnattendedScript || EnumHasAnyFlags(InOutPythonCommand.Flags, EPythonCommandFlags::Unattended)); - FPyObjectPtr PyResult = FPyObjectPtr::StealReference(EvalString(InStr, TEXT(""), Py_file_input)); - if (!PyResult) + int PyExecMode = 0; + switch (InOutPythonCommand.ExecutionMode) { - PyUtil::LogPythonError(); + case EPythonCommandExecutionMode::ExecuteFile: + PyExecMode = Py_file_input; + break; + case EPythonCommandExecutionMode::ExecuteStatement: + PyExecMode = Py_single_input; + break; + case EPythonCommandExecutionMode::EvaluateStatement: + PyExecMode = Py_eval_input; + break; + default: + checkf(false, TEXT("Invalid EPythonCommandExecutionMode!")); + break; + } + + FDelegateHandle LogCaptureHandle = PyCore::GetPythonLogCapture().AddLambda([&InOutPythonCommand](EPythonLogOutputType InLogType, const TCHAR* InLogString) { InOutPythonCommand.LogOutput.Add(FPythonLogOutputEntry{ InLogType, InLogString }); }); + FPyObjectPtr PyResult = FPyObjectPtr::StealReference(EvalString(*InOutPythonCommand.Command, TEXT(""), PyExecMode)); + PyCore::GetPythonLogCapture().Remove(LogCaptureHandle); + + if (PyResult) + { + InOutPythonCommand.CommandResult = PyUtil::PyObjectToUEStringRepr(PyResult); + } + else + { + InOutPythonCommand.CommandResult = PyUtil::LogPythonError(); return false; } } @@ -789,7 +906,7 @@ bool FPythonScriptPlugin::RunString(const TCHAR* InStr) return true; } -bool FPythonScriptPlugin::RunFile(const TCHAR* InFile, const TCHAR* InArgs) +bool FPythonScriptPlugin::RunFile(const TCHAR* InFile, const TCHAR* InArgs, FPythonCommandEx& InOutPythonCommand) { auto ResolveFilePath = [InFile]() -> FString { @@ -832,7 +949,8 @@ bool FPythonScriptPlugin::RunFile(const TCHAR* InFile, const TCHAR* InArgs) if (!bLoaded) { - UE_LOG(LogPython, Error, TEXT("Could not load Python file '%s' (resolved from '%s')"), *ResolvedFilePath, InFile); + InOutPythonCommand.CommandResult = FString::Printf(TEXT("Could not load Python file '%s' (resolved from '%s')"), *ResolvedFilePath, InFile); + UE_LOG(LogPython, Error, TEXT("%s"), *InOutPythonCommand.CommandResult); return false; } @@ -840,6 +958,7 @@ bool FPythonScriptPlugin::RunFile(const TCHAR* InFile, const TCHAR* InArgs) double ElapsedSeconds = 0.0; { FPyScopedGIL GIL; + TGuardValue UnattendedScriptGuard(GIsRunningUnattendedScript, GIsRunningUnattendedScript || EnumHasAnyFlags(InOutPythonCommand.Flags, EPythonCommandFlags::Unattended)); FPyObjectPtr PyFileGlobalDict = FPyObjectPtr::StealReference(PyDict_Copy(PyDefaultGlobalDict)); FPyObjectPtr PyFileLocalDict = PyFileGlobalDict; @@ -856,13 +975,18 @@ bool FPythonScriptPlugin::RunFile(const TCHAR* InFile, const TCHAR* InArgs) FScopedDurationTimer Timer(ElapsedSeconds); FPythonScopedArgv ScopedArgv(InArgs); - // We can't just use PyRun_File here as Python isn't always built against the same version of the CRT as UE4, so we get a crash at the CRT layer - PyResult = FPyObjectPtr::StealReference(EvalString(*FileStr, *ResolvedFilePath, Py_file_input, PyFileGlobalDict, PyFileLocalDict)); + FDelegateHandle LogCaptureHandle = PyCore::GetPythonLogCapture().AddLambda([&InOutPythonCommand](EPythonLogOutputType InLogType, const TCHAR* InLogString) { InOutPythonCommand.LogOutput.Add(FPythonLogOutputEntry{ InLogType, InLogString }); }); + PyResult = FPyObjectPtr::StealReference(EvalString(*FileStr, *ResolvedFilePath, Py_file_input, PyFileGlobalDict, PyFileLocalDict)); // We can't just use PyRun_File here as Python isn't always built against the same version of the CRT as UE4, so we get a crash at the CRT layer + PyCore::GetPythonLogCapture().Remove(LogCaptureHandle); } - if (!PyResult) + if (PyResult) { - PyUtil::LogPythonError(); + InOutPythonCommand.CommandResult = PyUtil::PyObjectToUEStringRepr(PyResult); + } + else + { + InOutPythonCommand.CommandResult = PyUtil::LogPythonError(); return false; } } diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPlugin.h b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPlugin.h index 0c964d0f8523..7efc40e48bae 100644 --- a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPlugin.h +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPlugin.h @@ -11,6 +11,7 @@ #include "Framework/Commands/InputChord.h" class FPythonScriptPlugin; +class FPythonScriptRemoteExecution; #if WITH_PYTHON @@ -20,7 +21,7 @@ class FPythonScriptPlugin; class FPythonCommandExecutor : public IConsoleCommandExecutor { public: - FPythonCommandExecutor(FPythonScriptPlugin* InPythonScriptPlugin); + FPythonCommandExecutor(IPythonScriptPlugin* InPythonScriptPlugin); static FName StaticName(); virtual FName GetName() const override; @@ -37,7 +38,33 @@ public: return FInputChord(); } private: - FPythonScriptPlugin* PythonScriptPlugin; + IPythonScriptPlugin* PythonScriptPlugin; +}; + +/** + * Executor for "Python (REPL)" commands + */ +class FPythonREPLCommandExecutor : public IConsoleCommandExecutor +{ +public: + FPythonREPLCommandExecutor(IPythonScriptPlugin* InPythonScriptPlugin); + + static FName StaticName(); + virtual FName GetName() const override; + virtual FText GetDisplayName() const override; + virtual FText GetDescription() const override; + virtual FText GetHintText() const override; + virtual void GetAutoCompleteSuggestions(const TCHAR* Input, TArray& Out) override; + virtual void GetExecHistory(TArray& Out) override; + virtual bool Exec(const TCHAR* Input) override; + virtual bool AllowHotKeyClose() const override; + virtual bool AllowMultiLine() const override; + virtual FInputChord GetHotKey() const override + { + return FInputChord(); + } +private: + IPythonScriptPlugin* PythonScriptPlugin; }; /** @@ -68,6 +95,7 @@ public: //~ IPythonScriptPlugin interface virtual bool IsPythonAvailable() const override; virtual bool ExecPythonCommand(const TCHAR* InPythonCommand) override; + virtual bool ExecPythonCommandEx(FPythonCommandEx& InOutPythonCommand) override; virtual FSimpleMulticastDelegate& OnPythonInitialized() override; virtual FSimpleMulticastDelegate& OnPythonShutdown() override; @@ -79,20 +107,24 @@ public: virtual bool Exec(UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar) override; #if WITH_PYTHON + /** Sync the remote execution environment to the current settings, starting or stopping it as required */ + void SyncRemoteExecutionToSettings(); + /** * Import the given module into the "unreal" package. * This function will take the given name and attempt to import either "unreal_{name}" or "_unreal_{name}" into the "unreal" package as "unreal.{name}". */ void ImportUnrealModule(const TCHAR* InModuleName); - bool HandlePythonExecCommand(const TCHAR* InPythonCommand); - + /** Evaluate/Execute a Python string, and return the result */ PyObject* EvalString(const TCHAR* InStr, const TCHAR* InContext, const int InMode); PyObject* EvalString(const TCHAR* InStr, const TCHAR* InContext, const int InMode, PyObject* InGlobalDict, PyObject* InLocalDict); - bool RunString(const TCHAR* InStr); + /** Run literal Python script */ + bool RunString(FPythonCommandEx& InOutPythonCommand); - bool RunFile(const TCHAR* InFile, const TCHAR* InArgs); + /** Run a Python file */ + bool RunFile(const TCHAR* InFile, const TCHAR* InArgs, FPythonCommandEx& InOutPythonCommand); #endif // WITH_PYTHON private: @@ -119,7 +151,9 @@ private: void OnPrepareToCleanseEditorObject(UObject* InObject); #endif // WITH_EDITOR + TUniquePtr RemoteExecution; FPythonCommandExecutor CmdExec; + FPythonREPLCommandExecutor CmdREPLExec; IPythonCommandMenu* CmdMenu; FDelegateHandle TickHandle; FDelegateHandle ModuleDelayedHandle; diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPluginSettings.cpp b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPluginSettings.cpp index e93b635112b2..a91ba8963f61 100644 --- a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPluginSettings.cpp +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPluginSettings.cpp @@ -1,6 +1,7 @@ // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. #include "PythonScriptPluginSettings.h" +#include "PythonScriptPlugin.h" #define LOCTEXT_NAMESPACE "PythonScriptPlugin" @@ -8,6 +9,53 @@ UPythonScriptPluginSettings::UPythonScriptPluginSettings() { CategoryName = TEXT("Plugins"); SectionName = TEXT("Python"); + + RemoteExecutionMulticastGroupEndpoint = TEXT("239.0.0.1:6766"); + RemoteExecutionMulticastBindAddress = TEXT("0.0.0.0"); + RemoteExecutionSendBufferSizeBytes = 2 * 1024 * 1024; + RemoteExecutionReceiveBufferSizeBytes = 2 * 1024 * 1024; + RemoteExecutionMulticastTtl = 0; +} + +#if WITH_EDITOR + +bool UPythonScriptPluginSettings::CanEditChange(const UProperty* InProperty) const +{ + bool bCanEditChange = Super::CanEditChange(InProperty); + + if (bCanEditChange && InProperty) + { + if (InProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UPythonScriptPluginSettings, RemoteExecutionMulticastGroupEndpoint) || + InProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UPythonScriptPluginSettings, RemoteExecutionMulticastBindAddress) || + InProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UPythonScriptPluginSettings, RemoteExecutionSendBufferSizeBytes) || + InProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UPythonScriptPluginSettings, RemoteExecutionReceiveBufferSizeBytes) || + InProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UPythonScriptPluginSettings, RemoteExecutionMulticastTtl) + ) + { + bCanEditChange &= bRemoteExecution; + } + } + + return bCanEditChange; +} + +void UPythonScriptPluginSettings::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) +{ + Super::PostEditChangeProperty(PropertyChangedEvent); + + if (PropertyChangedEvent.MemberProperty) + { + if (PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UPythonScriptPluginSettings, bRemoteExecution) || + PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UPythonScriptPluginSettings, RemoteExecutionMulticastGroupEndpoint) || + PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UPythonScriptPluginSettings, RemoteExecutionMulticastBindAddress) || + PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UPythonScriptPluginSettings, RemoteExecutionSendBufferSizeBytes) || + PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UPythonScriptPluginSettings, RemoteExecutionReceiveBufferSizeBytes) || + PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UPythonScriptPluginSettings, RemoteExecutionMulticastTtl) + ) + { + FPythonScriptPlugin::Get()->SyncRemoteExecutionToSettings(); + } + } } FText UPythonScriptPluginSettings::GetSectionText() const @@ -15,4 +63,7 @@ FText UPythonScriptPluginSettings::GetSectionText() const return LOCTEXT("SettingsDisplayName", "Python"); } +#endif // WITH_EDITOR + #undef LOCTEXT_NAMESPACE + diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPluginSettings.h b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPluginSettings.h index 05b17e1cd318..c57aba29531f 100644 --- a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPluginSettings.h +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPluginSettings.h @@ -19,6 +19,10 @@ public: UPythonScriptPluginSettings(); #if WITH_EDITOR + //~ UObject interface + virtual bool CanEditChange(const UProperty* InProperty) const override; + virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override; + //~ UDeveloperSettings interface virtual FText GetSectionText() const override; #endif @@ -34,4 +38,28 @@ public: /** Should Developer Mode be enabled on the Python interpreter (will enable extra warnings (eg, for deprecated code), and enable stub code generation for use with external IDEs). */ UPROPERTY(config, EditAnywhere, Category=Python, meta=(ConfigRestartRequired=true)) bool bDeveloperMode; + + /** Should remote Python execution be enabled? */ + UPROPERTY(config, EditAnywhere, Category=PythonRemoteExecution, meta=(DisplayName="Enable Remote Execution?")) + bool bRemoteExecution; + + /** The multicast group endpoint (in the form of IP_ADDRESS:PORT_NUMBER) that the UDP multicast socket should join */ + UPROPERTY(config, EditAnywhere, Category=PythonRemoteExecution, AdvancedDisplay, meta=(DisplayName="Multicast Group Endpoint")) + FString RemoteExecutionMulticastGroupEndpoint; + + /** The adapter address that the UDP multicast socket should bind to, or 0.0.0.0 to bind to all adapters */ + UPROPERTY(config, EditAnywhere, Category=PythonRemoteExecution, AdvancedDisplay, meta=(DisplayName="Multicast Bind Address")) + FString RemoteExecutionMulticastBindAddress; + + /** Size of the send buffer for the remote endpoint connection */ + UPROPERTY(config, EditAnywhere, Category=PythonRemoteExecution, AdvancedDisplay, meta=(DisplayName="Send Buffer Size", Units="Bytes")) + int32 RemoteExecutionSendBufferSizeBytes; + + /** Size of the receive buffer for the remote endpoint connection */ + UPROPERTY(config, EditAnywhere, Category=PythonRemoteExecution, AdvancedDisplay, meta=(DisplayName="Receive Buffer Size", Units="Bytes")) + int32 RemoteExecutionReceiveBufferSizeBytes; + + /** The TTL that the UDP multicast socket should use (0 is limited to the local host, 1 is limited to the local subnet) */ + UPROPERTY(config, EditAnywhere, Category=PythonRemoteExecution, AdvancedDisplay, meta=(DisplayName="Multicast Time-To-Live")) + uint8 RemoteExecutionMulticastTtl; }; diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptRemoteExecution.cpp b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptRemoteExecution.cpp new file mode 100644 index 000000000000..6b3c56fb0e92 --- /dev/null +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptRemoteExecution.cpp @@ -0,0 +1,799 @@ +// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. + +#include "PythonScriptRemoteExecution.h" +#include "IPythonScriptPlugin.h" +#include "PythonScriptPluginSettings.h" + +#include "Misc/App.h" +#include "Misc/Paths.h" +#include "Misc/EngineVersion.h" +#include "Logging/LogMacros.h" + +#include "Sockets.h" +#include "Common/TcpSocketBuilder.h" +#include "Common/UdpSocketBuilder.h" + +#include "Dom/JsonValue.h" +#include "Dom/JsonObject.h" +#include "Serialization/JsonSerializer.h" +#include "Policies/CondensedJsonPrintPolicy.h" + +#define LOCTEXT_NAMESPACE "PythonScriptRemoteExecution" + +#if WITH_PYTHON + +/** + * Remote Execution protocol definition. + * + * Messages are a UTF-8 encoded JSON object with the following layout: + * { + * "version": 1, // Required - Integer - Protocol version number (currently 1) + * "magic": "ue_py", // Required - String - Protocol magic identifier (currently "ue_py") + * "type": "...", // Required - String - Identifier for the message type (see below) + * "source": "...", // Required - String - Unique identifier of the node that sent the message (typically a GUID) + * "dest": "...", // Optional - String - Unique identifier of the node that should receive the message (typically a GUID) + * "data": "..." // Optional - Any - Message specific payload data (see below) + * } + * + * Message types: + * "ping" (UDP) - Service discovery request + * + * "pong" (UDP) - Service discovery response + * "dest" - Required - String - The node that requested the discovery + * "data" - Required - Object - Payload data: + * { + * "user": "...", // Required - String - The name of the user that owns the engine instance + * "machine": "...", // Required - String - The name of the machine that owns the engine instance + * "engine_version": "...", // Required - String - The version number of the engine + * "engine_root": "...", // Required - String - The absolute on-disk root of the engine + * "project_root: "...", // Optional - String - The absolute on-disk root of the project (if a project is loaded) + * "project_name": "..." // Optional - String - The name of the project (if a project is loaded) + * } + * + * "open_connection" (UDP) - Open a TCP command connection with the requested server + * "dest" - Required - String - The node that should open a connection to the server + * "data" - Required - Object - Payload data: + * { + * "command_ip": "...", // Required - String - The IP address of the TCP command server + * "command_port": 0 // Required - Integer - The port of the TCP command server + * } + * + * "close_connection" (UDP) - Close any active TCP command connection + * "dest" - Required - String - The node that should close its connection to the server + * + * "command" (TCP) - Execute a remote Python command + * "dest" - Required - String - The node that should execute the command + * "data" - Required - Object - Payload data: + * { + * "command": "...", // Required - String - The command to execute + * "unattended": True, // Required - Boolean - Whether to run the command in "unattended" mode (suppressing some UI) + * "exec_mode": "..." // Required - String - The execution mode to use as a string value (see EPythonCommandExecutionMode, and LexToString, LexFromString) + * } + * + * "command_result" (TCP) - Result of executing a remote Python command + * "dest" - Required - String - The node that should receive the result + * "data" - Required - Object - Payload data: + * { + * "success": True, // Required - Boolean - Whether the command executed successfully (without raising an uncaught exception) + * "command": "...", // Required - String - The command that was executed + * "result": "...", // Required - String - The result of running the command + * "output": [{ // Required - List - The log output from running the command + * "type: "...", // Required - String - The type of output (Info, Warning, or Error) + * "output": "..." // Required - String - The actual log output + * }] + * } + */ + +DEFINE_LOG_CATEGORY_STATIC(LogPythonRemoteExecution, Log, All); + +struct FPythonScriptRemoteExecutionMessage; + +namespace PythonScriptRemoteExecutionUtil +{ + const int32 ProtocolVersion = 1; + const FString ProtocolMagic = TEXT("ue_py"); + const FString TypePing = TEXT("ping"); + const FString TypePong = TEXT("pong"); + const FString TypeOpenConnection = TEXT("open_connection"); + const FString TypeCloseConnection = TEXT("close_connection"); + const FString TypeCommand = TEXT("command"); + const FString TypeCommandResult = TEXT("command_result"); + + bool SerializeJsonObject(const TSharedRef& InJsonObject, FString& OutJsonString, FText* OutError = nullptr); + bool DeserializeJsonObject(const FString& InJsonString, TSharedPtr& OutJsonObject, FText* OutError = nullptr); + bool ParseMessageData(const char* InMessageData, FPythonScriptRemoteExecutionMessage& OutMessage); + bool ParseMessageData(const TCHAR* InMessageData, FPythonScriptRemoteExecutionMessage& OutMessage); + bool WriteMessageData(const FPythonScriptRemoteExecutionMessage& InMessage, FString& OutMessageData); + void DestroySocket(ISocketSubsystem* InSocketSubsystem, FSocket*& InOutSocket); +} + +struct FPythonScriptRemoteExecutionMessage +{ + FPythonScriptRemoteExecutionMessage() = default; + + FPythonScriptRemoteExecutionMessage(FString InType, FString InSource, FString InDest = FString(), TSharedPtr InData = nullptr) + : Type(MoveTemp(InType)) + , Source(MoveTemp(InSource)) + , Dest(MoveTemp(InDest)) + , Data(MoveTemp(InData)) + { + } + + bool PassesReceiveFilter(const FString& InNodeId) const + { + return !Source.Equals(InNodeId) && (Dest.IsEmpty() || Dest.Equals(InNodeId)); + } + + bool ToJsonObject(TSharedPtr& OutJsonObject, FText* OutError = nullptr) const + { + // Validate required fields + if (Type.IsEmpty()) + { + if (OutError) + { + *OutError = LOCTEXT("Message.ToJson.Error.TypeCannotBeEmpty", "'type' cannot be empty!"); + } + return false; + } + if (Source.IsEmpty()) + { + if (OutError) + { + *OutError = LOCTEXT("Message.ToJson.Error.SourceCannotBeEmpty", "'source' cannot be empty!"); + } + return false; + } + + OutJsonObject = MakeShared(); + + // Write required protocol version information + OutJsonObject->SetNumberField(TEXT("version"), PythonScriptRemoteExecutionUtil::ProtocolVersion); + OutJsonObject->SetStringField(TEXT("magic"), PythonScriptRemoteExecutionUtil::ProtocolMagic); + + // Write required fields + OutJsonObject->SetStringField(TEXT("type"), Type); + OutJsonObject->SetStringField(TEXT("source"), Source); + + // Write optional fields + if (!Dest.IsEmpty()) + { + OutJsonObject->SetStringField(TEXT("dest"), Dest); + } + if (Data.IsValid()) + { + OutJsonObject->SetField(TEXT("data"), Data); + } + + return true; + } + + bool ToJsonString(FString& OutJsonString, FText* OutError = nullptr) const + { + TSharedPtr JsonObject; + return ToJsonObject(JsonObject, OutError) && PythonScriptRemoteExecutionUtil::SerializeJsonObject(JsonObject.ToSharedRef(), OutJsonString, OutError); + } + + bool FromJsonObject(const TSharedRef& InJsonObject, FText* OutError = nullptr) + { + // Read and validate required protocol version information + { + int32 LocalVersion = 0; + if (!InJsonObject->TryGetNumberField(TEXT("version"), LocalVersion) || LocalVersion != PythonScriptRemoteExecutionUtil::ProtocolVersion) + { + if (OutError) + { + *OutError = FText::Format(LOCTEXT("Message.FromJson.Error.MissingOrInvalidVersion", "'version' is missing or incorrect (got {0}, expected {1})!"), LocalVersion, PythonScriptRemoteExecutionUtil::ProtocolVersion); + } + return false; + } + + FString LocalMagic; + if (!InJsonObject->TryGetStringField(TEXT("magic"), LocalMagic) || !LocalMagic.Equals(PythonScriptRemoteExecutionUtil::ProtocolMagic)) + { + if (OutError) + { + *OutError = FText::Format(LOCTEXT("Message.FromJson.Error.MissingOrInvalidMagic", "'magic' is missing or incorrect (got '{0}', expected '{1}')!"), FText::AsCultureInvariant(LocalMagic), FText::AsCultureInvariant(PythonScriptRemoteExecutionUtil::ProtocolMagic)); + } + return false; + } + } + + // Read required fields + { + FString LocalType; + if (!InJsonObject->TryGetStringField(TEXT("type"), LocalType)) + { + if (OutError) + { + *OutError = LOCTEXT("Message.FromJson.Error.MissingType", "'type' is missing!"); + } + return false; + } + + FString LocalSource; + if (!InJsonObject->TryGetStringField(TEXT("source"), LocalSource)) + { + if (OutError) + { + *OutError = LOCTEXT("Message.FromJson.Error.MissingSource", "'source' is missing!"); + } + return false; + } + + Type = MoveTemp(LocalType); + Source = MoveTemp(LocalSource); + } + + // Read optional fields + InJsonObject->TryGetStringField(TEXT("dest"), Dest); + Data = InJsonObject->TryGetField(TEXT("data")); + + return true; + } + + bool FromJsonString(const FString& InJsonString, FText* OutError = nullptr) + { + TSharedPtr JsonObject; + return PythonScriptRemoteExecutionUtil::DeserializeJsonObject(InJsonString, JsonObject, OutError) && FromJsonObject(JsonObject.ToSharedRef(), OutError); + } + + /** Identifier for the message type */ + FString Type; + + /** Unique identifier of the node that sent the message (typically a GUID) */ + FString Source; + + /** Unique identifier of the node that should receive the message (typically a GUID) */ + FString Dest; + + /** Message specific payload data */ + TSharedPtr Data; +}; + +class FPythonScriptRemoteExecutionBroadcastConnection +{ +public: + FPythonScriptRemoteExecutionBroadcastConnection(FPythonScriptRemoteExecution* InRemoteExecution) + : RemoteExecution(InRemoteExecution) + , BroadcastSocket(nullptr) + { + check(RemoteExecution); + + NodeInfo = MakeShared(); + NodeInfo->SetStringField(TEXT("user"), FApp::GetSessionOwner()); + NodeInfo->SetStringField(TEXT("machine"), FPlatformProcess::ComputerName()); + NodeInfo->SetStringField(TEXT("engine_version"), FEngineVersion::Current().ToString()); + NodeInfo->SetStringField(TEXT("engine_root"), FPaths::ConvertRelativePathToFull(FPaths::EngineDir())); + if (FApp::HasProjectName()) + { + NodeInfo->SetStringField(TEXT("project_root"), FPaths::ConvertRelativePathToFull(FPaths::ProjectDir())); + NodeInfo->SetStringField(TEXT("project_name"), FApp::GetProjectName()); + } + + const UPythonScriptPluginSettings* PythonScriptPluginSettings = GetDefault(); + + bool bValidEndpointAddresses = true; + + FIPv4Endpoint MulticastGroupEndpoint(FIPv4Address::Any, 0); + if (!FIPv4Endpoint::Parse(PythonScriptPluginSettings->RemoteExecutionMulticastGroupEndpoint, MulticastGroupEndpoint)) + { + bValidEndpointAddresses = false; + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to parse multicast group endpoint '%s'. Remote execution will be disabled!"), *PythonScriptPluginSettings->RemoteExecutionMulticastGroupEndpoint); + } + + FIPv4Address MulticastBindAddress = FIPv4Address::Any; + if (!FIPv4Address::Parse(PythonScriptPluginSettings->RemoteExecutionMulticastBindAddress, MulticastBindAddress)) + { + bValidEndpointAddresses = false; + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to parse multicast bind address '%s'. Remote execution will be disabled!"), *PythonScriptPluginSettings->RemoteExecutionMulticastBindAddress); + } + + if (bValidEndpointAddresses) + { + BroadcastGroupAddr = MulticastGroupEndpoint.ToInternetAddr(); + + BroadcastSocket = FUdpSocketBuilder(TEXT("PythonRemoteExecutionBroadcastSocket")) + .AsReusable() + .BoundToAddress(MulticastBindAddress) + .BoundToPort(MulticastGroupEndpoint.Port) +#if PLATFORM_SUPPORTS_UDP_MULTICAST_GROUP + .JoinedToGroup(MulticastGroupEndpoint.Address) + .WithMulticastLoopback() +#endif + .WithSendBufferSize(PythonScriptPluginSettings->RemoteExecutionSendBufferSizeBytes) + .WithReceiveBufferSize(PythonScriptPluginSettings->RemoteExecutionReceiveBufferSizeBytes) + .WithMulticastTtl(PythonScriptPluginSettings->RemoteExecutionMulticastTtl); + } + } + + ~FPythonScriptRemoteExecutionBroadcastConnection() + { + PythonScriptRemoteExecutionUtil::DestroySocket(RemoteExecution->SocketSubsystem, BroadcastSocket); + } + + bool HasConnection() const + { + return BroadcastSocket != nullptr; + } + + void Tick(const float InDeltaTime) + { + if (BroadcastSocket) + { + uint32 PendingDataSize = 0; + while (BroadcastSocket->HasPendingData(PendingDataSize) && PendingDataSize > 0) + { + TArray> ReceivedData; + ReceivedData.SetNumZeroed(PendingDataSize + 1); + + int32 BytesRead = 0; + if (BroadcastSocket->Recv(ReceivedData.GetData(), ReceivedData.Num(), BytesRead) && BytesRead > 0) + { + ReceivedData.Last() = 0; // Ensure null terminator + + FPythonScriptRemoteExecutionMessage Message; + if (PythonScriptRemoteExecutionUtil::ParseMessageData((char*)ReceivedData.GetData(), Message)) + { + HandleMessage(Message); + } + } + } + } + } + +private: + void HandleMessage(const FPythonScriptRemoteExecutionMessage& InMessage) + { + if (!InMessage.PassesReceiveFilter(RemoteExecution->NodeId)) + { + return; + } + + if (InMessage.Type.Equals(PythonScriptRemoteExecutionUtil::TypePing)) + { + BroadcastPongMessage(InMessage.Source); + return; + } + + if (InMessage.Type.Equals(PythonScriptRemoteExecutionUtil::TypeOpenConnection)) + { + HandleOpenConnectionMessage(InMessage); + return; + } + + if (InMessage.Type.Equals(PythonScriptRemoteExecutionUtil::TypeCloseConnection)) + { + HandleCloseConnectionMessage(InMessage); + return; + } + + UE_LOG(LogPythonRemoteExecution, VeryVerbose, TEXT("Unhandled remote execution message type '%s'"), *InMessage.Type); + } + + void HandleOpenConnectionMessage(const FPythonScriptRemoteExecutionMessage& InMessage) + { + const TSharedPtr* ConnectionData = nullptr; + if (InMessage.Data && InMessage.Data->TryGetObject(ConnectionData) && *ConnectionData) + { + FIPv4Address CommandIp; + { + FString CommandIpString; + if (!(*ConnectionData)->TryGetStringField(TEXT("command_ip"), CommandIpString)) + { + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to find required data field 'command_ip' (string) for the 'open_connection' message!")); + return; + } + if (!FIPv4Address::Parse(CommandIpString, CommandIp)) + { + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to parse command address '%s'!"), *CommandIpString); + return; + } + } + + uint32 CommandPort = 0; + if (!(*ConnectionData)->TryGetNumberField(TEXT("command_port"), CommandPort)) + { + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to find required data field 'command_port' (integer) for the 'open_connection' message!")); + return; + } + + RemoteExecution->OpenCommandConnection(InMessage.Source, FIPv4Endpoint(CommandIp, (uint16)CommandPort)); + } + } + + void HandleCloseConnectionMessage(const FPythonScriptRemoteExecutionMessage& InMessage) + { + RemoteExecution->CloseCommandConnection(InMessage.Source); + } + + void BroadcastMessage(const FPythonScriptRemoteExecutionMessage& InMessage) + { + FString MessageStr; + FText WriteErrorMsg; + if (!InMessage.ToJsonString(MessageStr, &WriteErrorMsg)) + { + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to write remote execution message: %s"), *WriteErrorMsg.ToString()); + return; + } + BroadcastMessage(TCHAR_TO_UTF8(*MessageStr)); + } + + void BroadcastMessage(const char* InMessage) + { + check(BroadcastSocket); + + int32 BytesSent = 0; + BroadcastSocket->SendTo((uint8*)InMessage, FCStringAnsi::Strlen(InMessage), BytesSent, *BroadcastGroupAddr); + } + + void BroadcastPongMessage(const FString& InDestinationNodeId) + { + BroadcastMessage(FPythonScriptRemoteExecutionMessage(PythonScriptRemoteExecutionUtil::TypePong, RemoteExecution->NodeId, InDestinationNodeId, MakeShared(NodeInfo))); + } + + /** Owner remote execution instance */ + FPythonScriptRemoteExecution* RemoteExecution; + + /** The information about this node instance (used in "pong" messages) */ + TSharedPtr NodeInfo; + + /** The address of the UDP multicast group used for broadcast */ + TSharedPtr BroadcastGroupAddr; + + /** The UDP multicast socket used for broadcast */ + FSocket* BroadcastSocket; +}; + +class FPythonScriptRemoteExecutionCommandConnection +{ +public: + FPythonScriptRemoteExecutionCommandConnection(FPythonScriptRemoteExecution* InRemoteExecution, const FString& InRemoteNodeId, const FIPv4Endpoint& InCommandEndpoint) + : RemoteExecution(InRemoteExecution) + , RemoteNodeId(InRemoteNodeId) + , CommandEndpoint(InCommandEndpoint) + , CommandChannelSocket(nullptr) + { + check(RemoteExecution); + + const UPythonScriptPluginSettings* PythonScriptPluginSettings = GetDefault(); + + CommandChannelSocket = FTcpSocketBuilder(TEXT("PythonRemoteExecutionCommandSocket")) + .WithSendBufferSize(PythonScriptPluginSettings->RemoteExecutionSendBufferSizeBytes) + .WithReceiveBufferSize(PythonScriptPluginSettings->RemoteExecutionReceiveBufferSizeBytes); + + if (!CommandChannelSocket->Connect(*CommandEndpoint.ToInternetAddr())) + { + PythonScriptRemoteExecutionUtil::DestroySocket(RemoteExecution->SocketSubsystem, CommandChannelSocket); + } + } + + ~FPythonScriptRemoteExecutionCommandConnection() + { + PythonScriptRemoteExecutionUtil::DestroySocket(RemoteExecution->SocketSubsystem, CommandChannelSocket); + } + + bool HasConnection() const + { + return CommandChannelSocket != nullptr; + } + + bool IsConnectedTo(const FString& InRemoteNodeId) + { + return RemoteNodeId.Equals(InRemoteNodeId); + } + + bool IsConnectedTo(const FIPv4Endpoint& InCommandEndpoint) + { + return CommandEndpoint == InCommandEndpoint; + } + + bool IsConnectedTo(const FString& InRemoteNodeId, const FIPv4Endpoint& InCommandEndpoint) + { + return IsConnectedTo(InRemoteNodeId) + && IsConnectedTo(InCommandEndpoint); + } + + void Tick(const float InDeltaTime) + { + if (CommandChannelSocket) + { + uint32 PendingDataSize = 0; + while (CommandChannelSocket->HasPendingData(PendingDataSize) && PendingDataSize > 0) + { + TArray> ReceivedData; + ReceivedData.SetNumZeroed(PendingDataSize + 1); + + int32 BytesRead = 0; + if (CommandChannelSocket->Recv(ReceivedData.GetData(), ReceivedData.Num(), BytesRead) && BytesRead > 0) + { + ReceivedData.Last() = 0; // Ensure null terminator + + FPythonScriptRemoteExecutionMessage Message; + if (PythonScriptRemoteExecutionUtil::ParseMessageData((char*)ReceivedData.GetData(), Message)) + { + HandleMessage(Message); + } + } + } + } + } + +private: + void HandleMessage(const FPythonScriptRemoteExecutionMessage& InMessage) + { + if (!InMessage.PassesReceiveFilter(RemoteExecution->NodeId)) + { + return; + } + + if (InMessage.Type.Equals(PythonScriptRemoteExecutionUtil::TypeCommand)) + { + HandleCommandMessage(InMessage); + return; + } + + UE_LOG(LogPythonRemoteExecution, VeryVerbose, TEXT("Unhandled remote execution message type '%s'"), *InMessage.Type); + } + + void HandleCommandMessage(const FPythonScriptRemoteExecutionMessage& InMessage) + { + const TSharedPtr* CommandData = nullptr; + if (InMessage.Data && InMessage.Data->TryGetObject(CommandData) && *CommandData) + { + FPythonCommandEx PythonCommand; + + if (!(*CommandData)->TryGetStringField(TEXT("command"), PythonCommand.Command)) + { + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to find required data field 'command' (string) for the 'command' message!")); + return; + } + + { + bool bUnattended = false; + if (!(*CommandData)->TryGetBoolField(TEXT("unattended"), bUnattended)) + { + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to find required data field 'unattended' (bool) for the 'command' message!")); + return; + } + PythonCommand.Flags |= bUnattended ? EPythonCommandFlags::Unattended : EPythonCommandFlags::None; + } + + { + FString ExecModeString; + if (!(*CommandData)->TryGetStringField(TEXT("exec_mode"), ExecModeString)) + { + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to find required data field 'exec_mode' (string) for the 'command' message!")); + return; + } + if (!LexTryParseString(PythonCommand.ExecutionMode, *ExecModeString)) + { + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to find parse execution mode '%s'!"), *ExecModeString); + return; + } + } + + { + const bool bCommandSuccess = RemoteExecution->PythonScriptPlugin->ExecPythonCommandEx(PythonCommand); + SendCommandResultMessage(InMessage.Source, bCommandSuccess, PythonCommand.Command, PythonCommand.CommandResult, PythonCommand.LogOutput); + } + } + } + + void SendMessage(const FPythonScriptRemoteExecutionMessage& InMessage) + { + FString MessageStr; + FText WriteErrorMsg; + if (!InMessage.ToJsonString(MessageStr, &WriteErrorMsg)) + { + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to write remote execution message: %s"), *WriteErrorMsg.ToString()); + return; + } + SendMessage(TCHAR_TO_UTF8(*MessageStr)); + } + + void SendMessage(const char* InMessage) + { + check(CommandChannelSocket); + + int32 BytesSent = 0; + CommandChannelSocket->Send((uint8*)InMessage, FCStringAnsi::Strlen(InMessage), BytesSent); + } + + void SendCommandResultMessage(const FString& InDestinationNodeId, const bool bSuccess, const FString& InCommand, const FString& InResult, const TArray& InLogOutput) + { + TArray> JsonLogOutput; + for (const FPythonLogOutputEntry& LogEntry : InLogOutput) + { + TSharedRef JsonLogEntry = MakeShared(); + JsonLogEntry->SetStringField(TEXT("type"), LexToString(LogEntry.Type)); + JsonLogEntry->SetStringField(TEXT("output"), LogEntry.Output); + JsonLogOutput.Add(MakeShared(JsonLogEntry)); + } + + TSharedRef ResultInfo = MakeShared(); + ResultInfo->SetBoolField(TEXT("success"), bSuccess); + ResultInfo->SetStringField(TEXT("command"), InCommand); + ResultInfo->SetStringField(TEXT("result"), InResult); + ResultInfo->SetArrayField(TEXT("output"), JsonLogOutput); + + SendMessage(FPythonScriptRemoteExecutionMessage(PythonScriptRemoteExecutionUtil::TypeCommandResult, RemoteExecution->NodeId, InDestinationNodeId, MakeShared(ResultInfo))); + } + + /** Owner remote execution instance */ + FPythonScriptRemoteExecution* RemoteExecution; + + /** The ID of the remote node that we connected to */ + FString RemoteNodeId; + + /** Endpoint that this command channel should be connected to */ + FIPv4Endpoint CommandEndpoint; + + /** The TCP socket used to handle command requests */ + FSocket* CommandChannelSocket; +}; + +FPythonScriptRemoteExecution::FPythonScriptRemoteExecution(IPythonScriptPlugin* InPythonScriptPlugin) + : PythonScriptPlugin(InPythonScriptPlugin) + , SocketSubsystem(ISocketSubsystem::Get()) + , NodeId(FApp::GetInstanceId().ToString()) +{ + check(PythonScriptPlugin); + check(SocketSubsystem); + + if (GetDefault()->bRemoteExecution) + { + Start(); + } +} + +FPythonScriptRemoteExecution::~FPythonScriptRemoteExecution() +{ + Stop(); +} + +bool FPythonScriptRemoteExecution::Start() +{ + Stop(); + + BroadcastConnection = MakeUnique(this); + if (!BroadcastConnection->HasConnection()) + { + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to open remote execution broadcast channel! Check your settings and the output log for more information.")); + BroadcastConnection.Reset(); + } + + return BroadcastConnection.IsValid(); +} + +void FPythonScriptRemoteExecution::Stop() +{ + CommandConnection.Reset(); + BroadcastConnection.Reset(); +} + +void FPythonScriptRemoteExecution::SyncToSettings() +{ + Stop(); + + if (GetDefault()->bRemoteExecution) + { + Start(); + } +} + +void FPythonScriptRemoteExecution::Tick(const float InDeltaTime) +{ + if (CommandConnection) + { + CommandConnection->Tick(InDeltaTime); + } + + if (BroadcastConnection) + { + BroadcastConnection->Tick(InDeltaTime); + } +} + +void FPythonScriptRemoteExecution::OpenCommandConnection(const FString& InRemoteNodeId, const FIPv4Endpoint& InCommandEndpoint) +{ + if (!CommandConnection || !CommandConnection->IsConnectedTo(InRemoteNodeId, InCommandEndpoint)) + { + CommandConnection = MakeUnique(this, InRemoteNodeId, InCommandEndpoint); + if (!CommandConnection->HasConnection()) + { + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to open remote execution command channel to '%s' (%s)!"), *InRemoteNodeId, *InCommandEndpoint.ToString()); + CommandConnection.Reset(); + } + } +} + +void FPythonScriptRemoteExecution::CloseCommandConnection(const FString& InRemoteNodeId) +{ + if (CommandConnection && CommandConnection->IsConnectedTo(InRemoteNodeId)) + { + CommandConnection.Reset(); + } +} + +namespace PythonScriptRemoteExecutionUtil +{ + bool SerializeJsonObject(const TSharedRef& InJsonObject, FString& OutJsonString, FText* OutError) + { + TSharedRef>> JsonWriter = TJsonWriterFactory>::Create(&OutJsonString); + const bool bDidSerialize = FJsonSerializer::Serialize(InJsonObject, JsonWriter); + JsonWriter->Close(); + + if (!bDidSerialize) + { + if (OutError) + { + *OutError = LOCTEXT("SerializeJsonObject.Error.FailedToSerialize", "Failed to serialize JSON object!"); + } + return false; + } + + return true; + } + + bool DeserializeJsonObject(const FString& InJsonString, TSharedPtr& OutJsonObject, FText* OutError) + { + TSharedRef> JsonWriter = TJsonReaderFactory::Create(InJsonString); + if (!FJsonSerializer::Deserialize(JsonWriter, OutJsonObject)) + { + if (OutError) + { + *OutError = FText::Format(LOCTEXT("DeserializeJsonObject.Error.FailedToDeserialize", "Failed to deserialize JSON object! {0}"), FText::AsCultureInvariant(JsonWriter->GetErrorMessage())); + } + return false; + } + + return true; + } + + bool ParseMessageData(const char* InMessageData, FPythonScriptRemoteExecutionMessage& OutMessage) + { + return ParseMessageData(UTF8_TO_TCHAR(InMessageData), OutMessage); + } + + bool ParseMessageData(const TCHAR* InMessageData, FPythonScriptRemoteExecutionMessage& OutMessage) + { + FText ReadErrorMsg; + if (!OutMessage.FromJsonString(InMessageData, &ReadErrorMsg)) + { + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to read remote execution message '%s': %s"), InMessageData, *ReadErrorMsg.ToString()); + return false; + } + return true; + } + + bool WriteMessageData(const FPythonScriptRemoteExecutionMessage& InMessage, FString& OutMessageData) + { + FText WriteErrorMsg; + if (!InMessage.ToJsonString(OutMessageData, &WriteErrorMsg)) + { + UE_LOG(LogPythonRemoteExecution, Error, TEXT("Failed to write remote execution message: %s"), *WriteErrorMsg.ToString()); + return false; + } + return true; + } + + void DestroySocket(ISocketSubsystem* InSocketSubsystem, FSocket*& InOutSocket) + { + check(InSocketSubsystem); + + if (InOutSocket) + { + if (InOutSocket->GetConnectionState() == SCS_Connected) + { + InOutSocket->Close(); + } + + InSocketSubsystem->DestroySocket(InOutSocket); + InOutSocket = nullptr; + } + } +} + +#endif // WITH_PYTHON + +#undef LOCTEXT_NAMESPACE diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptRemoteExecution.h b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptRemoteExecution.h new file mode 100644 index 000000000000..132249fde4c4 --- /dev/null +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptRemoteExecution.h @@ -0,0 +1,61 @@ +// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "IncludePython.h" +#include "Templates/UniquePtr.h" + +struct FIPv4Endpoint; + +class ISocketSubsystem; +class IPythonScriptPlugin; +class FPythonScriptRemoteExecutionCommandConnection; +class FPythonScriptRemoteExecutionBroadcastConnection; + +#if WITH_PYTHON + +class FPythonScriptRemoteExecution +{ + friend class FPythonScriptRemoteExecutionCommandConnection; + friend class FPythonScriptRemoteExecutionBroadcastConnection; + +public: + explicit FPythonScriptRemoteExecution(IPythonScriptPlugin* InPythonScriptPlugin); + ~FPythonScriptRemoteExecution(); + + /** Start remote execution based on the current settings (also called during construction if remote execution should be active) */ + bool Start(); + + /** Stop remote execution (also called during destruction if remote execution is active) */ + void Stop(); + + /** Sync the remote execution environment to the current settings, starting or stopping it as required */ + void SyncToSettings(); + + /** Tick, processing and sending messages as required */ + void Tick(const float InDeltaTime); + +private: + /** Open a command connection to the given remote node, at the given endpoint */ + void OpenCommandConnection(const FString& InRemoteNodeId, const FIPv4Endpoint& InCommandEndpoint); + + /** Close any existing command connection to the given remote node */ + void CloseCommandConnection(const FString& InRemoteNodeId); + + /** The Python plugin that owns this instance */ + IPythonScriptPlugin* PythonScriptPlugin; + + /** Cached socket subsystem pointer */ + ISocketSubsystem* SocketSubsystem; + + /** The ID of this remote execution node */ + FString NodeId; + + /** Connection handling TCP commands */ + TUniquePtr CommandConnection; + + /** Connection handling UDP broadcast */ + TUniquePtr BroadcastConnection; +}; + +#endif // WITH_PYTHON diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Public/IPythonScriptPlugin.h b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Public/IPythonScriptPlugin.h index 0d22929d0946..aa50dc77c444 100644 --- a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Public/IPythonScriptPlugin.h +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Public/IPythonScriptPlugin.h @@ -3,8 +3,11 @@ #pragma once #include "CoreTypes.h" -#include "Modules/ModuleInterface.h" +#include "Misc/EnumClassFlags.h" #include "Modules/ModuleManager.h" +#include "Modules/ModuleInterface.h" + +struct FPythonCommandEx; class IPythonScriptPlugin : public IModuleInterface { @@ -27,6 +30,12 @@ public: * @return true if the command ran successfully, false if there were errors (the output log will show the errors). */ virtual bool ExecPythonCommand(const TCHAR* InPythonCommand) = 0; + + /** + * Execute the given Python command. + * @return true if the command ran successfully, false if there were errors. + */ + virtual bool ExecPythonCommandEx(FPythonCommandEx& InOutPythonCommand) = 0; /** * Delegate called after Python has been initialized. @@ -38,3 +47,122 @@ public: */ virtual FSimpleMulticastDelegate& OnPythonShutdown() = 0; }; + +/** Types of log output that Python can give. */ +enum class EPythonLogOutputType : uint8 +{ + /** This log was informative. */ + Info, + /** This log was a warning. */ + Warning, + /** This log was an error. */ + Error, +}; + +/** Flags that can be specified when running Python commands. */ +enum class EPythonCommandFlags : uint8 +{ + /** No special behavior. */ + None = 0, + /** Run the Python command in "unattended" mode (GIsRunningUnattendedScript set to true), which will suppress certain pieces of UI. */ + Unattended = 1<<0, +}; +ENUM_CLASS_FLAGS(EPythonCommandFlags); + +/** Controls the execution mode used for the Python command. */ +enum class EPythonCommandExecutionMode : uint8 +{ + /** Execute the Python command as a file. This allows you to execute either a literal Python script containing multiple statements, or a file with optional arguments. */ + ExecuteFile, + /** Execute the Python command as a single statement. This will execute a single statement and print the result. This mode cannot run files. */ + ExecuteStatement, + /** Evaluate the Python command as a single statement. This will evaluate a single statement and return the result. This mode cannot run files. */ + EvaluateStatement, +}; + +/** Log output entry captured from Python. */ +struct FPythonLogOutputEntry +{ + /** The type of the log output. */ + EPythonLogOutputType Type = EPythonLogOutputType::Info; + + /** The log output string. */ + FString Output; +}; + +/** Extended information when executing Python commands. */ +struct FPythonCommandEx +{ + /** Flags controlling how the command should be run. */ + EPythonCommandFlags Flags = EPythonCommandFlags::None; + + /** Controls the mode used to execute the command. */ + EPythonCommandExecutionMode ExecutionMode = EPythonCommandExecutionMode::ExecuteFile; + + /** The command to run. This may be literal Python code, or a file (with optional arguments) to run. */ + FString Command; + + /** The result of running the command. On success, for EvaluateStatement mode this will be the actual result of running the command, and will be None in all other cases. On failure, this will be the error information (typically a Python exception trace). */ + FString CommandResult; + + /** The log output captured while running the command. */ + TArray LogOutput; +}; + +inline const TCHAR* LexToString(EPythonLogOutputType InType) +{ + switch (InType) + { + case EPythonLogOutputType::Info: + return TEXT("Info"); + case EPythonLogOutputType::Warning: + return TEXT("Warning"); + case EPythonLogOutputType::Error: + return TEXT("Error"); + default: + break; + } + return TEXT(""); +} + +inline const TCHAR* LexToString(EPythonCommandExecutionMode InMode) +{ + switch (InMode) + { + case EPythonCommandExecutionMode::ExecuteFile: + return TEXT("ExecuteFile"); + case EPythonCommandExecutionMode::ExecuteStatement: + return TEXT("ExecuteStatement"); + case EPythonCommandExecutionMode::EvaluateStatement: + return TEXT("EvaluateStatement"); + default: + break; + } + return TEXT(""); +} + +inline bool LexTryParseString(EPythonCommandExecutionMode& OutMode, const TCHAR* InBuffer) +{ + if (FCString::Stricmp(InBuffer, TEXT("ExecuteFile")) == 0) + { + OutMode = EPythonCommandExecutionMode::ExecuteFile; + return true; + } + if (FCString::Stricmp(InBuffer, TEXT("ExecuteStatement")) == 0) + { + OutMode = EPythonCommandExecutionMode::ExecuteStatement; + return true; + } + if (FCString::Stricmp(InBuffer, TEXT("EvaluateStatement")) == 0) + { + OutMode = EPythonCommandExecutionMode::EvaluateStatement; + return true; + } + return false; +} + +inline void LexFromString(EPythonCommandExecutionMode& OutMode, const TCHAR* InBuffer) +{ + OutMode = EPythonCommandExecutionMode::ExecuteFile; + LexTryParseString(OutMode, InBuffer); +} diff --git a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/PythonScriptPlugin.Build.cs b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/PythonScriptPlugin.Build.cs index 206bd5b2eea1..f31277ac30cc 100644 --- a/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/PythonScriptPlugin.Build.cs +++ b/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/PythonScriptPlugin.Build.cs @@ -23,6 +23,9 @@ namespace UnrealBuildTool.Rules "Slate", "SlateCore", "InputCore", + "Sockets", + "Networking", + "Json", } ); diff --git a/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/NiagaraHlslTranslator.cpp b/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/NiagaraHlslTranslator.cpp index 5b569b8a021e..141cd6734765 100644 --- a/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/NiagaraHlslTranslator.cpp +++ b/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/NiagaraHlslTranslator.cpp @@ -5173,7 +5173,7 @@ void FHlslNiagaraTranslator::Convert(class UNiagaraNodeConvert* Convert, TArray FNiagaraTypeDefinition Type = Schema->PinToTypeDefinition(InputPin); if (!AddStructToDefinitionSet(Type)) { - Error(FText::Format(LOCTEXT("ConvertTypeError", "Cannot handle input pin type {0}! Pin: {1}"), Type.GetNameText(), InputPin->GetDisplayName()), nullptr, nullptr); + Error(FText::Format(LOCTEXT("ConvertTypeError_InvalidInput", "Cannot handle input pin type {0}! Pin: {1}"), Type.GetNameText(), InputPin->GetDisplayName()), nullptr, nullptr); } } } @@ -5187,7 +5187,7 @@ void FHlslNiagaraTranslator::Convert(class UNiagaraNodeConvert* Convert, TArray FNiagaraTypeDefinition Type = Schema->PinToTypeDefinition(OutputPin); if (!AddStructToDefinitionSet(Type)) { - Error(FText::Format(LOCTEXT("ConvertTypeError", "Cannot handle output pin type {0}! Pin: {1}"), Type.GetNameText(), OutputPin->GetDisplayName()), nullptr, nullptr); + Error(FText::Format(LOCTEXT("ConvertTypeError_InvalidOutput", "Cannot handle output pin type {0}! Pin: {1}"), Type.GetNameText(), OutputPin->GetDisplayName()), nullptr, nullptr); } int32 OutChunk = AddBodyChunk(GetUniqueSymbolName(OutputPin->PinName), TEXT(""), Type); Outputs.Add(OutChunk); @@ -5207,14 +5207,14 @@ void FHlslNiagaraTranslator::Convert(class UNiagaraNodeConvert* Convert, TArray FNiagaraTypeDefinition SrcPinType = Schema->PinToTypeDefinition(InputPins[SourceIndex]); if (!AddStructToDefinitionSet(SrcPinType)) { - Error(FText::Format(LOCTEXT("ConvertTypeError", "Cannot handle input subpin type {0}! Subpin: {1}"), SrcPinType.GetNameText(), InputPins[SourceIndex]->GetDisplayName()), nullptr, nullptr); + Error(FText::Format(LOCTEXT("ConvertTypeError_InvalidSubpinInput", "Cannot handle input subpin type {0}! Subpin: {1}"), SrcPinType.GetNameText(), InputPins[SourceIndex]->GetDisplayName()), nullptr, nullptr); } TArray ConditionedSourcePath = ConditionPropertyPath(SrcPinType, Connection.SourcePath); FNiagaraTypeDefinition DestPinType = Schema->PinToTypeDefinition(OutputPins[DestinationIndex]); if (!AddStructToDefinitionSet(DestPinType)) { - Error(FText::Format(LOCTEXT("ConvertTypeError", "Cannot handle output subpin type type {0}! Subpin: {1}"), DestPinType.GetNameText(), OutputPins[SourceIndex]->GetDisplayName()), nullptr, nullptr); + Error(FText::Format(LOCTEXT("ConvertTypeError_InvalidSubpinOutput", "Cannot handle output subpin type type {0}! Subpin: {1}"), DestPinType.GetNameText(), OutputPins[SourceIndex]->GetDisplayName()), nullptr, nullptr); } TArray ConditionedDestinationPath = ConditionPropertyPath(DestPinType, Connection.DestinationPath); diff --git a/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Java/src/com/epicgames/ue4/CameraPlayer14.java b/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Java/src/com/epicgames/ue4/CameraPlayer14.java index a8aeb5f91e54..e584b6da21dc 100644 --- a/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Java/src/com/epicgames/ue4/CameraPlayer14.java +++ b/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Java/src/com/epicgames/ue4/CameraPlayer14.java @@ -1378,7 +1378,7 @@ public class CameraPlayer14 mSurfaceTexture.getTransformMatrix(mTransformMatrix); - int degrees = (GameActivity._activity.DeviceRotation + CameraRotationOffset) % 360; + int degrees = (GameActivity._activity.getCurrentDeviceRotationDegree() + CameraRotationOffset) % 360; if (degrees == 0) { mScaleRotation00 = mTransformMatrix[1]; mScaleRotation01 = mTransformMatrix[5]; @@ -1917,7 +1917,7 @@ public class CameraPlayer14 GameActivity.Log.debug(mTransformMatrix[12] + ", " + mTransformMatrix[13] + ", " + mTransformMatrix[14] + ", " + mTransformMatrix[15]); */ - int degrees = (GameActivity._activity.DeviceRotation + CameraRotationOffset) % 360; + int degrees = (GameActivity._activity.getCurrentDeviceRotationDegree() + CameraRotationOffset) % 360; if (degrees == 0) { mScaleRotation00 = mTransformMatrix[1]; mScaleRotation01 = mTransformMatrix[5]; diff --git a/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Private/AndroidCameraModule.cpp b/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Private/AndroidCameraModule.cpp index 6353ea2e3c2a..00fb0fb89790 100644 --- a/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Private/AndroidCameraModule.cpp +++ b/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Private/AndroidCameraModule.cpp @@ -43,17 +43,11 @@ public: static jmethodID QueryMethod = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_AndroidCamera_GetCameraUrl", "(I)Ljava/lang/String;", false); for (int CameraIndex = 0; CameraIndex < CountCameras; ++CameraIndex) { - - jstring JavaString = (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, QueryMethod, CameraIndex); - if (JavaString != NULL) + const auto CameraUrl = FJavaHelper::FStringFromLocalRef(Env, (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, QueryMethod, CameraIndex)); + if (CameraUrl.Len()) { FMediaCaptureDeviceInfo DeviceInfo; - - const char* JavaChars = Env->GetStringUTFChars(JavaString, 0); - DeviceInfo.Url = FString(UTF8_TO_TCHAR(JavaChars)); - Env->ReleaseStringUTFChars(JavaString, JavaChars); - Env->DeleteLocalRef(JavaString); - + DeviceInfo.Url = CameraUrl; if (DeviceInfo.Url.Contains("front")) { DeviceInfo.Type = EMediaCaptureDeviceType::WebcamFront; diff --git a/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Private/AndroidJavaCameraPlayer.cpp b/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Private/AndroidJavaCameraPlayer.cpp index fa2d259dbb1d..dcfd20384467 100644 --- a/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Private/AndroidJavaCameraPlayer.cpp +++ b/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Private/AndroidJavaCameraPlayer.cpp @@ -80,9 +80,7 @@ FJavaAndroidCameraPlayer::FJavaAndroidCameraPlayer(bool swizzlePixels, bool vulk JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); // get field IDs for FrameUpdateInfo class members - jclass localFrameUpdateInfoClass = FAndroidApplication::FindJavaClass("com/epicgames/ue4/CameraPlayer14$FrameUpdateInfo"); - FrameUpdateInfoClass = (jclass)JEnv->NewGlobalRef(localFrameUpdateInfoClass); - JEnv->DeleteLocalRef(localFrameUpdateInfoClass); + FrameUpdateInfoClass = FAndroidApplication::FindJavaClassGlobalRef("com/epicgames/ue4/CameraPlayer14$FrameUpdateInfo"); FrameUpdateInfo_Buffer = FindField(JEnv, FrameUpdateInfoClass, "Buffer", "Ljava/nio/Buffer;", false); FrameUpdateInfo_CurrentPosition = FindField(JEnv, FrameUpdateInfoClass, "CurrentPosition", "I", false); FrameUpdateInfo_FrameReady = FindField(JEnv, FrameUpdateInfoClass, "FrameReady", "Z", false); @@ -95,9 +93,7 @@ FJavaAndroidCameraPlayer::FJavaAndroidCameraPlayer(bool swizzlePixels, bool vulk FrameUpdateInfo_VOffset = FindField(JEnv, FrameUpdateInfoClass, "VOffset", "F", false); // get field IDs for AudioTrackInfo class members - jclass localAudioTrackInfoClass = FAndroidApplication::FindJavaClass("com/epicgames/ue4/CameraPlayer14$AudioTrackInfo"); - AudioTrackInfoClass = (jclass)JEnv->NewGlobalRef(localAudioTrackInfoClass); - JEnv->DeleteLocalRef(localAudioTrackInfoClass); + AudioTrackInfoClass = FAndroidApplication::FindJavaClassGlobalRef("com/epicgames/ue4/CameraPlayer14$AudioTrackInfo"); AudioTrackInfo_Index = FindField(JEnv, AudioTrackInfoClass, "Index", "I", false); AudioTrackInfo_MimeType = FindField(JEnv, AudioTrackInfoClass, "MimeType", "Ljava/lang/String;", false); AudioTrackInfo_DisplayName = FindField(JEnv, AudioTrackInfoClass, "DisplayName", "Ljava/lang/String;", false); @@ -106,18 +102,14 @@ FJavaAndroidCameraPlayer::FJavaAndroidCameraPlayer(bool swizzlePixels, bool vulk AudioTrackInfo_SampleRate = FindField(JEnv, AudioTrackInfoClass, "SampleRate", "I", false); // get field IDs for CaptionTrackInfo class members - jclass localCaptionTrackInfoClass = FAndroidApplication::FindJavaClass("com/epicgames/ue4/CameraPlayer14$CaptionTrackInfo"); - CaptionTrackInfoClass = (jclass)JEnv->NewGlobalRef(localCaptionTrackInfoClass); - JEnv->DeleteLocalRef(localCaptionTrackInfoClass); + CaptionTrackInfoClass = FAndroidApplication::FindJavaClassGlobalRef("com/epicgames/ue4/CameraPlayer14$CaptionTrackInfo"); CaptionTrackInfo_Index = FindField(JEnv, CaptionTrackInfoClass, "Index", "I", false); CaptionTrackInfo_MimeType = FindField(JEnv, CaptionTrackInfoClass, "MimeType", "Ljava/lang/String;", false); CaptionTrackInfo_DisplayName = FindField(JEnv, CaptionTrackInfoClass, "DisplayName", "Ljava/lang/String;", false); CaptionTrackInfo_Language = FindField(JEnv, CaptionTrackInfoClass, "Language", "Ljava/lang/String;", false); // get field IDs for VideoTrackInfo class members - jclass localVideoTrackInfoClass = FAndroidApplication::FindJavaClass("com/epicgames/ue4/CameraPlayer14$VideoTrackInfo"); - VideoTrackInfoClass = (jclass)JEnv->NewGlobalRef(localVideoTrackInfoClass); - JEnv->DeleteLocalRef(localVideoTrackInfoClass); + VideoTrackInfoClass = FAndroidApplication::FindJavaClassGlobalRef("com/epicgames/ue4/CameraPlayer14$VideoTrackInfo"); VideoTrackInfo_Index = FindField(JEnv, VideoTrackInfoClass, "Index", "I", false); VideoTrackInfo_MimeType = FindField(JEnv, VideoTrackInfoClass, "MimeType", "Ljava/lang/String;", false); VideoTrackInfo_DisplayName = FindField(JEnv, VideoTrackInfoClass, "DisplayName", "Ljava/lang/String;", false); @@ -130,6 +122,17 @@ FJavaAndroidCameraPlayer::FJavaAndroidCameraPlayer(bool swizzlePixels, bool vulk VideoTrackInfo_FrameRateHigh = FindField(JEnv, VideoTrackInfoClass, "FrameRateHigh", "F", false); } +FJavaAndroidCameraPlayer::~FJavaAndroidCameraPlayer() +{ + if (auto Env = FAndroidApplication::GetJavaEnv()) + { + Env->DeleteGlobalRef(FrameUpdateInfoClass); + Env->DeleteGlobalRef(AudioTrackInfoClass); + Env->DeleteGlobalRef(CaptionTrackInfoClass); + Env->DeleteGlobalRef(VideoTrackInfoClass); + } +} + int32 FJavaAndroidCameraPlayer::GetDuration() { return CallMethod(GetDurationMethod); @@ -193,8 +196,8 @@ bool FJavaAndroidCameraPlayer::SetDataSource(const FString & Url) ScaleRotation.W = 1.0f; Offset.X = 0.0f; Offset.Y = 0.0f; - - bool Result = CallMethod(SetDataSourceURLMethod, GetJString(Url)); + + bool Result = CallMethod(SetDataSourceURLMethod, *GetJString(Url)); if (Result) { @@ -280,50 +283,40 @@ bool FJavaAndroidCameraPlayer::GetVideoLastFrameData(void* & outPixels, int64 & { // This can return an exception in some cases JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); - jobject Result = JEnv->CallObjectMethod(Object, GetVideoLastFrameDataMethod.Method); + auto Result = NewScopedJavaObject(JEnv, JEnv->CallObjectMethod(Object, GetVideoLastFrameDataMethod.Method)); if (JEnv->ExceptionCheck()) { JEnv->ExceptionDescribe(); JEnv->ExceptionClear(); - if (nullptr != Result) - { - JEnv->DeleteLocalRef(Result); - } *CurrentPosition = -1; *bRegionChanged = false; return false; } - if (nullptr == Result) + if (!Result) { return false; } - jobject buffer = JEnv->GetObjectField(Result, FrameUpdateInfo_Buffer); - if (nullptr != buffer) + auto buffer = NewScopedJavaObject(JEnv, JEnv->GetObjectField(*Result, FrameUpdateInfo_Buffer)); + if (buffer) { - *CurrentPosition = (int32)JEnv->GetIntField(Result, FrameUpdateInfo_CurrentPosition); - bool bFrameReady = (bool)JEnv->GetBooleanField(Result, FrameUpdateInfo_FrameReady); - *bRegionChanged = (bool)JEnv->GetBooleanField(Result, FrameUpdateInfo_RegionChanged); - ScaleRotation.X = (float)(float)JEnv->GetFloatField(Result, FrameUpdateInfo_ScaleRotation00); - ScaleRotation.Y = (float)(float)JEnv->GetFloatField(Result, FrameUpdateInfo_ScaleRotation01); - ScaleRotation.Z = (float)(float)JEnv->GetFloatField(Result, FrameUpdateInfo_ScaleRotation10); - ScaleRotation.W = (float)(float)JEnv->GetFloatField(Result, FrameUpdateInfo_ScaleRotation11); - Offset.X = (float)JEnv->GetFloatField(Result, FrameUpdateInfo_UOffset); - Offset.Y = (float)JEnv->GetFloatField(Result, FrameUpdateInfo_VOffset); + *CurrentPosition = (int32)JEnv->GetIntField(*Result, FrameUpdateInfo_CurrentPosition); + bool bFrameReady = (bool)JEnv->GetBooleanField(*Result, FrameUpdateInfo_FrameReady); + *bRegionChanged = (bool)JEnv->GetBooleanField(*Result, FrameUpdateInfo_RegionChanged); + ScaleRotation.X = (float)(float)JEnv->GetFloatField(*Result, FrameUpdateInfo_ScaleRotation00); + ScaleRotation.Y = (float)(float)JEnv->GetFloatField(*Result, FrameUpdateInfo_ScaleRotation01); + ScaleRotation.Z = (float)(float)JEnv->GetFloatField(*Result, FrameUpdateInfo_ScaleRotation10); + ScaleRotation.W = (float)(float)JEnv->GetFloatField(*Result, FrameUpdateInfo_ScaleRotation11); + Offset.X = (float)JEnv->GetFloatField(*Result, FrameUpdateInfo_UOffset); + Offset.Y = (float)JEnv->GetFloatField(*Result, FrameUpdateInfo_VOffset); - outPixels = JEnv->GetDirectBufferAddress(buffer); - outCount = JEnv->GetDirectBufferCapacity(buffer); - - // the GetObjectField returns a local ref, but Java will still own the real buffer - JEnv->DeleteLocalRef(buffer); - - JEnv->DeleteLocalRef(Result); + outPixels = JEnv->GetDirectBufferAddress(*buffer); + outCount = JEnv->GetDirectBufferCapacity(*buffer); return !(nullptr == outPixels || 0 == outCount); } - - JEnv->DeleteLocalRef(Result); + return false; } @@ -351,38 +344,32 @@ bool FJavaAndroidCameraPlayer::UpdateVideoFrame(int32 ExternalTextureId, int32 * { // This can return an exception in some cases JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); - jobject Result = JEnv->CallObjectMethod(Object, UpdateVideoFrameMethod.Method, ExternalTextureId); + auto Result = NewScopedJavaObject(JEnv, JEnv->CallObjectMethod(Object, UpdateVideoFrameMethod.Method, ExternalTextureId)); if (JEnv->ExceptionCheck()) { JEnv->ExceptionDescribe(); JEnv->ExceptionClear(); - if (nullptr != Result) - { - JEnv->DeleteLocalRef(Result); - } *CurrentPosition = -1; *bRegionChanged = false; return false; } - if (nullptr == Result) + if (!Result) { *CurrentPosition = -1; *bRegionChanged = false; return false; } - *CurrentPosition = (int32)JEnv->GetIntField(Result, FrameUpdateInfo_CurrentPosition); - bool bFrameReady = (bool)JEnv->GetBooleanField(Result, FrameUpdateInfo_FrameReady); - *bRegionChanged = (bool)JEnv->GetBooleanField(Result, FrameUpdateInfo_RegionChanged); - ScaleRotation.X = (float)(float)JEnv->GetFloatField(Result, FrameUpdateInfo_ScaleRotation00); - ScaleRotation.Y = (float)(float)JEnv->GetFloatField(Result, FrameUpdateInfo_ScaleRotation01); - ScaleRotation.Z = (float)(float)JEnv->GetFloatField(Result, FrameUpdateInfo_ScaleRotation10); - ScaleRotation.W = (float)(float)JEnv->GetFloatField(Result, FrameUpdateInfo_ScaleRotation11); - Offset.X = (float)JEnv->GetFloatField(Result, FrameUpdateInfo_UOffset); - Offset.Y = (float)JEnv->GetFloatField(Result, FrameUpdateInfo_VOffset); - - JEnv->DeleteLocalRef(Result); + *CurrentPosition = (int32)JEnv->GetIntField(*Result, FrameUpdateInfo_CurrentPosition); + bool bFrameReady = (bool)JEnv->GetBooleanField(*Result, FrameUpdateInfo_FrameReady); + *bRegionChanged = (bool)JEnv->GetBooleanField(*Result, FrameUpdateInfo_RegionChanged); + ScaleRotation.X = (float)(float)JEnv->GetFloatField(*Result, FrameUpdateInfo_ScaleRotation00); + ScaleRotation.Y = (float)(float)JEnv->GetFloatField(*Result, FrameUpdateInfo_ScaleRotation01); + ScaleRotation.Z = (float)(float)JEnv->GetFloatField(*Result, FrameUpdateInfo_ScaleRotation10); + ScaleRotation.W = (float)(float)JEnv->GetFloatField(*Result, FrameUpdateInfo_ScaleRotation11); + Offset.X = (float)JEnv->GetFloatField(*Result, FrameUpdateInfo_UOffset); + Offset.Y = (float)JEnv->GetFloatField(*Result, FrameUpdateInfo_VOffset); return bFrameReady; } @@ -391,7 +378,7 @@ bool FJavaAndroidCameraPlayer::GetVideoLastFrame(int32 destTexture) { // This can return an exception in some cases JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); - jobject Result = JEnv->CallObjectMethod(Object, GetVideoLastFrameMethod.Method, destTexture); + auto Result = NewScopedJavaObject(JEnv, JEnv->CallObjectMethod(Object, GetVideoLastFrameMethod.Method, destTexture)); if (JEnv->ExceptionCheck()) { JEnv->ExceptionDescribe(); @@ -399,21 +386,19 @@ bool FJavaAndroidCameraPlayer::GetVideoLastFrame(int32 destTexture) return false; } - if (nullptr == Result) + if (!Result) { return false; } - bool bFrameReady = (bool)JEnv->GetBooleanField(Result, FrameUpdateInfo_FrameReady); - ScaleRotation.X = (float)(float)JEnv->GetFloatField(Result, FrameUpdateInfo_ScaleRotation00); - ScaleRotation.Y = (float)(float)JEnv->GetFloatField(Result, FrameUpdateInfo_ScaleRotation01); - ScaleRotation.Z = (float)(float)JEnv->GetFloatField(Result, FrameUpdateInfo_ScaleRotation10); - ScaleRotation.W = (float)(float)JEnv->GetFloatField(Result, FrameUpdateInfo_ScaleRotation11); - Offset.X = (float)JEnv->GetFloatField(Result, FrameUpdateInfo_UOffset); - Offset.Y = (float)JEnv->GetFloatField(Result, FrameUpdateInfo_VOffset); - - JEnv->DeleteLocalRef(Result); - + bool bFrameReady = (bool)JEnv->GetBooleanField(*Result, FrameUpdateInfo_FrameReady); + ScaleRotation.X = (float)(float)JEnv->GetFloatField(*Result, FrameUpdateInfo_ScaleRotation00); + ScaleRotation.Y = (float)(float)JEnv->GetFloatField(*Result, FrameUpdateInfo_ScaleRotation01); + ScaleRotation.Z = (float)(float)JEnv->GetFloatField(*Result, FrameUpdateInfo_ScaleRotation10); + ScaleRotation.W = (float)(float)JEnv->GetFloatField(*Result, FrameUpdateInfo_ScaleRotation11); + Offset.X = (float)JEnv->GetFloatField(*Result, FrameUpdateInfo_UOffset); + Offset.Y = (float)JEnv->GetFloatField(*Result, FrameUpdateInfo_VOffset); + return bFrameReady; } @@ -424,7 +409,7 @@ bool FJavaAndroidCameraPlayer::TakePicture(const FString& Filename) bool FJavaAndroidCameraPlayer::TakePicture(const FString& Filename, int32 Width, int32 Height) { - return CallMethod(TakePictureMethod, GetJString(Filename), Width, Height); + return CallMethod(TakePictureMethod, *GetJString(Filename), Width, Height); } FName FJavaAndroidCameraPlayer::GetClassName() @@ -472,38 +457,19 @@ bool FJavaAndroidCameraPlayer::GetAudioTracks(TArray& AudioTracks) for (int Index = 0; Index < ElementCount; ++Index) { - jobject Track = JEnv->GetObjectArrayElement(TrackArray, Index); + auto Track = NewScopedJavaObject(JEnv, JEnv->GetObjectArrayElement(TrackArray, Index)); int32 AudioTrackIndex = AudioTracks.AddDefaulted(); FAudioTrack& AudioTrack = AudioTracks[AudioTrackIndex]; - AudioTrack.Index = (int32)JEnv->GetIntField(Track, AudioTrackInfo_Index); + AudioTrack.Index = (int32)JEnv->GetIntField(*Track, AudioTrackInfo_Index); - jstring jsMimeType = (jstring)JEnv->GetObjectField(Track, AudioTrackInfo_MimeType); - CHECK_JNI_RESULT(jsMimeType); - const char * nativeMimeType = JEnv->GetStringUTFChars(jsMimeType, 0); - AudioTrack.MimeType = FString(nativeMimeType); - JEnv->ReleaseStringUTFChars(jsMimeType, nativeMimeType); - JEnv->DeleteLocalRef(jsMimeType); - - jstring jsDisplayName = (jstring)JEnv->GetObjectField(Track, AudioTrackInfo_DisplayName); - CHECK_JNI_RESULT(jsDisplayName); - const char * nativeDisplayName = JEnv->GetStringUTFChars(jsDisplayName, 0); - AudioTrack.DisplayName = FString(nativeDisplayName); - JEnv->ReleaseStringUTFChars(jsDisplayName, nativeDisplayName); - JEnv->DeleteLocalRef(jsDisplayName); - - jstring jsLanguage = (jstring)JEnv->GetObjectField(Track, AudioTrackInfo_Language); - CHECK_JNI_RESULT(jsLanguage); - const char * nativeLanguage = JEnv->GetStringUTFChars(jsLanguage, 0); - AudioTrack.Language = FString(nativeLanguage); - JEnv->ReleaseStringUTFChars(jsLanguage, nativeLanguage); - JEnv->DeleteLocalRef(jsLanguage); - - AudioTrack.Channels = (int32)JEnv->GetIntField(Track, AudioTrackInfo_Channels); - AudioTrack.SampleRate = (int32)JEnv->GetIntField(Track, AudioTrackInfo_SampleRate); - - JEnv->DeleteLocalRef(Track); + AudioTrack.MimeType = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, AudioTrackInfo_MimeType)); + AudioTrack.DisplayName = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, AudioTrackInfo_DisplayName)); + AudioTrack.Language = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, AudioTrackInfo_Language)); + + AudioTrack.Channels = (int32)JEnv->GetIntField(*Track, AudioTrackInfo_Channels); + AudioTrack.SampleRate = (int32)JEnv->GetIntField(*Track, AudioTrackInfo_SampleRate); } JEnv->DeleteGlobalRef(TrackArray); @@ -525,35 +491,16 @@ bool FJavaAndroidCameraPlayer::GetCaptionTracks(TArray& CaptionTr for (int Index = 0; Index < ElementCount; ++Index) { - jobject Track = JEnv->GetObjectArrayElement(TrackArray, Index); + auto Track = NewScopedJavaObject(JEnv, JEnv->GetObjectArrayElement(TrackArray, Index)); int32 CaptionTrackIndex = CaptionTracks.AddDefaulted(); FCaptionTrack& CaptionTrack = CaptionTracks[CaptionTrackIndex]; - CaptionTrack.Index = (int32)JEnv->GetIntField(Track, CaptionTrackInfo_Index); + CaptionTrack.Index = (int32)JEnv->GetIntField(*Track, CaptionTrackInfo_Index); - jstring jsMimeType = (jstring)JEnv->GetObjectField(Track, CaptionTrackInfo_MimeType); - CHECK_JNI_RESULT(jsMimeType); - const char * nativeMimeType = JEnv->GetStringUTFChars(jsMimeType, 0); - CaptionTrack.MimeType = FString(nativeMimeType); - JEnv->ReleaseStringUTFChars(jsMimeType, nativeMimeType); - JEnv->DeleteLocalRef(jsMimeType); - - jstring jsDisplayName = (jstring)JEnv->GetObjectField(Track, CaptionTrackInfo_DisplayName); - CHECK_JNI_RESULT(jsDisplayName); - const char * nativeDisplayName = JEnv->GetStringUTFChars(jsDisplayName, 0); - CaptionTrack.DisplayName = FString(nativeDisplayName); - JEnv->ReleaseStringUTFChars(jsDisplayName, nativeDisplayName); - JEnv->DeleteLocalRef(jsDisplayName); - - jstring jsLanguage = (jstring)JEnv->GetObjectField(Track, CaptionTrackInfo_Language); - CHECK_JNI_RESULT(jsLanguage); - const char * nativeLanguage = JEnv->GetStringUTFChars(jsLanguage, 0); - CaptionTrack.Language = FString(nativeLanguage); - JEnv->ReleaseStringUTFChars(jsLanguage, nativeLanguage); - JEnv->DeleteLocalRef(jsLanguage); - - JEnv->DeleteLocalRef(Track); + CaptionTrack.MimeType = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, CaptionTrackInfo_MimeType)); + CaptionTrack.DisplayName = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, CaptionTrackInfo_DisplayName)); + CaptionTrack.Language = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, CaptionTrackInfo_Language)); } JEnv->DeleteGlobalRef(TrackArray); @@ -575,54 +522,33 @@ bool FJavaAndroidCameraPlayer::GetVideoTracks(TArray& VideoTracks) if (ElementCount > 0) { - jobject Track = JEnv->GetObjectArrayElement(TrackArray, 0); + auto Track = NewScopedJavaObject(JEnv, JEnv->GetObjectArrayElement(TrackArray, 0)); int32 VideoTrackIndex = VideoTracks.AddDefaulted(); FVideoTrack& VideoTrack = VideoTracks[VideoTrackIndex]; - VideoTrack.Index = (int32)JEnv->GetIntField(Track, VideoTrackInfo_Index); + VideoTrack.Index = (int32)JEnv->GetIntField(*Track, VideoTrackInfo_Index); - jstring jsMimeType = (jstring)JEnv->GetObjectField(Track, VideoTrackInfo_MimeType); - CHECK_JNI_RESULT(jsMimeType); - const char * nativeMimeType = JEnv->GetStringUTFChars(jsMimeType, 0); - VideoTrack.MimeType = FString(nativeMimeType); - JEnv->ReleaseStringUTFChars(jsMimeType, nativeMimeType); - JEnv->DeleteLocalRef(jsMimeType); + VideoTrack.MimeType = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, VideoTrackInfo_MimeType)); + VideoTrack.DisplayName = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, VideoTrackInfo_DisplayName)); + VideoTrack.Language = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, VideoTrackInfo_Language)); - jstring jsDisplayName = (jstring)JEnv->GetObjectField(Track, VideoTrackInfo_DisplayName); - CHECK_JNI_RESULT(jsDisplayName); - const char * nativeDisplayName = JEnv->GetStringUTFChars(jsDisplayName, 0); - VideoTrack.DisplayName = FString(nativeDisplayName); - JEnv->ReleaseStringUTFChars(jsDisplayName, nativeDisplayName); - JEnv->DeleteLocalRef(jsDisplayName); - - jstring jsLanguage = (jstring)JEnv->GetObjectField(Track, VideoTrackInfo_Language); - CHECK_JNI_RESULT(jsLanguage); - const char * nativeLanguage = JEnv->GetStringUTFChars(jsLanguage, 0); - VideoTrack.Language = FString(nativeLanguage); - JEnv->ReleaseStringUTFChars(jsLanguage, nativeLanguage); - JEnv->DeleteLocalRef(jsLanguage); - - VideoTrack.BitRate = (int32)JEnv->GetIntField(Track, VideoTrackInfo_BitRate); + VideoTrack.BitRate = (int32)JEnv->GetIntField(*Track, VideoTrackInfo_BitRate); VideoTrack.Dimensions = FIntPoint(GetVideoWidth(), GetVideoHeight()); VideoTrack.FrameRate = GetFrameRate(); - VideoTrack.FrameRates = TRange(JEnv->GetFloatField(Track, VideoTrackInfo_FrameRateLow), JEnv->GetFloatField(Track, VideoTrackInfo_FrameRateHigh)); + VideoTrack.FrameRates = TRange(JEnv->GetFloatField(*Track, VideoTrackInfo_FrameRateLow), JEnv->GetFloatField(*Track, VideoTrackInfo_FrameRateHigh)); VideoTrack.Format = 0; - JEnv->DeleteLocalRef(Track); - for (int Index = 0; Index < ElementCount; ++Index) { - jobject Format = JEnv->GetObjectArrayElement(TrackArray, Index); + auto Format = NewScopedJavaObject(JEnv, JEnv->GetObjectArrayElement(TrackArray, Index)); int32 VideoFormatIndex = VideoTrack.Formats.AddDefaulted(); FVideoFormat& VideoFormat = VideoTrack.Formats[VideoFormatIndex]; - VideoFormat.Dimensions = FIntPoint((int32)JEnv->GetIntField(Format, VideoTrackInfo_Width), (int32)JEnv->GetIntField(Format, VideoTrackInfo_Height)); - VideoFormat.FrameRate = JEnv->GetFloatField(Format, VideoTrackInfo_FrameRateHigh); - VideoFormat.FrameRates = TRange(JEnv->GetFloatField(Format, VideoTrackInfo_FrameRateLow), JEnv->GetFloatField(Format, VideoTrackInfo_FrameRateHigh)); - - JEnv->DeleteLocalRef(Format); + VideoFormat.Dimensions = FIntPoint((int32)JEnv->GetIntField(*Format, VideoTrackInfo_Width), (int32)JEnv->GetIntField(*Format, VideoTrackInfo_Height)); + VideoFormat.FrameRate = JEnv->GetFloatField(*Format, VideoTrackInfo_FrameRateHigh); + VideoFormat.FrameRates = TRange(JEnv->GetFloatField(*Format, VideoTrackInfo_FrameRateLow), JEnv->GetFloatField(*Format, VideoTrackInfo_FrameRateHigh)); if (VideoTrack.Dimensions == VideoFormat.Dimensions) { diff --git a/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Public/AndroidJavaCameraPlayer.h b/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Public/AndroidJavaCameraPlayer.h index 6f92fb6310d9..4aac02cd479e 100644 --- a/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Public/AndroidJavaCameraPlayer.h +++ b/Engine/Plugins/Media/AndroidCamera/Source/AndroidCamera/Public/AndroidJavaCameraPlayer.h @@ -61,6 +61,7 @@ public: public: FJavaAndroidCameraPlayer(bool swizzlePixels, bool vulkanRenderer); + virtual ~FJavaAndroidCameraPlayer(); int32 GetDuration(); bool IsActive(); void Reset(); diff --git a/Engine/Plugins/Media/AndroidMedia/Source/AndroidMedia/Private/Player/AndroidMediaPlayer.cpp b/Engine/Plugins/Media/AndroidMedia/Source/AndroidMedia/Private/Player/AndroidMediaPlayer.cpp index 0d1155d5100c..14f8f52df85e 100644 --- a/Engine/Plugins/Media/AndroidMedia/Source/AndroidMedia/Private/Player/AndroidMediaPlayer.cpp +++ b/Engine/Plugins/Media/AndroidMedia/Source/AndroidMedia/Private/Player/AndroidMediaPlayer.cpp @@ -61,6 +61,7 @@ FAndroidMediaPlayer::~FAndroidMediaPlayer() if (JavaMediaPlayer.IsValid()) { +#if ANDROIDMEDIAPLAYER_USE_EXTERNALTEXTURE if (GSupportsImageExternal && !FAndroidMisc::ShouldUseVulkan()) { // Unregister the external texture on render thread @@ -92,6 +93,7 @@ FAndroidMediaPlayer::~FAndroidMediaPlayer() }); } else +#endif // ANDROIDMEDIAPLAYER_USE_EXTERNALTEXTURE { JavaMediaPlayer->SetVideoTexture(nullptr); JavaMediaPlayer->Reset(); @@ -706,6 +708,7 @@ void FAndroidMediaPlayer::TickFetch(FTimespan DeltaTime, FTimespan /*Timecode*/) PinnedSamples->AddVideo(Params.VideoSample); }); } +#if ANDROIDMEDIAPLAYER_USE_EXTERNALTEXTURE else if (GSupportsImageExternal) { struct FWriteVideoSampleParams @@ -751,6 +754,7 @@ void FAndroidMediaPlayer::TickFetch(FTimespan DeltaTime, FTimespan /*Timecode*/) } }); } +#endif // ANDROIDMEDIAPLAYER_USE_EXTERNALTEXTURE else { // create new video sample diff --git a/Engine/Plugins/Media/AudioCaptureTimecodeProvider/Source/AudioCaptureTimecodeProvider/Private/AudioCaptureTimecodeProvider.cpp b/Engine/Plugins/Media/AudioCaptureTimecodeProvider/Source/AudioCaptureTimecodeProvider/Private/AudioCaptureTimecodeProvider.cpp index bb7426036070..2edba4021c88 100644 --- a/Engine/Plugins/Media/AudioCaptureTimecodeProvider/Source/AudioCaptureTimecodeProvider/Private/AudioCaptureTimecodeProvider.cpp +++ b/Engine/Plugins/Media/AudioCaptureTimecodeProvider/Source/AudioCaptureTimecodeProvider/Private/AudioCaptureTimecodeProvider.cpp @@ -11,7 +11,7 @@ /* FLinearTimecodeAudioCaptureCustomTimeStepImplementation implementation *****************************************************************************/ -struct UAudioCaptureTimecodeProvider::FLinearTimecodeAudioCaptureCustomTimeStepImplementation : public Audio::IAudioCaptureCallback +struct UAudioCaptureTimecodeProvider::FLinearTimecodeAudioCaptureCustomTimeStepImplementation { public: FLinearTimecodeAudioCaptureCustomTimeStepImplementation(UAudioCaptureTimecodeProvider* InOwner) @@ -35,10 +35,12 @@ public: //We want a fast timecode detection but we don't want to be called too often. const int32 NumberCaptureFrames = 64; - Audio::FAudioCaptureStreamParam StreamParam; - StreamParam.Callback = this; - StreamParam.NumFramesDesired = NumberCaptureFrames; - if (!AudioCapture.OpenDefaultCaptureStream(StreamParam)) + Audio::FOnCaptureFunction OnCapture = [this](const float* AudioData, int32 NumFrames, int32 NumChannels, double StreamTime, bool bOverFlow) + { + OnAudioCapture(AudioData, NumFrames, NumChannels, StreamTime, bOverFlow); + }; + + if (!AudioCapture.OpenDefaultCaptureStream(MoveTemp(OnCapture), NumberCaptureFrames)) { UE_LOG(LogAudioCaptureTimecodeProvider, Error, TEXT("Can't open the default capture stream for %s."), *Owner->GetName()); return false; @@ -57,8 +59,7 @@ public: return true; } - //~ Audio::IAudioCaptureCallback interface - virtual void OnAudioCapture(float* AudioData, int32 NumFrames, int32 NumChannels, double StreamTime, bool bOverflow) override + void OnAudioCapture(const float* AudioData, int32 NumFrames, int32 NumChannels, double StreamTime, bool bOverflow) { check(Owner); @@ -78,9 +79,9 @@ public: AudioData += AudioChannelIndex; int32 NumSamples = NumChannels * NumFrames; - float* End = AudioData + NumSamples; + const float* End = AudioData + NumSamples; - for (float* Begin = AudioData; Begin != End; Begin += NumChannels) + for (const float* Begin = AudioData; Begin != End; Begin += NumChannels) { if (TimecodeDecoder.Sample(*Begin, CurrentDecodingTimecode)) { diff --git a/Engine/Plugins/Media/WebMMedia/Source/WebMMedia/Private/Player/WebMVideoDecoder.cpp b/Engine/Plugins/Media/WebMMedia/Source/WebMMedia/Private/Player/WebMVideoDecoder.cpp index 5622bfa61611..c09c929c5080 100644 --- a/Engine/Plugins/Media/WebMMedia/Source/WebMMedia/Private/Player/WebMVideoDecoder.cpp +++ b/Engine/Plugins/Media/WebMMedia/Source/WebMMedia/Private/Player/WebMVideoDecoder.cpp @@ -178,7 +178,13 @@ void FWebMVideoDecoder::Close() } // Make sure all compute shader decoding is done - FlushRenderingCommands(); + // + // This function can also be called on a rendering thread (the streamer is ticked there during a startup movie, and decoder gets deleted on StartNextMovie() + // if there are >1 movie queued). In this case we will ensure that the resources survive for one more frame after use by other means. + if (IsInGameThread()) + { + FlushRenderingCommands(); + } if (bIsInitialized) { diff --git a/Engine/Plugins/Media/WebMMedia/Source/WebMMedia/Private/WebMContainer.cpp b/Engine/Plugins/Media/WebMMedia/Source/WebMMedia/Private/WebMContainer.cpp index f3225504a224..6ae335c39063 100644 --- a/Engine/Plugins/Media/WebMMedia/Source/WebMMedia/Private/WebMContainer.cpp +++ b/Engine/Plugins/Media/WebMMedia/Source/WebMMedia/Private/WebMContainer.cpp @@ -80,7 +80,7 @@ bool FWebMContainer::Open(const FString& FilePath) if (Track->GetType() == mkvparser::Track::kVideo) { - if (FCStringAnsi::Strcmp(Track->GetCodecId(), "V_VP9") == 0) + if (FCStringAnsi::Strcmp(Track->GetCodecId(), "V_VP9") == 0 || FCStringAnsi::Strcmp(Track->GetCodecId(), "V_VP8") == 0) { MkvFile->VideoTracks.Add(static_cast(Track)); @@ -99,7 +99,7 @@ bool FWebMContainer::Open(const FString& FilePath) } else if (Track->GetType() == mkvparser::Track::kAudio) { - if (FCStringAnsi::Strcmp(Track->GetCodecId(), "A_OPUS") == 0) + if (FCStringAnsi::Strcmp(Track->GetCodecId(), "A_OPUS") == 0 || FCStringAnsi::Strcmp(Track->GetCodecId(), "A_VORBIS") == 0) { MkvFile->AudioTracks.Add(static_cast(Track)); diff --git a/Engine/Plugins/MovieScene/SequencerScripting/Source/SequencerScripting/Private/ExtensionLibraries/MovieSceneSequenceExtensions.cpp b/Engine/Plugins/MovieScene/SequencerScripting/Source/SequencerScripting/Private/ExtensionLibraries/MovieSceneSequenceExtensions.cpp index 81b8abfd3314..ce24ac8529db 100644 --- a/Engine/Plugins/MovieScene/SequencerScripting/Source/SequencerScripting/Private/ExtensionLibraries/MovieSceneSequenceExtensions.cpp +++ b/Engine/Plugins/MovieScene/SequencerScripting/Source/SequencerScripting/Private/ExtensionLibraries/MovieSceneSequenceExtensions.cpp @@ -267,6 +267,98 @@ void UMovieSceneSequenceExtensions::SetPlaybackEndSeconds(UMovieSceneSequence* S } } +void UMovieSceneSequenceExtensions::SetViewRangeStart(UMovieSceneSequence* Sequence, float StartTimeInSeconds) +{ + UMovieScene* MovieScene = GetMovieScene(Sequence); + if (MovieScene) + { +#if WITH_EDITORONLY_DATA + MovieScene->SetViewRange(StartTimeInSeconds, MovieScene->GetEditorData().ViewEnd); +#endif + } +} + +float UMovieSceneSequenceExtensions::GetViewRangeStart(UMovieSceneSequence* Sequence) +{ + UMovieScene* MovieScene = GetMovieScene(Sequence); + if (MovieScene) + { +#if WITH_EDITORONLY_DATA + return MovieScene->GetEditorData().ViewStart; +#endif + } + return 0.f; +} + +void UMovieSceneSequenceExtensions::SetViewRangeEnd(UMovieSceneSequence* Sequence, float EndTimeInSeconds) +{ + UMovieScene* MovieScene = GetMovieScene(Sequence); + if (MovieScene) + { +#if WITH_EDITORONLY_DATA + MovieScene->SetViewRange(MovieScene->GetEditorData().ViewStart, EndTimeInSeconds); +#endif + } +} + +float UMovieSceneSequenceExtensions::GetViewRangeEnd(UMovieSceneSequence* Sequence) +{ + UMovieScene* MovieScene = GetMovieScene(Sequence); + if (MovieScene) + { +#if WITH_EDITORONLY_DATA + return MovieScene->GetEditorData().ViewEnd; +#endif + } + return 0.f; +} + +void UMovieSceneSequenceExtensions::SetWorkRangeStart(UMovieSceneSequence* Sequence, float StartTimeInSeconds) +{ + UMovieScene* MovieScene = GetMovieScene(Sequence); + if (MovieScene) + { +#if WITH_EDITORONLY_DATA + MovieScene->SetWorkingRange(StartTimeInSeconds, MovieScene->GetEditorData().WorkEnd); +#endif + } +} + +float UMovieSceneSequenceExtensions::GetWorkRangeStart(UMovieSceneSequence* Sequence) +{ + UMovieScene* MovieScene = GetMovieScene(Sequence); + if (MovieScene) + { +#if WITH_EDITORONLY_DATA + return MovieScene->GetEditorData().WorkStart; +#endif + } + return 0.f; +} + +void UMovieSceneSequenceExtensions::SetWorkRangeEnd(UMovieSceneSequence* Sequence, float EndTimeInSeconds) +{ + UMovieScene* MovieScene = GetMovieScene(Sequence); + if (MovieScene) + { +#if WITH_EDITORONLY_DATA + MovieScene->SetWorkingRange(MovieScene->GetEditorData().WorkStart, EndTimeInSeconds); +#endif + } +} + +float UMovieSceneSequenceExtensions::GetWorkRangeEnd(UMovieSceneSequence* Sequence) +{ + UMovieScene* MovieScene = GetMovieScene(Sequence); + if (MovieScene) + { +#if WITH_EDITORONLY_DATA + return MovieScene->GetEditorData().WorkEnd; +#endif + } + return 0.f; +} + FTimecode UMovieSceneSequenceExtensions::GetTimecodeSource(UMovieSceneSequence* Sequence) { UMovieScene* MovieScene = GetMovieScene(Sequence); diff --git a/Engine/Plugins/MovieScene/SequencerScripting/Source/SequencerScripting/Public/ExtensionLibraries/MovieSceneSequenceExtensions.h b/Engine/Plugins/MovieScene/SequencerScripting/Source/SequencerScripting/Public/ExtensionLibraries/MovieSceneSequenceExtensions.h index d0c18985f6e6..bda8334bed06 100644 --- a/Engine/Plugins/MovieScene/SequencerScripting/Source/SequencerScripting/Public/ExtensionLibraries/MovieSceneSequenceExtensions.h +++ b/Engine/Plugins/MovieScene/SequencerScripting/Source/SequencerScripting/Public/ExtensionLibraries/MovieSceneSequenceExtensions.h @@ -202,6 +202,78 @@ public: UFUNCTION(BlueprintCallable, Category = "Sequence", meta = (ScriptMethod)) static void SetPlaybackEndSeconds(UMovieSceneSequence* Sequence, float EndTime); + /** + * Set the sequence view range start in seconds + * + * @param Sequence The sequence within which to set the view range start + * @param StartTimeInSeconds The desired view range start time in seconds for this sequence + */ + UFUNCTION(BlueprintCallable, Category = "Sequence", meta = (ScriptMethod, DevelopmentOnly)) + static void SetViewRangeStart(UMovieSceneSequence* InSequence, float StartTimeInSeconds); + + /** + * Get the sequence view range start in seconds + * + * @param Sequence The sequence within which to get the view range start + * @return The view range start time in seconds for this sequence + */ + UFUNCTION(BlueprintPure, Category = "Sequence", meta = (ScriptMethod, DevelopmentOnly)) + static float GetViewRangeStart(UMovieSceneSequence* InSequence); + + /** + * Set the sequence view range end in seconds + * + * @param Sequence The sequence within which to set the view range end + * @param StartTimeInSeconds The desired view range end time in seconds for this sequence + */ + UFUNCTION(BlueprintCallable, Category = "Sequence", meta = (ScriptMethod, DevelopmentOnly)) + static void SetViewRangeEnd(UMovieSceneSequence* InSequence, float EndTimeInSeconds); + + /** + * Get the sequence view range end in seconds + * + * @param Sequence The sequence within which to get the view range end + * @return The view range end time in seconds for this sequence + */ + UFUNCTION(BlueprintPure, Category = "Sequence", meta = (ScriptMethod, DevelopmentOnly)) + static float GetViewRangeEnd(UMovieSceneSequence* InSequence); + + /** + * Set the sequence work range start in seconds + * + * @param Sequence The sequence within which to set the work range start + * @param StartTimeInSeconds The desired work range start time in seconds for this sequence + */ + UFUNCTION(BlueprintCallable, Category = "Sequence", meta = (ScriptMethod, DevelopmentOnly)) + static void SetWorkRangeStart(UMovieSceneSequence* InSequence, float StartTimeInSeconds); + + /** + * Get the sequence work range start in seconds + * + * @param Sequence The sequence within which to get the work range start + * @return The work range start time in seconds for this sequence + */ + UFUNCTION(BlueprintPure, Category = "Sequence", meta = (ScriptMethod, DevelopmentOnly)) + static float GetWorkRangeStart(UMovieSceneSequence* InSequence); + + /** + * Set the sequence work range end in seconds + * + * @param Sequence The sequence within which to set the work range end + * @param StartTimeInSeconds The desired work range end time in seconds for this sequence + */ + UFUNCTION(BlueprintCallable, Category = "Sequence", meta = (ScriptMethod, DevelopmentOnly)) + static void SetWorkRangeEnd(UMovieSceneSequence* InSequence, float EndTimeInSeconds); + + /** + * Get the sequence work range end in seconds + * + * @param Sequence The sequence within which to get the work range end + * @return The work range end time in seconds for this sequence + */ + UFUNCTION(BlueprintPure, Category = "Sequence", meta = (ScriptMethod, DevelopmentOnly)) + static float GetWorkRangeEnd(UMovieSceneSequence* InSequence); + /** * Get the timecode source of this sequence * diff --git a/Engine/Plugins/Online/Android/OnlineSubsystemGameCircle/Source/OnlineSubsystemGameCircle/Private/OnlineStoreInterfaceGameCircle.cpp b/Engine/Plugins/Online/Android/OnlineSubsystemGameCircle/Source/OnlineSubsystemGameCircle/Private/OnlineStoreInterfaceGameCircle.cpp index b463acfa9d3a..7bdf3407a7ec 100644 --- a/Engine/Plugins/Online/Android/OnlineSubsystemGameCircle/Source/OnlineSubsystemGameCircle/Private/OnlineStoreInterfaceGameCircle.cpp +++ b/Engine/Plugins/Online/Android/OnlineSubsystemGameCircle/Source/OnlineSubsystemGameCircle/Private/OnlineStoreInterfaceGameCircle.cpp @@ -5,6 +5,7 @@ #include "Async/TaskGraphInterfaces.h" #include #include "Android/AndroidPlatform.h" +#include "Android/AndroidJavaEnv.h" //////////////////////////////////////////////////////////////////// /// Amazon Store Helper Request Response Codes @@ -86,30 +87,11 @@ JNI_METHOD void Java_com_epicgames_ue4_AmazonStoreHelper_nativeQueryComplete(JNI FInAppPurchaseProductInfo NewProductInfo; - jstring NextId = (jstring)jenv->GetObjectArrayElement(productIDs, Idx); - const char* charsId = jenv->GetStringUTFChars(NextId, 0); - NewProductInfo.Identifier = FString(UTF8_TO_TCHAR(charsId)); - jenv->ReleaseStringUTFChars(NextId, charsId); - jenv->DeleteLocalRef(NextId); - - jstring NextTitle = (jstring)jenv->GetObjectArrayElement(titles, Idx); - const char* charsTitle = jenv->GetStringUTFChars(NextTitle, 0); - NewProductInfo.DisplayName = FString(UTF8_TO_TCHAR(charsTitle)); - jenv->ReleaseStringUTFChars(NextTitle, charsTitle); - jenv->DeleteLocalRef(NextTitle); - - jstring NextDesc = (jstring)jenv->GetObjectArrayElement(descriptions, Idx); - const char* charsDesc = jenv->GetStringUTFChars(NextDesc, 0); - NewProductInfo.DisplayDescription = FString(UTF8_TO_TCHAR(charsDesc)); - jenv->ReleaseStringUTFChars(NextDesc, charsDesc); - jenv->DeleteLocalRef(NextDesc); - - jstring NextPrice = (jstring)jenv->GetObjectArrayElement(prices, Idx); - const char* charsPrice = jenv->GetStringUTFChars(NextPrice, 0); - NewProductInfo.DisplayPrice = FString(UTF8_TO_TCHAR(charsPrice)); - jenv->ReleaseStringUTFChars(NextPrice, charsPrice); - jenv->DeleteLocalRef(NextPrice); - + NewProductInfo.Identifier = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(productIDs, Idx)); + NewProductInfo.DisplayName = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(titles, Idx)); + NewProductInfo.DisplayDescription = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(descriptions, Idx)); + NewProductInfo.DisplayPrice = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(prices, Idx)); + LexFromString(NewProductInfo.RawPrice, *NewProductInfo.DisplayPrice); ProvidedProductInformation.Add(NewProductInfo); @@ -206,17 +188,9 @@ JNI_METHOD void Java_com_epicgames_ue4_AmazonStoreHelper_nativePurchaseComplete( if (Result == EInAppPurchaseState::Success) { - const char* charsId = jenv->GetStringUTFChars(productId, 0); - ProductId = FString(UTF8_TO_TCHAR(charsId)); - jenv->ReleaseStringUTFChars(productId, charsId); - - const char* charsReceipt = jenv->GetStringUTFChars(receiptData, 0); - ReceiptData = FString(UTF8_TO_TCHAR(charsReceipt)); - jenv->ReleaseStringUTFChars(receiptData, charsReceipt); - - const char* charsSignature = jenv->GetStringUTFChars(signature, 0); - Signature = FString(UTF8_TO_TCHAR(charsSignature)); - jenv->ReleaseStringUTFChars(signature, charsSignature); + ProductId = FJavaHelper::FStringFromParam(jenv, productId); + ReceiptData = FJavaHelper::FStringFromParam(jenv, receiptData); + Signature = FJavaHelper::FStringFromParam(jenv, signature); } DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.ProcessIapResult"), STAT_FSimpleDelegateGraphTask_ProcessIapResult, STATGROUP_TaskGraphTasks); @@ -306,18 +280,9 @@ JNI_METHOD void Java_com_epicgames_ue4_AmazonStoreHelper_nativeRestorePurchasesC // Build the restore product information strings. FInAppPurchaseRestoreInfo RestoreInfo; - jstring NextId = (jstring)jenv->GetObjectArrayElement(ProductIDs, Idx); - const char* charsId = jenv->GetStringUTFChars(NextId, 0); - RestoreInfo.Identifier = FString(UTF8_TO_TCHAR(charsId)); - jenv->ReleaseStringUTFChars(NextId, charsId); - jenv->DeleteLocalRef(NextId); - - jstring NextReceipt = (jstring)jenv->GetObjectArrayElement(ReceiptsData, Idx); - const char* charsReceipt = jenv->GetStringUTFChars(NextReceipt, 0); - RestoreInfo.ReceiptData = FString(UTF8_TO_TCHAR(charsReceipt)); - jenv->ReleaseStringUTFChars(NextReceipt, charsReceipt); - jenv->DeleteLocalRef(NextReceipt); - + RestoreInfo.Identifier = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(ProductIDs, Idx)); + RestoreInfo.ReceiptData = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(ReceiptsData, Idx)); + RestoredPurchaseInfo.Add(RestoreInfo); FPlatformMisc::LowLevelOutputDebugStringf(TEXT("\nRestored Product Identifier: %s\n"), *RestoreInfo.Identifier); diff --git a/Engine/Plugins/Online/Android/OnlineSubsystemGooglePlay/Source/Private/OnlineStoreInterfaceGooglePlay.cpp b/Engine/Plugins/Online/Android/OnlineSubsystemGooglePlay/Source/Private/OnlineStoreInterfaceGooglePlay.cpp index d67823c21ed6..215844637d77 100644 --- a/Engine/Plugins/Online/Android/OnlineSubsystemGooglePlay/Source/Private/OnlineStoreInterfaceGooglePlay.cpp +++ b/Engine/Plugins/Online/Android/OnlineSubsystemGooglePlay/Source/Private/OnlineStoreInterfaceGooglePlay.cpp @@ -8,6 +8,7 @@ #include "OnlineSubsystem.h" #include "OnlineSubsystemGooglePlay.h" #include +#include "Android/AndroidJavaEnv.h" //////////////////////////////////////////////////////////////////// @@ -104,37 +105,14 @@ JNI_METHOD void Java_com_epicgames_ue4_GooglePlayStoreHelper_nativeQueryComplete FInAppPurchaseProductInfo NewProductInfo; - jstring NextId = (jstring)jenv->GetObjectArrayElement(productIDs, Idx); - const char* charsId = jenv->GetStringUTFChars(NextId, 0); - NewProductInfo.Identifier = FString(UTF8_TO_TCHAR(charsId)); - jenv->ReleaseStringUTFChars(NextId, charsId); - jenv->DeleteLocalRef(NextId); - - jstring NextTitle = (jstring)jenv->GetObjectArrayElement(titles, Idx); - const char* charsTitle = jenv->GetStringUTFChars(NextTitle, 0); - NewProductInfo.DisplayName = FString(UTF8_TO_TCHAR(charsTitle)); - jenv->ReleaseStringUTFChars(NextTitle, charsTitle); - jenv->DeleteLocalRef(NextTitle); - - jstring NextDesc = (jstring)jenv->GetObjectArrayElement(descriptions, Idx); - const char* charsDesc = jenv->GetStringUTFChars(NextDesc, 0); - NewProductInfo.DisplayDescription = FString(UTF8_TO_TCHAR(charsDesc)); - jenv->ReleaseStringUTFChars(NextDesc, charsDesc); - jenv->DeleteLocalRef(NextDesc); - - jstring NextPrice = (jstring)jenv->GetObjectArrayElement(prices, Idx); - const char* charsPrice = jenv->GetStringUTFChars(NextPrice, 0); - NewProductInfo.DisplayPrice = FString(UTF8_TO_TCHAR(charsPrice)); - jenv->ReleaseStringUTFChars(NextPrice, charsPrice); - jenv->DeleteLocalRef(NextPrice); - + NewProductInfo.Identifier = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(productIDs, Idx)); + NewProductInfo.DisplayName = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(titles, Idx)); + NewProductInfo.DisplayDescription = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(descriptions, Idx)); + NewProductInfo.DisplayPrice = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(prices, Idx)); + NewProductInfo.RawPrice = PricesRaw[Idx]; - - jstring NextCurrencyCode = (jstring)jenv->GetObjectArrayElement(currencyCodes, Idx); - const char* charsCurrencyCodes = jenv->GetStringUTFChars(NextCurrencyCode, 0); - NewProductInfo.CurrencyCode = FString(UTF8_TO_TCHAR(charsCurrencyCodes)); - jenv->ReleaseStringUTFChars(NextCurrencyCode, charsCurrencyCodes); - jenv->DeleteLocalRef(NextCurrencyCode); + + NewProductInfo.CurrencyCode = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(currencyCodes, Idx)); ProvidedProductInformation.Add(NewProductInfo); @@ -236,21 +214,10 @@ JNI_METHOD void Java_com_epicgames_ue4_GooglePlayStoreHelper_nativePurchaseCompl bool bWasSuccessful = (EGPResponse == EGooglePlayBillingResponseCode::Ok); if (bWasSuccessful) { - const char* charsId = jenv->GetStringUTFChars(productId, 0); - ProductId = FString(UTF8_TO_TCHAR(charsId)); - jenv->ReleaseStringUTFChars(productId, charsId); - - const char* charsToken = jenv->GetStringUTFChars(productToken, 0); - ProductToken = FString(UTF8_TO_TCHAR(charsToken)); - jenv->ReleaseStringUTFChars(productToken, charsToken); - - const char* charsReceipt = jenv->GetStringUTFChars(receiptData, 0); - ReceiptData = FString(UTF8_TO_TCHAR(charsReceipt)); - jenv->ReleaseStringUTFChars(receiptData, charsReceipt); - - const char* charsSignature = jenv->GetStringUTFChars(signature, 0); - Signature = FString(UTF8_TO_TCHAR(charsSignature)); - jenv->ReleaseStringUTFChars(signature, charsSignature); + ProductId = FJavaHelper::FStringFromParam(jenv, productId); + ProductToken = FJavaHelper::FStringFromParam(jenv, productToken); + ReceiptData = FJavaHelper::FStringFromParam(jenv, receiptData); + Signature = FJavaHelper::FStringFromParam(jenv, signature); } FGoogleTransactionData TransactionData(ProductId, ProductToken, ReceiptData, Signature); @@ -362,30 +329,11 @@ JNI_METHOD void Java_com_epicgames_ue4_GooglePlayStoreHelper_nativeRestorePurcha // Build the restore product information strings. FInAppPurchaseRestoreInfo RestoreInfo; - jstring NextId = (jstring)jenv->GetObjectArrayElement(ProductIDs, Idx); - const char* charsId = jenv->GetStringUTFChars(NextId, 0); - const FString OfferId = FString(UTF8_TO_TCHAR(charsId)); - jenv->ReleaseStringUTFChars(NextId, charsId); - jenv->DeleteLocalRef(NextId); - - jstring NextToken = (jstring)jenv->GetObjectArrayElement(ProductTokens, Idx); - const char* charsToken = jenv->GetStringUTFChars(NextToken, 0); - const FString ProductToken = FString(UTF8_TO_TCHAR(charsToken)); - jenv->ReleaseStringUTFChars(NextToken, charsToken); - jenv->DeleteLocalRef(NextToken); - - jstring NextReceipt = (jstring)jenv->GetObjectArrayElement(ReceiptsData, Idx); - const char* charsReceipt = jenv->GetStringUTFChars(NextReceipt, 0); - const FString ReceiptData = FString(UTF8_TO_TCHAR(charsReceipt)); - jenv->ReleaseStringUTFChars(NextReceipt, charsReceipt); - jenv->DeleteLocalRef(NextReceipt); - - jstring NextSignature = (jstring)jenv->GetObjectArrayElement(Signatures, Idx); - const char* charsSignature = jenv->GetStringUTFChars(NextSignature, 0); - const FString SignatureData = FString(UTF8_TO_TCHAR(charsSignature)); - jenv->ReleaseStringUTFChars(NextSignature, charsSignature); - jenv->DeleteLocalRef(NextSignature); - + const auto OfferId = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(ProductIDs, Idx)); + const auto ProductToken = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(ProductTokens, Idx)); + const auto ReceiptData = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(ReceiptsData, Idx)); + const auto SignatureData = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(Signatures, Idx)); + FGoogleTransactionData RestoredPurchase(OfferId, ProductToken, ReceiptData, SignatureData); RestoredPurchaseInfo.Add(RestoredPurchase); @@ -461,30 +409,11 @@ JNI_METHOD void Java_com_epicgames_ue4_GooglePlayStoreHelper_nativeQueryExisting for (jsize Idx = 0; Idx < NumProducts; Idx++) { // Build the product information strings. - jstring NextId = (jstring)jenv->GetObjectArrayElement(ProductIDs, Idx); - const char* charsId = jenv->GetStringUTFChars(NextId, 0); - const FString OfferId = FString(UTF8_TO_TCHAR(charsId)); - jenv->ReleaseStringUTFChars(NextId, charsId); - jenv->DeleteLocalRef(NextId); - - jstring NextToken = (jstring)jenv->GetObjectArrayElement(ProductTokens, Idx); - const char* charsToken = jenv->GetStringUTFChars(NextToken, 0); - const FString ProductToken = FString(UTF8_TO_TCHAR(charsToken)); - jenv->ReleaseStringUTFChars(NextToken, charsToken); - jenv->DeleteLocalRef(NextToken); - - jstring NextReceipt = (jstring)jenv->GetObjectArrayElement(ReceiptsData, Idx); - const char* charsReceipt = jenv->GetStringUTFChars(NextReceipt, 0); - const FString ReceiptData = FString(UTF8_TO_TCHAR(charsReceipt)); - jenv->ReleaseStringUTFChars(NextReceipt, charsReceipt); - jenv->DeleteLocalRef(NextReceipt); - - jstring NextSignature = (jstring)jenv->GetObjectArrayElement(Signatures, Idx); - const char* charsSignature = jenv->GetStringUTFChars(NextSignature, 0); - const FString SignatureData = FString(UTF8_TO_TCHAR(charsSignature)); - jenv->ReleaseStringUTFChars(NextSignature, charsSignature); - jenv->DeleteLocalRef(NextSignature); - + const auto OfferId = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(ProductIDs, Idx)); + const auto ProductToken = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(ProductTokens, Idx)); + const auto ReceiptData = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(ReceiptsData, Idx)); + const auto SignatureData = FJavaHelper::FStringFromLocalRef(jenv, (jstring)jenv->GetObjectArrayElement(Signatures, Idx)); + FGoogleTransactionData ExistingPurchase(OfferId, ProductToken, ReceiptData, SignatureData); ExistingPurchaseInfo.Add(ExistingPurchase); diff --git a/Engine/Plugins/Online/Android/OnlineSubsystemGooglePlay/Source/Private/OnlineSubsystemGooglePlay.cpp b/Engine/Plugins/Online/Android/OnlineSubsystemGooglePlay/Source/Private/OnlineSubsystemGooglePlay.cpp index 9e6625f714d7..624d759acb76 100644 --- a/Engine/Plugins/Online/Android/OnlineSubsystemGooglePlay/Source/Private/OnlineSubsystemGooglePlay.cpp +++ b/Engine/Plugins/Online/Android/OnlineSubsystemGooglePlay/Source/Private/OnlineSubsystemGooglePlay.cpp @@ -403,9 +403,7 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeGoogleClientConnectCom FString AccessToken; if (bSuccess) { - const char* charsToken = jenv->GetStringUTFChars(accessToken, 0); - AccessToken = FString(UTF8_TO_TCHAR(charsToken)); - jenv->ReleaseStringUTFChars(accessToken, charsToken); + AccessToken = FJavaHelper::FStringFromParam(jenv, accessToken); } UE_LOG_ONLINE(Log, TEXT("nativeGoogleClientConnectCompleted Success: %d Token: %s"), bSuccess, *AccessToken); diff --git a/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineIdentityInterfaceIOS.cpp b/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineIdentityInterfaceIOS.cpp index 4b2e053f0f0c..dbbe218a4819 100644 --- a/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineIdentityInterfaceIOS.cpp +++ b/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineIdentityInterfaceIOS.cpp @@ -60,7 +60,7 @@ bool FOnlineIdentityIOS::Login(int32 LocalUserNum, const FOnlineAccountCredentia UE_LOG_ONLINE_IDENTITY(Log, TEXT("The user %s has logged into Game Center"), *PlayerId); } - else if([IOSAppDelegate GetDelegate].OSVersion >= 6.0f) + else { // Trigger the login event on the main thread. bStartedLogin = true; @@ -108,17 +108,12 @@ bool FOnlineIdentityIOS::Login(int32 LocalUserNum, const FOnlineAccountCredentia else { // Game Center has provided a view controller for us to login, we present it. - [[IOSAppDelegate GetDelegate].IOSController + [[IOSAppDelegate GetDelegate].IOSController presentViewController:viewcontroller animated:YES completion:nil]; } })]; }); } - else - { - // User is not currently logged into game center - TriggerOnLoginCompleteDelegates(LocalUserNum, false, FUniqueNetIdIOS(), TEXT("IOS version is not compatible with the game center implementation")); - } return bStartedLogin; } diff --git a/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineStoreKitHelper.cpp b/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineStoreKitHelper.cpp index b052f33d9b60..58e816c112f0 100644 --- a/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineStoreKitHelper.cpp +++ b/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineStoreKitHelper.cpp @@ -14,29 +14,16 @@ FString convertReceiptToString(const SKPaymentTransaction* transaction) { FString ReceiptData; -#ifdef __IPHONE_7_0 - if ([IOSAppDelegate GetDelegate].OSVersion >= 7.0) + NSURL* nsReceiptUrl = [[NSBundle mainBundle] appStoreReceiptURL]; + NSData* nsReceiptData = [NSData dataWithContentsOfURL : nsReceiptUrl]; + if (nsReceiptData) { - NSURL* nsReceiptUrl = [[NSBundle mainBundle] appStoreReceiptURL]; - NSData* nsReceiptData = [NSData dataWithContentsOfURL : nsReceiptUrl]; - if (nsReceiptData) - { - NSString* nsEncodedReceiptData = [nsReceiptData base64EncodedStringWithOptions : NSDataBase64EncodingEndLineWithLineFeed]; - ReceiptData = nsEncodedReceiptData; - } - else - { - UE_LOG_ONLINE_STORE(Log, TEXT("No receipt data found for transaction")); - } + NSString* nsEncodedReceiptData = [nsReceiptData base64EncodedStringWithOptions : NSDataBase64EncodingEndLineWithLineFeed]; + ReceiptData = nsEncodedReceiptData; } else -#endif { -#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0 - // If earlier than IOS 7, we will need to use the transactionReceipt - NSString* nsEncodedReceiptData = [transaction.transactionReceipt base64EncodedStringWithOptions : NSDataBase64EncodingEndLineWithLineFeed]; - ReceiptData = nsEncodedReceiptData; -#endif + UE_LOG_ONLINE_STORE(Log, TEXT("No receipt data found for transaction")); } UE_LOG_ONLINE_STORE(VeryVerbose, TEXT("FStoreKitHelper::convertReceiptToString %s"), *ReceiptData); @@ -384,20 +371,9 @@ FStoreKitTransactionData::FStoreKitTransactionData(const SKPaymentTransaction* T -(void)restorePurchases { -#ifdef __IPHONE_7_0 - if ([IOSAppDelegate GetDelegate].OSVersion >= 7.0) - { - Request = [[SKReceiptRefreshRequest alloc] init]; - Request.delegate = self; - [Request start]; - } - else -#endif - { -#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0 - [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; -#endif - } + Request = [[SKReceiptRefreshRequest alloc] init]; + Request.delegate = self; + [Request start]; } @end @@ -465,10 +441,8 @@ FStoreKitTransactionData::FStoreKitTransactionData(const SKPaymentTransaction* T { SKMutablePayment* Payment = [SKMutablePayment paymentWithProduct:Product]; Payment.quantity = 1; - if ([IOSAppDelegate GetDelegate].OSVersion >= 8.3) - { - Payment.simulatesAskToBuyInSandbox = bAskToBuy; - } + Payment.simulatesAskToBuyInSandbox = bAskToBuy; + if (!userId.IsEmpty()) { // hash of username to detect irregular activity diff --git a/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineSubsystemIOS.cpp b/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineSubsystemIOS.cpp index 563ee8a0153d..07e9eac0c695 100644 --- a/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineSubsystemIOS.cpp +++ b/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineSubsystemIOS.cpp @@ -147,13 +147,7 @@ bool FOnlineSubsystemIOS::Init() bool bSuccessfullyStartedUp = true; UE_LOG_ONLINE(VeryVerbose, TEXT("FOnlineSubsystemIOS::Init()")); - bool bIsGameCenterSupported = ([IOSAppDelegate GetDelegate].OSVersion >= 4.1f); - if( !bIsGameCenterSupported ) - { - UE_LOG_ONLINE(Warning, TEXT("GameCenter is not supported on systems running IOS 4.0 or earlier.")); - bSuccessfullyStartedUp = false; - } - else if( !IsEnabled() ) + if( !IsEnabled() ) { UE_LOG_ONLINE(Warning, TEXT("GameCenter has been disabled in the system settings")); bSuccessfullyStartedUp = false; diff --git a/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineSubsystemIOSModule.cpp b/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineSubsystemIOSModule.cpp index 60b9cc7fecf8..c2fe3c45ccd9 100644 --- a/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineSubsystemIOSModule.cpp +++ b/Engine/Plugins/Online/IOS/OnlineSubsystemIOS/Source/Private/OnlineSubsystemIOSModule.cpp @@ -64,6 +64,8 @@ FOnlineSubsystemIOSPtr FOnlineFactoryIOS::IOSSingleton = NULL; void FOnlineSubsystemIOSModule::StartupModule() { + SCOPED_BOOT_TIMING("FOnlineSubsystemIOSModule::StartupModule"); + UE_LOG_ONLINE(Display, TEXT("FOnlineSubsystemIOSModule::StartupModule()")); FHttpModule::Get(); @@ -82,4 +84,4 @@ void FOnlineSubsystemIOSModule::ShutdownModule() delete IOSFactory; IOSFactory = NULL; -} \ No newline at end of file +} diff --git a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowManager.cpp b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowManager.cpp index 5390d563e868..9959c3775ec9 100644 --- a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowManager.cpp +++ b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowManager.cpp @@ -97,7 +97,7 @@ void FLoginFlowManager::Reset() OnlineSubsystemsMap.Empty(); } -bool FLoginFlowManager::AddLoginFlow(FName OnlineIdentifier, const FOnDisplayPopup& InPopupDelegate, const FOnDisplayPopup& InCreationFlowPopupDelegate, bool bPersistCookies) +bool FLoginFlowManager::AddLoginFlow(FName OnlineIdentifier, const FOnDisplayPopup& InPopupDelegate, const FOnDisplayPopup& InCreationFlowPopupDelegate, bool bPersistCookies, bool bConsumeInput) { bool bSuccess = false; @@ -121,6 +121,7 @@ bool FLoginFlowManager::AddLoginFlow(FName OnlineIdentifier, const FOnDisplayPop NewParams.BrowserContextSettings = MakeShared(ContextName); NewParams.BrowserContextSettings->bPersistSessionCookies = bPersistCookies; NewParams.bRegisteredContext = false; + NewParams.bConsumeInput = bConsumeInput; NewParams.LoginFlowLogoutDelegateHandle = OnlineIdentity->AddOnLoginFlowLogoutDelegate_Handle(FOnLoginFlowLogoutDelegate::CreateSP(this, &FLoginFlowManager::OnLoginFlowLogout, OnlineIdentifier)); @@ -213,6 +214,7 @@ void FLoginFlowManager::OnLoginFlowStarted(const FString& RequestedURL, const FO // generate a login flow chromium widget ILoginFlowModule::FCreateSettings CreateSettings; CreateSettings.Url = RequestedURL; + CreateSettings.bConsumeInput = Params->bConsumeInput; CreateSettings.BrowserContextSettings = Params->BrowserContextSettings; // Setup will allow login flow module events to trigger passed in delegates diff --git a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowModule.cpp b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowModule.cpp index 51f882f019ce..f809bf08016e 100644 --- a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowModule.cpp +++ b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowModule.cpp @@ -27,7 +27,8 @@ public: Settings.BrowserContextSettings, Settings.CloseCallback, Settings.ErrorCallback, - Settings.RedirectCallback); + Settings.RedirectCallback, + Settings.bConsumeInput); TSharedPtr LoginFlowWidget = nullptr; if (Settings.StyleSet) diff --git a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowViewModel.cpp b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowViewModel.cpp index cbcb612aa31e..faa21700eb12 100644 --- a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowViewModel.cpp +++ b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowViewModel.cpp @@ -67,6 +67,11 @@ public: return BrowserContextSettings; } + virtual bool ShouldConsumeInput() const override + { + return bConsumeInput; + } + private: FLoginFlowViewModelImpl( @@ -74,12 +79,14 @@ private: const TSharedPtr& InBrowserContextSettings, const FOnLoginFlowRequestClose& InOnRequestClose, const FOnLoginFlowError& InOnError, - const FOnLoginFlowRedirectURL& InOnRedirectURL) + const FOnLoginFlowRedirectURL& InOnRedirectURL, + bool bInConsumeInput) : LoginFlowStartingUrl(InLoginFlowStartingUrl) , BrowserContextSettings(InBrowserContextSettings) , OnRequestClose(InOnRequestClose) , OnError(InOnError) , OnRedirectURL(InOnRedirectURL) + , bConsumeInput(bInConsumeInput) { } void Initialize() @@ -93,6 +100,7 @@ private: const FOnLoginFlowRequestClose OnRequestClose; const FOnLoginFlowError OnError; const FOnLoginFlowRedirectURL OnRedirectURL; + bool bConsumeInput; friend FLoginFlowViewModelFactory; }; @@ -102,7 +110,8 @@ TSharedRef FLoginFlowViewModelFactory::Create( const TSharedPtr& BrowserContextSettings, const FOnLoginFlowRequestClose& OnRequestClose, const FOnLoginFlowError& OnError, - const FOnLoginFlowRedirectURL& OnRedirectURL) + const FOnLoginFlowRedirectURL& OnRedirectURL, + bool bConsumeInput) { TSharedRef< FLoginFlowViewModelImpl > ViewModel = MakeShareable( new FLoginFlowViewModelImpl( @@ -110,7 +119,8 @@ TSharedRef FLoginFlowViewModelFactory::Create( BrowserContextSettings, OnRequestClose, OnError, - OnRedirectURL)); + OnRedirectURL, + bConsumeInput)); ViewModel->Initialize(); return ViewModel; } diff --git a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowViewModel.h b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowViewModel.h index 7562d154ff27..674a5c422ddc 100644 --- a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowViewModel.h +++ b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/LoginFlowViewModel.h @@ -42,6 +42,9 @@ public: /** @return the context settings for the underlying browser */ virtual const TSharedPtr& GetBrowserContextSettings() const = 0; + + /** @return whether or not the login flow should consume any input not handled by the browser window */ + virtual bool ShouldConsumeInput() const = 0; }; FACTORY(TSharedRef, FLoginFlowViewModel, @@ -49,4 +52,5 @@ FACTORY(TSharedRef, FLoginFlowViewModel, const TSharedPtr& BrowserContextSettings, const FOnLoginFlowRequestClose& OnRequestClose, const FOnLoginFlowError& OnError, - const FOnLoginFlowRedirectURL& OnRedirectURL); + const FOnLoginFlowRedirectURL& OnRedirectURL, + const bool bConsumeInput); diff --git a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/SLoginFlow.cpp b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/SLoginFlow.cpp index 2d005eee4b35..4c3c7f353832 100644 --- a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/SLoginFlow.cpp +++ b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Private/SLoginFlow.cpp @@ -44,6 +44,9 @@ public: .OnCreateWindow(this, &SLoginFlowImpl::HandleBrowserCreateWindow) .OnCloseWindow(this, &SLoginFlowImpl::HandleBrowserCloseWindow) .OnShowDialog(this, &SLoginFlowImpl::HandleShowDialog) + .OnUnhandledKeyDown(this, &SLoginFlowImpl::HandleKey) + .OnUnhandledKeyUp(this, &SLoginFlowImpl::HandleKey) + .OnUnhandledKeyChar(this, &SLoginFlowImpl::HandleKeyChar) .ContextSettings(ViewModel->GetBrowserContextSettings().IsValid() ? *ViewModel->GetBrowserContextSettings() : TOptional()) ] ] @@ -442,6 +445,16 @@ private: return WebDialogHandling; } + bool HandleKey(const FKeyEvent& KeyEvent) + { + return ViewModel->ShouldConsumeInput(); + } + + bool HandleKeyChar(const FCharacterEvent& CharacterEvent) + { + return ViewModel->ShouldConsumeInput(); + } + private: TSharedPtr ViewModel; diff --git a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Public/ILoginFlowManager.h b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Public/ILoginFlowManager.h index 78435750fc07..42a970eea2c8 100644 --- a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Public/ILoginFlowManager.h +++ b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Public/ILoginFlowManager.h @@ -38,9 +38,10 @@ public: * @param InPopupDelegate external delegate to receive widgets from the login flow * @param InCreationFlowPopupDelegate external delegate to receive widgets from the account creation flow * @param bPersistCookies let the global web context manage cookies, or keep them in memory only + * @param bConsumeInput whether or not input, not handled by the widget, should be consumed an not bubbled up * @return whether or not the login flow was successfully added */ - virtual bool AddLoginFlow(FName OnlineIdentifier, const FOnDisplayPopup& InPopupDelegate, const FOnDisplayPopup& InCreationFlowPopupDelegate, bool bPersistCookies = true) = 0; + virtual bool AddLoginFlow(FName OnlineIdentifier, const FOnDisplayPopup& InPopupDelegate, const FOnDisplayPopup& InCreationFlowPopupDelegate, bool bPersistCookies = true, bool bConsumeInput = false) = 0; /** * Has a given login flow been setup diff --git a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Public/ILoginFlowModule.h b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Public/ILoginFlowModule.h index a9dd2e1a8448..0fae19edaef9 100644 --- a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Public/ILoginFlowModule.h +++ b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Public/ILoginFlowModule.h @@ -89,9 +89,12 @@ public: FOnLoginFlowError ErrorCallback; /** Delegate to fire for every URL redirect */ FOnLoginFlowRedirectURL RedirectCallback; + /** Whether or not the widget should consume input not handled by the browser */ + bool bConsumeInput; FCreateSettings() : StyleSet(nullptr) + , bConsumeInput(false) {} }; diff --git a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Public/LoginFlowManager.h b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Public/LoginFlowManager.h index c573788c50d9..07ce91746229 100644 --- a/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Public/LoginFlowManager.h +++ b/Engine/Plugins/Online/OnlineFramework/Source/LoginFlow/Public/LoginFlowManager.h @@ -24,7 +24,7 @@ public: ~FLoginFlowManager(); //~ Begin ILoginFlowManager interface - virtual bool AddLoginFlow(FName OnlineIdentifier, const FOnDisplayPopup& InPopupDelegate, const FOnDisplayPopup& InCreationFlowPopupDelegate, bool bPersistCookies) override; + virtual bool AddLoginFlow(FName OnlineIdentifier, const FOnDisplayPopup& InPopupDelegate, const FOnDisplayPopup& InCreationFlowPopupDelegate, bool bPersistCookies, bool bConsumeInput) override; virtual bool HasLoginFlow(FName OnlineIdentifier) override; virtual void CancelLoginFlow() override; virtual void CancelAccountCreationFlow() override; @@ -91,6 +91,8 @@ private: TSharedPtr BrowserContextSettings; /** Has this context been registered */ bool bRegisteredContext = false; + /** Whether or not keyboard input, not handled by the browser, should be consumed */ + bool bConsumeInput = false; }; /** diff --git a/Engine/Plugins/Online/OnlineFramework/Source/Party/Private/Chat/SocialGroupChannel.cpp b/Engine/Plugins/Online/OnlineFramework/Source/Party/Private/Chat/SocialGroupChannel.cpp new file mode 100644 index 000000000000..dde1ae8dde62 --- /dev/null +++ b/Engine/Plugins/Online/OnlineFramework/Source/Party/Private/Chat/SocialGroupChannel.cpp @@ -0,0 +1,62 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "Chat/SocialGroupChannel.h" +#include "User/SocialUser.h" +#include "SocialToolkit.h" +#include "SocialTypes.h" + +USocialGroupChannel::USocialGroupChannel() +{ +} + +void USocialGroupChannel::Initialize(IOnlineGroupsPtr InGroupInterface, USocialUser& InSocialUser, const FUniqueNetId& InGroupId) +{ + GroupId = InGroupId; + SocialUser = &InSocialUser; + GroupInterfacePtr = InGroupInterface; + + const FUniqueNetIdRepl UserId = SocialUser->GetUserId(ESocialSubsystem::Primary); + InGroupInterface->QueryGroupInfo(*UserId, *GroupId, FOnGroupsRequestCompleted::CreateUObject(this, &ThisClass::RefreshCompleted_GroupInfo)); + InGroupInterface->QueryGroupRoster(*UserId, *GroupId, FOnGroupsRequestCompleted::CreateUObject(this, &ThisClass::RefreshCompleted_Roster)); +} + +void USocialGroupChannel::RefreshCompleted_GroupInfo(FGroupsResult Result) +{ + IOnlineGroupsPtr GroupInterface = GroupInterfacePtr.Pin(); + + if (GroupInterface.IsValid()) + { + const FUniqueNetIdRepl UserId = SocialUser->GetUserId(ESocialSubsystem::Primary); + TSharedPtr Info = GroupInterface->GetCachedGroupInfo(*UserId, *GroupId); + if (Info.IsValid()) + { + // TODO + } + } +} + +void USocialGroupChannel::RefreshCompleted_Roster(FGroupsResult Result) +{ + IOnlineGroupsPtr GroupInterface = GroupInterfacePtr.Pin(); + + if (GroupInterface.IsValid()) + { + USocialToolkit& OwningToolkit = SocialUser->GetOwningToolkit(); + const FUniqueNetIdRepl UserId = SocialUser->GetUserId(ESocialSubsystem::Primary); + + TSharedPtr Roster = GroupInterface->GetCachedGroupRoster(*UserId, *GroupId); + if (Roster.IsValid()) + { + TArray GroupMembers; + Roster->CopyEntries(GroupMembers); + + Members.Reset(); + for (const FGroupMember& GroupMember : GroupMembers) + { + // MERGE-REVIEW: Was changed from FindOrCreate + USocialUser* NewUser = OwningToolkit.FindUser(GroupMember.GetId()); + Members.Add(NewUser); + } + } + } +} \ No newline at end of file diff --git a/Engine/Plugins/Online/OnlineFramework/Source/Party/Private/SocialToolkit.cpp b/Engine/Plugins/Online/OnlineFramework/Source/Party/Private/SocialToolkit.cpp index 41ccc2d87cd7..41a52e3c579a 100644 --- a/Engine/Plugins/Online/OnlineFramework/Source/Party/Private/SocialToolkit.cpp +++ b/Engine/Plugins/Online/OnlineFramework/Source/Party/Private/SocialToolkit.cpp @@ -276,6 +276,15 @@ void USocialToolkit::QueueUserDependentAction(const FUniqueNetIdRepl& UserId, TF } } +void USocialToolkit::QueueUserDependentAction(const FUniqueNetIdRepl& SubsystemId, FUserDependentAction UserActionDelegate) +{ + // MERGE-REVIEW: Was changed from FindOrCreate + if (USocialUser* SocialUser = FindUser(SubsystemId)) + { + SocialUser->RegisterInitCompleteHandler(UserActionDelegate); + } +} + void USocialToolkit::QueueUserDependentActionInternal(const FUniqueNetIdRepl& SubsystemId, ESocialSubsystem SubsystemType, TFunction&& UserActionFunc, bool bExecutePostInit) { if (!ensure(SubsystemId.IsValid())) diff --git a/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/Chat/SocialChatManager.cpp b/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/Chat/SocialChatManager.cpp index a8e2251e1948..38f1dbe9e45f 100644 --- a/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/Chat/SocialChatManager.cpp +++ b/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/Chat/SocialChatManager.cpp @@ -11,6 +11,7 @@ #include "SocialChatChannel.h" #include "SocialManager.h" #include "Party/SocialParty.h" +#include "Interfaces/OnlineGroupsInterface.h" #include "SocialPartyChatRoom.h" #include "ChatSlashCommands.h" @@ -265,6 +266,11 @@ void USocialChatManager::InitializeChatManager() { // separate warning? this is the expected result of running a subsystem-less execution (testing / no network) } + + + // KAIROS INIT + // MERGE-REVIEW: OnFinishedStartupQueries has bee removed + //OwningToolkit.OnFinishedStartupQueries().AddUObject(this, &ThisClass::InitializeGroupChannels); } IOnlineChatPtr USocialChatManager::GetOnlineChatInterface(ESocialSubsystem InSocialSubsystem) const @@ -465,3 +471,100 @@ ESocialChannelType USocialChatManager::TryChannelTypeLookupByRoomId(const FChatR { return ESocialChannelType::System; } + + +//---------------------------------------------------------------------- +// KIAROS GROUP MANAGEMENT, tbd channels? + +void USocialChatManager::InitializeGroupChannels() +{ + ESocialSubsystem InSocialSubsystem = ESocialSubsystem::Primary; + + GetOwningToolkit().QueueUserDependentAction( + GetOwningToolkit().GetLocalUserNetId(InSocialSubsystem), FUserDependentAction::CreateUObject(this, &ThisClass::LocalUserInitialized)); +} + +void USocialChatManager::LocalUserInitialized(USocialUser& LocalUser) +{ + ESocialSubsystem InSocialSubsystem = ESocialSubsystem::Primary; + + IOnlineGroupsPtr GroupInterface = GetOnlineGroupInterface(); + if (GroupInterface.IsValid()) + { + GroupInterface->OnGroupUpdated.AddUObject(this, &ThisClass::OnGroupUpdated); + + const TSharedPtr LocalUserNetId = LocalUser.GetUserId(InSocialSubsystem).GetUniqueNetId(); + check(LocalUserNetId.IsValid()); + + GroupInterface->QueryUserMembership(*LocalUserNetId.Get(), *LocalUserNetId.Get(), FOnGroupsRequestCompleted::CreateUObject(this, &ThisClass::RefreshGroupsRequestCompleted)); + } +} + +void USocialChatManager::RefreshGroupsRequestCompleted(FGroupsResult Result) +{ + IOnlineGroupsPtr GroupInterface = GetOnlineGroupInterface(); + if (GroupInterface.IsValid()) + { + USocialToolkit& OwningToolkit = GetOwningToolkit(); + + USocialUser& LocalUser = OwningToolkit.GetLocalUser(); + const TSharedPtr LocalUserNetId = LocalUser.GetUserId(ESocialSubsystem::Primary).GetUniqueNetId(); + check(LocalUserNetId.IsValid()); + + TSharedPtr Membership = GroupInterface->GetCachedUserMembership(*LocalUserNetId.Get(), *LocalUserNetId.Get()); + if (Membership.IsValid()) + { + TArray GroupMemberships; + Membership->CopyEntries(GroupMemberships); + + for (const FUserMembershipEntry& Entry : GroupMemberships) + { + USocialGroupChannel& GroupChannel = FindOrCreateGroupChannel(GroupInterface, *Entry.GroupId.Get()); + GroupChannel.SetDisplayName(Entry.Name); + } + } + } +} + +void USocialChatManager::OnGroupUpdated(const FUniqueNetId& GroupId) +{ + printf(""); +} + +void USocialChatManager::GetGroupChannels(TArray& JoinedChannels) const +{ + for (auto& Entry : GroupChannels) + { + JoinedChannels.Add(Entry.Value); + } +} + +IOnlineGroupsPtr USocialChatManager::GetOnlineGroupInterface(ESocialSubsystem InSocialSubsystem) const +{ + if (IOnlineSubsystem* OnlineSub = GetOwningToolkit().GetSocialOss(InSocialSubsystem)) + { + return OnlineSub->GetGroupsInterface(); + } + + return nullptr; +} + +USocialGroupChannel& USocialChatManager::FindOrCreateGroupChannel(IOnlineGroupsPtr InGroupInterface, const FUniqueNetId& GroupId) +{ + TSubclassOf NewGroupClass = GetClassForGroupChannel(); + check(NewGroupClass); + + USocialGroupChannel* NewGroupChannel = NewObject(this, NewGroupClass); + check(NewGroupChannel); + + GroupChannels.Add(FUniqueNetIdRepl(GroupId), NewGroupChannel); + + NewGroupChannel->Initialize(InGroupInterface, GetOwningToolkit().GetLocalUser(), GroupId); + + //TODO + //OnChannelCreated().Broadcast(*NewRoomChannel); + + return *NewGroupChannel; +} + +//---------------------------------------------------------------------- \ No newline at end of file diff --git a/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/Chat/SocialChatManager.h b/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/Chat/SocialChatManager.h index 910020b6215c..eef8a7588e9d 100644 --- a/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/Chat/SocialChatManager.h +++ b/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/Chat/SocialChatManager.h @@ -9,6 +9,8 @@ #include "SocialReadOnlyChatChannel.h" #include "SocialPrivateMessageChannel.h" #include "SocialChatRoom.h" +#include "SocialGroupChannel.h" +#include "Interfaces/OnlineGroupsInterface.h" #include "SocialChatManager.generated.h" class USocialChatRoom; @@ -101,6 +103,7 @@ public: virtual TSubclassOf GetClassForReadOnlyChannel() const { return USocialReadOnlyChatChannel::StaticClass(); } virtual bool IsChatRestricted() const; + virtual TSubclassOf GetClassForGroupChannel() const { return USocialGroupChannel::StaticClass(); } USocialToolkit& GetOwningToolkit() const; @@ -109,6 +112,31 @@ public: USocialChatChannel* GetChatRoomForType(ESocialChannelType Key); + + + //---------------------------------------------------------------------- + // KIAROS GROUP MANAGEMENT, tbd channels? + +public: + + virtual void GetGroupChannels(TArray& JoinedChannels) const; + + //DECLARE_EVENT_OneParam(USocialChatManager, FOnChatChannelFocusRequested, USocialChatChannel&); + //FOnChatChannelFocusRequested& OnGroupsChanged() const { return OnChannelFocusRequestedEvent; } + +protected: + virtual void InitializeGroupChannels(); + void LocalUserInitialized(USocialUser& LocalUser); + void RefreshGroupsRequestCompleted(FGroupsResult Result); + + IOnlineGroupsPtr GetOnlineGroupInterface(ESocialSubsystem InSocialSubsystem = ESocialSubsystem::Primary) const; + USocialGroupChannel& FindOrCreateGroupChannel(IOnlineGroupsPtr InGroupInterface, const FUniqueNetId& GroupId); + + void OnGroupUpdated(const FUniqueNetId& GroupId); + + // END KIAROS GROUP MANAGEMENT + //---------------------------------------------------------------------- + protected: IOnlineChatPtr GetOnlineChatInterface(ESocialSubsystem InSocialSubsystem = ESocialSubsystem::Primary) const; virtual void InitializeChatManager(); @@ -154,6 +182,9 @@ private: UPROPERTY(config) bool bEnableChatSlashCommands = true; + + UPROPERTY() + TMap GroupChannels; mutable FOnChatChannelCreated OnChannelCreatedEvent; mutable FOnChatChannelLeft OnChannelLeftEvent; diff --git a/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/Chat/SocialGroupChannel.h b/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/Chat/SocialGroupChannel.h new file mode 100644 index 000000000000..c63fb0006f27 --- /dev/null +++ b/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/Chat/SocialGroupChannel.h @@ -0,0 +1,48 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "Chat/SocialChatChannel.h" +#include "UObject/CoreOnline.h" +#include "Interfaces/OnlineGroupsInterface.h" +#include "SocialGroupChannel.generated.h" + +class USocialUser; + +/** + * + */ +UCLASS() +class PARTY_API USocialGroupChannel : public UObject +{ + GENERATED_BODY() + +public: + USocialGroupChannel(); + + void Initialize(IOnlineGroupsPtr InGroupInterface, USocialUser& InSocialUser, const FUniqueNetId& InGroupId); + + void SetDisplayName(const FText& InDisplayName) { DisplayName = InDisplayName; } + FText GetDisplayName() const { return DisplayName; } + + const TArray& GetMembers() const { return Members; } + +private: + void RefreshCompleted_GroupInfo(FGroupsResult Result); + void RefreshCompleted_Roster(FGroupsResult Result); + +private: + UPROPERTY() + USocialUser* SocialUser; + + UPROPERTY() + FUniqueNetIdRepl GroupId; + + UPROPERTY() + FText DisplayName; + + UPROPERTY() + TArray Members; + + TWeakPtr GroupInterfacePtr; +}; \ No newline at end of file diff --git a/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/SocialToolkit.h b/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/SocialToolkit.h index 6c8059992361..a4b5fd73b525 100644 --- a/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/SocialToolkit.h +++ b/Engine/Plugins/Online/OnlineFramework/Source/Party/Public/SocialToolkit.h @@ -21,6 +21,8 @@ enum class EMemberExitedReason; namespace EOnlinePresenceState { enum Type : uint8; } +DECLARE_DELEGATE_OneParam(FUserDependentAction, USocialUser&); + /** Represents the full suite of social functionality available to a given LocalPlayer */ UCLASS(Within = SocialManager) class PARTY_API USocialToolkit : public UObject @@ -42,6 +44,7 @@ public: TSharedRef CreateUserList(const FSocialUserListConfig& ListConfig); USocialUser& GetLocalUser() const; + FUniqueNetIdRepl GetLocalUserNetId(ESocialSubsystem SubsystemType) const; int32 GetLocalUserNum() const; @@ -71,6 +74,7 @@ public: */ void TrySendFriendInvite(const FString& DisplayNameOrEmail) const; + void QueueUserDependentAction(const FUniqueNetIdRepl& SubsystemId, FUserDependentAction UserActionDelegate); void RequestDisplayPlatformSocialUI() const; const FString& GetRecentPlayerNamespaceToQuery() const { return RecentPlayerNamespaceToQuery; } diff --git a/Engine/Plugins/Online/OnlineSubsystem/Source/Private/OnlineKeyValuePair.cpp b/Engine/Plugins/Online/OnlineSubsystem/Source/Private/OnlineKeyValuePair.cpp index d5c75e8b1ba4..965eb7b123e0 100644 --- a/Engine/Plugins/Online/OnlineSubsystem/Source/Private/OnlineKeyValuePair.cpp +++ b/Engine/Plugins/Online/OnlineSubsystem/Source/Private/OnlineKeyValuePair.cpp @@ -800,6 +800,55 @@ bool FVariantData::FromJson(const TSharedRef& JsonObject) return bResult; } +FString FVariantData::GetTypeSuffix() const +{ + switch (Type) + { + case EOnlineKeyValuePairDataType::Int32: + { + return TEXT("_i"); + } + case EOnlineKeyValuePairDataType::UInt32: + { + return TEXT("_u"); + } + case EOnlineKeyValuePairDataType::Float: + { + return TEXT("_f"); + } + case EOnlineKeyValuePairDataType::String: + { + return TEXT("_s"); + } + case EOnlineKeyValuePairDataType::Bool: + { + return TEXT("_b"); + } + case EOnlineKeyValuePairDataType::Int64: + { + return TEXT("_I"); + } + case EOnlineKeyValuePairDataType::UInt64: + { + return TEXT("_U"); + } + case EOnlineKeyValuePairDataType::Double: + { + return TEXT("_d"); + } + case EOnlineKeyValuePairDataType::Json: + { + return TEXT("_j"); + } + case EOnlineKeyValuePairDataType::Empty: + case EOnlineKeyValuePairDataType::Blob: + default: + break; + } + // Default to no suffix + return TEXT(""); +} + void FVariantData::AddToJsonObject(const TSharedRef& JsonObject, const FString& Name, const bool bWithTypeSuffix /* = true*/) const { switch (Type) @@ -962,12 +1011,25 @@ bool FVariantData::FromJsonValue(const FString& JsonPropertyName, const TSharedR } case TEXT('j'): { - const TSharedPtr* FieldValue; - if (JsonValue->TryGetObject(FieldValue)) + const TSharedPtr* FieldValueObject; + FString FieldValueString; + if (JsonValue->TryGetObject(FieldValueObject)) // Try to read as a JSON object { - SetValue((*FieldValue).ToSharedRef()); + SetValue((*FieldValueObject).ToSharedRef()); bResult = true; } + else if (JsonValue->TryGetString(FieldValueString)) // Try to read as a JSON string + { + SetJsonValueFromString(FieldValueString); +#if !UE_BUILD_SHIPPING + // See if this was a valid JSON string + TSharedPtr ValidJsonObject; + GetValue(ValidJsonObject); + bResult = ValidJsonObject.IsValid(); +#else + bResult = true; +#endif + } } default: break; diff --git a/Engine/Plugins/Online/OnlineSubsystem/Source/Private/OnlinePartyInterface.cpp b/Engine/Plugins/Online/OnlineSubsystem/Source/Private/OnlinePartyInterface.cpp index 827c3f9003f9..749136690efc 100644 --- a/Engine/Plugins/Online/OnlineSubsystem/Source/Private/OnlinePartyInterface.cpp +++ b/Engine/Plugins/Online/OnlineSubsystem/Source/Private/OnlinePartyInterface.cpp @@ -130,6 +130,11 @@ void FOnlinePartyData::FromJson(const FString& JsonString) } } +FString FPartyInvitationRecipient::ToDebugString() const +{ + return FString::Printf(TEXT("Id=[%s], PlatformData=[%s]"), *Id->ToDebugString(), *PlatformData); +} + bool FPartyConfiguration::operator==(const FPartyConfiguration& Other) const { return JoinRequestAction == Other.JoinRequestAction && diff --git a/Engine/Plugins/Online/OnlineSubsystem/Source/Private/OnlineSubsystemModule.cpp b/Engine/Plugins/Online/OnlineSubsystem/Source/Private/OnlineSubsystemModule.cpp index 21e68a2caab3..83f6d0ffd384 100644 --- a/Engine/Plugins/Online/OnlineSubsystem/Source/Private/OnlineSubsystemModule.cpp +++ b/Engine/Plugins/Online/OnlineSubsystem/Source/Private/OnlineSubsystemModule.cpp @@ -310,7 +310,7 @@ IOnlineSubsystem* FOnlineSubsystemModule::GetOnlineSubsystem(const FName InSubsy { OnlineSubsystems.Add(KeyName, NewSubsystemInstance); OnlineSubsystem = OnlineSubsystems.Find(KeyName); - FOnlineSubsystemDelegates::OnOnlineSubsystemCreated.Broadcast(NewSubsystemInstance.Get()); + FOnlineSubsystemDelegates::OnOnlineSubsystemCreated.Broadcast(NewSubsystemInstance.Get()); } else { diff --git a/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlineDeviceNotificationInterface.h b/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlineDeviceNotificationInterface.h new file mode 100644 index 000000000000..43002934442c --- /dev/null +++ b/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlineDeviceNotificationInterface.h @@ -0,0 +1,50 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" + +struct FOnlineError; + +/** + * Delegate used when the register device request is completed + * + * @param FOnlineError The Result of the Request + */ +DECLARE_DELEGATE_OneParam(FOnRegisterDeviceComplete, const FOnlineError& /*Result*/); + +/** + * Delegate used when the unregister device by channel type request is completed + * + * @param FOnlineError The Result of the Request + */ +DECLARE_DELEGATE_OneParam(FOnUnregisterDeviceByChannelTypeComplete, const FOnlineError& /*Result*/); + +/** + * IOnlineDeviceNotification - Interface for communications service + */ +class IOnlineDeviceNotification +{ +public: + virtual ~IOnlineDeviceNotification() {} + + /** + * Initiate the create/register device process + * + * @param LocalUserId user making the request + * @param InstanceId the device registration token generated on the device + * @param ChannelType the channel being registered (for example: fcm) + * @param Delegate completion callback (guaranteed to be called) + */ + virtual void RegisterDevice(const FUniqueNetId& LocalUserId, const FString& InstanceId, const FString& ChannelType, const FOnRegisterDeviceComplete& Delegate) = 0; + + /** + * Initiate the unregister device by channel type process + * + * @param LocalUserId user making the request + * @param InstanceId the device registration token generated on the device + * @param ChannelType the channel being unregistered (for example: fcm) + * @param Delegate completion callback (guaranteed to be called) + */ + virtual void UnregisterDeviceByChannelType(const FUniqueNetId& LocalUserId, const FString& InstanceId, const FString& ChannelType, const FOnUnregisterDeviceByChannelTypeComplete& Delegate) = 0; +}; diff --git a/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlineFriendsInterface.h b/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlineFriendsInterface.h index 3fe893f8d1cc..48364003c720 100644 --- a/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlineFriendsInterface.h +++ b/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlineFriendsInterface.h @@ -119,7 +119,7 @@ typedef FOnOutgoingInviteSent::FDelegate FOnOutgoingInviteSentDelegate; * @param ListName name of the friends list that was operated on * @param ErrorStr string representing the error condition */ -DECLARE_DELEGATE_FourParams(FOnReadFriendsListComplete, int32, bool, const FString&, const FString&); +DECLARE_DELEGATE_FourParams(FOnReadFriendsListComplete, int32 /*LocalUserNum*/, bool /*bWasSuccessful*/, const FString& /*ListName*/, const FString& /*ErrorStr*/); /** * Delegate used when the friends list delete request has completed @@ -129,7 +129,7 @@ DECLARE_DELEGATE_FourParams(FOnReadFriendsListComplete, int32, bool, const FStri * @param ListName name of the friends list that was operated on * @param ErrorStr string representing the error condition */ -DECLARE_DELEGATE_FourParams(FOnDeleteFriendsListComplete, int32, bool, const FString&, const FString&); +DECLARE_DELEGATE_FourParams(FOnDeleteFriendsListComplete, int32 /*LocalUserNum*/, bool /*bWasSuccessful*/, const FString& /*ListName*/, const FString& /*ErrorStr*/); /** * Delegate used when an invite send request has completed @@ -140,7 +140,7 @@ DECLARE_DELEGATE_FourParams(FOnDeleteFriendsListComplete, int32, bool, const FSt * @param ListName name of the friends list that was operated on * @param ErrorStr string representing the error condition */ -DECLARE_DELEGATE_FiveParams(FOnSendInviteComplete, int32, bool, const FUniqueNetId&, const FString&, const FString&); +DECLARE_DELEGATE_FiveParams(FOnSendInviteComplete, int32 /*LocalUserNum*/, bool /*bWasSuccessful*/, const FUniqueNetId& /*FriendId*/, const FString& /*ListName*/, const FString& /*ErrorStr*/); /** * Delegate used when an invite accept request has completed @@ -151,7 +151,7 @@ DECLARE_DELEGATE_FiveParams(FOnSendInviteComplete, int32, bool, const FUniqueNet * @param ListName name of the friends list that was operated on * @param ErrorStr string representing the error condition */ -DECLARE_DELEGATE_FiveParams(FOnAcceptInviteComplete, int32, bool, const FUniqueNetId&, const FString&, const FString&); +DECLARE_DELEGATE_FiveParams(FOnAcceptInviteComplete, int32 /*LocalUserNum*/, bool /*bWasSuccessful*/, const FUniqueNetId& /*FriendId*/, const FString& /*ListName*/, const FString& /*ErrorStr*/); /** * Delegate used when an invite reject request has completed @@ -162,7 +162,7 @@ DECLARE_DELEGATE_FiveParams(FOnAcceptInviteComplete, int32, bool, const FUniqueN * @param ListName name of the friends list that was operated on * @param ErrorStr string representing the error condition */ -DECLARE_MULTICAST_DELEGATE_FiveParams(FOnRejectInviteComplete, int32, bool, const FUniqueNetId&, const FString&, const FString&); +DECLARE_MULTICAST_DELEGATE_FiveParams(FOnRejectInviteComplete, int32 /*LocalUserNum*/, bool /*bWasSuccessful*/, const FUniqueNetId& /*FriendId*/, const FString& /*ListName*/, const FString& /*ErrorStr*/); typedef FOnRejectInviteComplete::FDelegate FOnRejectInviteCompleteDelegate; /** @@ -174,7 +174,7 @@ typedef FOnRejectInviteComplete::FDelegate FOnRejectInviteCompleteDelegate; * @param ListName name of the friends list that was operated on * @param ErrorStr string representing the error condition */ -DECLARE_MULTICAST_DELEGATE_FiveParams(FOnDeleteFriendComplete, int32, bool, const FUniqueNetId&, const FString&, const FString&); +DECLARE_MULTICAST_DELEGATE_FiveParams(FOnDeleteFriendComplete, int32 /*LocalUserNum*/, bool /*bWasSuccessful*/, const FUniqueNetId& /*FriendId*/, const FString& /*ListName*/, const FString& /*ErrorStr*/); typedef FOnDeleteFriendComplete::FDelegate FOnDeleteFriendCompleteDelegate; /** @@ -186,7 +186,7 @@ typedef FOnDeleteFriendComplete::FDelegate FOnDeleteFriendCompleteDelegate; * @param ListName name of the friends list that was operated on * @param ErrorStr string representing the error condition */ -DECLARE_MULTICAST_DELEGATE_FiveParams(FOnBlockedPlayerComplete, int32, bool, const FUniqueNetId&, const FString&, const FString&); +DECLARE_MULTICAST_DELEGATE_FiveParams(FOnBlockedPlayerComplete, int32 /*LocalUserNum*/, bool /*bWasSuccessful*/, const FUniqueNetId& /*UniqueID*/, const FString& /*ListName*/, const FString& /*ErrorStr*/); typedef FOnBlockedPlayerComplete::FDelegate FOnBlockedPlayerCompleteDelegate; /** @@ -198,7 +198,7 @@ typedef FOnBlockedPlayerComplete::FDelegate FOnBlockedPlayerCompleteDelegate; * @param ListName name of the friends list that was operated on * @param ErrorStr string representing the error condition */ -DECLARE_MULTICAST_DELEGATE_FiveParams(FOnUnblockedPlayerComplete, int32, bool, const FUniqueNetId&, const FString&, const FString&); +DECLARE_MULTICAST_DELEGATE_FiveParams(FOnUnblockedPlayerComplete, int32 /*LocalUserNum*/, bool /*bWasSuccessful*/, const FUniqueNetId& /*UniqueID*/, const FString& /*ListName*/, const FString& /*ErrorStr*/); typedef FOnUnblockedPlayerComplete::FDelegate FOnUnblockedPlayerCompleteDelegate; /** @@ -320,7 +320,7 @@ typedef FOnFriendRemoved::FDelegate FOnFriendRemovedDelegate; * @param Settings settings retrieved / updated * @param ErrorStr string representing the error condition */ -DECLARE_DELEGATE_FiveParams(FOnSettingsOperationComplete, const FUniqueNetId&, bool, bool, const FFriendSettings&, const FString&); +DECLARE_DELEGATE_FiveParams(FOnSettingsOperationComplete, const FUniqueNetId& /*UserId*/, bool /*bWasSuccessful*/, bool /*bWasUpdate*/, const FFriendSettings& /*Settings*/, const FString& /*ErrorStr*/); /** * Interface definition for the online services friends services @@ -446,7 +446,7 @@ public: * @param ListName name of the friends list that was operated on * @param ErrorStr string representing the error condition */ - DEFINE_ONLINE_PLAYER_DELEGATE_FOUR_PARAM(MAX_LOCAL_PLAYERS, OnRejectInviteComplete, bool, const FUniqueNetId&, const FString&, const FString&); + DEFINE_ONLINE_PLAYER_DELEGATE_FOUR_PARAM(MAX_LOCAL_PLAYERS, OnRejectInviteComplete, bool /*bWasSuccessful*/, const FUniqueNetId& /*FriendId*/, const FString& /*ListName*/, const FString& /*ErrorStr*/); /** * Starts an async task that deletes a friend from the named friends list @@ -468,29 +468,29 @@ public: * @param ListName name of the friends list that was operated on * @param ErrorStr string representing the error condition */ - DEFINE_ONLINE_PLAYER_DELEGATE_FOUR_PARAM(MAX_LOCAL_PLAYERS, OnDeleteFriendComplete, bool, const FUniqueNetId&, const FString&, const FString&); + DEFINE_ONLINE_PLAYER_DELEGATE_FOUR_PARAM(MAX_LOCAL_PLAYERS, OnDeleteFriendComplete, bool /*bWasSuccessful*/, const FUniqueNetId& /*FriendId*/, const FString& /*ListName*/, const FString& /*ErrorStr*/); /** * Delegate used when a block player request has completed * * @param LocalUserNum the controller number of the associated user that made the request * @param bWasSuccessful true if the async action completed without error, false if there was an error - * @param UniqueIF player that was blocked + * @param UniqueId player that was blocked * @param ListName name of the friends list that was operated on * @param ErrorStr string representing the error condition */ - DEFINE_ONLINE_PLAYER_DELEGATE_FOUR_PARAM(MAX_LOCAL_PLAYERS, OnBlockedPlayerComplete, bool, const FUniqueNetId&, const FString&, const FString&); + DEFINE_ONLINE_PLAYER_DELEGATE_FOUR_PARAM(MAX_LOCAL_PLAYERS, OnBlockedPlayerComplete, bool /*bWasSuccessful*/, const FUniqueNetId& /*UniqueId*/, const FString& /*ListName*/, const FString& /*ErrorStr*/); /** - * Delegate used when an ublock player request has completed + * Delegate used when an unblock player request has completed * * @param LocalUserNum the controller number of the associated user that made the request * @param bWasSuccessful true if the async action completed without error, false if there was an error - * @param UniqueIF player that was unblocked + * @param UniqueId player that was unblocked * @param ListName name of the friends list that was operated on * @param ErrorStr string representing the error condition */ - DEFINE_ONLINE_PLAYER_DELEGATE_FOUR_PARAM(MAX_LOCAL_PLAYERS, OnUnblockedPlayerComplete, bool, const FUniqueNetId&, const FString&, const FString&); + DEFINE_ONLINE_PLAYER_DELEGATE_FOUR_PARAM(MAX_LOCAL_PLAYERS, OnUnblockedPlayerComplete, bool /*bWasSuccessful*/, const FUniqueNetId& /*UniqueId*/, const FString& /*ListName*/, const FString& /*ErrorStr*/); /** * Delegate used in block list change notifications diff --git a/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlineGroupsInterface.h b/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlineGroupsInterface.h index dc8b89c64d4d..ce8fdb73e17f 100644 --- a/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlineGroupsInterface.h +++ b/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlineGroupsInterface.h @@ -338,15 +338,13 @@ DECLARE_DELEGATE_OneParam(FOnGroupsRequestCompleted, FGroupsResult); */ struct FFindGroupsResult { - int32 HttpStatus; + bool bDidSucceed; TArray< TSharedPtr > MatchingGroups; FPagedQuery Paging; FString ErrorContent; - inline bool DidSucceed() const { return EHttpResponseCodes::IsOk(HttpStatus); } - FFindGroupsResult() - : HttpStatus(0) + : bDidSucceed(false) { } }; diff --git a/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlinePartyInterface.h b/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlinePartyInterface.h index 956828b18f32..f7a12a049f79 100644 --- a/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlinePartyInterface.h +++ b/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlinePartyInterface.h @@ -491,19 +491,26 @@ enum class EMemberExitedReason Kicked }; +/** Recipient information for SendInvitation */ struct FPartyInvitationRecipient { + /** Constructor */ FPartyInvitationRecipient(const TSharedRef& InId) : Id(InId) - {} + {} + /** Constructor */ FPartyInvitationRecipient(const FUniqueNetId& InId) : Id(InId.AsShared()) {} - + /** Id of the user to send the invitation to */ TSharedRef Id; + /** Additional data to provide context for the invitee */ FString PlatformData; + + /** Get a string representation suitable for logging */ + FString ONLINESUBSYSTEM_API ToDebugString() const; }; diff --git a/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlinePresenceInterface.h b/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlinePresenceInterface.h index 08b533a1eda8..eb0fa325c661 100644 --- a/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlinePresenceInterface.h +++ b/Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces/OnlinePresenceInterface.h @@ -82,6 +82,39 @@ namespace EOnlinePresenceState return TEXT(""); } + /** + * @return EOnlinePresenceState from the string passed in + */ + inline EOnlinePresenceState::Type FromString(const TCHAR* StringVal) + { + if (FCString::Stricmp(StringVal, TEXT("Online")) == 0) + { + return EOnlinePresenceState::Online; + } + else if (FCString::Stricmp(StringVal, TEXT("Offline")) == 0) + { + return EOnlinePresenceState::Offline; + } + else if (FCString::Stricmp(StringVal, TEXT("Away")) == 0) + { + return EOnlinePresenceState::Away; + } + else if (FCString::Stricmp(StringVal, TEXT("ExtendedAway")) == 0) + { + return EOnlinePresenceState::ExtendedAway; + } + else if (FCString::Stricmp(StringVal, TEXT("DoNotDisturb")) == 0) + { + return EOnlinePresenceState::DoNotDisturb; + } + else if (FCString::Stricmp(StringVal, TEXT("Chat")) == 0) + { + return EOnlinePresenceState::Chat; + } + // Default to Offline / generally unavailable + return EOnlinePresenceState::Offline; + } + static FText OnlineText = NSLOCTEXT("OnlinePresence", "Online", "Online"); static FText OfflineText = NSLOCTEXT("OnlinePresence", "Offline", "Offline"); static FText AwayText = NSLOCTEXT("OnlinePresence", "Away", "Away"); diff --git a/Engine/Plugins/Online/OnlineSubsystem/Source/Public/OnlineKeyValuePair.h b/Engine/Plugins/Online/OnlineSubsystem/Source/Public/OnlineKeyValuePair.h index 3416acd92c88..6767ced57b9c 100644 --- a/Engine/Plugins/Online/OnlineSubsystem/Source/Public/OnlineKeyValuePair.h +++ b/Engine/Plugins/Online/OnlineSubsystem/Source/Public/OnlineKeyValuePair.h @@ -425,6 +425,13 @@ public: */ bool FromJson(const TSharedRef& JsonObject); + /** + * Combine the type suffix given this variant's type + * + * @return the the type suffix + */ + FString GetTypeSuffix() const; + /** * Insert variant data into json object * diff --git a/Engine/Plugins/Online/OnlineSubsystemFacebook/Source/Private/Android/OnlineIdentityFacebook.cpp b/Engine/Plugins/Online/OnlineSubsystemFacebook/Source/Private/Android/OnlineIdentityFacebook.cpp index a37064427b00..f960806249c8 100644 --- a/Engine/Plugins/Online/OnlineSubsystemFacebook/Source/Private/Android/OnlineIdentityFacebook.cpp +++ b/Engine/Plugins/Online/OnlineSubsystemFacebook/Source/Private/Android/OnlineIdentityFacebook.cpp @@ -254,13 +254,8 @@ FString AndroidThunkCpp_Facebook_GetAccessToken() const bool bIsOptional = false; static jmethodID FacebookGetAccessTokenMethod = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_Facebook_GetAccessToken", "()Ljava/lang/String;", bIsOptional); CHECK_JNI_METHOD(FacebookGetAccessTokenMethod); - - jstring accessToken = (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, FacebookGetAccessTokenMethod); - - const char* charsAccessToken = Env->GetStringUTFChars(accessToken, 0); - AccessToken = FString(UTF8_TO_TCHAR(charsAccessToken)); - Env->ReleaseStringUTFChars(accessToken, charsAccessToken); - Env->DeleteLocalRef(accessToken); + + AccessToken = FJavaHelper::FStringFromLocalRef(Env, (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, FacebookGetAccessTokenMethod)); } return AccessToken; @@ -277,18 +272,15 @@ bool AndroidThunkCpp_Facebook_Login(const TArray& InScopeFields) CHECK_JNI_METHOD(FacebookLoginMethod); // Convert scope array into java fields - jobjectArray ScopeIDArray = (jobjectArray)Env->NewObjectArray(InScopeFields.Num(), FJavaWrapper::JavaStringClass, nullptr); + auto ScopeIDArray = NewScopedJavaObject(Env, (jobjectArray)Env->NewObjectArray(InScopeFields.Num(), FJavaWrapper::JavaStringClass, nullptr)); for (uint32 Param = 0; Param < InScopeFields.Num(); Param++) { - jstring StringValue = Env->NewStringUTF(TCHAR_TO_UTF8(*InScopeFields[Param])); - Env->SetObjectArrayElement(ScopeIDArray, Param, StringValue); - Env->DeleteLocalRef(StringValue); + auto StringValue = FJavaHelper::ToJavaString(Env, InScopeFields[Param]); + Env->SetObjectArrayElement(*ScopeIDArray, Param, *StringValue); } - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FacebookLoginMethod, ScopeIDArray); - - // clean up references - Env->DeleteLocalRef(ScopeIDArray); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FacebookLoginMethod, *ScopeIDArray); + bSuccess = true; } @@ -299,10 +291,8 @@ JNI_METHOD void Java_com_epicgames_ue4_FacebookLogin_nativeLoginComplete(JNIEnv* { EFacebookLoginResponse LoginResponse = (EFacebookLoginResponse)responseCode; - const char* charsAccessToken = jenv->GetStringUTFChars(accessToken, 0); - FString AccessToken = FString(UTF8_TO_TCHAR(charsAccessToken)); - jenv->ReleaseStringUTFChars(accessToken, charsAccessToken); - + auto AccessToken = FJavaHelper::FStringFromParam(jenv, accessToken); + UE_LOG_ONLINE_IDENTITY(VeryVerbose, TEXT("nativeLoginComplete Response: %d Token: %s"), (int)LoginResponse, *AccessToken); DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.ProcessFacebookLogin"), STAT_FSimpleDelegateGraphTask_ProcessFacebookLogin, STATGROUP_TaskGraphTasks); diff --git a/Engine/Plugins/Online/OnlineSubsystemFacebook/Source/Private/Android/OnlineSharingFacebook.cpp b/Engine/Plugins/Online/OnlineSubsystemFacebook/Source/Private/Android/OnlineSharingFacebook.cpp index 5986133a9fbd..081423cc6b24 100644 --- a/Engine/Plugins/Online/OnlineSubsystemFacebook/Source/Private/Android/OnlineSharingFacebook.cpp +++ b/Engine/Plugins/Online/OnlineSubsystemFacebook/Source/Private/Android/OnlineSharingFacebook.cpp @@ -180,18 +180,15 @@ bool AndroidThunkCpp_Facebook_RequestReadPermissions(const TArrayNewObjectArray(InNewPermissions.Num(), FJavaWrapper::JavaStringClass, nullptr); + auto PermsIDArray = NewScopedJavaObject(Env, (jobjectArray)Env->NewObjectArray(InNewPermissions.Num(), FJavaWrapper::JavaStringClass, nullptr)); for (uint32 Param = 0; Param < InNewPermissions.Num(); Param++) { - jstring StringValue = Env->NewStringUTF(TCHAR_TO_UTF8(*InNewPermissions[Param].Name)); - Env->SetObjectArrayElement(PermsIDArray, Param, StringValue); - Env->DeleteLocalRef(StringValue); + auto StringValue = FJavaHelper::ToJavaString(Env, InNewPermissions[Param].Name); + Env->SetObjectArrayElement(*PermsIDArray, Param, *StringValue); } - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FacebookRequestReadMethod, PermsIDArray); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FacebookRequestReadMethod, *PermsIDArray); - // clean up references - Env->DeleteLocalRef(PermsIDArray); bSuccess = true; } @@ -201,11 +198,9 @@ bool AndroidThunkCpp_Facebook_RequestReadPermissions(const TArrayGetStringUTFChars(accessToken, 0); - FString AccessToken = FString(UTF8_TO_TCHAR(charsAccessToken)); - jenv->ReleaseStringUTFChars(accessToken, charsAccessToken); - + + auto AccessToken = FJavaHelper::FStringFromParam(jenv, accessToken); + UE_LOG_ONLINE_SHARING(VeryVerbose, TEXT("nativeRequestReadPermissionsComplete Response: %d Token: %s"), (int)LoginResponse, *AccessToken); DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.ProcessFacebookReadPermissions"), STAT_FSimpleDelegateGraphTask_ProcessFacebookReadPermissions, STATGROUP_TaskGraphTasks); @@ -239,18 +234,15 @@ bool AndroidThunkCpp_Facebook_RequestPublishPermissions(const TArrayNewObjectArray(InNewPermissions.Num(), FJavaWrapper::JavaStringClass, nullptr); + auto PermsIDArray = NewScopedJavaObject(Env, (jobjectArray)Env->NewObjectArray(InNewPermissions.Num(), FJavaWrapper::JavaStringClass, nullptr)); for (uint32 Param = 0; Param < InNewPermissions.Num(); Param++) { - jstring StringValue = Env->NewStringUTF(TCHAR_TO_UTF8(*InNewPermissions[Param].Name)); - Env->SetObjectArrayElement(PermsIDArray, Param, StringValue); - Env->DeleteLocalRef(StringValue); + auto StringValue = FJavaHelper::ToJavaString(Env, InNewPermissions[Param].Name); + Env->SetObjectArrayElement(*PermsIDArray, Param, *StringValue); } - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FacebookRequestPublishMethod, PermsIDArray); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FacebookRequestPublishMethod, *PermsIDArray); - // clean up references - Env->DeleteLocalRef(PermsIDArray); bSuccess = true; } @@ -261,10 +253,8 @@ JNI_METHOD void Java_com_epicgames_ue4_FacebookLogin_nativeRequestPublishPermiss { EFacebookLoginResponse LoginResponse = (EFacebookLoginResponse)responseCode; - const char* charsAccessToken = jenv->GetStringUTFChars(accessToken, 0); - FString AccessToken = FString(UTF8_TO_TCHAR(charsAccessToken)); - jenv->ReleaseStringUTFChars(accessToken, charsAccessToken); - + auto AccessToken = FJavaHelper::FStringFromParam(jenv, accessToken); + UE_LOG_ONLINE_SHARING(VeryVerbose, TEXT("nativeRequestPublishPermissionsComplete Response: %d Token: %s"), (int)LoginResponse, *AccessToken); DECLARE_CYCLE_STAT(TEXT("FSimpleDelegateGraphTask.ProcessFacebookPublishPermissions"), STAT_FSimpleDelegateGraphTask_ProcessFacebookPublishPermissions, STATGROUP_TaskGraphTasks); diff --git a/Engine/Plugins/Online/OnlineSubsystemGoogle/Source/Private/Android/OnlineIdentityGoogle.cpp b/Engine/Plugins/Online/OnlineSubsystemGoogle/Source/Private/Android/OnlineIdentityGoogle.cpp index 41c6cedea988..a688cb552254 100644 --- a/Engine/Plugins/Online/OnlineSubsystemGoogle/Source/Private/Android/OnlineIdentityGoogle.cpp +++ b/Engine/Plugins/Online/OnlineSubsystemGoogle/Source/Private/Android/OnlineIdentityGoogle.cpp @@ -299,10 +299,10 @@ int32 AndroidThunkCpp_Google_Init(const FString& InClientId, const FString& InSe CHECK_JNI_METHOD(GoogleInitGoogleMethod); //FPlatformMisc::LowLevelOutputDebugStringf(TEXT("GoogleInitGoogleMethod 0x%08x"), GoogleInitGoogleMethod); - jstring jClientAuthId = Env->NewStringUTF(TCHAR_TO_UTF8(*InClientId)); - jstring jServerAuthId = Env->NewStringUTF(TCHAR_TO_UTF8(*InServerId)); - - ReturnVal = FJavaWrapper::CallIntMethod(Env, FJavaWrapper::GameActivityThis, GoogleInitGoogleMethod, jClientAuthId, jServerAuthId); + auto jClientAuthId = FJavaHelper::ToJavaString(Env, InClientId); + auto jServerAuthId = FJavaHelper::ToJavaString(Env, InServerId); + + ReturnVal = FJavaWrapper::CallIntMethod(Env, FJavaWrapper::GameActivityThis, GoogleInitGoogleMethod, *jClientAuthId, *jServerAuthId); if (Env->ExceptionCheck()) { Env->ExceptionDescribe(); @@ -310,9 +310,6 @@ int32 AndroidThunkCpp_Google_Init(const FString& InClientId, const FString& InSe ReturnVal = GOOGLE_JNI_CPP_ERROR; } - Env->DeleteLocalRef(jClientAuthId); - Env->DeleteLocalRef(jServerAuthId); - FPlatformMisc::LowLevelOutputDebugStringf(TEXT("AndroidThunkJava_Google_Init retval=%d"), ReturnVal); } else @@ -334,15 +331,14 @@ int32 AndroidThunkCpp_Google_Login(const TArray& InScopeFields) UE_LOG_ONLINE_IDENTITY(Verbose, TEXT("GoogleLoginMethod 0x%08x"), GoogleLoginMethod); // Convert scope array into java fields - jobjectArray ScopeIDArray = (jobjectArray)Env->NewObjectArray(InScopeFields.Num(), FJavaWrapper::JavaStringClass, nullptr); + auto ScopeIDArray = NewScopedJavaObject(Env, (jobjectArray)Env->NewObjectArray(InScopeFields.Num(), FJavaWrapper::JavaStringClass, nullptr)); for (uint32 Param = 0; Param < InScopeFields.Num(); Param++) { - jstring StringValue = Env->NewStringUTF(TCHAR_TO_UTF8(*InScopeFields[Param])); - Env->SetObjectArrayElement(ScopeIDArray, Param, StringValue); - Env->DeleteLocalRef(StringValue); + auto StringValue = FJavaHelper::ToJavaString(Env, InScopeFields[Param]); + Env->SetObjectArrayElement(*ScopeIDArray, Param, *StringValue); } - ReturnVal = FJavaWrapper::CallIntMethod(Env, FJavaWrapper::GameActivityThis, GoogleLoginMethod, ScopeIDArray); + ReturnVal = FJavaWrapper::CallIntMethod(Env, FJavaWrapper::GameActivityThis, GoogleLoginMethod, *ScopeIDArray); if (Env->ExceptionCheck()) { Env->ExceptionDescribe(); @@ -350,8 +346,6 @@ int32 AndroidThunkCpp_Google_Login(const TArray& InScopeFields) ReturnVal = GOOGLE_JNI_CPP_ERROR; } - // clean up references - Env->DeleteLocalRef(ScopeIDArray); UE_LOG_ONLINE_IDENTITY(Verbose, TEXT("AndroidThunkCpp_Google_Login retval=%d"), ReturnVal); } else @@ -365,10 +359,7 @@ int32 AndroidThunkCpp_Google_Login(const TArray& InScopeFields) JNI_METHOD void Java_com_epicgames_ue4_GoogleLogin_nativeLoginComplete(JNIEnv* jenv, jobject thiz, jsize responseCode, jstring javaData) { EGoogleLoginResponse LoginResponse = (EGoogleLoginResponse)responseCode; - - const char* charsJavaData = jenv->GetStringUTFChars(javaData, 0); - FString JavaData = FString(UTF8_TO_TCHAR(charsJavaData)); - jenv->ReleaseStringUTFChars(javaData, charsJavaData); + auto JavaData = FJavaHelper::FStringFromParam(jenv, javaData); UE_LOG_ONLINE_IDENTITY(Verbose, TEXT("nativeLoginComplete Response: %s Data: %s"), ToString(LoginResponse), *JavaData); diff --git a/Engine/Plugins/Runtime/Analytics/Adjust/Source/AndroidAdjust/Private/AndroidAdjust.cpp b/Engine/Plugins/Runtime/Analytics/Adjust/Source/AndroidAdjust/Private/AndroidAdjust.cpp index 02bbcfda877f..92f05e5ab7c1 100644 --- a/Engine/Plugins/Runtime/Analytics/Adjust/Source/AndroidAdjust/Private/AndroidAdjust.cpp +++ b/Engine/Plugins/Runtime/Analytics/Adjust/Source/AndroidAdjust/Private/AndroidAdjust.cpp @@ -47,9 +47,8 @@ void AndroidThunkCpp_Adjust_SetPushToken(const FString& Token) if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { static jmethodID Method = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, " AndroidThunkJava_Adjust_SetPushToken", "(Ljava/lang/String;)V", false); - jstring TokenJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Token)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, TokenJava); - Env->DeleteLocalRef(TokenJava); + auto TokenJava = FJavaHelper::ToJavaString(Env, Token); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, *TokenJava); } } @@ -58,11 +57,9 @@ void AndroidThunkCpp_Adjust_AddSessionPartnerParameter(const FString& Key, const if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { static jmethodID Method = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_Adjust_AddSessionPartnerParameter", "(Ljava/lang/String;Ljava/lang/String;)V", false); - jstring KeyJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - jstring ValueJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Value)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, KeyJava, ValueJava); - Env->DeleteLocalRef(KeyJava); - Env->DeleteLocalRef(ValueJava); + auto KeyJava = FJavaHelper::ToJavaString(Env, Key); + auto ValueJava = FJavaHelper::ToJavaString(Env, Value); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, *KeyJava, *ValueJava); } } @@ -71,9 +68,8 @@ void AndroidThunkCpp_Adjust_RemoveSessionPartnerParameter(const FString& Key) if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { static jmethodID Method = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_Adjust_RemoveSessionPartnerParameter", "(Ljava/lang/String;)V", false); - jstring KeyJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, KeyJava); - Env->DeleteLocalRef(KeyJava); + auto KeyJava = FJavaHelper::ToJavaString(Env, Key); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, *KeyJava); } } @@ -91,11 +87,9 @@ void AndroidThunkCpp_Adjust_Event_AddCallbackParameter(const FString& Key, const if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { static jmethodID Method = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_Adjust_Event_AddCallbackParameter", "(Ljava/lang/String;Ljava/lang/String;)V", false); - jstring KeyJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - jstring ValueJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Value)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, KeyJava, ValueJava); - Env->DeleteLocalRef(KeyJava); - Env->DeleteLocalRef(ValueJava); + auto KeyJava = FJavaHelper::ToJavaString(Env, Key); + auto ValueJava = FJavaHelper::ToJavaString(Env, Value); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, *KeyJava, *ValueJava); } } @@ -104,9 +98,8 @@ void AndroidThunkCpp_Adjust_Event_RemoveCallbackParameter(const FString& Key) if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { static jmethodID Method = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_Adjust_Event_RemoveCallbackParameter", "(Ljava/lang/String;)V", false); - jstring KeyJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, KeyJava); - Env->DeleteLocalRef(KeyJava); + auto KeyJava = FJavaHelper::ToJavaString(Env, Key); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, *KeyJava); } } @@ -124,11 +117,9 @@ void AndroidThunkCpp_Adjust_Event_AddPartnerParameter(const FString& Key, const if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { static jmethodID Method = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_Adjust_Event_AddPartnerParameter", "(Ljava/lang/String;Ljava/lang/String;)V", false); - jstring KeyJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - jstring ValueJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Value)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, KeyJava, ValueJava); - Env->DeleteLocalRef(KeyJava); - Env->DeleteLocalRef(ValueJava); + auto KeyJava = FJavaHelper::ToJavaString(Env, Key); + auto ValueJava = FJavaHelper::ToJavaString(Env, Value); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, *KeyJava, *ValueJava); } } @@ -137,9 +128,8 @@ void AndroidThunkCpp_Adjust_Event_RemovePartnerParameter(const FString& Key) if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { static jmethodID Method = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_Adjust_Event_RemovePartnerParameter", "(Ljava/lang/String;)V", false); - jstring KeyJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, KeyJava); - Env->DeleteLocalRef(KeyJava); + auto KeyJava = FJavaHelper::ToJavaString(Env, Key); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, *KeyJava); } } @@ -157,9 +147,8 @@ void AndroidThunkCpp_Adjust_SendEvent(const FString& Token) if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { static jmethodID Method = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_Adjust_SendEvent", "(Ljava/lang/String;)V", false); - jstring TokenJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Token)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, TokenJava); - Env->DeleteLocalRef(TokenJava); + auto TokenJava = FJavaHelper::ToJavaString(Env, Token); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, *TokenJava); } } @@ -168,13 +157,10 @@ void AndroidThunkCpp_Adjust_SendRevenueEvent(const FString& Token, const FString if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { static jmethodID Method = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_Adjust_SendRevenueEvent", "(Ljava/lang/String;Ljava/lang/String;DLjava/lang/String;)V", false); - jstring TokenJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Token)); - jstring OrderIdJava = Env->NewStringUTF(TCHAR_TO_UTF8(*OrderId)); - jstring CurrencyJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Currency)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, TokenJava, OrderIdJava, Amount, CurrencyJava); - Env->DeleteLocalRef(TokenJava); - Env->DeleteLocalRef(OrderIdJava); - Env->DeleteLocalRef(CurrencyJava); + auto TokenJava = FJavaHelper::ToJavaString(Env, Token); + auto OrderIdJava = FJavaHelper::ToJavaString(Env, OrderId); + auto CurrencyJava = FJavaHelper::ToJavaString(Env, Currency); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, *TokenJava, *OrderIdJava, Amount, *CurrencyJava); } } diff --git a/Engine/Plugins/Runtime/AndroidPermission/Source/AndroidPermission/Private/AndroidPermissionCallbackProxy.cpp b/Engine/Plugins/Runtime/AndroidPermission/Source/AndroidPermission/Private/AndroidPermissionCallbackProxy.cpp index eade6cdaf156..06da61918ee2 100644 --- a/Engine/Plugins/Runtime/AndroidPermission/Source/AndroidPermission/Private/AndroidPermissionCallbackProxy.cpp +++ b/Engine/Plugins/Runtime/AndroidPermission/Source/AndroidPermission/Private/AndroidPermissionCallbackProxy.cpp @@ -29,12 +29,9 @@ JNI_METHOD void Java_com_google_vr_sdk_samples_permission_PermissionHelper_onAcq TArray arrGranted; int num = env->GetArrayLength(permissions); jint* jarrGranted = env->GetIntArrayElements(grantResults, 0); - for (int i = 0; i < num; i++) { - jstring str = (jstring)env->GetObjectArrayElement(permissions, i); - const char* charStr = env->GetStringUTFChars(str, 0); - arrPermissions.Add(FString(UTF8_TO_TCHAR(charStr))); - env->ReleaseStringUTFChars(str, charStr); - + for (int i = 0; i < num; i++) + { + arrPermissions.Add(FJavaHelper::FStringFromLocalRef(env, (jstring)env->GetObjectArrayElement(permissions, i))); arrGranted.Add(jarrGranted[i] == 0 ? true : false); // 0: permission granted, -1: permission denied } env->ReleaseIntArrayElements(grantResults, jarrGranted, 0); diff --git a/Engine/Plugins/Runtime/AndroidPermission/Source/AndroidPermission/Private/AndroidPermissionFunctionLibrary.cpp b/Engine/Plugins/Runtime/AndroidPermission/Source/AndroidPermission/Private/AndroidPermissionFunctionLibrary.cpp index 35a486d90afe..9bac48f67cba 100644 --- a/Engine/Plugins/Runtime/AndroidPermission/Source/AndroidPermission/Private/AndroidPermissionFunctionLibrary.cpp +++ b/Engine/Plugins/Runtime/AndroidPermission/Source/AndroidPermission/Private/AndroidPermissionFunctionLibrary.cpp @@ -21,7 +21,7 @@ void UAndroidPermissionFunctionLibrary::Initialize() { #if PLATFORM_ANDROID && USE_ANDROID_JNI JNIEnv* env = FAndroidApplication::GetJavaEnv(); - _PermissionHelperClass = (jclass)env->NewGlobalRef(FAndroidApplication::FindJavaClass("com/google/vr/sdk/samples/permission/PermissionHelper")); + _PermissionHelperClass = FAndroidApplication::FindJavaClassGlobalRef("com/google/vr/sdk/samples/permission/PermissionHelper"); _CheckPermissionMethodId = env->GetStaticMethodID(_PermissionHelperClass, "checkPermission", "(Ljava/lang/String;)Z"); _AcquirePermissionMethodId = env->GetStaticMethodID(_PermissionHelperClass, "acquirePermissions", "([Ljava/lang/String;)V"); #endif @@ -32,9 +32,8 @@ bool UAndroidPermissionFunctionLibrary::CheckPermission(const FString& permissio #if PLATFORM_ANDROID && USE_ANDROID_JNI UE_LOG(LogAndroidPermission, Log, TEXT("UAndroidPermissionFunctionLibrary::CheckPermission %s (Android)"), *permission); JNIEnv* env = FAndroidApplication::GetJavaEnv(); - jstring argument = env->NewStringUTF(TCHAR_TO_UTF8(*permission)); - bool bResult = env->CallStaticBooleanMethod(_PermissionHelperClass, _CheckPermissionMethodId, argument); - env->DeleteLocalRef(argument); + auto argument = FJavaHelper::ToJavaString(env, permission); + bool bResult = env->CallStaticBooleanMethod(_PermissionHelperClass, _CheckPermissionMethodId, *argument); return bResult; #else UE_LOG(LogAndroidPermission, Log, TEXT("UAndroidPermissionFunctionLibrary::CheckPermission (Else)")); @@ -47,14 +46,13 @@ UAndroidPermissionCallbackProxy* UAndroidPermissionFunctionLibrary::AcquirePermi #if PLATFORM_ANDROID && USE_ANDROID_JNI UE_LOG(LogAndroidPermission, Log, TEXT("UAndroidPermissionFunctionLibrary::AcquirePermissions")); JNIEnv* env = FAndroidApplication::GetJavaEnv(); - jobjectArray permissionsArray = (jobjectArray)env->NewObjectArray(permissions.Num(), FJavaWrapper::JavaStringClass, NULL); - for (int i = 0; i < permissions.Num(); i++) { - jstring str = env->NewStringUTF(TCHAR_TO_UTF8(*(permissions[i]))); - env->SetObjectArrayElement(permissionsArray, i, str); - env->DeleteLocalRef(str); + auto permissionsArray = NewScopedJavaObject(env, (jobjectArray)env->NewObjectArray(permissions.Num(), FJavaWrapper::JavaStringClass, NULL)); + for (int i = 0; i < permissions.Num(); i++) + { + auto str = FJavaHelper::ToJavaString(env, permissions[i]); + env->SetObjectArrayElement(*permissionsArray, i, *str); } - env->CallStaticVoidMethod(_PermissionHelperClass, _AcquirePermissionMethodId, permissionsArray); - env->DeleteLocalRef(permissionsArray); + env->CallStaticVoidMethod(_PermissionHelperClass, _AcquirePermissionMethodId, *permissionsArray); return UAndroidPermissionCallbackProxy::GetInstance(); #else UE_LOG(LogAndroidPermission, Log, TEXT("UAndroidPermissionFunctionLibrary::AcquirePermissions(%s) (Android)"), *(FString::Join(permissions, TEXT(",")))); diff --git a/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCapture.cpp b/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCapture.cpp index 735eccd48002..5161d14d745f 100644 --- a/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCapture.cpp +++ b/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCapture.cpp @@ -30,11 +30,11 @@ bool FAudioCapture::GetDefaultCaptureDeviceInfo(FCaptureDeviceInfo& OutInfo) return false; } -bool FAudioCapture::OpenDefaultCaptureStream(FAudioCaptureStreamParam& StreamParams) +bool FAudioCapture::OpenDefaultCaptureStream(FOnCaptureFunction OnCapture, uint32 NumFramesDesired) { if (Impl.IsValid()) { - return Impl->OpenDefaultCaptureStream(StreamParams); + return Impl->OpenDefaultCaptureStream(MoveTemp(OnCapture), NumFramesDesired); } return false; @@ -123,21 +123,6 @@ FAudioCaptureSynth::~FAudioCaptureSynth() { } -void FAudioCaptureSynth::OnAudioCapture(float* AudioData, int32 NumFrames, int32 NumChannels, double StreamTime, bool bOverflow) -{ - int32 NumSamples = NumChannels * NumFrames; - - FScopeLock Lock(&CaptureCriticalSection); - - if (bIsCapturing) - { - // Append the audio memory to the capture data buffer - int32 Index = AudioCaptureData.AddUninitialized(NumSamples); - float* AudioCaptureDataPtr = AudioCaptureData.GetData(); - FMemory::Memcpy(&AudioCaptureDataPtr[Index], AudioData, NumSamples * sizeof(float)); - } -} - bool FAudioCaptureSynth::GetDefaultCaptureDeviceInfo(FCaptureDeviceInfo& OutInfo) { return AudioCapture.GetDefaultCaptureDeviceInfo(OutInfo); @@ -148,15 +133,26 @@ bool FAudioCaptureSynth::OpenDefaultStream() bool bSuccess = true; if (!AudioCapture.IsStreamOpen()) { - FAudioCaptureStreamParam StreamParam; - StreamParam.Callback = this; - StreamParam.NumFramesDesired = 1024; + FOnCaptureFunction OnCapture = [this](const float* AudioData, int32 NumFrames, int32 NumChannels, double StreamTime, bool bOverFlow) + { + int32 NumSamples = NumChannels * NumFrames; + + FScopeLock Lock(&CaptureCriticalSection); + + if (bIsCapturing) + { + // Append the audio memory to the capture data buffer + int32 Index = AudioCaptureData.AddUninitialized(NumSamples); + float* AudioCaptureDataPtr = AudioCaptureData.GetData(); + FMemory::Memcpy(&AudioCaptureDataPtr[Index], AudioData, NumSamples * sizeof(float)); + } + }; // Prepare the audio buffer memory for 2 seconds of stereo audio at 48k SR to reduce chance for allocation in callbacks AudioCaptureData.Reserve(2 * 2 * 48000); // Start the stream here to avoid hitching the audio render thread. - if (AudioCapture.OpenDefaultCaptureStream(StreamParam)) + if (AudioCapture.OpenDefaultCaptureStream(MoveTemp(OnCapture), 1024)) { AudioCapture.StartStream(); } @@ -231,6 +227,87 @@ bool FAudioCaptureSynth::GetAudioData(TArray& OutAudioData) } // namespace audio +UAudioCapture::UAudioCapture() +{ + +} + +UAudioCapture::~UAudioCapture() +{ + +} + +bool UAudioCapture::OpenDefaultAudioStream() +{ + if (!AudioCapture.IsStreamOpen()) + { + Audio::FOnCaptureFunction OnCapture = [this](const float* AudioData, int32 NumFrames, int32 InNumChannels, double StreamTime, bool bOverFlow) + { + OnGeneratedAudio(AudioData, NumFrames * InNumChannels); + }; + + // Start the stream here to avoid hitching the audio render thread. + if (AudioCapture.OpenDefaultCaptureStream(MoveTemp(OnCapture), 1024)) + { + // If we opened the capture stream succesfully, get the capture device info and initialize the UAudioGenerator + Audio::FCaptureDeviceInfo Info; + if (AudioCapture.GetDefaultCaptureDeviceInfo(Info)) + { + Init(Info.PreferredSampleRate, Info.InputChannels); + return true; + } + } + } + return false; +} + +bool UAudioCapture::GetAudioCaptureDeviceInfo(FAudioCaptureDeviceInfo& OutInfo) +{ + Audio::FCaptureDeviceInfo Info; + if (AudioCapture.GetDefaultCaptureDeviceInfo(Info)) + { + OutInfo.DeviceName = FName(*Info.DeviceName); + OutInfo.NumInputChannels = Info.InputChannels; + OutInfo.SampleRate = Info.PreferredSampleRate; + return true; + } + return false; +} + +void UAudioCapture::StartCapturingAudio() +{ + if (AudioCapture.IsStreamOpen()) + { + AudioCapture.StartStream(); + } +} + +void UAudioCapture::StopCapturingAudio() +{ + if (AudioCapture.IsStreamOpen()) + { + AudioCapture.StopStream(); + } + +} + +bool UAudioCapture::IsCapturingAudio() +{ + return AudioCapture.IsCapturing(); +} + +UAudioCapture* UAudioCaptureFunctionLibrary::CreateAudioCapture() +{ + UAudioCapture* NewAudioCapture = NewObject(); + if (NewAudioCapture->OpenDefaultAudioStream()) + { + return NewAudioCapture; + } + + UE_LOG(LogAudioCapture, Error, TEXT("Failed to open a default audio stream to the audio capture device.")); + return nullptr; +} + void FAudioCaptureModule::StartupModule() { } diff --git a/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCaptureInternal.h b/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCaptureInternal.h index b84215d6ee70..27cb073436cb 100644 --- a/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCaptureInternal.h +++ b/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCaptureInternal.h @@ -25,7 +25,7 @@ namespace Audio FAudioCaptureImpl(); bool GetDefaultCaptureDeviceInfo(FCaptureDeviceInfo& OutInfo); - bool OpenDefaultCaptureStream(const FAudioCaptureStreamParam& StreamParams); + bool OpenDefaultCaptureStream(FOnCaptureFunction InOnCapture, uint32 NumFramesDesired); bool CloseStream(); bool StartStream(); bool StopStream(); @@ -47,7 +47,7 @@ namespace Audio #endif private: - IAudioCaptureCallback* Callback; + FOnCaptureFunction OnCapture; int32 NumChannels; int32 SampleRate; #if PLATFORM_WINDOWS @@ -67,7 +67,7 @@ namespace Audio FAudioCaptureImpl() {} bool GetDefaultCaptureDeviceInfo(FCaptureDeviceInfo& OutInfo) { return false; } - bool OpenDefaultCaptureStream(const FAudioCaptureStreamParam& StreamParams) { return false; } + bool OpenDefaultCaptureStream(FOnCaptureFunction OnCapture, uint32 NumFramesDesired) { return false; } bool CloseStream() { return false; } bool StartStream() { return false; } bool StopStream() { return false; } diff --git a/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCaptureMLAudio.cpp b/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCaptureMLAudio.cpp index fd4bcc6cf64e..11f8c9c28d93 100644 --- a/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCaptureMLAudio.cpp +++ b/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCaptureMLAudio.cpp @@ -41,10 +41,8 @@ static void OnAudioCaptureCallback(MLHandle Handle, void* CallbackContext) void FAudioCaptureImpl::OnAudioCapture(void* InBuffer, uint32 InBufferFrames, double StreamTime, bool bOverflow) { - check(Callback); FScopeLock ScopeLock(&ApplicationResumeCriticalSection); - int32 NumSamples = (int32)(InBufferFrames * NumChannels); //TODO: Check to see if float conversion is needed: @@ -59,7 +57,7 @@ void FAudioCaptureImpl::OnAudioCapture(void* InBuffer, uint32 InBufferFrames, do FloatBufferPtr[i] = (((float)InBufferData[i]) / 32767.0f); }; - Callback->OnAudioCapture(FloatBufferPtr, InBufferFrames, NumChannels, StreamTime, bOverflow); + OnAudioCapture(FloatBufferPtr, InBufferFrames, NumChannels, StreamTime, bOverflow); } bool FAudioCaptureImpl::GetDefaultCaptureDeviceInfo(FCaptureDeviceInfo& OutInfo) @@ -88,7 +86,7 @@ bool FAudioCaptureImpl::GetDefaultCaptureDeviceInfo(FCaptureDeviceInfo& OutInfo) return true; } -bool FAudioCaptureImpl::OpenDefaultCaptureStream(const FAudioCaptureStreamParam& StreamParams) +bool FAudioCaptureImpl::OpenDefaultCaptureStream(FOnCaptureFunction InOnCapture, uint32 NumFramesDesired) { UE_LOG(LogAudioCapture, Warning, TEXT("OPENING STREAM")); if (MLHandleIsValid(InputDeviceHandle)) @@ -96,7 +94,7 @@ bool FAudioCaptureImpl::OpenDefaultCaptureStream(const FAudioCaptureStreamParam& UE_LOG(LogAudioCapture, Error, TEXT("Capture Stream Already Opened")); } - if (!StreamParams.Callback) + if (!InOnCapture) { UE_LOG(LogAudioCapture, Error, TEXT("Need a callback object passed to open a capture stream")); return false; @@ -111,8 +109,10 @@ bool FAudioCaptureImpl::OpenDefaultCaptureStream(const FAudioCaptureStreamParam& uint32 RecommendedBufferSize = 0; uint32 MinBufferSize = 0; uint32 UnsignedSampleRate = SampleRate; - uint32 NumFrames = StreamParams.NumFramesDesired; - uint32 BufferSize = StreamParams.NumFramesDesired * NumChannels * sizeof(int16); + uint32 NumFrames = NumFramesDesired; + uint32 BufferSize = NumFramesDesired * NumChannels * sizeof(int16); + // MERGE-REVIEW - check logic here + uint32 RequestedBufferSize = StreamParams.NumFramesDesired * NumChannels * sizeof(int16); MLResult Result = MLAudioGetInputStreamDefaults(ChannelCount, UnsignedSampleRate, &DefaultBufferFormat, &RecommendedBufferSize, &MinBufferSize); if (Result != MLResult_Ok) @@ -123,8 +123,8 @@ bool FAudioCaptureImpl::OpenDefaultCaptureStream(const FAudioCaptureStreamParam& if (BufferSize < RecommendedBufferSize) { - UE_LOG(LogAudioCapture, Warning, TEXT("Requested buffer size of %u is smaller than the recommended buffer size, reverting to a buffer size of %u"), BufferSize, RecommendedBufferSize); - BufferSize = RecommendedBufferSize; + BufferSize = StreamParams.NumFramesDesired * NumChannels; + UE_LOG(LogAudioCapture, Display, TEXT("Using buffer size of %u"), StreamParams.NumFramesDesired * NumChannels); } UE_LOG(LogAudioCapture, Display, TEXT("Using buffer size of %u"), BufferSize); @@ -133,7 +133,7 @@ bool FAudioCaptureImpl::OpenDefaultCaptureStream(const FAudioCaptureStreamParam& DefaultBufferFormat.channel_count = ChannelCount; DefaultBufferFormat.samples_per_second = SampleRate; - Callback = StreamParams.Callback; + OnCapture = MoveTemp(InOnCapture); // Open up new audio stream Result = MLAudioCreateInputFromVoiceComm(&DefaultBufferFormat, BufferSize, &OnAudioCaptureCallback, this, &InputDeviceHandle); diff --git a/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCaptureRtAudio.cpp b/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCaptureRtAudio.cpp index 894674128585..8cd047428d46 100644 --- a/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCaptureRtAudio.cpp +++ b/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Private/AudioCaptureRtAudio.cpp @@ -10,8 +10,7 @@ namespace Audio { FAudioCaptureImpl::FAudioCaptureImpl() - : Callback(nullptr) - , NumChannels(0) + : NumChannels(0) , SampleRate(0) { } @@ -26,10 +25,8 @@ static int32 OnAudioCaptureCallback(void *OutBuffer, void* InBuffer, uint32 InBu void FAudioCaptureImpl::OnAudioCapture(void* InBuffer, uint32 InBufferFrames, double StreamTime, bool bOverflow) { - check(Callback); - float* InBufferData = (float*)InBuffer; - Callback->OnAudioCapture(InBufferData, InBufferFrames, NumChannels, StreamTime, bOverflow); + OnCapture(InBufferData, InBufferFrames, NumChannels, StreamTime, bOverflow); } bool FAudioCaptureImpl::GetDefaultCaptureDeviceInfo(FCaptureDeviceInfo& OutInfo) @@ -47,14 +44,8 @@ bool FAudioCaptureImpl::GetDefaultCaptureDeviceInfo(FCaptureDeviceInfo& OutInfo) return true; } -bool FAudioCaptureImpl::OpenDefaultCaptureStream(const FAudioCaptureStreamParam& StreamParams) +bool FAudioCaptureImpl::OpenDefaultCaptureStream(FOnCaptureFunction InOnCapture, uint32 NumFramesDesired) { - if (!StreamParams.Callback) - { - UE_LOG(LogAudioCapture, Error, TEXT("Need a callback object passed to open a capture stream")); - return false; - } - uint32 DefaultInputDeviceId = CaptureDevice.getDefaultInputDevice(); RtAudio::DeviceInfo DeviceInfo = CaptureDevice.getDeviceInfo(DefaultInputDeviceId); @@ -69,10 +60,10 @@ bool FAudioCaptureImpl::OpenDefaultCaptureStream(const FAudioCaptureStreamParam& CaptureDevice.closeStream(); } - uint32 NumFrames = StreamParams.NumFramesDesired; + uint32 NumFrames = NumFramesDesired; NumChannels = RtAudioStreamParams.nChannels; SampleRate = DeviceInfo.preferredSampleRate; - Callback = StreamParams.Callback; + OnCapture = MoveTemp(InOnCapture); // Open up new audio stream CaptureDevice.openStream(nullptr, &RtAudioStreamParams, RTAUDIO_FLOAT32, SampleRate, &NumFrames, &OnAudioCaptureCallback, this); diff --git a/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Public/AudioCapture.h b/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Public/AudioCapture.h index ac288d62a03e..3871ef313f86 100644 --- a/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Public/AudioCapture.h +++ b/Engine/Plugins/Runtime/AudioCapture/Source/AudioCapture/Public/AudioCapture.h @@ -7,6 +7,12 @@ #include "HAL/ThreadSafeBool.h" #include "DSP/Delay.h" #include "DSP/EnvelopeFollower.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "UObject/ObjectMacros.h" +#include "UObject/Object.h" +#include "Generators/AudioGenerator.h" + +#include "AudioCapture.generated.h" DECLARE_LOG_CATEGORY_EXTERN(LogAudioCapture, Log, All); @@ -20,24 +26,10 @@ namespace Audio int32 PreferredSampleRate; }; - class AUDIOCAPTURE_API IAudioCaptureCallback - { - public: - /** - * Called when audio capture has received a new capture buffer. - */ - virtual void OnAudioCapture(float* AudioData, int32 NumFrames, int32 NumChannels, double StreamTime, bool bOverflow) = 0; - virtual ~IAudioCaptureCallback() {} - }; - - struct FAudioCaptureStreamParam - { - IAudioCaptureCallback* Callback; - uint32 NumFramesDesired; - }; - class FAudioCaptureImpl; + typedef TFunction FOnCaptureFunction; + // Class which handles audio capture internally, implemented with a back-end per platform class AUDIOCAPTURE_API FAudioCapture { @@ -49,7 +41,7 @@ namespace Audio bool GetDefaultCaptureDeviceInfo(FCaptureDeviceInfo& OutInfo); // Opens the audio capture stream with the given parameters - bool OpenDefaultCaptureStream(FAudioCaptureStreamParam& StreamParams); + bool OpenDefaultCaptureStream(FOnCaptureFunction OnCapture, uint32 NumFramesDesired); // Closes the audio capture stream bool CloseStream(); @@ -82,17 +74,13 @@ namespace Audio }; - /** Class which contains an FAudioCapture object and performs analysis on the audio stream, only outputing audio if it matches a detection criteteria. */ - class FAudioCaptureSynth : public IAudioCaptureCallback + /** Class which contains an FAudioCapture object and performs analysis on the audio stream, only outputing audio if it matches a detection criteria. */ + class FAudioCaptureSynth { public: FAudioCaptureSynth(); virtual ~FAudioCaptureSynth(); - //~ IAudioCaptureCallback Begin - virtual void OnAudioCapture(float* AudioData, int32 NumFrames, int32 NumChannels, double StreamTime, bool bOverflow) override; - //~ IAudioCaptureCallback End - // Gets the default capture device info bool GetDefaultCaptureDeviceInfo(FCaptureDeviceInfo& OutInfo); @@ -153,4 +141,67 @@ class FAudioCaptureModule : public IModuleInterface public: virtual void StartupModule() override; virtual void ShutdownModule() override; +}; + +// Struct defining the time synth global quantization settings +USTRUCT(BlueprintType) +struct AUDIOCAPTURE_API FAudioCaptureDeviceInfo +{ + GENERATED_USTRUCT_BODY() + + // The name of the audio capture device + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "AudioCapture") + FName DeviceName; + + // The number of input channels + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "AudioCapture") + int32 NumInputChannels; + + // The sample rate of the audio capture device + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "AudioCapture") + int32 SampleRate; +}; + +// Class which opens up a handle to an audio capture device. +// Allows other objects to get audio buffers from the capture device. +UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent)) +class AUDIOCAPTURE_API UAudioCapture : public UAudioGenerator +{ + GENERATED_BODY() + +public: + UAudioCapture(); + ~UAudioCapture(); + + bool OpenDefaultAudioStream(); + + // Returns the audio capture device info + UFUNCTION(BlueprintCallable, Category = "AudioCapture") + bool GetAudioCaptureDeviceInfo(FAudioCaptureDeviceInfo& OutInfo); + + // Starts capturing audio + UFUNCTION(BlueprintCallable, Category = "AudioCapture") + void StartCapturingAudio(); + + // Stops capturing audio + UFUNCTION(BlueprintCallable, Category = "AudioCapture") + void StopCapturingAudio(); + + // Returns true if capturing audio + UFUNCTION(BlueprintCallable, Category = "AudioCapture") + bool IsCapturingAudio(); + +protected: + + Audio::FAudioCapture AudioCapture; +}; + +UCLASS() +class AUDIOCAPTURE_API UAudioCaptureFunctionLibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() +public: + + UFUNCTION(BlueprintCallable, Category = "Audio Capture") + static class UAudioCapture* CreateAudioCapture(); }; \ No newline at end of file diff --git a/Engine/Plugins/Runtime/Firebase/Source/Firebase.Build.cs b/Engine/Plugins/Runtime/Firebase/Source/Firebase.Build.cs index d12090965a5b..dabfb9ce037f 100644 --- a/Engine/Plugins/Runtime/Firebase/Source/Firebase.Build.cs +++ b/Engine/Plugins/Runtime/Firebase/Source/Firebase.Build.cs @@ -9,11 +9,15 @@ namespace UnrealBuildTool.Rules public Firebase(ReadOnlyTargetRules Target) : base(Target) { PrivateDependencyModuleNames.AddRange(new string[] { - // "Core", - // "CoreUObject" - }); + "Core", + "CoreUObject", + "Engine", + "Launch" + }); - if (Target.Platform == UnrealTargetPlatform.Android) + PublicDefinitions.Add("WITH_FIREBASE=1"); + + if (Target.Platform == UnrealTargetPlatform.Android) { PrivateDependencyModuleNames.Add("Launch"); diff --git a/Engine/Plugins/Runtime/Firebase/Source/Firebase.upl.xml b/Engine/Plugins/Runtime/Firebase/Source/Firebase.upl.xml index 322136beaf18..a8433513b57a 100644 --- a/Engine/Plugins/Runtime/Firebase/Source/Firebase.upl.xml +++ b/Engine/Plugins/Runtime/Firebase/Source/Firebase.upl.xml @@ -16,6 +16,29 @@ + + + + + + + + + + + + + + + + + + + @@ -51,4 +74,63 @@ apply plugin: 'com.google.gms.google-services' + + + + + + import android.text.TextUtils; + import static com.epicgames.ue4.notifications.EpicFirebaseMessagingService.KEY_NOTIFICATION_BODY; + import static com.epicgames.ue4.notifications.EpicFirebaseMessagingService.NOTIFICATION_ACTION; + import static com.epicgames.ue4.services.VoiceService.VOICE_ACTION_UPDATED; + + + + + + + + + + + if (NOTIFICATION_ACTION.equals(getIntent().getAction())) { + handleNotificationAction(); + } + else if(VOICE_ACTION_UPDATED.equals(getIntent().getAction())) { + routeServiceIntent(getIntent()); + } + + + f + + + + + + + + private void handleNotificationAction() { + Bundle extras = getIntent().getExtras(); + if (extras != null) { + String body = extras.getString(KEY_NOTIFICATION_BODY); + if(!TextUtils.isEmpty(body)) { + routeNotificationAction(body); + } + } + Intent i = getIntent(); + i.setAction(null); + setIntent(i); + } + + + + @Override + public void routeNotificationAction(String payload) { + super.routeNotificationAction(payload); + } + + + + + diff --git a/Engine/Plugins/Runtime/GoogleCloudMessaging/Source/GoogleCloudMessaging/Private/GoogleCloudMessagingAndroid.cpp b/Engine/Plugins/Runtime/GoogleCloudMessaging/Source/GoogleCloudMessaging/Private/GoogleCloudMessagingAndroid.cpp index e5d6db3fe899..f6f154bec9b7 100644 --- a/Engine/Plugins/Runtime/GoogleCloudMessaging/Source/GoogleCloudMessaging/Private/GoogleCloudMessagingAndroid.cpp +++ b/Engine/Plugins/Runtime/GoogleCloudMessaging/Source/GoogleCloudMessaging/Private/GoogleCloudMessagingAndroid.cpp @@ -65,10 +65,7 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeGCMFailedToRegisterFor // received message JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeGCMReceivedRemoteNotification( JNIEnv* jenv, jobject thiz, jstring jMessage ) { - FString Message; - const char* MessageChars = jenv->GetStringUTFChars( jMessage, 0 ); - Message = FString( UTF8_TO_TCHAR( MessageChars ) ); - jenv->ReleaseStringUTFChars( jMessage, MessageChars ); + auto Message = FJavaHelper::FStringFromParam(jenv, jMessage); int AppState = 3; // EApplicationState::Active; if (FAppEventManager::GetInstance()->IsGamePaused()) diff --git a/Engine/Plugins/Runtime/GoogleVR/GoogleVRController/Source/GoogleVRController/Private/GoogleVRController.cpp b/Engine/Plugins/Runtime/GoogleVR/GoogleVRController/Source/GoogleVRController/Private/GoogleVRController.cpp index a11a82634de0..aa33ef9e3d70 100644 --- a/Engine/Plugins/Runtime/GoogleVR/GoogleVRController/Source/GoogleVRController/Private/GoogleVRController.cpp +++ b/Engine/Plugins/Runtime/GoogleVR/GoogleVRController/Source/GoogleVRController/Private/GoogleVRController.cpp @@ -73,12 +73,13 @@ class FGoogleVRControllerPlugin : public IGoogleVRControllerPlugin JNIEnv* jenv = FAndroidApplication::GetJavaEnv(); static jmethodID Method = FJavaWrapper::FindMethod(jenv, FJavaWrapper::GameActivityClassID, "getApplicationContext", "()Landroid/content/Context;", false); static jobject ApplicationContext = FJavaWrapper::CallObjectMethod(jenv, FJavaWrapper::GameActivityThis, Method); - jclass MainClass = FAndroidApplication::FindJavaClass("com/epicgames/ue4/GameActivity"); + jclass MainClass = FAndroidApplication::FindJavaClassGlobalRef("com/epicgames/ue4/GameActivity"); jclass classClass = jenv->FindClass("java/lang/Class"); jmethodID getClassLoaderMethod = jenv->GetMethodID(classClass, "getClassLoader", "()Ljava/lang/ClassLoader;"); - jobject classLoader = jenv->CallObjectMethod(MainClass, getClassLoaderMethod); + auto classLoader = NewScopedJavaObject(jenv, jenv->CallObjectMethod(MainClass, getClassLoaderMethod)); - success = pController->Init(jenv, ApplicationContext, classLoader, options, GVRAPI); + success = pController->Init(jenv, ApplicationContext, *classLoader, options, GVRAPI); + jenv->DeleteGlobalRef(MainClass); #else #if GOOGLEVRCONTROLLER_SUPPORTED_EMULATOR_PLATFORMS success = static_cast(pController)->InitEmulator(options, CONTROLLER_EVENT_FORWARDED_PORT); diff --git a/Engine/Plugins/Runtime/GoogleVR/GoogleVRHMD/Source/GoogleVRHMD/Private/GoogleVRHMD.cpp b/Engine/Plugins/Runtime/GoogleVR/GoogleVRHMD/Source/GoogleVRHMD/Private/GoogleVRHMD.cpp index b3adcd8e2900..f2f3dc77d044 100644 --- a/Engine/Plugins/Runtime/GoogleVR/GoogleVRHMD/Source/GoogleVRHMD/Private/GoogleVRHMD.cpp +++ b/Engine/Plugins/Runtime/GoogleVR/GoogleVRHMD/Source/GoogleVRHMD/Private/GoogleVRHMD.cpp @@ -124,8 +124,8 @@ void AndroidThunkCpp_UiLayer_SetViewerName(const FString& ViewerName) if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { static jmethodID UiLayerMethod = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_UiLayer_SetViewerName", "(Ljava/lang/String;)V", false); - jstring NameJava = Env->NewStringUTF(TCHAR_TO_UTF8(*ViewerName)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, UiLayerMethod, NameJava); + auto NameJava = FJavaHelper::ToJavaString(Env, ViewerName); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, UiLayerMethod, *NameJava); } } @@ -204,14 +204,7 @@ FString AndroidThunkCpp_GetDataString() if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { static jmethodID Method = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_GetDataString", "()Z", false); - jstring JavaString = (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, Method); - if (JavaString != NULL) - { - const char* JavaChars = Env->GetStringUTFChars(JavaString, 0); - Result = FString(UTF8_TO_TCHAR(JavaChars)); - Env->ReleaseStringUTFChars(JavaString, JavaChars); - Env->DeleteLocalRef(JavaString); - } + Result = FJavaHelper::FStringFromLocalRef(Env, (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, Method)); } return Result; diff --git a/Engine/Plugins/Runtime/GoogleVR/GoogleVRTransition2D/Source/GoogleVRTransition2D/Private/GoogleVRTransition2DBPLibrary.cpp b/Engine/Plugins/Runtime/GoogleVR/GoogleVRTransition2D/Source/GoogleVRTransition2D/Private/GoogleVRTransition2DBPLibrary.cpp index b0d6601dc83d..e492e04d0958 100644 --- a/Engine/Plugins/Runtime/GoogleVR/GoogleVRTransition2D/Source/GoogleVRTransition2D/Private/GoogleVRTransition2DBPLibrary.cpp +++ b/Engine/Plugins/Runtime/GoogleVR/GoogleVRTransition2D/Source/GoogleVRTransition2D/Private/GoogleVRTransition2DBPLibrary.cpp @@ -16,7 +16,7 @@ void UGoogleVRTransition2DBPLibrary::Initialize() { #if PLATFORM_ANDROID JNIEnv* env = FAndroidApplication::GetJavaEnv(); - _TransitionHelperClass = (jclass)env->NewGlobalRef(FAndroidApplication::FindJavaClass("com/google/vr/sdk/samples/transition/GVRTransitionHelper")); + _TransitionHelperClass = FAndroidApplication::FindJavaClassGlobalRef("com/google/vr/sdk/samples/transition/GVRTransitionHelper"); _TransitionTo2DMethodId = env->GetStaticMethodID(_TransitionHelperClass, "transitionTo2D", "(Landroid/app/Activity;)V"); _TransitionToVRMethodId = env->GetStaticMethodID(_TransitionHelperClass, "transitionToVR", "()V"); #endif diff --git a/Engine/Plugins/Runtime/IOSReplayKit/IOSReplayKit.uplugin b/Engine/Plugins/Runtime/IOSReplayKit/IOSReplayKit.uplugin new file mode 100644 index 000000000000..7117c423d855 --- /dev/null +++ b/Engine/Plugins/Runtime/IOSReplayKit/IOSReplayKit.uplugin @@ -0,0 +1,24 @@ +{ + "FileVersion" : 3, + "Version" : 1, + "VersionName" : "1.0", + "FriendlyName" : "ReplayKit for iOS", + "Description" : "Support for local recording and broadcasting using ReplayKit", + "Category" : "Replay", + "CreatedBy" : "Epic Games, Inc.", + "CreatedByURL" : "http://epicgames.com", + "EnabledByDefault" : false, + "Installed" : false, + "Modules" : + [ + { + "Name": "IOSReplayKit", + "Type": "Runtime", + "LoadingPhase": "PreDefault", + "WhitelistPlatforms": + [ + "IOS" + ] + } + ] +} diff --git a/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/IOSReplayKit.Build.cs b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/IOSReplayKit.Build.cs new file mode 100644 index 000000000000..ed66ac8474d4 --- /dev/null +++ b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/IOSReplayKit.Build.cs @@ -0,0 +1,39 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +using System.IO; + +namespace UnrealBuildTool.Rules +{ + public class IOSReplayKit : ModuleRules + { + public IOSReplayKit(ReadOnlyTargetRules Target) : base(Target) + { + PrivateIncludePaths.AddRange(new string[] + { + "IOSReplayKit/Private", + }); + + PrivateDependencyModuleNames.AddRange(new string[] + { + "Core", + "CoreUObject", + "Engine" + }); + + if (Target.bBuildEditor) + { + PrivateDependencyModuleNames.Add("UnrealEd"); + } + + if (Target.Platform == UnrealTargetPlatform.IOS) + { + PublicFrameworks.AddRange( new string[]{ + "ReplayKit" + }); + + string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory, Target.RelativeEnginePath); + AdditionalPropertiesForReceipt.Add("IOSPlugin", Path.Combine(PluginPath, "IOSReplayKit_UPL.xml")); + } + } + } +} diff --git a/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/IOSReplayKit_UPL.xml b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/IOSReplayKit_UPL.xml new file mode 100644 index 000000000000..b860ce687c1e --- /dev/null +++ b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/IOSReplayKit_UPL.xml @@ -0,0 +1,12 @@ + + + + + + + + NSPhotoLibraryAddUsageDescription + This app saves screen captures to the photo library. + + + diff --git a/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Private/IOSReplayKit.cpp b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Private/IOSReplayKit.cpp new file mode 100644 index 000000000000..92ac3ca6cf81 --- /dev/null +++ b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Private/IOSReplayKit.cpp @@ -0,0 +1,143 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + +#include "IOSReplayKit.h" + +DEFINE_LOG_CATEGORY( LogIOSReplayKit ); + +#if PLATFORM_IOS + +#include "IOSAppDelegate.h" +#import "ReplayKitRecorder.h" +#include "IOSReplayKitControl.h" + +class FIOSReplayKit : public IIOSReplayKitModuleInterface, public FSelfRegisteringExec +{ +public: + virtual bool Exec(UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar) override; + + virtual void Initialize( bool bMicrophoneEnabled = false, bool bCameraEnabled = false ) override; + + virtual void StartRecording() override; + virtual void StopRecording() override; + + virtual void StartCaptureToFile() override; + virtual void StopCapture() override; + + virtual void StartBroadcast() override; + virtual void PauseBroadcast() override; + virtual void ResumeBroadcast() override; + virtual void StopBroadcast() override; + +private: + ReplayKitRecorder* rkr; +}; + +bool FIOSReplayKit::Exec(UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar) +{ + if (FParse::Command(&Cmd, TEXT("RKStart"))) + { + UIOSReplayKitControl::StartRecording(); + return true; + } + else if (FParse::Command(&Cmd, TEXT("RKStop"))) + { + UIOSReplayKitControl::StopRecording(); + return true; + } + + return false; +} + + +void FIOSReplayKit::Initialize( bool bMicrophoneEnabled, bool bCameraEnabled ) +{ + BOOL _bMicrophoneEnabled = bMicrophoneEnabled ? YES : NO; + // camera capture is disabled because it requires a UIView to display + BOOL _bCameraEnabled = NO; + + rkr = [[ReplayKitRecorder alloc] init]; + [rkr initializeWithMicrophoneEnabled:_bMicrophoneEnabled withCameraEnabled:_bCameraEnabled]; + +} + +void FIOSReplayKit::StartRecording() +{ + [rkr startRecording]; +} + +void FIOSReplayKit::StopRecording() +{ + [rkr stopRecording]; +} + +void FIOSReplayKit::StartCaptureToFile() +{ + [rkr startCapture]; +} + +void FIOSReplayKit::StopCapture() +{ + [rkr stopCapture]; +} + +void FIOSReplayKit::StartBroadcast() +{ + [rkr startBroadcast]; +} + +void FIOSReplayKit::PauseBroadcast() +{ + [rkr pauseBroadcast]; +} + +void FIOSReplayKit::ResumeBroadcast() +{ + [rkr resumeBroadcast]; +} + +void FIOSReplayKit::StopBroadcast() +{ + [rkr stopBroadcast]; +} + +#else + +class FIOSReplayKit : public IIOSReplayKitModuleInterface +{ +public: + + virtual void Initialize( bool bMicrophoneEnabled = false, bool bCameraEnabled = false ) + { + UE_LOG(LogIOSReplayKit, Display, TEXT("ReplayKit not available on this platform")); + } + + virtual void StartRecording() override {} + virtual void StopRecording() override {} + + virtual void StartCaptureToFile() override {} + virtual void StopCapture() override {} + + virtual void StartBroadcast() override {} + virtual void PauseBroadcast() override {} + virtual void ResumeBroadcast() override {} + virtual void StopBroadcast() override {} +}; + +#endif + +void IIOSReplayKitModuleInterface::StartupModule() +{ + // This code will execute after your module is loaded into memory (but after global variables are initialized, of course.) +} + + +void IIOSReplayKitModuleInterface::ShutdownModule() +{ + // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, + // we call this function before unloading the module. +} + +IMPLEMENT_MODULE(FIOSReplayKit, IOSReplayKit) + + + diff --git a/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Private/IOSReplayKitControl.cpp b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Private/IOSReplayKitControl.cpp new file mode 100644 index 000000000000..495eab9b16e9 --- /dev/null +++ b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Private/IOSReplayKitControl.cpp @@ -0,0 +1,29 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "IOSReplayKitControl.h" +#include "IOSReplayKit.h" + +void UIOSReplayKitControl::StartRecording(bool bMicrophoneEnabled) +{ + IIOSReplayKitModuleInterface::Get().Initialize(bMicrophoneEnabled, false); + IIOSReplayKitModuleInterface::Get().StartRecording(); + + UE_LOG(LogIOSReplayKit, Log, TEXT("Starting recording!")); +} + +void UIOSReplayKitControl::StopRecording() +{ + IIOSReplayKitModuleInterface::Get().StopRecording(); + UE_LOG(LogIOSReplayKit, Log, TEXT("Stopping recording!")); +} + +void UIOSReplayKitControl::StartCaptureToFile(bool bMicrophoneEnabled) +{ + IIOSReplayKitModuleInterface::Get().Initialize(bMicrophoneEnabled, false); + IIOSReplayKitModuleInterface::Get().StartCaptureToFile(); +} + +void UIOSReplayKitControl::StopCapture() +{ + IIOSReplayKitModuleInterface::Get().StopCapture(); +} diff --git a/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Private/ReplayKitRecorder.cpp b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Private/ReplayKitRecorder.cpp new file mode 100644 index 000000000000..eea7e6bbaad2 --- /dev/null +++ b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Private/ReplayKitRecorder.cpp @@ -0,0 +1,322 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + + +#include "ReplayKitRecorder.h" + +#if PLATFORM_IOS +#include "IOSAppDelegate.h" +#include "IOS/IOSView.h" +#include "Misc/Paths.h" +#include "Engine/Engine.h" +#include "Engine/GameViewportClient.h" + +@implementation ReplayKitRecorder + +RPScreenRecorder* _Nullable _screenRecorder; +RPBroadcastActivityViewController* _Nullable _broadcastActivityController; +RPBroadcastController* _Nullable _broadcastController; + +// stuff used when capturing to file +AVAssetWriter* _Nullable _assetWriter; +AVAssetWriterInput* _Nullable _videoInput; +AVAssetWriterInput* _Nullable _audioInput; +NSString* _Nullable _captureFilePath; + +- (void) initializeWithMicrophoneEnabled:(BOOL)bMicrophoneEnabled withCameraEnabled:(BOOL)bCameraEnabled { + _screenRecorder = [RPScreenRecorder sharedRecorder]; + [_screenRecorder setDelegate:self]; + + [_screenRecorder setMicrophoneEnabled:bMicrophoneEnabled]; + [_screenRecorder setCameraEnabled:bCameraEnabled]; +} + +- (void)startRecording { + // NOTE(omar): stop any live broadcasts before staring a local recording + if( _broadcastController != nil ) { + [self stopBroadcast]; + } + + if( [_screenRecorder isAvailable] ) { + [_screenRecorder startRecordingWithHandler:^(NSError * _Nullable error) { + if( error ) { + NSLog( @"error starting screen recording"); + } + }]; + } +} + +- (void)stopRecording { + if( [_screenRecorder isAvailable] && [_screenRecorder isRecording] ) { + [_screenRecorder stopRecordingWithHandler:^(RPPreviewViewController * _Nullable previewViewController, NSError * _Nullable error) { + [previewViewController setPreviewControllerDelegate:self]; + + // automatically show the video preview when recording is stopped + previewViewController.popoverPresentationController.sourceView = (UIView* _Nullable)[IOSAppDelegate GetDelegate].IOSView; + [[IOSAppDelegate GetDelegate].IOSController presentViewController:previewViewController animated:YES completion:nil]; + }]; + } +} + +- (void)createCaptureContext +{ + auto fileManager = [NSFileManager defaultManager]; + auto docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; + auto captureDir = [docDir stringByAppendingFormat:@"/Captures"]; + [fileManager createDirectoryAtPath:captureDir withIntermediateDirectories:YES attributes:nil error:nil]; + + [_captureFilePath release]; + + // create the asset writer + [_assetWriter release]; + // todo: do we care about the file name? support cleaning up old captures? + auto fileName = FString::Printf(TEXT("%s.mp4"), *FGuid::NewGuid().ToString());; + _captureFilePath = [captureDir stringByAppendingFormat:@"/%@", fileName.GetNSString()]; + [_captureFilePath retain]; + + _assetWriter = [AVAssetWriter assetWriterWithURL:[NSURL fileURLWithPath:_captureFilePath] fileType:AVFileTypeMPEG4 error:nil]; + [_assetWriter retain]; + + // create the video input + [_videoInput release]; + + auto view = [IOSAppDelegate GetDelegate].IOSView; + auto width= [NSNumber numberWithFloat:view.frame.size.width]; + auto height = [NSNumber numberWithFloat:view.frame.size.height]; + + if (GEngine && GEngine->GameViewport && GEngine->GameViewport->Viewport) + { + auto viewportSize = GEngine->GameViewport->Viewport->GetSizeXY(); + width = [NSNumber numberWithInt:viewportSize.X]; + height = [NSNumber numberWithInt:viewportSize.Y]; + } + + auto videoSettings = @{ + AVVideoCodecKey : AVVideoCodecTypeH264, + AVVideoWidthKey : width, + AVVideoHeightKey : height + }; + + _videoInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings]; + _videoInput.expectsMediaDataInRealTime = YES; + [_videoInput retain]; + + // create the audio input + [_audioInput release]; + AudioChannelLayout acl; + bzero(&acl, sizeof(acl)); + acl.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; + auto audioSettings = @{ + AVFormatIDKey : @(kAudioFormatMPEG4AAC), + AVSampleRateKey: @(44100), + AVChannelLayoutKey: [NSData dataWithBytes:&acl length:sizeof(acl)], + }; + _audioInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioSettings]; + _audioInput.expectsMediaDataInRealTime = YES; + [_audioInput retain]; + + // add the input to the writer + if ([_assetWriter canAddInput:_videoInput]) + { + [_assetWriter addInput:_videoInput]; + } + + if ([_assetWriter canAddInput:_audioInput]) + { + [_assetWriter addInput:_audioInput]; + } +} + +- (void)startCapture +{ + if (_broadcastController) + { + [self stopBroadcast]; + } + + if ([_screenRecorder isAvailable]) + { + [self createCaptureContext]; + + [_screenRecorder startCaptureWithHandler:^(CMSampleBufferRef sampleBuffer, RPSampleBufferType bufferType, NSError *error) + { + if (CMSampleBufferDataIsReady(sampleBuffer)) + { + if (_assetWriter.status == AVAssetWriterStatusUnknown) + { + [_assetWriter startWriting]; + [_assetWriter startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)]; + } + + if (_assetWriter.status == AVAssetWriterStatusFailed) + { + NSLog(@"%d: %@", (int)_assetWriter.error.code, _assetWriter.error.localizedDescription); + return; + } + + AVAssetWriterInput* input = nullptr; + + if (bufferType == RPSampleBufferTypeVideo) + { + input = _videoInput; + } + else if (bufferType == RPSampleBufferTypeAudioApp) + { + input = _audioInput; + } + else if (bufferType == RPSampleBufferTypeAudioMic) + { + // todo? + } + + if (input && input.isReadyForMoreMediaData) + { + [input appendSampleBuffer:sampleBuffer]; + } + } + } + + completionHandler:^(NSError *error) + { + if (error) + { + NSLog(@"completionHandler: %@", error); + } + }]; + } +} + +- (void)stopCapture +{ + if ([_screenRecorder isAvailable]) + { + [_screenRecorder stopCaptureWithHandler:^(NSError *error) + { + if (error) + { + NSLog(@"stopCaptureWithHandler: %@", error); + } + + if (_assetWriter) + { + [_assetWriter finishWritingWithCompletionHandler:^() + { + NSLog(@"finishWritingWithCompletionHandler"); + + if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(_captureFilePath)) + { + UISaveVideoAtPathToSavedPhotosAlbum(_captureFilePath, nil, nil, nil); + NSLog(@"capture saved to album"); + } + + [_captureFilePath release]; + _captureFilePath = nullptr; + + [_videoInput release]; + _videoInput = nullptr; + + [_audioInput release]; + _audioInput = nullptr; + + [_assetWriter release]; + _assetWriter = nullptr; + }]; + } + }]; + } +} + +// +// livestreaming functionality +// + +- (void)startBroadcast { + // NOTE(omar): ending any local recordings that might be active before starting a broadcast + if( [_screenRecorder isRecording] ) { + [self stopRecording]; + } + + [RPBroadcastActivityViewController loadBroadcastActivityViewControllerWithHandler:^(RPBroadcastActivityViewController * _Nullable broadcastActivityViewController, NSError * _Nullable error) { + _broadcastActivityController = broadcastActivityViewController; + [_broadcastActivityController setDelegate:self]; + [[IOSAppDelegate GetDelegate].IOSController presentViewController:_broadcastActivityController animated:YES completion:nil]; + }]; +} + +- (void)pauseBroadcast { + if( [_broadcastController isBroadcasting] ) { + [_broadcastController pauseBroadcast]; + } +} + +- (void)resumeBroadcast { + if( [_broadcastController isPaused] ) { + [_broadcastController resumeBroadcast]; + } +} + +- (void)stopBroadcast { + if( [_broadcastController isBroadcasting ] ) { + [_broadcastController finishBroadcastWithHandler:^(NSError * _Nullable error) { + if( error ) { + NSLog( @"error finishing broadcast" ); + } + + [_broadcastController release]; + _broadcastController = nil; + }]; + } +} + +// +// delegates +// + +// screen recorder delegate +- (void)screenRecorder:(RPScreenRecorder* _Nullable)screenRecorder didStopRecordingWithError:(NSError* _Nullable)error previewViewController:(RPPreviewViewController* _Nullable)previewViewController { + NSLog(@"RTRScreenRecorderDelegate::didStopRecrodingWithError"); + [previewViewController dismissViewControllerAnimated:YES completion:nil]; +} + +- (void)screenRecorderDidChangeAvailability:(RPScreenRecorder* _Nullable)screenRecorder { + NSLog(@"RTRScreenRecorderDelegate::screenRecorderDidChangeAvailability"); +} + +// screen recorder preview view controller delegate +- (void)previewControllerDidFinish:(RPPreviewViewController* _Nullable)previewController { + NSLog( @"RTRPreviewViewControllerDelegate::previewControllerDidFinish" ); + [previewController dismissViewControllerAnimated:YES completion:nil]; +} + +- (void)previewController:(RPPreviewViewController* _Nullable)previewController didFinishWithActivityTypes:(NSSet * _Nullable)activityTypes __TVOS_PROHIBITED { + NSLog( @"RTRPreviewViewControllerDelegate::didFinishWithActivityTypes" ); + [previewController dismissViewControllerAnimated:YES completion:nil]; +} + +// broadcast activity view controller delegate +- (void)broadcastActivityViewController:(RPBroadcastActivityViewController* _Nullable)broadcastActivityViewController didFinishWithBroadcastController:(RPBroadcastController* _Nullable)broadcastController error:(NSError* _Nullable)error { + NSLog( @"RPBroadcastActivityViewControllerDelegate::didFinishWithBroadcastController" ); + + [broadcastActivityViewController dismissViewControllerAnimated:YES completion:^{ + _broadcastController = [broadcastController retain]; + [_broadcastController setDelegate:self]; + [_broadcastController startBroadcastWithHandler:^(NSError* _Nullable _error) { + if( _error ) { + NSLog( @"error starting broadcast" ); + } + }]; + }]; +} + +// broadcast controller delegate +- (void)broadcastController:(RPBroadcastController* _Nullable)broadcastController didFinishWithError:(NSError* _Nullable)error { + NSLog( @"RPBroadcastControllerDelegate::didFinishWithError" ); +} + +- (void)broadcastController:(RPBroadcastController* _Nullable)broadcastController didUpdateServiceInfo:(NSDictionary *> *_Nullable)serviceInfo { + NSLog( @"RPBroadcastControllerDelegate::didUpdateServiceInfo" ); +} + + +@end + +#endif diff --git a/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Private/ReplayKitRecorder.h b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Private/ReplayKitRecorder.h new file mode 100644 index 000000000000..81c1ab258840 --- /dev/null +++ b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Private/ReplayKitRecorder.h @@ -0,0 +1,55 @@ +// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. + + +#include "CoreTypes.h" + +#if PLATFORM_IOS + +#import +#import + +// screen recorder wrapper class +@interface ReplayKitRecorder : NSObject + +- (void) initializeWithMicrophoneEnabled:(BOOL)bMicrophoneEnabled withCameraEnabled:(BOOL)bCameraEnabled; + +// local recording +- (void)startRecording; +- (void)stopRecording; + +- (void)startCapture; +- (void)stopCapture; + +// +// livestreaming functionality +//` +- (void)startBroadcast; +- (void)pauseBroadcast; +- (void)resumeBroadcast; +- (void)stopBroadcast; + +// +// delegates +// + +// screen recorder delegate +- (void)screenRecorder:(RPScreenRecorder *_Nullable)screenRecorder didStopRecordingWithError:(NSError *_Nullable)error previewViewController:(nullable RPPreviewViewController *)previewViewController; +- (void)screenRecorderDidChangeAvailability:(RPScreenRecorder *_Nullable)screenRecorder; + +// screen recorder preview view controller delegate +- (void)previewControllerDidFinish:(RPPreviewViewController *_Nullable)previewController; +- (void)previewController:(RPPreviewViewController *_Nullable)previewController didFinishWithActivityTypes:(NSSet *_Nullable)activityTypes __TVOS_PROHIBITED; + +// broadcast activity view controller delegate +- (void)broadcastActivityViewController:(RPBroadcastActivityViewController *_Nullable)broadcastActivityViewController didFinishWithBroadcastController:(nullable RPBroadcastController *)broadcastController error:(nullable NSError *)error; + +// broadcast controller delegate +- (void)broadcastController:(RPBroadcastController *_Nullable)broadcastController didFinishWithError:(NSError * __nullable)error; +- (void)broadcastController:(RPBroadcastController *_Nullable)broadcastController didUpdateServiceInfo:(NSDictionary *> *_Nullable)serviceInfo; + +@end + +#endif diff --git a/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Public/IOSReplayKit.h b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Public/IOSReplayKit.h new file mode 100644 index 000000000000..d770ea9b34b8 --- /dev/null +++ b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Public/IOSReplayKit.h @@ -0,0 +1,58 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Modules/ModuleManager.h" + +DECLARE_LOG_CATEGORY_EXTERN(LogIOSReplayKit, Log, All); + +/** + * The public interface to this module. In most cases, this interface is only public to sibling modules + * within this plugin. + */ +class IIOSReplayKitModuleInterface : public IModuleInterface +{ + +public: + + virtual void Initialize( bool bMicrophoneEnabled = false, bool bCameraEnabled = false ) = 0; + + virtual void StartRecording() = 0; + virtual void StopRecording() = 0; + + virtual void StartCaptureToFile() = 0; + virtual void StopCapture() = 0; + + virtual void StartBroadcast() = 0; + virtual void PauseBroadcast() = 0; + virtual void ResumeBroadcast() = 0; + virtual void StopBroadcast() = 0; + + /** + * Singleton-like access to this module's interface. This is just for convenience! + * Beware of calling this during the shutdown phase, though. Your module might have been unloaded already. + * + * @return Returns singleton instance, loading the module on demand if needed + */ + static inline IIOSReplayKitModuleInterface& Get() + { + return FModuleManager::LoadModuleChecked< IIOSReplayKitModuleInterface >( "IOSReplayKit" ); + } + + /** + * Checks to see if this module is loaded and ready. It is only valid to call Get() if IsAvailable() returns true. + * + * @return True if the module is loaded and ready to use + */ + static inline bool IsAvailable() + { + return FModuleManager::Get().IsModuleLoaded( "IOSReplayKit" ); + } + + /** IModuleInterface implementation */ + virtual void StartupModule() override; + virtual void ShutdownModule() override; +}; + + diff --git a/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Public/IOSReplayKitControl.h b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Public/IOSReplayKitControl.h new file mode 100644 index 000000000000..93100b9f6566 --- /dev/null +++ b/Engine/Plugins/Runtime/IOSReplayKit/Source/IOSReplayKit/Public/IOSReplayKitControl.h @@ -0,0 +1,26 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "IOSReplayKitControl.generated.h" + +UCLASS() +class IOSREPLAYKIT_API UIOSReplayKitControl : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION( BlueprintCallable, Category="IOSReplayKit", meta = (WorldContext = "WorldContextObject", Keywords = "replaykit record")) + static void StartRecording(bool bMicrophoneEnabled = true); + + UFUNCTION( BlueprintCallable, Category="IOSReplayKit", meta = (WorldContext = "WorldContextObject", Keywords = "replaykit record")) + static void StopRecording(); + + UFUNCTION( BlueprintCallable, Category="IOSReplayKit", meta = (WorldContext = "WorldContextObject", Keywords = "replaykit capture")) + static void StartCaptureToFile(bool bMicrophoneEnabled = true); + + UFUNCTION( BlueprintCallable, Category="IOSReplayKit", meta = (WorldContext = "WorldContextObject", Keywords = "replaykit capture")) + static void StopCapture(); +}; diff --git a/Engine/Plugins/Runtime/LocationServicesAndroidImpl/Source/LocationServicesAndroidImpl/Private/LocationServicesAndroidImpl.cpp b/Engine/Plugins/Runtime/LocationServicesAndroidImpl/Source/LocationServicesAndroidImpl/Private/LocationServicesAndroidImpl.cpp index d005f4140d7b..cb9129ba9f93 100644 --- a/Engine/Plugins/Runtime/LocationServicesAndroidImpl/Source/LocationServicesAndroidImpl/Private/LocationServicesAndroidImpl.cpp +++ b/Engine/Plugins/Runtime/LocationServicesAndroidImpl/Source/LocationServicesAndroidImpl/Private/LocationServicesAndroidImpl.cpp @@ -57,11 +57,11 @@ FLocationServicesData ULocationServicesAndroidImpl::GetLastKnownLocation() { static jmethodID GetLastKnownLocationMethod = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_GetLastKnownLocation", "()[F", false); - jfloatArray FloatValuesArray = (jfloatArray)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, GetLastKnownLocationMethod); + auto FloatValuesArray = NewScopedJavaObject(Env, (jfloatArray)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, GetLastKnownLocationMethod)); - jfloat* FloatValues = Env->GetFloatArrayElements(FloatValuesArray, 0); + jfloat* FloatValues = Env->GetFloatArrayElements(*FloatValuesArray, 0); - if (Env->GetArrayLength(FloatValuesArray) >= 6) + if (Env->GetArrayLength(*FloatValuesArray) >= 6) { LocData.Timestamp = FloatValues[0]; LocData.Longitude = FloatValues[1]; @@ -71,8 +71,7 @@ FLocationServicesData ULocationServicesAndroidImpl::GetLastKnownLocation() LocData.Altitude = FloatValues[5]; } - Env->ReleaseFloatArrayElements(FloatValuesArray, FloatValues, 0); - Env->DeleteLocalRef(FloatValuesArray); + Env->ReleaseFloatArrayElements(*FloatValuesArray, FloatValues, 0); } return LocData; @@ -113,4 +112,4 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeHandleLocationChanged( LocationData.Altitude = (float)altitude; ULocationServices::GetLocationServicesImpl()->OnLocationChanged.Broadcast(LocationData); -} \ No newline at end of file +} diff --git a/Engine/Plugins/Runtime/Steam/SteamAudio/Source/SteamAudio/Private/PhononCommon.cpp b/Engine/Plugins/Runtime/Steam/SteamAudio/Source/SteamAudio/Private/PhononCommon.cpp index 44e9bd69c102..8a3ae5b95384 100644 --- a/Engine/Plugins/Runtime/Steam/SteamAudio/Source/SteamAudio/Private/PhononCommon.cpp +++ b/Engine/Plugins/Runtime/Steam/SteamAudio/Source/SteamAudio/Private/PhononCommon.cpp @@ -212,9 +212,9 @@ namespace SteamAudio return StrippedMapName; } - void* LoadDll(const FString& DllFile) + void* LoadDll(const FString& DllFile, bool bErrorOnLoadFailure) { - UE_LOG(LogSteamAudio, Log, TEXT("Attempting to load %s"), *DllFile); + UE_LOG(LogSteamAudio, Display, TEXT("Attempting to load %s"), *DllFile); void* DllHandle = nullptr; @@ -224,16 +224,30 @@ namespace SteamAudio } else { - UE_LOG(LogSteamAudio, Error, TEXT("File does not exist. %s"), *DllFile); + if (bErrorOnLoadFailure) + { + UE_LOG(LogSteamAudio, Error, TEXT("Failed to load missing file. %s"), *DllFile); + } + else + { + UE_LOG(LogSteamAudio, Display, TEXT("File does not exist. %s"), *DllFile); + } } if (!DllHandle) { - UE_LOG(LogSteamAudio, Error, TEXT("Unable to load %s."), *DllFile); + if (bErrorOnLoadFailure) + { + UE_LOG(LogSteamAudio, Error, TEXT("Failure to load %s."), *DllFile) + } + else + { + UE_LOG(LogSteamAudio, Display, TEXT("Unable to load %s."), *DllFile); + } } else { - UE_LOG(LogSteamAudio, Log, TEXT("Loaded %s."), *DllFile); + UE_LOG(LogSteamAudio, Display, TEXT("Loaded %s."), *DllFile); } return DllHandle; diff --git a/Engine/Plugins/Runtime/Steam/SteamAudio/Source/SteamAudio/Private/PhononCommon.h b/Engine/Plugins/Runtime/Steam/SteamAudio/Source/SteamAudio/Private/PhononCommon.h index 9161eab6d203..b9a49c84963f 100644 --- a/Engine/Plugins/Runtime/Steam/SteamAudio/Source/SteamAudio/Private/PhononCommon.h +++ b/Engine/Plugins/Runtime/Steam/SteamAudio/Source/SteamAudio/Private/PhononCommon.h @@ -133,8 +133,8 @@ namespace SteamAudio /** Strips PIE prefix from map name for use in-editor. */ FString STEAMAUDIO_API StrippedMapName(const FString& MapName); - /** Attempts to loads the specified DLL, performing some basic error checking. Returns handle to DLL or nullptr on error.*/ - void* LoadDll(const FString& DllFile); + /** Attempts to loads the specified DLL, performing some basic error checking. Returns handle to DLL or nullptr if failed to load.*/ + void* LoadDll(const FString& DllFile, bool bErrorOnLoadFailure); /** Error logs non-successful statuses. */ void LogSteamAudioStatus(const IPLerror Status); diff --git a/Engine/Plugins/Runtime/Steam/SteamAudio/Source/SteamAudio/Private/SteamAudioModule.cpp b/Engine/Plugins/Runtime/Steam/SteamAudio/Source/SteamAudio/Private/SteamAudioModule.cpp index 864deb1201c0..c7c56b2d864c 100644 --- a/Engine/Plugins/Runtime/Steam/SteamAudio/Source/SteamAudio/Private/SteamAudioModule.cpp +++ b/Engine/Plugins/Runtime/Steam/SteamAudio/Source/SteamAudio/Private/SteamAudioModule.cpp @@ -50,12 +50,12 @@ namespace SteamAudio FString PathToDll = FPaths::EngineDir() / TEXT("Binaries/ThirdParty/Phonon/Win32/"); #else FString PathToDll = FPaths::EngineDir() / TEXT("Binaries/ThirdParty/Phonon/Win64/"); - FSteamAudioModule::TANDllHandle = LoadDll(PathToDll + TEXT("tanrt64.dll")); - FSteamAudioModule::TANUtilsDllHandle = LoadDll(PathToDll + TEXT("GPUUtilities.dll")); + FSteamAudioModule::TANDllHandle = LoadDll(PathToDll + TEXT("tanrt64.dll"), false); + FSteamAudioModule::TANUtilsDllHandle = LoadDll(PathToDll + TEXT("GPUUtilities.dll"), false); #endif FString DLLToLoad = PathToDll + TEXT("phonon.dll"); - FSteamAudioModule::PhononDllHandle = LoadDll(DLLToLoad); + FSteamAudioModule::PhononDllHandle = LoadDll(DLLToLoad, true); } #endif iplCreateContext(UnrealLog, nullptr, nullptr, &GlobalContext); diff --git a/Engine/Plugins/Runtime/Synthesis/Source/Synthesis/Classes/SubmixEffects/SubmixEffectTapDelay.h b/Engine/Plugins/Runtime/Synthesis/Source/Synthesis/Classes/SubmixEffects/SubmixEffectTapDelay.h index cc9d8f9f4d39..c2307ccb7682 100644 --- a/Engine/Plugins/Runtime/Synthesis/Source/Synthesis/Classes/SubmixEffects/SubmixEffectTapDelay.h +++ b/Engine/Plugins/Runtime/Synthesis/Source/Synthesis/Classes/SubmixEffects/SubmixEffectTapDelay.h @@ -69,7 +69,7 @@ struct SYNTHESIS_API FTapDelayInfo UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Realtime, meta = (ClampMin = "-180.0", ClampMax = "180.0")) float PanInDegrees; - UPROPERTY(transient) + UPROPERTY(Transient, meta = (IgnoreForMemberInitializationTest)) int32 TapId; public: diff --git a/Engine/Plugins/Runtime/Synthesis/Source/Synthesis/Private/SubmixEffectTapDelay.cpp b/Engine/Plugins/Runtime/Synthesis/Source/Synthesis/Private/SubmixEffectTapDelay.cpp index 774f0f2ce6fd..f3d2c5ea36fa 100644 --- a/Engine/Plugins/Runtime/Synthesis/Source/Synthesis/Private/SubmixEffectTapDelay.cpp +++ b/Engine/Plugins/Runtime/Synthesis/Source/Synthesis/Private/SubmixEffectTapDelay.cpp @@ -73,9 +73,8 @@ FTapDelayInfo::FTapDelayInfo() , Gain(-3.0f) , OutputChannel(0) , PanInDegrees(0.0f) - , TapId(0) + , TapId(TapIdCount++) { - TapId = TapIdCount++; } FSubmixEffectTapDelay::FSubmixEffectTapDelay() diff --git a/Engine/Plugins/Runtime/WebBrowserNativeProxy/Source/WebBrowserNativeProxy/Private/WebBrowserNativeProxyModule.cpp b/Engine/Plugins/Runtime/WebBrowserNativeProxy/Source/WebBrowserNativeProxy/Private/WebBrowserNativeProxyModule.cpp new file mode 100644 index 000000000000..c0b768b84a49 --- /dev/null +++ b/Engine/Plugins/Runtime/WebBrowserNativeProxy/Source/WebBrowserNativeProxy/Private/WebBrowserNativeProxyModule.cpp @@ -0,0 +1,153 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "WebBrowserNativeProxyModule.h" +#include "Modules/ModuleManager.h" +#include "WebBrowserModule.h" +#include "IWebBrowserSingleton.h" +#include "IWebBrowserWindow.h" +#include "IWebBrowserPopupFeatures.h" +#include "SWebBrowser.h" +#include "Framework/Application/SlateApplication.h" +#include "Widgets/Layout/SBorder.h" +#include "Misc/App.h" + +class FWebBrowserNativeProxyModule : public IWebBrowserNativeProxyModule +{ +public: + virtual void StartupModule() override + { + } + + virtual void ShutdownModule() override + { + Browser.Reset(); + } + + virtual TSharedPtr GetBrowser(bool bCreate) override + { + if (bCreate && FApp::CanEverRender()) + { + CreateBrowser(); + } + return Browser; + } + + virtual FOnBrowserAvailableEvent& OnBrowserAvailable() override + { + return BrowserAvailableEvent; + } + +private: + + void CreateBrowser() + { + if (!Browser.IsValid()) + { +#if BUILD_EMBEDDED_APP + Browser = IWebBrowserModule::Get().GetSingleton()->CreateNativeBrowserProxy(); +#else + + FCreateBrowserWindowSettings WindowSettings; + WindowSettings.bUseTransparency = true; + WindowSettings.bShowErrorMessage = false; + Browser = IWebBrowserModule::Get().GetSingleton()->CreateBrowserWindow(WindowSettings); + +#if !UE_BUILD_SHIPPING + IWebBrowserModule::Get().GetSingleton()->SetDevToolsShortcutEnabled(true); + Browser->OnCreateWindow().BindRaw(this, &FWebBrowserNativeProxyModule::HandleBrowserCreateWindow); +#endif +#endif + OnBrowserAvailable().Broadcast(Browser.ToSharedRef()); + } + } + +#if !BUILD_EMBEDDED_APP && !UE_BUILD_SHIPPING + bool HandleBrowserCreateWindow(const TWeakPtr& NewBrowserWindow, const TWeakPtr& PopupFeatures) + { + TSharedPtr ParentDebugToolsWindow = FSlateApplication::Get().GetActiveTopLevelWindow(); + if (ParentDebugToolsWindow.IsValid()) + { + TSharedPtr PopupFeaturesSP = PopupFeatures.Pin(); + check(PopupFeatures.IsValid()) + + const int PosX = PopupFeaturesSP->IsXSet() ? PopupFeaturesSP->GetX() : 100; + const int PosY = PopupFeaturesSP->IsYSet() ? PopupFeaturesSP->GetY() : 100; + const FVector2D BrowserWindowPosition(PosX, PosY); + + const int Width = PopupFeaturesSP->IsWidthSet() ? PopupFeaturesSP->GetWidth() : 1024; + const int Height = PopupFeaturesSP->IsHeightSet() ? PopupFeaturesSP->GetHeight() : 768; + const FVector2D BrowserWindowSize(Width, Height); + + const ESizingRule SizeingRule = PopupFeaturesSP->IsResizable() ? ESizingRule::UserSized : ESizingRule::FixedSize; + + TSharedPtr NewBrowserWindowSP = NewBrowserWindow.Pin(); + check(NewBrowserWindowSP.IsValid()) + + TSharedRef BrowserWindowWidget = + SNew(SWindow) + .Title(FText::FromString(TEXT("Debug"))) + .ClientSize(BrowserWindowSize) + .ScreenPosition(BrowserWindowPosition) + .AutoCenter(EAutoCenter::None) + .SizingRule(SizeingRule) + .SupportsMaximize(SizeingRule != ESizingRule::FixedSize) + .SupportsMinimize(SizeingRule != ESizingRule::FixedSize) + .HasCloseButton(true) + .CreateTitleBar(true) + .IsInitiallyMaximized(PopupFeaturesSP->IsFullscreen()) + .LayoutBorder(FMargin(0)); + + // Setup browser widget. + TSharedPtr BrowserWidget; + BrowserWindowWidget->SetContent( + SNew(SBorder) + .VAlign(VAlign_Fill) + .HAlign(HAlign_Fill) + .Padding(0) + [ + SAssignNew(BrowserWidget, SWebBrowser, NewBrowserWindowSP) + .ShowControls(PopupFeaturesSP->IsToolBarVisible()) + .ShowAddressBar(PopupFeaturesSP->IsLocationBarVisible()) + ] + ); + + // Setup some OnClose stuff. + { + struct FLocal + { + static void RequestDestroyWindowOverride(const TSharedRef& Window, TWeakPtr BrowserWindowPtr) + { + TSharedPtr BrowserWindow = BrowserWindowPtr.Pin(); + if (BrowserWindow.IsValid()) + { + if (BrowserWindow->IsClosing()) + { + FSlateApplicationBase::Get().RequestDestroyWindow(Window); + } + else + { + BrowserWindow->CloseBrowser(false); + } + } + } + }; + + BrowserWindowWidget->SetRequestDestroyWindowOverride(FRequestDestroyWindowOverride::CreateStatic(&FLocal::RequestDestroyWindowOverride, TWeakPtr(NewBrowserWindow))); + } + + FSlateApplication::Get().AddWindowAsNativeChild(BrowserWindowWidget, ParentDebugToolsWindow.ToSharedRef()); + BrowserWindowWidget->BringToFront(); + FSlateApplication::Get().SetKeyboardFocus(BrowserWidget, EFocusCause::SetDirectly); + + return true; + } + return false; + } +#endif + + TSharedPtr Browser; + FOnBrowserAvailableEvent BrowserAvailableEvent; +}; + + +IMPLEMENT_MODULE(FWebBrowserNativeProxyModule, WebBrowserNativeProxy); diff --git a/Engine/Plugins/Runtime/WebBrowserNativeProxy/Source/WebBrowserNativeProxy/Public/WebBrowserNativeProxyModule.h b/Engine/Plugins/Runtime/WebBrowserNativeProxy/Source/WebBrowserNativeProxy/Public/WebBrowserNativeProxyModule.h new file mode 100644 index 000000000000..ea6a0701058a --- /dev/null +++ b/Engine/Plugins/Runtime/WebBrowserNativeProxy/Source/WebBrowserNativeProxy/Public/WebBrowserNativeProxyModule.h @@ -0,0 +1,61 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "Modules/ModuleManager.h" +#include "IWebBrowserSingleton.h" + +/** + * The public interface to this module + */ +class IWebBrowserNativeProxyModule : public IModuleInterface +{ + +public: + + /** + * Name of this module + */ + static inline const TCHAR* GetModuleName() + { + return TEXT("WebBrowserNativeProxy"); + } + + /** + * Singleton-like access to this module's interface. This is just for convenience! + * Beware of calling this during the shutdown phase, though. Your module might have been unloaded already. + * + * @return Returns singleton instance, loading the module on demand if needed + */ + static inline IWebBrowserNativeProxyModule& Get() + { + return FModuleManager::LoadModuleChecked(GetModuleName()); + } + + /** + * Checks to see if this module is loaded and ready. It is only valid to call Get() if IsAvailable() returns true. + * + * @return True if the module is loaded and ready to use + */ + static inline bool IsAvailable() + { + return FModuleManager::Get().IsModuleLoaded(GetModuleName()); + } + +public: + + /** + * Get the single browser window associated with the module + * + * @param bCreate if true then create the window if not already created + * @return ptr to the browser window + */ + virtual TSharedPtr GetBrowser(bool bCreate=false) = 0; + + /** + * Callback for when the browser window has been created and is available + */ + DECLARE_EVENT_OneParam(IWebBrowserNativeProxyModule, FOnBrowserAvailableEvent, const TSharedRef& /*Browser*/); + virtual FOnBrowserAvailableEvent& OnBrowserAvailable() = 0; +}; + diff --git a/Engine/Plugins/Runtime/WebBrowserNativeProxy/Source/WebBrowserNativeProxy/WebBrowserNativeProxy.build.cs b/Engine/Plugins/Runtime/WebBrowserNativeProxy/Source/WebBrowserNativeProxy/WebBrowserNativeProxy.build.cs new file mode 100644 index 000000000000..489462e7dbb1 --- /dev/null +++ b/Engine/Plugins/Runtime/WebBrowserNativeProxy/Source/WebBrowserNativeProxy/WebBrowserNativeProxy.build.cs @@ -0,0 +1,27 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +namespace UnrealBuildTool.Rules +{ + public class WebBrowserNativeProxy : ModuleRules + { + public WebBrowserNativeProxy(ReadOnlyTargetRules Target) : base(Target) + { + PublicDependencyModuleNames.AddRange( + new string[] + { + "Core", + "CoreUObject", + "WebBrowser" + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "SlateCore", + "Slate", + } + ); + } + } +} \ No newline at end of file diff --git a/Engine/Plugins/Runtime/WebBrowserNativeProxy/WebBrowserNativeProxy.uplugin b/Engine/Plugins/Runtime/WebBrowserNativeProxy/WebBrowserNativeProxy.uplugin new file mode 100644 index 000000000000..0026dfe836af --- /dev/null +++ b/Engine/Plugins/Runtime/WebBrowserNativeProxy/WebBrowserNativeProxy.uplugin @@ -0,0 +1,31 @@ +{ + "FileVersion" : 3, + "Version" : 1, + "VersionName" : "1.0", + "FriendlyName" : "Web Browser to Native Proxying", + "Description" : "Maintains the browser to native proxy and provides hooks for registering UObjects bindings", + "Category" : "Web", + "CreatedBy" : "Epic Games, Inc.", + "CreatedByURL" : "http://epicgames.com", + "DocsURL" : "", + "MarketplaceURL" : "", + "SupportURL" : "", + "EnabledByDefault" : false, + "IsBetaVersion" : false, + "Installed" : false, + "Modules" : + [ + { + "Name" : "WebBrowserNativeProxy", + "Type" : "Runtime", + "LoadingPhase" : "PreDefault", + "WhitelistPlatforms" : + [ + "Win64", + "Mac", + "iOS", + "Android" + ] + } + ] +} diff --git a/Engine/Plugins/Runtime/WebMMoviePlayer/Source/WebMMoviePlayer/Private/WebMMovieStreamer.cpp b/Engine/Plugins/Runtime/WebMMoviePlayer/Source/WebMMoviePlayer/Private/WebMMovieStreamer.cpp index 702c9b7e802f..b4eb8343f507 100644 --- a/Engine/Plugins/Runtime/WebMMoviePlayer/Source/WebMMoviePlayer/Private/WebMMovieStreamer.cpp +++ b/Engine/Plugins/Runtime/WebMMoviePlayer/Source/WebMMoviePlayer/Private/WebMMovieStreamer.cpp @@ -27,6 +27,7 @@ FWebMMovieStreamer::FWebMMovieStreamer() , VideoFramesCurrentlyProcessing(0) , StartTime(0) , bPlaying(false) + , TicksLeftToWaitPostCompletion(0) { } @@ -134,6 +135,17 @@ bool FWebMMovieStreamer::Tick(float InDeltaTime) { if (bPlaying) { + if (TicksLeftToWaitPostCompletion) + { + if (--TicksLeftToWaitPostCompletion <= 0) + { + TicksLeftToWaitPostCompletion = 0; + return !StartNextMovie(); + } + + return false; + } + bool bHaveThingsToDo = false; bHaveThingsToDo |= DisplayFrames(InDeltaTime); @@ -141,16 +153,13 @@ bool FWebMMovieStreamer::Tick(float InDeltaTime) bHaveThingsToDo |= ReadMoreFrames(); - if (bHaveThingsToDo) + if (!bHaveThingsToDo) { - // We're still playing this movie - return false; - } - else - { - // Try to start next movie from the queue - return !StartNextMovie(); + // we're done playing this movie, make sure we can safely remove the textures next frame + TicksLeftToWaitPostCompletion = 1; + Viewport->SetTexture(nullptr); } + return false; } else { diff --git a/Engine/Plugins/Runtime/WebMMoviePlayer/Source/WebMMoviePlayer/Private/WebMMovieStreamer.h b/Engine/Plugins/Runtime/WebMMoviePlayer/Source/WebMMoviePlayer/Private/WebMMovieStreamer.h index d59410cfd7e2..fcd0a8c056ff 100644 --- a/Engine/Plugins/Runtime/WebMMoviePlayer/Source/WebMMoviePlayer/Private/WebMMovieStreamer.h +++ b/Engine/Plugins/Runtime/WebMMoviePlayer/Source/WebMMoviePlayer/Private/WebMMovieStreamer.h @@ -49,6 +49,13 @@ private: double StartTime; bool bPlaying; + /** + * Number of ticks to wait after the movie is complete before moving on to the next one. + * + * This allows us to defer texture deletion while it is being displayed. + */ + int32 TicksLeftToWaitPostCompletion; + bool StartNextMovie(); void ReleaseAcquiredResources(); bool DisplayFrames(float InDeltaTime); diff --git a/Engine/Plugins/Runtime/WindowsMixedReality/Source/WindowsMixedRealityHMD/Private/WindowsMixedRealityHMD.cpp b/Engine/Plugins/Runtime/WindowsMixedReality/Source/WindowsMixedRealityHMD/Private/WindowsMixedRealityHMD.cpp index 7af2cc60f9d8..1c370a7e4a53 100644 --- a/Engine/Plugins/Runtime/WindowsMixedReality/Source/WindowsMixedRealityHMD/Private/WindowsMixedRealityHMD.cpp +++ b/Engine/Plugins/Runtime/WindowsMixedReality/Source/WindowsMixedRealityHMD/Private/WindowsMixedRealityHMD.cpp @@ -206,8 +206,18 @@ namespace WindowsMixedReality TRefCountPtr FWindowsMixedRealityHMD::InternalGetD3D11Device() { - FlushRenderingCommands(); - return (ID3D11Device*)RHIGetNativeDevice(); + if (!D3D11Device.IsValid()) + { + FWindowsMixedRealityHMD* Self = this; + ENQUEUE_RENDER_COMMAND(InternalGetD3D11DeviceCmd)([Self](FRHICommandListImmediate& RHICmdList) + { + Self->D3D11Device = (ID3D11Device*)RHIGetNativeDevice(); + }); + + FlushRenderingCommands(); + } + + return D3D11Device; } /** Helper function for acquiring the appropriate FSceneViewport */ diff --git a/Engine/Plugins/Runtime/nDisplay/Source/DisplayCluster/Private/Render/Devices/DisplayClusterDeviceBase.cpp b/Engine/Plugins/Runtime/nDisplay/Source/DisplayCluster/Private/Render/Devices/DisplayClusterDeviceBase.cpp index 72199525402f..7e701d9dfb54 100644 --- a/Engine/Plugins/Runtime/nDisplay/Source/DisplayCluster/Private/Render/Devices/DisplayClusterDeviceBase.cpp +++ b/Engine/Plugins/Runtime/nDisplay/Source/DisplayCluster/Private/Render/Devices/DisplayClusterDeviceBase.cpp @@ -154,9 +154,9 @@ void FDisplayClusterDeviceBase::PerformSynchronizationPolicyNvSwapLock(int32& In EStereoscopicPass FDisplayClusterDeviceBase::EncodeStereoscopicPass(int ViewIndex) const { - EStereoscopicPass EncodedPass = EStereoscopicPass::eSSP_RIGHT_EYE_SIDE; + EStereoscopicPass EncodedPass = EStereoscopicPass::eSSP_FULL; - // We don't care about mono/stereo. We need to fullfil ViewState and StereoViewStates in a proper way. + // We don't care about mono/stereo. We need to fulfill ViewState and StereoViewStates in a proper way. // Look at ULocalPlayer::CalcSceneViewInitOptions for view states mapping. if (ViewIndex < 2) { @@ -164,7 +164,7 @@ EStereoscopicPass FDisplayClusterDeviceBase::EncodeStereoscopicPass(int ViewInde } else { - EncodedPass = EStereoscopicPass(int(EStereoscopicPass::eSSP_RIGHT_EYE_SIDE) + ViewIndex - 1); + EncodedPass = EStereoscopicPass(int(EStereoscopicPass::eSSP_RIGHT_EYE) + ViewIndex - 1); } return EncodedPass; @@ -172,12 +172,12 @@ EStereoscopicPass FDisplayClusterDeviceBase::EncodeStereoscopicPass(int ViewInde EStereoscopicPass FDisplayClusterDeviceBase::DecodeStereoscopicPass(const enum EStereoscopicPass StereoPassType) const { - EStereoscopicPass DecodedPass = EStereoscopicPass::eSSP_RIGHT_EYE_SIDE; + EStereoscopicPass DecodedPass = EStereoscopicPass::eSSP_FULL; // Monoscopic rendering if (ViewsAmountPerViewport == 1) { - DecodedPass = EStereoscopicPass::eSSP_RIGHT_EYE_SIDE; + DecodedPass = EStereoscopicPass::eSSP_FULL; } // Stereoscopic rendering else @@ -190,7 +190,7 @@ EStereoscopicPass FDisplayClusterDeviceBase::DecodeStereoscopicPass(const enum E break; default: - DecodedPass = ((int(StereoPassType) - int(EStereoscopicPass::eSSP_RIGHT_EYE_SIDE)) % 2 == 0) ? EStereoscopicPass::eSSP_RIGHT_EYE : EStereoscopicPass::eSSP_LEFT_EYE; + DecodedPass = ((int(StereoPassType) - int(EStereoscopicPass::eSSP_RIGHT_EYE)) % 2 == 0) ? EStereoscopicPass::eSSP_RIGHT_EYE : EStereoscopicPass::eSSP_LEFT_EYE; break; } } @@ -219,7 +219,7 @@ FDisplayClusterDeviceBase::EDisplayClusterEyeType FDisplayClusterDeviceBase::Dec EyeType = EDisplayClusterEyeType::StereoLeft; break; - case EStereoscopicPass::eSSP_RIGHT_EYE_SIDE: + case EStereoscopicPass::eSSP_FULL: EyeType = EDisplayClusterEyeType::Mono; break; @@ -417,7 +417,7 @@ uint32 FDisplayClusterDeviceBase::GetViewIndexForPass(EStereoscopicPass StereoPa break; default: - DecodedViewIndex = (int(StereoPassType) - int(EStereoscopicPass::eSSP_RIGHT_EYE_SIDE) + 1); + DecodedViewIndex = (int(StereoPassType) - int(EStereoscopicPass::eSSP_RIGHT_EYE) + 1); break; } diff --git a/Engine/Plugins/VirtualProduction/Takes/Source/TakeRecorder/Private/Widgets/STakeRecorderCockpit.cpp b/Engine/Plugins/VirtualProduction/Takes/Source/TakeRecorder/Private/Widgets/STakeRecorderCockpit.cpp index ead7fe3ab6ce..04ec2510ea70 100644 --- a/Engine/Plugins/VirtualProduction/Takes/Source/TakeRecorder/Private/Widgets/STakeRecorderCockpit.cpp +++ b/Engine/Plugins/VirtualProduction/Takes/Source/TakeRecorder/Private/Widgets/STakeRecorderCockpit.cpp @@ -368,7 +368,7 @@ void STakeRecorderCockpit::Construct(const FArguments& InArgs) SNew(STextBlock) .ColorAndOpacity(FSlateColor::UseSubduedForeground()) .Font(FTakeRecorderStyle::Get().GetFontStyle("TakeRecorder.Cockpit.SmallText")) - .Text(FText::FromString(TEXT("60 fps"))) + .Text(this, &STakeRecorderCockpit::GetFrameRateText) ] ] @@ -598,6 +598,11 @@ FText STakeRecorderCockpit::GetTimestampText() const return TextTime; } +FText STakeRecorderCockpit::GetFrameRateText() const +{ + return GetFrameRate().ToPrettyText(); +} + FFrameRate STakeRecorderCockpit::GetFrameRate() const { return TakeMetaData->GetFrameRate(); @@ -637,22 +642,6 @@ void STakeRecorderCockpit::SetUserDescriptionText(const FText& InNewText, ETextC } } -void STakeRecorderCockpit::SetFrameRate(FFrameRate InNewFrameRate) -{ - FScopedTransaction Transaction(LOCTEXT("SetFrameRate_Transaction", "Set Frame Rate")); - TakeMetaData->Modify(); - - TakeMetaData->SetFrameRate(InNewFrameRate); - - ULevelSequence* Sequence = LevelSequenceAttribute.Get(); - UMovieScene* MovieScene = Sequence ? Sequence->GetMovieScene() : nullptr; - if (MovieScene) - { - MovieScene->Modify(); - MovieScene->SetDisplayRate(InNewFrameRate); - } -} - void STakeRecorderCockpit::SetDurationText(const FText& InNewText, ETextCommit::Type) { double CurrentFrameTime = TakeMetaData->GetDuration().AsDecimal(); diff --git a/Engine/Plugins/VirtualProduction/Takes/Source/TakeRecorder/Private/Widgets/STakeRecorderCockpit.h b/Engine/Plugins/VirtualProduction/Takes/Source/TakeRecorder/Private/Widgets/STakeRecorderCockpit.h index 7aeb2638799c..fca7027c22c8 100644 --- a/Engine/Plugins/VirtualProduction/Takes/Source/TakeRecorder/Private/Widgets/STakeRecorderCockpit.h +++ b/Engine/Plugins/VirtualProduction/Takes/Source/TakeRecorder/Private/Widgets/STakeRecorderCockpit.h @@ -62,7 +62,7 @@ private: FText GetTakeWarningText() const; EVisibility GetRecordErrorVisibility() const; - FText GetRecordErrorText() const; + FText GetRecordErrorText() const; void UpdateRecordError(); void UpdateTakeError(); @@ -76,9 +76,9 @@ private: FText GetUserDescriptionText() const; void SetUserDescriptionText(const FText& InNewText, ETextCommit::Type); + FText GetFrameRateText() const; FFrameRate GetFrameRate() const; bool IsFrameRateCompatible(FFrameRate InFrameRate) const; - void SetFrameRate(FFrameRate InNewFrameRate); FText GetSlateText() const; void SetSlateText(const FText& InNewText, ETextCommit::Type InCommitType); diff --git a/Engine/Plugins/VirtualProduction/Takes/Source/TakeTrackRecorders/Private/MovieSceneAnimationTrackRecorder.cpp b/Engine/Plugins/VirtualProduction/Takes/Source/TakeTrackRecorders/Private/MovieSceneAnimationTrackRecorder.cpp index 0a8d939a3c57..256dac254e04 100644 --- a/Engine/Plugins/VirtualProduction/Takes/Source/TakeTrackRecorders/Private/MovieSceneAnimationTrackRecorder.cpp +++ b/Engine/Plugins/VirtualProduction/Takes/Source/TakeTrackRecorders/Private/MovieSceneAnimationTrackRecorder.cpp @@ -102,11 +102,13 @@ void UMovieSceneAnimationTrackRecorder::CreateTrackImpl() if (AnimSequence.IsValid()) { + FFrameRate SampleRate = MovieScene->GetDisplayRate(); + FText Error; FString Name = SkeletalMeshComponent->GetName(); FName SerializedType("Animation"); FString FileName = FString::Printf(TEXT("%s_%s"), *(SerializedType.ToString()), *Name); - float IntervalTime = AnimSettings->SampleRate.AsDecimal() > 0.0f ? 1.0f / AnimSettings->SampleRate.AsDecimal() : 1.0f / FAnimationRecordingSettings::DefaultSampleRate; + float IntervalTime = SampleRate.AsDecimal() > 0.0f ? 1.0f / SampleRate.AsDecimal() : 1.0f / FAnimationRecordingSettings::DefaultSampleRate; FAnimationFileHeader Header(SerializedType, ObjectGuid, IntervalTime); USkeleton* AnimSkeleton = AnimSequence->GetSkeleton(); @@ -224,9 +226,12 @@ void UMovieSceneAnimationTrackRecorder::RecordSampleImpl(const FQualifiedFrameTi // We capture world space transforms for actors if they're attached, but we're not recording the attachment parent bRecordInWorldSpace = !OwningTakeRecorderSource->IsOtherActorBeingRecorded(AttachParent->GetOwner()); } + + FFrameRate SampleRate = MovieSceneSection->GetTypedOuter()->GetDisplayRate(); + //Set this up here so we know that it's parent sources have also been added so we record in the correct space FAnimationRecordingSettings RecordingSettings; - RecordingSettings.SampleRate = AnimSettings->SampleRate.AsDecimal(); + RecordingSettings.SampleRate = SampleRate.AsDecimal(); RecordingSettings.InterpMode = AnimSettings->InterpMode; RecordingSettings.TangentMode = AnimSettings->TangentMode; RecordingSettings.Length = 0; diff --git a/Engine/Plugins/VirtualProduction/Takes/Source/TakeTrackRecorders/Public/TrackRecorders/MovieSceneAnimationTrackRecorderSettings.h b/Engine/Plugins/VirtualProduction/Takes/Source/TakeTrackRecorders/Public/TrackRecorders/MovieSceneAnimationTrackRecorderSettings.h index 087dce40f096..8e8de92e3bae 100644 --- a/Engine/Plugins/VirtualProduction/Takes/Source/TakeTrackRecorders/Public/TrackRecorders/MovieSceneAnimationTrackRecorderSettings.h +++ b/Engine/Plugins/VirtualProduction/Takes/Source/TakeTrackRecorders/Public/TrackRecorders/MovieSceneAnimationTrackRecorderSettings.h @@ -17,7 +17,6 @@ public: : Super(ObjInit) , AnimationTrackName(NSLOCTEXT("UMovieSceneAnimationTrackRecorderSettings", "DefaultAnimationTrackName", "RecordedAnimation")) , AnimationSubDirectory(TEXT("Animation")) - , SampleRate(30, 1) , bRemoveRootAnimation(true) { } @@ -30,10 +29,6 @@ public: UPROPERTY(config, EditAnywhere, BlueprintReadWrite, Category = "Animation Recorder Settings") FString AnimationSubDirectory; - /** Maximum sample rate of the recorded animation */ - UPROPERTY(EditAnywhere, Category = "Animation Recorder Settings") - FFrameRate SampleRate; - /** Interpolation mode for the recorded keys. */ UPROPERTY(EditAnywhere, Category = "Animation Recorder Settings", DisplayName = "Interpolation Mode") TEnumAsByte InterpMode; diff --git a/Engine/Plugins/VirtualProduction/Takes/Source/TakeViewer/Private/TakeViewerModule.cpp b/Engine/Plugins/VirtualProduction/Takes/Source/TakeViewer/Private/TakeViewerModule.cpp deleted file mode 100644 index 38cc7f021889..000000000000 --- a/Engine/Plugins/VirtualProduction/Takes/Source/TakeViewer/Private/TakeViewerModule.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. - -#include "Modules/ModuleManager.h" - -IMPLEMENT_MODULE(FDefaultModuleImpl, TakeViewer); \ No newline at end of file diff --git a/Engine/Plugins/VirtualProduction/Takes/Source/TakeViewer/TakeViewer.Build.cs b/Engine/Plugins/VirtualProduction/Takes/Source/TakeViewer/TakeViewer.Build.cs deleted file mode 100644 index 4d06d4454b1c..000000000000 --- a/Engine/Plugins/VirtualProduction/Takes/Source/TakeViewer/TakeViewer.Build.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. - -using UnrealBuildTool; - -public class TakeViewer : ModuleRules -{ - public TakeViewer(ReadOnlyTargetRules Target) : base(Target) - { - PrivateDependencyModuleNames.AddRange( - new string[] { - "Core", - } - ); - - PrivateIncludePaths.AddRange( - new string[] { - "TakeViewer/Private" - } - ); - } -} diff --git a/Engine/Plugins/VirtualProduction/Takes/Takes.uplugin b/Engine/Plugins/VirtualProduction/Takes/Takes.uplugin index 5c1a777e20a9..edfff677f930 100644 --- a/Engine/Plugins/VirtualProduction/Takes/Takes.uplugin +++ b/Engine/Plugins/VirtualProduction/Takes/Takes.uplugin @@ -42,10 +42,5 @@ "Type" : "Developer", "LoadingPhase" : "PostEngineInit" }, - { - "Name" : "TakeViewer", - "Type" : "Developer", - "LoadingPhase" : "PostEngineInit" - } ] } \ No newline at end of file diff --git a/Engine/Shaders/Private/DistortAccumulatePS.usf b/Engine/Shaders/Private/DistortAccumulatePS.usf index 89a85ba20f70..a5629a76bd47 100644 --- a/Engine/Shaders/Private/DistortAccumulatePS.usf +++ b/Engine/Shaders/Private/DistortAccumulatePS.usf @@ -33,7 +33,11 @@ void Main( out float4 OutColor : SV_Target0 ) { +#if INSTANCED_STEREO + ResolvedView = ResolveView(Interpolants.EyeIndex); +#else ResolvedView = ResolveView(); +#endif // material parameter inputs FMaterialPixelParameters MaterialParameters = GetMaterialPixelParameters(Interpolants, SvPosition); @@ -81,9 +85,16 @@ void Main( float2 NDC = (MaterialParameters.ScreenPosition.xy / MaterialParameters.ScreenPosition.w); float2 ScreenUV = NDC * ResolvedView.ScreenPositionScaleBias.xy + ResolvedView.ScreenPositionScaleBias.wz; - //Fix for Fov and aspect. + // When ISR is enabled we store two FOVs in the DistortionParams and compute the aspect ratio here +#if INSTANCED_STEREO + float InvTanHalfFov = DistortionParams[Interpolants.EyeIndex]; + float Ratio = DistortionParams.z / DistortionParams.w; +#else float InvTanHalfFov = DistortionParams.x; float Ratio = DistortionParams.y; +#endif + + // Fix for Fov and aspect. float2 FovFix = float2(InvTanHalfFov,Ratio*InvTanHalfFov); BufferUVDistortion *= DistortionParams.zw * float2(OffsetFudgeFactor,-OffsetFudgeFactor) * FovFix; diff --git a/Engine/Shaders/Private/DistortAccumulateVS.usf b/Engine/Shaders/Private/DistortAccumulateVS.usf index 4e5e75e0703c..1d1534ae6a05 100644 --- a/Engine/Shaders/Private/DistortAccumulateVS.usf +++ b/Engine/Shaders/Private/DistortAccumulateVS.usf @@ -61,7 +61,7 @@ struct FDistortAccumulateVSToPS O.FactoryInterpolants = VertexFactoryAssignInterpolants(Interpolants.FactoryInterpolants); // Finally, transform position to clip-space - O.Position = mul(WorldPosition, View.TranslatedWorldToClip); + O.Position = mul(WorldPosition, ResolvedView.TranslatedWorldToClip); O.PixelPosition = WorldPosition; @@ -80,10 +80,29 @@ void Main( out VS_OUTPUT_TYPE Output #if USE_GLOBAL_CLIP_PLANE && !USING_TESSELLATION , out float OutGlobalClipPlaneDistance : SV_ClipDistance +#endif +#if INSTANCED_STEREO + , uint InstanceId : SV_InstanceID + #if !MULTI_VIEW + , out float OutClipDistance : SV_ClipDistance1 + #else + , out uint ViewportIndex : SV_ViewPortArrayIndex + #endif #endif ) { +#if INSTANCED_STEREO + const uint EyeIndex = GetEyeIndex(InstanceId); + ResolvedView = ResolveView(EyeIndex); + #if !MULTI_VIEW + OutClipDistance = 0.0; + #else + ViewportIndex = EyeIndex; + #endif +#else + uint EyeIndex = 0; ResolvedView = ResolveView(); +#endif FVertexFactoryIntermediates VFIntermediates = GetVertexFactoryIntermediates(Input); float4 WorldPosition = VertexFactoryGetWorldPosition(Input, VFIntermediates); @@ -104,9 +123,24 @@ void Main( #else // !USING_TESSELLATION - Output.Position = mul(WorldPosition, View.TranslatedWorldToClip); + Output.Position = mul(WorldPosition, ResolvedView.TranslatedWorldToClip); Output.FactoryInterpolants = VertexFactoryGetInterpolantsVSToPS(Input, VFIntermediates, VertexParameters); + #if INSTANCED_STEREO && !MULTI_VIEW + BRANCH + if (IsInstancedStereo()) + { + // Clip at the center of the screen + OutClipDistance = dot(Output.Position, EyeClipEdge[EyeIndex]); + + // Scale to the width of a single eye viewport + Output.Position.x *= 0.5 * ResolvedView.HMDEyePaddingOffset; + + // Shift to the eye viewport + Output.Position.x += (EyeOffsetScale[EyeIndex] * Output.Position.w) * (1.0f - 0.5 * ResolvedView.HMDEyePaddingOffset); + } + #endif + #if USE_GLOBAL_CLIP_PLANE OutGlobalClipPlaneDistance = dot(ResolvedView.GlobalClippingPlane, float4(WorldPosition.xyz - ResolvedView.PreViewTranslation.xyz, 1)); #endif @@ -115,6 +149,14 @@ void Main( #endif // USING_TESSELLATION +#if INSTANCED_STEREO + #if USING_TESSELLATION + Output.FactoryInterpolants.InterpolantsVSToPS.EyeIndex = EyeIndex; + #else + Output.FactoryInterpolants.EyeIndex = EyeIndex; + #endif +#endif + OutputVertexID( Output ); } diff --git a/Engine/Shaders/Private/GameplayMediaEncoderShaders.usf b/Engine/Shaders/Private/GameplayMediaEncoderShaders.usf new file mode 100644 index 000000000000..6b2494c2bbcd --- /dev/null +++ b/Engine/Shaders/Private/GameplayMediaEncoderShaders.usf @@ -0,0 +1,19 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +/*========================================================================================= + GameplayMediaEncoderShaders.usf: utility shaders for the GameplayMediaEncoder module +=========================================================================================*/ + +#include "Common.ush" + +Texture2D InTexture; +SamplerState InTextureSampler; + +// Swizzle color channels from RGBA to BGRA +void ScreenSwizzlePS( + FScreenVertexOutput Input, + out float4 OutColor : SV_Target0 + ) +{ + OutColor = Texture2DSample(InTexture, InTextureSampler, Input.UV).bgra; +} diff --git a/Engine/Shaders/Private/MeshParticleVertexFactory.ush b/Engine/Shaders/Private/MeshParticleVertexFactory.ush index 41251eba611f..41f073db0000 100644 --- a/Engine/Shaders/Private/MeshParticleVertexFactory.ush +++ b/Engine/Shaders/Private/MeshParticleVertexFactory.ush @@ -182,7 +182,7 @@ float4x4 GetParticleTransform(FVertexFactoryInput Input) float4x4 GetParticlePrevTransform(FVertexFactoryInput Input) { #if PARTICLE_MESH_INSTANCED - uint TransformBaseIdx = Input.InstanceId * 3; + uint TransformBaseIdx = GetInstanceId(Input.InstanceId) * 3; float4x4 PrevTransform4x4 = float4x4( PrevTransformBuffer[TransformBaseIdx + 0], diff --git a/Engine/Shaders/Private/MobileBasePassPixelShader.usf b/Engine/Shaders/Private/MobileBasePassPixelShader.usf index 3864186e6fdd..a8487243b41f 100644 --- a/Engine/Shaders/Private/MobileBasePassPixelShader.usf +++ b/Engine/Shaders/Private/MobileBasePassPixelShader.usf @@ -433,7 +433,7 @@ void Main( GetLightMapCoordinates(Interpolants, LightmapUV0, LightmapUV1, LightmapDataIndex); half4 LightmapColor = GetLightMapColorLQ( LightmapUV0, LightmapUV1, LightmapDataIndex, MaterialParameters.WorldNormal ); - Color += LightmapColor.rgb * DiffuseColor; + Color += LightmapColor.rgb * DiffuseColor * View.IndirectLightingColorScale; IndirectIrradiance = LightmapColor.a; #elif CACHED_POINT_INDIRECT_LIGHTING #if MATERIALBLENDING_MASKED || MATERIALBLENDING_SOLID @@ -458,9 +458,7 @@ void Main( half3 DiffuseGI = max(half3(0,0,0), DotSH3(PointIndirectLighting, DiffuseTransferSH)); IndirectIrradiance = Luminance(DiffuseGI); - Color += DiffuseColor * DiffuseGI; - - + Color += DiffuseColor * DiffuseGI * View.IndirectLightingColorScale; #else // Non-directional for translucency @@ -470,7 +468,7 @@ void Main( half3 DiffuseGI = PointIndirectLighting; IndirectIrradiance = Luminance(DiffuseGI); - Color += DiffuseColor * DiffuseGI; + Color += DiffuseColor * DiffuseGI * View.IndirectLightingColorScale; #endif #endif @@ -541,7 +539,7 @@ void Main( float NoL = max(0, dot(float3(MaterialParameters.WorldNormal), float3(MobileDirectionalLight.DirectionalLightDirectionAndShadowTransition.xyz))); float RoL = max(0, dot(float3(MaterialParameters.ReflectionVector), float3(MobileDirectionalLight.DirectionalLightDirectionAndShadowTransition.xyz))); - float3 H = normalize(MaterialParameters.CameraVector + MobileDirectionalLight.DirectionalLightDirectionAndShadowTransition.xyz); + float3 H = normalize(float3(MaterialParameters.CameraVector) + float3(MobileDirectionalLight.DirectionalLightDirectionAndShadowTransition.xyz)); float NoH = max(0,dot(MaterialParameters.WorldNormal, H)); #if FULLY_ROUGH diff --git a/Engine/Shaders/Private/ParticleGPUSpriteVertexFactory.ush b/Engine/Shaders/Private/ParticleGPUSpriteVertexFactory.ush index 3a34933d09fa..aee0c905ed17 100644 --- a/Engine/Shaders/Private/ParticleGPUSpriteVertexFactory.ush +++ b/Engine/Shaders/Private/ParticleGPUSpriteVertexFactory.ush @@ -229,7 +229,7 @@ void GetSpriteTangents( FVertexFactoryIntermediates GetVertexFactoryIntermediates( FVertexFactoryInput Input ) { // Sample the position and velocity textures to get the current state of the particle. - uint InstanceId = Input.InstanceId * PARTICLES_PER_INSTANCE + Input.VertexId / 4; + uint InstanceId = GetInstanceId(Input.InstanceId) * PARTICLES_PER_INSTANCE + Input.VertexId / 4; float2 ParticleIndex = ParticleIndices[ParticleIndicesOffset + InstanceId]; float4 PositionSample = Texture2DSampleLevel(PositionTexture, PositionTextureSampler, ParticleIndex, 0); float4 VelocitySample = Texture2DSampleLevel(VelocityTexture, VelocityTextureSampler, ParticleIndex, 0); diff --git a/Engine/Shaders/Private/PostProcessHistogramCommon.ush b/Engine/Shaders/Private/PostProcessHistogramCommon.ush index 26b202ff1416..9392a9295d88 100644 --- a/Engine/Shaders/Private/PostProcessHistogramCommon.ush +++ b/Engine/Shaders/Private/PostProcessHistogramCommon.ush @@ -128,10 +128,7 @@ float ComputeAverageLuminaneWithoutOutlier(Texture2D HistogramTexture, float Min float ComputeEyeAdaptationExposure(Texture2D HistogramTexture) { float HistogramSum = ComputeHistogramSum(HistogramTexture); - float UnclampedAdaptedLuminance = ComputeAverageLuminaneWithoutOutlier(HistogramTexture, HistogramSum * EyeAdaptationParams[0].x, HistogramSum * EyeAdaptationParams[0].y); - float ClampedAdaptedLuminance = clamp(UnclampedAdaptedLuminance, EyeAdaptationParams[0].z, EyeAdaptationParams[0].w); - - return ClampedAdaptedLuminance; + return ComputeAverageLuminaneWithoutOutlier(HistogramTexture, HistogramSum * EyeAdaptationParams[0].x, HistogramSum * EyeAdaptationParams[0].y); } // Computation of triangle function on normalized space diff --git a/Engine/Shaders/Private/VectorFieldVisualizationVertexFactory.ush b/Engine/Shaders/Private/VectorFieldVisualizationVertexFactory.ush index 293aae7266f9..49cbe0d0be0d 100644 --- a/Engine/Shaders/Private/VectorFieldVisualizationVertexFactory.ush +++ b/Engine/Shaders/Private/VectorFieldVisualizationVertexFactory.ush @@ -56,7 +56,7 @@ FVertexFactoryIntermediates GetVertexFactoryIntermediates( FVertexFactoryInput I const float3 VoxelSize = VectorFieldVis.VoxelSize.xyz; const float3 HalfVoxelOffset = VoxelSize.xyz * 0.5f; const float3 VoxelMultipliers = float3(1, VoxelSize.x, VoxelSize.x * VoxelSize.y); - const float3 VoxelIndex = floor(float3(Input.InstanceId.xxx) * VoxelMultipliers.xyz); + const float3 VoxelIndex = floor((float3)GetInstanceId(Input.InstanceId.xxx) * VoxelMultipliers.xyz); const float3 VoxelUV = frac(VoxelIndex.xyz * VoxelSize.xyz) + HalfVoxelOffset; // Read vector for this voxel. diff --git a/Engine/Shaders/Public/ShaderVersion.ush b/Engine/Shaders/Public/ShaderVersion.ush index d4dbd77a9d65..990f3b524c42 100644 --- a/Engine/Shaders/Public/ShaderVersion.ush +++ b/Engine/Shaders/Public/ShaderVersion.ush @@ -3,6 +3,7 @@ // in Platform.ush (which should be included in any shader) it allows to invalidate the shader DDC. // // If you are merging streams and there is a conflict with this GUID you should make a new GUID rather than taking one or the other. -// GUID = 569B757A-6B67-4D56-AA92-6E8D8CD50EC3adwadefafafa +// GUID = A9DE8FE2-CD23-4357-87D6-2B96A9F90453 + diff --git a/Engine/Source/Developer/Apple/MetalShaderFormat/Private/MetalShaderFormat.cpp b/Engine/Source/Developer/Apple/MetalShaderFormat/Private/MetalShaderFormat.cpp index 4d41fc784c5b..d5b63a3883d8 100644 --- a/Engine/Source/Developer/Apple/MetalShaderFormat/Private/MetalShaderFormat.cpp +++ b/Engine/Source/Developer/Apple/MetalShaderFormat/Private/MetalShaderFormat.cpp @@ -14,6 +14,8 @@ #include "Misc/ConfigCacheIni.h" #include "MetalBackend.h" +#define WRITE_METAL_SHADER_SOURCE_ARCHIVE 0 + extern uint16 GetXcodeVersion(uint64& BuildVersion); extern bool StripShader_Metal(TArray& Code, class FString const& DebugPath, bool const bNative); extern uint64 AppendShader_Metal(class FName const& Format, class FString const& ArchivePath, const FSHAHash& Hash, TArray& Code); @@ -137,7 +139,7 @@ public: bOK = true; } -#if PLATFORM_MAC +#if PLATFORM_MAC && WRITE_METAL_SHADER_SOURCE_ARCHIVE if(bOK) { //TODO add a check in here - this will only work if we have shader archiving with debug info set. diff --git a/Engine/Source/Developer/PakFileUtilities/Private/PakFileUtilities.cpp b/Engine/Source/Developer/PakFileUtilities/Private/PakFileUtilities.cpp index e86b59ac1162..f7e7f8ac813b 100644 --- a/Engine/Source/Developer/PakFileUtilities/Private/PakFileUtilities.cpp +++ b/Engine/Source/Developer/PakFileUtilities/Private/PakFileUtilities.cpp @@ -2552,6 +2552,13 @@ bool ExtractFilesFromPak(const TCHAR* InPakFilename, TMap& I IFileManager::Get().FindFiles(PakFileList, *PakFileDirectory, *FPaths::GetCleanFilename(InPakFilename)); } + if (PakFileList.Num() == 0) + { + // No files found + return false; + } + + bool bIncludeDeleted = (OutDeletedEntries != nullptr); for (int32 PakFileIndex = 0; PakFileIndex < PakFileList.Num(); PakFileIndex++) diff --git a/Engine/Source/Developer/ShaderFormatOpenGL/Private/OpenGLShaderCompiler.cpp b/Engine/Source/Developer/ShaderFormatOpenGL/Private/OpenGLShaderCompiler.cpp index e451cd108292..16826a7ec2d9 100644 --- a/Engine/Source/Developer/ShaderFormatOpenGL/Private/OpenGLShaderCompiler.cpp +++ b/Engine/Source/Developer/ShaderFormatOpenGL/Private/OpenGLShaderCompiler.cpp @@ -1494,6 +1494,12 @@ void FOpenGLFrontend::CompileShader(const FShaderCompilerInput& Input,FShaderCom // This requires removing the HLSLCC_NoPreprocess flag later on! RemoveUniformBuffersFromSource(Input.Environment, PreprocessedShader); + uint32 CCFlags = CalculateCrossCompilerFlags(Version, Input.Environment.CompilerFlags); + + // Required as we added the RemoveUniformBuffersFromSource() function (the cross-compiler won't be able to interpret comments w/o a preprocessor) + CCFlags &= ~HLSLCC_NoPreprocess; + + // Write out the preprocessed file and a batch file to compile it if requested (DumpDebugInfoPath is valid) if (bDumpDebugInfo) { @@ -1504,6 +1510,11 @@ void FOpenGLFrontend::CompileShader(const FShaderCompilerInput& Input,FShaderCom FileWriter->Serialize((ANSICHAR*)AnsiSourceFile.Get(), AnsiSourceFile.Length()); { FString Line = CrossCompiler::CreateResourceTableFromEnvironment(Input.Environment); + + Line += TEXT("#if 0 /*DIRECT COMPILE*/\n"); + Line += CreateShaderCompilerWorkerDirectCommandLine(Input, CCFlags); + Line += TEXT("\n#endif /*DIRECT COMPILE*/\n"); + FileWriter->Serialize(TCHAR_TO_ANSI(*Line), Line.Len()); } FileWriter->Close(); @@ -1516,11 +1527,6 @@ void FOpenGLFrontend::CompileShader(const FShaderCompilerInput& Input,FShaderCom } } - uint32 CCFlags = CalculateCrossCompilerFlags(Version, Input.Environment.CompilerFlags); - - // Required as we added the RemoveUniformBuffersFromSource() function (the cross-compiler won't be able to interpret comments w/o a preprocessor) - CCFlags &= ~HLSLCC_NoPreprocess; - FGlslCodeBackend* BackEnd = CreateBackend(Version, CCFlags, HlslCompilerTarget); FGlslLanguageSpec* LanguageSpec = CreateLanguageSpec(Version); @@ -1567,7 +1573,7 @@ void FOpenGLFrontend::CompileShader(const FShaderCompilerInput& Input,FShaderCom GlslShaderSource = Dest; GlslSourceLen = FCStringAnsi::Strlen(GlslShaderSource); - FArchive* FileWriter = IFileManager::Get().CreateFileWriter(*(Input.DumpDebugInfoPath / Input.VirtualSourceFilePath + TEXT(".glsl"))); + FArchive* FileWriter = IFileManager::Get().CreateFileWriter(*GLSLFile); if (FileWriter) { FileWriter->Serialize(GlslShaderSource,GlslSourceLen+1); @@ -2005,7 +2011,9 @@ void FOpenGLFrontend::CompileOffline(const FShaderCompilerInput& Input, FShaderC const bool bSupportsOfflineCompilation = PlatformSupportsOfflineCompilation(ShaderVersion); if (!bSupportsOfflineCompilation) - return; + { + return; + } TSharedPtr ShaderSource = PrepareCodeForOfflineCompilation(ShaderVersion, (EShaderFrequency)Input.Target.Frequency, InShaderSource); @@ -2015,5 +2023,7 @@ void FOpenGLFrontend::CompileOffline(const FShaderCompilerInput& Input, FShaderC void FOpenGLFrontend::PlatformCompileOffline(const FShaderCompilerInput& Input, FShaderCompilerOutput& ShaderOutput, const ANSICHAR* ShaderSource, const GLSLVersion ShaderVersion) { if (ShaderVersion == GLSL_ES2 || ShaderVersion == GLSL_ES3_1_ANDROID || ShaderVersion == GLSL_ES2_IOS) + { CompileOfflineMali(Input, ShaderOutput, ShaderSource, FPlatformString::Strlen(ShaderSource), false); + } } diff --git a/Engine/Source/Developer/SlateReflector/Private/VisualTreeCapture.h b/Engine/Source/Developer/SlateReflector/Private/VisualTreeCapture.h index 3a3ffd94e962..cc2fff5c47e7 100644 --- a/Engine/Source/Developer/SlateReflector/Private/VisualTreeCapture.h +++ b/Engine/Source/Developer/SlateReflector/Private/VisualTreeCapture.h @@ -50,8 +50,13 @@ public: FVisualTreeCapture(); ~FVisualTreeCapture(); + /** Enables visual tree capture */ void Enable(); + + /** Disables visual tree capture */ void Disable(); + + /** Resets the visual tree capture to a pre-capture state and destroys the cached visual tree captured last. */ void Reset(); TSharedPtr GetVisualTreeForWindow(SWindow* InWindow); diff --git a/Engine/Source/Developer/SlateReflector/Private/Widgets/SWidgetReflector.cpp b/Engine/Source/Developer/SlateReflector/Private/Widgets/SWidgetReflector.cpp index a95a51f84086..a471f448b4bf 100644 --- a/Engine/Source/Developer/SlateReflector/Private/Widgets/SWidgetReflector.cpp +++ b/Engine/Source/Developer/SlateReflector/Private/Widgets/SWidgetReflector.cpp @@ -293,6 +293,7 @@ private: { VisualCapture.Reset(); SInvalidationPanel::SetEnableWidgetCaching(false); + VisualCapture.Reset(); } // If we're using the drawing picking mode enable it! else if (PickingMode == EWidgetPickingMode::Drawable) diff --git a/Engine/Source/Developer/StandaloneRenderer/Private/IOS/SlateOpenGLViewport.cpp b/Engine/Source/Developer/StandaloneRenderer/Private/IOS/SlateOpenGLViewport.cpp index 57da16f4fddf..30e708f87ab8 100644 --- a/Engine/Source/Developer/StandaloneRenderer/Private/IOS/SlateOpenGLViewport.cpp +++ b/Engine/Source/Developer/StandaloneRenderer/Private/IOS/SlateOpenGLViewport.cpp @@ -83,7 +83,7 @@ void FSlateOpenGLViewport::Resize( int Width, int Height, bool bInFullscreen ) CGRect Frame = [[UIScreen mainScreen] bounds]; CGFloat Scale = [[UIScreen mainScreen] scale]; - IOSAppDelegate* AppDelegate = (IOSAppDelegate*)[[UIApplication sharedApplication] delegate]; + IOSAppDelegate* AppDelegate = [IOSAppDelegate GetDelegate]; if (!AppDelegate.bDeviceInPortraitMode) { Swap(Frame.size.width, Frame.size.height); diff --git a/Engine/Source/Editor/AnimGraph/Private/AnimGraphNode_Constraint.cpp b/Engine/Source/Editor/AnimGraph/Private/AnimGraphNode_Constraint.cpp index 24a2b35e3810..d8d46fd3265f 100644 --- a/Engine/Source/Editor/AnimGraph/Private/AnimGraphNode_Constraint.cpp +++ b/Engine/Source/Editor/AnimGraph/Private/AnimGraphNode_Constraint.cpp @@ -55,6 +55,16 @@ void UAnimGraphNode_Constraint::ValidateAnimNodeDuringCompilation(USkeleton* For } } + float OverallWeight = 0.f; + for (const float& Weight : Node.ConstraintWeights) + { + OverallWeight += Weight; + } + if (Node.ConstraintWeights.Num() > 0 && !FMath::IsNearlyEqual(OverallWeight, 1.f, ZERO_ANIMWEIGHT_THRESH * float(Node.ConstraintWeights.Num()))) + { + MessageLog.Warning(*LOCTEXT("WeightsDontSumToOne", "@@ - The weights don't add up to 1.0").ToString(), this); + } + Super::ValidateAnimNodeDuringCompilation(ForSkeleton, MessageLog); } diff --git a/Engine/Source/Editor/AudioEditor/AudioEditor.Build.cs b/Engine/Source/Editor/AudioEditor/AudioEditor.Build.cs index ccd06e869cb1..57afcbe9ed8f 100644 --- a/Engine/Source/Editor/AudioEditor/AudioEditor.Build.cs +++ b/Engine/Source/Editor/AudioEditor/AudioEditor.Build.cs @@ -24,21 +24,23 @@ public class AudioEditor : ModuleRules "Core", "CoreUObject", "ApplicationCore", - "InputCore", - "Engine", - "UnrealEd", - "Slate", - "SlateCore", - "EditorStyle", - "RenderCore", - "LevelEditor", - "Landscape", - "PropertyEditor", - "DetailCustomizations", - "ClassViewer", - "GraphEditor", - "ContentBrowser", - }); + "AudioMixer", + "InputCore", + "Engine", + "UnrealEd", + "Slate", + "SlateCore", + "EditorStyle", + "RenderCore", + "LevelEditor", + "Landscape", + "PropertyEditor", + "DetailCustomizations", + "ClassViewer", + "GraphEditor", + "ContentBrowser", + } + ); PrivateIncludePathModuleNames.AddRange( new string[] { diff --git a/Engine/Source/Editor/Blutility/Classes/EditorUtilityWidget.h b/Engine/Source/Editor/Blutility/Classes/EditorUtilityWidget.h index 23dfcfffbb34..dc05646e9864 100644 --- a/Engine/Source/Editor/Blutility/Classes/EditorUtilityWidget.h +++ b/Engine/Source/Editor/Blutility/Classes/EditorUtilityWidget.h @@ -22,7 +22,7 @@ class BLUTILITY_API UEditorUtilityWidget : public UUserWidget GENERATED_UCLASS_BODY() public: - // The default action called when the blutility is invoked if bAutoRunDefaultAction=true (it is never called otherwise) + // The default action called when the widget is invoked if bAutoRunDefaultAction=true (it is never called otherwise) UFUNCTION(BlueprintImplementableEvent) void OnDefaultActionClicked(); diff --git a/Engine/Source/Editor/Blutility/Classes/EditorUtilityWidgetBlueprint.h b/Engine/Source/Editor/Blutility/Classes/EditorUtilityWidgetBlueprint.h index 721cd13085db..cddf6a34fa52 100644 --- a/Engine/Source/Editor/Blutility/Classes/EditorUtilityWidgetBlueprint.h +++ b/Engine/Source/Editor/Blutility/Classes/EditorUtilityWidgetBlueprint.h @@ -15,6 +15,7 @@ class UBlueprint; class UEditorUtilityWidget; +enum class EAssetEditorCloseReason : uint8; UCLASS() class UEditorUtilityWidgetBlueprint : public UWidgetBlueprint @@ -22,6 +23,8 @@ class UEditorUtilityWidgetBlueprint : public UWidgetBlueprint GENERATED_UCLASS_BODY() public: + virtual void BeginDestroy() override; + TSharedRef SpawnEditorUITab(const FSpawnTabArgs& SpawnTabArgs); /** Creates the slate widget from the UMG widget */ @@ -40,8 +43,21 @@ public: return CreatedUMGWidget; } + void SetRegistrationName(FName InRegistrationName) + { + RegistrationName = InRegistrationName; + } + + FName GetRegistrationName() const + { + return RegistrationName; + } + private: + FName RegistrationName; + TWeakPtr CreatedTab; UEditorUtilityWidget* CreatedUMGWidget; + }; diff --git a/Engine/Source/Editor/Blutility/Private/AssetTypeActions_EditorUtilityWidgetBlueprint.cpp b/Engine/Source/Editor/Blutility/Private/AssetTypeActions_EditorUtilityWidgetBlueprint.cpp index 69ad362b6639..cbdf3ffed657 100644 --- a/Engine/Source/Editor/Blutility/Private/AssetTypeActions_EditorUtilityWidgetBlueprint.cpp +++ b/Engine/Source/Editor/Blutility/Private/AssetTypeActions_EditorUtilityWidgetBlueprint.cpp @@ -105,7 +105,7 @@ void FAssetTypeActions_EditorUtilityWidgetBlueprint::ExecuteRun(FWeakBlueprintPo } else { - FName RegistrationName = FName(*(CDO->GetPathName() + LOCTEXT("ActiveTabSuffix", "_ActiveTab").ToString())); + FName RegistrationName = FName(*(Blueprint->GetPathName() + LOCTEXT("ActiveTabSuffix", "_ActiveTab").ToString())); FText DisplayName = FText::FromString(Blueprint->GetName()); FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked(TEXT("LevelEditor")); TSharedPtr LevelEditorTabManager = LevelEditorModule.GetLevelEditorTabManager(); @@ -113,7 +113,7 @@ void FAssetTypeActions_EditorUtilityWidgetBlueprint::ExecuteRun(FWeakBlueprintPo { IBlutilityModule* BlutilityModule = FModuleManager::GetModulePtr("Blutility"); UEditorUtilityWidgetBlueprint* WidgetBlueprint = Cast(Blueprint); - + WidgetBlueprint->SetRegistrationName(RegistrationName); LevelEditorTabManager->RegisterTabSpawner(RegistrationName, FOnSpawnTab::CreateUObject(WidgetBlueprint, &UEditorUtilityWidgetBlueprint::SpawnEditorUITab)) .SetDisplayName(DisplayName) .SetGroup(BlutilityModule->GetMenuGroup().ToSharedRef()); diff --git a/Engine/Source/Editor/Blutility/Private/BlutilityModule.cpp b/Engine/Source/Editor/Blutility/Private/BlutilityModule.cpp index 042f3489712a..2810730b1af9 100644 --- a/Engine/Source/Editor/Blutility/Private/BlutilityModule.cpp +++ b/Engine/Source/Editor/Blutility/Private/BlutilityModule.cpp @@ -33,6 +33,7 @@ #include "UnrealEdMisc.h" #include "EditorSupportDelegates.h" #include "UObject/PurgingReferenceCollector.h" +#include "AssetRegistryModule.h" #define LOCTEXT_NAMESPACE "AssetTypeActions" @@ -93,35 +94,43 @@ public: FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked(TEXT("LevelEditor")); LevelEditorModule.OnTabManagerChanged().AddRaw(this, &FBlutilityModule::ReinitializeUIs); LevelEditorModule.OnMapChanged().AddRaw(this, &FBlutilityModule::OnMapChanged); - FEditorSupportDelegates::PrepareToCleanseEditorObject.AddRaw(this, &FBlutilityModule::OnPrepareToCleanseEditorObject); + + FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked(TEXT("AssetRegistry")); + AssetRegistryModule.Get().OnAssetRemoved().AddRaw(this, &FBlutilityModule::HandleAssetRemoved); } void ReinitializeUIs() { - EditorUtilityContext = NewObject(); - if (EditorUtilityContext) + if (!EditorUtilityContext) { - for (FSoftObjectPath BlueprintPath : EditorUtilityContext->LoadedUIs) - { - UObject* BlueprintObject = BlueprintPath.TryLoad(); - if (BlueprintObject) + EditorUtilityContext = NewObject(); + } + FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked(TEXT("LevelEditor")); + TSharedPtr LevelEditorTabManager = LevelEditorModule.GetLevelEditorTabManager(); + TArray CorrectPaths; + for (FSoftObjectPath BlueprintPath : EditorUtilityContext->LoadedUIs) + { + UObject* BlueprintObject = BlueprintPath.TryLoad(); + if (BlueprintObject && !BlueprintObject->IsPendingKillOrUnreachable()) + { + UEditorUtilityWidgetBlueprint* Blueprint = Cast(BlueprintObject); + const UEditorUtilityWidget* CDO = Blueprint->GeneratedClass->GetDefaultObject(); + FName RegistrationName = FName(*(Blueprint->GetPathName() + LOCTEXT("ActiveTabSuffix", "_ActiveTab").ToString())); + Blueprint->SetRegistrationName(RegistrationName); + FText DisplayName = FText::FromString(Blueprint->GetName()); + if (LevelEditorTabManager && !LevelEditorTabManager->CanSpawnTab(RegistrationName)) { - UEditorUtilityWidgetBlueprint* Blueprint = Cast(BlueprintObject); - const UEditorUtilityWidget* CDO = Blueprint->GeneratedClass->GetDefaultObject(); - FName RegistrationName = FName(*CDO->GetPathName()); - FText DisplayName = FText::FromString(Blueprint->GetName()); - FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked(TEXT("LevelEditor")); - TSharedPtr LevelEditorTabManager = LevelEditorModule.GetLevelEditorTabManager(); - if (LevelEditorTabManager && !LevelEditorTabManager->CanSpawnTab(RegistrationName)) - { - LevelEditorTabManager->RegisterTabSpawner(RegistrationName, FOnSpawnTab::CreateUObject(Blueprint, &UEditorUtilityWidgetBlueprint::SpawnEditorUITab)) - .SetDisplayName(DisplayName) - .SetGroup(GetMenuGroup().ToSharedRef()); - } + LevelEditorTabManager->RegisterTabSpawner(RegistrationName, FOnSpawnTab::CreateUObject(Blueprint, &UEditorUtilityWidgetBlueprint::SpawnEditorUITab)) + .SetDisplayName(DisplayName) + .SetGroup(GetMenuGroup().ToSharedRef()); + CorrectPaths.Add(BlueprintPath); } } } + + EditorUtilityContext->LoadedUIs = CorrectPaths; + EditorUtilityContext->SaveConfig(); } void OnMapChanged(UWorld* InWorld, EMapChangeType MapChangeType) @@ -217,7 +226,7 @@ public: { if (EditorUtilityContext) { - EditorUtilityContext->LoadedUIs.Add(InBlueprint); + EditorUtilityContext->LoadedUIs.AddUnique(InBlueprint); EditorUtilityContext->SaveConfig(); } } @@ -285,6 +294,34 @@ protected: } } + void HandleAssetRemoved(const FAssetData& InAssetData) + { + if (EditorUtilityContext) + { + bool bDeletingLoadedUI = false; + for (FSoftObjectPath LoadedUIPath : EditorUtilityContext->LoadedUIs) + { + if (LoadedUIPath.GetAssetPathName() == InAssetData.ObjectPath) + { + bDeletingLoadedUI = true; + break; + } + } + + if (bDeletingLoadedUI) + { + FName UIToCleanup = FName(*(InAssetData.ObjectPath.ToString() + LOCTEXT("ActiveTabSuffix", "_ActiveTab").ToString())); + FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked(TEXT("LevelEditor")); + TSharedPtr LevelEditorTabManager = LevelEditorModule.GetLevelEditorTabManager(); + TSharedPtr CurrentTab = LevelEditorTabManager->FindExistingLiveTab(UIToCleanup); + if (CurrentTab.IsValid()) + { + CurrentTab->RequestCloseTab(); + } + } + } + } +protected: /** Scripted Editor Widgets workspace menu item */ TSharedPtr ScriptedEditorWidgetsGroup; diff --git a/Engine/Source/Editor/Blutility/Private/EditorUtilityWidgetBlueprint.cpp b/Engine/Source/Editor/Blutility/Private/EditorUtilityWidgetBlueprint.cpp index 52a4a18fa69a..d93bcecca312 100644 --- a/Engine/Source/Editor/Blutility/Private/EditorUtilityWidgetBlueprint.cpp +++ b/Engine/Source/Editor/Blutility/Private/EditorUtilityWidgetBlueprint.cpp @@ -6,6 +6,7 @@ #include "EditorUtilityWidget.h" #include "IBlutilityModule.h" #include "Modules/ModuleManager.h" +#include "LevelEditor.h" @@ -16,8 +17,26 @@ UEditorUtilityWidgetBlueprint::UEditorUtilityWidgetBlueprint(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { + } +void UEditorUtilityWidgetBlueprint::BeginDestroy() +{ + // Created tab is invalid on editor shutdown, prevents the cleanup script from running then + if (CreatedTab.IsValid()) + { + IBlutilityModule* BlutilityModule = FModuleManager::GetModulePtr("Blutility"); + BlutilityModule->RemoveLoadedScriptUI(this); + + FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked(TEXT("LevelEditor")); + TSharedPtr LevelEditorTabManager = LevelEditorModule.GetLevelEditorTabManager(); + LevelEditorTabManager->UnregisterTabSpawner(RegistrationName); + } + + Super::BeginDestroy(); +} + + TSharedRef UEditorUtilityWidgetBlueprint::SpawnEditorUITab(const FSpawnTabArgs& SpawnTabArgs) { TSharedRef SpawnedTab = SNew(SDockTab); diff --git a/Engine/Source/Editor/EditorStyle/Private/SlateEditorStyle.cpp b/Engine/Source/Editor/EditorStyle/Private/SlateEditorStyle.cpp index 36a0de726aa8..b9b1e30dc5a1 100644 --- a/Engine/Source/Editor/EditorStyle/Private/SlateEditorStyle.cpp +++ b/Engine/Source/Editor/EditorStyle/Private/SlateEditorStyle.cpp @@ -4765,21 +4765,37 @@ void FSlateEditorStyle::FStyle::SetupLevelEditorStyle() Set("LevelEditor.SourceControl.Problem.Small", new IMAGE_BRUSH("Icons/icon_source_control_40x_problem", Icon20x20)); Set("LevelEditor.PreviewMode.Enabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_SM5_Enabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.Enabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_SM5_Enabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.Disabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_SM5_Disabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.Disabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_SM5_Disabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.SM5.Enabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_SM5_Enabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.SM5.Enabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_SM5_Enabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.SM5.Disabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_SM5_Enabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.SM5.Disabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_SM5_Enabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.SM4.Enabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_SM4_Enabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.SM4.Enabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_SM4_Enabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.SM4.Disabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_SM4_Enabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.SM4.Disabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_SM4_Enabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.AndroidES2.Enabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_AndroidES2_Enabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.AndroidES2.Enabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_AndroidES2_Enabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.AndroidES2.Disabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_AndroidES2_Disabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.AndroidES2.Disabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_AndroidES2_Disabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.AndroidES31.Enabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_AndroidES31_Enabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.AndroidES31.Enabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_AndroidES31_Enabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.AndroidES31.Disabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_AndroidES31_Disabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.AndroidES31.Disabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_AndroidES31_Disabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.AndroidVulkan.Enabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_AndroidVulkan_Enabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.AndroidVulkan.Enabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_AndroidVulkan_Enabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.AndroidVulkan.Disabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_AndroidVulkan_Disabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.AndroidVulkan.Disabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_AndroidVulkan_Disabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.iOS.Enabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_iOS_Enabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.iOS.Enabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_iOS_Enabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.iOS.Disabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_iOS_Disabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.iOS.Disabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_iOS_Disabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.HTML5.Enabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_HTML5_Enabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.HTML5.Enabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_HTML5_Enabled_40x", Icon20x20)); Set("LevelEditor.PreviewMode.HTML5.Disabled", new IMAGE_BRUSH("Icons/icon_PreviewMode_HTML5_Disabled_40x", Icon40x40)); + Set("LevelEditor.PreviewMode.HTML5.Disabled.Small", new IMAGE_BRUSH("Icons/icon_PreviewMode_HTML5_Disabled_40x", Icon20x20)); Set("LevelEditor.ViewOptions", new IMAGE_BRUSH("Icons/icon_view_40x", Icon40x40)); Set( "LevelEditor.ViewOptions.Small", new IMAGE_BRUSH( "Icons/icon_view_40x", Icon20x20 ) ); diff --git a/Engine/Source/Editor/Persona/Private/PersonaMeshDetails.cpp b/Engine/Source/Editor/Persona/Private/PersonaMeshDetails.cpp index 746b460d3855..66eacbcd77cc 100644 --- a/Engine/Source/Editor/Persona/Private/PersonaMeshDetails.cpp +++ b/Engine/Source/Editor/Persona/Private/PersonaMeshDetails.cpp @@ -1297,6 +1297,11 @@ void FPersonaMeshDetails::CustomizeLODSettingsCategories(IDetailLayoutBuilder& D IDetailPropertyRow& MinLODRow = LODSettingsCategory.AddProperty(MinLODPropertyHandle); MinLODRow.IsEnabled(TAttribute::Create(TAttribute::FGetter::CreateSP(this, &FPersonaMeshDetails::IsLODInfoEditingEnabled, -1))); DetailLayout.HideProperty(MinLODPropertyHandle); + + TSharedPtr DisableBelowMinLodStrippingPropertyHandle = DetailLayout.GetProperty(GET_MEMBER_NAME_CHECKED(USkeletalMesh, DisableBelowMinLodStripping), USkeletalMesh::StaticClass()); + IDetailPropertyRow& DisableBelowMinLodStrippingRow = LODSettingsCategory.AddProperty(DisableBelowMinLodStrippingPropertyHandle); + DisableBelowMinLodStrippingRow.IsEnabled(TAttribute::Create(TAttribute::FGetter::CreateSP(this, &FPersonaMeshDetails::IsLODInfoEditingEnabled, -1))); + DetailLayout.HideProperty(DisableBelowMinLodStrippingPropertyHandle); } // save LOD settings diff --git a/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditor.cpp b/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditor.cpp index ef781983f2e2..019c3f0ee67f 100644 --- a/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditor.cpp +++ b/Engine/Source/Editor/StaticMeshEditor/Private/StaticMeshEditor.cpp @@ -504,8 +504,10 @@ TSharedRef FStaticMeshEditor::SpawnTab_SecondaryToolbar( const FSpawnT { check( Args.GetTabId() == SecondaryToolbarTabId ); + FText TabLabel = !SecondaryToolbarDisplayName.IsEmpty() ? SecondaryToolbarDisplayName : LOCTEXT("SecondaryToolbar_TabTitle", "Secondary Toolbar"); + TSharedRef SpawnedTab = SNew(SDockTab) - .Label( LOCTEXT("SecondaryToolbar_TabTitle", "Secondary Toolbar") ) + .Label( TabLabel ) .Icon( FEditorStyle::GetBrush("LevelEditor.Tabs.Toolbar") ) .ShouldAutosize( true ) [ diff --git a/Engine/Source/Editor/UnrealEd/Private/AssetSelection.cpp b/Engine/Source/Editor/UnrealEd/Private/AssetSelection.cpp index a257c13a854b..530da0629957 100644 --- a/Engine/Source/Editor/UnrealEd/Private/AssetSelection.cpp +++ b/Engine/Source/Editor/UnrealEd/Private/AssetSelection.cpp @@ -430,9 +430,9 @@ namespace ActorPlacementUtils FString FileName = SourceControlHelpers::PackageFilename(InLevel->GetPathName()); // Query file state also checks the source control status FSourceControlState SCState = SourceControlHelpers::QueryFileState(FileName, true); - if (!SCState.bIsCheckedOut) + if (!(SCState.bIsCheckedOut || SCState.bIsAdded || SCState.bIsUnknown)) { - if (EAppReturnType::Ok != OpenMsgDlgInt(EAppMsgType::OkCancel, NSLOCTEXT("UnrealEd","LevelNotCheckedOutMsg", "This actor will be placed in a level that is not currently checked out. Continue?"), NSLOCTEXT("UnrealEd", "ActorPlacement_Title", "Actor Placement Warning"))) + if (EAppReturnType::Ok != OpenMsgDlgInt(EAppMsgType::OkCancel, NSLOCTEXT("UnrealEd","LevelNotCheckedOutMsg", "This actor will be placed in a level that is is source control but not currently checked out. Continue?"), NSLOCTEXT("UnrealEd", "ActorPlacement_Title", "Actor Placement Warning"))) { return false; } diff --git a/Engine/Source/Editor/UnrealEd/Private/Commandlets/AssetRegistryGenerator.cpp b/Engine/Source/Editor/UnrealEd/Private/Commandlets/AssetRegistryGenerator.cpp index 72ae873493ee..b9420629937e 100644 --- a/Engine/Source/Editor/UnrealEd/Private/Commandlets/AssetRegistryGenerator.cpp +++ b/Engine/Source/Editor/UnrealEd/Private/Commandlets/AssetRegistryGenerator.cpp @@ -1283,7 +1283,7 @@ void FAssetRegistryGenerator::RemovePackageFromManifest(FName PackageName, int32 } } -void FAssetRegistryGenerator::ResolveChunkDependencyGraph(const FChunkDependencyTreeNode& Node, FChunkPackageSet BaseAssetSet, TArray>& OutPackagesMovedBetweenChunks) +void FAssetRegistryGenerator::ResolveChunkDependencyGraph(const FChunkDependencyTreeNode& Node, const FChunkPackageSet& BaseAssetSet, TArray>& OutPackagesMovedBetweenChunks) { if (FinalChunkManifests.Num() > Node.ChunkID && FinalChunkManifests[Node.ChunkID]) { @@ -1296,14 +1296,24 @@ void FAssetRegistryGenerator::ResolveChunkDependencyGraph(const FChunkDependency UE_LOG(LogAssetRegistryGenerator, Verbose, TEXT("Removed %s from chunk %i because it is duplicated in another chunk."), *It.Key().ToString(), Node.ChunkID); } } + + FChunkPackageSet ModifiedAssetSet; + // Add the current Chunk's assets for (auto It = FinalChunkManifests[Node.ChunkID]->CreateConstIterator(); It; ++It)//for (const auto It : *(FinalChunkManifests[Node.ChunkID])) { - BaseAssetSet.Add(It.Key(), It.Value()); + if (!ModifiedAssetSet.Num()) + { + ModifiedAssetSet = BaseAssetSet; + } + + ModifiedAssetSet.Add(It.Key(), It.Value()); } + + const auto& AssetSet = ModifiedAssetSet.Num() ? ModifiedAssetSet : BaseAssetSet; for (const auto It : Node.ChildNodes) { - ResolveChunkDependencyGraph(It, BaseAssetSet, OutPackagesMovedBetweenChunks); + ResolveChunkDependencyGraph(It, AssetSet, OutPackagesMovedBetweenChunks); } } } diff --git a/Engine/Source/Editor/UnrealEd/Private/EditorEngine.cpp b/Engine/Source/Editor/UnrealEd/Private/EditorEngine.cpp index 4d04c3bb8b86..e77f81993b54 100644 --- a/Engine/Source/Editor/UnrealEd/Private/EditorEngine.cpp +++ b/Engine/Source/Editor/UnrealEd/Private/EditorEngine.cpp @@ -6866,7 +6866,7 @@ void UEditorEngine::VerifyLoadMapWorldCleanup() for( TObjectIterator It; It; ++It ) { UWorld* World = *It; - if (World->WorldType != EWorldType::EditorPreview && World->WorldType != EWorldType::Editor && World->WorldType != EWorldType::Inactive) + if (World->WorldType != EWorldType::EditorPreview && World->WorldType != EWorldType::Editor && World->WorldType != EWorldType::Inactive && World->WorldType != EWorldType::GamePreview) { TArray OtherEditorWorlds; EditorLevelUtils::GetWorlds(EditorWorld, OtherEditorWorlds, true, false); diff --git a/Engine/Source/Editor/UnrealEd/Private/EditorServer.cpp b/Engine/Source/Editor/UnrealEd/Private/EditorServer.cpp index aca4b393bcf1..47b7adbf1b16 100644 --- a/Engine/Source/Editor/UnrealEd/Private/EditorServer.cpp +++ b/Engine/Source/Editor/UnrealEd/Private/EditorServer.cpp @@ -1960,7 +1960,7 @@ void UEditorEngine::CheckForWorldGCLeaks( UWorld* NewWorld, UPackage* WorldPacka { UWorld* RemainingWorld = *It; const bool bIsNewWorld = (NewWorld && RemainingWorld == NewWorld); - const bool bIsPersistantWorldType = (RemainingWorld->WorldType == EWorldType::Inactive) || (RemainingWorld->WorldType == EWorldType::EditorPreview); + const bool bIsPersistantWorldType = (RemainingWorld->WorldType == EWorldType::Inactive) || (RemainingWorld->WorldType == EWorldType::EditorPreview) || (RemainingWorld->WorldType == EWorldType::GamePreview); if(!bIsNewWorld && !bIsPersistantWorldType && !WorldHasValidContext(RemainingWorld)) { StaticExec(RemainingWorld, *FString::Printf(TEXT("OBJ REFS CLASS=WORLD NAME=%s"), *RemainingWorld->GetPathName())); diff --git a/Engine/Source/Editor/UnrealEd/Private/Factories/SkeletalMeshImport.cpp b/Engine/Source/Editor/UnrealEd/Private/Factories/SkeletalMeshImport.cpp index 4fb3f5034525..c8179189e43d 100644 --- a/Engine/Source/Editor/UnrealEd/Private/Factories/SkeletalMeshImport.cpp +++ b/Engine/Source/Editor/UnrealEd/Private/Factories/SkeletalMeshImport.cpp @@ -389,6 +389,7 @@ ExistingSkelMeshData* SaveExistingSkelMeshData(USkeletalMesh* ExistingSkelMesh, ExistingMeshDataPtr->UseMaterialNameSlotWorkflow = SkeletalMeshIsUsingMaterialSlotNameWorkflow(ExistingSkelMesh->AssetImportData); ExistingMeshDataPtr->MinLOD = ExistingSkelMesh->MinLod; + ExistingMeshDataPtr->DisableBelowMinLodStripping = ExistingSkelMesh->DisableBelowMinLodStripping; FSkeletalMeshModel* ImportedResource = ExistingSkelMesh->GetImportedModel(); @@ -733,6 +734,7 @@ void RestoreExistingSkelMeshData(ExistingSkelMeshData* MeshData, USkeletalMesh* } SkeletalMesh->MinLod = MeshData->MinLOD; + SkeletalMesh->DisableBelowMinLodStripping = MeshData->DisableBelowMinLodStripping; FSkeletalMeshModel* SkeletalMeshImportedModel = SkeletalMesh->GetImportedModel(); diff --git a/Engine/Source/Editor/UnrealEd/Private/FileHelpers.cpp b/Engine/Source/Editor/UnrealEd/Private/FileHelpers.cpp index 95539f4c4634..e7768ae0b38a 100644 --- a/Engine/Source/Editor/UnrealEd/Private/FileHelpers.cpp +++ b/Engine/Source/Editor/UnrealEd/Private/FileHelpers.cpp @@ -77,6 +77,12 @@ bool FEditorFileUtils::bIsPromptingForCheckoutAndSave = false; TSet FEditorFileUtils::PackagesNotSavedDuringSaveAll; TSet FEditorFileUtils::PackagesNotToPromptAnyMore; + +static TAutoConsoleVariable CVarSkipSourceControlCheckForEditablePackages( + TEXT("r.Editor.SkipSourceControlCheckForEditablePackages"), + 0, + TEXT("Whether to skip the source control status check for editable packages, 0: Disable (Default), 1: Enable")); + #define LOCTEXT_NAMESPACE "FileHelpers" /** A special output device that puts save output in the message log when flushed */ @@ -1335,8 +1341,46 @@ bool FEditorFileUtils::AddCheckoutPackageItems(bool bCheckDirty, TArray(), PackagesToCheckOut); + TArray SourceControlCheckPackages; + if (CVarSkipSourceControlCheckForEditablePackages.GetValueOnAnyThread()) + { + for (auto Package : PackagesToCheckOut) + { + if (!Package) + { + continue; + } + + FString Filename; + if (FPackageName::DoesPackageExist(Package->GetName(), NULL, &Filename)) + { + if (IFileManager::Get().IsReadOnly(*Filename)) + { + // check if the package is readonly + SourceControlCheckPackages.Add(Package); + } + else + { + auto SourceControlState = SourceControlProvider.GetState(Package, EStateCacheUsage::Use); + if (!SourceControlState) + { + // check if source control doesn't know about the package + SourceControlCheckPackages.Add(Package); + } + } + } + } + } + else + { + SourceControlCheckPackages = PackagesToCheckOut; + } + + if (SourceControlCheckPackages.Num()) + { + // Update the source control status of all potentially relevant packages + SourceControlProvider.Execute(ISourceControlOperation::Create(), SourceControlCheckPackages); + } } FPackagesDialogModule& CheckoutPackagesDialogModule = FModuleManager::LoadModuleChecked(TEXT("PackagesDialog")); diff --git a/Engine/Source/Editor/UnrealEd/Private/Kismet2/KismetDebugUtilities.cpp b/Engine/Source/Editor/UnrealEd/Private/Kismet2/KismetDebugUtilities.cpp index 93c4483952e6..06345d49c5ba 100644 --- a/Engine/Source/Editor/UnrealEd/Private/Kismet2/KismetDebugUtilities.cpp +++ b/Engine/Source/Editor/UnrealEd/Private/Kismet2/KismetDebugUtilities.cpp @@ -1209,10 +1209,10 @@ FKismetDebugUtilities::EWatchTextResult FKismetDebugUtilities::FindDebuggingData UFunction* OuterFunction = Cast(Property->GetOuter()); if (!PropertyBase && OuterFunction) { - UBlueprintGeneratedClass* BPGC = Cast(OuterFunction->GetOuter()); + UBlueprintGeneratedClass* BPGC = Cast(Blueprint->GeneratedClass); if (BPGC && ActiveObject->IsA(BPGC)) { - PropertyBase = GetPersistentUberGraphFrame( OuterFunction, ActiveObject ); + PropertyBase = BPGC->GetPersistentUberGraphFrame(ActiveObject, OuterFunction); } } #endif // USE_UBER_GRAPH_PERSISTENT_FRAME diff --git a/Engine/Source/Editor/UnrealEd/Public/Commandlets/AssetRegistryGenerator.h b/Engine/Source/Editor/UnrealEd/Public/Commandlets/AssetRegistryGenerator.h index cf1bc5d66ef8..8d7f148a3530 100644 --- a/Engine/Source/Editor/UnrealEd/Public/Commandlets/AssetRegistryGenerator.h +++ b/Engine/Source/Editor/UnrealEd/Public/Commandlets/AssetRegistryGenerator.h @@ -322,7 +322,7 @@ private: FString GetShortestReferenceChain(FName PackageName, int32 ChunkID); /** Deprecated method to remove redundant chunks */ - void ResolveChunkDependencyGraph(const FChunkDependencyTreeNode& Node, FChunkPackageSet BaseAssetSet, TArray>& OutPackagesMovedBetweenChunks); + void ResolveChunkDependencyGraph(const FChunkDependencyTreeNode& Node, const FChunkPackageSet& BaseAssetSet, TArray>& OutPackagesMovedBetweenChunks); /** Helper function to verify Chunk asset assigment is valid */ bool CheckChunkAssetsAreNotInChild(const FChunkDependencyTreeNode& Node); @@ -333,4 +333,4 @@ private: /** Helper function to fill a given collection with a set of packages */ void WriteCollection(FName CollectionName, const TArray& PackageNames); -}; \ No newline at end of file +}; diff --git a/Engine/Source/Editor/UnrealEd/Public/SkelImport.h b/Engine/Source/Editor/UnrealEd/Public/SkelImport.h index 9e487c0ef987..884584aa8396 100644 --- a/Engine/Source/Editor/UnrealEd/Public/SkelImport.h +++ b/Engine/Source/Editor/UnrealEd/Public/SkelImport.h @@ -82,6 +82,7 @@ struct ExistingSkelMeshData FSkeletalMeshSamplingInfo ExistingSamplingInfo; FPerPlatformInt MinLOD; + FPerPlatformBool DisableBelowMinLodStripping; }; /** diff --git a/Engine/Source/Editor/UnrealEd/UnrealEd.Build.cs b/Engine/Source/Editor/UnrealEd/UnrealEd.Build.cs index b2e063c02a2e..d486ba535043 100644 --- a/Engine/Source/Editor/UnrealEd/UnrealEd.Build.cs +++ b/Engine/Source/Editor/UnrealEd/UnrealEd.Build.cs @@ -289,6 +289,9 @@ public class UnrealEd : ModuleRules PublicDependencyModuleNames.Add("XAudio2"); PublicDependencyModuleNames.Add("AudioMixerXAudio2"); + PrivateDependencyModuleNames.Add("WindowsPlatformFeatures"); + PrivateDependencyModuleNames.Add("GameplayMediaEncoder"); + AddEngineThirdPartyPrivateStaticDependencies(Target, "UEOgg", "Vorbis", diff --git a/Engine/Source/Programs/AutomationTool/Android/AndroidPlatform.Automation.cs b/Engine/Source/Programs/AutomationTool/Android/AndroidPlatform.Automation.cs index 08732df47469..d7726daf0df7 100644 --- a/Engine/Source/Programs/AutomationTool/Android/AndroidPlatform.Automation.cs +++ b/Engine/Source/Programs/AutomationTool/Android/AndroidPlatform.Automation.cs @@ -326,50 +326,50 @@ public class AndroidPlatform : Platform else { - // Always delete the target OBB file if it exists - if (File.Exists(LocalObbName)) - { - File.Delete(LocalObbName); - } + // Always delete the target OBB file if it exists + if (File.Exists(LocalObbName)) + { + File.Delete(LocalObbName); + } - // Now create the OBB as a ZIP archive. - LogInformation("Creating {0} from {1}", LocalObbName, SC.StageDirectory); - using (ZipFile ObbFile = new ZipFile(LocalObbName)) - { - ObbFile.CompressionMethod = CompressionMethod.None; - ObbFile.CompressionLevel = Ionic.Zlib.CompressionLevel.None; - ObbFile.UseZip64WhenSaving = Ionic.Zip.Zip64Option.Never; + // Now create the OBB as a ZIP archive. + LogInformation("Creating {0} from {1}", LocalObbName, SC.StageDirectory); + using (ZipFile ObbFile = new ZipFile(LocalObbName)) + { + ObbFile.CompressionMethod = CompressionMethod.None; + ObbFile.CompressionLevel = Ionic.Zlib.CompressionLevel.None; + ObbFile.UseZip64WhenSaving = Ionic.Zip.Zip64Option.Never; - int ObbFileCount = 0; - ObbFile.AddProgress += - delegate (object sender, AddProgressEventArgs e) + int ObbFileCount = 0; + ObbFile.AddProgress += + delegate(object sender, AddProgressEventArgs e) + { + if (e.EventType == ZipProgressEventType.Adding_AfterAddEntry) { - if (e.EventType == ZipProgressEventType.Adding_AfterAddEntry) - { - ObbFileCount += 1; - LogInformation("[{0}/{1}] Adding {2} to OBB", - ObbFileCount, e.EntriesTotal, - e.CurrentEntry.FileName); - } - }; + ObbFileCount += 1; + LogInformation("[{0}/{1}] Adding {2} to OBB", + ObbFileCount, e.EntriesTotal, + e.CurrentEntry.FileName); + } + }; - foreach (FileReference FileToObb in FilesToObb) - { - string DestinationPath = Path.GetDirectoryName(FileToObb.FullName).Replace(StageDirectoryPath, SC.ShortProjectName); - ObbFile.AddFile(FileToObb.FullName, DestinationPath); - } - - // ObbFile.AddDirectory(SC.StageDirectory+"/"+SC.ShortProjectName, SC.ShortProjectName); - try - { - ObbFile.Save(); - } - catch (Exception) - { - LogInformation("Failed to build OBB: " + LocalObbName); - throw new AutomationException(ExitCode.Error_AndroidOBBError, "Stage Failed. Could not build OBB {0}. The file may be too big to fit in an OBB (2 GiB limit)", LocalObbName); - } + foreach (FileReference FileToObb in FilesToObb) + { + string DestinationPath = Path.GetDirectoryName(FileToObb.FullName).Replace(StageDirectoryPath, SC.ShortProjectName); + ObbFile.AddFile(FileToObb.FullName, DestinationPath); } + + // ObbFile.AddDirectory(SC.StageDirectory+"/"+SC.ShortProjectName, SC.ShortProjectName); + try + { + ObbFile.Save(); + } + catch (Exception) + { + LogInformation("Failed to build OBB: " + LocalObbName); + throw new AutomationException(ExitCode.Error_AndroidOBBError, "Stage Failed. Could not build OBB {0}. The file may be too big to fit in an OBB (2 GiB limit)", LocalObbName); + } + } } // make sure the OBB is <= 2GiB (or 4GiB if large OBB enabled) @@ -409,12 +409,34 @@ public class AndroidPlatform : Platform } } - + TargetReceipt Receipt = SC.StageTargets[0].Receipt; + + // when we make an embedded executable, all we do is output to libUE4.so - we don't need to make an APK at all + // however, we still let package go through to make the .obb file + string CookFlavor = SC.FinalCookPlatform.IndexOf("_") > 0 ? SC.FinalCookPlatform.Substring(SC.FinalCookPlatform.IndexOf("_")) : ""; if (!Params.Prebuilt) { - string CookFlavor = SC.FinalCookPlatform.IndexOf("_") > 0 ? SC.FinalCookPlatform.Substring(SC.FinalCookPlatform.IndexOf("_")) : ""; string SOName = GetSONameWithoutArchitecture(Params, SC.StageExecutables[0]); - Deploy.PrepForUATPackageOrDeploy(Params.RawProjectPath, Params.ShortProjectName, SC.ProjectRoot, SOName, SC.LocalRoot + "/Engine", Params.Distribution, CookFlavor, false); + bool bShouldCompileAsDll = Receipt.HasValueForAdditionalProperty("CompileAsDll", "true"); + if (bShouldCompileAsDll) + { + // MakeApk + SOName = Receipt.BuildProducts[0].Path.FullName; + + // saving package info, which will allow + TargetType Type = TargetType.Game; + if (CookFlavor.EndsWith("Client")) + { + Type = TargetType.Client; + } + else if (CookFlavor.EndsWith("Server")) + { + Type = TargetType.Server; + } + LogInformation("SavePackageInfo"); + Deploy.SavePackageInfo(Params.ShortProjectName, SC.ProjectRoot.FullName, Type); + } + Deploy.PrepForUATPackageOrDeploy(Params.RawProjectPath, Params.ShortProjectName, SC.ProjectRoot, SOName, SC.LocalRoot + "/Engine", Params.Distribution, CookFlavor, SC.StageTargets[0].Receipt.Configuration, false, bShouldCompileAsDll); } // Create APK specific OBB in case we have a detached OBB. @@ -570,7 +592,7 @@ public class AndroidPlatform : Platform LogInformation("Writing bat for install with {0}", bPackageDataInsideApk ? "data in APK" : "separate OBB"); BatchLines = new string[] { "setlocal", - "if NOT \"UE_SDKS_ROOT\"==\"\" (call %UE_SDKS_ROOT%\\HostWin64\\Android\\SetupEnvironmentVars.bat)", + "if NOT \"%UE_SDKS_ROOT%\"==\"\" (call %UE_SDKS_ROOT%\\HostWin64\\Android\\SetupEnvironmentVars.bat)", "set ANDROIDHOME=%ANDROID_HOME%", "if \"%ANDROIDHOME%\"==\"\" set ANDROIDHOME="+Environment.GetEnvironmentVariable("ANDROID_HOME"), "set ADB=%ANDROIDHOME%\\platform-tools\\adb.exe", @@ -648,7 +670,7 @@ public class AndroidPlatform : Platform LogInformation("Writing bat for uninstall with {0}", bPackageDataInsideApk ? "data in APK" : "separate OBB"); BatchLines = new string[] { "setlocal", - "if NOT \"UE_SDKS_ROOT\"==\"\" (call %UE_SDKS_ROOT%\\HostWin64\\Android\\SetupEnvironmentVars.bat)", + "if NOT \"%UE_SDKS_ROOT%\"==\"\" (call %UE_SDKS_ROOT%\\HostWin64\\Android\\SetupEnvironmentVars.bat)", "set ANDROIDHOME=%ANDROID_HOME%", "if \"%ANDROIDHOME%\"==\"\" set ANDROIDHOME="+Environment.GetEnvironmentVariable("ANDROID_HOME"), "set ADB=%ANDROIDHOME%\\platform-tools\\adb.exe", @@ -1051,7 +1073,7 @@ public class AndroidPlatform : Platform string CookFlavor = SC.FinalCookPlatform.IndexOf("_") > 0 ? SC.FinalCookPlatform.Substring(SC.FinalCookPlatform.IndexOf("_")) : ""; string SOName = GetSONameWithoutArchitecture(Params, SC.StageExecutables[0]); Deploy.SetAndroidPluginData(AppArchitectures, CollectPluginDataPaths(SC)); - Deploy.PrepForUATPackageOrDeploy(Params.RawProjectPath, Params.ShortProjectName, SC.ProjectRoot, SOName, SC.LocalRoot + "/Engine", Params.Distribution, CookFlavor, true); + Deploy.PrepForUATPackageOrDeploy(Params.RawProjectPath, Params.ShortProjectName, SC.ProjectRoot, SOName, SC.LocalRoot + "/Engine", Params.Distribution, CookFlavor, SC.StageTargets[0].Receipt.Configuration, true, false); } // now we can use the apk to get more info @@ -1488,37 +1510,74 @@ public class AndroidPlatform : Platform /** Run an external exe (and capture the output), given the exe path and the commandline. */ public static string GetPackageInfo(string ApkName, bool bRetrieveVersionCode) { + string ReturnValue = null; + // we expect there to be one, so use the first one string AaptPath = GetAaptPath(); PackageInfoMutex.WaitOne(); - var ExeInfo = new ProcessStartInfo(AaptPath, "dump --include-meta-data badging \"" + ApkName + "\""); - ExeInfo.UseShellExecute = false; - ExeInfo.RedirectStandardOutput = true; - using (var GameProcess = Process.Start(ExeInfo)) + if (File.Exists(ApkName)) { - PackageLine = null; - LaunchableActivityLine = null; - MetaAppTypeLine = null; - GameProcess.BeginOutputReadLine(); - GameProcess.OutputDataReceived += ParsePackageName; - GameProcess.WaitForExit(); - } - - PackageInfoMutex.ReleaseMutex(); - - string ReturnValue = null; - if (PackageLine != null) - { - // the line should look like: package: name='com.epicgames.qagame' versionCode='1' versionName='1.0' - string[] Tokens = PackageLine.Split("'".ToCharArray()); - int TokenIndex = bRetrieveVersionCode ? 3 : 1; - if (Tokens.Length >= TokenIndex + 1) + var ExeInfo = new ProcessStartInfo(AaptPath, "dump --include-meta-data badging \"" + ApkName + "\""); + ExeInfo.UseShellExecute = false; + ExeInfo.RedirectStandardOutput = true; + using (var GameProcess = Process.Start(ExeInfo)) { - ReturnValue = Tokens[TokenIndex]; + PackageLine = null; + LaunchableActivityLine = null; + MetaAppTypeLine = null; + GameProcess.BeginOutputReadLine(); + GameProcess.OutputDataReceived += ParsePackageName; + GameProcess.WaitForExit(); } + + PackageInfoMutex.ReleaseMutex(); + + if (PackageLine != null) + { + // the line should look like: package: name='com.epicgames.qagame' versionCode='1' versionName='1.0' + string[] Tokens = PackageLine.Split("'".ToCharArray()); + int TokenIndex = bRetrieveVersionCode ? 3 : 1; + if (Tokens.Length >= TokenIndex + 1) + { + ReturnValue = Tokens[TokenIndex]; + } + } + LogInformation("GetPackageInfo ReturnValue: {0}", ReturnValue); } + + if (ReturnValue == null || ReturnValue.Length == 0) + { + /** If APK does not exist or we cant find package info in apk use the packageInfo file */ + ReturnValue = GetPackageInfoFromInfoFile(ApkName, bRetrieveVersionCode); + } + + return ReturnValue; + } + + /** Lookup package info in packageInfo.txt file in same directory as the APK would have been */ + private static string GetPackageInfoFromInfoFile(string ApkName, bool bRetrieveVersionCode) + { + string ReturnValue = null; + String PackageInfoPath = Path.Combine(Path.GetDirectoryName(ApkName), "packageInfo.txt"); + Boolean fileExists = File.Exists(PackageInfoPath); + if (fileExists) + { + string[] Lines = File.ReadAllLines(PackageInfoPath); + int LineIndex = bRetrieveVersionCode ? 1 : 0; + LogInformation("packageInfo line index: {0}", LineIndex); + if (Lines.Length >= 2) + { + ReturnValue = Lines[LineIndex]; + } + // parse extra info that the aapt-based method got + MetaAppTypeLine = Lines[3]; + } + LogInformation("packageInfo.txt file exists: {0}", fileExists); + LogInformation("packageInfo return MetaAppTypeLine: {0}", MetaAppTypeLine); + LogInformation("packageInfo return value: {0}", ReturnValue); + return ReturnValue; } diff --git a/Engine/Source/Programs/AutomationTool/AutomationUtils/Platform.cs b/Engine/Source/Programs/AutomationTool/AutomationUtils/Platform.cs index 7fd5434ad42c..c805590b1084 100644 --- a/Engine/Source/Programs/AutomationTool/AutomationUtils/Platform.cs +++ b/Engine/Source/Programs/AutomationTool/AutomationUtils/Platform.cs @@ -427,6 +427,16 @@ namespace AutomationTool get { return false; } } + /// + /// Gets extra launch commandline arguments for this platform. + /// + /// ProjectParams + /// Launch platform string. + public virtual string GetLaunchExtraCommandLine(ProjectParams Params) + { + return ""; + } + /// /// True if this platform can write to the abslog path that's on the host desktop. /// diff --git a/Engine/Source/Programs/AutomationTool/Gauntlet/Gauntlet.Automation.csproj b/Engine/Source/Programs/AutomationTool/Gauntlet/Gauntlet.Automation.csproj index 1ccf686991fd..31c70eec1573 100644 --- a/Engine/Source/Programs/AutomationTool/Gauntlet/Gauntlet.Automation.csproj +++ b/Engine/Source/Programs/AutomationTool/Gauntlet/Gauntlet.Automation.csproj @@ -199,6 +199,7 @@ + diff --git a/Engine/Source/Programs/AutomationTool/Gauntlet/Platform/Android/Gauntlet.AndroidBuildSource.cs b/Engine/Source/Programs/AutomationTool/Gauntlet/Platform/Android/Gauntlet.AndroidBuildSource.cs index 0a5723711ef1..7f9ec7748da7 100644 --- a/Engine/Source/Programs/AutomationTool/Gauntlet/Platform/Android/Gauntlet.AndroidBuildSource.cs +++ b/Engine/Source/Programs/AutomationTool/Gauntlet/Platform/Android/Gauntlet.AndroidBuildSource.cs @@ -71,8 +71,16 @@ namespace Gauntlet Match Info = Regex.Match(Fi.Name, RegEx, RegexOptions.IgnoreCase); - if (Info.Success == false) + bool TestInstall = Fi.Name.EndsWith("_TEST.bat", StringComparison.OrdinalIgnoreCase); + + // filter out non-matching or test installation batch files + // test installation scripts are intended to be manually invoked + if (Info.Success == false || TestInstall) { + if (TestInstall) + { + Log.Verbose("Ignoring test installation batch file {0}", Fi.Name); + } continue; } diff --git a/Engine/Source/Programs/AutomationTool/Gauntlet/SelfTest/TestData/LogParser/Win64FatalError.txt b/Engine/Source/Programs/AutomationTool/Gauntlet/SelfTest/TestData/LogParser/Win64FatalError.txt new file mode 100644 index 000000000000..28d7d0186e74 --- /dev/null +++ b/Engine/Source/Programs/AutomationTool/Gauntlet/SelfTest/TestData/LogParser/Win64FatalError.txt @@ -0,0 +1,12892 @@ +LogWindows: Failed to load 'aqProf.dll' (GetLastError=126) +LogWindows: File 'aqProf.dll' does not exist +LogWindows: Failed to load 'VtuneApi.dll' (GetLastError=126) +LogWindows: File 'VtuneApi.dll' does not exist +LogWindows: Failed to load 'VtuneApi32e.dll' (GetLastError=126) +LogWindows: File 'VtuneApi32e.dll' does not exist +LogConsoleResponse: Display: Failed to find resolution value strings in scalability ini. Falling back to default. +LogPakFile: Registered encryption key '00000000000000000000000000000000': 0 pak files mounted, 0 remain pending +LogPakFile: Display: Found Pak file ../../../FortniteGame/Content/Paks/pakchunk1_s2-WindowsClient.pak attempting to mount. +LogPakFile: Display: Mounting pak file ../../../FortniteGame/Content/Paks/pakchunk1_s2-WindowsClient.pak. +LogPakFile: Display: Found Pak file ../../../FortniteGame/Content/Paks/pakchunk1_s1-WindowsClient.pak attempting to mount. +LogPakFile: Display: Mounting pak file ../../../FortniteGame/Content/Paks/pakchunk1_s1-WindowsClient.pak. +LogPakFile: Display: Found Pak file ../../../FortniteGame/Content/Paks/pakchunk11_s1-WindowsClient.pak attempting to mount. +LogPakFile: Display: Mounting pak file ../../../FortniteGame/Content/Paks/pakchunk11_s1-WindowsClient.pak. +LogPakFile: Display: Found Pak file ../../../FortniteGame/Content/Paks/pakchunk11-WindowsClient.pak attempting to mount. +LogPakFile: Display: Mounting pak file ../../../FortniteGame/Content/Paks/pakchunk11-WindowsClient.pak. +LogPakFile: Display: Found Pak file ../../../FortniteGame/Content/Paks/pakchunk10_s4-WindowsClient.pak attempting to mount. +LogPakFile: Display: Mounting pak file ../../../FortniteGame/Content/Paks/pakchunk10_s4-WindowsClient.pak. +LogPakFile: Display: Found Pak file ../../../FortniteGame/Content/Paks/pakchunk10_s3-WindowsClient.pak attempting to mount. +LogPakFile: Display: Mounting pak file ../../../FortniteGame/Content/Paks/pakchunk10_s3-WindowsClient.pak. +LogPakFile: Display: Found Pak file ../../../FortniteGame/Content/Paks/pakchunk10_s2-WindowsClient.pak attempting to mount. +LogPakFile: Display: Mounting pak file ../../../FortniteGame/Content/Paks/pakchunk10_s2-WindowsClient.pak. +LogPakFile: Display: Found Pak file ../../../FortniteGame/Content/Paks/pakchunk10_s1-WindowsClient.pak attempting to mount. +LogPakFile: Display: Mounting pak file ../../../FortniteGame/Content/Paks/pakchunk10_s1-WindowsClient.pak. +LogPakFile: Display: Found Pak file ../../../FortniteGame/Content/Paks/pakchunk10-WindowsClient.pak attempting to mount. +LogPakFile: Display: Mounting pak file ../../../FortniteGame/Content/Paks/pakchunk10-WindowsClient.pak. +LogPakFile: Display: Found Pak file ../../../FortniteGame/Content/Paks/pakchunk1-WindowsClient.pak attempting to mount. +LogPakFile: Display: Mounting pak file ../../../FortniteGame/Content/Paks/pakchunk1-WindowsClient.pak. +LogPakFile: Display: Found Pak file ../../../FortniteGame/Content/Paks/pakchunk0-WindowsClient.pak attempting to mount. +LogPakFile: Display: Mounting pak file ../../../FortniteGame/Content/Paks/pakchunk0-WindowsClient.pak. +LogPlatformFile: Not using cached read wrapper +LogTaskGraph: Started task graph with 5 named threads and 35 total threads with 3 sets of task threads. +LogStats: Stats thread started at 1.572962 +LogD3D11RHI: Loaded GFSDK_Aftermath_Lib.x64.dll +LogICUInternationalization: ICU TimeZone Detection - Raw Offset: -5:00, Platform Override: '' +LogPluginManager: Mounting plugin AESHandlerComponent +LogPluginManager: Mounting plugin PlatformCrypto +LogPluginManager: Mounting plugin AndroidDeviceProfileSelector +LogPluginManager: Mounting plugin AndroidPermission +LogPluginManager: Mounting plugin AnimationBudgetAllocator +LogPluginManager: Mounting plugin AnimationSharing +LogPluginManager: Mounting plugin SignificanceManager +LogPluginManager: Mounting plugin AppleARKit +LogPluginManager: Mounting plugin AppleImageUtils +LogPluginManager: Mounting plugin AppleARKitFaceSupport +LogPluginManager: Mounting plugin ProceduralMeshComponent +LogPluginManager: Mounting plugin LiveLink +LogPluginManager: Mounting plugin FortAppleARKitFaceSupport +LogPluginManager: Mounting plugin FacialAnimSystem +LogPluginManager: Mounting plugin SpeechGraphics +LogPluginManager: Mounting plugin BlueprintContext +LogPluginManager: Mounting plugin BlueprintMaterialTextureNodes +LogPluginManager: Mounting plugin CommonUI +LogPluginManager: Mounting plugin ControlRig +LogPluginManager: Mounting plugin Crashlytics +LogPluginManager: Mounting plugin DiscordRPC +LogPluginManager: Mounting plugin EditorScriptingUtilities +LogPluginManager: Mounting plugin FortInstallBundleManager +LogPluginManager: Found config from plugin[FortInstallBundleManager] D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Engine.ini +LogPluginManager: Mounting plugin OnlineSubsystem +LogPluginManager: Mounting plugin FortniteEarlyStartupPatcher +LogPluginManager: Mounting plugin EpicCMS +LogPluginManager: Mounting plugin EpicCMSUIFramework +LogPluginManager: Mounting plugin OnlineFramework +LogPluginManager: Mounting plugin OnlineSubsystemUtils +LogPluginManager: Mounting plugin OnlineSubsystemMcp +LogPluginManager: Mounting plugin FunctionalTestingEditor +LogPluginManager: Mounting plugin GameplayAbilities +LogPluginManager: Mounting plugin GameplayTagsEditor +LogPluginManager: Mounting plugin AssetManagerEditor +LogPluginManager: Mounting plugin Gauntlet +LogPluginManager: Mounting plugin GoogleARCore +LogPluginManager: Mounting plugin GoogleARCoreServices +LogPluginManager: Mounting plugin ImagePlate +LogPluginManager: Mounting plugin IOSDeviceProfileSelector +LogPluginManager: Mounting plugin IOSReplayKit +LogPluginManager: Mounting plugin LiveLinkCurveDebugUI +LogPluginManager: Mounting plugin LogitechLED +LogPluginManager: Mounting plugin MatchmakingService +LogPluginManager: Mounting plugin MeshNetwork +LogPluginManager: Mounting plugin ReplicationGraph +LogPluginManager: Mounting plugin NetUI +LogPluginManager: Mounting plugin OnlineSubsystemLiveServer +LogPluginManager: Mounting plugin OnlineSubsystemFacebook +LogPluginManager: Mounting plugin OnlineSubsystemGoogle +LogPluginManager: Mounting plugin OnlineSubsystemNull +LogPluginManager: Mounting plugin OnlineSubsystemPS4Server +LogPluginManager: Mounting plugin OnlineSubsystemTwitch +LogPluginManager: Mounting plugin Oodle +LogPluginManager: Mounting plugin Paper2D +LogPluginManager: Mounting plugin PhysXVehicles +LogPluginManager: Mounting plugin PurchaseFlow +LogPluginManager: Mounting plugin PythonScriptPlugin +LogPluginManager: Mounting plugin RazerChroma +LogPluginManager: Mounting plugin Social +LogPluginManager: Mounting plugin SocialUMG +LogPluginManager: Mounting plugin SubtitlesWidgets +LogPluginManager: Mounting plugin SubtitlesWidgetsEditor +LogPluginManager: Mounting plugin UAC +LogPluginManager: Mounting plugin UACBase +LogPluginManager: Mounting plugin WindowsDeviceProfileSelector +LogPluginManager: Mounting plugin WinDualShock +LogPluginManager: Mounting plugin LauncherChunkInstaller +LogPluginManager: Mounting plugin TimeSynth +LogPluginManager: Mounting plugin MIDIDevice +LogPluginManager: Mounting plugin WebBrowserNativeProxy +LogPluginManager: Mounting plugin OnlineJSBridge +LogPluginManager: Mounting plugin OnlineGameplayFramework +LogPluginManager: Mounting plugin KairosSceneCapture +LogPluginManager: Mounting plugin HighlightFeature +LogPluginManager: Mounting plugin VoiceChatManager +LogPluginManager: Mounting plugin VivoxVoiceChat +LogPluginManager: Mounting plugin VoiceJSBridge +LogPluginManager: Mounting plugin ApolloAR +LogPluginManager: Mounting plugin ARToolkit +LogPluginManager: Mounting plugin EpicGameplayStats +LogPluginManager: Mounting plugin EsportsCamera +LogPluginManager: Mounting plugin HTTPChunkInstaller +LogPluginManager: Mounting plugin ScreenCapture +LogPluginManager: Mounting plugin ZeusAR +LogPluginManager: Mounting plugin CryptoKeys +LogPluginManager: Mounting plugin AppleVision +LogPluginManager: Mounting plugin BackChannel +LogPluginManager: Mounting plugin AvfMedia +LogPluginManager: Mounting plugin WmfMedia +LogPluginManager: Mounting plugin NetcodeUnitTest +LogPluginManager: Mounting plugin NUTUnrealEngine4 +LogInit: WinSock: version 1.1 (2.2), MaxSocks=32767, MaxUdp=65467 +LogInit: Using libcurl 7.55.1-DEV +LogInit: - built for x86_64-pc-win32 +LogInit: - supports SSL with OpenSSL/1.0.2h +LogInit: - supports HTTP deflate (compression) using libz 1.2.8 +LogInit: - other features: +LogInit: CURL_VERSION_SSL +LogInit: CURL_VERSION_LIBZ +LogInit: CURL_VERSION_IPV6 +LogInit: CURL_VERSION_ASYNCHDNS +LogInit: CURL_VERSION_LARGEFILE +LogInit: CURL_VERSION_IDN +LogInit: CurlRequestOptions (configurable via config and command line): +LogInit: - bVerifyPeer = true - Libcurl will verify peer certificate +LogInit: - bUseHttpProxy = false - Libcurl will NOT use HTTP proxy +LogInit: - bDontReuseConnections = false - Libcurl will reuse connections +LogInit: - MaxHostConnections = 16 - Libcurl will limit the number of connections to a host +LogInit: - LocalHostAddr = Default +LogInit: - BufferSize = 65536 +LogHttp: HTTP thread active frame time 5.0 ms. Minimum active sleep time is 0.0 ms. HTTP thread idle frame time 33.3 ms. Minimum idle sleep time is 0.0 ms. +LogWebSockets: Verbose: Lws(Notice): SSL will not be initialized by libwebsockets: no LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT +LogWebSockets: Verbose: Lws(Notice): Creating Vhost 'default' (serving disabled), 6 protocols, IPv6 on +LogOnline: MCP: Mcp Startup! +LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +LogOnlineVoice: OSS: Voice interface disabled by config [OnlineSubsystem].bHasVoiceEnabled +LogInit: Build: UE4-CL-0 +LogInit: Engine Version: 4.22.0-0+UE4 +LogInit: Compatible Engine Version: 4.22.0-0+UE4 +LogInit: Net CL: 0 +LogInit: OS: Windows 10 (Release 1709) (), CPU: Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz, GPU: NVIDIA GeForce GTX 1080 +LogInit: Compiled (64-bit): Nov 29 2018 10:03:34 +LogInit: Compiled with Visual C++: 19.16.27024.01 +LogInit: Build Configuration: Development +LogInit: Branch Name: UE4 +LogInit: Command Line: -unattended -stdout -AllowStdOutLogVerbosity -multihome=10.1.168.34 -epicapp=DevLatest -buildidoverride=6834 -nosbmm -noepicportal -AUTH_TYPE=Epic -AUTH_LOGIN=loadbot07063@epicgames.com -AUTH_PASSWORD=LoadBot123 -FullStdOutLogOutput -nosplash -nosound -ini:Engine:[Core.Log]:LogHttp=VeryVerbose,[Core.Log]:LogXmpp=VeryVerbose,[Core.Log]:LogWebSockets=VeryVerbose,[Core.Log]:LogAnalytics=VeryVerbose -subgame=Athena -pilotedclient=AthenaSanityCheck -deterministicbot -FixedSeed -botMMTimeout=300 -botMMTries=2 -autoflush -userdir=D:\Epic\Kairos\GauntletTemp\PCTemp\LocalDevice0_UserDir -basedir=D:\Epic\Kairos\FortniteGame\Saved\StagedBuilds\WindowsClient\FortniteGame\Binaries\Win64 +LogInit: Base Directory: D:/Epic/Kairos/FortniteGame/Saved/StagedBuilds/WindowsClient/FortniteGame/Binaries/Win64/ +LogInit: Installed Engine Build: 0 +LogDevObjectVersion: Number of dev versions registered: 22 +LogDevObjectVersion: Dev-Blueprints (B0D832E4-1F89-4F0D-ACCF-7EB736FD4AA2): 10 +LogDevObjectVersion: Dev-Build (E1C64328-A22C-4D53-A36C-8E866417BD8C): 0 +LogDevObjectVersion: Dev-Core (375EC13C-06E4-48FB-B500-84F0262A717E): 2 +LogDevObjectVersion: Dev-Editor (E4B068ED-F494-42E9-A231-DA0B2E46BB41): 26 +LogDevObjectVersion: Dev-Framework (CFFC743F-43B0-4480-9391-14DF171D2073): 34 +LogDevObjectVersion: Dev-Mobile (B02B49B5-BB20-44E9-A304-32B752E40360): 2 +LogDevObjectVersion: Dev-Networking (A4E4105C-59A1-49B5-A7C5-40C4547EDFEE): 0 +LogDevObjectVersion: Dev-Online (39C831C9-5AE6-47DC-9A44-9C173E1C8E7C): 0 +LogDevObjectVersion: Dev-Physics (78F01B33-EBEA-4F98-B9B4-84EACCB95AA2): 0 +LogDevObjectVersion: Dev-Platform (6631380F-2D4D-43E0-8009-CF276956A95A): 0 +LogDevObjectVersion: Dev-Rendering (12F88B9F-8875-4AFC-A67C-D90C383ABD29): 27 +LogDevObjectVersion: Dev-Sequencer (7B5AE74C-D270-4C10-A958-57980B212A5A): 9 +LogDevObjectVersion: Dev-VR (D7296918-1DD6-4BDD-9DE2-64A83CC13884): 2 +LogDevObjectVersion: Dev-LoadTimes (C2A15278-BFE7-4AFE-6C17-90FF531DF755): 1 +LogDevObjectVersion: Private-Geometry (6EACA3D4-40EC-4CC1-B786-8BED09428FC5): 3 +LogDevObjectVersion: Dev-AnimPhys (29E575DD-E0A3-4627-9D10-D276232CDCEA): 17 +LogDevObjectVersion: Dev-Anim (AF43A65D-7FD3-4947-9873-3E8ED9C1BB05): 2 +LogDevObjectVersion: Dev-ReflectionCapture (6B266CEC-1EC7-4B8F-A30B-E4D90942FC07): 1 +LogDevObjectVersion: Dev-Automation (0DF73D61-A23F-47EA-B727-89E90C41499A): 1 +LogDevObjectVersion: FortniteMain (601D1886-AC64-4F84-AA16-D3DE0DEAC7D6): 22 +LogDevObjectVersion: Dev-Enterprise (9DFFBCD6-494F-0158-E221-12823C92A888): 4 +LogDevObjectVersion: Dev-Niagara (F2AED0AC-9AFE-416F-8664-AA7FFA26D6FC): 1 +LogInit: Presizing for max 2097152 objects, including 1 objects not considered by GC, pre-allocating 17825792 bytes for permanent pool. +LogStreaming: Display: Async Loading initialized: Event Driven Loader: true, Async Loading Thread: true, Async Post Load: true +LogInit: Object subsystem initialized +LogFortMemory: AppInit - CPU:116.19MB (Peak: 245.72MB) +LogConfig: Setting CVar [[con.DebugEarlyDefault:1]] +LogConfig: Setting CVar [[t.FPSChart.DoCsvProfile:1]] +LogConfig: Setting CVar [[tick.LightweightTimeguardThresholdMS:30]] +LogConfig: Setting CVar [[r.AllowStaticLighting:0]] +LogConfig: Setting CVar [[r.Shadow.CacheWPOPrimitives:1]] +LogConfig: Setting CVar [[r.CapsuleIndirectConeAngle:.2]] +LogConfig: Setting CVar [[r.AOSpecularOcclusionMode:0]] +LogConfig: Setting CVar [[r.SupportSimpleForwardShading:1]] +LogConfig: Setting CVar [[p.BatchPhysXTasksSize:8]] +LogConfig: Setting CVar [[r.DoLazyStaticMeshUpdate:1]] +LogConfig: Setting CVar [[FX.BatchAsync:1]] +LogConfig: Setting CVar [[FX.BatchAsyncBatchSize:32]] +LogConfig: Setting CVar [[grass.TickInterval:5]] +LogConfig: Setting CVar [[r.Mobile.TonemapperFilm:1]] +LogConfig: Setting CVar [[r.DistanceFields.ForceMaxAtlasSize:1]] +LogConfig: Setting CVar [[r.DistanceFields.AtlasSizeZ:1024]] +LogConfig: Setting CVar [[Compat.MAX_GPUSKIN_BONES:75]] +LogConfig: Setting CVar [[r.setres:1280x720]] +LogConfig: Setting CVar [[Slate.MaxFontAtlasPagesBeforeFlush:4]] +LogConfig: Setting CVar [[net.ProcessQueuedBunchesMillisecondLimit:0]] +LogConfig: Setting CVar [[InGamePerformanceTracking.Enabled:1]] +LogConfig: Setting CVar [[InGamePerformanceTracking.HistorySize:240]] +LogConfig: Setting CVar [[t.FPSChart.InterestingFramerates:30,60]] +LogConfig: Setting CVar [[p.DisableQueryOnlyActors:1]] +LogConfig: Setting CVar [[r.StencilForLODDither:1]] +LogConfig: Setting CVar [[r.gpucrash.collectionenable:1]] +LogConfig: Setting CVar [[r.gpucrash.datadepth:5]] +LogConfig: Setting CVar [[EnsureOnNaNFail:1]] +LogConfig: Setting CVar [[demo.WithLevelStreamingFixes:1]] +LogConfig: Setting CVar [[net.DisableRemapScriptActors:1]] +LogConfig: Setting CVar [[demo.ReplayStreamerAutoDemoPrefix:UnsavedReplay-]] +LogConfig: Setting CVar [[demo.ReplayStreamerAutoDemoUseDateTimePostfix:1]] +LogConfig: Setting CVar [[RecordingBufferLength:30]] +LogConfig: Setting CVar [[r.ScreenCapture.BitRate:3000000]] +LogConfig: Setting CVar [[Fort.AthenaReplayBrowserDisplayFileName:1]] +LogConfig: Setting CVar [[Fort.AutomaticClientReplayRecordingLimit:1]] +[2018.11.29-17.15.41:575][ 0]LogConfig: Setting CVar [[con.DebugEarlyDefault:1]] +[2018.11.29-17.15.41:575][ 0]LogConfig: Setting CVar [[t.FPSChart.DoCsvProfile:1]] +[2018.11.29-17.15.41:575][ 0]LogConfig: Setting CVar [[tick.LightweightTimeguardThresholdMS:30]] +[2018.11.29-17.15.41:575][ 0]LogConfig: Setting CVar [[r.AllowStaticLighting:0]] +[2018.11.29-17.15.41:575][ 0]LogConfig: Setting CVar [[r.Shadow.CacheWPOPrimitives:1]] +[2018.11.29-17.15.41:575][ 0]LogConfig: Setting CVar [[r.CapsuleIndirectConeAngle:.2]] +[2018.11.29-17.15.41:575][ 0]LogConfig: Setting CVar [[r.AOSpecularOcclusionMode:0]] +[2018.11.29-17.15.41:575][ 0]LogConfig: Setting CVar [[r.SupportSimpleForwardShading:1]] +[2018.11.29-17.15.41:575][ 0]LogConfig: Setting CVar [[p.BatchPhysXTasksSize:8]] +[2018.11.29-17.15.41:575][ 0]LogConfig: Setting CVar [[r.DoLazyStaticMeshUpdate:1]] +[2018.11.29-17.15.41:575][ 0]LogConfig: Setting CVar [[FX.BatchAsync:1]] +[2018.11.29-17.15.41:575][ 0]LogConfig: Setting CVar [[FX.BatchAsyncBatchSize:32]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[grass.TickInterval:5]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[r.Mobile.TonemapperFilm:1]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[r.DistanceFields.ForceMaxAtlasSize:1]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[r.DistanceFields.AtlasSizeZ:1024]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[Compat.MAX_GPUSKIN_BONES:75]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[r.setres:1280x720]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[Slate.MaxFontAtlasPagesBeforeFlush:4]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[net.ProcessQueuedBunchesMillisecondLimit:0]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[InGamePerformanceTracking.Enabled:1]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[InGamePerformanceTracking.HistorySize:240]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[t.FPSChart.InterestingFramerates:30,60]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[p.DisableQueryOnlyActors:1]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[r.StencilForLODDither:1]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[r.gpucrash.collectionenable:1]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[r.gpucrash.datadepth:5]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[EnsureOnNaNFail:1]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[demo.WithLevelStreamingFixes:1]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[net.DisableRemapScriptActors:1]] +[2018.11.29-17.15.41:576][ 0]LogConfig: Setting CVar [[demo.ReplayStreamerAutoDemoPrefix:UnsavedReplay-]] +[2018.11.29-17.15.41:577][ 0]LogConfig: Setting CVar [[demo.ReplayStreamerAutoDemoUseDateTimePostfix:1]] +[2018.11.29-17.15.41:577][ 0]LogConfig: Setting CVar [[RecordingBufferLength:30]] +[2018.11.29-17.15.41:577][ 0]LogConfig: Setting CVar [[r.ScreenCapture.BitRate:3000000]] +[2018.11.29-17.15.41:577][ 0]LogConfig: Setting CVar [[Fort.AthenaReplayBrowserDisplayFileName:1]] +[2018.11.29-17.15.41:577][ 0]LogConfig: Setting CVar [[Fort.AutomaticClientReplayRecordingLimit:1]] +[2018.11.29-17.15.41:577][ 0]LogConfig: Applying CVar settings from Section [/Script/Engine.RendererSettings] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Engine.ini] +[2018.11.29-17.15.41:577][ 0]LogConfig: Setting CVar [[r.GPUCrashDebugging:0]] +[2018.11.29-17.15.41:577][ 0]LogConfig: Setting CVar [[r.MobileHDR:1]] +[2018.11.29-17.15.41:577][ 0]LogConfig: Setting CVar [[r.AllowOcclusionQueries:1]] +[2018.11.29-17.15.41:577][ 0]LogConfig: Setting CVar [[r.ExpandNewlyOcclusionTestedBBoxesAmount:75]] +[2018.11.29-17.15.41:577][ 0]LogConfig: Setting CVar [[r.MinScreenRadiusForLights:0.030000]] +[2018.11.29-17.15.41:577][ 0]LogConfig: Setting CVar [[r.MinScreenRadiusForDepthPrepass:0.030000]] +[2018.11.29-17.15.41:577][ 0]LogConfig: Setting CVar [[r.PrecomputedVisibilityWarning:0]] +[2018.11.29-17.15.41:577][ 0]LogConfig: Setting CVar [[r.TextureStreaming:1]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.NormalMapsForStaticLighting:0]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.GenerateMeshDistanceFields:1]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.GenerateLandscapeGIData:0]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.DistanceFieldBuild.Compress:1]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.DistanceFieldBuild.EightBit:1]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.TessellationAdaptivePixelsPerTriangle:48.000000]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.TranslucentSortPolicy:0]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.CustomDepth:3]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.DefaultFeature.Bloom:1]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.DefaultFeature.AmbientOcclusion:1]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.DefaultFeature.AmbientOcclusionStaticFraction:0]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.DefaultFeature.AutoExposure:1]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.DefaultFeature.MotionBlur:1]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.DefaultFeature.LensFlare:0]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.DefaultFeature.AntiAliasing:2]] +[2018.11.29-17.15.41:578][ 0]LogConfig: Setting CVar [[r.EarlyZPass:2]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.EarlyZPassMovable:1]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.DBuffer:0]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.ClearSceneMethod:1]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.BasePassOutputsVelocity:1]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.WireframeCullThreshold:5.000000]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.LightShaftRenderToSeparateTranslucency:1]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.EarlyZPassOnlyMaterialMasking:1]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.VertexFoggingForOpaque:0]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.SelectiveBasePassOutputs:1]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.TonemapperFilm:1]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.Streaming.MaxTextureUVDensity:2500]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.Mobile.DisableVertexFog:0]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.MobileNumDynamicPointLights:4]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.Mobile.AllowMovableDirectionalLights:1]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.Mobile.AllowDistanceFieldShadows:0]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.Mobile.EnableStaticAndCSMShadowReceivers:0]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.Mobile.SkyLightPermutation:2]] +[2018.11.29-17.15.41:579][ 0]LogConfig: Setting CVar [[r.Mobile.CompressLandscapeWeightmaps:1]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[r.SupportStationarySkylight:0]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[r.SupportLowQualityLightmaps:0]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[r.SupportAtmosphericFog:0]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[r.Mobile.ForceFullPrecisionInPS:1]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[OpenGL.UseEmulatedUBs:1]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Applying CVar settings from Section [/Script/Engine.RendererOverrideSettings] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Engine.ini] +[2018.11.29-17.15.41:580][ 0]LogConfig: Applying CVar settings from Section [/Script/Engine.StreamingSettings] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Engine.ini] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[s.MinBulkDataSizeForAsyncLoading:131072]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[s.AsyncLoadingThreadEnabled:1]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[s.EventDrivenLoaderEnabled:1]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[s.WarnIfTimeLimitExceeded:0]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[s.TimeLimitExceededMultiplier:1.5]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[s.TimeLimitExceededMinTime:0.005]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[s.UseBackgroundLevelStreaming:1]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[s.PriorityAsyncLoadingExtraTime:40.0]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[s.LevelStreamingActorsUpdateTimeLimit:5.0]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[s.PriorityLevelStreamingActorsUpdateExtraTime:10.0]] +[2018.11.29-17.15.41:580][ 0]LogConfig: Setting CVar [[s.LevelStreamingComponentsRegistrationGranularity:10]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[s.UnregisterComponentsTimeLimit:1.0]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[s.LevelStreamingComponentsUnregistrationGranularity:5]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[s.ProcessPrestreamingRequests:1]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[s.ForceGCAfterLevelStreamedOut:0]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[s.ContinuouslyIncrementalGCWhileLevelsPendingPurge:0]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[s.AllowLevelRequestsWhileAsyncLoadingInMatch:1]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[s.MaxLevelRequestsAtOnceWhileInMatch:2]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Applying CVar settings from Section [/Script/Engine.GarbageCollectionSettings] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Engine.ini] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[gc.MaxObjectsNotConsideredByGC:1]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[gc.SizeOfPermanentObjectPool:17825792]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[gc.FlushStreamingOnGC:0]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[gc.NumRetriesBeforeForcingGC:10]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[gc.AllowParallelGC:1]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[gc.TimeBetweenPurgingPendingKillObjects:61.1]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[gc.MaxObjectsInEditor:8388607]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[gc.IncrementalBeginDestroyEnabled:1]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[gc.CreateGCClusters:1]] +[2018.11.29-17.15.41:581][ 0]LogConfig: Setting CVar [[gc.MergeGCClusters:0]] +[2018.11.29-17.15.41:582][ 0]LogConfig: Setting CVar [[gc.MinGCClusterSize:5]] +[2018.11.29-17.15.41:582][ 0]LogConfig: Setting CVar [[gc.ActorClusteringEnabled:1]] +[2018.11.29-17.15.41:582][ 0]LogConfig: Setting CVar [[gc.BlueprintClusteringEnabled:1]] +[2018.11.29-17.15.41:582][ 0]LogConfig: Setting CVar [[gc.UseDisregardForGCOnDedicatedServers:1]] +[2018.11.29-17.15.41:582][ 0]LogConfig: Applying CVar settings from Section [/Script/Engine.NetworkSettings] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Engine.ini] +[2018.11.29-17.15.41:582][ 0]LogConfig: Setting CVar [[n.VerifyPeer:1]] +[2018.11.29-17.15.41:591][ 0]LogConfig: Applying CVar settings from Section [ViewDistanceQuality@3] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:591][ 0]LogConfig: Setting CVar [[r.SkeletalMeshLODBias:0]] +[2018.11.29-17.15.41:592][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale:2.0]] +[2018.11.29-17.15.41:592][ 0]LogConfig: Setting CVar [[Fort.Scalability.AIBudget:8,16]] +[2018.11.29-17.15.41:592][ 0]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget:5,10,10,75]] +[2018.11.29-17.15.41:592][ 0]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget.URORates:0,1,2,3]] +[2018.11.29-17.15.41:592][ 0]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget.SkelMeshMinLOD:0,1,1,2]] +[2018.11.29-17.15.41:592][ 0]LogConfig: Setting CVar [[Fort.Scalability.BucketDistances:50,100,250,500]] +[2018.11.29-17.15.41:592][ 0]LogConfig: Setting CVar [[Fort.Scalability.PlayerCosmeticPropBudget:0]] +[2018.11.29-17.15.41:592][ 0]LogConfig: Setting CVar [[Fort.Scalability.TieUROToLODs:1]] +[2018.11.29-17.15.41:592][ 0]LogConfig: Setting CVar [[Fort.Scalability.EnableAnimCurveOptimizations:1]] +[2018.11.29-17.15.41:593][ 0]LogConfig: Setting CVar [[Athena.Scalability.SecondarySkelMeshTickingThreshold:1]] +[2018.11.29-17.15.41:593][ 0]LogConfig: Setting CVar [[p.AnimDynamicsLODThreshold:1]] +[2018.11.29-17.15.41:593][ 0]LogConfig: Setting CVar [[p.RigidBodyLODThreshold:1]] +[2018.11.29-17.15.41:593][ 0]LogConfig: Setting CVar [[r.StaticMeshLODDistanceScale:1]] +[2018.11.29-17.15.41:593][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.SecondaryScale:1.0]] +[2018.11.29-17.15.41:593][ 0]LogConfig: Setting CVar [[r.HLOD.DistanceOverride:40000,35000]] +[2018.11.29-17.15.41:593][ 0]LogConfig: Setting CVar [[Athena.Scalability.HLODProxyMaxDrawDistance:0.0]] +[2018.11.29-17.15.41:593][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMaxAngle:80.0]] +[2018.11.29-17.15.41:593][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMaxAngleScale:1.0]] +[2018.11.29-17.15.41:594][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMinAngle:15.0]] +[2018.11.29-17.15.41:594][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMinAngleScale:2.0]] +[2018.11.29-17.15.41:594][ 0]LogConfig: Setting CVar [[Athena.EnableProxyPredictionPawnLOD:1]] +[2018.11.29-17.15.41:594][ 0]LogConfig: Setting CVar [[Athena.EnableProxySimulatedStepUpLOD:0]] +[2018.11.29-17.15.41:594][ 0]LogConfig: Setting CVar [[Athena.EnableProxySimulatedStepUpMinNormalZ:0.1]] +[2018.11.29-17.15.41:594][ 0]LogConfig: Setting CVar [[Athena.ForceThrottledSimulatedFloorChecks:1]] +[2018.11.29-17.15.41:594][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingSkipFramesLowestLOD:1]] +[2018.11.29-17.15.41:594][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingSkipFramesInvisible:3]] +[2018.11.29-17.15.41:594][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_Players:66]] +[2018.11.29-17.15.41:594][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_AI:66]] +[2018.11.29-17.15.41:594][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_Combined:66]] +[2018.11.29-17.15.41:595][ 0]LogConfig: Setting CVar [[r.NeverOcclusionTestDistance:1250]] +[2018.11.29-17.15.41:595][ 0]LogConfig: Setting CVar [[a.Budget.Enabled:1]] +[2018.11.29-17.15.41:595][ 0]LogConfig: Setting CVar [[a.Budget.BudgetMs:1.5]] +[2018.11.29-17.15.41:595][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingSkipFramesLargeGameLOD2:0]] +[2018.11.29-17.15.41:595][ 0]LogConfig: Applying CVar settings from Section [AntiAliasingQuality@3] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:595][ 0]LogConfig: Setting CVar [[r.PostProcessAAQuality:4]] +[2018.11.29-17.15.41:595][ 0]LogConfig: Setting CVar [[r.Tonemapper.Sharpen:0.5]] +[2018.11.29-17.15.41:595][ 0]LogConfig: Applying CVar settings from Section [ShadowQuality@3] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:595][ 0]LogConfig: Setting CVar [[r.LightFunctionQuality:1]] +[2018.11.29-17.15.41:595][ 0]LogConfig: Setting CVar [[r.ShadowQuality:5]] +[2018.11.29-17.15.41:595][ 0]LogConfig: Setting CVar [[r.Shadow.CSM.MaxCascades:10]] +[2018.11.29-17.15.41:596][ 0]LogConfig: Setting CVar [[r.Shadow.MaxResolution:2048]] +[2018.11.29-17.15.41:596][ 0]LogConfig: Setting CVar [[r.Shadow.MaxCSMResolution:2048]] +[2018.11.29-17.15.41:596][ 0]LogConfig: Setting CVar [[r.Shadow.RadiusThreshold:0.01]] +[2018.11.29-17.15.41:596][ 0]LogConfig: Setting CVar [[r.Shadow.DistanceScale:1.0]] +[2018.11.29-17.15.41:596][ 0]LogConfig: Setting CVar [[r.Shadow.CSM.TransitionScale:1.0]] +[2018.11.29-17.15.41:596][ 0]LogConfig: Setting CVar [[r.Shadow.PreShadowResolutionFactor:1.0]] +[2018.11.29-17.15.41:596][ 0]LogConfig: Setting CVar [[r.DistanceFieldShadowing:1]] +[2018.11.29-17.15.41:596][ 0]LogConfig: Setting CVar [[r.DistanceFieldAO:1]] +[2018.11.29-17.15.41:596][ 0]LogConfig: Setting CVar [[r.AOQuality:2]] +[2018.11.29-17.15.41:596][ 0]LogConfig: Setting CVar [[r.VolumetricFog:1]] +[2018.11.29-17.15.41:596][ 0]LogConfig: Setting CVar [[r.VolumetricFog.GridPixelSize:8]] +[2018.11.29-17.15.41:597][ 0]LogConfig: Setting CVar [[r.VolumetricFog.GridSizeZ:128]] +[2018.11.29-17.15.41:597][ 0]LogConfig: Setting CVar [[r.VolumetricFog.HistoryMissSupersampleCount:4]] +[2018.11.29-17.15.41:597][ 0]LogConfig: Setting CVar [[r.LightMaxDrawDistanceScale:1]] +[2018.11.29-17.15.41:597][ 0]LogConfig: Setting CVar [[r.CapsuleShadows:1]] +[2018.11.29-17.15.41:597][ 0]LogConfig: Setting CVar [[r.SimpleForwardShading:0]] +[2018.11.29-17.15.41:597][ 0]LogConfig: Setting CVar [[Fort.TODDirectionalLightUpdateRate:0]] +[2018.11.29-17.15.41:597][ 0]LogConfig: Setting CVar [[r.Shadow.MaxNumPointShadowCacheUpdatesPerFrame:-1]] +[2018.11.29-17.15.41:597][ 0]LogConfig: Setting CVar [[r.Shadow.MaxNumSpotShadowCacheUpdatesPerFrame:-1]] +[2018.11.29-17.15.41:597][ 0]LogConfig: Applying CVar settings from Section [PostProcessQuality@3] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:597][ 0]LogConfig: Setting CVar [[r.MotionBlurQuality:4]] +[2018.11.29-17.15.41:597][ 0]LogConfig: Setting CVar [[r.AmbientOcclusionMipLevelFactor:0.4]] +[2018.11.29-17.15.41:598][ 0]LogConfig: Setting CVar [[r.AmbientOcclusionMaxQuality:100]] +[2018.11.29-17.15.41:598][ 0]LogConfig: Setting CVar [[r.AmbientOcclusionLevels:-1]] +[2018.11.29-17.15.41:598][ 0]LogConfig: Setting CVar [[r.AmbientOcclusionRadiusScale:1.0]] +[2018.11.29-17.15.41:598][ 0]LogConfig: Setting CVar [[r.DepthOfFieldQuality:2]] +[2018.11.29-17.15.41:598][ 0]LogConfig: Setting CVar [[r.RenderTargetPoolMin:400]] +[2018.11.29-17.15.41:598][ 0]LogConfig: Setting CVar [[r.LensFlareQuality:2]] +[2018.11.29-17.15.41:598][ 0]LogConfig: Setting CVar [[r.SceneColorFringeQuality:1]] +[2018.11.29-17.15.41:598][ 0]LogConfig: Setting CVar [[r.EyeAdaptationQuality:1]] +[2018.11.29-17.15.41:598][ 0]LogConfig: Setting CVar [[r.BloomQuality:5]] +[2018.11.29-17.15.41:598][ 0]LogConfig: Setting CVar [[r.FastBlurThreshold:100]] +[2018.11.29-17.15.41:598][ 0]LogConfig: Setting CVar [[r.Upscale.Quality:3]] +[2018.11.29-17.15.41:598][ 0]LogConfig: Setting CVar [[r.Tonemapper.GrainQuantization:1]] +[2018.11.29-17.15.41:598][ 0]LogConfig: Setting CVar [[r.LightShaftQuality:1]] +[2018.11.29-17.15.41:598][ 0]LogConfig: Setting CVar [[r.Filter.SizeScale:1]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.Tonemapper.Quality:5]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.DOF.Gather.AccumulatorQuality:1 ; higher gathering accumulator quality]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.DOF.Gather.PostfilterMethod:1 ; Median3x3 postfilering method]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.DOF.Gather.EnableBokehSettings:0 ; no bokeh simulation when gathering]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.DOF.Gather.RingCount:4 ; medium number of samples when gathering]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.DOF.Scatter.ForegroundCompositing:1 ; additive foreground scattering]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.DOF.Scatter.BackgroundCompositing:2 ; additive background scattering]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.DOF.Scatter.EnableBokehSettings:1 ; bokeh simulation when scattering]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.DOF.Scatter.MaxSpriteRatio:0.1 ; only a maximum of 10% of scattered bokeh]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.DOF.Recombine.Quality:1 ; cheap slight out of focus]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.DOF.Recombine.EnableBokehSettings:0 ; no bokeh simulation on slight out of focus]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.DOF.TemporalAAQuality:1 ; more stable temporal accumulation]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.DOF.Kernel.MaxForegroundRadius:0.025]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.DOF.Kernel.MaxBackgroundRadius:0.025]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.AmbientOcclusion.Compute:0]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Applying CVar settings from Section [TextureQuality@3] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.Streaming.MipBias:0]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.Streaming.AmortizeCPUToGPUCopy:0]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.Streaming.MaxNumTexturesToStreamPerFrame:0]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.Streaming.Boost:1]] +[2018.11.29-17.15.41:599][ 0]LogConfig: Setting CVar [[r.MaxAnisotropy:8]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.Streaming.LimitPoolSizeToVRAM:0]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.Streaming.PoolSize:1000]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.Streaming.MaxEffectiveScreenSize:0]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Applying CVar settings from Section [EffectsQuality@3] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.TranslucencyLightingVolumeDim:64]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.RefractionQuality:2]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.SSR.Quality:3]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.SceneColorFormat:4]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.DetailMode:2]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.TranslucencyVolumeBlur:1]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.MaterialQualityLevel:1 ; High quality]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.SSS.Scale:1]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.SSS.SampleSet:2]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.SSS.Quality:1]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.SSS.HalfRes:1]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.EmitterSpawnRateScale:1.0]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[r.ParticleLightQuality:2]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[Fort.Wind:1]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_Low:0.85]] +[2018.11.29-17.15.41:600][ 0]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_Medium:0.7]] +[2018.11.29-17.15.41:601][ 0]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_High:0.3]] +[2018.11.29-17.15.41:601][ 0]LogConfig: Setting CVar [[fx.Significance.MaxRange:14000]] +[2018.11.29-17.15.41:601][ 0]LogConfig: Setting CVar [[p.AnimDynamicsWind:1]] +[2018.11.29-17.15.41:601][ 0]LogConfig: Setting CVar [[r.SeparateTranslucency:1]] +[2018.11.29-17.15.41:601][ 0]LogConfig: Applying CVar settings from Section [FoliageQuality@3] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:601][ 0]LogConfig: Setting CVar [[foliage.DensityScale:1.0]] +[2018.11.29-17.15.41:601][ 0]LogConfig: Setting CVar [[grass.DensityScale:1.0]] +[2018.11.29-17.15.41:614][ 0]LogD3D11RHI: D3D11 adapters: +[2018.11.29-17.15.41:767][ 0]LogD3D11RHI: 0. 'NVIDIA GeForce GTX 1080' (Feature Level 11_0) +[2018.11.29-17.15.41:767][ 0]LogD3D11RHI: 8079/0/48368 MB DedicatedVideo/DedicatedSystem/SharedSystem, Outputs:1, VendorId:0x10de +[2018.11.29-17.15.41:771][ 0]LogD3D11RHI: 1. 'Microsoft Basic Render Driver' (Feature Level 11_0) +[2018.11.29-17.15.41:771][ 0]LogD3D11RHI: 0/0/48368 MB DedicatedVideo/DedicatedSystem/SharedSystem, Outputs:0, VendorId:0x1414 +[2018.11.29-17.15.41:771][ 0]LogD3D11RHI: Chosen D3D11 Adapter: 0 +[2018.11.29-17.15.41:787][ 0]LogInit: Selected Device Profile: [WindowsClient] +[2018.11.29-17.15.41:787][ 0]LogInit: Applying CVar settings loaded from the selected device profile: [WindowsClient] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[dp.AllowScalabilityGroupsToChangeAtRuntime:1]] +[2018.11.29-17.15.41:788][ 0]LogHAL: Display: Platform has ~ 95 GB [101436329984 / 137438953472 / 95], which maps to Largest [LargestMinGB=32, LargerMinGB=12, DefaultMinGB=8, SmallerMinGB=6, SmallestMinGB=0) +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[au.DisableEnvelopeFollowing:1]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[r.DistanceFields.ParallelAtlasUpdate:1]] +[2018.11.29-17.15.41:788][ 0]LogInit: Going up to parent DeviceProfile [Windows] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[r.Vulkan.UseRealUBs:1]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[sg.ViewDistanceQuality:2]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Applying CVar settings from Section [ViewDistanceQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[r.SkeletalMeshLODBias:0]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale:1.67]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[Fort.Scalability.AIBudget:8,16]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget:5,10,10,75]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget.URORates:0,1,2,3]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget.SkelMeshMinLOD:0,1,1,2]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[Fort.Scalability.BucketDistances:50,100,250,500]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[Fort.Scalability.PlayerCosmeticPropBudget:0]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[Fort.Scalability.TieUROToLODs:1]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[Fort.Scalability.EnableAnimCurveOptimizations:1]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[Athena.Scalability.SecondarySkelMeshTickingThreshold:1]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[p.AnimDynamicsLODThreshold:1]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[p.RigidBodyLODThreshold:1]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[r.StaticMeshLODDistanceScale:1]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.SecondaryScale:1.0]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[r.HLOD.DistanceOverride:40000,35000]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[Athena.Scalability.HLODProxyMaxDrawDistance:0.0]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMaxAngle:80.0]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMaxAngleScale:1.0]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMinAngle:15.0]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMinAngleScale:2.0]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[Athena.EnableProxyPredictionPawnLOD:1]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[Athena.EnableProxySimulatedStepUpLOD:0]] +[2018.11.29-17.15.41:788][ 0]LogConfig: Setting CVar [[Athena.EnableProxySimulatedStepUpMinNormalZ:0.1]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[Athena.ForceThrottledSimulatedFloorChecks:1]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingSkipFramesLowestLOD:1]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingSkipFramesInvisible:4]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_Players:50]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_AI:50]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_Combined:50]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.NeverOcclusionTestDistance:1250]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[a.Budget.Enabled:1]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[a.Budget.BudgetMs:1.5]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[sg.AntiAliasingQuality:2]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Applying CVar settings from Section [AntiAliasingQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.PostProcessAAQuality:3]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.Tonemapper.Sharpen:0.5]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[sg.ShadowQuality:2]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Applying CVar settings from Section [ShadowQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.LightFunctionQuality:1]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.ShadowQuality:5]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.Shadow.CSM.MaxCascades:2]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.Shadow.MaxResolution:1024]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.Shadow.MaxCSMResolution:2048]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.Shadow.RadiusThreshold:0.04]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.Shadow.DistanceScale:0.85]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.Shadow.CSM.TransitionScale:0.8]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.Shadow.PreShadowResolutionFactor:0.5]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.DistanceFieldShadowing:1]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.DistanceFieldAO:1]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.AOQuality:1]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.VolumetricFog:1]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.VolumetricFog.GridPixelSize:16]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.VolumetricFog.GridSizeZ:64]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.VolumetricFog.HistoryMissSupersampleCount:4]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.LightMaxDrawDistanceScale:.5]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.CapsuleShadows:1]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.SimpleForwardShading:0]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.Shadow.MaxNumPointShadowCacheUpdatesPerFrame:2]] +[2018.11.29-17.15.41:789][ 0]LogConfig: Setting CVar [[r.Shadow.MaxNumSpotShadowCacheUpdatesPerFrame:4]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[Fort.TODDirectionalLightUpdateRate:0]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[sg.PostProcessQuality:2]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Applying CVar settings from Section [PostProcessQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.MotionBlurQuality:3]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.AmbientOcclusionMipLevelFactor:0.6]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.AmbientOcclusionMaxQuality:100]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.AmbientOcclusionLevels:-1]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.AmbientOcclusionRadiusScale:1.5]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.DepthOfFieldQuality:2]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.RenderTargetPoolMin:400]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.LensFlareQuality:2]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.SceneColorFringeQuality:1]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.EyeAdaptationQuality:1]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.BloomQuality:5]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.FastBlurThreshold:3]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.Upscale.Quality:2]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.Tonemapper.GrainQuantization:1]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.LightShaftQuality:0]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.Filter.SizeScale:0.8]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.Tonemapper.Quality:5]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.DOF.Gather.AccumulatorQuality:0 ; lower gathering accumulator quality]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.DOF.Gather.PostfilterMethod:2 ; Max3x3 postfilering method]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.DOF.Gather.EnableBokehSettings:0 ; no bokeh simulation when gathering]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.DOF.Gather.RingCount:4 ; medium number of samples when gathering]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.DOF.Scatter.ForegroundCompositing:1 ; additive foreground scattering]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.DOF.Scatter.BackgroundCompositing:1 ; no background occlusion]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.DOF.Scatter.EnableBokehSettings:0 ; no bokeh simulation when scattering]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.DOF.Scatter.MaxSpriteRatio:0.04 ; only a maximum of 4% of scattered bokeh]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.DOF.Recombine.Quality:0 ; no slight out of focus]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.DOF.TemporalAAQuality:0 ; faster temporal accumulation]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.DOF.Kernel.MaxForegroundRadius:0.012 ; required because of AccumulatorQuality=0]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.DOF.Kernel.MaxBackgroundRadius:0.012 ; required because of AccumulatorQuality=0]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[r.AmbientOcclusion.Compute:0]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Setting CVar [[sg.TextureQuality:2]] +[2018.11.29-17.15.41:790][ 0]LogConfig: Applying CVar settings from Section [TextureQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.Streaming.MipBias:0]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.Streaming.AmortizeCPUToGPUCopy:0]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.Streaming.MaxNumTexturesToStreamPerFrame:0]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.Streaming.Boost:1]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.MaxAnisotropy:4]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.Streaming.LimitPoolSizeToVRAM:1]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.Streaming.PoolSize:800]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.Streaming.MaxEffectiveScreenSize:0]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[sg.EffectsQuality:2]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Applying CVar settings from Section [EffectsQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.TranslucencyLightingVolumeDim:48]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.RefractionQuality:2]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.SSR.Quality:2]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.SceneColorFormat:3]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.DetailMode:1]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.TranslucencyVolumeBlur:1]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.MaterialQualityLevel:1 ; High quality]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.SSS.Scale:1]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.SSS.SampleSet:1]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.SSS.Quality:-1]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.SSS.HalfRes:1]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.EmitterSpawnRateScale:0.5]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.ParticleLightQuality:1]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[Fort.Wind:1]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_Low:0.85]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_Medium:0.7]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_High:0.3]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[fx.Significance.MaxRange:14000]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[p.AnimDynamicsWind:1]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.SeparateTranslucency:1]] +[2018.11.29-17.15.41:791][ 0]LogInit: Going up to parent DeviceProfile [] +[2018.11.29-17.15.41:791][ 0]LogConfig: Applying CVar settings from Section [ViewDistanceQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.SkeletalMeshLODBias:0]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale:1.67]] +[2018.11.29-17.15.41:791][ 0]LogConfig: Setting CVar [[Fort.Scalability.AIBudget:8,16]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget:5,10,10,75]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget.URORates:0,1,2,3]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget.SkelMeshMinLOD:0,1,1,2]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Fort.Scalability.BucketDistances:50,100,250,500]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Fort.Scalability.PlayerCosmeticPropBudget:0]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Fort.Scalability.TieUROToLODs:1]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Fort.Scalability.EnableAnimCurveOptimizations:1]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Athena.Scalability.SecondarySkelMeshTickingThreshold:1]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[p.AnimDynamicsLODThreshold:1]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[p.RigidBodyLODThreshold:1]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.StaticMeshLODDistanceScale:1]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.SecondaryScale:1.0]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.HLOD.DistanceOverride:40000,35000]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Athena.Scalability.HLODProxyMaxDrawDistance:0.0]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMaxAngle:80.0]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMaxAngleScale:1.0]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMinAngle:15.0]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMinAngleScale:2.0]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Athena.EnableProxyPredictionPawnLOD:1]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Athena.EnableProxySimulatedStepUpLOD:0]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Athena.EnableProxySimulatedStepUpMinNormalZ:0.1]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Athena.ForceThrottledSimulatedFloorChecks:1]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingSkipFramesLowestLOD:1]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingSkipFramesInvisible:4]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_Players:50]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_AI:50]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_Combined:50]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.NeverOcclusionTestDistance:1250]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[a.Budget.Enabled:1]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[a.Budget.BudgetMs:1.5]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Applying CVar settings from Section [AntiAliasingQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.PostProcessAAQuality:3]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.Tonemapper.Sharpen:0.5]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Applying CVar settings from Section [ShadowQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.LightFunctionQuality:1]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.ShadowQuality:5]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.Shadow.CSM.MaxCascades:2]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.Shadow.MaxResolution:1024]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.Shadow.MaxCSMResolution:2048]] +[2018.11.29-17.15.41:792][ 0]LogConfig: Setting CVar [[r.Shadow.RadiusThreshold:0.04]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.Shadow.DistanceScale:0.85]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.Shadow.CSM.TransitionScale:0.8]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.Shadow.PreShadowResolutionFactor:0.5]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DistanceFieldShadowing:1]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DistanceFieldAO:1]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.AOQuality:1]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.VolumetricFog:1]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.VolumetricFog.GridPixelSize:16]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.VolumetricFog.GridSizeZ:64]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.VolumetricFog.HistoryMissSupersampleCount:4]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.LightMaxDrawDistanceScale:.5]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.CapsuleShadows:1]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.SimpleForwardShading:0]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.Shadow.MaxNumPointShadowCacheUpdatesPerFrame:2]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.Shadow.MaxNumSpotShadowCacheUpdatesPerFrame:4]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[Fort.TODDirectionalLightUpdateRate:0]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Applying CVar settings from Section [PostProcessQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.MotionBlurQuality:3]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.AmbientOcclusionMipLevelFactor:0.6]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.AmbientOcclusionMaxQuality:100]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.AmbientOcclusionLevels:-1]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.AmbientOcclusionRadiusScale:1.5]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DepthOfFieldQuality:2]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.RenderTargetPoolMin:400]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.LensFlareQuality:2]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.SceneColorFringeQuality:1]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.EyeAdaptationQuality:1]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.BloomQuality:5]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.FastBlurThreshold:3]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.Upscale.Quality:2]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.Tonemapper.GrainQuantization:1]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.LightShaftQuality:0]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.Filter.SizeScale:0.8]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.Tonemapper.Quality:5]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DOF.Gather.AccumulatorQuality:0 ; lower gathering accumulator quality]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DOF.Gather.PostfilterMethod:2 ; Max3x3 postfilering method]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DOF.Gather.EnableBokehSettings:0 ; no bokeh simulation when gathering]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DOF.Gather.RingCount:4 ; medium number of samples when gathering]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DOF.Scatter.ForegroundCompositing:1 ; additive foreground scattering]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DOF.Scatter.BackgroundCompositing:1 ; no background occlusion]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DOF.Scatter.EnableBokehSettings:0 ; no bokeh simulation when scattering]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DOF.Scatter.MaxSpriteRatio:0.04 ; only a maximum of 4% of scattered bokeh]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DOF.Recombine.Quality:0 ; no slight out of focus]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DOF.TemporalAAQuality:0 ; faster temporal accumulation]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DOF.Kernel.MaxForegroundRadius:0.012 ; required because of AccumulatorQuality=0]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.DOF.Kernel.MaxBackgroundRadius:0.012 ; required because of AccumulatorQuality=0]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.AmbientOcclusion.Compute:0]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Applying CVar settings from Section [TextureQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.Streaming.MipBias:0]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.Streaming.AmortizeCPUToGPUCopy:0]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.Streaming.MaxNumTexturesToStreamPerFrame:0]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.Streaming.Boost:1]] +[2018.11.29-17.15.41:793][ 0]LogConfig: Setting CVar [[r.MaxAnisotropy:4]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.Streaming.LimitPoolSizeToVRAM:1]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.Streaming.PoolSize:800]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.Streaming.MaxEffectiveScreenSize:0]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Applying CVar settings from Section [EffectsQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.TranslucencyLightingVolumeDim:48]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.RefractionQuality:2]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.SSR.Quality:2]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.SceneColorFormat:3]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.DetailMode:1]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.TranslucencyVolumeBlur:1]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.MaterialQualityLevel:1 ; High quality]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.SSS.Scale:1]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.SSS.SampleSet:1]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.SSS.Quality:-1]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.SSS.HalfRes:1]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.EmitterSpawnRateScale:0.5]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.ParticleLightQuality:1]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[Fort.Wind:1]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_Low:0.85]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_Medium:0.7]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_High:0.3]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[fx.Significance.MaxRange:14000]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[p.AnimDynamicsWind:1]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[r.SeparateTranslucency:1]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Applying CVar settings from Section [FoliageQuality@3] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[foliage.DensityScale:1.0]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[grass.DensityScale:1.0]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Applying CVar settings from Section [Startup] File [../../../Engine/Config/ConsoleVariables.ini] +[2018.11.29-17.15.41:794][ 0]LogConfig: Setting CVar [[net.UseAdaptiveNetUpdateFrequency:0]] +[2018.11.29-17.15.41:794][ 0]LogConfig: Applying CVar settings from Section [ConsoleVariables] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Engine.ini] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[net.AllowAsyncLoading:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[net.DelayUnmappedRPCs:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[net.MaxRPCPerNetUpdate:10]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[net.PingExcludeFrameTime:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[net.UseAdaptiveNetUpdateFrequency:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[OSS.VerboseSessionInPayloads:0]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[OSS.VerboseSessionOutPayloads:0]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[OSS.VerboseIdentityPayloads:0]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[httpReplay.ChunkUploadDelayInSeconds:20]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[demo.CheckpointUploadDelayInSeconds:60]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[demo.ForceDisableAsyncPackageMapLoading:0]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[gpad.LeftStickInnerDeadzone:0.24]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[gpad.LeftStickOuterDeadzone:0.01]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[gpad.RightStickInnerDeadzone:0.27]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[gpad.RightStickOuterDeadzone:0.01]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[demo.UseNetRelevancy:0]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[demo.CullDistanceOverride:3000]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[demo.RecordHzWhenNotRelevant:2]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[demo.ClientRecordAsyncEndOfFrame:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[gc.CreateGCClusters:0]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[tick.DoAsyncEndOfFrameTasks:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[Athena.Vehicle.ShowAirHeightOver:3]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[Athena.Vehicle.ShowAirDistanceOver:5]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[Analytic.DumpPlayerInventoryPerZonePhase:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[Weapon.TryToFireRestrictedByTypeCooldowns:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[Weapon.UseInterpolateToPerfectAim:0]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[r.StaticMesh.StripMinLodDataDuringCooking:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[r.SkeletalMesh.StripMinLodDataDuringCooking:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[r.ForceStripAdjacencyDataDuringCooking:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[r.AOGlobalDFStartDistance:100]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[r.RHICmdBalanceParallelLists:0]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[foliage.MinVertsToSplitNode:8192]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[p.ForceNoKSPairs:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[p.ForceNoKKPairs:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[Athena.bMegaStormEnabled:0]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[FortRepGraph.SpatialBiasX:-270000]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[FortRepGraph.SpatialBiasY:-270000]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[Fort.GliderRedeployRequiresJump:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[Fort.GliderRedeployUseWindowOfTime:0]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[Fort.GliderRedeployWindowLength:5.0]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[Fort.GliderRedeployPreventSkydiving:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[Fort.EnableFacialAnimation:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[Fort.EnableFacialVideoSource:0]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[dp.AllowScalabilityGroupsToChangeAtRuntime:1]] +[2018.11.29-17.15.41:795][ 0]LogConfig: Setting CVar [[au.DisableHPFiltering:1]] +[2018.11.29-17.15.41:796][ 0]LogInit: Computer: RDU-WD-L0078 +[2018.11.29-17.15.41:796][ 0]LogInit: User: andrewgrant +[2018.11.29-17.15.41:796][ 0]LogInit: CPU Page size=4096, Cores=6 +[2018.11.29-17.15.41:796][ 0]LogInit: High frequency timer resolution =3.312532 MHz +[2018.11.29-17.15.41:796][ 0]LogMemory: Memory total: Physical=94.5GB (95GB approx) +[2018.11.29-17.15.41:796][ 0]LogMemory: Platform Memory Stats for WindowsClient +[2018.11.29-17.15.41:796][ 0]LogMemory: Process Physical Memory: 250.54 MB used, 255.76 MB peak +[2018.11.29-17.15.41:796][ 0]LogMemory: Process Virtual Memory: 246.53 MB used, 246.53 MB peak +[2018.11.29-17.15.41:796][ 0]LogMemory: Physical Memory: 13974.73 MB used, 82762.50 MB free, 96737.22 MB total +[2018.11.29-17.15.41:796][ 0]LogMemory: Virtual Memory: 699.07 MB used, 134217032.00 MB free, 134217728.00 MB total +[2018.11.29-17.15.41:815][ 0]LogWindows: WindowsPlatformFeatures enabled +[2018.11.29-17.15.42:132][ 0]LogInit: Using OS detected language (en-US). +[2018.11.29-17.15.42:132][ 0]LogInit: Using OS detected locale (en-US). +[2018.11.29-17.15.42:158][ 0]LogTextLocalizationManager: No specific localization for 'en-US' exists, so the 'en' localization will be used. +[2018.11.29-17.15.42:170][ 0]LogOnline: OSS: Flushing Catalog Service cached offers/items. +[2018.11.29-17.15.42:199][ 0]LogSlate: Warning: FCoreStyle assets not detected, skipping FCoreStyle initialization +[2018.11.29-17.15.42:199][ 0]LogSlate: New Slate User Created. User Index 0, Is Virtual User: 0 +[2018.11.29-17.15.42:199][ 0]LogSlate: Slate User Registered. User Index 0, Is Virtual User: 0 +[2018.11.29-17.15.42:216][ 0]LogD3D11RHI: Creating new Direct3DDevice +[2018.11.29-17.15.42:216][ 0]LogD3D11RHI: GPU DeviceId: 0x1b80 (for the marketing name, search the web for "GPU Device Id") +[2018.11.29-17.15.42:216][ 0]LogWindows: EnumDisplayDevices: +[2018.11.29-17.15.42:216][ 0]LogWindows: 0. 'NVIDIA GeForce GTX 1080' (P:1 D:1) +[2018.11.29-17.15.42:216][ 0]LogWindows: 1. 'NVIDIA GeForce GTX 1080' (P:0 D:0) +[2018.11.29-17.15.42:217][ 0]LogWindows: 2. 'NVIDIA GeForce GTX 1080' (P:0 D:0) +[2018.11.29-17.15.42:217][ 0]LogWindows: 3. 'NVIDIA GeForce GTX 1080' (P:0 D:0) +[2018.11.29-17.15.42:217][ 0]LogWindows: 4. 'DameWare Development Mirror Driver 64-bit' (P:0 D:0) +[2018.11.29-17.15.42:217][ 0]LogWindows: DebugString: GetVideoDriverDetailsInvalid PrimaryIsNotTheChoosenAdapter FoundDriverCount:4 +[2018.11.29-17.15.42:217][ 0]LogD3D11RHI: Adapter Name: NVIDIA GeForce GTX 1080 +[2018.11.29-17.15.42:217][ 0]LogD3D11RHI: Driver Version: 397.77 (internal:24.21.13.9777, unified:397.77) +[2018.11.29-17.15.42:217][ 0]LogD3D11RHI: Driver Date: 5-11-2018 +[2018.11.29-17.15.42:217][ 0]LogRHI: Texture pool is 5655 MB (70% of 8079 MB) +[2018.11.29-17.15.42:333][ 0]LogD3D11RHI: Async texture creation enabled +[2018.11.29-17.15.42:357][ 0]LogD3D11RHI: GPU Timing Frequency: 1000.000000 (Debug: 2 2) +[2018.11.29-17.15.42:361][ 0]LogShaderLibrary: Display: Using ../../../FortniteGame/Content/ShaderArchive-Global-PCD3D_SM5.ushaderbytecode for material shader code. Total 1479 unique shaders. +[2018.11.29-17.15.42:361][ 0]LogShaderLibrary: Display: Cooked Context: Using Shared Shader Library Global +[2018.11.29-17.15.42:361][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: Global_SC and no native library supported. +[2018.11.29-17.15.42:361][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: AppleARKit and no native library supported. +[2018.11.29-17.15.42:361][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: AppleARKit_SC and no native library supported. +[2018.11.29-17.15.42:361][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: AppleARKit and no native library supported. +[2018.11.29-17.15.42:362][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: AppleARKit_SC and no native library supported. +[2018.11.29-17.15.42:362][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: AppleARKitFaceSupport and no native library supported. +[2018.11.29-17.15.42:362][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: AppleARKitFaceSupport_SC and no native library supported. +[2018.11.29-17.15.42:362][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: AppleARKitFaceSupport and no native library supported. +[2018.11.29-17.15.42:362][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: AppleARKitFaceSupport_SC and no native library supported. +[2018.11.29-17.15.42:362][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FortAppleARKitFaceSupport and no native library supported. +[2018.11.29-17.15.42:363][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FortAppleARKitFaceSupport_SC and no native library supported. +[2018.11.29-17.15.42:363][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FortAppleARKitFaceSupport and no native library supported. +[2018.11.29-17.15.42:363][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FortAppleARKitFaceSupport_SC and no native library supported. +[2018.11.29-17.15.42:363][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FacialAnimSystem and no native library supported. +[2018.11.29-17.15.42:363][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FacialAnimSystem_SC and no native library supported. +[2018.11.29-17.15.42:363][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FacialAnimSystem and no native library supported. +[2018.11.29-17.15.42:363][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FacialAnimSystem_SC and no native library supported. +[2018.11.29-17.15.42:364][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: BlueprintMaterialTextureNodes and no native library supported. +[2018.11.29-17.15.42:364][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: BlueprintMaterialTextureNodes_SC and no native library supported. +[2018.11.29-17.15.42:364][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: BlueprintMaterialTextureNodes and no native library supported. +[2018.11.29-17.15.42:364][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: BlueprintMaterialTextureNodes_SC and no native library supported. +[2018.11.29-17.15.42:364][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ControlRig and no native library supported. +[2018.11.29-17.15.42:364][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ControlRig_SC and no native library supported. +[2018.11.29-17.15.42:365][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ControlRig and no native library supported. +[2018.11.29-17.15.42:365][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ControlRig_SC and no native library supported. +[2018.11.29-17.15.42:365][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FortInstallBundleManager and no native library supported. +[2018.11.29-17.15.42:365][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FortInstallBundleManager_SC and no native library supported. +[2018.11.29-17.15.42:365][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FortInstallBundleManager and no native library supported. +[2018.11.29-17.15.42:365][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FortInstallBundleManager_SC and no native library supported. +[2018.11.29-17.15.42:365][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FortniteEarlyStartupPatcher and no native library supported. +[2018.11.29-17.15.42:366][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FortniteEarlyStartupPatcher_SC and no native library supported. +[2018.11.29-17.15.42:366][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FortniteEarlyStartupPatcher and no native library supported. +[2018.11.29-17.15.42:366][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FortniteEarlyStartupPatcher_SC and no native library supported. +[2018.11.29-17.15.42:366][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: GoogleARCore and no native library supported. +[2018.11.29-17.15.42:366][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: GoogleARCore_SC and no native library supported. +[2018.11.29-17.15.42:366][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: GoogleARCore and no native library supported. +[2018.11.29-17.15.42:367][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: GoogleARCore_SC and no native library supported. +[2018.11.29-17.15.42:367][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: GoogleARCoreServices and no native library supported. +[2018.11.29-17.15.42:367][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: GoogleARCoreServices_SC and no native library supported. +[2018.11.29-17.15.42:367][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: GoogleARCoreServices and no native library supported. +[2018.11.29-17.15.42:367][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: GoogleARCoreServices_SC and no native library supported. +[2018.11.29-17.15.42:367][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ImagePlate and no native library supported. +[2018.11.29-17.15.42:367][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ImagePlate_SC and no native library supported. +[2018.11.29-17.15.42:368][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ImagePlate and no native library supported. +[2018.11.29-17.15.42:368][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ImagePlate_SC and no native library supported. +[2018.11.29-17.15.42:368][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: NetUI and no native library supported. +[2018.11.29-17.15.42:368][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: NetUI_SC and no native library supported. +[2018.11.29-17.15.42:368][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: NetUI and no native library supported. +[2018.11.29-17.15.42:368][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: NetUI_SC and no native library supported. +[2018.11.29-17.15.42:368][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: Paper2D and no native library supported. +[2018.11.29-17.15.42:369][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: Paper2D_SC and no native library supported. +[2018.11.29-17.15.42:369][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: Paper2D and no native library supported. +[2018.11.29-17.15.42:369][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: Paper2D_SC and no native library supported. +[2018.11.29-17.15.42:369][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: PythonScriptPlugin and no native library supported. +[2018.11.29-17.15.42:369][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: PythonScriptPlugin_SC and no native library supported. +[2018.11.29-17.15.42:369][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: PythonScriptPlugin and no native library supported. +[2018.11.29-17.15.42:369][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: PythonScriptPlugin_SC and no native library supported. +[2018.11.29-17.15.42:369][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: Social and no native library supported. +[2018.11.29-17.15.42:369][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: Social_SC and no native library supported. +[2018.11.29-17.15.42:370][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: Social and no native library supported. +[2018.11.29-17.15.42:370][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: Social_SC and no native library supported. +[2018.11.29-17.15.42:370][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: SocialUMG and no native library supported. +[2018.11.29-17.15.42:370][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: SocialUMG_SC and no native library supported. +[2018.11.29-17.15.42:370][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: SocialUMG and no native library supported. +[2018.11.29-17.15.42:370][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: SocialUMG_SC and no native library supported. +[2018.11.29-17.15.42:370][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: SubtitlesWidgetsEditor and no native library supported. +[2018.11.29-17.15.42:370][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: SubtitlesWidgetsEditor_SC and no native library supported. +[2018.11.29-17.15.42:370][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: SubtitlesWidgetsEditor and no native library supported. +[2018.11.29-17.15.42:371][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: SubtitlesWidgetsEditor_SC and no native library supported. +[2018.11.29-17.15.42:371][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: TimeSynth and no native library supported. +[2018.11.29-17.15.42:371][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: TimeSynth_SC and no native library supported. +[2018.11.29-17.15.42:371][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: TimeSynth and no native library supported. +[2018.11.29-17.15.42:371][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: TimeSynth_SC and no native library supported. +[2018.11.29-17.15.42:371][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: KairosSceneCapture and no native library supported. +[2018.11.29-17.15.42:371][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: KairosSceneCapture_SC and no native library supported. +[2018.11.29-17.15.42:371][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: KairosSceneCapture and no native library supported. +[2018.11.29-17.15.42:371][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: KairosSceneCapture_SC and no native library supported. +[2018.11.29-17.15.42:372][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ApolloAR and no native library supported. +[2018.11.29-17.15.42:372][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ApolloAR_SC and no native library supported. +[2018.11.29-17.15.42:372][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ApolloAR and no native library supported. +[2018.11.29-17.15.42:372][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ApolloAR_SC and no native library supported. +[2018.11.29-17.15.42:372][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ARToolkit and no native library supported. +[2018.11.29-17.15.42:372][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ARToolkit_SC and no native library supported. +[2018.11.29-17.15.42:372][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ARToolkit and no native library supported. +[2018.11.29-17.15.42:372][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ARToolkit_SC and no native library supported. +[2018.11.29-17.15.42:372][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: EsportsCamera and no native library supported. +[2018.11.29-17.15.42:373][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: EsportsCamera_SC and no native library supported. +[2018.11.29-17.15.42:373][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: EsportsCamera and no native library supported. +[2018.11.29-17.15.42:373][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: EsportsCamera_SC and no native library supported. +[2018.11.29-17.15.42:373][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ScreenCapture and no native library supported. +[2018.11.29-17.15.42:373][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ScreenCapture_SC and no native library supported. +[2018.11.29-17.15.42:373][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ScreenCapture and no native library supported. +[2018.11.29-17.15.42:373][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ScreenCapture_SC and no native library supported. +[2018.11.29-17.15.42:373][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ZeusAR and no native library supported. +[2018.11.29-17.15.42:373][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ZeusAR_SC and no native library supported. +[2018.11.29-17.15.42:374][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ZeusAR and no native library supported. +[2018.11.29-17.15.42:374][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: ZeusAR_SC and no native library supported. +[2018.11.29-17.15.42:374][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: CryptoKeys and no native library supported. +[2018.11.29-17.15.42:374][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: CryptoKeys_SC and no native library supported. +[2018.11.29-17.15.42:374][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: CryptoKeys and no native library supported. +[2018.11.29-17.15.42:374][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: CryptoKeys_SC and no native library supported. +[2018.11.29-17.15.42:376][ 0]LogPakFile: New pak file ../../../FortniteGame/Content/Paks/pakchunk0-WindowsClient.pak added to pak precacher. +[2018.11.29-17.15.42:403][ 0]LogMaterial: Verifying Global Shaders for PCD3D_SM5 +[2018.11.29-17.15.42:427][ 0]LogSlate: Using FreeType 2.6.0 +[2018.11.29-17.15.42:427][ 0]LogSlate: SlateFontServices - WITH_FREETYPE: 1, WITH_HARFBUZZ: 1 +[2018.11.29-17.15.42:433][ 0]FortInstallBundleManager: Display: No Build Metadata, Assuming Bulk Build. +[2018.11.29-17.15.42:511][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Window'. Using FWindowStyle defaults instead. +[2018.11.29-17.15.42:511][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Window'. Using FWindowStyle defaults instead. +[2018.11.29-17.15.42:569][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Window'. Using FWindowStyle defaults instead. +[2018.11.29-17.15.42:596][ 0]LogShaderLibrary: Display: Using ../../../FortniteGame/Content/ShaderArchive-FortniteGame-PCD3D_SM5.ushaderbytecode for material shader code. Total 117809 unique shaders. +[2018.11.29-17.15.42:596][ 0]LogShaderLibrary: Display: Cooked Context: Using Shared Shader Library FortniteGame +[2018.11.29-17.15.42:596][ 0]LogShaderLibrary: Display: Failed to load Shared Shader Library: FortniteGame_SC and no native library supported. +[2018.11.29-17.15.42:596][ 0]LogRHI: Display: Opened pipeline cache after state change and enqueued 0 of 0 tasks for precompile. +[2018.11.29-17.15.42:596][ 0]LogRHI: Display: Failed to open default shader pipeline cache for FortniteGame using shader platform 0. +[2018.11.29-17.15.42:596][ 0]LogInit: Using OS detected language (en-US). +[2018.11.29-17.15.42:596][ 0]LogInit: Using OS detected locale (en-US). +[2018.11.29-17.15.42:605][ 0]LogTextLocalizationManager: No specific localization for 'en-US' exists, so the 'en' localization will be used. +[2018.11.29-17.15.42:778][ 0]LogTextLocalizationManager: Compacting localization data took 3.65ms +[2018.11.29-17.15.43:090][ 0]LogAssetRegistry: FAssetRegistry took 0.3113 seconds to start up +[2018.11.29-17.15.43:361][ 0]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.15.43:362][ 0]LogPackageLocalizationCache: Processed 27 localized package path(s) for 1 prioritized culture(s) in 0.000162 seconds +[2018.11.29-17.15.43:364][ 0]LogInit: Selected Device Profile: [WindowsClient] +[2018.11.29-17.15.43:401][ 0]LogNetVersion: FortniteGame 1.0.0, NetCL: 0, EngineNetVer: 6, GameNetVer: 0 (Checksum: 1108316383) +[2018.11.29-17.15.43:512][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.15.43:512][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.15.43:513][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.15.43:513][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.15.43:513][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.15.43:514][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.15.43:514][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.15.43:580][ 0]LogStats: UGameplayTagsManager::ConstructGameplayTagTree: ImportINI prefixes - 0.000 s +[2018.11.29-17.15.43:605][ 0]LogStats: UGameplayTagsManager::ConstructGameplayTagTree: Construct from data asset - 0.025 s +[2018.11.29-17.15.43:624][ 0]LogGameplayTags: Display: Loading Tag File: ../../../FortniteGame/Config/Tags/GamepadActionNameTags.ini +[2018.11.29-17.15.43:626][ 0]LogGameplayTags: Display: Loading Tag File: ../../../FortniteGame/Config/Tags/LootTags.ini +[2018.11.29-17.15.43:627][ 0]LogStats: UGameplayTagsManager::ConstructGameplayTagTree: ImportINI - 0.022 s +[2018.11.29-17.15.43:634][ 0]LogStats: UGameplayTagsManager::ConstructGameplayTagTree: Reconstruct NetIndex - 0.007 s +[2018.11.29-17.15.43:634][ 0]LogStats: UGameplayTagsManager::ConstructGameplayTagTree: GameplayTagTreeChangedEvent.Broadcast - 0.000 s +[2018.11.29-17.15.43:663][ 0]LogConsoleResponse: User settings scalability group: Mixed +[2018.11.29-17.15.43:675][ 0]ImportText(ScriptedBehaviors): Not enough closing parenthesis in: (ScriptName="MoveNorth", Actions=((Template="MoveTime", Params=("1.0", "0.0", "2")) +[2018.11.29-17.15.43:675][ 0]ImportText(ScriptedBehaviors): Not enough closing parenthesis in: (ScriptName="MoveSouth", Actions=((Template="MoveTime", Params=("-1.0", "0.0", "2")) +[2018.11.29-17.15.43:675][ 0]ImportText(ScriptedBehaviors): Not enough closing parenthesis in: (ScriptName="MoveEast", Actions=((Template="MoveTime", Params=("0.0", "1.0", "2")) +[2018.11.29-17.15.43:675][ 0]ImportText(ScriptedBehaviors): Not enough closing parenthesis in: (ScriptName="MoveWest", Actions=((Template="MoveTime", Params=("0.0", "-1.0", "2")) +[2018.11.29-17.15.43:675][ 0]ImportText(ScriptedBehaviors): Not enough closing parenthesis in: (ScriptName="MoveNE", Actions=((Template="MoveTime", Params=("0.8", "0.8", "2")) +[2018.11.29-17.15.43:675][ 0]ImportText(ScriptedBehaviors): Not enough closing parenthesis in: (ScriptName="MoveNW", Actions=((Template="MoveTime", Params=("0.8", "-0.8", "2")) +[2018.11.29-17.15.43:675][ 0]ImportText(ScriptedBehaviors): Not enough closing parenthesis in: (ScriptName="MoveSE", Actions=((Template="MoveTime", Params=("-0.8", "0.8", "2")) +[2018.11.29-17.15.43:675][ 0]ImportText(ScriptedBehaviors): Not enough closing parenthesis in: (ScriptName="MoveSW", Actions=((Template="MoveTime", Params=("-0.8", "-0.8", "2")) +[2018.11.29-17.15.43:683][ 0]LogFortSignificance: Display: Set AI budget to '8,16' +[2018.11.29-17.15.43:683][ 0]LogFortSignificance: Display: Set Athena Player Pawn budget to '5,10,10,75' +[2018.11.29-17.15.43:683][ 0]LogFortSignificance: Display: Set Athena SKVehicle budget to '3, 3, 100' +[2018.11.29-17.15.43:683][ 0]LogFortSignificance: Display: Set Athena Player Pawn URO rate to '0,1,2,3' +[2018.11.29-17.15.43:683][ 0]LogFortSignificance: Display: Set Athena Player Pawn URO interpolation to '1,1,1,1' +[2018.11.29-17.15.43:683][ 0]LogFortSignificance: Display: Set Athena Player SkelMeshMinLOD to '0,1,1,2' +[2018.11.29-17.15.43:683][ 0]LogFortSignificance: Display: Set bucket distances to '50,100,250,500' +[2018.11.29-17.15.43:690][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'CheckBox'. Using FCheckBoxStyle defaults instead. +[2018.11.29-17.15.43:690][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ComboBox'. Using FComboBoxStyle defaults instead. +[2018.11.29-17.15.43:690][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'TableView.Row'. Using FTableRowStyle defaults instead. +[2018.11.29-17.15.43:690][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.15.43:690][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableTextBox'. Using FEditableTextBoxStyle defaults instead. +[2018.11.29-17.15.43:690][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ExpandableArea'. Using FExpandableAreaStyle defaults instead. +[2018.11.29-17.15.43:690][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.15.43:691][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.15.43:691][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.15.43:691][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableTextBox'. Using FEditableTextBoxStyle defaults instead. +[2018.11.29-17.15.43:691][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.15.43:691][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.15.43:691][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.43:691][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.43:691][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.43:691][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'SpinBox'. Using FSpinBoxStyle defaults instead. +[2018.11.29-17.15.43:739][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.15.43:739][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.15.43:743][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.15.43:743][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.15.43:802][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.15.43:803][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.15.43:803][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.15.43:803][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.15.43:803][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.15.43:803][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.15.43:843][ 0]LogSlate: Took 0.001240 seconds to synchronously load lazily loaded font '../../../FortniteGame/Content/UI/Foundation/Fonts/BurbankBigRegular-Bold.ufont' (155K) +[2018.11.29-17.15.43:843][ 0]LogOnline: OSS: Using EpicApp backend 'DevLatest' with host 'fortnite-public-service-latest-gamedev.ol.epicgames.net' based on environment 'GameDev' and override 'DevLatest' +[2018.11.29-17.15.43:850][ 0]LogInit: Display: Build flavor: '"Western"' +[2018.11.29-17.15.43:919][ 0]LogAndroidPermission: UAndroidPermissionCallbackProxy::GetInstance +[2018.11.29-17.15.43:941][ 0]LogOnline: Facebook: Facebook Startup! +[2018.11.29-17.15.43:941][ 0]LogOnline: Google: Google Startup! +[2018.11.29-17.15.43:969][ 0]LogUAC: Finished RandomCrypto self check. +[2018.11.29-17.15.43:970][ 0]LogUAC: UACClient initialized +[2018.11.29-17.15.43:970][ 0]LogUAC: Finished StringCrypto self check. +[2018.11.29-17.15.44:002][ 0]LogKairos: Setting up Kairos delegate +[2018.11.29-17.15.44:029][ 0]LogUObjectArray: 96374 objects as part of root set at end of initial load. +[2018.11.29-17.15.44:029][ 0]LogUObjectArray: 3 objects are not in the root set, but can never be destroyed because they are in the DisregardForGC set. +[2018.11.29-17.15.44:029][ 0]LogUObjectAllocator: 17175848 out of 17825792 bytes used by permanent object pool. +[2018.11.29-17.15.44:029][ 0]LogUObjectArray: CloseDisregardForGC: 96374/96374 objects in disregard for GC pool +[2018.11.29-17.15.44:118][ 0]LogMoviePlayer: Warning: PassLoadingScreenWindowBackToGame failed. No Window +[2018.11.29-17.15.44:118][ 0]LogEngine: Initializing Engine... +[2018.11.29-17.15.44:131][ 0]LogInit: Display: Limiting process virtual memory size to 16777216 KB +[2018.11.29-17.15.44:157][ 0]LogFortMemory: UFortAssetManager default bundle state is (Client) +[2018.11.29-17.15.44:157][ 0]LogFort: Display: Fastcook is 0 +[2018.11.29-17.15.44:540][ 0]LogFort: Display: Startup job "InitializeAbilitySystem()" starting +[2018.11.29-17.15.44:851][ 0]LogPakFile: New pak file ../../../FortniteGame/Content/Paks/pakchunk10-WindowsClient.pak added to pak precacher. +[2018.11.29-17.15.44:851][ 0]LogFort: Display: Startup job "InitializeAbilitySystem()" took 0.31 seconds to complete +[2018.11.29-17.15.44:851][ 0]LogFort: Display: Startup job "ScanForNavAgentCostData()" starting +[2018.11.29-17.15.44:856][ 0]LogFort: Display: Startup job "ScanForNavAgentCostData()" took 0.00 seconds to complete +[2018.11.29-17.15.44:856][ 0]LogFort: Display: Startup job "GetGameData()" starting +[2018.11.29-17.15.44:856][ 0]LogFort: Loading GameData: /Game/Balance/DefaultGameData.DefaultGameData ... +[2018.11.29-17.15.51:216][ 0]LogPakFile: New pak file ../../../FortniteGame/Content/Paks/pakchunk10_s4-WindowsClient.pak added to pak precacher. +[2018.11.29-17.15.51:216][ 0]LogPakFile: New pak file ../../../FortniteGame/Content/Paks/pakchunk10_s2-WindowsClient.pak added to pak precacher. +[2018.11.29-17.15.51:216][ 0]LogPakFile: New pak file ../../../FortniteGame/Content/Paks/pakchunk10_s3-WindowsClient.pak added to pak precacher. +[2018.11.29-17.15.51:216][ 0]LogPakFile: New pak file ../../../FortniteGame/Content/Paks/pakchunk10_s1-WindowsClient.pak added to pak precacher. +[2018.11.29-17.15.51:216][ 0]LogPakFile: New pak file ../../../FortniteGame/Content/Paks/pakchunk1_s1-WindowsClient.pak added to pak precacher. +[2018.11.29-17.15.51:216][ 0]LogPakFile: New pak file ../../../FortniteGame/Content/Paks/pakchunk1-WindowsClient.pak added to pak precacher. +[2018.11.29-17.15.51:216][ 0]LogStreaming: Error: Couldn't find file for package /Game/Items/Datatables/LootQuotaData requested by async loading code. NameToLoad: /Game/Items/Datatables/LootQuotaData +[2018.11.29-17.15.51:216][ 0]LogStreaming: Error: This will hitch streaming because it ends up searching the disk instead of finding the file in the pak file. +[2018.11.29-17.15.51:216][ 0]LogStreaming: Error: Found 0 dependent packages... +[2018.11.29-17.15.51:216][ 0]LogPakFile: New pak file ../../../FortniteGame/Content/Paks/pakchunk1_s2-WindowsClient.pak added to pak precacher. +[2018.11.29-17.15.51:216][ 0]LogStreaming: Warning: FAsyncPackage::LoadImports for /Game/Effects/SplineTrails/Blueprints/BP_SplineVolumeTrail_v1b: Skipping import BoolProperty /Script/Engine.Texture:DeferCompression, depends on missing native class +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:216][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:217][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:218][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:218][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:218][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:218][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:218][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:218][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:218][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:218][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:218][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:218][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:218][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:219][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.15.51:219][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.15.51:219][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:219][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:219][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:219][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:219][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:219][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:219][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:219][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:219][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:219][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:219][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:220][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:220][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:220][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:220][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:220][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:220][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:220][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:220][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:220][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:220][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:220][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:220][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:221][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:221][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:221][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:221][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:221][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:221][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:221][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:221][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.15.51:221][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.15.51:221][ 0]LogConsoleResponse: User settings scalability group: Mixed +[2018.11.29-17.15.51:223][ 0]LogRHI: Display: Applied New ShaderPipelineCache GameUsageMask [Material=1 | Shadow=2 | Foliage=3] +[2018.11.29-17.15.52:773][ 0]LogStreaming: Warning: Took 1557.93ms to ProcessLoadedPackages +[2018.11.29-17.15.53:518][ 0]LogStreaming: Warning: Took 744.21ms to ProcessLoadedPackages +[2018.11.29-17.15.53:518][ 0]LogStats: ... GameData loaded! - 8.662 s +[2018.11.29-17.15.53:518][ 0]LogFort: Display: Startup job "GetGameData()" took 8.66 seconds to complete +[2018.11.29-17.15.53:518][ 0]LogFort: Display: Startup job "LoadHandle = PreloadStartupAssets()" starting +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:611][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:612][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableTextBox'. Using FEditableTextBoxStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableTextBox'. Using FEditableTextBoxStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:613][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:614][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:615][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:616][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:617][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableTextBox'. Using FEditableTextBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableTextBox'. Using FEditableTextBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:618][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Slider'. Using FSliderStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.02:619][ 0]LogBlueprint: Warning: USimpleConstructionScript::FixupRootNodeParentReferences() - Couldn't find native parent component 'Sprite' for 'Music Loop' in BlueprintGeneratedClass 'MinigameState_Generic_C' (it may have been removed) +[2018.11.29-17.16.02:774][ 0]LogStreaming: Warning: Took 675.18ms to ProcessLoadedPackages +[2018.11.29-17.16.07:846][ 0]LogStreaming: Warning: Took 5071.81ms to ProcessLoadedPackages +[2018.11.29-17.16.07:847][ 0]LogFort: Display: Startup job "LoadHandle = PreloadStartupAssets()" took 14.33 seconds to complete +[2018.11.29-17.16.07:847][ 0]LogFort: Display: Startup job "LoadHandle = PreloadStartupSubAssets()" starting +[2018.11.29-17.16.07:955][ 0]LogFort: Display: Startup job "LoadHandle = PreloadStartupSubAssets()" took 0.11 seconds to complete +[2018.11.29-17.16.07:955][ 0]LogFort: Display: Startup job "UFortGlobals::Get().LoadUIStyle()" starting +[2018.11.29-17.16.07:981][ 0]LogFort: Display: Startup job "UFortGlobals::Get().LoadUIStyle()" took 0.03 seconds to complete +[2018.11.29-17.16.07:981][ 0]LogFort: Display: All startup jobs took 23.44 seconds to complete +[2018.11.29-17.16.07:981][ 0]LogInit: Initializing FReadOnlyCVARCache +[2018.11.29-17.16.07:981][ 0]LogNetVersion: Set ProjectVersion to 1.0.0. Version Checksum will be recalculated on next use. +[2018.11.29-17.16.07:981][ 0]LogInit: Texture streaming: Enabled +[2018.11.29-17.16.08:045][ 0]LogFortMemory: UFortAssetManager::ChangeLoadState() changing bundle state to (Client, Menu) +[2018.11.29-17.16.08:187][ 0]LogRHI: Display: Applied New ShaderPipelineCache GameUsageMask [Material=1 | Shadow=2 | Foliage=3] +[2018.11.29-17.16.08:187][ 0]LogConsoleResponse: Display: Apply Settings: +[2018.11.29-17.16.08:187][ 0]LogRHI: Display: Applied New ShaderPipelineCache GameUsageMask [Material=1 | Shadow=2 | Foliage=3] +[2018.11.29-17.16.08:190][ 0]LogUMG: Display: Widget Class InvisibleCursorWidget_C - Loaded Fast Template. +[2018.11.29-17.16.08:190][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.08:190][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.08:190][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.08:191][ 0]LogSlate: Updating window title bar state: overlay mode, drag disabled, window buttons hidden, title bar hidden +[2018.11.29-17.16.08:191][ 0]LogFortMemory: --------------------- +[2018.11.29-17.16.08:191][ 0]LogFortMemory: UFortAssetManager::ChangeGameSubMode is changing mode from [NoMode] to Athena +[2018.11.29-17.16.08:193][ 0]LogFortMemory: UFortAssetManager::ChangeGameSubMode() changing bundle state to (Menu, Client, ClientAthena) +[2018.11.29-17.16.08:375][ 0]LogFortLoadingScreen: Fail to show loading screen when 'IsShowingInitialLoadingScreen()' is true. +[2018.11.29-17.16.08:375][ 0]LogFortLoadingScreen: World hasn't begun play +[2018.11.29-17.16.08:375][ 0]LogBlueprintContext: Display: Creating blueprint contexts for Local Player ' FortLocalPlayer_2147482238 ' of Game Instance ' FortGameInstance_2147482282 ' +[2018.11.29-17.16.08:376][ 0]LogBlueprintContext: Display: Created Blueprint Context 'HomeBaseContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:376][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortMcpContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:376][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortMusicContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:377][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortOutpostContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:377][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortPrototypingContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:377][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortReplayContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:377][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortToyContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:377][ 0]LogBlueprintContext: Display: Created Blueprint Context 'LocalServiceMessageContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:377][ 0]LogBlueprintContext: Display: Created Blueprint Context 'AthenaAccountContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:377][ 0]LogBlueprintContext: Display: Created Blueprint Context 'AthenaHUDContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:377][ 0]LogBlueprintContext: Display: Created Blueprint Context 'AthenaProfileStatContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:377][ 0]LogBlueprintContext: Display: Created Blueprint Context 'AthenaSpectatorUIContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:377][ 0]LogBlueprintContext: Display: Created Blueprint Context 'CMSContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:377][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortAbilitySystemContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:377][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortAccountStatsContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.08:377][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortHeroManagementContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.12:526][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortHomebaseUIContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.12:526][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortHUDContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.12:526][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortInventoryContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.12:526][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortLeaderboardContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.12:526][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortPickerContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.12:536][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortSettingsContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.12:536][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortStoreContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.12:536][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortTooltipUIContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.12:536][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortTutorialContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.12:536][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortUIDataConfigurationContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.12:536][ 0]LogBlueprintContext: Display: Created Blueprint Context 'HUDLayoutToolContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.12:536][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortMatchmakingContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.12:536][ 0]LogBlueprintContext: Display: Created Blueprint Context 'FortPartyContext' for Local Player 'FortLocalPlayer_2147482238' +[2018.11.29-17.16.12:536][ 0]LogAnalytics: Verbose: [Fortnite.DevLatest] Initializing ET Analytics provider +[2018.11.29-17.16.12:536][ 0]LogAnalytics: [Fortnite.DevLatest] APIServer = https://datarouter.ol.epicgames.com/. AppVersion = 1.0.0 - UE4-CL-0 +[2018.11.29-17.16.12:537][ 0]LogAnalytics: [Fortnite.DevLatest] SetUserId accb3c904505355102cf80b4f2cb03d3||e04d67a7-16cd-41f9-b939-be602538533a|fa55e3108f3fc66d6c4ff7eb4398e2a9| +[2018.11.29-17.16.12:537][ 0]LogAnalytics: [Fortnite.DevLatest] AnalyticsET::StartSession +[2018.11.29-17.16.12:538][ 0]LogFortChat: *!* UFortChatManager::InitializeChatManager - +[2018.11.29-17.16.12:540][ 0]LogInit: Display: Game Engine Initialized. +[2018.11.29-17.16.12:540][ 0]LogGauntlet: Display: Gauntlet Initialized +[2018.11.29-17.16.12:540][ 0]LogGameplayTags: Display: UGameplayTagsManager::DoneAddingNativeTags. DelegateIsBound: 1 +[2018.11.29-17.16.12:542][ 0]LogStats: UGameplayTagsManager::ConstructGameplayTagTree: ImportINI prefixes - 0.000 s +[2018.11.29-17.16.12:586][ 0]LogStats: UGameplayTagsManager::ConstructGameplayTagTree: Construct from data asset - 0.036 s +[2018.11.29-17.16.12:600][ 0]LogGameplayTags: Display: Loading Tag File: ../../../FortniteGame/Config/Tags/GamepadActionNameTags.ini +[2018.11.29-17.16.12:601][ 0]LogGameplayTags: Display: Loading Tag File: ../../../FortniteGame/Config/Tags/LootTags.ini +[2018.11.29-17.16.12:603][ 0]LogStats: UGameplayTagsManager::ConstructGameplayTagTree: ImportINI - 0.017 s +[2018.11.29-17.16.12:623][ 0]LogStats: UGameplayTagsManager::ConstructGameplayTagTree: Reconstruct NetIndex - 0.020 s +[2018.11.29-17.16.12:623][ 0]LogStats: UGameplayTagsManager::ConstructGameplayTagTree: GameplayTagTreeChangedEvent.Broadcast - 0.000 s +[2018.11.29-17.16.12:624][ 0]LogFortMemory: PostEngineInit - CPU:1286.26MB (Peak: 1795.54MB) +[2018.11.29-17.16.12:624][ 0]LogInit: Display: Starting Game. +[2018.11.29-17.16.12:624][ 0]LogHotfixManager: Display: Update State UpdateIdle -> UpdatePending +[2018.11.29-17.16.12:624][ 0]LogNet: Browse: /Game/Maps/Frontend?Name=Player +[2018.11.29-17.16.13:058][ 0]LogFortLoadingScreen: Fail to show loading screen when 'IsShowingInitialLoadingScreen()' is true. +[2018.11.29-17.16.13:058][ 0]LogFortLoadingScreen: bCurrentlyInLoadMap is true +[2018.11.29-17.16.13:081][ 0]LogLoad: LoadMap: /Game/Maps/Frontend?Name=Player +[2018.11.29-17.16.13:092][ 0]LogGarbage: Collecting garbage (GCheckForIllegalMarkPendingKill = 1) +[2018.11.29-17.16.13:106][ 0]LogGarbage: 13.060402 ms for Verify GC Assumptions +[2018.11.29-17.16.13:140][ 0]LogGarbage: 34.114991 ms for GC +[2018.11.29-17.16.13:140][ 0]LogGarbage: 0.390336 ms for Gather Unreachable Objects (72 objects collected including 0 cluster objects from 0 clusters) +[2018.11.29-17.16.13:141][ 0]LogGarbage: 0.193508 ms for unhashing unreachable objects. Items 72 (72/72) +[2018.11.29-17.16.13:147][ 0]LogGarbage: GC purged 72 objects (470800 -> 470728) +[2018.11.29-17.16.13:172][ 0]LogUObjectHash: Compacting FUObjectHashTables data took 24.78ms +[2018.11.29-17.16.14:527][ 0]LogStreaming: Display: /Game/Maps/Frontend is prestreaming /Game/Maps/FrontEnd/Maps/FrontEndStore +[2018.11.29-17.16.14:527][ 0]LogStreaming: Display: /Game/Maps/Frontend is prestreaming /Game/Maps/UI/Frontend_BG_Main +[2018.11.29-17.16.14:527][ 0]LogStreaming: Display: /Game/Maps/Frontend is prestreaming /Game/Maps/UI/Frontend_STW_Default +[2018.11.29-17.16.14:527][ 0]LogStreaming: Display: /Game/Maps/FrontEnd/Maps/FrontEndStore is prestreaming /Game/Maps/FrontEnd/Maps/FrontEndStore_Pinata +[2018.11.29-17.16.14:549][ 0]LogAIModule: Creating AISystem for world Frontend +[2018.11.29-17.16.14:549][ 0]LogLoad: Game class is 'FortGameModeFrontEnd' +[2018.11.29-17.16.14:550][ 0]LogLevelActorContainer: Created LevelActorCluster (0) for /Game/Maps/FrontEnd/Maps/FrontEndStore.FrontEndStore:PersistentLevel with 34 objects, 0 referenced clusters and 16 mutable objects. +[2018.11.29-17.16.14:551][ 0]LogLevelActorContainer: Created LevelActorCluster (1) for /Game/Maps/UI/Frontend_BG_Main.Frontend_BG_Main:PersistentLevel with 12 objects, 0 referenced clusters and 7 mutable objects. +[2018.11.29-17.16.14:551][ 0]LogLevelActorContainer: Created LevelActorCluster (2) for /Game/Maps/UI/Frontend_STW_Default.Frontend_STW_Default:PersistentLevel with 8 objects, 0 referenced clusters and 9 mutable objects. +[2018.11.29-17.16.14:555][ 0]LogLevelActorContainer: Created LevelActorCluster (3) for /Game/Maps/Frontend.Frontend:PersistentLevel with 6 objects, 0 referenced clusters and 3 mutable objects. +[2018.11.29-17.16.14:556][ 0]LogWorld: Bringing World /Game/Maps/Frontend.Frontend up for play (max tick rate 60) at 2018.11.29-12.16.14 +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_DefaultDuo (Server Only) +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_DefaultSolo (Server Only) +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_DefaultSquad (Server Only) +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_33 (Server Only) +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_50v50 (Server Only) +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_50v50HE (Server Only) +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_50v50SAU (Server Only) +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_50v50_Cube (Server Only) +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Disco (Server Only) +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Disco_32 (Server Only) +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Disco_32_Alt (Server Only) +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Disco_40 (Server Only) +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Disco_40_Alt (Server Only) +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Disco_Alt (Server Only) +[2018.11.29-17.16.14:732][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Seize (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Soaring_50s (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_5x20 (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Barrier (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Barrier_12 (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Barrier_Food (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Bling_Duos (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Bling_Solo (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Bling_Squads (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Bling_Winter_Duos (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Bling_Winter_Solo (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Bling_Winter_Squads (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Blitz_Duos (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Blitz_Solo (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Blitz_Squad (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Carmine (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Classic_Duos (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Classic_Solo (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Classic_Squads (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Comp_Blitz_Solo (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Comp_Meta_Solo (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Comp_Solo (Server Only) +[2018.11.29-17.16.14:733][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_CreativeTestIsland (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Deimos_50 (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Deimos_Duo (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Deimos_DuoCN (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Deimos_DuoShow (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Deimos_PlanB_Squad (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Deimos_Solo (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Deimos_SoloCN (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Deimos_SoloShow (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Deimos_Squad (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Deimos_SquadCN (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Deimos_SquadShow (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Deimos_Test_Solo (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Up_Duos (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Up_Solo (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Up_Squads (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Final_12 (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Final_20 (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Final_50 (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Fortnite (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Fortnite_B_Duos (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Fortnite_B_Solo (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Fortnite_B_Squads (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Gungame_Solo (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Ground_Duos (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Ground_Solo (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Ground_Squads (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Hard_Duos (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Hard_Solo (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Hard_Squad (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_FlyExplosives_Duos (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_FlyExplosives_Solo (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_FlyExplosives_Squads (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_HighExplosives_Solo (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_HighExplosives_Squads (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Impact_Duos (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Impact_Solo (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Impact_Squads (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Hard_Duos (Server Only) +[2018.11.29-17.16.14:734][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Hard_Solo (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Hard_Squad (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Playground (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Practice (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Respawn_24 (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Respawn_Duos (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Respawn_Solo (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Respawn_Squads (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Score_Duos (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Score_Solo (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Score_Squads (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Close_Duos (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Close_Solo (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Close_Squad (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_ShowdownAlt_Duos (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_ShowdownAlt_Solo (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_ShowdownAlt_Squads (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Showdown_Duos (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Showdown_Solo (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Showdown_Squads (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_SkySupply_Solo (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_SkySupply_Duos (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_SkySupply_Squads (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Slide_Duos (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Slide_Solo (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Slide_Squads (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Sneaky_Duos (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Sneaky_Solo (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Sneaky_Squads (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Snipers_Duos (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Snipers_Solo (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Snipers (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Soaring_Duos (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Soaring_Solo (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Soaring_Squads (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_SolidGold_Duos (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_SolidGold_Solo (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_SolidGold_Squads (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Stage_Squads (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Steady_Duos (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Steady_Solo (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Steady_Squads (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Taxes_Duos (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Taxes_Solo (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Taxes_Squads (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Test (Server Only) +[2018.11.29-17.16.14:735][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Trailers (Server Only) +[2018.11.29-17.16.14:736][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Trios (Server Only) +[2018.11.29-17.16.14:736][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Vamp_Duo (Server Only) +[2018.11.29-17.16.14:736][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Vamp_Solo (Server Only) +[2018.11.29-17.16.14:736][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Vamp_Squad (Server Only) +[2018.11.29-17.16.14:736][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Velocity_Duos (Server Only) +[2018.11.29-17.16.14:736][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Velocity_Solo (Server Only) +[2018.11.29-17.16.14:736][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_Velocity_Squads (Server Only) +[2018.11.29-17.16.14:736][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_WW_Duos (Server Only) +[2018.11.29-17.16.14:736][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_WW_Solo (Server Only) +[2018.11.29-17.16.14:736][ 0]LogFort: PLAYLIST: FortPlaylistManager::IntializePlaylists() Adding Playlist: Playlist_WW_Squads (Server Only) +[2018.11.29-17.16.14:736][ 0]LogOnlineGame: PLAYLIST: Serving ALL available playlists given to client from MCP! +[2018.11.29-17.16.14:736][ 0]LogOnlineGame: PLAYLIST: Excluding NO playlists given to client from MCP! +[2018.11.29-17.16.14:776][ 0]LogFortDayNight: AFortTimeOfDayManager::PostInitializeComponents: World is "Frontend", this is "TODM_Disabled_C_2147482001" +[2018.11.29-17.16.14:783][ 0]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] AnalyticsET URL:datarouter/api/v1/public/data?SessionID={058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}&AppID=Fortnite.DevLatest&AppVersion=1.0.0 - UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3||e04d67a7-16cd-41f9-b939-be602538533a|fa55e3108f3fc66d6c4ff7eb4398e2a9|&AppEnvironment=datacollector-binary&UploadType=eteventstream. Payload:{"Events":[{"EventName":"SessionStart","DateOffset":"+00:00:02.245","GameSessionID":"","Platform":"Windows","ProviderType":"Client","GameState":"","AttributionId":"","Platform":"Windows"},{"EventName":"Core.AppStartup","DateOffset":"+00:00:02.245","GameSessionID":"","Platform":"Windows","ProviderType":"Client","GameState":""},{"EventName":"Core.GameSessionIDChanged","DateOffset":"+00:00:00.000","GameSessionID":"FRONTEND-D82C7D9743CE4BB7F8846694F8B24119","Platform":"Windows","ProviderType":"Client","GameState":"","PreviousGameSessionID":""},{"EventName":"Core.GameStateClassNameChanged","DateOffset":"+00:00:00.000","GameSessionID":"FRONTEND-D82C7D9743CE4BB7F8846694F8B24119","Platform":"Windows","ProviderType":"Client","GameState":"FortGameStateFrontEnd","PreviousGameStateClassName":""}]} +[2018.11.29-17.16.14:783][ 0]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.14:783][ 0]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.14:783][ 0]LogHttp: Verbose: 00000231A5183580: URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7C%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.16.14:783][ 0]LogHttp: Verbose: 00000231A5183580: Verb='POST' +[2018.11.29-17.16.14:783][ 0]LogHttp: Verbose: 00000231A5183580: Custom headers are present +[2018.11.29-17.16.14:783][ 0]LogHttp: Verbose: 00000231A5183580: Payload size=796 +[2018.11.29-17.16.14:783][ 0]LogHttp: Verbose: 00000231A5183580: Adding header 'Content-Type: application/json; charset=utf-8' +[2018.11.29-17.16.14:783][ 0]LogHttp: Verbose: 00000231A5183580: Adding header 'User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.14:783][ 0]LogHttp: Verbose: 00000231A5183580: Adding header 'Content-Length: 796' +[2018.11.29-17.16.14:783][ 0]LogHttp: Verbose: 00000231A5183580: Adding header 'Expect: ' +[2018.11.29-17.16.14:783][ 0]LogHttp: 00000231A5183580: Starting POST request to URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7C%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.16.14:783][ 0]LogHttp: Verbose: 00000231A5183580: request (easy handle:00000231BFD15560) has been added to threaded queue for processing +[2018.11.29-17.16.14:784][ 0]LogFortDayNight: Game State in World Frontend is resetting. TimeOfDayManager is None. +[2018.11.29-17.16.14:784][ 0]LogWorld: Bringing up level for play took: 0.231444 +[2018.11.29-17.16.14:784][ 0]LogOnlineGame: Client adding GameAccountId/AuthTicket for local player to login url. FortGameOptions=[ASID={058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}?Platform=WIN?AnalyticsPlat=Windows?bIsFirstServerJoin=1] +[2018.11.29-17.16.14:785][ 0]LogOnlineGame: Server received AuthTicket from client for player: UniqueId:[INVALID] Platform=[WIN] Analytics=[Windows] +[2018.11.29-17.16.14:791][ 0]LogFort: Warning: GetOrInitializeHero called with invalid player info! +[2018.11.29-17.16.14:791][ 0]LogFort: Warning: GetOrInitializeHero called with invalid player info! +[2018.11.29-17.16.14:791][ 0]LogParty: Verbose: Failed to get persistent party leader +[2018.11.29-17.16.14:792][ 0]LogGameMode: Display: Match State Changed from EnteringMap to WaitingToStart +[2018.11.29-17.16.14:794][ 0]LogLevel: ActivateLevel /Game/Maps/FrontEnd/FortniteWorldMap 1 1 1 +[2018.11.29-17.16.14:794][ 0]LogFortDayNight: Day phase actor TODM_Disabled_C_2147482001 is setting itself as the day phase handler for the GameState on World Frontend. +[2018.11.29-17.16.14:794][ 0]LogFortDayNight: SetTimeOfDayManager: World is "Frontend", Old TimeOfDayManager: "None", New TimeOfDayManager: "TODM_Disabled_C_2147482001" +[2018.11.29-17.16.14:794][ 0]LogFortDayNight: SetupTimeOfDayCallbacks: World is "Frontend", FortTimeOfDayManager is "TODM_Disabled_C_2147482001" +[2018.11.29-17.16.14:794][ 0]LogFortMusic: Warning: Trying to assign a bank to a music manager that doesn't yet exist. +[2018.11.29-17.16.14:794][ 0]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] AnalyticsET URL:datarouter/api/v1/public/data?SessionID={058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}&AppID=Fortnite.DevLatest&AppVersion=1.0.0 - UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3||e04d67a7-16cd-41f9-b939-be602538533a|fa55e3108f3fc66d6c4ff7eb4398e2a9|&AppEnvironment=datacollector-binary&UploadType=eteventstream. Payload:{"Events":[{"EventName":"Core.GameStateClassNameChanged","DateOffset":"+00:00:00.000","GameSessionID":"FRONTEND-D82C7D9743CE4BB7F8846694F8B24119","Platform":"Windows","ProviderType":"Client","GameState":"FortGameStateFrontEnd-Athena","PreviousGameStateClassName":"FortGameStateFrontEnd"}]} +[2018.11.29-17.16.14:794][ 0]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.14:794][ 0]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.14:794][ 0]LogHttp: Verbose: 00000231A518BC80: URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7C%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.16.14:794][ 0]LogHttp: Verbose: 00000231A518BC80: Verb='POST' +[2018.11.29-17.16.14:794][ 0]LogHttp: Verbose: 00000231A518BC80: Custom headers are present +[2018.11.29-17.16.14:794][ 0]LogHttp: Verbose: 00000231A518BC80: Payload size=289 +[2018.11.29-17.16.14:795][ 0]LogHttp: Verbose: 00000231A518BC80: Adding header 'Content-Type: application/json; charset=utf-8' +[2018.11.29-17.16.14:795][ 0]LogHttp: Verbose: 00000231A518BC80: Adding header 'User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.14:795][ 0]LogHttp: Verbose: 00000231A518BC80: Adding header 'Content-Length: 289' +[2018.11.29-17.16.14:795][ 0]LogHttp: Verbose: 00000231A518BC80: Adding header 'Expect: ' +[2018.11.29-17.16.14:795][ 0]LogHttp: 00000231A518BC80: Starting POST request to URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7C%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.16.14:795][ 0]LogHttp: Verbose: 00000231A518BC80: request (easy handle:00000231F8455560) has been added to threaded queue for processing +[2018.11.29-17.16.14:795][ 0]LogConsoleResponse: Scalability mode 1 is now ACTIVE. +[2018.11.29-17.16.14:795][ 0]LogConsoleResponse: Scalability mode 1 applied as highest priority mode active. +[2018.11.29-17.16.14:795][ 0]LogGameState: Match State Changed from EnteringMap to WaitingToStart +[2018.11.29-17.16.14:795][ 0]LogHealthSnapshot: ======= Snapshot: Waiting to Start (FortGameStateFrontEnd) ======= +[2018.11.29-17.16.14:795][ 0]LogHealthSnapshot: Games Played: 0 +[2018.11.29-17.16.14:795][ 0]LogHealthSnapshot: CPU Memory: Used 1109.00MB, Peak 1109.00MB +[2018.11.29-17.16.14:795][ 0]LogHealthSnapshot: Physical Memory: Used 1635.39MB, Peak 1801.85MB +[2018.11.29-17.16.14:795][ 0]LogHealthSnapshot: ========================================================= +[2018.11.29-17.16.14:796][ 0]LogLoad: Took 1.714712 seconds to LoadMap(/Game/Maps/Frontend) +[2018.11.29-17.16.14:897][ 0]LogHttp: Verbose: 00000231A5183580: request (easy handle:00000231BFD15560) has started threaded processing +[2018.11.29-17.16.14:897][ 0]LogHttp: Verbose: 00000231A518BC80: request (easy handle:00000231F8455560) has started threaded processing +[2018.11.29-17.16.14:897][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'Found bundle for host datarouter.ol.epicgames.com: 0x231ecd0f340 [serially]' +[2018.11.29-17.16.14:897][ 0]LogHttp: VeryVerbose: 00000231A5183580: ' Trying 18.235.16.110...' +[2018.11.29-17.16.14:897][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'TCP_NODELAY set' +[2018.11.29-17.16.14:897][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'Hostname 'datarouter.ol.epicgames.com' was found in DNS cache' +[2018.11.29-17.16.14:897][ 0]LogHttp: VeryVerbose: 00000231A518BC80: ' Trying 18.235.16.110...' +[2018.11.29-17.16.14:897][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'TCP_NODELAY set' +[2018.11.29-17.16.14:897][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'Connected to datarouter.ol.epicgames.com (18.235.16.110) port 443 (#0)' +[2018.11.29-17.16.14:897][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'Connected to datarouter.ol.epicgames.com (18.235.16.110) port 443 (#1)' +[2018.11.29-17.16.14:897][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'ALPN, offering http/1.1' +[2018.11.29-17.16.14:897][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.14:897][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'TLSv1.2 (OUT), TLS header, Certificate Status (22):' +[2018.11.29-17.16.14:897][ 0]LogHttp: VeryVerbose: 00000231A5183580: Sent SSL data (5 bytes) +[2018.11.29-17.16.14:897][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.14:897][ 0]LogHttp: VeryVerbose: 00000231A5183580: Sent SSL data (512 bytes) +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'ALPN, offering http/1.1' +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'TLSv1.2 (OUT), TLS header, Certificate Status (22):' +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Sent SSL data (5 bytes) +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Sent SSL data (512 bytes) +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received SSL data (5 bytes) +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received SSL data (104 bytes) +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received SSL data (5 bytes) +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'TLSv1.2 (IN), TLS handshake, Certificate (11):' +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received SSL data (4568 bytes) +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received SSL data (5 bytes) +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'TLSv1.2 (IN), TLS handshake, Server key exchange (12):' +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received SSL data (333 bytes) +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received SSL data (5 bytes) +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'TLSv1.2 (IN), TLS handshake, Server finished (14):' +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received SSL data (4 bytes) +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: Sent SSL data (5 bytes) +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'TLSv1.2 (OUT), TLS handshake, Client key exchange (16):' +[2018.11.29-17.16.14:898][ 0]LogHttp: VeryVerbose: 00000231A5183580: Sent SSL data (70 bytes) +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A5183580: Sent SSL data (5 bytes) +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A5183580: Sent SSL data (1 bytes) +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A5183580: Sent SSL data (5 bytes) +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A5183580: Sent SSL data (16 bytes) +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received SSL data (5 bytes) +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received SSL data (104 bytes) +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received SSL data (5 bytes) +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'TLSv1.2 (IN), TLS handshake, Certificate (11):' +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received SSL data (4568 bytes) +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received SSL data (5 bytes) +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'TLSv1.2 (IN), TLS handshake, Server key exchange (12):' +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received SSL data (333 bytes) +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received SSL data (5 bytes) +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'TLSv1.2 (IN), TLS handshake, Server finished (14):' +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received SSL data (4 bytes) +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Sent SSL data (5 bytes) +[2018.11.29-17.16.14:899][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'TLSv1.2 (OUT), TLS handshake, Client key exchange (16):' +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Sent SSL data (70 bytes) +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Sent SSL data (5 bytes) +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Sent SSL data (1 bytes) +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Sent SSL data (5 bytes) +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Sent SSL data (16 bytes) +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received SSL data (5 bytes) +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received SSL data (1 bytes) +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received SSL data (5 bytes) +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received SSL data (16 bytes) +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'Server certificate:' +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A5183580: ' subject: CN=*.ol.epicgames.com' +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A5183580: ' start date: Mar 12 00:00:00 2018 GMT' +[2018.11.29-17.16.14:900][ 0]LogHttp: VeryVerbose: 00000231A5183580: ' expire date: Apr 12 12:00:00 2019 GMT' +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A5183580: ' subjectAltName: host "datarouter.ol.epicgames.com" matched cert's "*.ol.epicgames.com"' +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A5183580: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A5183580: ' SSL certificate verify ok.' +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A5183580: Sent SSL data (5 bytes) +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A5183580: Sent header (549 bytes) - POST /datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7C%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream HTTP/1.1Host: datarouter.ol.epicgames.comAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/json; charset=utf-8User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Length: 796 +[2018.11.29-17.16.14:901][ 0]LogHttp: Verbose: 00000231A5183580: UploadCallback: 796 bytes out of 796 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=796 (<-this will get returned from the callback)) +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A5183580: Sent SSL data (5 bytes) +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A5183580: Sent data (796 bytes) +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'We are completely uploaded and fine' +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received SSL data (5 bytes) +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received SSL data (1 bytes) +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received SSL data (5 bytes) +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received SSL data (16 bytes) +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.16.14:901][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'old SSL session ID is stale, removing' +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'Server certificate:' +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A518BC80: ' subject: CN=*.ol.epicgames.com' +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A518BC80: ' start date: Mar 12 00:00:00 2018 GMT' +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A518BC80: ' expire date: Apr 12 12:00:00 2019 GMT' +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A518BC80: ' subjectAltName: host "datarouter.ol.epicgames.com" matched cert's "*.ol.epicgames.com"' +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A518BC80: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A518BC80: ' SSL certificate verify ok.' +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Sent SSL data (5 bytes) +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Sent header (549 bytes) - POST /datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7C%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream HTTP/1.1Host: datarouter.ol.epicgames.comAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/json; charset=utf-8User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Length: 289 +[2018.11.29-17.16.14:902][ 0]LogHttp: Verbose: 00000231A518BC80: UploadCallback: 289 bytes out of 289 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=289 (<-this will get returned from the callback)) +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Sent SSL data (5 bytes) +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Sent data (289 bytes) +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'We are completely uploaded and fine' +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received SSL data (5 bytes) +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received header (25 bytes) +[2018.11.29-17.16.14:902][ 0]LogHttp: Verbose: 00000231A5183580: Received response header 'HTTP/1.1 204 No Content'. +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received header (37 bytes) +[2018.11.29-17.16.14:902][ 0]LogHttp: Verbose: 00000231A5183580: Received response header 'Date: Thu, 29 Nov 2018 17:16:14 GMT'. +[2018.11.29-17.16.14:902][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received header (24 bytes) +[2018.11.29-17.16.14:902][ 0]LogHttp: Verbose: 00000231A5183580: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.14:903][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received header (32 bytes) +[2018.11.29-17.16.14:903][ 0]LogHttp: Verbose: 00000231A5183580: Received response header 'Access-Control-Allow-Origin: *'. +[2018.11.29-17.16.14:903][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received header (61 bytes) +[2018.11.29-17.16.14:903][ 0]LogHttp: Verbose: 00000231A5183580: Received response header 'X-Epic-Correlation-ID: e32a42db-94c8-44ef-b5db-26b285da9efd'. +[2018.11.29-17.16.14:903][ 0]LogHttp: Verbose: 00000231A5183580: Received response header ''. +[2018.11.29-17.16.14:903][ 0]LogHttp: VeryVerbose: 00000231A5183580: Received header (2 bytes) +[2018.11.29-17.16.14:903][ 0]LogHttp: VeryVerbose: 00000231A5183580: 'Connection #0 to host datarouter.ol.epicgames.com left intact' +[2018.11.29-17.16.14:903][ 0]LogHttp: Verbose: Request 00000231A5183580 (easy handle:00000231BFD15560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.14:903][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received SSL data (5 bytes) +[2018.11.29-17.16.14:903][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received header (25 bytes) +[2018.11.29-17.16.14:903][ 0]LogHttp: Verbose: 00000231A518BC80: Received response header 'HTTP/1.1 204 No Content'. +[2018.11.29-17.16.14:903][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received header (37 bytes) +[2018.11.29-17.16.14:904][ 0]LogHttp: Verbose: 00000231A518BC80: Received response header 'Date: Thu, 29 Nov 2018 17:16:14 GMT'. +[2018.11.29-17.16.14:904][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received header (24 bytes) +[2018.11.29-17.16.14:904][ 0]LogHttp: Verbose: 00000231A518BC80: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.14:904][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received header (32 bytes) +[2018.11.29-17.16.14:904][ 0]LogHttp: Verbose: 00000231A518BC80: Received response header 'Access-Control-Allow-Origin: *'. +[2018.11.29-17.16.14:904][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received header (61 bytes) +[2018.11.29-17.16.14:904][ 0]LogHttp: Verbose: 00000231A518BC80: Received response header 'X-Epic-Correlation-ID: 9b4eb2ae-332d-4709-ae33-c7392a0e69a1'. +[2018.11.29-17.16.14:904][ 0]LogHttp: Verbose: 00000231A518BC80: Received response header ''. +[2018.11.29-17.16.14:904][ 0]LogHttp: VeryVerbose: 00000231A518BC80: Received header (2 bytes) +[2018.11.29-17.16.14:904][ 0]LogHttp: VeryVerbose: 00000231A518BC80: 'Connection #1 to host datarouter.ol.epicgames.com left intact' +[2018.11.29-17.16.14:904][ 0]LogHttp: Verbose: Request 00000231A518BC80 (easy handle:00000231F8455560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.14:906][ 0]LogFortMemory: InitComplete - CPU:1108.59MB (Peak: 1801.85MB) +[2018.11.29-17.16.14:906][ 0]LogLoad: (Engine Initialization) Total time: 35.44 seconds +[2018.11.29-17.16.14:959][ 0]LogCore: Display: Setting hang detector multiplier to 3.0000s. New hang duration: 90.0000s. New present duration: 0.0000s. +[2018.11.29-17.16.14:982][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.14:983][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.14:983][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.14:983][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.14:983][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.14:986][ 0]LogGarbage: Collecting garbage (GCheckForIllegalMarkPendingKill = 1) +[2018.11.29-17.16.14:998][ 0]LogGarbage: 12.189769 ms for Verify GC Assumptions +[2018.11.29-17.16.15:036][ 0]LogGarbage: 38.793286 ms for GC +[2018.11.29-17.16.15:037][ 0]LogGarbage: 0.557580 ms for Gather Unreachable Objects (7176 objects collected including 0 cluster objects from 0 clusters) +[2018.11.29-17.16.15:043][ 0]LogGarbage: 5.337911 ms for unhashing unreachable objects. Items 7176 (7176/7176) +[2018.11.29-17.16.15:206][ 0]LogGarbage: GC purged 7176 objects (486668 -> 479492) +[2018.11.29-17.16.15:241][ 0]LogUObjectHash: Compacting FUObjectHashTables data took 35.13ms +[2018.11.29-17.16.15:349][ 0]LogUMG: Display: Widget Class UIManager_C - Loaded Fast Template. +[2018.11.29-17.16.15:349][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:349][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:357][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:358][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:358][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:358][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:358][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:358][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:358][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:358][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:358][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:358][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:358][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:358][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:359][ 0]LogUMG: Display: Widget Class ArrowCursorWidget_C - Loaded Fast Template. +[2018.11.29-17.16.15:360][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:360][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:360][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:360][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:360][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:360][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:360][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:360][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:360][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:360][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:360][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:361][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:361][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:361][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:361][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:361][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:361][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:361][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:361][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:361][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:361][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:361][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:361][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:361][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:361][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.15:362][ 0]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.15:362][ 0]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:362][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:363][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:363][ 0]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.15:363][ 0]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.15:363][ 0]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.15:363][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:363][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:363][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:363][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:363][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:363][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:363][ 0]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.15:363][ 0]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.15:363][ 0]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.15:363][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:363][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:363][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:363][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:363][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:363][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:363][ 0]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.15:363][ 0]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.15:363][ 0]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.15:364][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:364][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:364][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:364][ 0]LogUMG: Display: Widget Class ConfirmationWindow_C - Loaded Fast Template. +[2018.11.29-17.16.15:364][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:364][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:365][ 0]LogUMG: Display: Widget Class ErrorWindow_C - Loaded Fast Template. +[2018.11.29-17.16.15:365][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:365][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:365][ 0]LogUMG: Display: Widget Class WebPurchase_C - Loaded Fast Template. +[2018.11.29-17.16.15:365][ 0]LogUMG: Display: Widget Class ProgressModalWidget_C - Loaded Fast Template. +[2018.11.29-17.16.15:366][ 0]LogUMG: Display: Widget Class BannerSelectionWidget_C - Loaded Fast Template. +[2018.11.29-17.16.15:366][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.15:368][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:368][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:368][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:368][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:368][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:369][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:369][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:369][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:369][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:369][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:369][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:369][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:369][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:369][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:369][ 0]LogUMG: Display: Widget Class FrontEndRewards_Widget_C - Loaded Fast Template. +[2018.11.29-17.16.15:369][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:369][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:370][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:370][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:370][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:370][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:370][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:371][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:372][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:372][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:372][ 0]LogUMG: Display: Widget Class DailyRewards_C - Loaded Fast Template. +[2018.11.29-17.16.15:372][ 0]LogUMG: Display: Widget Class PartyFinder_C - Loaded Fast Template. +[2018.11.29-17.16.15:372][ 0]LogUMG: Display: Widget Class MgmtTabsScreen_C - Loaded Fast Template. +[2018.11.29-17.16.15:372][ 0]LogUMG: Display: Widget Class ItemManagementScreen_C - Loaded Fast Template. +[2018.11.29-17.16.15:374][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.15:375][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:375][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:375][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:375][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:376][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:376][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:377][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:377][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:377][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:377][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:378][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:378][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:378][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:378][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:379][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:379][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:379][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:379][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:380][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:380][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:380][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:380][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:380][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:380][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:380][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:380][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:380][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:380][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:380][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:380][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:380][ 0]LogUMG: Display: Widget Class ItemTransform_C - Loaded Fast Template. +[2018.11.29-17.16.15:382][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:382][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:384][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:385][ 0]LogUMG: Display: Widget Class CollectionBookWidget_C - Loaded Fast Template. +[2018.11.29-17.16.15:387][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:387][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:388][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:388][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:388][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:388][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:388][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:388][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:388][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:388][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:388][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:388][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:390][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:390][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:398][ 0]LogContentStreaming: Texture pool size now 800 MB +[2018.11.29-17.16.15:402][ 0]LogSlate: Took 0.000675 seconds to synchronously load lazily loaded font '../../../FortniteGame/Content/UI/Foundation/Fonts/NotoSans-Bold.ufont' (445K) +[2018.11.29-17.16.15:405][ 0]LogSlate: Took 0.001077 seconds to synchronously load lazily loaded font '../../../FortniteGame/Content/UI/Foundation/Fonts/NotoSans-Regular.ufont' (445K) +[2018.11.29-17.16.15:419][ 0]LogStreaming: Display: Suspending async loading (1) +[2018.11.29-17.16.15:466][ 0]LogStreaming: Display: Resuming async loading (0) +[2018.11.29-17.16.15:467][ 0]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/Maps/FrontEnd/FortniteWorldMap) is flushing async loading +[2018.11.29-17.16.15:467][ 0]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.15:528][ 0]LogLevelActorContainer: Created LevelActorCluster (4) for /Game/Maps/FrontEnd/FortniteWorldMap.FortniteWorldMap:PersistentLevel with 16 objects, 0 referenced clusters and 12 mutable objects. +[2018.11.29-17.16.15:538][ 0]LogFortUI: Display: [UFortUIManagerWidget_NUI::NativeTick] change state to Login with current values CurrentState: Invalid and NextState: Invalid +[2018.11.29-17.16.15:538][ 0]LogFortUI: Display: [UFortUIManagerWidget_NUI::SetUIState] states from: Invalid to Login +[2018.11.29-17.16.15:538][ 0]LogUMG: Display: Widget Class LoginScreen_C - Loaded Fast Template. +[2018.11.29-17.16.15:539][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:539][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:539][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:539][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:539][ 0]LogFortUI: Display: [UFortUIManagerWidget_NUI::TransitionToNextState] Switching states from: Invalid to Login +[2018.11.29-17.16.15:539][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:539][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:539][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:539][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:540][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:540][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:540][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:540][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:540][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:540][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:540][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:540][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:540][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:540][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:540][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:540][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:540][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:540][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:541][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:541][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:541][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:541][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:541][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:541][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:541][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:541][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:541][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:541][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:541][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:542][ 0]LogFortUI: [UFortSplashScreenWidget] Enter BeginSplashScreenFlow +[2018.11.29-17.16.15:542][ 0]LogFortUI: [UFortSplashScreenWidget] Enter ShouldBypassSplashScreen +[2018.11.29-17.16.15:542][ 0]LogFortUI: [UFortSplashScreenWidget] Skip splash screen, -skiptitlescreen included +[2018.11.29-17.16.15:542][ 0]LogFortUI: [UFortUIStateWidget_Login] EndSplashScreenFlow +[2018.11.29-17.16.15:542][ 0]LogFortUI: [UFortUIStateWidget_Login] Start update check +[2018.11.29-17.16.15:542][ 0]LogUMG: Display: Widget Class StatusWidget_C - Loaded Fast Template. +[2018.11.29-17.16.15:542][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:542][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:542][ 0]LogCommonUI: Pushing StatusWidget_C_2147481839 into widget stack LoginFlowStack +[2018.11.29-17.16.15:543][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:543][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:543][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:543][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.15:543][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:543][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:543][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.15:543][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.15:543][ 0]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.15:543][ 0]LogCommonInput: Verbose: InternalPushActivatablePanel : Adding push for new activatable panel StatusWidget_C_2147481839: +[2018.11.29-17.16.15:543][ 0]LogCommonInput: Verbose: Input suspension: Started +[2018.11.29-17.16.15:543][ 0]LogCommonInput: Verbose: Begin StartNextOperation +[2018.11.29-17.16.15:543][ 0]LogCommonInput: Verbose: StartNextOperation: activatable panel pushed on stack for panel: StatusWidget_C_2147481839 +[2018.11.29-17.16.15:543][ 0]LogCommonInput: Verbose: StartNextOperation: begin intro for panel: StatusWidget_C_2147481839 +[2018.11.29-17.16.15:543][ 0]LogCommonInput: Verbose: OnPrePanelActivated: panel activated complete: StatusWidget_C_2147481839 +[2018.11.29-17.16.15:543][ 0]LogCommonInput: Verbose: Begin StartNextOperation +[2018.11.29-17.16.15:543][ 0]LogCommonInput: Verbose: StartNextOperation: Finished, Clearing pending ops +[2018.11.29-17.16.15:543][ 0]LogCommonUI: CommonWidgetStack: LoginFlowStack + StatusWidget_C_2147481839 +ActiveWidgetIndex: 0 +[2018.11.29-17.16.15:544][ 0]LogOnlineGame: Display: StartUpdateCheck initial update not complete +[2018.11.29-17.16.15:544][ 0]LogOnlineGame: Display: StartUpdateCheck starting update check +[2018.11.29-17.16.15:544][ 0]LogHotfixManager: Display: Update already in progress +[2018.11.29-17.16.15:551][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.15:551][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.15:551][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.15:551][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.15:551][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.15:551][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.15:551][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.15:551][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.15:551][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.15:551][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.15:551][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.15:551][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.15:551][ 1]LogHttp: 00000231A5183580: request has been successfully processed. URL: https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7C%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream, HTTP code: 204, content length: 0, actual payload size: 0 +[2018.11.29-17.16.15:551][ 1]LogHttp: Verbose: 00000231A5183580 Response Header Date: Thu, 29 Nov 2018 17:16:14 GMT +[2018.11.29-17.16.15:551][ 1]LogHttp: Verbose: 00000231A5183580 Response Header Connection: keep-alive +[2018.11.29-17.16.15:551][ 1]LogHttp: Verbose: 00000231A5183580 Response Header Access-Control-Allow-Origin: * +[2018.11.29-17.16.15:551][ 1]LogHttp: Verbose: 00000231A5183580 Response Header X-Epic-Correlation-ID: e32a42db-94c8-44ef-b5db-26b285da9efd +[2018.11.29-17.16.15:551][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.15:551][ 1]LogHttp: 00000231A518BC80: request has been successfully processed. URL: https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7C%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream, HTTP code: 204, content length: 0, actual payload size: 0 +[2018.11.29-17.16.15:551][ 1]LogHttp: Verbose: 00000231A518BC80 Response Header Date: Thu, 29 Nov 2018 17:16:14 GMT +[2018.11.29-17.16.15:552][ 1]LogHttp: Verbose: 00000231A518BC80 Response Header Connection: keep-alive +[2018.11.29-17.16.15:552][ 1]LogHttp: Verbose: 00000231A518BC80 Response Header Access-Control-Allow-Origin: * +[2018.11.29-17.16.15:552][ 1]LogHttp: Verbose: 00000231A518BC80 Response Header X-Epic-Correlation-ID: 9b4eb2ae-332d-4709-ae33-c7392a0e69a1 +[2018.11.29-17.16.15:552][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.15:553][ 1]FortClientBot: {"event": "StateChange", "oldstate": "ControllerInitialized", "newstate": "Idle", "bot": "Player", "timeinstate":0.417} +[2018.11.29-17.16.15:554][ 1]LogLevel: ActivateLevel /Game/Maps/FortniteTownmap 1 1 1 +[2018.11.29-17.16.15:554][ 1]LogHotfixManager: Display: Update State UpdatePending -> CheckingForPatch +[2018.11.29-17.16.15:554][ 1]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.15:554][ 1]LogOnlineIdentity: OSS: Sending User Privilege request. url=https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/v2/versioncheck/Windows?version=UE4-CL-0-Windows +[2018.11.29-17.16.15:556][ 1]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/Maps/FortniteTownmap) is flushing async loading +[2018.11.29-17.16.15:571][ 1]LogLevelActorContainer: Created LevelActorCluster (5) for /Game/Maps/FortniteTownmap.FortniteTownmap:PersistentLevel with 134 objects, 0 referenced clusters and 7 mutable objects. +[2018.11.29-17.16.15:579][ 1]LogRenderer: Reallocating scene render targets to support 1920x1200 Format 9 NumSamples 1 (Frame:1). +[2018.11.29-17.16.15:579][ 1]LogSlate: Took 0.000536 seconds to synchronously load lazily loaded font '../../../FortniteGame/Content/UI/Foundation/Fonts/BurbankBigCondensed-Black.ufont' (157K) +[2018.11.29-17.16.15:588][ 2]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.15:588][ 2]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.15:588][ 2]LogHttp: Verbose: 00000231A4924E80: URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/token' +[2018.11.29-17.16.15:588][ 2]LogHttp: Verbose: 00000231A4924E80: Verb='POST' +[2018.11.29-17.16.15:588][ 2]LogHttp: Verbose: 00000231A4924E80: Custom headers are present +[2018.11.29-17.16.15:588][ 2]LogHttp: Verbose: 00000231A4924E80: Payload size=44 +[2018.11.29-17.16.15:588][ 2]LogHttp: Verbose: 00000231A4924E80: Adding header 'X-Epic-Correlation-ID: FN-VrOJK__0okOJuuqJ0XZtsA' +[2018.11.29-17.16.15:589][ 2]LogHttp: Verbose: 00000231A4924E80: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.15:589][ 2]LogHttp: Verbose: 00000231A4924E80: Adding header 'Content-Type: application/x-www-form-urlencoded' +[2018.11.29-17.16.15:589][ 2]LogHttp: Verbose: 00000231A4924E80: Adding header 'Content-Length: 44' +[2018.11.29-17.16.15:589][ 2]LogHttp: Verbose: 00000231A4924E80: Adding header 'Expect: ' +[2018.11.29-17.16.15:589][ 2]LogHttp: 00000231A4924E80: Starting POST request to URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/token' +[2018.11.29-17.16.15:589][ 2]LogHttp: Verbose: 00000231A4924E80: request (easy handle:00000231936D5560) has been added to threaded queue for processing +[2018.11.29-17.16.15:589][ 2]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.15:589][ 2]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.15:589][ 2]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] ET response for [https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7C%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream]. Code: 204. Payload: +[2018.11.29-17.16.15:589][ 2]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.15:589][ 2]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.15:589][ 2]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] ET response for [https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7C%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream]. Code: 204. Payload: +[2018.11.29-17.16.15:591][ 2]LogLevel: ActivateLevel /Game/Maps/UI/Frontend_SkillTree 1 1 1 +[2018.11.29-17.16.15:592][ 2]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/Maps/UI/Frontend_SkillTree) is flushing async loading +[2018.11.29-17.16.15:592][ 2]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.15:597][ 2]LogHttp: Verbose: 00000231A4924E80: request (easy handle:00000231936D5560) has started threaded processing +[2018.11.29-17.16.15:598][ 2]LogLevelActorContainer: Created LevelActorCluster (6) for /Game/Maps/UI/Frontend_SkillTree.Frontend_SkillTree:PersistentLevel with 8 objects, 0 referenced clusters and 7 mutable objects. +[2018.11.29-17.16.15:599][ 3]LogRenderer: Warning: Gaussian DOF algorithm is deprecated and will be removed from deferred shading renderer. Consider using the Circle DOF method in post process settings. +[2018.11.29-17.16.15:605][ 3]LogHttp: VeryVerbose: 00000231A4924E80: ' Trying 10.40.238.51...' +[2018.11.29-17.16.15:605][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'TCP_NODELAY set' +[2018.11.29-17.16.15:612][ 3]LogLevel: ActivateLevel /Game/Maps/FrontEnd/Maps/FrontEndStore_Pinata 1 1 1 +[2018.11.29-17.16.15:612][ 3]LogCommonInput: Verbose: Input suspension: Stopped +[2018.11.29-17.16.15:612][ 3]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/Maps/FrontEnd/Maps/FrontEndStore_Pinata) is flushing async loading +[2018.11.29-17.16.15:613][ 3]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.16:013][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'Connected to account-public-service-gamedev.ol.epicgames.net (10.40.238.51) port 443 (#2)' +[2018.11.29-17.16.16:013][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'ALPN, offering http/1.1' +[2018.11.29-17.16.16:013][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.16:013][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'TLSv1.2 (OUT), TLS header, Certificate Status (22):' +[2018.11.29-17.16.16:013][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Sent SSL data (5 bytes) +[2018.11.29-17.16.16:013][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.16:013][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Sent SSL data (512 bytes) +[2018.11.29-17.16.16:013][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received SSL data (5 bytes) +[2018.11.29-17.16.16:013][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.16:013][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received SSL data (104 bytes) +[2018.11.29-17.16.16:013][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received SSL data (5 bytes) +[2018.11.29-17.16.16:013][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'TLSv1.2 (IN), TLS handshake, Certificate (11):' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received SSL data (4568 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received SSL data (5 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'TLSv1.2 (IN), TLS handshake, Server key exchange (12):' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received SSL data (333 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received SSL data (5 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'TLSv1.2 (IN), TLS handshake, Server finished (14):' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received SSL data (4 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Sent SSL data (5 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'TLSv1.2 (OUT), TLS handshake, Client key exchange (16):' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Sent SSL data (70 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Sent SSL data (5 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Sent SSL data (1 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Sent SSL data (5 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Sent SSL data (16 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received SSL data (5 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received SSL data (1 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received SSL data (5 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received SSL data (16 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'Server certificate:' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: ' subjectAltName: host "account-public-service-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: ' SSL certificate verify ok.' +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Sent SSL data (5 bytes) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Sent header (430 bytes) - POST /account/api/oauth/token HTTP/1.1Host: account-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-VrOJK__0okOJuuqJ0XZtsAUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Type: application/x-www-form-urlencodedAuthorization: basic ZWM2ODRiOGM2ODdmNDc5ZmFkZWEzY2IyYWQ4M2Y1YzY6MmNlY2JhMzJlNGIzNDFkMGI2NjkyOTg4YTBlMTM2YWY=Content-Length: 44 +[2018.11.29-17.16.16:014][ 3]LogHttp: Verbose: 00000231A4924E80: UploadCallback: 44 bytes out of 44 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=44 (<-this will get returned from the callback)) +[2018.11.29-17.16.16:014][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Sent SSL data (5 bytes) +[2018.11.29-17.16.16:015][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Sent data (44 bytes) +[2018.11.29-17.16.16:015][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'We are completely uploaded and fine' +[2018.11.29-17.16.16:015][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received SSL data (5 bytes) +[2018.11.29-17.16.16:015][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received header (17 bytes) +[2018.11.29-17.16.16:015][ 3]LogHttp: Verbose: 00000231A4924E80: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.16:015][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received header (37 bytes) +[2018.11.29-17.16.16:015][ 3]LogHttp: Verbose: 00000231A4924E80: Received response header 'Date: Thu, 29 Nov 2018 17:16:15 GMT'. +[2018.11.29-17.16.16:015][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received header (32 bytes) +[2018.11.29-17.16.16:015][ 3]LogHttp: Verbose: 00000231A4924E80: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.16:015][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received header (22 bytes) +[2018.11.29-17.16.16:015][ 3]LogHttp: Verbose: 00000231A4924E80: Received response header 'Content-Length: 1050'. +[2018.11.29-17.16.16:015][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received header (24 bytes) +[2018.11.29-17.16.16:015][ 3]LogHttp: Verbose: 00000231A4924E80: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.16:015][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received header (49 bytes) +[2018.11.29-17.16.16:015][ 3]LogHttp: Verbose: 00000231A4924E80: Received response header 'Cache-Control: no-cache, no-store, no-transform'. +[2018.11.29-17.16.16:015][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received header (50 bytes) +[2018.11.29-17.16.16:015][ 3]LogHttp: Verbose: 00000231A4924E80: Received response header 'X-Epic-Correlation-ID: FN-VrOJK__0okOJuuqJ0XZtsA'. +[2018.11.29-17.16.16:015][ 3]LogHttp: Verbose: 00000231A4924E80: Received response header ''. +[2018.11.29-17.16.16:015][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received header (2 bytes) +[2018.11.29-17.16.16:015][ 3]LogHttp: VeryVerbose: 00000231A4924E80: Received data (1050 bytes) +[2018.11.29-17.16.16:015][ 3]LogHttp: Verbose: 00000231A4924E80: ReceiveResponseBodyCallback: 1050 bytes out of 1050 received. (SizeInBlocks=1, BlockSizeInBytes=1050, Response->TotalBytesRead=0, Response->GetContentLength()=1050, SizeToDownload=1050 (<-this will get returned from the callback)) +[2018.11.29-17.16.16:015][ 3]LogHttp: VeryVerbose: 00000231A4924E80: 'Connection #2 to host account-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.16:015][ 3]LogHttp: Verbose: Request 00000231A4924E80 (easy handle:00000231936D5560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.16:030][ 3]LogUMG: Display: Widget Class StoreItemCardFront_C - Loaded Fast Template. +[2018.11.29-17.16.16:030][ 3]LogUMG: Display: Widget Class ChoiceCardCount_C - Loaded Fast Template. +[2018.11.29-17.16.16:031][ 3]LogUMG: Display: Widget Class ChoiceCardName_C - Loaded Fast Template. +[2018.11.29-17.16.16:035][ 4]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.16:035][ 4]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.16:035][ 4]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:035][ 4]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:035][ 4]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:035][ 4]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:035][ 4]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:035][ 4]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:035][ 4]LogHttp: 00000231A4924E80: request has been successfully processed. URL: https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/token, HTTP code: 200, content length: 1050, actual payload size: 1050 +[2018.11.29-17.16.16:035][ 4]LogHttp: Verbose: 00000231A4924E80 Response Header Date: Thu, 29 Nov 2018 17:16:15 GMT +[2018.11.29-17.16.16:035][ 4]LogHttp: Verbose: 00000231A4924E80 Response Header Content-Type: application/json +[2018.11.29-17.16.16:035][ 4]LogHttp: Verbose: 00000231A4924E80 Response Header Content-Length: 1050 +[2018.11.29-17.16.16:035][ 4]LogHttp: Verbose: 00000231A4924E80 Response Header Connection: keep-alive +[2018.11.29-17.16.16:035][ 4]LogHttp: Verbose: 00000231A4924E80 Response Header Cache-Control: no-cache, no-store, no-transform +[2018.11.29-17.16.16:035][ 4]LogHttp: Verbose: 00000231A4924E80 Response Header X-Epic-Correlation-ID: FN-VrOJK__0okOJuuqJ0XZtsA +[2018.11.29-17.16.16:035][ 4]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.16:036][ 4]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:036][ 4]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.16:036][ 4]LogOnline: MCP: Service status updated [Normal] -> [Connected] +[2018.11.29-17.16.16:036][ 4]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.16:036][ 4]LogHttp: Verbose: 00000231A492E480: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/v2/versioncheck/Windows?version=UE4-CL-0-Windows' +[2018.11.29-17.16.16:036][ 4]LogHttp: Verbose: 00000231A492E480: Verb='GET' +[2018.11.29-17.16.16:037][ 4]LogHttp: Verbose: 00000231A492E480: Custom headers are present +[2018.11.29-17.16.16:037][ 4]LogHttp: Verbose: 00000231A492E480: Payload size=0 +[2018.11.29-17.16.16:037][ 4]LogHttp: Verbose: 00000231A492E480: Adding header 'X-Epic-Correlation-ID: FN-xI0e52IvpU_vcWI5Upu93w' +[2018.11.29-17.16.16:037][ 4]LogHttp: Verbose: 00000231A492E480: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.16:037][ 4]LogHttp: Verbose: 00000231A492E480: Adding header 'Content-Type: application/x-www-form-urlencoded' +[2018.11.29-17.16.16:037][ 4]LogHttp: Verbose: 00000231A492E480: Adding header 'Content-Length: 0' +[2018.11.29-17.16.16:037][ 4]LogHttp: Verbose: 00000231A492E480: Adding header 'Expect: ' +[2018.11.29-17.16.16:037][ 4]LogHttp: 00000231A492E480: Starting GET request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/v2/versioncheck/Windows?version=UE4-CL-0-Windows' +[2018.11.29-17.16.16:037][ 4]LogHttp: Verbose: 00000231A492E480: request (easy handle:00000231E78B5560) has been added to threaded queue for processing +[2018.11.29-17.16.16:039][ 4]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.16:039][ 4]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Window'. Using FWindowStyle defaults instead. +[2018.11.29-17.16.16:040][ 4]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.16:040][ 4]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Window'. Using FWindowStyle defaults instead. +[2018.11.29-17.16.16:040][ 4]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.16:040][ 4]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Window'. Using FWindowStyle defaults instead. +[2018.11.29-17.16.16:040][ 4]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.16:040][ 4]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Window'. Using FWindowStyle defaults instead. +[2018.11.29-17.16.16:040][ 4]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.16:040][ 4]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Window'. Using FWindowStyle defaults instead. +[2018.11.29-17.16.16:040][ 4]LogLevel: ActivateLevel /Game/Maps/UI/Frontend_Manage 1 1 1 +[2018.11.29-17.16.16:041][ 4]LogHttp: Verbose: 00000231A492E480: request (easy handle:00000231E78B5560) has started threaded processing +[2018.11.29-17.16.16:041][ 4]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/Maps/UI/Frontend_Manage) is flushing async loading +[2018.11.29-17.16.16:041][ 4]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: ' Trying 10.40.132.204...' +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'TCP_NODELAY set' +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#3)' +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'ALPN, offering http/1.1' +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'TLSv1.2 (OUT), TLS header, Certificate Status (22):' +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: Sent SSL data (5 bytes) +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: Sent SSL data (512 bytes) +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received SSL data (5 bytes) +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received SSL data (89 bytes) +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received SSL data (5 bytes) +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'TLSv1.2 (IN), TLS handshake, Certificate (11):' +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received SSL data (4568 bytes) +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received SSL data (5 bytes) +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'TLSv1.2 (IN), TLS handshake, Server key exchange (12):' +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received SSL data (333 bytes) +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received SSL data (5 bytes) +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'TLSv1.2 (IN), TLS handshake, Server finished (14):' +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received SSL data (4 bytes) +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: Sent SSL data (5 bytes) +[2018.11.29-17.16.16:383][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'TLSv1.2 (OUT), TLS handshake, Client key exchange (16):' +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: Sent SSL data (70 bytes) +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: Sent SSL data (5 bytes) +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: Sent SSL data (1 bytes) +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: Sent SSL data (5 bytes) +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: Sent SSL data (16 bytes) +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received SSL data (5 bytes) +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received SSL data (1 bytes) +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received SSL data (5 bytes) +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received SSL data (16 bytes) +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'ALPN, server did not agree to a protocol' +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'Server certificate:' +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: ' subjectAltName: host "fortnite-public-service-latest-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: ' SSL certificate verify ok.' +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: Sent SSL data (5 bytes) +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: Sent header (1023 bytes) - GET /fortnite/api/v2/versioncheck/Windows?version=UE4-CL-0-Windows HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-xI0e52IvpU_vcWI5Upu93wUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Type: application/x-www-form-urlencodedAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJwIjoiZU5wMVVFRnV3ekFNKzgrUVN3dDBCd0YrUzZBNmRDTFVzUUpMeVpiZnp4MldiSWZ1UmxFQ1NkRTBDbWR5OEd4VWpGSUo3eDNXekY0NVBxU01aQk5YRE5RWW1QTllnUm5GdzdXTDdKejFQTkNVVUszeFNhc1hjZEFCK3FvWk5HQkQxZ1cxanhQWUxWeHVIY2VvYTNGYTFudVdTRDlqdUhTY2ttUnBsdWZxSUpxQm9XNFNJYVhsS2ZISnZBcGNZWXNXd3lUbVd2ZDJkYmdwcno0UlByM1wvQmg4WWVRWlZsdHdiekVSTDd4SWY4SEQ3ZlNabVhZZW5FbzhnMjgweDA5c1wvMW1kTDkzMXJuVFRCdjdXOFVBclhMM25jbHl3PSIsImNsc3ZjIjoiZm9ydG5pdGUiLCJ0IjoicyIsImNsaWQiOiJlYzY4NGI4YzY4N2Y0NzlmYWRlYTNjYjJhZDgzZjVjNiIsImljIjp0cnVlLCJleHAiOjE1NDM1MjYxNzUsImFtIjoiY2xpZW50X2NyZWRlbnRpYWxzIiwiaWF0 +[2018.11.29-17.16.16:384][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received SSL data (5 bytes) +[2018.11.29-17.16.16:385][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received header (17 bytes) +[2018.11.29-17.16.16:385][ 4]LogHttp: Verbose: 00000231A492E480: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.16:385][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received header (32 bytes) +[2018.11.29-17.16.16:385][ 4]LogHttp: Verbose: 00000231A492E480: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.16:385][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received header (37 bytes) +[2018.11.29-17.16.16:385][ 4]LogHttp: Verbose: 00000231A492E480: Received response header 'Date: Thu, 29 Nov 2018 17:16:16 GMT'. +[2018.11.29-17.16.16:385][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received header (31 bytes) +[2018.11.29-17.16.16:385][ 4]LogHttp: Verbose: 00000231A492E480: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.16:385][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received header (50 bytes) +[2018.11.29-17.16.16:385][ 4]LogHttp: Verbose: 00000231A492E480: Received response header 'X-Epic-Correlation-ID: FN-xI0e52IvpU_vcWI5Upu93w'. +[2018.11.29-17.16.16:385][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received header (75 bytes) +[2018.11.29-17.16.16:385][ 4]LogHttp: Verbose: 00000231A492E480: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.16:385][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received header (20 bytes) +[2018.11.29-17.16.16:385][ 4]LogHttp: Verbose: 00000231A492E480: Received response header 'Content-Length: 22'. +[2018.11.29-17.16.16:385][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received header (24 bytes) +[2018.11.29-17.16.16:385][ 4]LogHttp: Verbose: 00000231A492E480: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.16:385][ 4]LogHttp: Verbose: 00000231A492E480: Received response header ''. +[2018.11.29-17.16.16:385][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received header (2 bytes) +[2018.11.29-17.16.16:385][ 4]LogHttp: VeryVerbose: 00000231A492E480: Received data (22 bytes) +[2018.11.29-17.16.16:385][ 4]LogHttp: Verbose: 00000231A492E480: ReceiveResponseBodyCallback: 22 bytes out of 22 received. (SizeInBlocks=1, BlockSizeInBytes=22, Response->TotalBytesRead=0, Response->GetContentLength()=22, SizeToDownload=22 (<-this will get returned from the callback)) +[2018.11.29-17.16.16:385][ 4]LogHttp: VeryVerbose: 00000231A492E480: 'Connection #3 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.16:385][ 4]LogHttp: Verbose: Request 00000231A492E480 (easy handle:00000231E78B5560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.16:398][ 4]LogLevelActorContainer: Created LevelActorCluster (7) for /Game/Maps/UI/Frontend_Manage.Frontend_Manage:PersistentLevel with 444 objects, 0 referenced clusters and 84 mutable objects. +[2018.11.29-17.16.16:406][ 5]LogGauntlet: Display: Changed state to Gauntlet_FrontEnd +[2018.11.29-17.16.16:406][ 5]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.16:406][ 5]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.16:406][ 5]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:406][ 5]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:406][ 5]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:406][ 5]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:406][ 5]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:406][ 5]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:406][ 5]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:406][ 5]LogHttp: 00000231A492E480: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/v2/versioncheck/Windows?version=UE4-CL-0-Windows, HTTP code: 200, content length: 22, actual payload size: 22 +[2018.11.29-17.16.16:406][ 5]LogHttp: Verbose: 00000231A492E480 Response Header Content-Type: application/json +[2018.11.29-17.16.16:406][ 5]LogHttp: Verbose: 00000231A492E480 Response Header Date: Thu, 29 Nov 2018 17:16:16 GMT +[2018.11.29-17.16.16:406][ 5]LogHttp: Verbose: 00000231A492E480 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.16:406][ 5]LogHttp: Verbose: 00000231A492E480 Response Header X-Epic-Correlation-ID: FN-xI0e52IvpU_vcWI5Upu93w +[2018.11.29-17.16.16:406][ 5]LogHttp: Verbose: 00000231A492E480 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.16:406][ 5]LogHttp: Verbose: 00000231A492E480 Response Header Content-Length: 22 +[2018.11.29-17.16.16:406][ 5]LogHttp: Verbose: 00000231A492E480 Response Header Connection: keep-alive +[2018.11.29-17.16.16:406][ 5]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.16:407][ 5]LogLevel: ActivateLevel /Game/Maps/UI/Frontend_Research 1 1 1 +[2018.11.29-17.16.16:408][ 5]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.16:484][ 5]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/Maps/UI/Frontend_Research) is flushing async loading +[2018.11.29-17.16.16:660][ 5]LogLevelActorContainer: Created LevelActorCluster (8) for /Game/Maps/UI/Frontend_Research.Frontend_Research:PersistentLevel with 78 objects, 0 referenced clusters and 24 mutable objects. +[2018.11.29-17.16.16:669][ 6]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:669][ 6]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.16:669][ 6]LogHotfixManager: Verbose: [OnCheckForPatchComplete] Privilege=1 PrivilegeResult=0 +[2018.11.29-17.16.16:669][ 6]LogHotfixManager: Display: Update State CheckingForPatch -> CheckingForHotfix +[2018.11.29-17.16.16:669][ 6]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.16:669][ 6]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.16:669][ 6]LogHttp: Verbose: 00000231A20145C0: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/cloudstorage/system' +[2018.11.29-17.16.16:669][ 6]LogHttp: Verbose: 00000231A20145C0: Verb='GET' +[2018.11.29-17.16.16:669][ 6]LogHttp: Verbose: 00000231A20145C0: Custom headers are present +[2018.11.29-17.16.16:669][ 6]LogHttp: Verbose: 00000231A20145C0: Payload size=0 +[2018.11.29-17.16.16:669][ 6]LogHttp: Verbose: 00000231A20145C0: Adding header 'X-Epic-Correlation-ID: FN-2hZqN3ITjUe1SX_CM6NDww' +[2018.11.29-17.16.16:669][ 6]LogHttp: Verbose: 00000231A20145C0: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.16:669][ 6]LogHttp: Verbose: 00000231A20145C0: Adding header 'Content-Length: 0' +[2018.11.29-17.16.16:669][ 6]LogHttp: Verbose: 00000231A20145C0: Adding header 'Expect: ' +[2018.11.29-17.16.16:670][ 6]LogHttp: 00000231A20145C0: Starting GET request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/cloudstorage/system' +[2018.11.29-17.16.16:670][ 6]LogHttp: Verbose: 00000231A20145C0: request (easy handle:00000231B1DF5560) has been added to threaded queue for processing +[2018.11.29-17.16.16:672][ 6]LogLevel: ActivateLevel /Game/Maps/UI/Frontend_Upgrades 1 1 1 +[2018.11.29-17.16.16:673][ 6]LogHttp: Verbose: 00000231A20145C0: request (easy handle:00000231B1DF5560) has started threaded processing +[2018.11.29-17.16.16:673][ 6]LogHttp: VeryVerbose: 00000231A20145C0: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.16:673][ 6]LogHttp: VeryVerbose: 00000231A20145C0: 'Re-using existing connection! (#3) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.16:673][ 6]LogHttp: VeryVerbose: 00000231A20145C0: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#3)' +[2018.11.29-17.16.16:673][ 6]LogHttp: VeryVerbose: 00000231A20145C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.16:673][ 6]LogHttp: VeryVerbose: 00000231A20145C0: Sent header (1023 bytes) - GET /fortnite/api/cloudstorage/system HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-2hZqN3ITjUe1SX_CM6NDwwUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJwIjoiZU5wMVVFRnV3ekFNKzgrUVN3dDBCd0YrUzZBNmRDTFVzUUpMeVpiZnp4MldiSWZ1UmxFQ1NkRTBDbWR5OEd4VWpGSUo3eDNXekY0NVBxU01aQk5YRE5RWW1QTllnUm5GdzdXTDdKejFQTkNVVUszeFNhc1hjZEFCK3FvWk5HQkQxZ1cxanhQWUxWeHVIY2VvYTNGYTFudVdTRDlqdUhTY2ttUnBsdWZxSUpxQm9XNFNJYVhsS2ZISnZBcGNZWXNXd3lUbVd2ZDJkYmdwcno0UlByM1wvQmg4WWVRWlZsdHdiekVSTDd4SWY4SEQ3ZlNabVhZZW5FbzhnMjgweDA5c1wvMW1kTDkzMXJuVFRCdjdXOFVBclhMM25jbHl3PSIsImNsc3ZjIjoiZm9ydG5pdGUiLCJ0IjoicyIsImNsaWQiOiJlYzY4NGI4YzY4N2Y0NzlmYWRlYTNjYjJhZDgzZjVjNiIsImljIjp0cnVlLCJleHAiOjE1NDM1MjYxNzUsImFtIjoiY2xpZW50X2NyZWRlbnRpYWxzIiwiaWF0IjoxNTQzNTExNzc1LCJqdGkiOiIzZmIyMjIzZDdiNjE0NDdiOGQ1OGJkMWQ5ODRhYTI3NSJ9.AljgE +[2018.11.29-17.16.16:673][ 6]LogFort: Display: [FortCustomizationAssetLoader CP_Head_M_Sensei] Finished loading. 4 assets loaded. +[2018.11.29-17.16.16:673][ 6]LogFort: Display: [FortCustomizationAssetLoader CP_Head_M_Director] Finished loading. 3 assets loaded. +[2018.11.29-17.16.16:673][ 6]LogFort: Display: [FortCustomizationAssetLoader CP_Head_F_Weaponsmith] Finished loading. 5 assets loaded. +[2018.11.29-17.16.16:674][ 6]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/Maps/UI/Frontend_Upgrades) is flushing async loading +[2018.11.29-17.16.16:674][ 6]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.16:744][ 6]LogHttp: VeryVerbose: 00000231A20145C0: Received SSL data (5 bytes) +[2018.11.29-17.16.16:744][ 6]LogHttp: VeryVerbose: 00000231A20145C0: Received header (17 bytes) +[2018.11.29-17.16.16:744][ 6]LogHttp: Verbose: 00000231A20145C0: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.16:744][ 6]LogHttp: VeryVerbose: 00000231A20145C0: Received header (32 bytes) +[2018.11.29-17.16.16:744][ 6]LogHttp: Verbose: 00000231A20145C0: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.16:744][ 6]LogHttp: VeryVerbose: 00000231A20145C0: Received header (37 bytes) +[2018.11.29-17.16.16:744][ 6]LogHttp: Verbose: 00000231A20145C0: Received response header 'Date: Thu, 29 Nov 2018 17:16:16 GMT'. +[2018.11.29-17.16.16:744][ 6]LogHttp: VeryVerbose: 00000231A20145C0: Received header (31 bytes) +[2018.11.29-17.16.16:744][ 6]LogHttp: Verbose: 00000231A20145C0: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.16:744][ 6]LogHttp: VeryVerbose: 00000231A20145C0: Received header (50 bytes) +[2018.11.29-17.16.16:744][ 6]LogHttp: Verbose: 00000231A20145C0: Received response header 'X-Epic-Correlation-ID: FN-2hZqN3ITjUe1SX_CM6NDww'. +[2018.11.29-17.16.16:744][ 6]LogHttp: VeryVerbose: 00000231A20145C0: Received header (75 bytes) +[2018.11.29-17.16.16:744][ 6]LogHttp: Verbose: 00000231A20145C0: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.16:744][ 6]LogHttp: VeryVerbose: 00000231A20145C0: Received header (22 bytes) +[2018.11.29-17.16.16:744][ 6]LogHttp: Verbose: 00000231A20145C0: Received response header 'Content-Length: 2072'. +[2018.11.29-17.16.16:744][ 6]LogHttp: VeryVerbose: 00000231A20145C0: Received header (24 bytes) +[2018.11.29-17.16.16:744][ 6]LogHttp: Verbose: 00000231A20145C0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.16:744][ 6]LogHttp: Verbose: 00000231A20145C0: Received response header ''. +[2018.11.29-17.16.16:744][ 6]LogHttp: VeryVerbose: 00000231A20145C0: Received header (2 bytes) +[2018.11.29-17.16.16:744][ 6]LogHttp: VeryVerbose: 00000231A20145C0: Received data (2072 bytes) +[2018.11.29-17.16.16:744][ 6]LogHttp: Verbose: 00000231A20145C0: ReceiveResponseBodyCallback: 2072 bytes out of 2072 received. (SizeInBlocks=1, BlockSizeInBytes=2072, Response->TotalBytesRead=0, Response->GetContentLength()=2072, SizeToDownload=2072 (<-this will get returned from the callback)) +[2018.11.29-17.16.16:745][ 6]LogHttp: VeryVerbose: 00000231A20145C0: 'Connection #3 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.16:745][ 6]LogHttp: Verbose: Request 00000231A20145C0 (easy handle:00000231B1DF5560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.16:750][ 6]LogLevelActorContainer: Created LevelActorCluster (9) for /Game/Maps/UI/Frontend_Upgrades.Frontend_Upgrades:PersistentLevel with 54 objects, 0 referenced clusters and 15 mutable objects. +[2018.11.29-17.16.16:754][ 7]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.16:754][ 7]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.16:754][ 7]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:754][ 7]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:755][ 7]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:755][ 7]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:755][ 7]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:755][ 7]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:755][ 7]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:755][ 7]LogHttp: 00000231A20145C0: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/cloudstorage/system, HTTP code: 200, content length: 2072, actual payload size: 2072 +[2018.11.29-17.16.16:755][ 7]LogHttp: Verbose: 00000231A20145C0 Response Header Content-Type: application/json +[2018.11.29-17.16.16:755][ 7]LogHttp: Verbose: 00000231A20145C0 Response Header Date: Thu, 29 Nov 2018 17:16:16 GMT +[2018.11.29-17.16.16:755][ 7]LogHttp: Verbose: 00000231A20145C0 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.16:755][ 7]LogHttp: Verbose: 00000231A20145C0 Response Header X-Epic-Correlation-ID: FN-2hZqN3ITjUe1SX_CM6NDww +[2018.11.29-17.16.16:755][ 7]LogHttp: Verbose: 00000231A20145C0 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.16:755][ 7]LogHttp: Verbose: 00000231A20145C0 Response Header Content-Length: 2072 +[2018.11.29-17.16.16:756][ 7]LogHttp: Verbose: 00000231A20145C0 Response Header Connection: keep-alive +[2018.11.29-17.16.16:756][ 7]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.16:759][ 7]LogLevel: ActivateLevel /Game/Maps/UI/Frontend_HeroLoadout 1 1 1 +[2018.11.29-17.16.16:769][ 7]LogFort: Display: [FortCustomizationAssetLoader CP_Head_M_Scientist] Finished loading. 4 assets loaded. +[2018.11.29-17.16.16:770][ 7]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/Maps/UI/Frontend_HeroLoadout) is flushing async loading +[2018.11.29-17.16.16:770][ 7]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.16:895][ 7]LogLevelActorContainer: Created LevelActorCluster (10) for /Game/Maps/UI/Frontend_HeroLoadout.Frontend_HeroLoadout:PersistentLevel with 404 objects, 0 referenced clusters and 69 mutable objects. +[2018.11.29-17.16.16:898][ 8]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.16:898][ 8]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.16:899][ 8]LogOnlineTitleFile: OSS: FOnlineTitleFileMcp::DeleteCachedFiles Clearing cached files: [bSkipEnumerated:1] +[2018.11.29-17.16.16:899][ 8]LogOnlineTitleFile: OSS: Cleared 0 cached files. +[2018.11.29-17.16.16:899][ 8]LogHotfixManager: Verbose: Using default hotfix DefaultEngine.ini +[2018.11.29-17.16.16:899][ 8]LogHotfixManager: Verbose: Using default hotfix DefaultRuntimeOptions.ini +[2018.11.29-17.16.16:899][ 8]LogHotfixManager: Verbose: Using default hotfix DefaultGame.ini +[2018.11.29-17.16.16:901][ 8]LogLevel: ActivateLevel /Game/Maps/UI/Frontend_Commander 1 1 1 +[2018.11.29-17.16.16:906][ 8]LogPrimitiveComponent: Warning: CreateDynamicMaterialInstance on /Game/Maps/Frontend.Frontend:PersistentLevel.PlayerPawn_Constructor_C_2147481629.CharacterPartSkelMesh_Body_2147481552: Material index 0 is invalid. +[2018.11.29-17.16.16:908][ 8]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/Maps/UI/Frontend_Commander) is flushing async loading +[2018.11.29-17.16.16:908][ 8]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.17:122][ 8]LogLevelActorContainer: Created LevelActorCluster (11) for /Game/Maps/UI/Frontend_Commander.Frontend_Commander:PersistentLevel with 68 objects, 0 referenced clusters and 17 mutable objects. +[2018.11.29-17.16.17:126][ 9]LogHotfixManager: Hotfix file (DefaultEngine.ini) downloaded. Size was (128) +[2018.11.29-17.16.17:126][ 9]LogHotfixManager: Hotfix file (DefaultGame.ini) downloaded. Size was (864) +[2018.11.29-17.16.17:126][ 9]LogHotfixManager: Hotfix file (DefaultRuntimeOptions.ini) downloaded. Size was (80) +[2018.11.29-17.16.17:126][ 9]LogHotfixManager: Verbose: Applying hotfix DefaultEngine.ini +[2018.11.29-17.16.17:132][ 9]LogHotfixManager: Updating config from DefaultEngine.ini took 0.004564 seconds and reloaded 0 objects +[2018.11.29-17.16.17:132][ 9]LogHotfixManager: Verbose: Applying hotfix DefaultGame.ini +[2018.11.29-17.16.17:133][ 9]LogHotfixManager: Verbose: Reloading /Script/FortniteGame.Default__FortGameInstance +[2018.11.29-17.16.17:133][ 9]LogHotfixManager: Verbose: Reloading /Engine/Transient.FortEngine_2147482588:FortGameInstance_2147482282 +[2018.11.29-17.16.17:134][ 9]LogHotfixManager: Verbose: Reloading /Script/FortniteGame.Default__FortGlobals +[2018.11.29-17.16.17:134][ 9]LogHotfixManager: Verbose: Reloading /Engine/Transient.FortEngine_2147482588:FortGlobals_2147482579 +[2018.11.29-17.16.17:134][ 9]LogHotfixManager: Verbose: Reloading /Script/FortniteGame.Default__FortOnlineAccount +[2018.11.29-17.16.17:134][ 9]LogHotfixManager: Verbose: Reloading /Engine/Transient.FortEngine_2147482588:FortLocalPlayer_2147482238.FortOnlineAccount_2147481969 +[2018.11.29-17.16.17:135][ 9]LogHotfixManager: Updating config from DefaultGame.ini took 0.001729 seconds and reloaded 6 objects +[2018.11.29-17.16.17:135][ 9]LogHotfixManager: Verbose: Applying hotfix DefaultRuntimeOptions.ini +[2018.11.29-17.16.17:135][ 9]LogHotfixManager: Verbose: Reloading /Script/FortniteGame.Default__FortRuntimeOptions +[2018.11.29-17.16.17:137][ 9]LogHotfixManager: Updating config from DefaultRuntimeOptions.ini took 0.002316 seconds and reloaded 1 objects +[2018.11.29-17.16.17:137][ 9]LogHotfixManager: Display: Hotfix data has been successfully applied +[2018.11.29-17.16.17:137][ 9]LogHotfixManager: Display: Checking for assets to be patched using data from 'AssetHotfix' section in the Game .ini file +[2018.11.29-17.16.17:137][ 9]LogHotfixManager: Display: No assets were found in the 'AssetHotfix' section in the Game .ini file. No patching needed. +[2018.11.29-17.16.17:137][ 9]LogHotfixManager: Display: OnHotfixCheckComplete 1 +[2018.11.29-17.16.17:140][ 9]LogLevel: ActivateLevel /Game/Maps/UI/Frontend_STW_Default 1 1 1 +[2018.11.29-17.16.17:157][ 10]LogLevel: ActivateLevel /Game/Maps/WorldLightingMenu 1 1 1 +[2018.11.29-17.16.17:158][ 10]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/Maps/WorldLightingMenu) is flushing async loading +[2018.11.29-17.16.17:158][ 10]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.17:172][ 11]LogLevel: ActivateLevel /Game/Maps/UI/Frontend_Lobby_Layout2 1 1 1 +[2018.11.29-17.16.17:173][ 11]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/Maps/UI/Frontend_Lobby_Layout2) is flushing async loading +[2018.11.29-17.16.17:173][ 11]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.17:235][ 11]LogUMG: Display: Widget Class TeamMemberPedestal_Nameplate_C - Loaded Fast Template. +[2018.11.29-17.16.17:236][ 11]LogUMG: Display: Widget Class LobbyPlayerAddPlayer_C - Loaded Fast Template. +[2018.11.29-17.16.17:236][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:236][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:236][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:236][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:236][ 11]LogUMG: Display: Widget Class LobbyPlayerPadGadgets_C - Loaded Fast Template. +[2018.11.29-17.16.17:236][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:236][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:236][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:236][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:236][ 11]LogUMG: Display: Widget Class TeamMemberPedestal_XPBoostInfo_C - Loaded Fast Template. +[2018.11.29-17.16.17:237][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:238][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:238][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:238][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:238][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:238][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:238][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:238][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:239][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:239][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:239][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:239][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:239][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:239][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:239][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:239][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:240][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:240][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:240][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:240][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:240][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:240][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:240][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:240][ 11]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:243][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:243][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:243][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:243][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:244][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:244][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:244][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:244][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:244][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:244][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:244][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:244][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:244][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:244][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:244][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:244][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:244][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:245][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.17:246][ 12]LogHotfixManager: Display: Update State CheckingForHotfix -> WaitingOnInitialLoad +[2018.11.29-17.16.17:248][ 13]LogHotfixManager: Finished initial load/hotfix phase in 0.001466s +[2018.11.29-17.16.17:248][ 13]LogHotfixManager: Display: Update State WaitingOnInitialLoad -> InitialLoadComplete +[2018.11.29-17.16.17:248][ 13]LogHotfixManager: Display: CheckComplete UpdateSuccess +[2018.11.29-17.16.17:562][ 31]LogFortLoadingScreen: Garbage Collecting before dropping load screen +[2018.11.29-17.16.17:563][ 31]LogCore: Display: Setting hang detector multiplier to 1.0000s. New hang duration: 30.0000s. New present duration: 0.0000s. +[2018.11.29-17.16.17:563][ 31]LogFortLoadingScreen: Hiding loading screen when 'IsShowingInitialLoadingScreen()' is false. +[2018.11.29-17.16.17:563][ 31]LogFortLoadingScreen: PC: AFortPlayerController is not in Zone and always returns 'hide loading screen' +[2018.11.29-17.16.17:566][ 31]LogGarbage: Collecting garbage (GCheckForIllegalMarkPendingKill = 1) +[2018.11.29-17.16.17:579][ 31]LogGarbage: 12.764254 ms for Verify GC Assumptions +[2018.11.29-17.16.17:621][ 31]LogGarbage: 41.630692 ms for GC +[2018.11.29-17.16.17:621][ 31]LogGarbage: 0.466109 ms for Gather Unreachable Objects (25 objects collected including 0 cluster objects from 0 clusters) +[2018.11.29-17.16.17:622][ 31]LogGarbage: 0.126791 ms for unhashing unreachable objects. Items 25 (25/25) +[2018.11.29-17.16.17:627][ 31]LogGarbage: GC purged 25 objects (503340 -> 503315) +[2018.11.29-17.16.17:656][ 31]LogUObjectHash: Compacting FUObjectHashTables data took 28.30ms +[2018.11.29-17.16.17:765][ 38]LogHotfixManager: Display: External CheckComplete UpdateSuccess +[2018.11.29-17.16.17:765][ 38]LogHotfixManager: Display: Update State InitialLoadComplete -> UpdatePending +[2018.11.29-17.16.17:765][ 38]LogFortUI: [UFortUIStateWidget_Login] HandleUpdateCheckComplete +[2018.11.29-17.16.17:765][ 38]LogFortUI: [UFortUIStateWidget_Login] PatchingComplete +[2018.11.29-17.16.17:765][ 38]LogFortUI: [UFortUIStateWidget_Login] EndUpdateCheck +[2018.11.29-17.16.17:765][ 38]LogOnlineAccount: [UOnlineAccountCommon::StartLogin] Starting Login state machine +[2018.11.29-17.16.17:765][ 38]LogFortUI: [UFortUIStateWidget_Login] Autologin started +[2018.11.29-17.16.17:766][ 38]LogLevel: ActivateLevel /Game/Maps/UI/Frontend_Lobby_Default 1 1 1 +[2018.11.29-17.16.17:767][ 38]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/Maps/UI/Frontend_Lobby_Default) is flushing async loading +[2018.11.29-17.16.17:767][ 38]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.17:792][ 38]LogLevelActorContainer: Created LevelActorCluster (12) for /Game/Maps/UI/Frontend_Lobby_Default.Frontend_Lobby_Default:PersistentLevel with 16 objects, 0 referenced clusters and 9 mutable objects. +[2018.11.29-17.16.17:798][ 39]LogOnlineAccount: Display: [UOnlineAccountCommon::ContinueLoggingIn] Login: Checking Epic services queue... (LoginWaitingRoom) +[2018.11.29-17.16.17:814][ 40]LogOnlineAccount: Display: [UOnlineAccountCommon::ContinueLoggingIn] Login: Signing in to Epic services... (LoggingIn) +[2018.11.29-17.16.17:814][ 40]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.17:815][ 40]LogOnlineIdentity: OSS: Sending Login request. url=https://account-public-service-gamedev.ol.epicgames.net/account, type=Epic, id=loadbot07063@epicgames.com +[2018.11.29-17.16.17:815][ 40]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.17:815][ 40]LogHttp: Verbose: 00000231A3D5D1C0: URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/token' +[2018.11.29-17.16.17:815][ 40]LogHttp: Verbose: 00000231A3D5D1C0: Verb='POST' +[2018.11.29-17.16.17:815][ 40]LogHttp: Verbose: 00000231A3D5D1C0: Custom headers are present +[2018.11.29-17.16.17:815][ 40]LogHttp: Verbose: 00000231A3D5D1C0: Payload size=110 +[2018.11.29-17.16.17:815][ 40]LogHttp: Verbose: 00000231A3D5D1C0: Adding header 'X-Epic-Correlation-ID: FN-WEz1GGOiFEii-JUyrOOU0A' +[2018.11.29-17.16.17:815][ 40]LogHttp: Verbose: 00000231A3D5D1C0: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.17:815][ 40]LogHttp: Verbose: 00000231A3D5D1C0: Adding header 'Content-Type: application/x-www-form-urlencoded' +[2018.11.29-17.16.17:815][ 40]LogHttp: Verbose: 00000231A3D5D1C0: Adding header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9' +[2018.11.29-17.16.17:815][ 40]LogHttp: Verbose: 00000231A3D5D1C0: Adding header 'Content-Length: 110' +[2018.11.29-17.16.17:815][ 40]LogHttp: Verbose: 00000231A3D5D1C0: Adding header 'Expect: ' +[2018.11.29-17.16.17:815][ 40]LogHttp: 00000231A3D5D1C0: Starting POST request to URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/token' +[2018.11.29-17.16.17:815][ 40]LogHttp: Verbose: 00000231A3D5D1C0: request (easy handle:0000023196925560) has been added to threaded queue for processing +[2018.11.29-17.16.17:850][ 43]LogHttp: Verbose: 00000231A3D5D1C0: request (easy handle:0000023196925560) has started threaded processing +[2018.11.29-17.16.17:850][ 43]LogHttp: VeryVerbose: 00000231A3D5D1C0: 'Found bundle for host account-public-service-gamedev.ol.epicgames.net: 0x23190f00c40 [can pipeline]' +[2018.11.29-17.16.17:850][ 43]LogHttp: VeryVerbose: 00000231A3D5D1C0: 'Re-using existing connection! (#2) with host account-public-service-gamedev.ol.epicgames.net' +[2018.11.29-17.16.17:850][ 43]LogHttp: VeryVerbose: 00000231A3D5D1C0: 'Connected to account-public-service-gamedev.ol.epicgames.net (10.40.238.51) port 443 (#2)' +[2018.11.29-17.16.17:850][ 43]LogHttp: VeryVerbose: 00000231A3D5D1C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.17:850][ 43]LogHttp: VeryVerbose: 00000231A3D5D1C0: Sent header (483 bytes) - POST /account/api/oauth/token HTTP/1.1Host: account-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-WEz1GGOiFEii-JUyrOOU0AUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Type: application/x-www-form-urlencodedAuthorization: basic ZWM2ODRiOGM2ODdmNDc5ZmFkZWEzY2IyYWQ4M2Y1YzY6MmNlY2JhMzJlNGIzNDFkMGI2NjkyOTg4YTBlMTM2YWY=X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9Content-Length: 110 +[2018.11.29-17.16.17:851][ 43]LogHttp: Verbose: 00000231A3D5D1C0: UploadCallback: 110 bytes out of 110 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=110 (<-this will get returned from the callback)) +[2018.11.29-17.16.17:851][ 43]LogHttp: VeryVerbose: 00000231A3D5D1C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.17:851][ 43]LogHttp: VeryVerbose: 00000231A3D5D1C0: Sent data (110 bytes) +[2018.11.29-17.16.17:851][ 43]LogHttp: VeryVerbose: 00000231A3D5D1C0: 'We are completely uploaded and fine' +[2018.11.29-17.16.17:851][ 43]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.17:851][ 43]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.17:937][ 48]LogHttp: VeryVerbose: 00000231A3D5D1C0: Received SSL data (5 bytes) +[2018.11.29-17.16.17:937][ 48]LogHttp: VeryVerbose: 00000231A3D5D1C0: Received header (17 bytes) +[2018.11.29-17.16.17:937][ 48]LogHttp: Verbose: 00000231A3D5D1C0: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.17:937][ 48]LogHttp: VeryVerbose: 00000231A3D5D1C0: Received header (37 bytes) +[2018.11.29-17.16.17:937][ 48]LogHttp: Verbose: 00000231A3D5D1C0: Received response header 'Date: Thu, 29 Nov 2018 17:16:17 GMT'. +[2018.11.29-17.16.17:937][ 48]LogHttp: VeryVerbose: 00000231A3D5D1C0: Received header (32 bytes) +[2018.11.29-17.16.17:938][ 48]LogHttp: Verbose: 00000231A3D5D1C0: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.17:938][ 48]LogHttp: VeryVerbose: 00000231A3D5D1C0: Received header (28 bytes) +[2018.11.29-17.16.17:938][ 48]LogHttp: Verbose: 00000231A3D5D1C0: Received response header 'Transfer-Encoding: chunked'. +[2018.11.29-17.16.17:938][ 48]LogHttp: VeryVerbose: 00000231A3D5D1C0: Received header (24 bytes) +[2018.11.29-17.16.17:938][ 48]LogHttp: Verbose: 00000231A3D5D1C0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.17:938][ 48]LogHttp: VeryVerbose: 00000231A3D5D1C0: Received header (49 bytes) +[2018.11.29-17.16.17:938][ 48]LogHttp: Verbose: 00000231A3D5D1C0: Received response header 'Cache-Control: no-cache, no-store, no-transform'. +[2018.11.29-17.16.17:938][ 48]LogHttp: VeryVerbose: 00000231A3D5D1C0: Received header (52 bytes) +[2018.11.29-17.16.17:938][ 48]LogHttp: Verbose: 00000231A3D5D1C0: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.17:938][ 48]LogHttp: VeryVerbose: 00000231A3D5D1C0: Received header (50 bytes) +[2018.11.29-17.16.17:938][ 48]LogHttp: Verbose: 00000231A3D5D1C0: Received response header 'X-Epic-Correlation-ID: FN-WEz1GGOiFEii-JUyrOOU0A'. +[2018.11.29-17.16.17:938][ 48]LogHttp: Verbose: 00000231A3D5D1C0: Received response header ''. +[2018.11.29-17.16.17:938][ 48]LogHttp: VeryVerbose: 00000231A3D5D1C0: Received header (2 bytes) +[2018.11.29-17.16.17:938][ 48]LogHttp: VeryVerbose: 00000231A3D5D1C0: Received data (9709 bytes) +[2018.11.29-17.16.17:938][ 48]LogHttp: Verbose: 00000231A3D5D1C0: ReceiveResponseBodyCallback: 9701 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=9701, Response->TotalBytesRead=0, Response->GetContentLength()=0, SizeToDownload=9701 (<-this will get returned from the callback)) +[2018.11.29-17.16.17:938][ 48]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.17:939][ 48]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.17:939][ 48]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.17:939][ 48]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.17:939][ 48]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.17:939][ 48]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.17:939][ 48]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.17:939][ 48]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.17:939][ 48]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.17:950][ 49]LogHttp: VeryVerbose: 00000231A3D5D1C0: Received SSL data (5 bytes) +[2018.11.29-17.16.17:950][ 49]LogHttp: VeryVerbose: 00000231A3D5D1C0: Received data (5 bytes) +[2018.11.29-17.16.17:950][ 49]LogHttp: VeryVerbose: 00000231A3D5D1C0: 'Connection #2 to host account-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.17:950][ 49]LogHttp: Verbose: Request 00000231A3D5D1C0 (easy handle:0000023196925560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.17:950][ 49]LogHttp: 00000231A3D5D1C0: request has been successfully processed. URL: https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/token, HTTP code: 200, content length: -1, actual payload size: 9701 +[2018.11.29-17.16.17:950][ 49]LogHttp: Verbose: 00000231A3D5D1C0 Response Header Date: Thu, 29 Nov 2018 17:16:17 GMT +[2018.11.29-17.16.17:951][ 49]LogHttp: Verbose: 00000231A3D5D1C0 Response Header Content-Type: application/json +[2018.11.29-17.16.17:951][ 49]LogHttp: Verbose: 00000231A3D5D1C0 Response Header Transfer-Encoding: chunked +[2018.11.29-17.16.17:951][ 49]LogHttp: Verbose: 00000231A3D5D1C0 Response Header Connection: keep-alive +[2018.11.29-17.16.17:951][ 49]LogHttp: Verbose: 00000231A3D5D1C0 Response Header Cache-Control: no-cache, no-store, no-transform +[2018.11.29-17.16.17:951][ 49]LogHttp: Verbose: 00000231A3D5D1C0 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.17:951][ 49]LogHttp: Verbose: 00000231A3D5D1C0 Response Header X-Epic-Correlation-ID: FN-WEz1GGOiFEii-JUyrOOU0A +[2018.11.29-17.16.17:951][ 49]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.17:966][ 50]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.17:966][ 50]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.17:968][ 50]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.17:968][ 50]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.17:968][ 50]LogHttp: Verbose: 00000231A448F380: URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/sessions/kill?killType=OTHERS_ACCOUNT_CLIENT_SERVICE' +[2018.11.29-17.16.17:968][ 50]LogHttp: Verbose: 00000231A448F380: Verb='DELETE' +[2018.11.29-17.16.17:968][ 50]LogHttp: Verbose: 00000231A448F380: Custom headers are present +[2018.11.29-17.16.17:968][ 50]LogHttp: Verbose: 00000231A448F380: Payload size=0 +[2018.11.29-17.16.17:968][ 50]LogHttp: Verbose: 00000231A448F380: Adding header 'X-Epic-Correlation-ID: FN-2xM5Jx4P8kSIVdsPyMLubA' +[2018.11.29-17.16.17:968][ 50]LogHttp: Verbose: 00000231A448F380: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.17:968][ 50]LogHttp: Verbose: 00000231A448F380: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.17:968][ 50]LogHttp: Verbose: 00000231A448F380: Adding header 'Content-Length: 0' +[2018.11.29-17.16.17:969][ 50]LogHttp: Verbose: 00000231A448F380: Adding header 'Expect: ' +[2018.11.29-17.16.17:969][ 50]LogHttp: 00000231A448F380: Starting DELETE request to URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/sessions/kill?killType=OTHERS_ACCOUNT_CLIENT_SERVICE' +[2018.11.29-17.16.17:969][ 50]LogHttp: Verbose: 00000231A448F380: request (easy handle:00000231A1CA5560) has been added to threaded queue for processing +[2018.11.29-17.16.17:969][ 50]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.17:969][ 50]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.17:969][ 50]LogHttp: Verbose: 00000231A448F100: URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/public/account/e6f5091c3b2f4c359cf2aad75c424de0' +[2018.11.29-17.16.17:969][ 50]LogHttp: Verbose: 00000231A448F100: Verb='GET' +[2018.11.29-17.16.17:969][ 50]LogHttp: Verbose: 00000231A448F100: Custom headers are present +[2018.11.29-17.16.17:969][ 50]LogHttp: Verbose: 00000231A448F100: Payload size=0 +[2018.11.29-17.16.17:969][ 50]LogHttp: Verbose: 00000231A448F100: Adding header 'X-Epic-Correlation-ID: FN-KxC6Ryf4R0yNYc2wqVerxQ' +[2018.11.29-17.16.17:969][ 50]LogHttp: Verbose: 00000231A448F100: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.17:969][ 50]LogHttp: Verbose: 00000231A448F100: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.17:969][ 50]LogHttp: Verbose: 00000231A448F100: Adding header 'Content-Length: 0' +[2018.11.29-17.16.17:969][ 50]LogHttp: Verbose: 00000231A448F100: Adding header 'Expect: ' +[2018.11.29-17.16.17:969][ 50]LogHttp: 00000231A448F100: Starting GET request to URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/public/account/e6f5091c3b2f4c359cf2aad75c424de0' +[2018.11.29-17.16.17:970][ 50]LogHttp: Verbose: 00000231A448F100: request (easy handle:00000231A29E0010) has been added to threaded queue for processing +[2018.11.29-17.16.17:970][ 50]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.17:970][ 50]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.17:970][ 50]LogHttp: Verbose: 00000231A41DC2C0: URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/public/account/e6f5091c3b2f4c359cf2aad75c424de0/externalAuths' +[2018.11.29-17.16.17:970][ 50]LogHttp: Verbose: 00000231A41DC2C0: Verb='GET' +[2018.11.29-17.16.17:970][ 50]LogHttp: Verbose: 00000231A41DC2C0: Custom headers are present +[2018.11.29-17.16.17:970][ 50]LogHttp: Verbose: 00000231A41DC2C0: Payload size=0 +[2018.11.29-17.16.17:970][ 50]LogHttp: Verbose: 00000231A41DC2C0: Adding header 'X-Epic-Correlation-ID: FN-cATVPfo2UkORt8vvdO87PA' +[2018.11.29-17.16.17:970][ 50]LogHttp: Verbose: 00000231A41DC2C0: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.17:970][ 50]LogHttp: Verbose: 00000231A41DC2C0: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.17:970][ 50]LogHttp: Verbose: 00000231A41DC2C0: Adding header 'Content-Length: 0' +[2018.11.29-17.16.17:970][ 50]LogHttp: Verbose: 00000231A41DC2C0: Adding header 'Expect: ' +[2018.11.29-17.16.17:970][ 50]LogHttp: 00000231A41DC2C0: Starting GET request to URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/public/account/e6f5091c3b2f4c359cf2aad75c424de0/externalAuths' +[2018.11.29-17.16.17:970][ 50]LogHttp: Verbose: 00000231A41DC2C0: request (easy handle:00000231A23DAAB0) has been added to threaded queue for processing +[2018.11.29-17.16.17:985][ 51]LogHttp: Verbose: 00000231A448F380: request (easy handle:00000231A1CA5560) has started threaded processing +[2018.11.29-17.16.17:985][ 51]LogHttp: Verbose: 00000231A448F100: request (easy handle:00000231A29E0010) has started threaded processing +[2018.11.29-17.16.17:985][ 51]LogHttp: Verbose: 00000231A41DC2C0: request (easy handle:00000231A23DAAB0) has started threaded processing +[2018.11.29-17.16.17:985][ 51]LogHttp: VeryVerbose: 00000231A448F380: 'Found bundle for host account-public-service-gamedev.ol.epicgames.net: 0x23190f00c40 [can pipeline]' +[2018.11.29-17.16.17:985][ 51]LogHttp: VeryVerbose: 00000231A448F380: 'Re-using existing connection! (#2) with host account-public-service-gamedev.ol.epicgames.net' +[2018.11.29-17.16.17:985][ 51]LogHttp: VeryVerbose: 00000231A448F380: 'Connected to account-public-service-gamedev.ol.epicgames.net (10.40.238.51) port 443 (#2)' +[2018.11.29-17.16.17:986][ 51]LogHttp: VeryVerbose: 00000231A448F380: Sent SSL data (5 bytes) +[2018.11.29-17.16.17:986][ 51]LogHttp: VeryVerbose: 00000231A448F380: Sent header (1023 bytes) - DELETE /account/api/oauth/sessions/kill?killType=OTHERS_ACCOUNT_CLIENT_SERVICE HTTP/1.1Host: account-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-2xM5Jx4P8kSIVdsPyMLubAUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Type: application/jsonAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRd +[2018.11.29-17.16.17:986][ 51]LogHttp: VeryVerbose: 00000231A448F100: 'Found bundle for host account-public-service-gamedev.ol.epicgames.net: 0x23190f00c40 [can pipeline]' +[2018.11.29-17.16.17:986][ 51]LogHttp: VeryVerbose: 00000231A448F100: 'Hostname account-public-service-gamedev.ol.epicgames.net was found in DNS cache' +[2018.11.29-17.16.17:986][ 51]LogHttp: VeryVerbose: 00000231A448F100: ' Trying 10.40.238.51...' +[2018.11.29-17.16.17:986][ 51]LogHttp: VeryVerbose: 00000231A448F100: 'TCP_NODELAY set' +[2018.11.29-17.16.17:986][ 51]LogHttp: VeryVerbose: 00000231A41DC2C0: 'Found bundle for host account-public-service-gamedev.ol.epicgames.net: 0x23190f00c40 [can pipeline]' +[2018.11.29-17.16.17:986][ 51]LogHttp: VeryVerbose: 00000231A41DC2C0: 'Hostname account-public-service-gamedev.ol.epicgames.net was found in DNS cache' +[2018.11.29-17.16.17:986][ 51]LogHttp: VeryVerbose: 00000231A41DC2C0: ' Trying 10.40.238.51...' +[2018.11.29-17.16.17:987][ 51]LogHttp: VeryVerbose: 00000231A41DC2C0: 'TCP_NODELAY set' +[2018.11.29-17.16.18:034][ 54]LogHttp: VeryVerbose: 00000231A448F100: 'Connected to account-public-service-gamedev.ol.epicgames.net (10.40.238.51) port 443 (#4)' +[2018.11.29-17.16.18:034][ 54]LogHttp: VeryVerbose: 00000231A41DC2C0: 'Connected to account-public-service-gamedev.ol.epicgames.net (10.40.238.51) port 443 (#5)' +[2018.11.29-17.16.18:050][ 55]LogHttp: VeryVerbose: 00000231A448F100: 'ALPN, offering http/1.1' +[2018.11.29-17.16.18:050][ 55]LogHttp: VeryVerbose: 00000231A448F100: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.18:050][ 55]LogHttp: VeryVerbose: 00000231A448F100: 'SSL re-using session ID' +[2018.11.29-17.16.18:050][ 55]LogHttp: VeryVerbose: 00000231A448F100: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:050][ 55]LogHttp: VeryVerbose: 00000231A448F100: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.18:050][ 55]LogHttp: VeryVerbose: 00000231A448F100: Sent SSL data (512 bytes) +[2018.11.29-17.16.18:050][ 55]LogHttp: VeryVerbose: 00000231A41DC2C0: 'ALPN, offering http/1.1' +[2018.11.29-17.16.18:050][ 55]LogHttp: VeryVerbose: 00000231A41DC2C0: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.18:050][ 55]LogHttp: VeryVerbose: 00000231A41DC2C0: 'SSL re-using session ID' +[2018.11.29-17.16.18:050][ 55]LogHttp: VeryVerbose: 00000231A41DC2C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:050][ 55]LogHttp: VeryVerbose: 00000231A41DC2C0: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.18:050][ 55]LogHttp: VeryVerbose: 00000231A41DC2C0: Sent SSL data (512 bytes) +[2018.11.29-17.16.18:084][ 57]LogHttp: VeryVerbose: 00000231A448F380: Received SSL data (5 bytes) +[2018.11.29-17.16.18:084][ 57]LogHttp: VeryVerbose: 00000231A448F380: Received header (25 bytes) +[2018.11.29-17.16.18:084][ 57]LogHttp: Verbose: 00000231A448F380: Received response header 'HTTP/1.1 204 No Content'. +[2018.11.29-17.16.18:084][ 57]LogHttp: VeryVerbose: 00000231A448F380: Received header (37 bytes) +[2018.11.29-17.16.18:084][ 57]LogHttp: Verbose: 00000231A448F380: Received response header 'Date: Thu, 29 Nov 2018 17:16:17 GMT'. +[2018.11.29-17.16.18:084][ 57]LogHttp: VeryVerbose: 00000231A448F380: Received header (24 bytes) +[2018.11.29-17.16.18:084][ 57]LogHttp: Verbose: 00000231A448F380: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.18:084][ 57]LogHttp: VeryVerbose: 00000231A448F380: Received header (49 bytes) +[2018.11.29-17.16.18:084][ 57]LogHttp: Verbose: 00000231A448F380: Received response header 'Cache-Control: no-cache, no-store, no-transform'. +[2018.11.29-17.16.18:085][ 57]LogHttp: VeryVerbose: 00000231A448F380: Received header (52 bytes) +[2018.11.29-17.16.18:085][ 57]LogHttp: Verbose: 00000231A448F380: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.18:085][ 57]LogHttp: VeryVerbose: 00000231A448F380: Received header (50 bytes) +[2018.11.29-17.16.18:085][ 57]LogHttp: Verbose: 00000231A448F380: Received response header 'X-Epic-Correlation-ID: FN-2xM5Jx4P8kSIVdsPyMLubA'. +[2018.11.29-17.16.18:085][ 57]LogHttp: Verbose: 00000231A448F380: Received response header ''. +[2018.11.29-17.16.18:085][ 57]LogHttp: VeryVerbose: 00000231A448F380: Received header (2 bytes) +[2018.11.29-17.16.18:085][ 57]LogHttp: VeryVerbose: 00000231A448F380: 'Connection #2 to host account-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.18:085][ 57]LogHttp: Verbose: Request 00000231A448F380 (easy handle:00000231A1CA5560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.18:085][ 57]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:085][ 57]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:085][ 57]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:085][ 57]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:085][ 57]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:085][ 57]LogHttp: 00000231A448F380: request has been successfully processed. URL: https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/sessions/kill?killType=OTHERS_ACCOUNT_CLIENT_SERVICE, HTTP code: 204, content length: 0, actual payload size: 0 +[2018.11.29-17.16.18:086][ 57]LogHttp: Verbose: 00000231A448F380 Response Header Date: Thu, 29 Nov 2018 17:16:17 GMT +[2018.11.29-17.16.18:086][ 57]LogHttp: Verbose: 00000231A448F380 Response Header Connection: keep-alive +[2018.11.29-17.16.18:086][ 57]LogHttp: Verbose: 00000231A448F380 Response Header Cache-Control: no-cache, no-store, no-transform +[2018.11.29-17.16.18:086][ 57]LogHttp: Verbose: 00000231A448F380 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.18:086][ 57]LogHttp: Verbose: 00000231A448F380 Response Header X-Epic-Correlation-ID: FN-2xM5Jx4P8kSIVdsPyMLubA +[2018.11.29-17.16.18:086][ 57]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:100][ 58]LogHttp: VeryVerbose: 00000231A448F100: Received SSL data (5 bytes) +[2018.11.29-17.16.18:100][ 58]LogHttp: VeryVerbose: 00000231A448F100: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.18:100][ 58]LogHttp: VeryVerbose: 00000231A448F100: Received SSL data (96 bytes) +[2018.11.29-17.16.18:100][ 58]LogHttp: VeryVerbose: 00000231A448F100: Received SSL data (5 bytes) +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: Received SSL data (1 bytes) +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: Received SSL data (5 bytes) +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: Received SSL data (16 bytes) +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: Sent SSL data (1 bytes) +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: Sent SSL data (16 bytes) +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: 'Server certificate:' +[2018.11.29-17.16.18:101][ 58]LogHttp: VeryVerbose: 00000231A448F100: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.16.18:102][ 58]LogHttp: VeryVerbose: 00000231A448F100: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.16.18:102][ 58]LogHttp: VeryVerbose: 00000231A448F100: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.16.18:102][ 58]LogHttp: VeryVerbose: 00000231A448F100: ' subjectAltName: host "account-public-service-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.16.18:102][ 58]LogHttp: VeryVerbose: 00000231A448F100: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.18:102][ 58]LogHttp: VeryVerbose: 00000231A448F100: ' SSL certificate verify ok.' +[2018.11.29-17.16.18:102][ 58]LogHttp: VeryVerbose: 00000231A448F100: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:102][ 58]LogHttp: VeryVerbose: 00000231A448F100: Sent header (1023 bytes) - GET /account/api/public/account/e6f5091c3b2f4c359cf2aad75c424de0 HTTP/1.1Host: account-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-KxC6Ryf4R0yNYc2wqVerxQUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Type: application/jsonAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM0R +[2018.11.29-17.16.18:102][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: Received SSL data (5 bytes) +[2018.11.29-17.16.18:102][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.18:102][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: Received SSL data (96 bytes) +[2018.11.29-17.16.18:102][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: Received SSL data (5 bytes) +[2018.11.29-17.16.18:102][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.18:102][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: Received SSL data (1 bytes) +[2018.11.29-17.16.18:102][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: Received SSL data (5 bytes) +[2018.11.29-17.16.18:103][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.18:103][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: Received SSL data (16 bytes) +[2018.11.29-17.16.18:103][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:103][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.18:103][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: Sent SSL data (1 bytes) +[2018.11.29-17.16.18:103][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:103][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.18:103][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: Sent SSL data (16 bytes) +[2018.11.29-17.16.18:103][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.18:103][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.16.18:103][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: 'Server certificate:' +[2018.11.29-17.16.18:103][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.16.18:103][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.16.18:103][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.16.18:104][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: ' subjectAltName: host "account-public-service-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.16.18:104][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.18:104][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: ' SSL certificate verify ok.' +[2018.11.29-17.16.18:104][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:104][ 58]LogHttp: VeryVerbose: 00000231A41DC2C0: Sent header (1023 bytes) - GET /account/api/public/account/e6f5091c3b2f4c359cf2aad75c424de0/externalAuths HTTP/1.1Host: account-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-cATVPfo2UkORt8vvdO87PAUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Type: application/jsonAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRd +[2018.11.29-17.16.18:104][ 58]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:104][ 58]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:104][ 58]LogOnlineIdentity: OSS: Kill auth sessions request complete. url=https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/sessions/kill?killType=OTHERS_ACCOUNT_CLIENT_SERVICE code=204 response= +[2018.11.29-17.16.18:167][ 62]LogHttp: VeryVerbose: 00000231A448F100: Received SSL data (5 bytes) +[2018.11.29-17.16.18:167][ 62]LogHttp: VeryVerbose: 00000231A448F100: Received header (17 bytes) +[2018.11.29-17.16.18:168][ 62]LogHttp: Verbose: 00000231A448F100: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.18:168][ 62]LogHttp: VeryVerbose: 00000231A448F100: Received header (37 bytes) +[2018.11.29-17.16.18:168][ 62]LogHttp: Verbose: 00000231A448F100: Received response header 'Date: Thu, 29 Nov 2018 17:16:18 GMT'. +[2018.11.29-17.16.18:168][ 62]LogHttp: VeryVerbose: 00000231A448F100: Received header (32 bytes) +[2018.11.29-17.16.18:168][ 62]LogHttp: Verbose: 00000231A448F100: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.18:168][ 62]LogHttp: VeryVerbose: 00000231A448F100: Received header (21 bytes) +[2018.11.29-17.16.18:168][ 62]LogHttp: Verbose: 00000231A448F100: Received response header 'Content-Length: 442'. +[2018.11.29-17.16.18:168][ 62]LogHttp: VeryVerbose: 00000231A448F100: Received header (24 bytes) +[2018.11.29-17.16.18:168][ 62]LogHttp: Verbose: 00000231A448F100: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.18:168][ 62]LogHttp: VeryVerbose: 00000231A448F100: Received header (49 bytes) +[2018.11.29-17.16.18:169][ 62]LogHttp: Verbose: 00000231A448F100: Received response header 'Cache-Control: no-cache, no-store, no-transform'. +[2018.11.29-17.16.18:169][ 62]LogHttp: VeryVerbose: 00000231A448F100: Received header (52 bytes) +[2018.11.29-17.16.18:169][ 62]LogHttp: Verbose: 00000231A448F100: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.18:169][ 62]LogHttp: VeryVerbose: 00000231A448F100: Received header (50 bytes) +[2018.11.29-17.16.18:169][ 62]LogHttp: Verbose: 00000231A448F100: Received response header 'X-Epic-Correlation-ID: FN-KxC6Ryf4R0yNYc2wqVerxQ'. +[2018.11.29-17.16.18:169][ 62]LogHttp: Verbose: 00000231A448F100: Received response header ''. +[2018.11.29-17.16.18:169][ 62]LogHttp: VeryVerbose: 00000231A448F100: Received header (2 bytes) +[2018.11.29-17.16.18:169][ 62]LogHttp: VeryVerbose: 00000231A448F100: Received data (442 bytes) +[2018.11.29-17.16.18:169][ 62]LogHttp: Verbose: 00000231A448F100: ReceiveResponseBodyCallback: 442 bytes out of 442 received. (SizeInBlocks=1, BlockSizeInBytes=442, Response->TotalBytesRead=0, Response->GetContentLength()=442, SizeToDownload=442 (<-this will get returned from the callback)) +[2018.11.29-17.16.18:169][ 62]LogHttp: VeryVerbose: 00000231A448F100: 'Connection #4 to host account-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.18:169][ 62]LogHttp: Verbose: Request 00000231A448F100 (easy handle:00000231A29E0010) has completed (code:0) and has been marked as such +[2018.11.29-17.16.18:169][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: Received SSL data (5 bytes) +[2018.11.29-17.16.18:169][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: Received header (17 bytes) +[2018.11.29-17.16.18:169][ 62]LogHttp: Verbose: 00000231A41DC2C0: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.18:169][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: Received header (37 bytes) +[2018.11.29-17.16.18:170][ 62]LogHttp: Verbose: 00000231A41DC2C0: Received response header 'Date: Thu, 29 Nov 2018 17:16:18 GMT'. +[2018.11.29-17.16.18:170][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: Received header (32 bytes) +[2018.11.29-17.16.18:170][ 62]LogHttp: Verbose: 00000231A41DC2C0: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.18:170][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: Received header (19 bytes) +[2018.11.29-17.16.18:170][ 62]LogHttp: Verbose: 00000231A41DC2C0: Received response header 'Content-Length: 3'. +[2018.11.29-17.16.18:170][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: Received header (24 bytes) +[2018.11.29-17.16.18:170][ 62]LogHttp: Verbose: 00000231A41DC2C0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.18:170][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: Received header (49 bytes) +[2018.11.29-17.16.18:170][ 62]LogHttp: Verbose: 00000231A41DC2C0: Received response header 'Cache-Control: no-cache, no-store, no-transform'. +[2018.11.29-17.16.18:170][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: Received header (52 bytes) +[2018.11.29-17.16.18:170][ 62]LogHttp: Verbose: 00000231A41DC2C0: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.18:170][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: Received header (50 bytes) +[2018.11.29-17.16.18:170][ 62]LogHttp: Verbose: 00000231A41DC2C0: Received response header 'X-Epic-Correlation-ID: FN-cATVPfo2UkORt8vvdO87PA'. +[2018.11.29-17.16.18:170][ 62]LogHttp: Verbose: 00000231A41DC2C0: Received response header ''. +[2018.11.29-17.16.18:170][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: Received header (2 bytes) +[2018.11.29-17.16.18:170][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: Received data (3 bytes) +[2018.11.29-17.16.18:170][ 62]LogHttp: Verbose: 00000231A41DC2C0: ReceiveResponseBodyCallback: 3 bytes out of 3 received. (SizeInBlocks=1, BlockSizeInBytes=3, Response->TotalBytesRead=0, Response->GetContentLength()=3, SizeToDownload=3 (<-this will get returned from the callback)) +[2018.11.29-17.16.18:170][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: 'Connection cache is full, closing the oldest one.' +[2018.11.29-17.16.18:170][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: 'Closing connection 0' +[2018.11.29-17.16.18:171][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:171][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.16.18:171][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: Sent SSL data (2 bytes) +[2018.11.29-17.16.18:171][ 62]LogHttp: VeryVerbose: 00000231A41DC2C0: 'Connection #5 to host account-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.18:171][ 62]LogHttp: Verbose: Request 00000231A41DC2C0 (easy handle:00000231A23DAAB0) has completed (code:0) and has been marked as such +[2018.11.29-17.16.18:171][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:171][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:171][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:171][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:171][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:171][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:171][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:171][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:171][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:171][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:172][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:172][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:172][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:172][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:172][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:172][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:172][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:172][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:172][ 62]LogHttp: 00000231A448F100: request has been successfully processed. URL: https://account-public-service-gamedev.ol.epicgames.net/account/api/public/account/e6f5091c3b2f4c359cf2aad75c424de0, HTTP code: 200, content length: 442, actual payload size: 442 +[2018.11.29-17.16.18:172][ 62]LogHttp: Verbose: 00000231A448F100 Response Header Date: Thu, 29 Nov 2018 17:16:18 GMT +[2018.11.29-17.16.18:172][ 62]LogHttp: Verbose: 00000231A448F100 Response Header Content-Type: application/json +[2018.11.29-17.16.18:172][ 62]LogHttp: Verbose: 00000231A448F100 Response Header Content-Length: 442 +[2018.11.29-17.16.18:172][ 62]LogHttp: Verbose: 00000231A448F100 Response Header Connection: keep-alive +[2018.11.29-17.16.18:172][ 62]LogHttp: Verbose: 00000231A448F100 Response Header Cache-Control: no-cache, no-store, no-transform +[2018.11.29-17.16.18:172][ 62]LogHttp: Verbose: 00000231A448F100 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.18:172][ 62]LogHttp: Verbose: 00000231A448F100 Response Header X-Epic-Correlation-ID: FN-KxC6Ryf4R0yNYc2wqVerxQ +[2018.11.29-17.16.18:172][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:172][ 62]LogHttp: 00000231A41DC2C0: request has been successfully processed. URL: https://account-public-service-gamedev.ol.epicgames.net/account/api/public/account/e6f5091c3b2f4c359cf2aad75c424de0/externalAuths, HTTP code: 200, content length: 3, actual payload size: 3 +[2018.11.29-17.16.18:173][ 62]LogHttp: Verbose: 00000231A41DC2C0 Response Header Date: Thu, 29 Nov 2018 17:16:18 GMT +[2018.11.29-17.16.18:173][ 62]LogHttp: Verbose: 00000231A41DC2C0 Response Header Content-Type: application/json +[2018.11.29-17.16.18:173][ 62]LogHttp: Verbose: 00000231A41DC2C0 Response Header Content-Length: 3 +[2018.11.29-17.16.18:173][ 62]LogHttp: Verbose: 00000231A41DC2C0 Response Header Connection: keep-alive +[2018.11.29-17.16.18:173][ 62]LogHttp: Verbose: 00000231A41DC2C0 Response Header Cache-Control: no-cache, no-store, no-transform +[2018.11.29-17.16.18:173][ 62]LogHttp: Verbose: 00000231A41DC2C0 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.18:173][ 62]LogHttp: Verbose: 00000231A41DC2C0 Response Header X-Epic-Correlation-ID: FN-cATVPfo2UkORt8vvdO87PA +[2018.11.29-17.16.18:173][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:173][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:173][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:173][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:173][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:174][ 62]LogOnlineAccount: Setting LocalPlayer FortLocalPlayer_2147482238 to ControllerId 0 +[2018.11.29-17.16.18:174][ 62]LogOnlineAccount: Display: [UOnlineAccountCommon::ProcessUserLogin] Successfully logged in user. UserId=[e6f5091c3b2f4c359cf2aad75c424de0] DisplayName=[LoadBot07063] EpicAccountId=[MCP:e6f5091c3b2f4c359cf2aad75c424de0] AuthTicket=[eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM0RoMXFQVm9LNXp2M1J0TjZCUUM3QUJ1UGJTcTRpdjRjbWJGV3BtXC9CTHRGSjBqVE83ZTJPdkNlcU5rT1AyakFHdFJJYmdXWHBieFZyZzF1WUJGc0g0ZGJHYnhkeEZwR21IZlU5dGRvSUtsWklUcjViazdYNWZVOXQzbXRZeEU0dkF0Mkp0SVY5SjcxSzV1OXVkSnpRWWZVWlJ3YnRkWlJ1U0p2YUREaCtIV3JneFFcL3dNWlp2SEhDeTVnamN5Q1ZMUFMzOHhMdmtJXC9TVG9yMU4yWEFMWFArRFdHdHZveHMwWUZiNUZOalFydnFcLzRibDhEejVScmluTDZWNDUrUnVrOU5hamNXSTZ6UnQxQVZnekF0SlwvcnYzR3lmTko0NjJQVElXT29OR1NkWG54bTVLZHFONUVpVHQ0T0Q0U2JVOE9LSWFINEJyNUM0SXF6VXpvT204S09PVHNWUmVBcW13RnZDOEYzV3RETjZlSnBXR2NVZ3Q3aDViczdpY2FNOVQ1TjNuU1Q4M2pVNUV6OUVjbGZ5WG5hem54NWxsc3FLbXBTUlhDM0JvbUFtVFNuWGFPallTaFpkUnR6b3NTZlBlNHRqVzN0Nll5Qmg5eURBQTZYcURKZWcyTUthUEhPTXRMQXEwdVR5UzNMWXBkZk50OE0rR241eDhSUUJQOXF6N0JhRjVPQlJoREZFKzVOVTlGUnFPUmtlYyt3ZXBjNjNGZkU2OXJveVpwVm45WHBcL0VOK1RNYnF0cEY1UngzVFQwWXV4cWxWbG91TGVVZHVqYjVOaGNrRFwvamp1czExcFlJMFV2NlQzb3VsVG1tdEllWVYwd1dwUEM3Z3g2Mll4OUEzQmZaa0U2OVJoTFI3ZDNkekpmZ2w3Z255RDlOMFpnS1wvbStiOXZQRXZjdUNrNUYzWGR2bnVhQU5ZVE9XRXl0aVUrUkQ0TU5qcnBUcTQ3T2xlR3JLQ0dIcTVGMHZlT0tSMm11cUtvcXZ1Zkx1ZUt4OHZ0NFh0N1phNG52a3ZcL2dKWWl2IiwiaWFpIjoiZTZmNTA5MWMzYjJmNGMzNTljZjJhYWQ3NWM0MjRkZTAiLCJjbHN2YyI6ImZvcnRuaXRlIiwibHB2IjoxNTQzNTExNzc3LCJ0IjoicyIsImljIjp0cnVlLCJleHAiOjE1NDM1NDA1NzcsImlhdCI6MTU0MzUxMTc3NywianRpIjoiY2UzZTg2M2I0NTA2NDQyMWI0NDlmMTcyOWYwNjNmNWYifQ.AQ0XBAer5ZnmzSHTYzFrjeKuvgDS-n1kPlO1m8NGn6RIfRymLo4DuWK_yQTvoKMd1XvRR6wG5qTqtjaiobKxgL8D] +[2018.11.29-17.16.18:175][ 62]LogAnalytics: [Fortnite.DevLatest] SetUserId accb3c904505355102cf80b4f2cb03d3|e6f5091c3b2f4c359cf2aad75c424de0|e04d67a7-16cd-41f9-b939-be602538533a|fa55e3108f3fc66d6c4ff7eb4398e2a9| +[2018.11.29-17.16.18:176][ 62]LogParty: FSocialQuery_UserInfo executing for [1] users on subsystem [Primary] +[2018.11.29-17.16.18:176][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:181][ 62]LogOnlineAccount: Display: [UOnlineAccountCommon::ContinueLoggingIn] Login: (CheckPlatformPlayAllowed) +[2018.11.29-17.16.18:182][ 62]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:184][ 63]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:184][ 63]LogHttp: Verbose: 00000231A448B500: URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/public/account?accountId=e6f5091c3b2f4c359cf2aad75c424de0' +[2018.11.29-17.16.18:184][ 63]LogHttp: Verbose: 00000231A448B500: Verb='GET' +[2018.11.29-17.16.18:185][ 63]LogHttp: Verbose: 00000231A448B500: Custom headers are present +[2018.11.29-17.16.18:185][ 63]LogHttp: Verbose: 00000231A448B500: Payload size=0 +[2018.11.29-17.16.18:185][ 63]LogHttp: Verbose: 00000231A448B500: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.18:185][ 63]LogHttp: Verbose: 00000231A448B500: Adding header 'X-Epic-Correlation-ID: FN-NmGVQYUBfkGNflmsspJQfw' +[2018.11.29-17.16.18:185][ 63]LogHttp: Verbose: 00000231A448B500: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.18:185][ 63]LogHttp: Verbose: 00000231A448B500: Adding header 'Content-Length: 0' +[2018.11.29-17.16.18:185][ 63]LogHttp: Verbose: 00000231A448B500: Adding header 'Expect: ' +[2018.11.29-17.16.18:185][ 63]LogHttp: 00000231A448B500: Starting GET request to URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/public/account?accountId=e6f5091c3b2f4c359cf2aad75c424de0' +[2018.11.29-17.16.18:186][ 63]LogHttp: Verbose: 00000231A448B500: request (easy handle:00000231A25D5560) has been added to threaded queue for processing +[2018.11.29-17.16.18:201][ 64]LogHttp: Verbose: 00000231A448B500: request (easy handle:00000231A25D5560) has started threaded processing +[2018.11.29-17.16.18:201][ 64]LogHttp: VeryVerbose: 00000231A448B500: 'Found bundle for host account-public-service-gamedev.ol.epicgames.net: 0x23190f00c40 [can pipeline]' +[2018.11.29-17.16.18:201][ 64]LogHttp: VeryVerbose: 00000231A448B500: 'Re-using existing connection! (#2) with host account-public-service-gamedev.ol.epicgames.net' +[2018.11.29-17.16.18:201][ 64]LogHttp: VeryVerbose: 00000231A448B500: 'Connected to account-public-service-gamedev.ol.epicgames.net (10.40.238.51) port 443 (#2)' +[2018.11.29-17.16.18:201][ 64]LogHttp: VeryVerbose: 00000231A448B500: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:201][ 64]LogHttp: VeryVerbose: 00000231A448B500: Sent header (1023 bytes) - GET /account/api/public/account?accountId=e6f5091c3b2f4c359cf2aad75c424de0 HTTP/1.1Host: account-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/jsonX-Epic-Correlation-ID: FN-NmGVQYUBfkGNflmsspJQfwUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmb +[2018.11.29-17.16.18:201][ 64]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:201][ 64]LogHttp: Verbose: 00000231A448B280: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/tryPlayOnPlatform/account/e6f5091c3b2f4c359cf2aad75c424de0?platform=PC' +[2018.11.29-17.16.18:202][ 64]LogHttp: Verbose: 00000231A448B280: Verb='POST' +[2018.11.29-17.16.18:202][ 64]LogHttp: Verbose: 00000231A448B280: Custom headers are present +[2018.11.29-17.16.18:202][ 64]LogHttp: Verbose: 00000231A448B280: Payload size=0 +[2018.11.29-17.16.18:202][ 64]LogHttp: Verbose: 00000231A448B280: Adding header 'X-Epic-Correlation-ID: FN-f2QCYJEKk0C-XItNUCtqIA' +[2018.11.29-17.16.18:202][ 64]LogHttp: Verbose: 00000231A448B280: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.18:202][ 64]LogHttp: Verbose: 00000231A448B280: Adding header 'Content-Length: 0' +[2018.11.29-17.16.18:202][ 64]LogHttp: Verbose: 00000231A448B280: Adding header 'Expect: ' +[2018.11.29-17.16.18:202][ 64]LogHttp: 00000231A448B280: Starting POST request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/tryPlayOnPlatform/account/e6f5091c3b2f4c359cf2aad75c424de0?platform=PC' +[2018.11.29-17.16.18:202][ 64]LogHttp: Verbose: 00000231A448B280: request (easy handle:00000231968A0010) has been added to threaded queue for processing +[2018.11.29-17.16.18:217][ 65]LogHttp: Verbose: 00000231A448B280: request (easy handle:00000231968A0010) has started threaded processing +[2018.11.29-17.16.18:217][ 65]LogHttp: VeryVerbose: 00000231A448B280: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.18:218][ 65]LogHttp: VeryVerbose: 00000231A448B280: 'Re-using existing connection! (#3) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.18:218][ 65]LogHttp: VeryVerbose: 00000231A448B280: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#3)' +[2018.11.29-17.16.18:218][ 65]LogHttp: VeryVerbose: 00000231A448B280: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:218][ 65]LogHttp: VeryVerbose: 00000231A448B280: Sent header (1023 bytes) - POST /fortnite/api/game/v2/tryPlayOnPlatform/account/e6f5091c3b2f4c359cf2aad75c424de0?platform=PC HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-f2QCYJEKk0C-XItNUCtqIAUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbm +[2018.11.29-17.16.18:267][ 68]LogHttp: VeryVerbose: 00000231A448B500: Received SSL data (5 bytes) +[2018.11.29-17.16.18:267][ 68]LogHttp: VeryVerbose: 00000231A448B500: Received header (17 bytes) +[2018.11.29-17.16.18:267][ 68]LogHttp: Verbose: 00000231A448B500: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.18:267][ 68]LogHttp: VeryVerbose: 00000231A448B500: Received header (37 bytes) +[2018.11.29-17.16.18:267][ 68]LogHttp: Verbose: 00000231A448B500: Received response header 'Date: Thu, 29 Nov 2018 17:16:18 GMT'. +[2018.11.29-17.16.18:267][ 68]LogHttp: VeryVerbose: 00000231A448B500: Received header (32 bytes) +[2018.11.29-17.16.18:267][ 68]LogHttp: Verbose: 00000231A448B500: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.18:267][ 68]LogHttp: VeryVerbose: 00000231A448B500: Received header (21 bytes) +[2018.11.29-17.16.18:268][ 68]LogHttp: Verbose: 00000231A448B500: Received response header 'Content-Length: 110'. +[2018.11.29-17.16.18:268][ 68]LogHttp: VeryVerbose: 00000231A448B500: Received header (24 bytes) +[2018.11.29-17.16.18:268][ 68]LogHttp: Verbose: 00000231A448B500: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.18:268][ 68]LogHttp: VeryVerbose: 00000231A448B500: Received header (49 bytes) +[2018.11.29-17.16.18:268][ 68]LogHttp: Verbose: 00000231A448B500: Received response header 'Cache-Control: no-cache, no-store, no-transform'. +[2018.11.29-17.16.18:268][ 68]LogHttp: VeryVerbose: 00000231A448B500: Received header (52 bytes) +[2018.11.29-17.16.18:268][ 68]LogHttp: Verbose: 00000231A448B500: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.18:268][ 68]LogHttp: VeryVerbose: 00000231A448B500: Received header (50 bytes) +[2018.11.29-17.16.18:268][ 68]LogHttp: Verbose: 00000231A448B500: Received response header 'X-Epic-Correlation-ID: FN-NmGVQYUBfkGNflmsspJQfw'. +[2018.11.29-17.16.18:268][ 68]LogHttp: Verbose: 00000231A448B500: Received response header ''. +[2018.11.29-17.16.18:268][ 68]LogHttp: VeryVerbose: 00000231A448B500: Received header (2 bytes) +[2018.11.29-17.16.18:268][ 68]LogHttp: VeryVerbose: 00000231A448B500: Received data (110 bytes) +[2018.11.29-17.16.18:268][ 68]LogHttp: Verbose: 00000231A448B500: ReceiveResponseBodyCallback: 110 bytes out of 110 received. (SizeInBlocks=1, BlockSizeInBytes=110, Response->TotalBytesRead=0, Response->GetContentLength()=110, SizeToDownload=110 (<-this will get returned from the callback)) +[2018.11.29-17.16.18:268][ 68]LogHttp: VeryVerbose: 00000231A448B500: 'Connection #2 to host account-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.18:268][ 68]LogHttp: VeryVerbose: 00000231A448B280: Received SSL data (5 bytes) +[2018.11.29-17.16.18:268][ 68]LogHttp: VeryVerbose: 00000231A448B280: Received header (17 bytes) +[2018.11.29-17.16.18:268][ 68]LogHttp: Verbose: 00000231A448B280: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.18:268][ 68]LogHttp: VeryVerbose: 00000231A448B280: Received header (26 bytes) +[2018.11.29-17.16.18:268][ 68]LogHttp: Verbose: 00000231A448B280: Received response header 'Content-Type: text/plain'. +[2018.11.29-17.16.18:268][ 68]LogHttp: VeryVerbose: 00000231A448B280: Received header (37 bytes) +[2018.11.29-17.16.18:268][ 68]LogHttp: Verbose: 00000231A448B280: Received response header 'Date: Thu, 29 Nov 2018 17:16:18 GMT'. +[2018.11.29-17.16.18:268][ 68]LogHttp: VeryVerbose: 00000231A448B280: Received header (31 bytes) +[2018.11.29-17.16.18:269][ 68]LogHttp: Verbose: 00000231A448B280: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.18:269][ 68]LogHttp: VeryVerbose: 00000231A448B280: Received header (50 bytes) +[2018.11.29-17.16.18:269][ 68]LogHttp: Verbose: 00000231A448B280: Received response header 'X-Epic-Correlation-ID: FN-f2QCYJEKk0C-XItNUCtqIA'. +[2018.11.29-17.16.18:269][ 68]LogHttp: VeryVerbose: 00000231A448B280: Received header (52 bytes) +[2018.11.29-17.16.18:269][ 68]LogHttp: Verbose: 00000231A448B280: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.18:269][ 68]LogHttp: VeryVerbose: 00000231A448B280: Received header (75 bytes) +[2018.11.29-17.16.18:269][ 68]LogHttp: Verbose: 00000231A448B280: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.18:269][ 68]LogHttp: VeryVerbose: 00000231A448B280: Received header (19 bytes) +[2018.11.29-17.16.18:269][ 68]LogHttp: Verbose: 00000231A448B280: Received response header 'Content-Length: 4'. +[2018.11.29-17.16.18:269][ 68]LogHttp: VeryVerbose: 00000231A448B280: Received header (24 bytes) +[2018.11.29-17.16.18:269][ 68]LogHttp: Verbose: 00000231A448B280: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.18:269][ 68]LogHttp: Verbose: 00000231A448B280: Received response header ''. +[2018.11.29-17.16.18:269][ 68]LogHttp: VeryVerbose: 00000231A448B280: Received header (2 bytes) +[2018.11.29-17.16.18:269][ 68]LogHttp: VeryVerbose: 00000231A448B280: Received data (4 bytes) +[2018.11.29-17.16.18:269][ 68]LogHttp: Verbose: 00000231A448B280: ReceiveResponseBodyCallback: 4 bytes out of 4 received. (SizeInBlocks=1, BlockSizeInBytes=4, Response->TotalBytesRead=0, Response->GetContentLength()=4, SizeToDownload=4 (<-this will get returned from the callback)) +[2018.11.29-17.16.18:269][ 68]LogHttp: VeryVerbose: 00000231A448B280: 'Connection #3 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.18:269][ 68]LogHttp: Verbose: Request 00000231A448B500 (easy handle:00000231A25D5560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.18:269][ 68]LogHttp: Verbose: Request 00000231A448B280 (easy handle:00000231968A0010) has completed (code:0) and has been marked as such +[2018.11.29-17.16.18:269][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:269][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:269][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:269][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:269][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:269][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:270][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:270][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:270][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:270][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:270][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:270][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:270][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:270][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:270][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:270][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:270][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:270][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:270][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:270][ 68]LogHttp: 00000231A448B500: request has been successfully processed. URL: https://account-public-service-gamedev.ol.epicgames.net/account/api/public/account?accountId=e6f5091c3b2f4c359cf2aad75c424de0, HTTP code: 200, content length: 110, actual payload size: 110 +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B500 Response Header Date: Thu, 29 Nov 2018 17:16:18 GMT +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B500 Response Header Content-Type: application/json +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B500 Response Header Content-Length: 110 +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B500 Response Header Connection: keep-alive +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B500 Response Header Cache-Control: no-cache, no-store, no-transform +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B500 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B500 Response Header X-Epic-Correlation-ID: FN-NmGVQYUBfkGNflmsspJQfw +[2018.11.29-17.16.18:271][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:271][ 68]LogHttp: 00000231A448B280: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/tryPlayOnPlatform/account/e6f5091c3b2f4c359cf2aad75c424de0?platform=PC, HTTP code: 200, content length: 4, actual payload size: 4 +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B280 Response Header Content-Type: text/plain +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B280 Response Header Date: Thu, 29 Nov 2018 17:16:18 GMT +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B280 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B280 Response Header X-Epic-Correlation-ID: FN-f2QCYJEKk0C-XItNUCtqIA +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B280 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B280 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B280 Response Header Content-Length: 4 +[2018.11.29-17.16.18:271][ 68]LogHttp: Verbose: 00000231A448B280 Response Header Connection: keep-alive +[2018.11.29-17.16.18:271][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:271][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:271][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:272][ 68]LogParty: FSocialQuery_UserInfo completed query for [1] users on subsystem [Primary] with error [] +[2018.11.29-17.16.18:272][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:272][ 68]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:272][ 68]LogOnlineAccount: UFortOnlineAccount::CheckPlatformPlayAllowed_HttpRequestComplete: play IS allowed on this platform +[2018.11.29-17.16.18:281][ 68]LogOnlineAccount: Display: [UOnlineAccountCommon::ContinueLoggingIn] Login: Contacting services... (CheckServiceAvailability) +[2018.11.29-17.16.18:285][ 69]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:285][ 69]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:285][ 69]LogHttp: Verbose: 00000231A448BA00: URL='https://lightswitch-public-service-gamedev.ol.epicgames.net/lightswitch/api/service/bulk/status?serviceId=FortniteDevLatest' +[2018.11.29-17.16.18:285][ 69]LogHttp: Verbose: 00000231A448BA00: Verb='GET' +[2018.11.29-17.16.18:285][ 69]LogHttp: Verbose: 00000231A448BA00: Custom headers are present +[2018.11.29-17.16.18:285][ 69]LogHttp: Verbose: 00000231A448BA00: Payload size=0 +[2018.11.29-17.16.18:285][ 69]LogHttp: Verbose: 00000231A448BA00: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.18:285][ 69]LogHttp: Verbose: 00000231A448BA00: Adding header 'X-Epic-Correlation-ID: FN-VLwcVMlkmUe62H4_oObFng' +[2018.11.29-17.16.18:285][ 69]LogHttp: Verbose: 00000231A448BA00: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.18:286][ 69]LogHttp: Verbose: 00000231A448BA00: Adding header 'Content-Length: 0' +[2018.11.29-17.16.18:286][ 69]LogHttp: Verbose: 00000231A448BA00: Adding header 'Expect: ' +[2018.11.29-17.16.18:286][ 69]LogHttp: 00000231A448BA00: Starting GET request to URL='https://lightswitch-public-service-gamedev.ol.epicgames.net/lightswitch/api/service/bulk/status?serviceId=FortniteDevLatest' +[2018.11.29-17.16.18:286][ 69]LogHttp: Verbose: 00000231A448BA00: request (easy handle:000002319346AAB0) has been added to threaded queue for processing +[2018.11.29-17.16.18:300][ 70]LogHttp: Verbose: 00000231A448BA00: request (easy handle:000002319346AAB0) has started threaded processing +[2018.11.29-17.16.18:300][ 70]LogHttp: VeryVerbose: 00000231A448BA00: ' Trying 10.40.236.236...' +[2018.11.29-17.16.18:300][ 70]LogHttp: VeryVerbose: 00000231A448BA00: 'TCP_NODELAY set' +[2018.11.29-17.16.18:351][ 73]LogHttp: VeryVerbose: 00000231A448BA00: 'Connected to lightswitch-public-service-gamedev.ol.epicgames.net (10.40.236.236) port 443 (#6)' +[2018.11.29-17.16.18:351][ 73]LogHttp: VeryVerbose: 00000231A448BA00: 'ALPN, offering http/1.1' +[2018.11.29-17.16.18:351][ 73]LogHttp: VeryVerbose: 00000231A448BA00: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.18:368][ 74]LogHttp: VeryVerbose: 00000231A448BA00: 'TLSv1.2 (OUT), TLS header, Certificate Status (22):' +[2018.11.29-17.16.18:368][ 74]LogHttp: VeryVerbose: 00000231A448BA00: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:368][ 74]LogHttp: VeryVerbose: 00000231A448BA00: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.18:368][ 74]LogHttp: VeryVerbose: 00000231A448BA00: Sent SSL data (512 bytes) +[2018.11.29-17.16.18:384][ 75]LogHttp: VeryVerbose: 00000231A448BA00: Received SSL data (5 bytes) +[2018.11.29-17.16.18:384][ 75]LogHttp: VeryVerbose: 00000231A448BA00: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.18:384][ 75]LogHttp: VeryVerbose: 00000231A448BA00: Received SSL data (104 bytes) +[2018.11.29-17.16.18:384][ 75]LogHttp: VeryVerbose: 00000231A448BA00: Received SSL data (5 bytes) +[2018.11.29-17.16.18:384][ 75]LogHttp: VeryVerbose: 00000231A448BA00: 'TLSv1.2 (IN), TLS handshake, Certificate (11):' +[2018.11.29-17.16.18:384][ 75]LogHttp: VeryVerbose: 00000231A448BA00: Received SSL data (4568 bytes) +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: Received SSL data (5 bytes) +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: 'TLSv1.2 (IN), TLS handshake, Server key exchange (12):' +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: Received SSL data (333 bytes) +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: Received SSL data (5 bytes) +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: 'TLSv1.2 (IN), TLS handshake, Server finished (14):' +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: Received SSL data (4 bytes) +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: 'TLSv1.2 (OUT), TLS handshake, Client key exchange (16):' +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: Sent SSL data (70 bytes) +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: Sent SSL data (1 bytes) +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.18:400][ 76]LogHttp: VeryVerbose: 00000231A448BA00: Sent SSL data (16 bytes) +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: Received SSL data (5 bytes) +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: Received SSL data (1 bytes) +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: Received SSL data (5 bytes) +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: Received SSL data (16 bytes) +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: 'Server certificate:' +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: ' subjectAltName: host "lightswitch-public-service-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: ' SSL certificate verify ok.' +[2018.11.29-17.16.18:551][ 85]LogHttp: VeryVerbose: 00000231A448BA00: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:552][ 85]LogHttp: VeryVerbose: 00000231A448BA00: Sent header (1023 bytes) - GET /lightswitch/api/service/bulk/status?serviceId=FortniteDevLatest HTTP/1.1Host: lightswitch-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/jsonX-Epic-Correlation-ID: FN-VLwcVMlkmUe62H4_oObFngUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmN +[2018.11.29-17.16.18:634][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Received SSL data (5 bytes) +[2018.11.29-17.16.18:634][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Received header (17 bytes) +[2018.11.29-17.16.18:635][ 90]LogHttp: Verbose: 00000231A448BA00: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.18:635][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Received header (37 bytes) +[2018.11.29-17.16.18:635][ 90]LogHttp: Verbose: 00000231A448BA00: Received response header 'Date: Thu, 29 Nov 2018 17:16:18 GMT'. +[2018.11.29-17.16.18:635][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Received header (32 bytes) +[2018.11.29-17.16.18:635][ 90]LogHttp: Verbose: 00000231A448BA00: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.18:635][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Received header (28 bytes) +[2018.11.29-17.16.18:635][ 90]LogHttp: Verbose: 00000231A448BA00: Received response header 'Transfer-Encoding: chunked'. +[2018.11.29-17.16.18:636][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Received header (24 bytes) +[2018.11.29-17.16.18:636][ 90]LogHttp: Verbose: 00000231A448BA00: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.18:636][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Received header (23 bytes) +[2018.11.29-17.16.18:636][ 90]LogHttp: Verbose: 00000231A448BA00: Received response header 'Vary: Accept-Encoding'. +[2018.11.29-17.16.18:636][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Received header (52 bytes) +[2018.11.29-17.16.18:636][ 90]LogHttp: Verbose: 00000231A448BA00: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.18:636][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Received header (50 bytes) +[2018.11.29-17.16.18:636][ 90]LogHttp: Verbose: 00000231A448BA00: Received response header 'X-Epic-Correlation-ID: FN-VLwcVMlkmUe62H4_oObFng'. +[2018.11.29-17.16.18:637][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Received header (24 bytes) +[2018.11.29-17.16.18:637][ 90]LogHttp: Verbose: 00000231A448BA00: Received response header 'Content-Encoding: gzip'. +[2018.11.29-17.16.18:637][ 90]LogHttp: Verbose: 00000231A448BA00: Received response header ''. +[2018.11.29-17.16.18:637][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Received header (2 bytes) +[2018.11.29-17.16.18:637][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Received data (175 bytes) +[2018.11.29-17.16.18:637][ 90]LogHttp: Verbose: 00000231A448BA00: ReceiveResponseBodyCallback: 199 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=199, Response->TotalBytesRead=0, Response->GetContentLength()=0, SizeToDownload=199 (<-this will get returned from the callback)) +[2018.11.29-17.16.18:637][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Received SSL data (5 bytes) +[2018.11.29-17.16.18:637][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Received data (5 bytes) +[2018.11.29-17.16.18:637][ 90]LogHttp: VeryVerbose: 00000231A448BA00: 'Connection cache is full, closing the oldest one.' +[2018.11.29-17.16.18:638][ 90]LogHttp: VeryVerbose: 00000231A448BA00: 'Closing connection 1' +[2018.11.29-17.16.18:638][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:638][ 90]LogHttp: VeryVerbose: 00000231A448BA00: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.16.18:638][ 90]LogHttp: VeryVerbose: 00000231A448BA00: Sent SSL data (2 bytes) +[2018.11.29-17.16.18:638][ 90]LogHttp: VeryVerbose: 00000231A448BA00: 'Connection #6 to host lightswitch-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.18:638][ 90]LogHttp: Verbose: Request 00000231A448BA00 (easy handle:000002319346AAB0) has completed (code:0) and has been marked as such +[2018.11.29-17.16.18:638][ 90]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:639][ 90]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:639][ 90]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:639][ 90]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:639][ 90]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:639][ 90]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:639][ 90]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:639][ 90]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:639][ 90]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:639][ 90]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:639][ 90]LogHttp: 00000231A448BA00: request has been successfully processed. URL: https://lightswitch-public-service-gamedev.ol.epicgames.net/lightswitch/api/service/bulk/status?serviceId=FortniteDevLatest, HTTP code: 200, content length: -1, actual payload size: 199 +[2018.11.29-17.16.18:639][ 90]LogHttp: Verbose: 00000231A448BA00 Response Header Date: Thu, 29 Nov 2018 17:16:18 GMT +[2018.11.29-17.16.18:639][ 90]LogHttp: Verbose: 00000231A448BA00 Response Header Content-Type: application/json +[2018.11.29-17.16.18:640][ 90]LogHttp: Verbose: 00000231A448BA00 Response Header Transfer-Encoding: chunked +[2018.11.29-17.16.18:640][ 90]LogHttp: Verbose: 00000231A448BA00 Response Header Connection: keep-alive +[2018.11.29-17.16.18:640][ 90]LogHttp: Verbose: 00000231A448BA00 Response Header Vary: Accept-Encoding +[2018.11.29-17.16.18:640][ 90]LogHttp: Verbose: 00000231A448BA00 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.18:640][ 90]LogHttp: Verbose: 00000231A448BA00 Response Header X-Epic-Correlation-ID: FN-VLwcVMlkmUe62H4_oObFng +[2018.11.29-17.16.18:640][ 90]LogHttp: Verbose: 00000231A448BA00 Response Header Content-Encoding: gzip +[2018.11.29-17.16.18:640][ 90]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:640][ 90]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:640][ 90]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:648][ 90]LogOnlineAccount: Display: [UOnlineAccountCommon::ContinueLoggingIn] Login: Checking entitlements... (CheckEntitledToPlay) +[2018.11.29-17.16.18:648][ 90]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:651][ 91]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:651][ 91]LogHttp: Verbose: 00000231A22CED40: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/enabled_features' +[2018.11.29-17.16.18:651][ 91]LogHttp: Verbose: 00000231A22CED40: Verb='GET' +[2018.11.29-17.16.18:651][ 91]LogHttp: Verbose: 00000231A22CED40: Custom headers are present +[2018.11.29-17.16.18:651][ 91]LogHttp: Verbose: 00000231A22CED40: Payload size=0 +[2018.11.29-17.16.18:651][ 91]LogHttp: Verbose: 00000231A22CED40: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.18:651][ 91]LogHttp: Verbose: 00000231A22CED40: Adding header 'X-Epic-Correlation-ID: FN-jCYiIB2bKUa-DbXJYIxIjA' +[2018.11.29-17.16.18:651][ 91]LogHttp: Verbose: 00000231A22CED40: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.18:651][ 91]LogHttp: Verbose: 00000231A22CED40: Adding header 'Content-Length: 0' +[2018.11.29-17.16.18:651][ 91]LogHttp: Verbose: 00000231A22CED40: Adding header 'Expect: ' +[2018.11.29-17.16.18:651][ 91]LogHttp: 00000231A22CED40: Starting GET request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/enabled_features' +[2018.11.29-17.16.18:651][ 91]LogHttp: Verbose: 00000231A22CED40: request (easy handle:00000231FBAC5560) has been added to threaded queue for processing +[2018.11.29-17.16.18:666][ 92]LogHttp: Verbose: 00000231A22CED40: request (easy handle:00000231FBAC5560) has started threaded processing +[2018.11.29-17.16.18:666][ 92]LogHttp: VeryVerbose: 00000231A22CED40: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.18:666][ 92]LogHttp: VeryVerbose: 00000231A22CED40: 'Re-using existing connection! (#3) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.18:666][ 92]LogHttp: VeryVerbose: 00000231A22CED40: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#3)' +[2018.11.29-17.16.18:666][ 92]LogHttp: VeryVerbose: 00000231A22CED40: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:666][ 92]LogHttp: VeryVerbose: 00000231A22CED40: Sent header (1023 bytes) - GET /fortnite/api/game/v2/enabled_features HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/jsonX-Epic-Correlation-ID: FN-jCYiIB2bKUa-DbXJYIxIjAUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM0RoMXFQVm9LNXp2M +[2018.11.29-17.16.18:717][ 95]LogHttp: VeryVerbose: 00000231A22CED40: Received SSL data (5 bytes) +[2018.11.29-17.16.18:717][ 95]LogHttp: VeryVerbose: 00000231A22CED40: Received header (17 bytes) +[2018.11.29-17.16.18:717][ 95]LogHttp: Verbose: 00000231A22CED40: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.18:717][ 95]LogHttp: VeryVerbose: 00000231A22CED40: Received header (32 bytes) +[2018.11.29-17.16.18:717][ 95]LogHttp: Verbose: 00000231A22CED40: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.18:718][ 95]LogHttp: VeryVerbose: 00000231A22CED40: Received header (37 bytes) +[2018.11.29-17.16.18:718][ 95]LogHttp: Verbose: 00000231A22CED40: Received response header 'Date: Thu, 29 Nov 2018 17:16:18 GMT'. +[2018.11.29-17.16.18:718][ 95]LogHttp: VeryVerbose: 00000231A22CED40: Received header (31 bytes) +[2018.11.29-17.16.18:718][ 95]LogHttp: Verbose: 00000231A22CED40: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.18:718][ 95]LogHttp: VeryVerbose: 00000231A22CED40: Received header (50 bytes) +[2018.11.29-17.16.18:718][ 95]LogHttp: Verbose: 00000231A22CED40: Received response header 'X-Epic-Correlation-ID: FN-jCYiIB2bKUa-DbXJYIxIjA'. +[2018.11.29-17.16.18:718][ 95]LogHttp: VeryVerbose: 00000231A22CED40: Received header (52 bytes) +[2018.11.29-17.16.18:718][ 95]LogHttp: Verbose: 00000231A22CED40: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.18:718][ 95]LogHttp: VeryVerbose: 00000231A22CED40: Received header (75 bytes) +[2018.11.29-17.16.18:718][ 95]LogHttp: Verbose: 00000231A22CED40: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.18:718][ 95]LogHttp: VeryVerbose: 00000231A22CED40: Received header (19 bytes) +[2018.11.29-17.16.18:718][ 95]LogHttp: Verbose: 00000231A22CED40: Received response header 'Content-Length: 2'. +[2018.11.29-17.16.18:718][ 95]LogHttp: VeryVerbose: 00000231A22CED40: Received header (24 bytes) +[2018.11.29-17.16.18:718][ 95]LogHttp: Verbose: 00000231A22CED40: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.18:718][ 95]LogHttp: Verbose: 00000231A22CED40: Received response header ''. +[2018.11.29-17.16.18:718][ 95]LogHttp: VeryVerbose: 00000231A22CED40: Received header (2 bytes) +[2018.11.29-17.16.18:718][ 95]LogHttp: VeryVerbose: 00000231A22CED40: Received data (2 bytes) +[2018.11.29-17.16.18:718][ 95]LogHttp: Verbose: 00000231A22CED40: ReceiveResponseBodyCallback: 2 bytes out of 2 received. (SizeInBlocks=1, BlockSizeInBytes=2, Response->TotalBytesRead=0, Response->GetContentLength()=2, SizeToDownload=2 (<-this will get returned from the callback)) +[2018.11.29-17.16.18:718][ 95]LogHttp: VeryVerbose: 00000231A22CED40: 'Connection cache is full, closing the oldest one.' +[2018.11.29-17.16.18:718][ 95]LogHttp: VeryVerbose: 00000231A22CED40: 'Closing connection 4' +[2018.11.29-17.16.18:719][ 95]LogHttp: VeryVerbose: 00000231A22CED40: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:719][ 95]LogHttp: VeryVerbose: 00000231A22CED40: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.16.18:719][ 95]LogHttp: VeryVerbose: 00000231A22CED40: Sent SSL data (2 bytes) +[2018.11.29-17.16.18:719][ 95]LogHttp: VeryVerbose: 00000231A22CED40: 'Connection #3 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.18:719][ 95]LogHttp: Verbose: Request 00000231A22CED40 (easy handle:00000231FBAC5560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.18:719][ 95]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:719][ 95]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:719][ 95]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:719][ 95]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:719][ 95]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:719][ 95]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:720][ 95]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:720][ 95]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:720][ 95]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:720][ 95]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:720][ 95]LogHttp: 00000231A22CED40: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/enabled_features, HTTP code: 200, content length: 2, actual payload size: 2 +[2018.11.29-17.16.18:720][ 95]LogHttp: Verbose: 00000231A22CED40 Response Header Content-Type: application/json +[2018.11.29-17.16.18:720][ 95]LogHttp: Verbose: 00000231A22CED40 Response Header Date: Thu, 29 Nov 2018 17:16:18 GMT +[2018.11.29-17.16.18:720][ 95]LogHttp: Verbose: 00000231A22CED40 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.18:720][ 95]LogHttp: Verbose: 00000231A22CED40 Response Header X-Epic-Correlation-ID: FN-jCYiIB2bKUa-DbXJYIxIjA +[2018.11.29-17.16.18:720][ 95]LogHttp: Verbose: 00000231A22CED40 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.18:720][ 95]LogHttp: Verbose: 00000231A22CED40 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.18:720][ 95]LogHttp: Verbose: 00000231A22CED40 Response Header Content-Length: 2 +[2018.11.29-17.16.18:720][ 95]LogHttp: Verbose: 00000231A22CED40 Response Header Connection: keep-alive +[2018.11.29-17.16.18:720][ 95]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:734][ 96]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:734][ 96]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:734][ 96]LogOnline: OSS: QueryAvailableFeatures request complete and valid. Response string length is 2, code is 200 +[2018.11.29-17.16.18:745][ 96]LogOnline: OSS: QueryAvailableFeatures request complete. url=https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/enabled_features code=200 response=[] +[2018.11.29-17.16.18:759][ 96]LogOnlineAccount: Display: [UOnlineAccountCommon::ContinueLoggingIn] Login: Downloading user settings... (DownloadingClientSettings) +[2018.11.29-17.16.18:759][ 96]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:762][ 97]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:762][ 97]LogHttp: Verbose: 00000231A22CBB40: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/cloudstorage/user/e6f5091c3b2f4c359cf2aad75c424de0' +[2018.11.29-17.16.18:762][ 97]LogHttp: Verbose: 00000231A22CBB40: Verb='GET' +[2018.11.29-17.16.18:762][ 97]LogHttp: Verbose: 00000231A22CBB40: Custom headers are present +[2018.11.29-17.16.18:762][ 97]LogHttp: Verbose: 00000231A22CBB40: Payload size=0 +[2018.11.29-17.16.18:762][ 97]LogHttp: Verbose: 00000231A22CBB40: Adding header 'X-Epic-Correlation-ID: FN-AX5y0oj980y7mGCPUlxfEw' +[2018.11.29-17.16.18:762][ 97]LogHttp: Verbose: 00000231A22CBB40: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.18:762][ 97]LogHttp: Verbose: 00000231A22CBB40: Adding header 'Content-Length: 0' +[2018.11.29-17.16.18:762][ 97]LogHttp: Verbose: 00000231A22CBB40: Adding header 'Expect: ' +[2018.11.29-17.16.18:762][ 97]LogHttp: 00000231A22CBB40: Starting GET request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/cloudstorage/user/e6f5091c3b2f4c359cf2aad75c424de0' +[2018.11.29-17.16.18:762][ 97]LogHttp: Verbose: 00000231A22CBB40: request (easy handle:00000231A2065560) has been added to threaded queue for processing +[2018.11.29-17.16.18:793][ 99]LogHttp: Verbose: 00000231A22CBB40: request (easy handle:00000231A2065560) has started threaded processing +[2018.11.29-17.16.18:793][ 99]LogHttp: VeryVerbose: 00000231A22CBB40: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.18:793][ 99]LogHttp: VeryVerbose: 00000231A22CBB40: 'Re-using existing connection! (#3) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.18:793][ 99]LogHttp: VeryVerbose: 00000231A22CBB40: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#3)' +[2018.11.29-17.16.18:793][ 99]LogHttp: VeryVerbose: 00000231A22CBB40: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:793][ 99]LogHttp: VeryVerbose: 00000231A22CBB40: Sent header (1023 bytes) - GET /fortnite/api/cloudstorage/user/e6f5091c3b2f4c359cf2aad75c424de0 HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-AX5y0oj980y7mGCPUlxfEwUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM0RoMXFQVm9LNXp2M1J0TjZ +[2018.11.29-17.16.18:845][102]LogHttp: VeryVerbose: 00000231A22CBB40: Received SSL data (5 bytes) +[2018.11.29-17.16.18:845][102]LogHttp: VeryVerbose: 00000231A22CBB40: Received header (17 bytes) +[2018.11.29-17.16.18:845][102]LogHttp: Verbose: 00000231A22CBB40: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.18:845][102]LogHttp: VeryVerbose: 00000231A22CBB40: Received header (32 bytes) +[2018.11.29-17.16.18:845][102]LogHttp: Verbose: 00000231A22CBB40: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.18:846][102]LogHttp: VeryVerbose: 00000231A22CBB40: Received header (37 bytes) +[2018.11.29-17.16.18:846][102]LogHttp: Verbose: 00000231A22CBB40: Received response header 'Date: Thu, 29 Nov 2018 17:16:18 GMT'. +[2018.11.29-17.16.18:846][102]LogHttp: VeryVerbose: 00000231A22CBB40: Received header (31 bytes) +[2018.11.29-17.16.18:846][102]LogHttp: Verbose: 00000231A22CBB40: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.18:846][102]LogHttp: VeryVerbose: 00000231A22CBB40: Received header (50 bytes) +[2018.11.29-17.16.18:846][102]LogHttp: Verbose: 00000231A22CBB40: Received response header 'X-Epic-Correlation-ID: FN-AX5y0oj980y7mGCPUlxfEw'. +[2018.11.29-17.16.18:846][102]LogHttp: VeryVerbose: 00000231A22CBB40: Received header (52 bytes) +[2018.11.29-17.16.18:846][102]LogHttp: Verbose: 00000231A22CBB40: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.18:846][102]LogHttp: VeryVerbose: 00000231A22CBB40: Received header (75 bytes) +[2018.11.29-17.16.18:846][102]LogHttp: Verbose: 00000231A22CBB40: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.18:846][102]LogHttp: VeryVerbose: 00000231A22CBB40: Received header (22 bytes) +[2018.11.29-17.16.18:846][102]LogHttp: Verbose: 00000231A22CBB40: Received response header 'Content-Length: 1953'. +[2018.11.29-17.16.18:846][102]LogHttp: VeryVerbose: 00000231A22CBB40: Received header (24 bytes) +[2018.11.29-17.16.18:846][102]LogHttp: Verbose: 00000231A22CBB40: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.18:846][102]LogHttp: Verbose: 00000231A22CBB40: Received response header ''. +[2018.11.29-17.16.18:846][102]LogHttp: VeryVerbose: 00000231A22CBB40: Received header (2 bytes) +[2018.11.29-17.16.18:846][102]LogHttp: VeryVerbose: 00000231A22CBB40: Received data (1953 bytes) +[2018.11.29-17.16.18:846][102]LogHttp: Verbose: 00000231A22CBB40: ReceiveResponseBodyCallback: 1953 bytes out of 1953 received. (SizeInBlocks=1, BlockSizeInBytes=1953, Response->TotalBytesRead=0, Response->GetContentLength()=1953, SizeToDownload=1953 (<-this will get returned from the callback)) +[2018.11.29-17.16.18:846][102]LogHttp: VeryVerbose: 00000231A22CBB40: 'Connection #3 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.18:847][102]LogHttp: Verbose: Request 00000231A22CBB40 (easy handle:00000231A2065560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.18:847][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:847][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:847][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:847][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:847][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:847][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:847][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:848][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:848][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:848][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:848][102]LogHttp: 00000231A22CBB40: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/cloudstorage/user/e6f5091c3b2f4c359cf2aad75c424de0, HTTP code: 200, content length: 1953, actual payload size: 1953 +[2018.11.29-17.16.18:848][102]LogHttp: Verbose: 00000231A22CBB40 Response Header Content-Type: application/json +[2018.11.29-17.16.18:848][102]LogHttp: Verbose: 00000231A22CBB40 Response Header Date: Thu, 29 Nov 2018 17:16:18 GMT +[2018.11.29-17.16.18:848][102]LogHttp: Verbose: 00000231A22CBB40 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.18:848][102]LogHttp: Verbose: 00000231A22CBB40 Response Header X-Epic-Correlation-ID: FN-AX5y0oj980y7mGCPUlxfEw +[2018.11.29-17.16.18:848][102]LogHttp: Verbose: 00000231A22CBB40 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.18:848][102]LogHttp: Verbose: 00000231A22CBB40 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.18:848][102]LogHttp: Verbose: 00000231A22CBB40 Response Header Content-Length: 1953 +[2018.11.29-17.16.18:848][102]LogHttp: Verbose: 00000231A22CBB40 Response Header Connection: keep-alive +[2018.11.29-17.16.18:848][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:848][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.18:848][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:849][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.18:850][102]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.18:850][102]LogHttp: Verbose: 00000231A448C180: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/cloudstorage/user/e6f5091c3b2f4c359cf2aad75c424de0/ClientSettings.Sav' +[2018.11.29-17.16.18:850][102]LogHttp: Verbose: 00000231A448C180: Verb='GET' +[2018.11.29-17.16.18:850][102]LogHttp: Verbose: 00000231A448C180: Custom headers are present +[2018.11.29-17.16.18:850][102]LogHttp: Verbose: 00000231A448C180: Payload size=0 +[2018.11.29-17.16.18:850][102]LogHttp: Verbose: 00000231A448C180: Adding header 'X-Epic-Correlation-ID: FN-IN3ksgs1sEayCqwW1xEKoA' +[2018.11.29-17.16.18:850][102]LogHttp: Verbose: 00000231A448C180: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.18:850][102]LogHttp: Verbose: 00000231A448C180: Adding header 'Content-Length: 0' +[2018.11.29-17.16.18:850][102]LogHttp: Verbose: 00000231A448C180: Adding header 'Expect: ' +[2018.11.29-17.16.18:850][102]LogHttp: 00000231A448C180: Starting GET request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/cloudstorage/user/e6f5091c3b2f4c359cf2aad75c424de0/ClientSettings.Sav' +[2018.11.29-17.16.18:850][102]LogHttp: Verbose: 00000231A448C180: request (easy handle:00000231A206AAB0) has been added to threaded queue for processing +[2018.11.29-17.16.18:879][104]LogHttp: Verbose: 00000231A448C180: request (easy handle:00000231A206AAB0) has started threaded processing +[2018.11.29-17.16.18:879][104]LogHttp: VeryVerbose: 00000231A448C180: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.18:879][104]LogHttp: VeryVerbose: 00000231A448C180: 'Re-using existing connection! (#3) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.18:879][104]LogHttp: VeryVerbose: 00000231A448C180: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#3)' +[2018.11.29-17.16.18:879][104]LogHttp: VeryVerbose: 00000231A448C180: Sent SSL data (5 bytes) +[2018.11.29-17.16.18:879][104]LogHttp: VeryVerbose: 00000231A448C180: Sent header (1023 bytes) - GET /fortnite/api/cloudstorage/user/e6f5091c3b2f4c359cf2aad75c424de0/ClientSettings.Sav HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-IN3ksgs1sEayCqwW1xEKoAUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM0Ro +[2018.11.29-17.16.19:012][112]LogHttp: VeryVerbose: 00000231A448C180: Received SSL data (5 bytes) +[2018.11.29-17.16.19:012][112]LogHttp: VeryVerbose: 00000231A448C180: Received header (17 bytes) +[2018.11.29-17.16.19:012][112]LogHttp: Verbose: 00000231A448C180: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.19:012][112]LogHttp: VeryVerbose: 00000231A448C180: Received header (26 bytes) +[2018.11.29-17.16.19:012][112]LogHttp: Verbose: 00000231A448C180: Received response header 'Content-Type: text/plain'. +[2018.11.29-17.16.19:012][112]LogHttp: VeryVerbose: 00000231A448C180: Received header (37 bytes) +[2018.11.29-17.16.19:012][112]LogHttp: Verbose: 00000231A448C180: Received response header 'Date: Thu, 29 Nov 2018 17:16:18 GMT'. +[2018.11.29-17.16.19:012][112]LogHttp: VeryVerbose: 00000231A448C180: Received header (31 bytes) +[2018.11.29-17.16.19:012][112]LogHttp: Verbose: 00000231A448C180: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.19:012][112]LogHttp: VeryVerbose: 00000231A448C180: Received header (50 bytes) +[2018.11.29-17.16.19:013][112]LogHttp: Verbose: 00000231A448C180: Received response header 'X-Epic-Correlation-ID: FN-IN3ksgs1sEayCqwW1xEKoA'. +[2018.11.29-17.16.19:013][112]LogHttp: VeryVerbose: 00000231A448C180: Received header (52 bytes) +[2018.11.29-17.16.19:013][112]LogHttp: Verbose: 00000231A448C180: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.19:013][112]LogHttp: VeryVerbose: 00000231A448C180: Received header (75 bytes) +[2018.11.29-17.16.19:013][112]LogHttp: Verbose: 00000231A448C180: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.19:013][112]LogHttp: VeryVerbose: 00000231A448C180: Received header (22 bytes) +[2018.11.29-17.16.19:013][112]LogHttp: Verbose: 00000231A448C180: Received response header 'Content-Length: 1850'. +[2018.11.29-17.16.19:013][112]LogHttp: VeryVerbose: 00000231A448C180: Received header (24 bytes) +[2018.11.29-17.16.19:013][112]LogHttp: Verbose: 00000231A448C180: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.19:013][112]LogHttp: Verbose: 00000231A448C180: Received response header ''. +[2018.11.29-17.16.19:013][112]LogHttp: VeryVerbose: 00000231A448C180: Received header (2 bytes) +[2018.11.29-17.16.19:013][112]LogHttp: VeryVerbose: 00000231A448C180: Received data (1850 bytes) +[2018.11.29-17.16.19:013][112]LogHttp: Verbose: 00000231A448C180: ReceiveResponseBodyCallback: 1850 bytes out of 1850 received. (SizeInBlocks=1, BlockSizeInBytes=1850, Response->TotalBytesRead=0, Response->GetContentLength()=1850, SizeToDownload=1850 (<-this will get returned from the callback)) +[2018.11.29-17.16.19:013][112]LogHttp: VeryVerbose: 00000231A448C180: 'Connection #3 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.19:014][112]LogHttp: Verbose: Request 00000231A448C180 (easy handle:00000231A206AAB0) has completed (code:0) and has been marked as such +[2018.11.29-17.16.19:014][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:014][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:014][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:014][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:014][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:014][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:014][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:014][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:015][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:015][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:015][112]LogHttp: 00000231A448C180: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/cloudstorage/user/e6f5091c3b2f4c359cf2aad75c424de0/ClientSettings.Sav, HTTP code: 200, content length: 1850, actual payload size: 1850 +[2018.11.29-17.16.19:015][112]LogHttp: Verbose: 00000231A448C180 Response Header Content-Type: text/plain +[2018.11.29-17.16.19:015][112]LogHttp: Verbose: 00000231A448C180 Response Header Date: Thu, 29 Nov 2018 17:16:18 GMT +[2018.11.29-17.16.19:015][112]LogHttp: Verbose: 00000231A448C180 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.19:015][112]LogHttp: Verbose: 00000231A448C180 Response Header X-Epic-Correlation-ID: FN-IN3ksgs1sEayCqwW1xEKoA +[2018.11.29-17.16.19:015][112]LogHttp: Verbose: 00000231A448C180 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.19:016][112]LogHttp: Verbose: 00000231A448C180 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.19:016][112]LogHttp: Verbose: 00000231A448C180 Response Header Content-Length: 1850 +[2018.11.29-17.16.19:016][112]LogHttp: Verbose: 00000231A448C180 Response Header Connection: keep-alive +[2018.11.29-17.16.19:016][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.19:016][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:016][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.19:020][112]LogFortSettings: Client settings finished loading with result Success +[2018.11.29-17.16.19:020][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:020][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:020][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:020][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:020][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:020][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:020][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:020][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:021][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:021][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:021][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:021][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:021][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:021][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:021][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:021][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:022][112]LogConsoleResponse: Display: Apply Settings: +[2018.11.29-17.16.19:022][112]LogConfig: Applying CVar settings from Section [ViewDistanceQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.16.19:022][112]LogConfig: Setting CVar [[r.SkeletalMeshLODBias:0]] +[2018.11.29-17.16.19:022][112]LogConfig: Setting CVar [[r.ViewDistanceScale:1.67]] +[2018.11.29-17.16.19:023][112]LogConfig: Setting CVar [[Fort.Scalability.AIBudget:8,16]] +[2018.11.29-17.16.19:023][112]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget:5,10,10,75]] +[2018.11.29-17.16.19:023][112]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget.URORates:0,1,2,3]] +[2018.11.29-17.16.19:023][112]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget.SkelMeshMinLOD:0,1,1,2]] +[2018.11.29-17.16.19:023][112]LogConfig: Setting CVar [[Fort.Scalability.BucketDistances:50,100,250,500]] +[2018.11.29-17.16.19:023][112]LogConfig: Setting CVar [[Fort.Scalability.PlayerCosmeticPropBudget:0]] +[2018.11.29-17.16.19:023][112]LogConfig: Setting CVar [[Fort.Scalability.TieUROToLODs:1]] +[2018.11.29-17.16.19:023][112]LogConfig: Setting CVar [[Fort.Scalability.EnableAnimCurveOptimizations:1]] +[2018.11.29-17.16.19:023][112]LogConfig: Setting CVar [[Athena.Scalability.SecondarySkelMeshTickingThreshold:1]] +[2018.11.29-17.16.19:023][112]LogConfig: Setting CVar [[p.AnimDynamicsLODThreshold:1]] +[2018.11.29-17.16.19:023][112]LogConfig: Setting CVar [[p.RigidBodyLODThreshold:1]] +[2018.11.29-17.16.19:023][112]LogConfig: Setting CVar [[r.StaticMeshLODDistanceScale:1]] +[2018.11.29-17.16.19:023][112]LogConfig: Setting CVar [[r.ViewDistanceScale.SecondaryScale:1.0]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[r.HLOD.DistanceOverride:40000,35000]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[Athena.Scalability.HLODProxyMaxDrawDistance:0.0]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMaxAngle:80.0]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMaxAngleScale:1.0]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMinAngle:15.0]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMinAngleScale:2.0]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[Athena.EnableProxyPredictionPawnLOD:1]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[Athena.EnableProxySimulatedStepUpLOD:0]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[Athena.EnableProxySimulatedStepUpMinNormalZ:0.1]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[Athena.ForceThrottledSimulatedFloorChecks:1]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[Athena.NetworkSmoothingSkipFramesLowestLOD:1]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[Athena.NetworkSmoothingSkipFramesInvisible:4]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_Players:50]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_AI:50]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_Combined:50]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[r.NeverOcclusionTestDistance:1250]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[a.Budget.Enabled:1]] +[2018.11.29-17.16.19:024][112]LogConfig: Setting CVar [[a.Budget.BudgetMs:1.5]] +[2018.11.29-17.16.19:024][112]LogConfig: Applying CVar settings from Section [AntiAliasingQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.PostProcessAAQuality:3]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.Tonemapper.Sharpen:0.5]] +[2018.11.29-17.16.19:025][112]LogConfig: Applying CVar settings from Section [ShadowQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.LightFunctionQuality:1]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.ShadowQuality:5]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.Shadow.CSM.MaxCascades:2]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.Shadow.MaxResolution:1024]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.Shadow.MaxCSMResolution:2048]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.Shadow.RadiusThreshold:0.04]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.Shadow.DistanceScale:0.85]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.Shadow.CSM.TransitionScale:0.8]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.Shadow.PreShadowResolutionFactor:0.5]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.DistanceFieldShadowing:1]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.DistanceFieldAO:1]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.AOQuality:1]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.VolumetricFog:1]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.VolumetricFog.GridPixelSize:16]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.VolumetricFog.GridSizeZ:64]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.VolumetricFog.HistoryMissSupersampleCount:4]] +[2018.11.29-17.16.19:025][112]LogConfig: Setting CVar [[r.LightMaxDrawDistanceScale:.5]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.CapsuleShadows:1]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.SimpleForwardShading:0]] +[2018.11.29-17.16.19:026][112]LogConsoleManager: Warning: Setting the console variable 'r.SimpleForwardShading' with 'SetByScalability' was ignored as it is lower priority than the previous 'SetByConsole'. Value remains '0' +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.Shadow.MaxNumPointShadowCacheUpdatesPerFrame:2]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.Shadow.MaxNumSpotShadowCacheUpdatesPerFrame:4]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[Fort.TODDirectionalLightUpdateRate:0]] +[2018.11.29-17.16.19:026][112]LogConfig: Applying CVar settings from Section [PostProcessQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.MotionBlurQuality:3]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.AmbientOcclusionMipLevelFactor:0.6]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.AmbientOcclusionMaxQuality:100]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.AmbientOcclusionLevels:-1]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.AmbientOcclusionRadiusScale:1.5]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.DepthOfFieldQuality:2]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.RenderTargetPoolMin:400]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.LensFlareQuality:2]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.SceneColorFringeQuality:1]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.EyeAdaptationQuality:1]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.BloomQuality:5]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.FastBlurThreshold:3]] +[2018.11.29-17.16.19:026][112]LogConfig: Setting CVar [[r.Upscale.Quality:2]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.Tonemapper.GrainQuantization:1]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.LightShaftQuality:0]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.Filter.SizeScale:0.8]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.Tonemapper.Quality:5]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.DOF.Gather.AccumulatorQuality:0 ; lower gathering accumulator quality]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.DOF.Gather.PostfilterMethod:2 ; Max3x3 postfilering method]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.DOF.Gather.EnableBokehSettings:0 ; no bokeh simulation when gathering]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.DOF.Gather.RingCount:4 ; medium number of samples when gathering]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.DOF.Scatter.ForegroundCompositing:1 ; additive foreground scattering]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.DOF.Scatter.BackgroundCompositing:1 ; no background occlusion]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.DOF.Scatter.EnableBokehSettings:0 ; no bokeh simulation when scattering]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.DOF.Scatter.MaxSpriteRatio:0.04 ; only a maximum of 4% of scattered bokeh]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.DOF.Recombine.Quality:0 ; no slight out of focus]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.DOF.TemporalAAQuality:0 ; faster temporal accumulation]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.DOF.Kernel.MaxForegroundRadius:0.012 ; required because of AccumulatorQuality=0]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.DOF.Kernel.MaxBackgroundRadius:0.012 ; required because of AccumulatorQuality=0]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.AmbientOcclusion.Compute:0]] +[2018.11.29-17.16.19:027][112]LogConfig: Applying CVar settings from Section [TextureQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.Streaming.MipBias:0]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.Streaming.AmortizeCPUToGPUCopy:0]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.Streaming.MaxNumTexturesToStreamPerFrame:0]] +[2018.11.29-17.16.19:027][112]LogConfig: Setting CVar [[r.Streaming.Boost:1]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.MaxAnisotropy:4]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.Streaming.LimitPoolSizeToVRAM:1]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.Streaming.PoolSize:800]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.Streaming.MaxEffectiveScreenSize:0]] +[2018.11.29-17.16.19:028][112]LogConfig: Applying CVar settings from Section [EffectsQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.TranslucencyLightingVolumeDim:48]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.RefractionQuality:2]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.SSR.Quality:2]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.SceneColorFormat:3]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.DetailMode:1]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.TranslucencyVolumeBlur:1]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.MaterialQualityLevel:1 ; High quality]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.SSS.Scale:1]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.SSS.SampleSet:1]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.SSS.Quality:-1]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.SSS.HalfRes:1]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.EmitterSpawnRateScale:0.5]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[r.ParticleLightQuality:1]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[Fort.Wind:1]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_Low:0.85]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_Medium:0.7]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_High:0.3]] +[2018.11.29-17.16.19:028][112]LogConfig: Setting CVar [[fx.Significance.MaxRange:14000]] +[2018.11.29-17.16.19:029][112]LogConfig: Setting CVar [[p.AnimDynamicsWind:1]] +[2018.11.29-17.16.19:029][112]LogConfig: Setting CVar [[r.SeparateTranslucency:1]] +[2018.11.29-17.16.19:029][112]LogConfig: Applying CVar settings from Section [FoliageQuality@3] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.16.19:029][112]LogConfig: Setting CVar [[foliage.DensityScale:1.0]] +[2018.11.29-17.16.19:029][112]LogConfig: Setting CVar [[grass.DensityScale:1.0]] +[2018.11.29-17.16.19:029][112]LogConsoleResponse: User settings scalability group: Mixed +[2018.11.29-17.16.19:029][112]LogRHI: Display: Applied New ShaderPipelineCache GameUsageMask [Material=1 | Shadow=2 | Foliage=3] +[2018.11.29-17.16.19:171][112]LogFortChat: *!* UFortChatManager::AttemptJoinReservedChatRooms - SubGame: Athena, DeltaSeconds: 0.000000 +[2018.11.29-17.16.19:171][112]LogFortChat: *!* UFortChatManager::AttemptJoinReservedChatRooms - ShouldRequestRooms: 0, ChatRestricted: 0 +[2018.11.29-17.16.19:171][112]LogFortChat: NOT joinining general chat, requesting rooms is currently disabled +[2018.11.29-17.16.19:171][112]LogFortChat: *!* UFortChatManager::DisableGlobalChatRoom - DisableReason: 1 +[2018.11.29-17.16.19:171][112]LogFortChat: *!* UFortChatRoomJoinHelper::DisableChatRoom - DisableReason +[2018.11.29-17.16.19:171][112]LogFortChat: *!* UFortChatManager::DisableFounderChatRoom - DisableReason: 1 +[2018.11.29-17.16.19:171][112]LogFortChat: *!* UFortChatRoomJoinHelper::DisableChatRoom - DisableReason +[2018.11.29-17.16.19:171][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:171][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:171][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:171][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:171][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:171][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:171][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:171][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:172][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:172][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:172][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:172][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:172][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:172][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:172][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:172][112]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.19:278][112]LogVivoxVoiceChat: Initializing Vivox 4.9.0002.30545 +[2018.11.29-17.16.19:496][112]LogVivoxVoiceChat: Warning: Error: VivoxMediaVxa::VxaDeviceFactory::GetDefaultCaptureDevice(91) - vxa_list_capture_devices->num_devices == 0 +[2018.11.29-17.16.19:496][112]LogVivoxVoiceChat: Warning: Error: VivoxMediaVxa::VxaDeviceFactory::GetDefaultCaptureDevice(91) - vxa_list_capture_devices->num_devices == 0 +[2018.11.29-17.16.19:496][112]LogVivoxVoiceChat: Warning: Error: VivoxMediaVxa::VxaDeviceFactory::GetDefaultCaptureDevice(91) - vxa_list_capture_devices->num_devices == 0 +[2018.11.29-17.16.19:496][112]LogVivoxVoiceChat: Warning: Error: VivoxMediaVxa::VxaDeviceFactory::GetDefaultCaptureDevice(91) - vxa_list_capture_devices->num_devices == 0 +[2018.11.29-17.16.19:496][112]LogVivoxVoiceChat: Warning: Error: VivoxMediaVxa::VxaDeviceFactory::GetDefaultCaptureDevice(91) - vxa_list_capture_devices->num_devices == 0 +[2018.11.29-17.16.19:500][112]LogOnlineAccount: Display: [UOnlineAccountCommon::ContinueLoggingIn] Login: Downloading profile... (QueryProfile) +[2018.11.29-17.16.19:506][112]LogCatalogHelper: AppStore set to EpicPurchasingService +[2018.11.29-17.16.19:507][112]LogFort: Loading GameData: /Game/Balance/AthenaGameData.AthenaGameData ... +[2018.11.29-17.16.19:509][112]LogStats: ... GameData loaded! - 0.002 s +[2018.11.29-17.16.19:510][112]LogFortPlayerRegistration: BindToState(AFortPlayerState* State) trying to initialize ability system actor +[2018.11.29-17.16.19:510][112]LogFortPlayerRegistration: InitializeAbilitySystemActor initialized with proxy for LoadBot07063 +[2018.11.29-17.16.19:511][112]LogFort: ApplyHeroEffectsAndAbilities succeeded +[2018.11.29-17.16.19:511][112]LogFort: ApplyHomebaseEffectsOnPlayerSetup Succeeded +[2018.11.29-17.16.19:512][112]LogFortPlayerRegistration: BindToPlayerController trying to initialize ability system actor +[2018.11.29-17.16.19:512][112]LogFort: ApplyHeroEffectsAndAbilities succeeded +[2018.11.29-17.16.19:512][112]LogFort: ApplyHomebaseEffectsOnPlayerSetup Succeeded +[2018.11.29-17.16.19:512][112]LogFort: UFortRegisteredPlayerInfo::SynchronizeProfile is adding FFortProfileSynchronizeRequest : RequestId [0]. +[2018.11.29-17.16.19:513][112]LogProfileSys: Requesting full profile update for profile 'common_public' for player 'LoadBot07063' +[2018.11.29-17.16.19:513][112]LogProfileSys: Requesting full profile update for profile 'common_core' for player 'LoadBot07063' +[2018.11.29-17.16.19:513][112]LogProfileSys: Requesting full profile update for profile 'athena' for player 'LoadBot07063' +[2018.11.29-17.16.19:513][112]LogProfileSys: MCP-Profile: Dispatching request to https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=common_public&rvn=-1 +[2018.11.29-17.16.19:513][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.19:513][112]LogProfileSys: MCP-Profile: Command QueryProfile queued to send +[2018.11.29-17.16.19:514][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.19:514][112]LogProfileSys: MCP-Profile: Command QueryProfile queued to send +[2018.11.29-17.16.19:514][112]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.19:514][112]LogProfileSys: MCP-Profile: Command QueryProfile queued to send +[2018.11.29-17.16.19:514][112]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [0]) Request.RequestId [0] initial WaitingFor flags [E0]. +[2018.11.29-17.16.19:514][112]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [0]) Request.RequestId [0] final WaitingFor flags [E0]. +[2018.11.29-17.16.19:514][112]LogFort: Initialized MCP profile for FortPlayerControllerFrontEnd_2147481983 (force sync: yes) +[2018.11.29-17.16.19:515][112]LogCore: Display: Setting hang detector multiplier to 3.0000s. New hang duration: 90.0000s. New present duration: 0.0000s. +[2018.11.29-17.16.19:516][112]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.19:519][112]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.19:519][112]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.19:519][112]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.19:520][112]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.19:520][112]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.19:527][113]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:527][113]LogHttp: Verbose: 00000231A0D77A40: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=common_public&rvn=-1' +[2018.11.29-17.16.19:528][113]LogHttp: Verbose: 00000231A0D77A40: Verb='POST' +[2018.11.29-17.16.19:528][113]LogHttp: Verbose: 00000231A0D77A40: Custom headers are present +[2018.11.29-17.16.19:528][113]LogHttp: Verbose: 00000231A0D77A40: Payload size=4 +[2018.11.29-17.16.19:528][113]LogHttp: Verbose: 00000231A0D77A40: Adding header 'Accept: */*' +[2018.11.29-17.16.19:528][113]LogHttp: Verbose: 00000231A0D77A40: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.19:528][113]LogHttp: Verbose: 00000231A0D77A40: Adding header 'X-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}' +[2018.11.29-17.16.19:528][113]LogHttp: Verbose: 00000231A0D77A40: Adding header 'X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119' +[2018.11.29-17.16.19:528][113]LogHttp: Verbose: 00000231A0D77A40: Adding header 'X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":-1},{"profileId":"common_core","clientCommandRevision":-1},{"profileId":"athena","clientCommandRevision":-1}]' +[2018.11.29-17.16.19:528][113]LogHttp: Verbose: 00000231A0D77A40: Adding header 'X-Epic-Correlation-ID: FN-HVlqxOkNzEiE5QKi98YVZA' +[2018.11.29-17.16.19:528][113]LogHttp: Verbose: 00000231A0D77A40: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.19:528][113]LogHttp: Verbose: 00000231A0D77A40: Adding header 'Content-Length: 4' +[2018.11.29-17.16.19:528][113]LogHttp: Verbose: 00000231A0D77A40: Adding header 'Expect: ' +[2018.11.29-17.16.19:528][113]LogHttp: 00000231A0D77A40: Starting POST request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=common_public&rvn=-1' +[2018.11.29-17.16.19:528][113]LogHttp: Verbose: 00000231A0D77A40: request (easy handle:00000231A0D85560) has been added to threaded queue for processing +[2018.11.29-17.16.19:550][115]LogHttp: Verbose: 00000231A0D77A40: request (easy handle:00000231A0D85560) has started threaded processing +[2018.11.29-17.16.19:550][115]LogHttp: VeryVerbose: 00000231A0D77A40: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.19:550][115]LogHttp: VeryVerbose: 00000231A0D77A40: 'Re-using existing connection! (#3) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.19:550][115]LogHttp: VeryVerbose: 00000231A0D77A40: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#3)' +[2018.11.29-17.16.19:550][115]LogHttp: VeryVerbose: 00000231A0D77A40: Sent SSL data (5 bytes) +[2018.11.29-17.16.19:550][115]LogHttp: VeryVerbose: 00000231A0D77A40: Sent header (1023 bytes) - POST /fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=common_public&rvn=-1 HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept-Encoding: deflate, gzipAccept: */*Content-Type: application/jsonX-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":-1},{"profileId":"common_core","clientCommandRevision":-1},{"profileId":"athena","clientCommandRevision":-1}]X-Epic-Correlation-ID: FN-HVlqxOkNzEiE5QKi98YVZAUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2 +[2018.11.29-17.16.19:550][115]LogHttp: Verbose: 00000231A0D77A40: UploadCallback: 4 bytes out of 4 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=4 (<-this will get returned from the callback)) +[2018.11.29-17.16.19:550][115]LogHttp: VeryVerbose: 00000231A0D77A40: Sent SSL data (5 bytes) +[2018.11.29-17.16.19:550][115]LogHttp: VeryVerbose: 00000231A0D77A40: Sent data (4 bytes) +[2018.11.29-17.16.19:550][115]LogHttp: VeryVerbose: 00000231A0D77A40: 'We are completely uploaded and fine' +[2018.11.29-17.16.19:551][115]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:551][115]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:634][120]LogHttp: VeryVerbose: 00000231A0D77A40: Received SSL data (5 bytes) +[2018.11.29-17.16.19:634][120]LogHttp: VeryVerbose: 00000231A0D77A40: Received header (17 bytes) +[2018.11.29-17.16.19:634][120]LogHttp: Verbose: 00000231A0D77A40: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.19:634][120]LogHttp: VeryVerbose: 00000231A0D77A40: Received header (32 bytes) +[2018.11.29-17.16.19:634][120]LogHttp: Verbose: 00000231A0D77A40: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.19:634][120]LogHttp: VeryVerbose: 00000231A0D77A40: Received header (37 bytes) +[2018.11.29-17.16.19:634][120]LogHttp: Verbose: 00000231A0D77A40: Received response header 'Date: Thu, 29 Nov 2018 17:16:19 GMT'. +[2018.11.29-17.16.19:634][120]LogHttp: VeryVerbose: 00000231A0D77A40: Received header (31 bytes) +[2018.11.29-17.16.19:634][120]LogHttp: Verbose: 00000231A0D77A40: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.19:634][120]LogHttp: VeryVerbose: 00000231A0D77A40: Received header (50 bytes) +[2018.11.29-17.16.19:634][120]LogHttp: Verbose: 00000231A0D77A40: Received response header 'X-Epic-Correlation-ID: FN-HVlqxOkNzEiE5QKi98YVZA'. +[2018.11.29-17.16.19:634][120]LogHttp: VeryVerbose: 00000231A0D77A40: Received header (52 bytes) +[2018.11.29-17.16.19:634][120]LogHttp: Verbose: 00000231A0D77A40: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.19:634][120]LogHttp: VeryVerbose: 00000231A0D77A40: Received header (75 bytes) +[2018.11.29-17.16.19:634][120]LogHttp: Verbose: 00000231A0D77A40: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.19:635][120]LogHttp: VeryVerbose: 00000231A0D77A40: Received header (33 bytes) +[2018.11.29-17.16.19:635][120]LogHttp: Verbose: 00000231A0D77A40: Received response header 'X-EpicGames-Profile-Revision: 1'. +[2018.11.29-17.16.19:635][120]LogHttp: VeryVerbose: 00000231A0D77A40: Received header (21 bytes) +[2018.11.29-17.16.19:635][120]LogHttp: Verbose: 00000231A0D77A40: Received response header 'Content-Length: 632'. +[2018.11.29-17.16.19:635][120]LogHttp: VeryVerbose: 00000231A0D77A40: Received header (24 bytes) +[2018.11.29-17.16.19:635][120]LogHttp: Verbose: 00000231A0D77A40: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.19:635][120]LogHttp: Verbose: 00000231A0D77A40: Received response header ''. +[2018.11.29-17.16.19:635][120]LogHttp: VeryVerbose: 00000231A0D77A40: Received header (2 bytes) +[2018.11.29-17.16.19:635][120]LogHttp: VeryVerbose: 00000231A0D77A40: Received data (632 bytes) +[2018.11.29-17.16.19:635][120]LogHttp: Verbose: 00000231A0D77A40: ReceiveResponseBodyCallback: 632 bytes out of 632 received. (SizeInBlocks=1, BlockSizeInBytes=632, Response->TotalBytesRead=0, Response->GetContentLength()=632, SizeToDownload=632 (<-this will get returned from the callback)) +[2018.11.29-17.16.19:635][120]LogHttp: VeryVerbose: 00000231A0D77A40: 'Connection #3 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.19:635][120]LogHttp: Verbose: Request 00000231A0D77A40 (easy handle:00000231A0D85560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.19:635][120]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:635][120]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:635][120]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:635][120]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:635][120]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:635][120]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:635][120]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:636][120]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:636][120]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:636][120]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:636][120]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:636][120]LogHttp: 00000231A0D77A40: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=common_public&rvn=-1, HTTP code: 200, content length: 632, actual payload size: 632 +[2018.11.29-17.16.19:636][120]LogHttp: Verbose: 00000231A0D77A40 Response Header Content-Type: application/json +[2018.11.29-17.16.19:636][120]LogHttp: Verbose: 00000231A0D77A40 Response Header Date: Thu, 29 Nov 2018 17:16:19 GMT +[2018.11.29-17.16.19:636][120]LogHttp: Verbose: 00000231A0D77A40 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.19:636][120]LogHttp: Verbose: 00000231A0D77A40 Response Header X-Epic-Correlation-ID: FN-HVlqxOkNzEiE5QKi98YVZA +[2018.11.29-17.16.19:636][120]LogHttp: Verbose: 00000231A0D77A40 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.19:636][120]LogHttp: Verbose: 00000231A0D77A40 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.19:636][120]LogHttp: Verbose: 00000231A0D77A40 Response Header X-EpicGames-Profile-Revision: 1 +[2018.11.29-17.16.19:636][120]LogHttp: Verbose: 00000231A0D77A40 Response Header Content-Length: 632 +[2018.11.29-17.16.19:636][120]LogHttp: Verbose: 00000231A0D77A40 Response Header Connection: keep-alive +[2018.11.29-17.16.19:636][120]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.19:636][120]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:636][120]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.19:636][120]LogProfileSys: Display: MCP-Version = gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.19:646][120]LogProfileSys: UMcpProfile::HandleProfileUpdate updated lock expiration on Account MCP:e6f5091c3b2f4c359cf2aad75c424de0 for ProfileId common_public to --- +[2018.11.29-17.16.19:646][120]LogProfileSys: MCP-Profile: Full profile update (rev=1, version=fortnite_start@w=9) for LoadBot07063 accountId=MCP:e6f5091c3b2f4c359cf2aad75c424de0 profileId=common_public. +[2018.11.29-17.16.19:646][120]LogProfileSys: Display: HandleFullProfileUpdate Complete: +[2018.11.29-17.16.19:646][120]LogProfileSys: Display: TotalTime: 0.00 +[2018.11.29-17.16.19:646][120]LogProfileSys: Display: StatUpdate: 0.00 +[2018.11.29-17.16.19:646][120]LogProfileSys: Display: ItemUpdate: 0.00 +[2018.11.29-17.16.19:646][120]LogProfileSys: Display: DestroyOld: 0.00 +[2018.11.29-17.16.19:646][120]LogParty: Display: Homebase updated for Team Member: +[2018.11.29-17.16.19:646][120]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.19:684][120]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [0]) Request.RequestId [0] initial WaitingFor flags [E0]. +[2018.11.29-17.16.19:684][120]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [0]) Request.RequestId [0] final WaitingFor flags [A0]. +[2018.11.29-17.16.19:685][120]LogProfileSys: Requesting full profile update for profile 'common_core' for player 'LoadBot07063' +[2018.11.29-17.16.19:685][120]LogProfileSys: Requesting full profile update for profile 'athena' for player 'LoadBot07063' +[2018.11.29-17.16.19:685][120]LogProfileSys: MCP-Profile: Dispatching request to https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=common_core&rvn=-1 +[2018.11.29-17.16.19:688][121]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:688][121]LogHttp: Verbose: 00000231A0D77CC0: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=common_core&rvn=-1' +[2018.11.29-17.16.19:688][121]LogHttp: Verbose: 00000231A0D77CC0: Verb='POST' +[2018.11.29-17.16.19:688][121]LogHttp: Verbose: 00000231A0D77CC0: Custom headers are present +[2018.11.29-17.16.19:688][121]LogHttp: Verbose: 00000231A0D77CC0: Payload size=4 +[2018.11.29-17.16.19:688][121]LogHttp: Verbose: 00000231A0D77CC0: Adding header 'Accept: */*' +[2018.11.29-17.16.19:688][121]LogHttp: Verbose: 00000231A0D77CC0: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.19:688][121]LogHttp: Verbose: 00000231A0D77CC0: Adding header 'X-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}' +[2018.11.29-17.16.19:688][121]LogHttp: Verbose: 00000231A0D77CC0: Adding header 'X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119' +[2018.11.29-17.16.19:688][121]LogHttp: Verbose: 00000231A0D77CC0: Adding header 'X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":-1},{"profileId":"athena","clientCommandRevision":-1}]' +[2018.11.29-17.16.19:688][121]LogHttp: Verbose: 00000231A0D77CC0: Adding header 'X-Epic-Correlation-ID: FN-qzcQRea7-Eq46MBx9LrRXw' +[2018.11.29-17.16.19:688][121]LogHttp: Verbose: 00000231A0D77CC0: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.19:688][121]LogHttp: Verbose: 00000231A0D77CC0: Adding header 'Content-Length: 4' +[2018.11.29-17.16.19:688][121]LogHttp: Verbose: 00000231A0D77CC0: Adding header 'Expect: ' +[2018.11.29-17.16.19:688][121]LogHttp: 00000231A0D77CC0: Starting POST request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=common_core&rvn=-1' +[2018.11.29-17.16.19:688][121]LogHttp: Verbose: 00000231A0D77CC0: request (easy handle:00000231A0CEAAB0) has been added to threaded queue for processing +[2018.11.29-17.16.19:692][122]LogHttp: Verbose: 00000231A0D77CC0: request (easy handle:00000231A0CEAAB0) has started threaded processing +[2018.11.29-17.16.19:692][122]LogHttp: VeryVerbose: 00000231A0D77CC0: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.19:692][122]LogHttp: VeryVerbose: 00000231A0D77CC0: 'Re-using existing connection! (#3) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.19:692][122]LogHttp: VeryVerbose: 00000231A0D77CC0: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#3)' +[2018.11.29-17.16.19:692][122]LogHttp: VeryVerbose: 00000231A0D77CC0: Sent SSL data (5 bytes) +[2018.11.29-17.16.19:692][122]LogHttp: VeryVerbose: 00000231A0D77CC0: Sent header (1023 bytes) - POST /fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=common_core&rvn=-1 HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept-Encoding: deflate, gzipAccept: */*Content-Type: application/jsonX-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":-1},{"profileId":"athena","clientCommandRevision":-1}]X-Epic-Correlation-ID: FN-qzcQRea7-Eq46MBx9LrRXwUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2Iiw +[2018.11.29-17.16.19:692][122]LogHttp: Verbose: 00000231A0D77CC0: UploadCallback: 4 bytes out of 4 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=4 (<-this will get returned from the callback)) +[2018.11.29-17.16.19:692][122]LogHttp: VeryVerbose: 00000231A0D77CC0: Sent SSL data (5 bytes) +[2018.11.29-17.16.19:692][122]LogHttp: VeryVerbose: 00000231A0D77CC0: Sent data (4 bytes) +[2018.11.29-17.16.19:692][122]LogHttp: VeryVerbose: 00000231A0D77CC0: 'We are completely uploaded and fine' +[2018.11.29-17.16.19:708][123]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:708][123]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:742][125]LogHttp: VeryVerbose: 00000231A0D77CC0: Received SSL data (5 bytes) +[2018.11.29-17.16.19:776][127]LogHttp: VeryVerbose: 00000231A0D77CC0: Received header (17 bytes) +[2018.11.29-17.16.19:776][127]LogHttp: Verbose: 00000231A0D77CC0: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.19:776][127]LogHttp: VeryVerbose: 00000231A0D77CC0: Received header (32 bytes) +[2018.11.29-17.16.19:776][127]LogHttp: Verbose: 00000231A0D77CC0: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.19:776][127]LogHttp: VeryVerbose: 00000231A0D77CC0: Received header (37 bytes) +[2018.11.29-17.16.19:776][127]LogHttp: Verbose: 00000231A0D77CC0: Received response header 'Date: Thu, 29 Nov 2018 17:16:19 GMT'. +[2018.11.29-17.16.19:776][127]LogHttp: VeryVerbose: 00000231A0D77CC0: Received header (31 bytes) +[2018.11.29-17.16.19:776][127]LogHttp: Verbose: 00000231A0D77CC0: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.19:776][127]LogHttp: VeryVerbose: 00000231A0D77CC0: Received header (50 bytes) +[2018.11.29-17.16.19:776][127]LogHttp: Verbose: 00000231A0D77CC0: Received response header 'X-Epic-Correlation-ID: FN-qzcQRea7-Eq46MBx9LrRXw'. +[2018.11.29-17.16.19:776][127]LogHttp: VeryVerbose: 00000231A0D77CC0: Received header (52 bytes) +[2018.11.29-17.16.19:776][127]LogHttp: Verbose: 00000231A0D77CC0: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.19:776][127]LogHttp: VeryVerbose: 00000231A0D77CC0: Received header (75 bytes) +[2018.11.29-17.16.19:776][127]LogHttp: Verbose: 00000231A0D77CC0: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.19:776][127]LogHttp: VeryVerbose: 00000231A0D77CC0: Received header (35 bytes) +[2018.11.29-17.16.19:776][127]LogHttp: Verbose: 00000231A0D77CC0: Received response header 'X-EpicGames-Profile-Revision: 204'. +[2018.11.29-17.16.19:776][127]LogHttp: VeryVerbose: 00000231A0D77CC0: Received header (28 bytes) +[2018.11.29-17.16.19:776][127]LogHttp: Verbose: 00000231A0D77CC0: Received response header 'transfer-encoding: chunked'. +[2018.11.29-17.16.19:776][127]LogHttp: VeryVerbose: 00000231A0D77CC0: Received header (24 bytes) +[2018.11.29-17.16.19:776][127]LogHttp: Verbose: 00000231A0D77CC0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.19:776][127]LogHttp: Verbose: 00000231A0D77CC0: Received response header ''. +[2018.11.29-17.16.19:776][127]LogHttp: VeryVerbose: 00000231A0D77CC0: Received header (2 bytes) +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: 00000231A0D77CC0: Received data (14076 bytes) +[2018.11.29-17.16.19:777][127]LogHttp: Verbose: 00000231A0D77CC0: ReceiveResponseBodyCallback: 14068 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=14068, Response->TotalBytesRead=0, Response->GetContentLength()=0, SizeToDownload=14068 (<-this will get returned from the callback)) +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: 00000231A0D77CC0: Received SSL data (5 bytes) +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: 00000231A0D77CC0: Received data (5 bytes) +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: 00000231A0D77CC0: 'Connection #3 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.19:777][127]LogHttp: Verbose: Request 00000231A0D77CC0 (easy handle:00000231A0CEAAB0) has completed (code:0) and has been marked as such +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:777][127]LogHttp: 00000231A0D77CC0: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=common_core&rvn=-1, HTTP code: 200, content length: -1, actual payload size: 14068 +[2018.11.29-17.16.19:777][127]LogHttp: Verbose: 00000231A0D77CC0 Response Header Content-Type: application/json +[2018.11.29-17.16.19:777][127]LogHttp: Verbose: 00000231A0D77CC0 Response Header Date: Thu, 29 Nov 2018 17:16:19 GMT +[2018.11.29-17.16.19:777][127]LogHttp: Verbose: 00000231A0D77CC0 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.19:777][127]LogHttp: Verbose: 00000231A0D77CC0 Response Header X-Epic-Correlation-ID: FN-qzcQRea7-Eq46MBx9LrRXw +[2018.11.29-17.16.19:777][127]LogHttp: Verbose: 00000231A0D77CC0 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.19:777][127]LogHttp: Verbose: 00000231A0D77CC0 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.19:777][127]LogHttp: Verbose: 00000231A0D77CC0 Response Header X-EpicGames-Profile-Revision: 204 +[2018.11.29-17.16.19:777][127]LogHttp: Verbose: 00000231A0D77CC0 Response Header transfer-encoding: chunked +[2018.11.29-17.16.19:777][127]LogHttp: Verbose: 00000231A0D77CC0 Response Header Connection: keep-alive +[2018.11.29-17.16.19:777][127]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.19:792][128]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:792][128]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.19:806][128]LogProfileSys: UMcpProfile::HandleProfileUpdate updated lock expiration on Account MCP:e6f5091c3b2f4c359cf2aad75c424de0 for ProfileId common_core to --- +[2018.11.29-17.16.19:806][128]LogProfileSys: MCP-Profile: Full profile update (rev=204, version=grant_skirmish_banners_october_2018@w=9) for LoadBot07063 accountId=MCP:e6f5091c3b2f4c359cf2aad75c424de0 profileId=common_core. +[2018.11.29-17.16.19:808][128]LogProfileSys: Display: HandleFullProfileUpdate Complete: +[2018.11.29-17.16.19:808][128]LogProfileSys: Display: TotalTime: 0.00 +[2018.11.29-17.16.19:808][128]LogProfileSys: Display: StatUpdate: 0.00 +[2018.11.29-17.16.19:808][128]LogProfileSys: Display: ItemUpdate: 0.00 +[2018.11.29-17.16.19:808][128]LogProfileSys: Display: DestroyOld: 0.00 +[2018.11.29-17.16.19:810][128]LogParty: Display: Homebase updated for Team Member: +[2018.11.29-17.16.19:811][128]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [0]) Request.RequestId [0] initial WaitingFor flags [A0]. +[2018.11.29-17.16.19:811][128]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [0]) Request.RequestId [0] final WaitingFor flags [20]. +[2018.11.29-17.16.19:811][128]LogProfileSys: Requesting full profile update for profile 'athena' for player 'LoadBot07063' +[2018.11.29-17.16.19:811][128]LogProfileSys: MCP-Profile: Dispatching request to https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=athena&rvn=-1 +[2018.11.29-17.16.19:816][129]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:816][129]LogHttp: Verbose: 00000231A0D777C0: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=athena&rvn=-1' +[2018.11.29-17.16.19:816][129]LogHttp: Verbose: 00000231A0D777C0: Verb='POST' +[2018.11.29-17.16.19:816][129]LogHttp: Verbose: 00000231A0D777C0: Custom headers are present +[2018.11.29-17.16.19:816][129]LogHttp: Verbose: 00000231A0D777C0: Payload size=4 +[2018.11.29-17.16.19:816][129]LogHttp: Verbose: 00000231A0D777C0: Adding header 'Accept: */*' +[2018.11.29-17.16.19:817][129]LogHttp: Verbose: 00000231A0D777C0: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.19:817][129]LogHttp: Verbose: 00000231A0D777C0: Adding header 'X-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}' +[2018.11.29-17.16.19:817][129]LogHttp: Verbose: 00000231A0D777C0: Adding header 'X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119' +[2018.11.29-17.16.19:817][129]LogHttp: Verbose: 00000231A0D777C0: Adding header 'X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":-1}]' +[2018.11.29-17.16.19:817][129]LogHttp: Verbose: 00000231A0D777C0: Adding header 'X-Epic-Correlation-ID: FN-c7GE_QHTKU6EsKtbQTgx1g' +[2018.11.29-17.16.19:817][129]LogHttp: Verbose: 00000231A0D777C0: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.19:817][129]LogHttp: Verbose: 00000231A0D777C0: Adding header 'Content-Length: 4' +[2018.11.29-17.16.19:817][129]LogHttp: Verbose: 00000231A0D777C0: Adding header 'Expect: ' +[2018.11.29-17.16.19:817][129]LogHttp: 00000231A0D777C0: Starting POST request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=athena&rvn=-1' +[2018.11.29-17.16.19:817][129]LogHttp: Verbose: 00000231A0D777C0: request (easy handle:00000231A5605560) has been added to threaded queue for processing +[2018.11.29-17.16.19:843][131]LogHttp: Verbose: 00000231A0D777C0: request (easy handle:00000231A5605560) has started threaded processing +[2018.11.29-17.16.19:844][131]LogHttp: VeryVerbose: 00000231A0D777C0: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.19:844][131]LogHttp: VeryVerbose: 00000231A0D777C0: 'Re-using existing connection! (#3) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.19:844][131]LogHttp: VeryVerbose: 00000231A0D777C0: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#3)' +[2018.11.29-17.16.19:844][131]LogHttp: VeryVerbose: 00000231A0D777C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.19:844][131]LogHttp: VeryVerbose: 00000231A0D777C0: Sent header (1023 bytes) - POST /fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=athena&rvn=-1 HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept-Encoding: deflate, gzipAccept: */*Content-Type: application/jsonX-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":-1}]X-Epic-Correlation-ID: FN-c7GE_QHTKU6EsKtbQTgx1gUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0i +[2018.11.29-17.16.19:844][131]LogHttp: Verbose: 00000231A0D777C0: UploadCallback: 4 bytes out of 4 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=4 (<-this will get returned from the callback)) +[2018.11.29-17.16.19:844][131]LogHttp: VeryVerbose: 00000231A0D777C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.19:844][131]LogHttp: VeryVerbose: 00000231A0D777C0: Sent data (4 bytes) +[2018.11.29-17.16.19:844][131]LogHttp: VeryVerbose: 00000231A0D777C0: 'We are completely uploaded and fine' +[2018.11.29-17.16.19:844][131]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:844][131]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:910][135]LogHttp: VeryVerbose: 00000231A0D777C0: Received SSL data (5 bytes) +[2018.11.29-17.16.19:910][135]LogHttp: VeryVerbose: 00000231A0D777C0: Received header (17 bytes) +[2018.11.29-17.16.19:910][135]LogHttp: Verbose: 00000231A0D777C0: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.19:911][135]LogHttp: VeryVerbose: 00000231A0D777C0: Received header (32 bytes) +[2018.11.29-17.16.19:911][135]LogHttp: Verbose: 00000231A0D777C0: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.19:911][135]LogHttp: VeryVerbose: 00000231A0D777C0: Received header (37 bytes) +[2018.11.29-17.16.19:911][135]LogHttp: Verbose: 00000231A0D777C0: Received response header 'Date: Thu, 29 Nov 2018 17:16:19 GMT'. +[2018.11.29-17.16.19:911][135]LogHttp: VeryVerbose: 00000231A0D777C0: Received header (31 bytes) +[2018.11.29-17.16.19:911][135]LogHttp: Verbose: 00000231A0D777C0: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.19:911][135]LogHttp: VeryVerbose: 00000231A0D777C0: Received header (50 bytes) +[2018.11.29-17.16.19:911][135]LogHttp: Verbose: 00000231A0D777C0: Received response header 'X-Epic-Correlation-ID: FN-c7GE_QHTKU6EsKtbQTgx1g'. +[2018.11.29-17.16.19:911][135]LogHttp: VeryVerbose: 00000231A0D777C0: Received header (52 bytes) +[2018.11.29-17.16.19:911][135]LogHttp: Verbose: 00000231A0D777C0: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.19:911][135]LogHttp: VeryVerbose: 00000231A0D777C0: Received header (75 bytes) +[2018.11.29-17.16.19:911][135]LogHttp: Verbose: 00000231A0D777C0: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.19:911][135]LogHttp: VeryVerbose: 00000231A0D777C0: Received header (35 bytes) +[2018.11.29-17.16.19:911][135]LogHttp: Verbose: 00000231A0D777C0: Received response header 'X-EpicGames-Profile-Revision: 234'. +[2018.11.29-17.16.19:911][135]LogHttp: VeryVerbose: 00000231A0D777C0: Received header (23 bytes) +[2018.11.29-17.16.19:911][135]LogHttp: Verbose: 00000231A0D777C0: Received response header 'Content-Length: 10529'. +[2018.11.29-17.16.19:911][135]LogHttp: VeryVerbose: 00000231A0D777C0: Received header (24 bytes) +[2018.11.29-17.16.19:911][135]LogHttp: Verbose: 00000231A0D777C0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.19:912][135]LogHttp: Verbose: 00000231A0D777C0: Received response header ''. +[2018.11.29-17.16.19:912][135]LogHttp: VeryVerbose: 00000231A0D777C0: Received header (2 bytes) +[2018.11.29-17.16.19:912][135]LogHttp: VeryVerbose: 00000231A0D777C0: Received data (10529 bytes) +[2018.11.29-17.16.19:912][135]LogHttp: Verbose: 00000231A0D777C0: ReceiveResponseBodyCallback: 10529 bytes out of 10529 received. (SizeInBlocks=1, BlockSizeInBytes=10529, Response->TotalBytesRead=0, Response->GetContentLength()=10529, SizeToDownload=10529 (<-this will get returned from the callback)) +[2018.11.29-17.16.19:912][135]LogHttp: VeryVerbose: 00000231A0D777C0: 'Connection #3 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.19:912][135]LogHttp: Verbose: Request 00000231A0D777C0 (easy handle:00000231A5605560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.19:912][135]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:912][135]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:912][135]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:912][135]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:912][135]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:912][135]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:912][135]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:912][135]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:912][135]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:913][135]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:913][135]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:913][135]LogHttp: 00000231A0D777C0: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/QueryProfile?profileId=athena&rvn=-1, HTTP code: 200, content length: 10529, actual payload size: 10529 +[2018.11.29-17.16.19:913][135]LogHttp: Verbose: 00000231A0D777C0 Response Header Content-Type: application/json +[2018.11.29-17.16.19:913][135]LogHttp: Verbose: 00000231A0D777C0 Response Header Date: Thu, 29 Nov 2018 17:16:19 GMT +[2018.11.29-17.16.19:913][135]LogHttp: Verbose: 00000231A0D777C0 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.19:913][135]LogHttp: Verbose: 00000231A0D777C0 Response Header X-Epic-Correlation-ID: FN-c7GE_QHTKU6EsKtbQTgx1g +[2018.11.29-17.16.19:913][135]LogHttp: Verbose: 00000231A0D777C0 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.19:913][135]LogHttp: Verbose: 00000231A0D777C0 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.19:913][135]LogHttp: Verbose: 00000231A0D777C0 Response Header X-EpicGames-Profile-Revision: 234 +[2018.11.29-17.16.19:913][135]LogHttp: Verbose: 00000231A0D777C0 Response Header Content-Length: 10529 +[2018.11.29-17.16.19:913][135]LogHttp: Verbose: 00000231A0D777C0 Response Header Connection: keep-alive +[2018.11.29-17.16.19:913][135]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.19:927][136]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.19:927][136]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.19:939][136]LogProfileSys: UMcpProfile::HandleProfileUpdate updated lock expiration on Account MCP:e6f5091c3b2f4c359cf2aad75c424de0 for ProfileId athena to --- +[2018.11.29-17.16.19:939][136]LogProfileSys: MCP-Profile: Full profile update (rev=235, version=fortnitemares_part4_fixup_oct_18@w=5) for LoadBot07063 accountId=MCP:e6f5091c3b2f4c359cf2aad75c424de0 profileId=athena. +[2018.11.29-17.16.19:941][136]LogProfileSys: Display: HandleFullProfileUpdate Complete: +[2018.11.29-17.16.19:941][136]LogProfileSys: Display: TotalTime: 0.00 +[2018.11.29-17.16.19:941][136]LogProfileSys: Display: StatUpdate: 0.00 +[2018.11.29-17.16.19:941][136]LogProfileSys: Display: ItemUpdate: 0.00 +[2018.11.29-17.16.19:941][136]LogProfileSys: Display: DestroyOld: 0.00 +[2018.11.29-17.16.19:944][136]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.19:952][136]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.19:952][136]LogProfileSys: MCP-Profile: Command MarkNewQuestNotificationSent queued to send +[2018.11.29-17.16.19:952][136]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [0]) Request.RequestId [0] initial WaitingFor flags [20]. +[2018.11.29-17.16.19:952][136]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [0]) Request.RequestId [0] final WaitingFor flags [0]. +[2018.11.29-17.16.19:952][136]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [0]) is removing FFortProfileSynchronizeRequest : Request.RequestId [0]. +[2018.11.29-17.16.19:952][136]LogProfileSys: MCP-Profile: Dispatching request to https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/MarkNewQuestNotificationSent?profileId=athena&rvn=235 +[2018.11.29-17.16.19:955][136]LogOnlineAccount: Display: [UOnlineAccountCommon::ContinueLoggingIn] Login: Downloading keychain... (QueryKeychain) +[2018.11.29-17.16.19:955][136]LogKeychainHelper: [FMcpKeychainHelper] Refresh +[2018.11.29-17.16.19:955][136]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.19:955][136]LogProfileSys: MCP-Profile: Dispatching request to https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/storefront/v2/keychain?numKeysDownloaded=0&rvn=204 +[2018.11.29-17.16.19:957][137]LogRenderer: Reallocating scene render targets to support 1284x804 Format 9 NumSamples 1 (Frame:112). +[2018.11.29-17.16.19:958][137]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.19:958][137]LogHttp: Verbose: 00000231A22CF240: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/MarkNewQuestNotificationSent?profileId=athena&rvn=235' +[2018.11.29-17.16.19:958][137]LogHttp: Verbose: 00000231A22CF240: Verb='POST' +[2018.11.29-17.16.19:958][137]LogHttp: Verbose: 00000231A22CF240: Custom headers are present +[2018.11.29-17.16.19:958][137]LogHttp: Verbose: 00000231A22CF240: Payload size=108 +[2018.11.29-17.16.19:958][137]LogHttp: Verbose: 00000231A22CF240: Adding header 'Accept: */*' +[2018.11.29-17.16.19:958][137]LogHttp: Verbose: 00000231A22CF240: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.19:958][137]LogHttp: Verbose: 00000231A22CF240: Adding header 'X-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}' +[2018.11.29-17.16.19:958][137]LogHttp: Verbose: 00000231A22CF240: Adding header 'X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119' +[2018.11.29-17.16.19:958][137]LogHttp: Verbose: 00000231A22CF240: Adding header 'X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":238}]' +[2018.11.29-17.16.19:958][137]LogHttp: Verbose: 00000231A22CF240: Adding header 'X-Epic-Correlation-ID: FN-mP913hDIrkOXkJYqZWWugA' +[2018.11.29-17.16.19:958][137]LogHttp: Verbose: 00000231A22CF240: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.19:958][137]LogHttp: Verbose: 00000231A22CF240: Adding header 'Content-Length: 108' +[2018.11.29-17.16.19:958][137]LogHttp: Verbose: 00000231A22CF240: Adding header 'Expect: ' +[2018.11.29-17.16.19:958][137]LogHttp: 00000231A22CF240: Starting POST request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/MarkNewQuestNotificationSent?profileId=athena&rvn=235' +[2018.11.29-17.16.19:958][137]LogHttp: Verbose: 00000231A22CF240: request (easy handle:00000231A30AAAB0) has been added to threaded queue for processing +[2018.11.29-17.16.19:974][138]LogHttp: Verbose: 00000231A22CF240: request (easy handle:00000231A30AAAB0) has started threaded processing +[2018.11.29-17.16.19:974][138]LogHttp: VeryVerbose: 00000231A22CF240: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.19:974][138]LogHttp: VeryVerbose: 00000231A22CF240: 'Re-using existing connection! (#3) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.19:974][138]LogHttp: VeryVerbose: 00000231A22CF240: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#3)' +[2018.11.29-17.16.19:974][138]LogHttp: VeryVerbose: 00000231A22CF240: Sent SSL data (5 bytes) +[2018.11.29-17.16.19:974][138]LogHttp: VeryVerbose: 00000231A22CF240: Sent header (1023 bytes) - POST /fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/MarkNewQuestNotificationSent?profileId=athena&rvn=235 HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept-Encoding: deflate, gzipAccept: */*Content-Type: application/jsonX-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":238}]X-Epic-Correlation-ID: FN-mP913hDIrkOXkJYqZWWugAUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMm +[2018.11.29-17.16.19:974][138]LogHttp: Verbose: 00000231A22CF240: UploadCallback: 108 bytes out of 108 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=108 (<-this will get returned from the callback)) +[2018.11.29-17.16.19:974][138]LogHttp: VeryVerbose: 00000231A22CF240: Sent SSL data (5 bytes) +[2018.11.29-17.16.19:974][138]LogHttp: VeryVerbose: 00000231A22CF240: Sent data (108 bytes) +[2018.11.29-17.16.19:974][138]LogHttp: VeryVerbose: 00000231A22CF240: 'We are completely uploaded and fine' +[2018.11.29-17.16.20:001][138]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:001][138]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:001][138]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:002][138]LogHttp: Verbose: 00000231969CED40: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/storefront/v2/keychain?numKeysDownloaded=0&rvn=204' +[2018.11.29-17.16.20:002][138]LogRenderer: Reallocating scene render targets to support 1920x1200 Format 9 NumSamples 1 (Frame:113). +[2018.11.29-17.16.20:002][138]LogHttp: Verbose: 00000231969CED40: Verb='GET' +[2018.11.29-17.16.20:002][138]LogHttp: Verbose: 00000231969CED40: Custom headers are present +[2018.11.29-17.16.20:002][138]LogHttp: Verbose: 00000231969CED40: Payload size=0 +[2018.11.29-17.16.20:002][138]LogHttp: Verbose: 00000231969CED40: Adding header 'X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":238}]' +[2018.11.29-17.16.20:002][138]LogHttp: Verbose: 00000231969CED40: Adding header 'X-Epic-Correlation-ID: FN-0nIVATAWXU_sG1C2CrSYqA' +[2018.11.29-17.16.20:002][138]LogHttp: Verbose: 00000231969CED40: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.20:002][138]LogHttp: Verbose: 00000231969CED40: Adding header 'Content-Length: 0' +[2018.11.29-17.16.20:002][138]LogHttp: Verbose: 00000231969CED40: Adding header 'Expect: ' +[2018.11.29-17.16.20:002][138]LogHttp: 00000231969CED40: Starting GET request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/storefront/v2/keychain?numKeysDownloaded=0&rvn=204' +[2018.11.29-17.16.20:003][138]LogHttp: Verbose: 00000231969CED40: request (easy handle:00000231E339AAB0) has been added to threaded queue for processing +[2018.11.29-17.16.20:008][139]LogHttp: Verbose: 00000231969CED40: request (easy handle:00000231E339AAB0) has started threaded processing +[2018.11.29-17.16.20:008][139]LogHttp: VeryVerbose: 00000231969CED40: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.20:008][139]LogHttp: VeryVerbose: 00000231969CED40: 'Hostname fortnite-public-service-latest-gamedev.ol.epicgames.net was found in DNS cache' +[2018.11.29-17.16.20:008][139]LogHttp: VeryVerbose: 00000231969CED40: ' Trying 10.40.132.204...' +[2018.11.29-17.16.20:008][139]LogHttp: VeryVerbose: 00000231969CED40: 'TCP_NODELAY set' +[2018.11.29-17.16.20:019][139]LogHttp: VeryVerbose: 00000231A22CF240: Received SSL data (5 bytes) +[2018.11.29-17.16.20:019][139]LogHttp: VeryVerbose: 00000231A22CF240: Received header (17 bytes) +[2018.11.29-17.16.20:019][139]LogHttp: Verbose: 00000231A22CF240: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.20:019][139]LogHttp: VeryVerbose: 00000231A22CF240: Received header (32 bytes) +[2018.11.29-17.16.20:019][139]LogHttp: Verbose: 00000231A22CF240: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.20:019][139]LogHttp: VeryVerbose: 00000231A22CF240: Received header (37 bytes) +[2018.11.29-17.16.20:019][139]LogHttp: Verbose: 00000231A22CF240: Received response header 'Date: Thu, 29 Nov 2018 17:16:19 GMT'. +[2018.11.29-17.16.20:019][139]LogHttp: VeryVerbose: 00000231A22CF240: Received header (31 bytes) +[2018.11.29-17.16.20:019][139]LogHttp: Verbose: 00000231A22CF240: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.20:019][139]LogHttp: VeryVerbose: 00000231A22CF240: Received header (50 bytes) +[2018.11.29-17.16.20:019][139]LogHttp: Verbose: 00000231A22CF240: Received response header 'X-Epic-Correlation-ID: FN-mP913hDIrkOXkJYqZWWugA'. +[2018.11.29-17.16.20:019][139]LogHttp: VeryVerbose: 00000231A22CF240: Received header (52 bytes) +[2018.11.29-17.16.20:019][139]LogHttp: Verbose: 00000231A22CF240: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.20:019][139]LogHttp: VeryVerbose: 00000231A22CF240: Received header (75 bytes) +[2018.11.29-17.16.20:019][139]LogHttp: Verbose: 00000231A22CF240: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.20:019][139]LogHttp: VeryVerbose: 00000231A22CF240: Received header (35 bytes) +[2018.11.29-17.16.20:019][139]LogHttp: Verbose: 00000231A22CF240: Received response header 'X-EpicGames-Profile-Revision: 235'. +[2018.11.29-17.16.20:019][139]LogHttp: VeryVerbose: 00000231A22CF240: Received header (21 bytes) +[2018.11.29-17.16.20:019][139]LogHttp: Verbose: 00000231A22CF240: Received response header 'Content-Length: 471'. +[2018.11.29-17.16.20:019][139]LogHttp: VeryVerbose: 00000231A22CF240: Received header (24 bytes) +[2018.11.29-17.16.20:019][139]LogHttp: Verbose: 00000231A22CF240: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.20:019][139]LogHttp: Verbose: 00000231A22CF240: Received response header ''. +[2018.11.29-17.16.20:019][139]LogHttp: VeryVerbose: 00000231A22CF240: Received header (2 bytes) +[2018.11.29-17.16.20:019][139]LogHttp: VeryVerbose: 00000231A22CF240: Received data (471 bytes) +[2018.11.29-17.16.20:019][139]LogHttp: Verbose: 00000231A22CF240: ReceiveResponseBodyCallback: 471 bytes out of 471 received. (SizeInBlocks=1, BlockSizeInBytes=471, Response->TotalBytesRead=0, Response->GetContentLength()=471, SizeToDownload=471 (<-this will get returned from the callback)) +[2018.11.29-17.16.20:019][139]LogHttp: VeryVerbose: 00000231A22CF240: 'Connection #3 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.20:019][139]LogHttp: Verbose: Request 00000231A22CF240 (easy handle:00000231A30AAAB0) has completed (code:0) and has been marked as such +[2018.11.29-17.16.20:030][139]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:030][139]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:030][139]LogRenderer: Reallocating scene render targets to support 1284x804 Format 9 NumSamples 1 (Frame:114). +[2018.11.29-17.16.20:030][139]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:030][139]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:030][139]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:030][139]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:030][139]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:030][139]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:030][139]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:030][139]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:030][139]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:030][139]LogHttp: 00000231A22CF240: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/MarkNewQuestNotificationSent?profileId=athena&rvn=235, HTTP code: 200, content length: 471, actual payload size: 471 +[2018.11.29-17.16.20:030][139]LogHttp: Verbose: 00000231A22CF240 Response Header Content-Type: application/json +[2018.11.29-17.16.20:030][139]LogHttp: Verbose: 00000231A22CF240 Response Header Date: Thu, 29 Nov 2018 17:16:19 GMT +[2018.11.29-17.16.20:030][139]LogHttp: Verbose: 00000231A22CF240 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.20:030][139]LogHttp: Verbose: 00000231A22CF240 Response Header X-Epic-Correlation-ID: FN-mP913hDIrkOXkJYqZWWugA +[2018.11.29-17.16.20:030][139]LogHttp: Verbose: 00000231A22CF240 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.20:031][139]LogHttp: Verbose: 00000231A22CF240 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.20:031][139]LogHttp: Verbose: 00000231A22CF240 Response Header X-EpicGames-Profile-Revision: 235 +[2018.11.29-17.16.20:031][139]LogHttp: Verbose: 00000231A22CF240 Response Header Content-Length: 471 +[2018.11.29-17.16.20:031][139]LogHttp: Verbose: 00000231A22CF240 Response Header Connection: keep-alive +[2018.11.29-17.16.20:031][139]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:059][140]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:059][140]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:060][140]LogProfileSys: UMcpProfile::HandleProfileUpdate updated lock expiration on Account MCP:e6f5091c3b2f4c359cf2aad75c424de0 for ProfileId athena to --- +[2018.11.29-17.16.20:065][141]LogHttp: VeryVerbose: 00000231969CED40: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#7)' +[2018.11.29-17.16.20:070][141]LogHttp: VeryVerbose: 00000231969CED40: 'ALPN, offering http/1.1' +[2018.11.29-17.16.20:070][141]LogHttp: VeryVerbose: 00000231969CED40: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.20:073][141]LogHttp: VeryVerbose: 00000231969CED40: 'SSL re-using session ID' +[2018.11.29-17.16.20:074][141]LogHttp: VeryVerbose: 00000231969CED40: Sent SSL data (5 bytes) +[2018.11.29-17.16.20:074][141]LogHttp: VeryVerbose: 00000231969CED40: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.20:074][141]LogHttp: VeryVerbose: 00000231969CED40: Sent SSL data (512 bytes) +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: Received SSL data (5 bytes) +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: Received SSL data (89 bytes) +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: Received SSL data (5 bytes) +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: Received SSL data (1 bytes) +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: Received SSL data (5 bytes) +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: Received SSL data (16 bytes) +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: Sent SSL data (5 bytes) +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: Sent SSL data (1 bytes) +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: Sent SSL data (5 bytes) +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: Sent SSL data (16 bytes) +[2018.11.29-17.16.20:121][143]LogHttp: VeryVerbose: 00000231969CED40: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.20:122][143]LogHttp: VeryVerbose: 00000231969CED40: 'ALPN, server did not agree to a protocol' +[2018.11.29-17.16.20:122][143]LogHttp: VeryVerbose: 00000231969CED40: 'Server certificate:' +[2018.11.29-17.16.20:122][143]LogHttp: VeryVerbose: 00000231969CED40: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.16.20:122][143]LogHttp: VeryVerbose: 00000231969CED40: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.16.20:122][143]LogHttp: VeryVerbose: 00000231969CED40: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.16.20:122][143]LogHttp: VeryVerbose: 00000231969CED40: ' subjectAltName: host "fortnite-public-service-latest-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.16.20:122][143]LogHttp: VeryVerbose: 00000231969CED40: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.20:122][143]LogHttp: VeryVerbose: 00000231969CED40: ' SSL certificate verify ok.' +[2018.11.29-17.16.20:122][143]LogHttp: VeryVerbose: 00000231969CED40: Sent SSL data (5 bytes) +[2018.11.29-17.16.20:122][143]LogHttp: VeryVerbose: 00000231969CED40: Sent header (1023 bytes) - GET /fortnite/api/storefront/v2/keychain?numKeysDownloaded=0&rvn=204 HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":238}]X-Epic-Correlation-ID: FN-0nIVATAWXU_sG1C2CrSYqAUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6 +[2018.11.29-17.16.20:164][144]LogHttp: VeryVerbose: 00000231969CED40: Received SSL data (5 bytes) +[2018.11.29-17.16.20:164][144]LogHttp: VeryVerbose: 00000231969CED40: Received header (17 bytes) +[2018.11.29-17.16.20:164][144]LogHttp: Verbose: 00000231969CED40: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.20:164][144]LogHttp: VeryVerbose: 00000231969CED40: Received header (32 bytes) +[2018.11.29-17.16.20:164][144]LogHttp: Verbose: 00000231969CED40: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.20:164][144]LogHttp: VeryVerbose: 00000231969CED40: Received header (37 bytes) +[2018.11.29-17.16.20:164][144]LogHttp: Verbose: 00000231969CED40: Received response header 'Date: Thu, 29 Nov 2018 17:16:20 GMT'. +[2018.11.29-17.16.20:164][144]LogHttp: VeryVerbose: 00000231969CED40: Received header (31 bytes) +[2018.11.29-17.16.20:164][144]LogHttp: Verbose: 00000231969CED40: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.20:164][144]LogHttp: VeryVerbose: 00000231969CED40: Received header (50 bytes) +[2018.11.29-17.16.20:164][144]LogHttp: Verbose: 00000231969CED40: Received response header 'X-Epic-Correlation-ID: FN-0nIVATAWXU_sG1C2CrSYqA'. +[2018.11.29-17.16.20:164][144]LogHttp: VeryVerbose: 00000231969CED40: Received header (52 bytes) +[2018.11.29-17.16.20:164][144]LogHttp: Verbose: 00000231969CED40: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.20:164][144]LogHttp: VeryVerbose: 00000231969CED40: Received header (75 bytes) +[2018.11.29-17.16.20:164][144]LogHttp: Verbose: 00000231969CED40: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.20:164][144]LogHttp: VeryVerbose: 00000231969CED40: Received header (22 bytes) +[2018.11.29-17.16.20:164][144]LogHttp: Verbose: 00000231969CED40: Received response header 'Content-Length: 2377'. +[2018.11.29-17.16.20:165][144]LogHttp: VeryVerbose: 00000231969CED40: Received header (24 bytes) +[2018.11.29-17.16.20:165][144]LogHttp: Verbose: 00000231969CED40: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.20:165][144]LogHttp: Verbose: 00000231969CED40: Received response header ''. +[2018.11.29-17.16.20:165][144]LogHttp: VeryVerbose: 00000231969CED40: Received header (2 bytes) +[2018.11.29-17.16.20:165][144]LogHttp: VeryVerbose: 00000231969CED40: Received data (2377 bytes) +[2018.11.29-17.16.20:165][144]LogHttp: Verbose: 00000231969CED40: ReceiveResponseBodyCallback: 2377 bytes out of 2377 received. (SizeInBlocks=1, BlockSizeInBytes=2377, Response->TotalBytesRead=0, Response->GetContentLength()=2377, SizeToDownload=2377 (<-this will get returned from the callback)) +[2018.11.29-17.16.20:165][144]LogHttp: VeryVerbose: 00000231969CED40: 'Connection cache is full, closing the oldest one.' +[2018.11.29-17.16.20:165][144]LogHttp: VeryVerbose: 00000231969CED40: 'Closing connection 5' +[2018.11.29-17.16.20:165][144]LogHttp: VeryVerbose: 00000231969CED40: Sent SSL data (5 bytes) +[2018.11.29-17.16.20:165][144]LogHttp: VeryVerbose: 00000231969CED40: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.16.20:165][144]LogHttp: VeryVerbose: 00000231969CED40: Sent SSL data (2 bytes) +[2018.11.29-17.16.20:167][144]LogHttp: VeryVerbose: 00000231969CED40: 'Connection #7 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.20:167][144]LogHttp: Verbose: Request 00000231969CED40 (easy handle:00000231E339AAB0) has completed (code:0) and has been marked as such +[2018.11.29-17.16.20:167][144]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:167][144]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:167][144]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:167][144]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:168][144]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:168][144]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:168][144]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:168][144]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:168][144]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:168][144]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:168][144]LogHttp: 00000231969CED40: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/storefront/v2/keychain?numKeysDownloaded=0&rvn=204, HTTP code: 200, content length: 2377, actual payload size: 2377 +[2018.11.29-17.16.20:168][144]LogHttp: Verbose: 00000231969CED40 Response Header Content-Type: application/json +[2018.11.29-17.16.20:168][144]LogHttp: Verbose: 00000231969CED40 Response Header Date: Thu, 29 Nov 2018 17:16:20 GMT +[2018.11.29-17.16.20:168][144]LogHttp: Verbose: 00000231969CED40 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.20:168][144]LogHttp: Verbose: 00000231969CED40 Response Header X-Epic-Correlation-ID: FN-0nIVATAWXU_sG1C2CrSYqA +[2018.11.29-17.16.20:168][144]LogHttp: Verbose: 00000231969CED40 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.20:168][144]LogHttp: Verbose: 00000231969CED40 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.20:168][144]LogHttp: Verbose: 00000231969CED40 Response Header Content-Length: 2377 +[2018.11.29-17.16.20:168][144]LogHttp: Verbose: 00000231969CED40 Response Header Connection: keep-alive +[2018.11.29-17.16.20:168][144]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:168][144]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:168][144]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:169][144]LogKeychainHelper: RefreshKeychain complete (HTTP 200) +[2018.11.29-17.16.20:169][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:169][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID 29BB987D45D13E44971FDF938D787D81 added +[2018.11.29-17.16.20:169][144]LogPakFile: Registered encryption key '29BB987D45D13E44971FDF938D787D81': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:169][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:170][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID 4A8216304A1A18CB9583BC8CFF99EE26 added +[2018.11.29-17.16.20:170][144]LogPakFile: Registered encryption key '4A8216304A1A18CB9583BC8CFF99EE26': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:170][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:170][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID AEA23B234AFC8D8282ECF9AC552CCE0D added +[2018.11.29-17.16.20:170][144]LogPakFile: Registered encryption key 'AEA23B234AFC8D8282ECF9AC552CCE0D': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:170][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:170][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID EF114716417D000CAC03EFB8F3FD79E0 added +[2018.11.29-17.16.20:171][144]LogPakFile: Registered encryption key 'EF114716417D000CAC03EFB8F3FD79E0': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:171][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:171][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID 0690C12E471B0A42CD02549ADA662D64 added +[2018.11.29-17.16.20:171][144]LogPakFile: Registered encryption key '0690C12E471B0A42CD02549ADA662D64': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:171][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:171][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID D8FDE5644FE474C7C3D476AA18426FEB added +[2018.11.29-17.16.20:171][144]LogPakFile: Registered encryption key 'D8FDE5644FE474C7C3D476AA18426FEB': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:172][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:172][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID 94AB24604D6F33B1BDF1B4911CABA3FC added +[2018.11.29-17.16.20:172][144]LogPakFile: Registered encryption key '94AB24604D6F33B1BDF1B4911CABA3FC': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:172][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:172][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID F32262244DE021E18BF22F9BF7594474 added +[2018.11.29-17.16.20:172][144]LogPakFile: Registered encryption key 'F32262244DE021E18BF22F9BF7594474': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:172][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:172][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID 308F587F46CB50450DCA9B9CFD50E120 added +[2018.11.29-17.16.20:172][144]LogPakFile: Registered encryption key '308F587F46CB50450DCA9B9CFD50E120': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:173][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:173][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID 172B237342C2165A212FEEAC80584DD5 added +[2018.11.29-17.16.20:173][144]LogPakFile: Registered encryption key '172B237342C2165A212FEEAC80584DD5': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:173][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:173][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:173][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID F7CAA8D040108722FFA35FAA63DFD63E added +[2018.11.29-17.16.20:173][144]LogPakFile: Registered encryption key 'F7CAA8D040108722FFA35FAA63DFD63E': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:173][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:173][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID 2301C91045828DBFCDD966BE1AFE22F7 added +[2018.11.29-17.16.20:173][144]LogPakFile: Registered encryption key '2301C91045828DBFCDD966BE1AFE22F7': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:174][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:174][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID D82BF0194AE18598B8B08491E2256E16 added +[2018.11.29-17.16.20:174][144]LogPakFile: Registered encryption key 'D82BF0194AE18598B8B08491E2256E16': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:174][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:174][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID F5CA1EB943DF1E1D3DEDFFB7BB3195E5 added +[2018.11.29-17.16.20:174][144]LogPakFile: Registered encryption key 'F5CA1EB943DF1E1D3DEDFFB7BB3195E5': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:174][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:174][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID 663D9B9644802987C767C8929F0DB43B added +[2018.11.29-17.16.20:174][144]LogPakFile: Registered encryption key '663D9B9644802987C767C8929F0DB43B': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:175][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:175][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:175][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID 8F6ACF5D43BC4BC272D72EBC072BDB4F added +[2018.11.29-17.16.20:175][144]LogPakFile: Registered encryption key '8F6ACF5D43BC4BC272D72EBC072BDB4F': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:175][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:175][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:175][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID 1609BAEA4AD6B664847EB5AACEAAD2AF added +[2018.11.29-17.16.20:175][144]LogPakFile: Registered encryption key '1609BAEA4AD6B664847EB5AACEAAD2AF': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:175][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:175][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID 8978846F401CE9062618CFB4295B8C2E added +[2018.11.29-17.16.20:175][144]LogPakFile: Registered encryption key '8978846F401CE9062618CFB4295B8C2E': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:175][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:175][144]LogContentEncryptionManager: [FFortContentEncryptionManager] MergeInKeyChain() called +[2018.11.29-17.16.20:175][144]LogContentEncryptionManager: [FFortContentEncryptionManager] New key with GUID E582349045884D5CD6A5518608336738 added +[2018.11.29-17.16.20:175][144]LogPakFile: Registered encryption key 'E582349045884D5CD6A5518608336738': 0 pak files mounted, 0 remain pending +[2018.11.29-17.16.20:179][144]LogOnlineAccount: Display: [UOnlineAccountCommon::ContinueLoggingIn] Login: Claiming rewards... (SilentClaimMfaReward) +[2018.11.29-17.16.20:196][145]LogOnlineAccount: Display: [UOnlineAccountCommon::ContinueLoggingIn] Login: Redeeming offline purchases... (RedeemOfflinePurchases) +[2018.11.29-17.16.20:196][145]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:200][146]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:200][146]LogHttp: Verbose: 00000231969C4AC0: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/receipts/v1/account/e6f5091c3b2f4c359cf2aad75c424de0/receipts' +[2018.11.29-17.16.20:200][146]LogHttp: Verbose: 00000231969C4AC0: Verb='GET' +[2018.11.29-17.16.20:200][146]LogHttp: Verbose: 00000231969C4AC0: Custom headers are present +[2018.11.29-17.16.20:200][146]LogHttp: Verbose: 00000231969C4AC0: Payload size=0 +[2018.11.29-17.16.20:200][146]LogHttp: Verbose: 00000231969C4AC0: Adding header 'X-Epic-Correlation-ID: FN-NrvcBY-MMUSWwND-vmvDAw' +[2018.11.29-17.16.20:200][146]LogHttp: Verbose: 00000231969C4AC0: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.20:200][146]LogHttp: Verbose: 00000231969C4AC0: Adding header 'Content-Length: 0' +[2018.11.29-17.16.20:201][146]LogHttp: Verbose: 00000231969C4AC0: Adding header 'Expect: ' +[2018.11.29-17.16.20:201][146]LogHttp: 00000231969C4AC0: Starting GET request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/receipts/v1/account/e6f5091c3b2f4c359cf2aad75c424de0/receipts' +[2018.11.29-17.16.20:201][146]LogHttp: Verbose: 00000231969C4AC0: request (easy handle:00000231A5E60010) has been added to threaded queue for processing +[2018.11.29-17.16.20:248][149]LogHttp: Verbose: 00000231969C4AC0: request (easy handle:00000231A5E60010) has started threaded processing +[2018.11.29-17.16.20:248][149]LogHttp: VeryVerbose: 00000231969C4AC0: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.20:248][149]LogHttp: VeryVerbose: 00000231969C4AC0: 'Re-using existing connection! (#3) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.20:248][149]LogHttp: VeryVerbose: 00000231969C4AC0: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#3)' +[2018.11.29-17.16.20:248][149]LogHttp: VeryVerbose: 00000231969C4AC0: Sent SSL data (5 bytes) +[2018.11.29-17.16.20:248][149]LogHttp: VeryVerbose: 00000231969C4AC0: Sent header (1023 bytes) - GET /fortnite/api/receipts/v1/account/e6f5091c3b2f4c359cf2aad75c424de0/receipts HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-NrvcBY-MMUSWwND-vmvDAwUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM0RoMXFQVm9L +[2018.11.29-17.16.20:279][150]LogUMG: Display: Widget Class KairosToastMessage_C - Loaded Fast Template. +[2018.11.29-17.16.20:280][150]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.20:281][150]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.20:281][150]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.20:281][150]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.20:281][150]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.20:281][150]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.20:281][150]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.20:281][150]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.20:282][150]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.20:284][150]LogFort: Setting up first time rich presence +[2018.11.29-17.16.20:285][150]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.20:298][151]LogOnline: MCP: New XMPP connection configured to Server=[wss://xmpp-service-gamedev.ol.epicgames.net] Port=[443] +[2018.11.29-17.16.20:298][151]LogOnlineIdentity: OSS: FOnlineIdentityMcp::HandleXmppConnectionCreated +[2018.11.29-17.16.20:298][151]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::HandleXmppConnectionCreated +[2018.11.29-17.16.20:298][151]LogOnlineChannels: Verbose: OSS: FOnlineChannelsServiceMcp::HandleXmppConnectionCreated +[2018.11.29-17.16.20:298][151]LogXmpp: Starting Login on connection +[2018.11.29-17.16.20:298][151]LogXmpp: Server = wss://xmpp-service-gamedev.ol.epicgames.net:443 +[2018.11.29-17.16.20:298][151]LogXmpp: User = e6f5091c3b2f4c359cf2aad75c424de0:gamedev.ol.epicgames.net:V2:FortniteDevLatest:WIN::02893B0E4C31D665986F7F914616016E +[2018.11.29-17.16.20:298][151]LogWebSockets: VeryVerbose: FLwsWebSocket[1]: Constructed url=wss://xmpp-service-gamedev.ol.epicgames.net:443 protocols=xmpp +[2018.11.29-17.16.20:298][151]LogXmpp: Strophe processing LoginStatus change Was: NotStarted Now: ProcessingLogin +[2018.11.29-17.16.20:298][151]LogWebSockets: Verbose: FLwsWebSocket[1]::Connect: setting State=StartConnecting url=wss://xmpp-service-gamedev.ol.epicgames.net:443 bWantsMessageEvents=0 bWantsRawMessageEvents=1 +[2018.11.29-17.16.20:298][151]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: Attempting to connect using external socket +[2018.11.29-17.16.20:304][152]LogWebSockets: Verbose: FLwsWebSocket[1]::ConnectInternal: setting State=Connecting PreviousState=StartConnecting +[2018.11.29-17.16.20:387][157]LogHttp: VeryVerbose: 00000231969C4AC0: Received SSL data (5 bytes) +[2018.11.29-17.16.20:387][157]LogHttp: VeryVerbose: 00000231969C4AC0: Received header (17 bytes) +[2018.11.29-17.16.20:387][157]LogHttp: Verbose: 00000231969C4AC0: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.20:387][157]LogHttp: VeryVerbose: 00000231969C4AC0: Received header (32 bytes) +[2018.11.29-17.16.20:387][157]LogHttp: Verbose: 00000231969C4AC0: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.20:388][157]LogHttp: VeryVerbose: 00000231969C4AC0: Received header (37 bytes) +[2018.11.29-17.16.20:388][157]LogHttp: Verbose: 00000231969C4AC0: Received response header 'Date: Thu, 29 Nov 2018 17:16:20 GMT'. +[2018.11.29-17.16.20:388][157]LogHttp: VeryVerbose: 00000231969C4AC0: Received header (31 bytes) +[2018.11.29-17.16.20:388][157]LogHttp: Verbose: 00000231969C4AC0: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.20:388][157]LogHttp: VeryVerbose: 00000231969C4AC0: Received header (50 bytes) +[2018.11.29-17.16.20:388][157]LogHttp: Verbose: 00000231969C4AC0: Received response header 'X-Epic-Correlation-ID: FN-NrvcBY-MMUSWwND-vmvDAw'. +[2018.11.29-17.16.20:388][157]LogHttp: VeryVerbose: 00000231969C4AC0: Received header (52 bytes) +[2018.11.29-17.16.20:388][157]LogHttp: Verbose: 00000231969C4AC0: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.20:388][157]LogHttp: VeryVerbose: 00000231969C4AC0: Received header (75 bytes) +[2018.11.29-17.16.20:388][157]LogHttp: Verbose: 00000231969C4AC0: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.20:388][157]LogHttp: VeryVerbose: 00000231969C4AC0: Received header (19 bytes) +[2018.11.29-17.16.20:388][157]LogHttp: Verbose: 00000231969C4AC0: Received response header 'Content-Length: 2'. +[2018.11.29-17.16.20:388][157]LogHttp: VeryVerbose: 00000231969C4AC0: Received header (24 bytes) +[2018.11.29-17.16.20:388][157]LogHttp: Verbose: 00000231969C4AC0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.20:388][157]LogHttp: Verbose: 00000231969C4AC0: Received response header ''. +[2018.11.29-17.16.20:388][157]LogHttp: VeryVerbose: 00000231969C4AC0: Received header (2 bytes) +[2018.11.29-17.16.20:388][157]LogHttp: VeryVerbose: 00000231969C4AC0: Received data (2 bytes) +[2018.11.29-17.16.20:388][157]LogHttp: Verbose: 00000231969C4AC0: ReceiveResponseBodyCallback: 2 bytes out of 2 received. (SizeInBlocks=1, BlockSizeInBytes=2, Response->TotalBytesRead=0, Response->GetContentLength()=2, SizeToDownload=2 (<-this will get returned from the callback)) +[2018.11.29-17.16.20:388][157]LogHttp: VeryVerbose: 00000231969C4AC0: 'Connection #3 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.20:389][157]LogHttp: Verbose: Request 00000231969C4AC0 (easy handle:00000231A5E60010) has completed (code:0) and has been marked as such +[2018.11.29-17.16.20:389][157]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:389][157]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:389][157]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:389][157]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:389][157]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:389][157]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:389][157]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:389][157]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:389][157]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:389][157]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:390][157]LogHttp: 00000231969C4AC0: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/receipts/v1/account/e6f5091c3b2f4c359cf2aad75c424de0/receipts, HTTP code: 200, content length: 2, actual payload size: 2 +[2018.11.29-17.16.20:390][157]LogHttp: Verbose: 00000231969C4AC0 Response Header Content-Type: application/json +[2018.11.29-17.16.20:390][157]LogHttp: Verbose: 00000231969C4AC0 Response Header Date: Thu, 29 Nov 2018 17:16:20 GMT +[2018.11.29-17.16.20:390][157]LogHttp: Verbose: 00000231969C4AC0 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.20:390][157]LogHttp: Verbose: 00000231969C4AC0 Response Header X-Epic-Correlation-ID: FN-NrvcBY-MMUSWwND-vmvDAw +[2018.11.29-17.16.20:390][157]LogHttp: Verbose: 00000231969C4AC0 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.20:390][157]LogHttp: Verbose: 00000231969C4AC0 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.20:390][157]LogHttp: Verbose: 00000231969C4AC0 Response Header Content-Length: 2 +[2018.11.29-17.16.20:390][157]LogHttp: Verbose: 00000231969C4AC0 Response Header Connection: keep-alive +[2018.11.29-17.16.20:390][157]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:390][157]LogWebSockets: Verbose: FLwsWebSocket[1]::ConnectInternal: lws_client_connect_via_info succeeded +[2018.11.29-17.16.20:404][158]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:404][158]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:404][158]LogCatalogHelper: Found receipt with 1 offers for appstore=EpicPurchasingService +[2018.11.29-17.16.20:404][158]LogCatalogHelper: Offer 0 had 0 line-items +[2018.11.29-17.16.20:404][158]LogCatalogHelper: Validated no receipts +[2018.11.29-17.16.20:418][158]LogOnlineAccount: Display: [UOnlineAccountCommon::ContinueLoggingIn] Login: Searching for session to rejoin... (CheckingRejoin) +[2018.11.29-17.16.20:434][159]LogOnlineAccount: Display: [UOnlineAccountCommon::ContinueLoggingIn] Login: Checking connection to datacenters... (DoQosPingTests) +[2018.11.29-17.16.20:451][160]LogOnlineAccount: Display: [UOnlineAccountCommon::ContinueLoggingIn] Login: Creating party... (CreatingParty) +[2018.11.29-17.16.20:451][160]LogParty: Attempting to create new persistent party +[2018.11.29-17.16.20:452][160]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::PublishPartyInfoToPresence success to publish presence user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.20:452][160]LogParty: Verbose: Member [LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0), Party (C9AE807B4F9D1F30F1535488AB79E7A8)] is now fully initialized. +[2018.11.29-17.16.20:452][160]LogParty: Verbose: Created new party member [LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0), Party (C9AE807B4F9D1F30F1535488AB79E7A8)] +[2018.11.29-17.16.20:452][160]LogOnlineParty: Verbose: OSS: ApproveUserForRejoin: user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 User e6f5091c3b2f4c359cf2aad75c424de0 has been added to the approved list +[2018.11.29-17.16.20:453][160]LogParty: Verbose: Party [C9AE807B4F9D1F30F1535488AB79E7A8, LocalOwner (LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0)), Leader (LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0))] attempting to update party config +[2018.11.29-17.16.20:453][160]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.updatepartyconfiguration user=e6f5091c3b2f4c359cf2aad75c424de0 to=all payload={"partyId":"C9AE807B4F9D1F30F1535488AB79E7A8","presencePermissions":-1834389760,"invitePermissions":32512,"partyFlags":2,"notAcceptingMembersReason":1,"maxMembers":4,"password":"","accessKey":"1A9601624B2510433E8340B1FAAD2362"} +[2018.11.29-17.16.20:453][160]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::PublishPartyInfoToPresence success to publish presence user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.20:453][160]LogOnlineParty: Verbose: OSS: UpdateParty request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.20:453][160]LogParty: Verbose: [C9AE807B4F9D1F30F1535488AB79E7A8] Party config updated Succeeded +[2018.11.29-17.16.20:453][160]LogParty: Verbose: Initializing rep data for party [C9AE807B4F9D1F30F1535488AB79E7A8, LocalOwner (LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0)), Leader (LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0))] +[2018.11.29-17.16.20:453][160]LogParty: Verbose: Party [C9AE807B4F9D1F30F1535488AB79E7A8, LocalOwner (LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0)), Leader (LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0))] attempting to update party config +[2018.11.29-17.16.20:453][160]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.updatepartyconfiguration user=e6f5091c3b2f4c359cf2aad75c424de0 to=all payload={"partyId":"C9AE807B4F9D1F30F1535488AB79E7A8","presencePermissions":-1834389757,"invitePermissions":32515,"partyFlags":2,"notAcceptingMembersReason":1,"maxMembers":4,"password":"","accessKey":"1A9601624B2510433E8340B1FAAD2362"} +[2018.11.29-17.16.20:453][160]LogOnlineParty: Warning: OSS: FOnlinePartySystemMcp::PublishPartyInfoToPresence failure to publish presence user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.20:453][160]LogOnlineParty: Verbose: OSS: UpdateParty request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.20:453][160]LogParty: Verbose: [C9AE807B4F9D1F30F1535488AB79E7A8] Party config updated Succeeded +[2018.11.29-17.16.20:453][160]LogParty: Verbose: Party [C9AE807B4F9D1F30F1535488AB79E7A8, LocalOwner (LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0)), Leader (LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0))] attempting to update party config +[2018.11.29-17.16.20:454][160]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.updatepartyconfiguration user=e6f5091c3b2f4c359cf2aad75c424de0 to=all payload={"partyId":"C9AE807B4F9D1F30F1535488AB79E7A8","presencePermissions":-1834389757,"invitePermissions":32515,"partyFlags":3,"notAcceptingMembersReason":0,"maxMembers":4,"password":"","accessKey":"1A9601624B2510433E8340B1FAAD2362"} +[2018.11.29-17.16.20:454][160]LogOnlineParty: Warning: OSS: FOnlinePartySystemMcp::PublishPartyInfoToPresence failure to publish presence user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.20:454][160]LogOnlineParty: Verbose: OSS: UpdateParty request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.20:454][160]LogParty: Verbose: [C9AE807B4F9D1F30F1535488AB79E7A8] Party config updated Succeeded +[2018.11.29-17.16.20:454][160]LogParty: Display: New party member state for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] added to the local player's party [C9AE807B4F9D1F30F1535488AB79E7A8]. +[2018.11.29-17.16.20:454][160]LogFort: ApplyHeroEffectsAndAbilities succeeded +[2018.11.29-17.16.20:454][160]LogFort: ApplyHomebaseEffectsOnPlayerSetup Succeeded +[2018.11.29-17.16.20:455][160]LogParty: Verbose: UFortUITeamInfo::GetParty: Adding for party leader Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] +[2018.11.29-17.16.20:455][160]LogParty: Display: Adding [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] as a new member to [MCP:e6f5091c3b2f4c359cf2aad75c424de0]'s party via an existing UITeamMember in [LoadBot07063]'s game. +[2018.11.29-17.16.20:455][160]LogParty: Display: New member [MCP:e6f5091c3b2f4c359cf2aad75c424de0] added to UI Party led by [MCP:e6f5091c3b2f4c359cf2aad75c424de0] platform id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] +[2018.11.29-17.16.20:455][160]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.16.20:455][160]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] added to team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.16.20:455][160]LogParty: Display: Got bad homebase data +[2018.11.29-17.16.20:456][160]LogParty: Verbose: Persistent party state changed to Disconnected +[2018.11.29-17.16.20:456][160]LogParty: Verbose: Finished trying to create party [C9AE807B4F9D1F30F1535488AB79E7A8] with result [Succeeded] +[2018.11.29-17.16.20:456][160]LogOnlineParty: OSS: CreateParty request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 state=Disconnected +[2018.11.29-17.16.20:459][161]LogOnlineParty: Verbose: OSS: UpdatePartyData request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.20:459][161]LogOnlineParty: Verbose: OSS: UpdatePartyMemberData request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.20:460][161]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.16.20:460][161]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] team member data updated, team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.16.20:460][161]LogParty: Display: Got bad homebase data +[2018.11.29-17.16.20:461][161]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.16.20:461][161]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] team member data updated, team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.16.20:461][161]LogParty: Display: Got bad homebase data +[2018.11.29-17.16.20:461][161]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.16.20:461][161]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] team member data updated, team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.16.20:461][161]LogParty: Display: Got bad homebase data +[2018.11.29-17.16.20:461][161]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.16.20:461][161]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] team member data updated, team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.16.20:461][161]LogParty: Display: Got bad homebase data +[2018.11.29-17.16.20:462][161]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.16.20:462][161]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] team member data updated, team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.16.20:462][161]LogParty: Display: Got bad homebase data +[2018.11.29-17.16.20:462][161]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.16.20:462][161]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] team member data updated, team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.16.20:462][161]LogParty: Display: Got bad homebase data +[2018.11.29-17.16.20:468][161]LogOnlineAccount: Display: [UOnlineAccountCommon::ContinueLoggingIn] Login: Completing Sign-in... (Completed) +[2018.11.29-17.16.20:469][161]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:469][161]LogScheduledEvents: Queuing calendar request to MCP +[2018.11.29-17.16.20:469][161]LogParty: LocalPlayer [0] has logged in - starting up SocialToolkit. +[2018.11.29-17.16.20:469][161]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:469][161]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:470][161]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:470][161]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:470][161]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:470][161]LogProfileSys: MCP-Profile: Dispatching request to https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/storefront/v2/catalog?rvn=204 +[2018.11.29-17.16.20:472][161]LogOnlineGame: Verbose: [UFortUIStateWidget_Login::HandleLoginRequestComplete] [Result=2] [ErrorReason=] +[2018.11.29-17.16.20:473][161]LogFortUI: [UFortUIStateWidget_Login::StartMOTDFlow] Start function +[2018.11.29-17.16.20:473][161]LogFortUI: [UFortUIStateWidget_Login::StartMOTDFlow] Not FNMobile +[2018.11.29-17.16.20:473][161]LogFortUI: [UFortUIStateWidget_Login::EndMOTDFlow] Start function +[2018.11.29-17.16.20:473][161]LogFortUI: [UFortUIStateWidget_Login::EndMOTDFlow] Set seen login message +[2018.11.29-17.16.20:473][161]LogFortUI: [UFortUIStateWidget_Login::EndMOTDFlow] Logged in +[2018.11.29-17.16.20:473][161]FortClientBot: {"Event":"BotLoginSuccessful"} +[2018.11.29-17.16.20:473][161]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.20:543][162]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:543][162]LogHttp: Verbose: 00000231969C3BC0: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/calendar/v1/timeline' +[2018.11.29-17.16.20:544][162]LogHttp: Verbose: 00000231969C3BC0: Verb='GET' +[2018.11.29-17.16.20:544][162]LogHttp: Verbose: 00000231969C3BC0: Custom headers are present +[2018.11.29-17.16.20:544][162]LogHttp: Verbose: 00000231969C3BC0: Payload size=0 +[2018.11.29-17.16.20:544][162]LogHttp: Verbose: 00000231969C3BC0: Adding header 'X-Epic-Correlation-ID: FN-5SVbRoNo_Uy_ITSjCEKSeg' +[2018.11.29-17.16.20:544][162]LogHttp: Verbose: 00000231969C3BC0: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.20:544][162]LogHttp: Verbose: 00000231969C3BC0: Adding header 'Content-Length: 0' +[2018.11.29-17.16.20:544][162]LogHttp: Verbose: 00000231969C3BC0: Adding header 'Expect: ' +[2018.11.29-17.16.20:544][162]LogHttp: 00000231969C3BC0: Starting GET request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/calendar/v1/timeline' +[2018.11.29-17.16.20:544][162]LogHttp: Verbose: 00000231969C3BC0: request (easy handle:00000231A30A0010) has been added to threaded queue for processing +[2018.11.29-17.16.20:544][162]LogGameMode: GameMode returned ReadyToStartMatch +[2018.11.29-17.16.20:544][162]LogGameMode: Display: Match State Changed from WaitingToStart to InProgress +[2018.11.29-17.16.20:545][162]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.20:592][162]LogHttp: Verbose: 00000231969C3BC0: request (easy handle:00000231A30A0010) has started threaded processing +[2018.11.29-17.16.20:592][162]LogHttp: VeryVerbose: 00000231969C3BC0: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.20:592][162]LogHttp: VeryVerbose: 00000231969C3BC0: 'Re-using existing connection! (#3) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.20:592][162]LogHttp: VeryVerbose: 00000231969C3BC0: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#3)' +[2018.11.29-17.16.20:592][162]LogHttp: VeryVerbose: 00000231969C3BC0: Sent SSL data (5 bytes) +[2018.11.29-17.16.20:592][162]LogHttp: VeryVerbose: 00000231969C3BC0: Sent header (1023 bytes) - GET /fortnite/api/calendar/v1/timeline HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-5SVbRoNo_Uy_ITSjCEKSegUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM0RoMXFQVm9LNXp2M1J0TjZCUUM3QUJ1UGJTcTRpdjRjbWJGV3BtX +[2018.11.29-17.16.20:592][162]LogHotfixManager: Display: Returning cached update result 1 +[2018.11.29-17.16.20:592][162]LogGameState: Match State Changed from WaitingToStart to InProgress +[2018.11.29-17.16.20:593][162]LogHealthSnapshot: ======= Snapshot: Start of Match (FortGameStateFrontEnd) ======= +[2018.11.29-17.16.20:593][162]LogHealthSnapshot: Games Played: 0 +[2018.11.29-17.16.20:593][162]LogHealthSnapshot: CPU Memory: Used 1148.55MB, Peak 1148.55MB +[2018.11.29-17.16.20:593][162]LogHealthSnapshot: Physical Memory: Used 1743.30MB, Peak 1808.21MB +[2018.11.29-17.16.20:593][162]LogHealthSnapshot: ========================================================= +[2018.11.29-17.16.20:593][162]LogCore: Warning: LIGHTWEIGHT_TIME_GUARD: FTickFunctionTask - FortGameModeFrontEnd /Game/Maps/Frontend.Frontend:PersistentLevel.FortGameModeFrontEnd_2147482011[TickActor] took 48.29ms! +[2018.11.29-17.16.20:597][162]LogGarbage: Collecting garbage (GCheckForIllegalMarkPendingKill = 1) +[2018.11.29-17.16.20:607][162]LogGarbage: 9.952508 ms for Verify GC Assumptions +[2018.11.29-17.16.20:640][162]LogHttp: VeryVerbose: 00000231969C3BC0: Received SSL data (5 bytes) +[2018.11.29-17.16.20:640][162]LogHttp: VeryVerbose: 00000231969C3BC0: Received header (17 bytes) +[2018.11.29-17.16.20:640][162]LogHttp: Verbose: 00000231969C3BC0: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.20:640][162]LogHttp: VeryVerbose: 00000231969C3BC0: Received header (32 bytes) +[2018.11.29-17.16.20:640][162]LogHttp: Verbose: 00000231969C3BC0: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.20:640][162]LogHttp: VeryVerbose: 00000231969C3BC0: Received header (37 bytes) +[2018.11.29-17.16.20:640][162]LogHttp: Verbose: 00000231969C3BC0: Received response header 'Date: Thu, 29 Nov 2018 17:16:20 GMT'. +[2018.11.29-17.16.20:640][162]LogHttp: VeryVerbose: 00000231969C3BC0: Received header (31 bytes) +[2018.11.29-17.16.20:640][162]LogHttp: Verbose: 00000231969C3BC0: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.20:640][162]LogHttp: VeryVerbose: 00000231969C3BC0: Received header (50 bytes) +[2018.11.29-17.16.20:640][162]LogHttp: Verbose: 00000231969C3BC0: Received response header 'X-Epic-Correlation-ID: FN-5SVbRoNo_Uy_ITSjCEKSeg'. +[2018.11.29-17.16.20:640][162]LogHttp: VeryVerbose: 00000231969C3BC0: Received header (52 bytes) +[2018.11.29-17.16.20:640][162]LogHttp: Verbose: 00000231969C3BC0: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.20:640][162]LogHttp: VeryVerbose: 00000231969C3BC0: Received header (75 bytes) +[2018.11.29-17.16.20:640][162]LogHttp: Verbose: 00000231969C3BC0: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.20:640][162]LogHttp: VeryVerbose: 00000231969C3BC0: Received header (22 bytes) +[2018.11.29-17.16.20:640][162]LogHttp: Verbose: 00000231969C3BC0: Received response header 'Content-Length: 2022'. +[2018.11.29-17.16.20:640][162]LogHttp: VeryVerbose: 00000231969C3BC0: Received header (24 bytes) +[2018.11.29-17.16.20:640][162]LogHttp: Verbose: 00000231969C3BC0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.20:640][162]LogHttp: Verbose: 00000231969C3BC0: Received response header ''. +[2018.11.29-17.16.20:640][162]LogHttp: VeryVerbose: 00000231969C3BC0: Received header (2 bytes) +[2018.11.29-17.16.20:640][162]LogHttp: VeryVerbose: 00000231969C3BC0: Received data (2022 bytes) +[2018.11.29-17.16.20:640][162]LogHttp: Verbose: 00000231969C3BC0: ReceiveResponseBodyCallback: 2022 bytes out of 2022 received. (SizeInBlocks=1, BlockSizeInBytes=2022, Response->TotalBytesRead=0, Response->GetContentLength()=2022, SizeToDownload=2022 (<-this will get returned from the callback)) +[2018.11.29-17.16.20:641][162]LogHttp: VeryVerbose: 00000231969C3BC0: 'Connection #3 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.20:641][162]LogHttp: Verbose: Request 00000231969C3BC0 (easy handle:00000231A30A0010) has completed (code:0) and has been marked as such +[2018.11.29-17.16.20:641][162]LogGarbage: 32.327537 ms for GC +[2018.11.29-17.16.20:641][162]LogGarbage: 0.436826 ms for Gather Unreachable Objects (14 objects collected including 0 cluster objects from 0 clusters) +[2018.11.29-17.16.20:644][162]LogFort: Display: [FortCustomizationAssetLoader M_Med_Soldier_Head_TV13] Finished loading. 7 assets loaded. +[2018.11.29-17.16.20:645][163]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:645][163]LogHttp: Verbose: 00000231969C36C0: URL='https://friends-public-service-gamedev.ol.epicgames.net/friends/api/public/friends/e6f5091c3b2f4c359cf2aad75c424de0?includePending=true' +[2018.11.29-17.16.20:645][163]LogHttp: Verbose: 00000231969C36C0: Verb='GET' +[2018.11.29-17.16.20:645][163]LogHttp: Verbose: 00000231969C36C0: Custom headers are present +[2018.11.29-17.16.20:645][163]LogHttp: Verbose: 00000231969C36C0: Payload size=0 +[2018.11.29-17.16.20:645][163]LogHttp: Verbose: 00000231969C36C0: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.20:645][163]LogHttp: Verbose: 00000231969C36C0: Adding header 'X-Epic-Correlation-ID: FN-laR3qbdQaU_cmqbf_80b4Q' +[2018.11.29-17.16.20:645][163]LogHttp: Verbose: 00000231969C36C0: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.20:645][163]LogHttp: Verbose: 00000231969C36C0: Adding header 'Content-Length: 0' +[2018.11.29-17.16.20:646][163]LogHttp: Verbose: 00000231969C36C0: Adding header 'Expect: ' +[2018.11.29-17.16.20:646][163]LogHttp: 00000231969C36C0: Starting GET request to URL='https://friends-public-service-gamedev.ol.epicgames.net/friends/api/public/friends/e6f5091c3b2f4c359cf2aad75c424de0?includePending=true' +[2018.11.29-17.16.20:646][163]LogHttp: Verbose: 00000231969C36C0: request (easy handle:00000231A3AFAAB0) has been added to threaded queue for processing +[2018.11.29-17.16.20:646][163]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:646][163]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:646][163]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:646][163]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:646][163]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:646][163]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:646][163]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:646][163]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:646][163]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:646][163]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:646][163]LogHttp: 00000231969C3BC0: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/calendar/v1/timeline, HTTP code: 200, content length: 2022, actual payload size: 2022 +[2018.11.29-17.16.20:646][163]LogHttp: Verbose: 00000231969C3BC0 Response Header Content-Type: application/json +[2018.11.29-17.16.20:646][163]LogHttp: Verbose: 00000231969C3BC0 Response Header Date: Thu, 29 Nov 2018 17:16:20 GMT +[2018.11.29-17.16.20:646][163]LogHttp: Verbose: 00000231969C3BC0 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.20:646][163]LogHttp: Verbose: 00000231969C3BC0 Response Header X-Epic-Correlation-ID: FN-5SVbRoNo_Uy_ITSjCEKSeg +[2018.11.29-17.16.20:646][163]LogHttp: Verbose: 00000231969C3BC0 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.20:646][163]LogHttp: Verbose: 00000231969C3BC0 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.20:646][163]LogHttp: Verbose: 00000231969C3BC0 Response Header Content-Length: 2022 +[2018.11.29-17.16.20:646][163]LogHttp: Verbose: 00000231969C3BC0 Response Header Connection: keep-alive +[2018.11.29-17.16.20:646][163]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:893][163]LogWebSockets: Verbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_ESTABLISHED, setting State=Connected PreviousState=Connecting +[2018.11.29-17.16.20:893][163]LogHttp: Verbose: 00000231969C36C0: request (easy handle:00000231A3AFAAB0) has started threaded processing +[2018.11.29-17.16.20:893][163]LogHttp: VeryVerbose: 00000231969C36C0: ' Trying 10.40.239.169...' +[2018.11.29-17.16.20:893][163]LogHttp: VeryVerbose: 00000231969C36C0: 'TCP_NODELAY set' +[2018.11.29-17.16.20:893][163]LogHttp: VeryVerbose: 00000231969C36C0: 'Connected to friends-public-service-gamedev.ol.epicgames.net (10.40.239.169) port 443 (#8)' +[2018.11.29-17.16.20:893][163]LogHttp: VeryVerbose: 00000231969C36C0: 'ALPN, offering http/1.1' +[2018.11.29-17.16.20:893][163]LogHttp: VeryVerbose: 00000231969C36C0: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.20:893][163]LogHttp: VeryVerbose: 00000231969C36C0: 'TLSv1.2 (OUT), TLS header, Certificate Status (22):' +[2018.11.29-17.16.20:893][163]LogHttp: VeryVerbose: 00000231969C36C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.20:893][163]LogHttp: VeryVerbose: 00000231969C36C0: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.20:893][163]LogHttp: VeryVerbose: 00000231969C36C0: Sent SSL data (512 bytes) +[2018.11.29-17.16.20:893][163]LogHttp: VeryVerbose: 00000231969C36C0: Received SSL data (5 bytes) +[2018.11.29-17.16.20:893][163]LogHttp: VeryVerbose: 00000231969C36C0: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.20:893][163]LogHttp: VeryVerbose: 00000231969C36C0: Received SSL data (104 bytes) +[2018.11.29-17.16.20:893][163]LogHttp: VeryVerbose: 00000231969C36C0: Received SSL data (5 bytes) +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: 'TLSv1.2 (IN), TLS handshake, Certificate (11):' +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: Received SSL data (4568 bytes) +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: Received SSL data (5 bytes) +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: 'TLSv1.2 (IN), TLS handshake, Server key exchange (12):' +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: Received SSL data (333 bytes) +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: Received SSL data (5 bytes) +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: 'TLSv1.2 (IN), TLS handshake, Server finished (14):' +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: Received SSL data (4 bytes) +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: 'TLSv1.2 (OUT), TLS handshake, Client key exchange (16):' +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: Sent SSL data (70 bytes) +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: Sent SSL data (1 bytes) +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.20:894][163]LogHttp: VeryVerbose: 00000231969C36C0: Sent SSL data (16 bytes) +[2018.11.29-17.16.20:894][163]LogHotfixManager: Display: CheckComplete UpdateSuccess +[2018.11.29-17.16.20:894][163]LogGarbage: 0.050415 ms for incrementally unhashing unreachable objects. Items 14 (14/14) +[2018.11.29-17.16.20:898][164]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: connection successful +[2018.11.29-17.16.20:898][164]LogXmpp: VeryVerbose: libstrophe[71688] conn debug: SENT: +[2018.11.29-17.16.20:898][164]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.20:898][164]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.20:898][164]LogScheduledEvents: Calendar request returned HTTP 200 +[2018.11.29-17.16.20:898][164]LogScheduledEvents: Received new Calendar data. Events time offset is 168 hrs +[2018.11.29-17.16.20:898][164]LogScheduledEvents: Updating channel 'client-matchmaking' due to new data. +[2018.11.29-17.16.20:898][164]LogScheduledEvents: Updating channel 'client-events' due to new data. +[2018.11.29-17.16.20:898][164]LogScheduledEvents: Calendar update complete. Current events time is 2018-12-06T17:16:20.519Z. Cache expires 2018-12-06T20:57:53.722Z. +[2018.11.29-17.16.20:898][164]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.20:898][164]LogHttp: Verbose: 00000231969C2A40: URL='https://friends-public-service-gamedev.ol.epicgames.net/friends/api/public/blocklist/e6f5091c3b2f4c359cf2aad75c424de0' +[2018.11.29-17.16.20:898][164]LogHttp: Verbose: 00000231969C2A40: Verb='GET' +[2018.11.29-17.16.20:898][164]LogHttp: Verbose: 00000231969C2A40: Custom headers are present +[2018.11.29-17.16.20:898][164]LogHttp: Verbose: 00000231969C2A40: Payload size=0 +[2018.11.29-17.16.20:898][164]LogHttp: Verbose: 00000231969C2A40: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.20:899][164]LogHttp: Verbose: 00000231969C2A40: Adding header 'X-Epic-Correlation-ID: FN-COpTAMr6VEeU6Fmp8YCxRQ' +[2018.11.29-17.16.20:899][164]LogHttp: Verbose: 00000231969C2A40: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.20:899][164]LogHttp: Verbose: 00000231969C2A40: Adding header 'Content-Length: 0' +[2018.11.29-17.16.20:899][164]LogHttp: Verbose: 00000231969C2A40: Adding header 'Expect: ' +[2018.11.29-17.16.20:899][164]LogHttp: 00000231969C2A40: Starting GET request to URL='https://friends-public-service-gamedev.ol.epicgames.net/friends/api/public/blocklist/e6f5091c3b2f4c359cf2aad75c424de0' +[2018.11.29-17.16.20:899][164]LogHttp: Verbose: 00000231969C2A40: request (easy handle:00000231A3F4AAB0) has been added to threaded queue for processing +[2018.11.29-17.16.20:903][164]LogHttp: Verbose: 00000231969C2A40: request (easy handle:00000231A3F4AAB0) has started threaded processing +[2018.11.29-17.16.20:903][164]LogHttp: VeryVerbose: 00000231969C2A40: 'Found bundle for host friends-public-service-gamedev.ol.epicgames.net: 0x2318f885740 [serially]' +[2018.11.29-17.16.20:903][164]LogHttp: VeryVerbose: 00000231969C2A40: 'Hostname friends-public-service-gamedev.ol.epicgames.net was found in DNS cache' +[2018.11.29-17.16.20:903][164]LogHttp: VeryVerbose: 00000231969C2A40: ' Trying 10.40.239.169...' +[2018.11.29-17.16.20:903][164]LogHttp: VeryVerbose: 00000231969C2A40: 'TCP_NODELAY set' +[2018.11.29-17.16.20:903][164]LogLevel: ActivateLevel /Game/Maps/UI/Frontend_Lobby_Default 0 0 0 +[2018.11.29-17.16.20:903][164]LogLevel: ActivateLevel /Game/Maps/UI/Frontend_Lobby_Winter2018 1 1 1 +[2018.11.29-17.16.20:906][164]LogStreaming: Display: ULevelStreaming::RequestLevel(/Game/Maps/UI/Frontend_Lobby_Winter2018) is flushing async loading +[2018.11.29-17.16.20:906][164]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Received SSL data (5 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Received SSL data (1 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Received SSL data (5 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Received SSL data (16 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: 'Server certificate:' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: ' subjectAltName: host "friends-public-service-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: ' SSL certificate verify ok.' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Sent header (1023 bytes) - GET /friends/api/public/friends/e6f5091c3b2f4c359cf2aad75c424de0?includePending=true HTTP/1.1Host: friends-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/jsonX-Epic-Correlation-ID: FN-laR3qbdQaU_cmqbf_80b4QUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZ +[2018.11.29-17.16.21:303][164]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::SendFromQueue: Wrote 96 bytes, 0 bytes remaining in this packet +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C2A40: 'Connected to friends-public-service-gamedev.ol.epicgames.net (10.40.239.169) port 443 (#9)' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C2A40: 'ALPN, offering http/1.1' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C2A40: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C2A40: 'SSL re-using session ID' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C2A40: Sent SSL data (5 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C2A40: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C2A40: Sent SSL data (512 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Received SSL data (5 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Received header (17 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: Verbose: 00000231969C36C0: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Received header (37 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: Verbose: 00000231969C36C0: Received response header 'Date: Thu, 29 Nov 2018 17:16:20 GMT'. +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Received header (32 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: Verbose: 00000231969C36C0: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Received header (21 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: Verbose: 00000231969C36C0: Received response header 'Content-Length: 174'. +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Received header (24 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: Verbose: 00000231969C36C0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Received header (50 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: Verbose: 00000231969C36C0: Received response header 'X-Epic-Correlation-ID: FN-laR3qbdQaU_cmqbf_80b4Q'. +[2018.11.29-17.16.21:303][164]LogHttp: Verbose: 00000231969C36C0: Received response header ''. +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Received header (2 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: Received data (174 bytes) +[2018.11.29-17.16.21:303][164]LogHttp: Verbose: 00000231969C36C0: ReceiveResponseBodyCallback: 174 bytes out of 174 received. (SizeInBlocks=1, BlockSizeInBytes=174, Response->TotalBytesRead=0, Response->GetContentLength()=174, SizeToDownload=174 (<-this will get returned from the callback)) +[2018.11.29-17.16.21:303][164]LogHttp: VeryVerbose: 00000231969C36C0: 'Connection #8 to host friends-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.21:303][164]LogHttp: Verbose: Request 00000231969C36C0 (easy handle:00000231A3AFAAB0) has completed (code:0) and has been marked as such +[2018.11.29-17.16.21:304][164]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=154 BytesLeft=0 +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Received SSL data (5 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Received SSL data (96 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Received SSL data (5 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Received SSL data (1 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Received SSL data (5 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Received SSL data (16 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Sent SSL data (5 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Sent SSL data (1 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Sent SSL data (5 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Sent SSL data (16 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: 'Server certificate:' +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: ' subjectAltName: host "friends-public-service-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: ' SSL certificate verify ok.' +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Sent SSL data (5 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Sent header (1023 bytes) - GET /friends/api/public/blocklist/e6f5091c3b2f4c359cf2aad75c424de0 HTTP/1.1Host: friends-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/jsonX-Epic-Correlation-ID: FN-COpTAMr6VEeU6Fmp8YCxRQUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM +[2018.11.29-17.16.21:304][164]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=412 BytesLeft=0 +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Received SSL data (5 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Received header (17 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: Verbose: 00000231969C2A40: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Received header (37 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: Verbose: 00000231969C2A40: Received response header 'Date: Thu, 29 Nov 2018 17:16:20 GMT'. +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Received header (32 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: Verbose: 00000231969C2A40: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Received header (20 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: Verbose: 00000231969C2A40: Received response header 'Content-Length: 26'. +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Received header (24 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: Verbose: 00000231969C2A40: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Received header (50 bytes) +[2018.11.29-17.16.21:304][164]LogHttp: Verbose: 00000231969C2A40: Received response header 'X-Epic-Correlation-ID: FN-COpTAMr6VEeU6Fmp8YCxRQ'. +[2018.11.29-17.16.21:304][164]LogHttp: Verbose: 00000231969C2A40: Received response header ''. +[2018.11.29-17.16.21:304][164]LogHttp: VeryVerbose: 00000231969C2A40: Received header (2 bytes) +[2018.11.29-17.16.21:305][164]LogHttp: VeryVerbose: 00000231969C2A40: Received data (26 bytes) +[2018.11.29-17.16.21:305][164]LogHttp: Verbose: 00000231969C2A40: ReceiveResponseBodyCallback: 26 bytes out of 26 received. (SizeInBlocks=1, BlockSizeInBytes=26, Response->TotalBytesRead=0, Response->GetContentLength()=26, SizeToDownload=26 (<-this will get returned from the callback)) +[2018.11.29-17.16.21:305][164]LogHttp: VeryVerbose: 00000231969C2A40: 'Connection cache is full, closing the oldest one.' +[2018.11.29-17.16.21:305][164]LogHttp: VeryVerbose: 00000231969C2A40: 'Closing connection 2' +[2018.11.29-17.16.21:305][164]LogHttp: VeryVerbose: 00000231969C2A40: Sent SSL data (5 bytes) +[2018.11.29-17.16.21:305][164]LogHttp: VeryVerbose: 00000231969C2A40: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.16.21:305][164]LogHttp: VeryVerbose: 00000231969C2A40: Sent SSL data (2 bytes) +[2018.11.29-17.16.21:305][164]LogHttp: VeryVerbose: 00000231969C2A40: 'Connection #9 to host friends-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.21:305][164]LogHttp: Verbose: Request 00000231969C2A40 (easy handle:00000231A3F4AAB0) has completed (code:0) and has been marked as such +[2018.11.29-17.16.21:313][164]LogLevelActorContainer: Created LevelActorCluster (13) for /Game/Maps/UI/Frontend_Lobby_Winter2018.Frontend_Lobby_Winter2018:PersistentLevel with 220 objects, 0 referenced clusters and 39 mutable objects. +[2018.11.29-17.16.21:317][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.21:317][165]LogHttp: Verbose: 00000231969C2040: URL='https://friends-public-service-gamedev.ol.epicgames.net/friends/api/public/list/fortnite/e6f5091c3b2f4c359cf2aad75c424de0/recentPlayers' +[2018.11.29-17.16.21:317][165]LogHttp: Verbose: 00000231969C2040: Verb='GET' +[2018.11.29-17.16.21:317][165]LogHttp: Verbose: 00000231969C2040: Custom headers are present +[2018.11.29-17.16.21:317][165]LogHttp: Verbose: 00000231969C2040: Payload size=0 +[2018.11.29-17.16.21:317][165]LogHttp: Verbose: 00000231969C2040: Adding header 'X-Epic-Correlation-ID: FN-yxC6Z0oEs0O1E4gMm4z9wg' +[2018.11.29-17.16.21:317][165]LogHttp: Verbose: 00000231969C2040: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.21:317][165]LogHttp: Verbose: 00000231969C2040: Adding header 'Content-Length: 0' +[2018.11.29-17.16.21:317][165]LogHttp: Verbose: 00000231969C2040: Adding header 'Expect: ' +[2018.11.29-17.16.21:317][165]LogHttp: 00000231969C2040: Starting GET request to URL='https://friends-public-service-gamedev.ol.epicgames.net/friends/api/public/list/fortnite/e6f5091c3b2f4c359cf2aad75c424de0/recentPlayers' +[2018.11.29-17.16.21:317][165]LogHttp: Verbose: 00000231969C2040: request (easy handle:00000231A3F45560) has been added to threaded queue for processing +[2018.11.29-17.16.21:317][165]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: RECV: +[2018.11.29-17.16.21:317][165]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: RECV: PLAINzlib +[2018.11.29-17.16.21:317][165]LogXmpp: VeryVerbose: libstrophe[71688] conn debug: SENT: AGU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwAGVnMX5leUpyYVdRaU9pSnpSa3RxYURsd1MzZDVSMXBSV2tOdk9GODFOREZGU0dOWGRtTldMVnBIZGxGS1JqZGpUbTU1TVMxTklpd2lZV3huSWpvaVVGTXlOVFlpZlEuZXlKaGNIQWlPaUptYjNKMGJtbDBaU0lzSW5OMVlpSTZJbVUyWmpVd09URmpNMkl5WmpSak16VTVZMll5WVdGa056VmpOREkwWkdVd0lpd2laSFpwWkNJNkltWmhOVFZsTXpFd09HWXpabU0yTm1RMll6Um1aamRsWWpRek9UaGxNbUU1SWl3aVkyeHBaQ0k2SW1Wak5qZzBZamhqTmpnM1pqUTNPV1poWkdWaE0yTmlNbUZrT0RObU5XTTJJaXdpWVcwaU9pSndZWE56ZDI5eVpDSXNJbkFpT2lKbFRuRjBWblIwVDBsNlJVMWNMMW80UzBsV2NXMXpSVlJ4UVN0TGVWRnRTVVl5ZFRkRWRteFdkVFJ0YlhwVVdrNVNhMmx1YkRjNVprcFlTbWR3U0ZSd1FUTTVjSGhaZG5aWmVEaGplRlpvYjNSalQxQlNaV0ZyV0ZSS1oxaHlVWGxKZVZoQ09HdHFkVEJxT1VvMWJHaHljblJtVkVrNFEwbGtiakV3VGl0bWJEaHNRMkk0WmtoNlJqQjRSMEYxUW5wNldrcFJTVkJLZFUxVWRYRjZiVlJYY0ZaSlpuWnpSVWRKUWxwNVlsaElkVmMxV0Uxc1QyRjJLMFJ6WjJvMVozRTRRbUkwU3l0YVZqSkpWakp0TkVKVlYwWnVSMDVrVEVKSVdtbGFRVlpZUzBSR1pHSm5TV05VVHpCRWNXcG5WRzR3TkdKMWNtOTRPVEJUY0dSeWRrWjVXbGhFYUhaTVEzbFJkVlptYm1OVk1VSlBNMFJvTVhGUVZtOUxOWHAyTTFKMFRqWkNVVU0zUVVKMVVHSlRjVFJwZGpSamJXSkdWM0J0WEM5Q1RIUkdTakJxVkU4M1pUSlBka05sY1U1clQxQXlha0ZIZEZKSlltZFhXSEJpZUZaeVp6RjFXVUpHYzBnMFpHSkhZbmhrZUVad1IyMUlabFU1ZEdSdlNVdHNXa2xVY2pWaWF6ZFlOV1pWT1hRemJYUlplRVUwZGtGME1rcDBTVlk1U2pjeFN6VjFPWFZrU25wUldXWlZXbEozWW5Sa1dsSjFVMHAyWVVSRWFDdElWM0puZUZGY0wzZE5XbHAyU0VoRGVUVm5hbU41UTFaTVVGTXpPSGhNZG10SlhDOVRWRzl5TVU0eVdFRk1XRkFyUkZkSGRIWnZlSE13V1VaaU5VWk9hbEZ5ZG5GY0x6UmliRGhFZWpWU2NtbHVURFpXTkRVclVuVnJPVTVoYW1OWFNUWjZVblF4UVZabmVrRjBTbHd2Y25ZelIzbG1Ua28wTmpKUVZFbFhUMjlPUjFOa1dHNTRiVFZMWkhGT05VVnBWSFEwVDBRMFUySlZPRTlMU1dGSU5FSnlOVU0wU1hGNlZYcHZUMjA0UzA5UFZITldVbVZCY1cxM1JuWkRPRVl6VjNSRVRqWmxTbkJYUjJOVlozUTNhRFZpY3pkcFkyRk5PVlExVGpOdVUxUTRNMnBWTlVWNk9VVmpiR1o1V0c1aGVtNTROV3hzYzNGTGJYQlRVbGhETTBKdmJVRnRWRk51V0dGUGFsbFRhRnBrVW5SNmIzTlRabEJsTkhScVZ6TjBObGw1UW1nNWVVUkJRVFpZY1VSS1pXY3lUVXRoVUVoUFRYUk1RWEV3ZFZSNVV6Tk1XWEJrWms1ME9FMHJSMjQxZURoU1VVSlFPWEY2TjBKaFJqVlBRbEpvUkVaRkt6Vk9WVGxHVW5GUFVtdGxZeXQzWlhCak5qTkdaa1UyT1hKdmVWcHdWbTQ1V0hCY0wwVk9LMVJOWW5GMGNFWTFVbmd6VkZRd1dYVjRjV3hXYkc5MVRHVlZaSFZxWWpWT2FHTnJSRnd2YW1wMWN6RXhjRmxKTUZWMk5sUXpiM1ZzVkcxdGRFbGxXVll3ZDFkd1VFTTNaM2cyTWxsNE9VRXpRbVphYTBVMk9WSm9URkkzWkROa2VrcG1aMnczWjI1NVJEbE9NRnBuUzF3dmJTdGlPWFpRUlhaamRVTnJOVVl6V0dSMmJuVmhRVTVaVkU5WFJYbDBhVlVyVWtRMFRVNXFjbkJVY1RRM1QyeGxSM0pMUTBkSWNUVkdNSFpsVDB0U01tMTFjVXR2Y1haMVpreDFaVXQ0T0haME5GaDBOMXBoTkc1MmEzWmNMMmRLV1dsMklpd2lhV0ZwSWpvaVpUWm1OVEE1TVdNellqSm1OR016TlRsalpqSmhZV1EzTldNME1qUmtaVEFpTENKamJITjJZeUk2SW1admNuUnVhWFJsSWl3aWJIQjJJam94TlRRek5URXhOemMzTENKMElqb2ljeUlzSW1saklqcDBjblZsTENKbGVIQWlPakUxTkRNMU5EQTFOemNzSW1saGRDSTZNVFUwTXpVeE1UYzNOeXdpYW5ScElqb2lZMlV6WlRnMk0ySTBOVEEyTkRReU1XSTBORGxtTVRjeU9XWXdOak5tTldZaWZRLkFRMFhCQWVyNVpubXpTSFRZekZyamVLdXZnRFMtbjFrUGxPMW04TkduNlJJZlJ5bUxvNER1V0tfeVFUdm9LTWQxWHZSUjZ3RzVxVHF0amFpb2JLeGdMOEQ= +[2018.11.29-17.16.21:317][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.21:317][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.21:317][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:317][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:317][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:317][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:317][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:317][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.21:317][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.21:317][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:317][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:317][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:317][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:318][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:318][165]LogHttp: 00000231969C36C0: request has been successfully processed. URL: https://friends-public-service-gamedev.ol.epicgames.net/friends/api/public/friends/e6f5091c3b2f4c359cf2aad75c424de0?includePending=true, HTTP code: 200, content length: 174, actual payload size: 174 +[2018.11.29-17.16.21:318][165]LogHttp: Verbose: 00000231969C36C0 Response Header Date: Thu, 29 Nov 2018 17:16:20 GMT +[2018.11.29-17.16.21:318][165]LogHttp: Verbose: 00000231969C36C0 Response Header Content-Type: application/json +[2018.11.29-17.16.21:318][165]LogHttp: Verbose: 00000231969C36C0 Response Header Content-Length: 174 +[2018.11.29-17.16.21:318][165]LogHttp: Verbose: 00000231969C36C0 Response Header Connection: keep-alive +[2018.11.29-17.16.21:318][165]LogHttp: Verbose: 00000231969C36C0 Response Header X-Epic-Correlation-ID: FN-laR3qbdQaU_cmqbf_80b4Q +[2018.11.29-17.16.21:318][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.21:318][165]LogHttp: 00000231969C2A40: request has been successfully processed. URL: https://friends-public-service-gamedev.ol.epicgames.net/friends/api/public/blocklist/e6f5091c3b2f4c359cf2aad75c424de0, HTTP code: 200, content length: 26, actual payload size: 26 +[2018.11.29-17.16.21:318][165]LogHttp: Verbose: 00000231969C2A40 Response Header Date: Thu, 29 Nov 2018 17:16:20 GMT +[2018.11.29-17.16.21:318][165]LogHttp: Verbose: 00000231969C2A40 Response Header Content-Type: application/json +[2018.11.29-17.16.21:318][165]LogHttp: Verbose: 00000231969C2A40 Response Header Content-Length: 26 +[2018.11.29-17.16.21:318][165]LogHttp: Verbose: 00000231969C2A40 Response Header Connection: keep-alive +[2018.11.29-17.16.21:318][165]LogHttp: Verbose: 00000231969C2A40 Response Header X-Epic-Correlation-ID: FN-COpTAMr6VEeU6Fmp8YCxRQ +[2018.11.29-17.16.21:318][165]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.21:321][165]LogHotfixManager: Display: External CheckComplete UpdateSuccess +[2018.11.29-17.16.21:321][165]LogHotfixManager: Display: Update State UpdatePending -> UpdateComplete +[2018.11.29-17.16.21:321][165]LogFort: Display: AFortGameModeFrontEnd::OnUpdateCheckComplete called. Result=1 +[2018.11.29-17.16.21:321][165]LogFortPlayerRegistration: BindToPlayerController trying to initialize ability system actor +[2018.11.29-17.16.21:321][165]LogFort: ApplyHeroEffectsAndAbilities succeeded +[2018.11.29-17.16.21:321][165]LogFort: ApplyHomebaseEffectsOnPlayerSetup Succeeded +[2018.11.29-17.16.21:321][165]LogFortPlayerRegistration: BindToState(AFortPlayerState* State) trying to initialize ability system actor +[2018.11.29-17.16.21:321][165]LogFortPlayerRegistration: BindToPlayerController trying to initialize ability system actor +[2018.11.29-17.16.21:322][165]LogFort: UFortRegisteredPlayerInfo::SynchronizeProfile is adding FFortProfileSynchronizeRequest : RequestId [1]. +[2018.11.29-17.16.21:322][165]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [1]) Request.RequestId [1] initial WaitingFor flags [0]. +[2018.11.29-17.16.21:322][165]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [1]) Request.RequestId [1] final WaitingFor flags [0]. +[2018.11.29-17.16.21:322][165]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [1]) is removing FFortProfileSynchronizeRequest : Request.RequestId [1]. +[2018.11.29-17.16.21:322][165]LogFort: Initialized MCP profile for FortPlayerControllerFrontEnd_2147481983 (force sync: no) +[2018.11.29-17.16.21:322][165]LogOnlineAccount: [OnUpdateCheckComplete::Begin] +[2018.11.29-17.16.21:341][166]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::SendFromQueue: Wrote 2836 bytes, 0 bytes remaining in this packet +[2018.11.29-17.16.21:344][166]LogHttp: Verbose: 00000231969C2040: request (easy handle:00000231A3F45560) has started threaded processing +[2018.11.29-17.16.21:344][166]LogHttp: VeryVerbose: 00000231969C2040: 'Found bundle for host friends-public-service-gamedev.ol.epicgames.net: 0x2318f885740 [can pipeline]' +[2018.11.29-17.16.21:344][166]LogHttp: VeryVerbose: 00000231969C2040: 'Re-using existing connection! (#8) with host friends-public-service-gamedev.ol.epicgames.net' +[2018.11.29-17.16.21:344][166]LogHttp: VeryVerbose: 00000231969C2040: 'Connected to friends-public-service-gamedev.ol.epicgames.net (10.40.239.169) port 443 (#8)' +[2018.11.29-17.16.21:344][166]LogHttp: VeryVerbose: 00000231969C2040: Sent SSL data (5 bytes) +[2018.11.29-17.16.21:344][166]LogHttp: VeryVerbose: 00000231969C2040: Sent header (1023 bytes) - GET /friends/api/public/list/fortnite/e6f5091c3b2f4c359cf2aad75c424de0/recentPlayers HTTP/1.1Host: friends-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-yxC6Z0oEs0O1E4gMm4z9wgUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM0RoMXFQVm9LNXp +[2018.11.29-17.16.21:355][166]LogStaticMesh: Allocated 512x512x1024 distance field atlas = 256.0Mb, with 1078 objects containing 18.4Mb backing data +[2018.11.29-17.16.21:410][166]LogHttp: VeryVerbose: 00000231969C2040: Received SSL data (5 bytes) +[2018.11.29-17.16.21:410][166]LogHttp: VeryVerbose: 00000231969C2040: Received header (17 bytes) +[2018.11.29-17.16.21:410][166]LogHttp: Verbose: 00000231969C2040: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.21:410][166]LogHttp: VeryVerbose: 00000231969C2040: Received header (37 bytes) +[2018.11.29-17.16.21:410][166]LogHttp: Verbose: 00000231969C2040: Received response header 'Date: Thu, 29 Nov 2018 17:16:21 GMT'. +[2018.11.29-17.16.21:410][166]LogHttp: VeryVerbose: 00000231969C2040: Received header (32 bytes) +[2018.11.29-17.16.21:410][166]LogHttp: Verbose: 00000231969C2040: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.21:410][166]LogHttp: VeryVerbose: 00000231969C2040: Received header (19 bytes) +[2018.11.29-17.16.21:410][166]LogHttp: Verbose: 00000231969C2040: Received response header 'Content-Length: 3'. +[2018.11.29-17.16.21:410][166]LogHttp: VeryVerbose: 00000231969C2040: Received header (24 bytes) +[2018.11.29-17.16.21:410][166]LogHttp: Verbose: 00000231969C2040: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.21:410][166]LogHttp: VeryVerbose: 00000231969C2040: Received header (50 bytes) +[2018.11.29-17.16.21:410][166]LogHttp: Verbose: 00000231969C2040: Received response header 'X-Epic-Correlation-ID: FN-yxC6Z0oEs0O1E4gMm4z9wg'. +[2018.11.29-17.16.21:410][166]LogHttp: Verbose: 00000231969C2040: Received response header ''. +[2018.11.29-17.16.21:410][166]LogHttp: VeryVerbose: 00000231969C2040: Received header (2 bytes) +[2018.11.29-17.16.21:410][166]LogHttp: VeryVerbose: 00000231969C2040: Received data (3 bytes) +[2018.11.29-17.16.21:410][166]LogHttp: Verbose: 00000231969C2040: ReceiveResponseBodyCallback: 3 bytes out of 3 received. (SizeInBlocks=1, BlockSizeInBytes=3, Response->TotalBytesRead=0, Response->GetContentLength()=3, SizeToDownload=3 (<-this will get returned from the callback)) +[2018.11.29-17.16.21:411][166]LogHttp: VeryVerbose: 00000231969C2040: 'Connection cache is full, closing the oldest one.' +[2018.11.29-17.16.21:411][166]LogHttp: VeryVerbose: 00000231969C2040: 'Closing connection 6' +[2018.11.29-17.16.21:411][166]LogHttp: VeryVerbose: 00000231969C2040: Sent SSL data (5 bytes) +[2018.11.29-17.16.21:411][166]LogHttp: VeryVerbose: 00000231969C2040: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.16.21:411][166]LogHttp: VeryVerbose: 00000231969C2040: Sent SSL data (2 bytes) +[2018.11.29-17.16.21:411][166]LogHttp: VeryVerbose: 00000231969C2040: 'Connection #8 to host friends-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.21:411][166]LogHttp: Verbose: Request 00000231969C2040 (easy handle:00000231A3F45560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.21:442][166]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=51 BytesLeft=0 +[2018.11.29-17.16.21:719][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.21:719][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.21:719][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:719][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:719][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:719][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:719][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:719][166]LogHttp: 00000231969C2040: request has been successfully processed. URL: https://friends-public-service-gamedev.ol.epicgames.net/friends/api/public/list/fortnite/e6f5091c3b2f4c359cf2aad75c424de0/recentPlayers, HTTP code: 200, content length: 3, actual payload size: 3 +[2018.11.29-17.16.21:720][166]LogHttp: Verbose: 00000231969C2040 Response Header Date: Thu, 29 Nov 2018 17:16:21 GMT +[2018.11.29-17.16.21:720][166]LogHttp: Verbose: 00000231969C2040 Response Header Content-Type: application/json +[2018.11.29-17.16.21:720][166]LogHttp: Verbose: 00000231969C2040 Response Header Content-Length: 3 +[2018.11.29-17.16.21:720][166]LogHttp: Verbose: 00000231969C2040 Response Header Connection: keep-alive +[2018.11.29-17.16.21:720][166]LogHttp: Verbose: 00000231969C2040 Response Header X-Epic-Correlation-ID: FN-yxC6Z0oEs0O1E4gMm4z9wg +[2018.11.29-17.16.21:720][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.21:720][166]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: RECV: +[2018.11.29-17.16.21:720][166]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: SASL PLAIN auth successful +[2018.11.29-17.16.21:720][166]LogXmpp: VeryVerbose: libstrophe[71688] conn debug: SENT: +[2018.11.29-17.16.21:720][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:720][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.21:720][166]LogParty: SocialToolkit [0] finished querying friends list [default] on subsystem [Primary] with error []. +[2018.11.29-17.16.21:720][166]LogParty: Verbose: SocialToolkit [0] processing queried list of [1] users on subsystem [Primary] +[2018.11.29-17.16.21:720][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:720][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.21:721][166]LogParty: SocialToolkit [0] finished querying recent player list [fortnite] on subsystem [Primary] with error []. +[2018.11.29-17.16.21:721][166]LogParty: Verbose: SocialToolkit [0] processing queried list of [0] users on subsystem [Primary] +[2018.11.29-17.16.21:721][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.21:721][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.21:721][166]LogParty: SocialToolkit [0] finished querying blocked players on subsystem [Primary] with error []. +[2018.11.29-17.16.21:721][166]LogParty: Verbose: SocialToolkit [0] processing queried list of [0] users on subsystem [Primary] +[2018.11.29-17.16.21:721][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.21:721][166]LogHttp: Verbose: 00000231969C2540: URL='https://friends-public-service-gamedev.ol.epicgames.net/friends/api/v1/e6f5091c3b2f4c359cf2aad75c424de0/settings' +[2018.11.29-17.16.21:721][166]LogHttp: Verbose: 00000231969C2540: Verb='GET' +[2018.11.29-17.16.21:721][166]LogHttp: Verbose: 00000231969C2540: Custom headers are present +[2018.11.29-17.16.21:721][166]LogHttp: Verbose: 00000231969C2540: Payload size=0 +[2018.11.29-17.16.21:721][166]LogHttp: Verbose: 00000231969C2540: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.21:721][166]LogHttp: Verbose: 00000231969C2540: Adding header 'X-Epic-Correlation-ID: FN-iwpmwUymqEm4SIUhHBk_Cw' +[2018.11.29-17.16.21:721][166]LogHttp: Verbose: 00000231969C2540: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.21:722][166]LogHttp: Verbose: 00000231969C2540: Adding header 'Content-Length: 0' +[2018.11.29-17.16.21:722][166]LogHttp: Verbose: 00000231969C2540: Adding header 'Expect: ' +[2018.11.29-17.16.21:722][166]LogHttp: 00000231969C2540: Starting GET request to URL='https://friends-public-service-gamedev.ol.epicgames.net/friends/api/v1/e6f5091c3b2f4c359cf2aad75c424de0/settings' +[2018.11.29-17.16.21:722][166]LogHttp: Verbose: 00000231969C2540: request (easy handle:00000231A166AAB0) has been added to threaded queue for processing +[2018.11.29-17.16.21:722][166]LogParty: FSocialQuery_UserInfo executing for [1] users on subsystem [Primary] +[2018.11.29-17.16.21:722][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.21:726][166]LogFortUI: Display: [UFortUIManagerWidget_NUI::SetUIState] states from: Login to FrontEnd +[2018.11.29-17.16.21:727][166]LogUMG: Display: Widget Class FrontEnd_C - Loaded Fast Template. +[2018.11.29-17.16.21:734][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:734][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:734][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.21:735][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:735][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:735][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:735][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:735][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:735][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:735][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:735][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:736][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:737][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:738][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:739][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:739][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:739][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:739][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:739][166]LogFortUI: Display: [UFortUIManagerWidget_NUI::TransitionToNextState] Switching states from: Login to FrontEnd +[2018.11.29-17.16.21:739][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:739][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:739][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:739][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:739][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:739][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:739][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:739][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:739][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:739][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:740][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:740][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:740][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:740][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:740][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:740][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:740][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:741][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:742][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:743][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:743][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:743][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:743][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:743][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:743][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:743][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:743][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:743][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:743][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:745][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:747][166]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::SendFromQueue: Wrote 96 bytes, 0 bytes remaining in this packet +[2018.11.29-17.16.21:747][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:747][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:747][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:747][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:747][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:748][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:748][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:748][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:748][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:748][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:748][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:748][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:748][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:748][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:749][166]LogHttp: Verbose: 00000231969C2540: request (easy handle:00000231A166AAB0) has started threaded processing +[2018.11.29-17.16.21:749][166]LogHttp: VeryVerbose: 00000231969C2540: 'Found bundle for host friends-public-service-gamedev.ol.epicgames.net: 0x2318f885740 [can pipeline]' +[2018.11.29-17.16.21:749][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:749][166]LogHttp: VeryVerbose: 00000231969C2540: 'Re-using existing connection! (#8) with host friends-public-service-gamedev.ol.epicgames.net' +[2018.11.29-17.16.21:749][166]LogHttp: VeryVerbose: 00000231969C2540: 'Connected to friends-public-service-gamedev.ol.epicgames.net (10.40.239.169) port 443 (#8)' +[2018.11.29-17.16.21:749][166]LogHttp: VeryVerbose: 00000231969C2540: Sent SSL data (5 bytes) +[2018.11.29-17.16.21:749][166]LogHttp: VeryVerbose: 00000231969C2540: Sent header (1023 bytes) - GET /friends/api/v1/e6f5091c3b2f4c359cf2aad75c424de0/settings HTTP/1.1Host: friends-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/jsonX-Epic-Correlation-ID: FN-iwpmwUymqEm4SIUhHBk_CwUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM0RoMX +[2018.11.29-17.16.21:749][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:749][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:749][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:749][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:749][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:749][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:750][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:750][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:750][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:750][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:750][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:750][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:750][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:750][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:750][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:750][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:750][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:750][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:751][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:751][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:751][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:751][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:751][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:751][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:751][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:752][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:752][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:752][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:752][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:752][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:752][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:752][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:752][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:752][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:753][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:754][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:755][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:755][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:755][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:755][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:755][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:755][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:755][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:755][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:755][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:755][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:755][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:755][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:755][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:755][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:756][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:757][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:757][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:757][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:757][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:757][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:757][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:757][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:757][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:757][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:757][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:757][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:757][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:758][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:758][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:758][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:758][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:758][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:758][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:758][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:758][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:758][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:758][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:758][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:759][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:759][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:759][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:759][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:759][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:759][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:759][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:759][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:759][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:759][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:760][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:760][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:760][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:760][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:760][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:760][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:760][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:760][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:760][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:760][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:760][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:761][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:762][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:763][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:764][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:764][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:764][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:764][166]LogUMG: Display: Widget Class TeamSelectWidget_C - Loaded Fast Template. +[2018.11.29-17.16.21:765][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:765][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:765][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:765][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:765][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:765][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:765][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:765][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:765][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:765][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:765][166]LogUMG: Display: Widget Class RespawnPromptWidget_C - Loaded Fast Template. +[2018.11.29-17.16.21:765][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:765][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:765][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:765][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:765][166]LogUMG: Display: Widget Class PrivacyWidget_C - Loaded Fast Template. +[2018.11.29-17.16.21:766][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:766][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:766][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:766][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:766][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:767][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:767][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:767][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:767][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:767][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:767][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:767][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:767][166]LogUMG: Display: Widget Class ShowFriendCodesSelection_C - Loaded Fast Template. +[2018.11.29-17.16.21:767][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:767][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:767][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableTextBox'. Using FEditableTextBoxStyle defaults instead. +[2018.11.29-17.16.21:768][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableTextBox'. Using FEditableTextBoxStyle defaults instead. +[2018.11.29-17.16.21:768][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:768][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:768][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:768][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:768][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:768][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:768][166]LogUMG: Display: Widget Class MessageCenterWidget_C - Loaded Fast Template. +[2018.11.29-17.16.21:769][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:769][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:769][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:769][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:769][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:769][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:769][166]LogUMG: Display: Widget Class OptionsMenu_C - Loaded Fast Template. +[2018.11.29-17.16.21:769][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:769][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:770][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:770][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:770][166]LogUMG: Display: Widget Class News_C - Loaded Fast Template. +[2018.11.29-17.16.21:770][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:770][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:770][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:770][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:770][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:770][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:770][166]LogUMG: Display: Widget Class LegalInfo_C - Loaded Fast Template. +[2018.11.29-17.16.21:771][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:771][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:771][166]LogUMG: Display: Widget Class FullPartyBarAthena_C - Loaded Fast Template. +[2018.11.29-17.16.21:771][166]LogUMG: Display: Widget Class FullPartyMemberAthena_C - Loaded Fast Template. +[2018.11.29-17.16.21:771][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:771][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:771][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:771][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:771][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:771][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:772][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:773][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:773][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:773][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:773][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:773][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:773][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:773][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:773][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:773][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:773][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:773][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:774][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:775][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:776][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:776][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:776][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:776][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:776][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:776][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:776][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:776][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:776][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:776][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:776][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:777][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:778][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:778][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:778][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:778][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:778][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:778][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:779][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:780][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:781][166]LogUMG: Display: Widget Class Feedback_C - Loaded Fast Template. +[2018.11.29-17.16.21:781][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:782][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:783][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:783][166]LogUMG: Display: Widget Class ReportPlayer_C - Loaded Fast Template. +[2018.11.29-17.16.21:783][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:783][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogDataTable: Warning: UDataTable::FindRow : 'UFortGlobalUIContext::GetHealthyGamingData' requested row 'US' not in DataTable '/Game/UI/Foundation/Config/HealthyGamingData.HealthyGamingData'. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:784][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:785][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:786][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:786][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:786][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:786][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:786][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:786][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:786][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:786][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:786][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:786][166]LogUMG: Display: Widget Class UserActionMenu_C - Loaded Fast Template. +[2018.11.29-17.16.21:787][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:787][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:787][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:787][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:787][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:787][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:787][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:787][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:787][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:787][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:787][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:787][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:788][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:788][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:788][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:788][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.21:788][166]LogOnlineGame: Verbose: MCP-Utils: Dispatching request to https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/events/tournamentandhistory/e6f5091c3b2f4c359cf2aad75c424de0/NONE/WindowsClient +[2018.11.29-17.16.21:788][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.21:788][166]LogFort: UFortUIStateWidget_Frontend::NativeConstruct : Attempt Get McpCommonCore +[2018.11.29-17.16.21:788][166]LogFort: UFortUIStateWidget_Frontend::NativeConstruct : Get McpCommonCore SUCCEEDED +[2018.11.29-17.16.21:789][166]LogOnlineGame: Verbose: UFortMcpContext Using PartnerId +[2018.11.29-17.16.21:789][166]LogUMG: Display: Widget Class AthenaTabsScreen_C - Loaded Fast Template. +[2018.11.29-17.16.21:789][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:789][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:790][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:790][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:790][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:790][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:790][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:790][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:790][166]LogSlate: Updating window title bar state: overlay mode, drag disabled, window buttons hidden, title bar hidden +[2018.11.29-17.16.21:790][166]LogCommonUI: Pushing AthenaTabsScreen_C_2147481043 into widget stack MainContentStack +[2018.11.29-17.16.21:790][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:790][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:790][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:790][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:790][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:790][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:792][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:792][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:792][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:792][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:792][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:792][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:792][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:793][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:793][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:793][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:793][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:793][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:793][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:794][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:794][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:794][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:794][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:794][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:795][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:795][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:795][166]LogUMG: Display: Widget Class AthenaLobby_C - Loaded Fast Template. +[2018.11.29-17.16.21:796][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:796][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:802][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:803][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:804][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:804][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:804][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:804][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:804][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:804][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:804][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:804][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:804][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:804][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:804][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:804][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:804][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:804][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:805][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:805][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:805][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:805][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:805][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:805][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:805][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:805][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:805][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:805][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:805][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:805][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:805][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:805][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:806][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:806][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:806][166]LogUMG: Display: Widget Class RewardInfoSimpleWidget_C - Loaded Fast Template. +[2018.11.29-17.16.21:806][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:806][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:806][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:806][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:806][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:806][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:807][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:808][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:809][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:809][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:809][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:809][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:809][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:809][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:809][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:809][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:809][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:809][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:809][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:809][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:809][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:810][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:811][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:812][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:813][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:814][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:815][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:815][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:815][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:816][166]LogUMG: Display: Widget Class DailyQuestWidget_C - Loaded Fast Template. +[2018.11.29-17.16.21:816][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:816][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:816][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:816][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:816][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:816][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:817][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:817][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:817][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:817][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:817][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:817][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:817][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:817][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:817][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:817][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:817][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:817][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:818][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:818][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:818][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:818][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:818][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:818][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:818][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:818][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:818][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:818][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:818][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:819][166]LogHttp: VeryVerbose: 00000231969C2540: Received SSL data (5 bytes) +[2018.11.29-17.16.21:819][166]LogHttp: VeryVerbose: 00000231969C2540: Received header (17 bytes) +[2018.11.29-17.16.21:819][166]LogHttp: Verbose: 00000231969C2540: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.21:819][166]LogHttp: VeryVerbose: 00000231969C2540: Received header (37 bytes) +[2018.11.29-17.16.21:819][166]LogHttp: Verbose: 00000231969C2540: Received response header 'Date: Thu, 29 Nov 2018 17:16:21 GMT'. +[2018.11.29-17.16.21:819][166]LogHttp: VeryVerbose: 00000231969C2540: Received header (32 bytes) +[2018.11.29-17.16.21:819][166]LogHttp: Verbose: 00000231969C2540: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.21:819][166]LogHttp: VeryVerbose: 00000231969C2540: Received header (20 bytes) +[2018.11.29-17.16.21:819][166]LogHttp: Verbose: 00000231969C2540: Received response header 'Content-Length: 32'. +[2018.11.29-17.16.21:819][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:819][166]LogHttp: VeryVerbose: 00000231969C2540: Received header (24 bytes) +[2018.11.29-17.16.21:819][166]LogHttp: Verbose: 00000231969C2540: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.21:819][166]LogHttp: VeryVerbose: 00000231969C2540: Received header (50 bytes) +[2018.11.29-17.16.21:819][166]LogHttp: Verbose: 00000231969C2540: Received response header 'X-Epic-Correlation-ID: FN-iwpmwUymqEm4SIUhHBk_Cw'. +[2018.11.29-17.16.21:819][166]LogHttp: Verbose: 00000231969C2540: Received response header ''. +[2018.11.29-17.16.21:819][166]LogHttp: VeryVerbose: 00000231969C2540: Received header (2 bytes) +[2018.11.29-17.16.21:819][166]LogHttp: VeryVerbose: 00000231969C2540: Received data (32 bytes) +[2018.11.29-17.16.21:819][166]LogHttp: Verbose: 00000231969C2540: ReceiveResponseBodyCallback: 32 bytes out of 32 received. (SizeInBlocks=1, BlockSizeInBytes=32, Response->TotalBytesRead=0, Response->GetContentLength()=32, SizeToDownload=32 (<-this will get returned from the callback)) +[2018.11.29-17.16.21:819][166]LogHttp: VeryVerbose: 00000231969C2540: 'Connection #8 to host friends-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.21:819][166]LogHttp: Verbose: Request 00000231969C2540 (easy handle:00000231A166AAB0) has completed (code:0) and has been marked as such +[2018.11.29-17.16.21:819][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:819][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:819][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:819][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:819][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:819][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:820][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:820][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:820][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:820][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:820][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:820][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:820][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:820][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:820][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:820][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:820][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:820][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:821][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:821][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:821][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:821][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:821][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:821][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:822][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:822][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:822][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:822][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:822][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:822][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:823][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:823][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:823][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:823][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:823][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:823][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:823][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:823][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:823][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:823][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:823][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:824][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:824][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:824][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:824][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:824][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:824][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:824][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:825][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:825][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:825][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:825][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:825][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:825][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:825][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:825][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:825][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:825][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:825][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:825][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:826][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:826][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:826][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:826][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:826][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:826][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:826][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:826][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:826][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:826][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:827][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:827][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:827][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:827][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:827][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:827][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:827][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:827][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:828][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:829][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:830][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:831][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:831][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:831][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:831][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:831][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:831][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:831][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:831][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:831][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:831][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:831][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:832][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:832][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:832][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:832][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:832][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:832][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:832][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:832][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:832][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:832][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:833][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:833][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:833][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:833][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:833][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:833][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:833][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:833][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:833][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:833][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:834][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:834][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:834][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:834][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:834][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:835][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:835][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:835][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:835][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:835][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:835][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:835][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:836][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:836][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:836][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:836][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:836][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:836][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:836][166]LogUMG: Display: Widget Class IconTabButton_C - Loaded Fast Template. +[2018.11.29-17.16.21:837][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:837][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:837][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:837][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:837][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:837][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:837][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:837][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:837][166]LogUMG: Display: Widget Class Tooltip-Basic-S_C - Loaded Fast Template. +[2018.11.29-17.16.21:838][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:838][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:838][166]LogUMG: Display: Widget Class AthenaSeasonTab_C - Loaded Fast Template. +[2018.11.29-17.16.21:839][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:839][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:839][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:839][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:839][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:839][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:839][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:839][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:839][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:839][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:840][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:841][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:841][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:841][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:841][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:841][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:841][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:841][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:841][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:841][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:841][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:841][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:841][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:842][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:842][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:842][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:842][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:842][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:842][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:843][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:843][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:843][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:843][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:843][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:844][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:844][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:844][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:844][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:844][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:844][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:844][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:844][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:844][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:844][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:845][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:845][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:845][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:845][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.21:845][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:845][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.21:845][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:846][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:847][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:848][166]LogUMG: Display: Widget Class AthenaSeasonPageWidget_C - Loaded Fast Template. +[2018.11.29-17.16.21:848][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:849][166]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=154 BytesLeft=0 +[2018.11.29-17.16.21:849][166]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=399 BytesLeft=0 +[2018.11.29-17.16.21:849][166]LogUMG: Display: Widget Class AthenaSeasonLevelPaidRewardsWidget_C - Loaded Fast Template. +[2018.11.29-17.16.21:849][166]LogUMG: Display: Widget Class AthenaSeasonLevelFreeRewardsWidget_C - Loaded Fast Template. +[2018.11.29-17.16.21:849][166]LogUMG: Display: Widget Class AthenaSeasonLevelHeaderWidget_C - Loaded Fast Template. +[2018.11.29-17.16.21:849][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:850][166]LogUMG: Display: Widget Class AthenaSeasonReward_C - Loaded Fast Template. +[2018.11.29-17.16.21:850][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:850][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:850][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:850][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:850][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:851][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:851][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:851][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:852][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:852][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:852][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:852][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:852][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:852][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:852][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:853][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:853][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:853][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:853][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:853][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:854][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:854][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:854][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:854][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:854][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:854][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:854][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:854][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:854][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:855][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:855][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:855][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:855][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:855][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:855][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:855][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:856][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:856][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:856][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:856][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:856][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:856][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:857][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:857][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:857][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:857][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:857][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:857][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:858][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:858][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:858][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:858][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:858][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:858][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:858][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:859][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:859][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:859][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:859][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:859][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:859][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:859][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:859][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:859][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:860][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:860][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:860][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:860][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:860][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:861][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:861][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:861][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:861][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:861][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:862][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:862][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:862][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:862][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:862][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:862][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:862][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:862][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:862][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:862][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:863][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:863][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:863][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:863][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:863][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:863][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:863][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:863][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:863][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:864][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:864][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:864][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:864][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:864][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:864][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:864][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:864][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:864][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:864][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:865][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:865][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:865][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:865][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:865][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:865][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:865][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:865][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:865][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:866][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:866][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:866][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:866][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:866][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:866][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:866][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:866][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:866][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:866][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:867][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:867][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:867][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:867][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:867][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:867][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:867][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:867][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:867][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:868][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:868][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:868][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:869][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:869][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:869][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:869][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:869][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:869][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:869][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:869][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:869][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:869][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:870][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:870][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:870][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:870][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:870][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:870][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:870][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:870][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:870][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:871][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:871][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:871][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:871][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:871][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:871][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:871][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:871][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:871][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:872][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:872][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:872][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:872][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:872][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:872][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:872][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:872][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:872][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:873][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:873][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:873][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:873][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:873][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:873][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:874][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:874][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:874][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:874][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:874][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:874][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:874][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:874][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:874][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:874][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:874][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:874][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:874][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:875][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:875][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:875][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:875][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:875][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:875][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:876][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:876][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:876][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:876][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:876][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:876][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:876][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:877][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:877][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:877][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:877][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:877][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:877][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:877][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:877][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:877][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:878][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:878][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:878][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:878][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:878][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:878][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:878][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:878][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:878][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:879][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:879][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:879][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:879][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:879][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:879][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:879][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:879][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:879][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:880][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:880][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:880][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:880][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:880][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:880][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:880][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:880][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:880][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:880][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:881][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:881][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:881][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:881][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:882][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:882][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:882][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:882][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:882][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:882][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:882][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:883][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:883][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:883][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:883][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:883][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:883][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:883][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:883][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:883][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:883][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:884][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:884][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:884][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:884][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:884][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:884][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:884][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:884][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:884][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:884][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:885][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:885][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:885][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:885][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:885][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:885][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:885][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:885][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:885][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:886][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:886][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:886][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:886][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:886][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:886][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:886][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:886][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:886][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:887][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:887][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:887][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:887][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:887][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:887][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:887][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:887][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:887][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:887][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:888][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:888][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:888][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:888][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:888][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:888][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:888][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:888][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:889][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:889][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:889][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:889][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:889][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:889][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:890][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:890][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:890][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:890][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:890][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:890][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:890][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:890][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:890][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:890][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:890][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:890][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:891][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:891][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:891][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:891][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:891][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:891][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:892][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:892][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:892][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:892][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:892][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:892][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:892][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:892][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:893][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:893][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:893][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:893][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:893][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:893][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:893][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:893][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:893][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:893][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:894][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:894][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:894][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:894][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:894][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:894][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:894][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:894][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:895][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:895][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:895][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:895][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:895][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:895][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:895][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:896][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:896][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:896][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:896][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:896][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:896][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:896][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:896][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:896][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:896][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:896][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:896][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:897][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:897][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:897][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:897][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:897][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:897][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:897][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:897][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:897][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:898][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:898][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:898][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:898][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:898][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:898][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:898][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:899][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:899][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:899][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:899][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:899][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:899][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:899][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:899][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:900][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:900][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:900][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:900][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:900][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:900][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:900][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:900][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:900][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:901][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:901][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:901][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:901][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:901][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:901][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:901][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:901][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:901][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:901][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:902][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:902][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:902][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:902][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:902][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:902][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:902][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:902][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:902][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:902][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:903][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:903][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:903][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:903][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:903][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:903][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:903][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:903][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:903][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:904][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:904][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:904][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:904][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:904][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:904][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:904][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:905][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:905][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:905][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:905][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:905][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:905][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:905][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:906][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:906][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:906][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:906][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:906][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:906][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:906][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:906][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:907][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:907][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:907][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:907][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:907][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:907][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:907][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:907][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:907][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:908][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:908][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:908][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:908][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:908][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:908][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:908][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:908][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:908][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:908][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:909][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:909][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:909][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:909][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:909][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:909][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:909][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:909][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:909][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:910][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:910][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:910][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:910][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:910][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:910][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:910][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:910][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:910][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:910][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:911][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:911][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:911][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:911][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:911][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:911][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:911][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:911][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:911][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:912][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:912][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:912][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:912][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:912][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:912][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:912][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:912][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:913][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:913][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:913][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:913][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:913][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:913][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:913][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:913][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:913][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:914][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:914][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:914][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:914][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:914][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:914][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:915][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:915][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:915][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:915][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:915][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:915][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:915][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:916][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:916][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:916][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:916][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:916][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:916][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:916][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:916][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:916][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:916][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:917][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:917][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:917][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:917][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:917][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:917][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:917][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:917][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:917][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:918][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:918][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:918][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:918][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:918][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:918][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:918][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:919][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:919][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:919][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:919][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:919][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:919][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:919][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:919][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:919][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:919][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:919][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:920][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:920][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:920][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:920][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:920][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:920][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:920][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:920][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:921][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:921][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:921][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:921][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:921][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:921][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:922][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:922][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:922][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:922][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:922][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:922][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:922][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:922][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:922][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:922][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:923][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:923][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:923][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:923][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:923][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:923][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:923][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:923][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:923][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:924][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:924][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:924][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:924][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:924][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:924][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:924][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:924][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:924][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:924][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:925][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:925][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:925][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:925][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:925][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:925][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:925][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:925][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:925][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:926][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:926][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:926][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:926][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:926][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:926][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:926][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:926][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:926][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:926][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:927][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:927][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:927][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:927][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:927][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:928][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:928][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:928][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:928][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:928][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:928][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:928][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:928][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:928][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:929][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:929][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:929][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:929][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:929][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:929][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:929][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:929][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:930][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:930][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:930][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:930][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:930][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:930][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:930][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:930][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:930][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:931][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:931][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:931][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:931][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:931][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:931][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:931][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:931][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:931][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:931][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:932][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:932][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:932][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:932][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:932][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:932][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:932][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:932][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:932][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:933][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:933][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:933][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:933][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:933][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:933][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:933][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:933][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:933][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:934][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:934][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:934][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:934][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:934][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:934][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:934][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:934][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:934][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:934][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:935][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:935][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:935][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:935][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:935][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:935][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:935][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:936][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:936][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:936][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:936][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:936][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:936][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:936][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:936][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:936][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:936][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:936][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:936][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:937][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:937][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:937][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:937][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:937][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:937][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:937][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:938][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:938][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:938][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:938][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:938][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:939][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:939][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:939][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:939][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:939][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:939][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:939][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:939][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:939][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:939][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:940][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:940][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:940][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:940][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:940][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:940][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:940][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:940][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:940][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:941][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:941][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:941][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:941][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:941][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:941][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:941][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:941][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:941][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:941][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:942][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:942][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:942][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:942][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:942][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:942][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:942][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:942][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:942][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:942][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:943][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:943][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:943][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:943][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:943][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:943][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:943][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:943][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:943][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:944][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:944][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:944][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:944][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:944][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:944][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:944][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:944][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:945][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:945][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:945][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:945][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:945][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:946][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:946][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:946][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:946][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:946][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:946][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:946][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:946][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:946][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:947][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:947][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:947][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:947][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:947][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:947][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:947][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:947][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:947][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:948][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:948][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:948][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:948][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:948][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:948][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:948][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:948][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:948][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:949][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:949][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:949][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:949][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:949][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:949][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:949][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:949][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:949][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:949][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:950][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:950][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:950][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:950][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:950][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:950][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:951][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:951][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:951][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:951][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:951][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:951][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:951][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:952][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:952][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:952][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:952][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:952][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:952][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:952][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:952][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:952][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:953][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:953][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:953][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:953][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:953][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:953][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:953][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:953][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:953][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:954][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:954][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:954][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:954][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:954][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:954][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:954][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:954][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:954][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:954][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:955][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:955][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:955][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:955][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:955][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:955][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:955][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:955][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:955][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:956][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:956][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:956][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:956][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:956][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:956][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:956][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:956][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:957][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:957][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:957][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:957][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:957][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:957][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:957][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:958][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:958][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:958][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:958][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:958][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:958][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:958][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:959][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:959][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:959][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:959][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:959][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:959][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:959][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:959][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:959][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:960][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:960][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:960][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:960][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:960][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:960][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:960][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:960][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:960][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:960][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:961][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:961][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:961][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:961][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:961][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:961][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:961][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:962][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:962][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:962][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:962][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:962][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:962][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:963][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:963][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:963][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:963][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:963][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:963][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:963][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:963][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:963][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:964][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:964][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:964][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:964][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:964][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:964][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:964][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:964][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:964][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:965][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:965][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:965][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:965][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:965][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:965][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:965][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:965][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:965][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:966][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:966][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:966][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:966][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:966][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:966][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:966][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:966][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:967][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:967][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:967][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:967][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:968][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:968][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:968][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:968][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:968][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:968][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:968][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:968][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:968][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:969][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:969][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:969][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:969][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:969][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:969][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:969][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:969][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:969][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:970][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:970][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:970][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:970][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:971][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:971][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:971][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:971][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:971][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:971][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:971][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:971][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:971][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:972][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:972][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:972][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:972][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:972][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:972][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:972][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:972][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:972][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:973][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:973][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:973][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:973][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:973][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:973][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:973][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:973][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:973][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:974][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:974][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:974][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:974][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:974][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:974][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:974][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:974][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:975][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:975][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:975][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:975][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:975][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:975][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:976][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:976][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:976][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:976][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:976][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:976][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:976][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:976][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:977][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:977][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:977][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:977][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:977][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:977][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:977][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:977][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:977][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:978][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:978][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:978][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:978][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:978][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:978][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:978][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:978][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:978][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:979][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:979][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:979][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:979][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:979][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:979][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:979][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:979][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:980][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:980][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:980][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:980][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:981][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:981][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:981][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:981][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:981][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:981][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:981][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:981][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:981][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:981][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:982][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:982][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:982][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:982][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:982][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:982][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:982][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:983][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:983][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:983][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:983][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:984][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:984][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:984][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:984][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:984][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:984][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:984][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:984][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:984][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:984][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:985][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:985][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:985][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:985][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:985][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:985][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:985][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:985][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:985][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:986][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:986][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:986][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:986][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:986][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:986][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:986][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:986][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:986][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:987][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:987][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:987][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:987][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:987][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:987][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:987][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:987][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:987][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:987][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:988][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:988][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:988][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:988][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:988][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:988][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:989][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:989][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:989][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:989][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:989][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:989][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:989][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:989][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:990][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:990][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:990][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:990][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:990][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:990][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:990][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:990][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:991][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:991][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:991][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:991][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:991][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:991][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:991][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:991][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:991][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:992][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:992][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:992][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:992][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:992][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:992][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:992][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:992][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:992][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:993][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:993][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:993][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:993][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:993][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:993][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:994][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:994][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:994][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:994][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:994][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:994][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:994][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:995][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:995][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:995][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:995][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:995][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:995][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:995][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:995][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:995][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:995][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:996][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:996][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:996][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:996][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:996][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:996][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:996][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:996][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:996][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:997][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:997][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:997][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:997][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:997][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:997][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:997][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:997][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:997][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:998][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:998][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:998][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:998][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:998][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:998][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:998][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:998][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:999][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:999][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.21:999][166]LogUMG: Display: Widget Class AthenaChallengesTab_C - Loaded Fast Template. +[2018.11.29-17.16.21:999][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.21:999][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:000][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:000][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:000][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:000][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:000][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:000][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:000][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:000][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:000][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:000][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:000][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:000][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:000][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:000][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:001][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:001][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:001][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:001][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:001][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:001][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:001][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:001][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:001][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:001][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:002][166]LogUMG: Display: Widget Class ShowdownScreen_C - Loaded Fast Template. +[2018.11.29-17.16.22:002][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:002][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:003][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:003][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:003][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:003][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:003][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:003][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:004][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:005][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:006][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:006][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:006][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:006][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:006][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:006][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:006][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:006][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:006][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:006][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:006][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:006][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:006][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:006][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:007][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:007][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:007][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:007][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:007][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:007][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:007][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:007][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:008][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:008][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:008][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:008][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:008][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:008][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:008][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:008][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:008][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:008][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:008][166]LogUMG: Display: Widget Class AthenaLockerTab_C - Loaded Fast Template. +[2018.11.29-17.16.22:009][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:009][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:016][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:016][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:016][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:016][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:016][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:017][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:018][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:019][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:019][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:019][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:019][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:019][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:019][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:019][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:019][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:020][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:020][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:020][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:020][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:020][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:020][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:020][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:020][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:020][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:020][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:020][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:021][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:021][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:021][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:021][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:021][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:021][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:021][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:021][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:022][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:022][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:022][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:022][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:022][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:022][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:023][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:023][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:023][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:023][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:023][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:023][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:023][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:023][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:024][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:024][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:024][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:024][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:024][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:024][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:024][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:025][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:025][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:025][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:025][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:025][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:025][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:025][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:025][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:025][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:026][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:026][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:026][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:026][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:026][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:026][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:026][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:026][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:026][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:026][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:027][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:027][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:027][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:027][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:027][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:027][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:027][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:027][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:028][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:028][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:028][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:028][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:028][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:028][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:028][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:028][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:029][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:029][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:029][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:029][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:029][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:029][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:029][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:029][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:030][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:030][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:030][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:030][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:030][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:030][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:030][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:031][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:031][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:031][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:031][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:031][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:031][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:031][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:032][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:032][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:032][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:032][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:032][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:032][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:033][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:033][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:033][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:033][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:033][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:033][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:034][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:034][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:034][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:034][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:034][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:034][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:034][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:034][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:035][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:035][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:035][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:035][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:035][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:035][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:035][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:035][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:035][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:035][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:035][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:036][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:036][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:036][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:036][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:036][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:036][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:036][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:036][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:036][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:036][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:036][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:036][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:037][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:037][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:037][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:037][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:037][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:037][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:037][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:037][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:037][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:037][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:037][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:038][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:038][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:038][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:038][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:038][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:038][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:038][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:038][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:038][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:038][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:038][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:038][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:039][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:039][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:039][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:039][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:039][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:039][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:039][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:039][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:039][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:039][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:040][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:040][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:040][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:040][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:040][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:040][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:040][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:040][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:040][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:040][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:040][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:040][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:041][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:041][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:041][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:041][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:041][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:041][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:041][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:041][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:041][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:041][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:041][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:042][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:042][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:042][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:042][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:042][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:042][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:042][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:042][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:042][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:042][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:042][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:042][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:043][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:043][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:043][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:043][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:043][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:043][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:043][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:043][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:044][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:044][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:044][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:044][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:044][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:047][166]LogUMG: Display: Widget Class AthenaItemCustomizationSelector_C - Loaded Fast Template. +[2018.11.29-17.16.22:047][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:047][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:048][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:048][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:048][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:048][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:049][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:049][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:049][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:049][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:049][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:049][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:049][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:050][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:050][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:050][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:050][166]LogUMG: Display: Widget Class AthenaDirectAcquisitionScreen_C - Loaded Fast Template. +[2018.11.29-17.16.22:051][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:051][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:051][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:051][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:051][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:051][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:051][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:052][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:052][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:052][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:052][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:052][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:052][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:052][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:052][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:052][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:052][166]LogFort: UFortDirectAcquisitionWidgetBase::NativeConstruct : Attempt Get McpCommonCore +[2018.11.29-17.16.22:052][166]LogFort: UFortDirectAcquisitionWidgetBase::NativeConstruct : Get McpCommonCore SUCCEEDED +[2018.11.29-17.16.22:053][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:053][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:053][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:053][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:053][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:053][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:053][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:053][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:054][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:054][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:054][166]LogUMG: Display: Widget Class CareerScreen_C - Loaded Fast Template. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:055][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:056][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:057][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:057][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:057][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:057][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:057][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:057][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:057][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:057][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:057][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:057][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:058][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:058][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:058][166]LogUMG: Display: Widget Class StoreMain_Root_C - Loaded Fast Template. +[2018.11.29-17.16.22:058][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:058][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:058][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:058][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:058][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:059][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:059][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:059][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:059][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:059][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:059][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:059][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:059][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:059][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:059][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:059][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:059][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:059][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:060][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:060][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:060][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:060][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:060][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:060][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:061][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:061][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:061][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:061][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:061][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:061][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:061][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:062][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:062][166]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: InternalPushActivatablePanel : Adding push for new activatable panel AthenaTabsScreen_C_2147481043: +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: Input suspension: Started +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: Begin StartNextOperation +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: StartNextOperation: activatable panel pushed on stack for panel: AthenaTabsScreen_C_2147481043 +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: StartNextOperation: begin intro for panel: AthenaTabsScreen_C_2147481043 +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: OnPrePanelActivated: panel activated complete: AthenaTabsScreen_C_2147481043 +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: InternalPushActivatablePanel : Adding outro op for top activatable panel +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: InternalPushActivatablePanel : Adding push for new activatable panel AthenaLobby_C_2147481034: +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: Begin StartNextOperation +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: StartNextOperation: deactivate for panel: AthenaTabsScreen_C_2147481043 +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: OnPostPanelDeactivatedForPush: deactivated panel: AthenaTabsScreen_C_2147481043 +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: Begin StartNextOperation +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: StartNextOperation: activatable panel pushed on stack for panel: AthenaLobby_C_2147481034 +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: StartNextOperation: begin intro for panel: AthenaLobby_C_2147481034 +[2018.11.29-17.16.22:062][166]LogCommonInput: Verbose: OnPrePanelActivated: panel activated complete: AthenaLobby_C_2147481034 +[2018.11.29-17.16.22:062][166]LogFort: UFortFrontEndContext::ShouldShowBeginningOfSeasonDialog : Called for 'BlockMOTDForBattlePassUpsell' +[2018.11.29-17.16.22:062][166]LogFort: UFortFrontEndContext::ShouldShowBeginningOfSeasonDialog : Player does not own battle bass +[2018.11.29-17.16.22:062][166]LogFort: UFortFrontEndContext::ShouldShowBeginningOfSeasonDialog : retrieved current season +[2018.11.29-17.16.22:063][166]LogFort: UFortFrontEndContext::ShouldShowBeginningOfSeasonDialog : retrieved user settings +[2018.11.29-17.16.22:063][166]LogFort: UFortFrontEndContext::ShouldShowBeginningOfSeasonDialog : Current Season: 7, User Settings Season: 0 +[2018.11.29-17.16.22:063][166]LogFort: UFortFrontEndContext::ShouldShowBeginningOfSeasonDialog : return true +[2018.11.29-17.16.22:064][166]LogProfileSys: MCP-Profile: Dispatching request to https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/ClientQuestLogin?profileId=athena&rvn=236 +[2018.11.29-17.16.22:064][166]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:065][166]LogProfileSys: MCP-Profile: Command ClientQuestLogin queued to send +[2018.11.29-17.16.22:065][166]LogCommonInput: Verbose: Begin StartNextOperation +[2018.11.29-17.16.22:065][166]LogCommonInput: Verbose: StartNextOperation: Finished, Clearing pending ops +[2018.11.29-17.16.22:065][166]LogCommonUI: CommonWidgetStack: MainContentStack + AthenaTabsScreen_C_2147481043 +ActiveWidgetIndex: 0 +[2018.11.29-17.16.22:065][166]LogSlate: Updating window title bar state: overlay mode, drag disabled, window buttons hidden, title bar hidden +[2018.11.29-17.16.22:066][166]LogGarbage: GC purged 14 objects (505018 -> 505004) +[2018.11.29-17.16.22:071][166]LogSlate: Took 0.000280 seconds to synchronously load lazily loaded font '../../../FortniteGame/Content/UI/Foundation/Fonts/burbanksmall-bold.ufont' (82K) +[2018.11.29-17.16.22:075][166]LogSlate: Took 0.000248 seconds to synchronously load lazily loaded font '../../../FortniteGame/Content/UI/Foundation/Fonts/burbanksmall-black.ufont' (80K) +[2018.11.29-17.16.22:086][167]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:086][167]LogHttp: Verbose: 00000231969C3440: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/storefront/v2/catalog?rvn=204' +[2018.11.29-17.16.22:086][167]LogHttp: Verbose: 00000231969C3440: Verb='GET' +[2018.11.29-17.16.22:086][167]LogHttp: Verbose: 00000231969C3440: Custom headers are present +[2018.11.29-17.16.22:086][167]LogHttp: Verbose: 00000231969C3440: Payload size=0 +[2018.11.29-17.16.22:086][167]LogHttp: Verbose: 00000231969C3440: Adding header 'X-EpicGames-Language: en' +[2018.11.29-17.16.22:086][167]LogHttp: Verbose: 00000231969C3440: Adding header 'X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":239}]' +[2018.11.29-17.16.22:086][167]LogHttp: Verbose: 00000231969C3440: Adding header 'X-Epic-Correlation-ID: FN-DiQpi4H62EOrc-duD7E2Rw' +[2018.11.29-17.16.22:086][167]LogHttp: Verbose: 00000231969C3440: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.22:086][167]LogHttp: Verbose: 00000231969C3440: Adding header 'Content-Length: 0' +[2018.11.29-17.16.22:086][167]LogHttp: Verbose: 00000231969C3440: Adding header 'Expect: ' +[2018.11.29-17.16.22:087][167]LogHttp: 00000231969C3440: Starting GET request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/storefront/v2/catalog?rvn=204' +[2018.11.29-17.16.22:087][167]LogHttp: Verbose: 00000231969C3440: request (easy handle:00000231A1665560) has been added to threaded queue for processing +[2018.11.29-17.16.22:087][167]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: RECV: +[2018.11.29-17.16.22:087][167]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: Reopened stream successfully. +[2018.11.29-17.16.22:087][167]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: RECV: zlib +[2018.11.29-17.16.22:087][167]LogXmpp: VeryVerbose: libstrophe[71688] conn debug: SENT: V2:FortniteDevLatest:WIN::02893B0E4C31D665986F7F914616016E +[2018.11.29-17.16.22:087][167]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:087][167]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:087][167]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:087][167]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:087][167]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:087][167]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:087][167]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:087][167]LogHttp: 00000231969C2540: request has been successfully processed. URL: https://friends-public-service-gamedev.ol.epicgames.net/friends/api/v1/e6f5091c3b2f4c359cf2aad75c424de0/settings, HTTP code: 200, content length: 32, actual payload size: 32 +[2018.11.29-17.16.22:087][167]LogHttp: Verbose: 00000231969C2540 Response Header Date: Thu, 29 Nov 2018 17:16:21 GMT +[2018.11.29-17.16.22:087][167]LogHttp: Verbose: 00000231969C2540 Response Header Content-Type: application/json +[2018.11.29-17.16.22:087][167]LogHttp: Verbose: 00000231969C2540 Response Header Content-Length: 32 +[2018.11.29-17.16.22:087][167]LogHttp: Verbose: 00000231969C2540 Response Header Connection: keep-alive +[2018.11.29-17.16.22:087][167]LogHttp: Verbose: 00000231969C2540 Response Header X-Epic-Correlation-ID: FN-iwpmwUymqEm4SIUhHBk_Cw +[2018.11.29-17.16.22:087][167]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:094][167]LogHttp: Verbose: 00000231969C3440: request (easy handle:00000231A1665560) has started threaded processing +[2018.11.29-17.16.22:094][167]LogHttp: VeryVerbose: 00000231969C3440: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.22:094][167]LogHttp: VeryVerbose: 00000231969C3440: 'Re-using existing connection! (#3) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.22:094][167]LogHttp: VeryVerbose: 00000231969C3440: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#3)' +[2018.11.29-17.16.22:094][167]LogHttp: VeryVerbose: 00000231969C3440: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:094][167]LogHttp: VeryVerbose: 00000231969C3440: Sent header (1023 bytes) - GET /fortnite/api/storefront/v2/catalog?rvn=204 HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-EpicGames-Language: enX-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":239}]X-Epic-Correlation-ID: FN-DiQpi4H62EOrc-duD7E2RwUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F +[2018.11.29-17.16.22:094][167]LogUMG: Display: Widget Class InputReflectorButton_C - Loaded Fast Template. +[2018.11.29-17.16.22:094][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:094][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:094][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:094][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:094][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:094][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:095][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:095][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:095][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:095][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:095][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:095][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:095][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:095][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:095][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:096][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:096][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:096][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:096][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:096][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:096][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:096][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:096][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:096][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:096][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:096][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.22:096][167]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.22:097][167]LogFortLoadingScreen: Garbage Collecting before dropping load screen +[2018.11.29-17.16.22:097][167]LogCore: Display: Setting hang detector multiplier to 1.0000s. New hang duration: 30.0000s. New present duration: 0.0000s. +[2018.11.29-17.16.22:097][167]LogFortLoadingScreen: Hiding loading screen when 'IsShowingInitialLoadingScreen()' is false. +[2018.11.29-17.16.22:097][167]LogFortLoadingScreen: PC: AFortPlayerController is not in Zone and always returns 'hide loading screen' +[2018.11.29-17.16.22:097][167]LogFort: *!* FortInteractabilityTracker::ReportPhasesToAnalytics - Dumping 5 Phases to Analytics, InteractiveTime: 4.93 NonInteractiveTime: 37.70 +[2018.11.29-17.16.22:097][167]LogFort: *!* UFortInteractabilityTracker::ReportPhasesToAnalytics - Phase: InitialLoad (1:0) - 36.07 +[2018.11.29-17.16.22:097][167]LogFort: *!* UFortInteractabilityTracker::ReportPhasesToAnalytics - Phase: Login (1:0) - 2.02 +[2018.11.29-17.16.22:097][167]LogFort: *!* UFortInteractabilityTracker::ReportPhasesToAnalytics - Phase: AthenaGameplay (1:0) - 2.91 +[2018.11.29-17.16.22:097][167]LogFort: *!* UFortInteractabilityTracker::ReportPhasesToAnalytics - Phase: LoginToGameModeTransition (1:0) - 1.62 +[2018.11.29-17.16.22:097][167]LogFort: *!* UFortInteractabilityTracker::ReportPhasesToAnalytics - Phase: AthenaGameplay (0:1) - 0.00 +[2018.11.29-17.16.22:097][167]LogFort: UFortUIStateWidget_Frontend::CheckForGifts : Called +[2018.11.29-17.16.22:097][167]LogFort: UFortUIStateWidget_Frontend::CheckForGifts : Gifting flow was off, turning it on +[2018.11.29-17.16.22:097][167]LogFort: UFortUIStateWidget_Frontend::CheckForGifts : No message, checking for gift box +[2018.11.29-17.16.22:097][167]LogFort: UFortUIStateWidget_Frontend::CheckForGifts : No message or giftbox available, abandoning flow +[2018.11.29-17.16.22:099][167]LogGarbage: Collecting garbage while async loading (GCheckForIllegalMarkPendingKill = 1) +[2018.11.29-17.16.22:107][167]LogGarbage: 7.140761 ms for Verify GC Assumptions +[2018.11.29-17.16.22:134][167]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::SendFromQueue: Wrote 170 bytes, 0 bytes remaining in this packet +[2018.11.29-17.16.22:134][167]LogGarbage: 27.103738 ms for GC +[2018.11.29-17.16.22:134][167]LogGarbage: 0.000906 ms for dissolving GC clusters +[2018.11.29-17.16.22:135][167]LogGarbage: 0.406336 ms for Gather Unreachable Objects (942 objects collected including 0 cluster objects from 0 clusters) +[2018.11.29-17.16.22:136][167]LogGarbage: 0.977802 ms for unhashing unreachable objects. Items 942 (942/942) +[2018.11.29-17.16.22:142][167]LogGarbage: GC purged 942 objects (528196 -> 527254) +[2018.11.29-17.16.22:174][167]LogUObjectHash: Compacting FUObjectHashTables data took 32.38ms +[2018.11.29-17.16.22:184][168]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:184][168]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:184][168]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:184][168]LogHttp: Verbose: 00000231AE14E0C0: URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/public/account?accountId=6c9320e13012459c912b7f93b1b65bdf' +[2018.11.29-17.16.22:184][168]LogHttp: Verbose: 00000231AE14E0C0: Verb='GET' +[2018.11.29-17.16.22:184][168]LogHttp: Verbose: 00000231AE14E0C0: Custom headers are present +[2018.11.29-17.16.22:184][168]LogHttp: Verbose: 00000231AE14E0C0: Payload size=0 +[2018.11.29-17.16.22:184][168]LogHttp: Verbose: 00000231AE14E0C0: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.22:184][168]LogHttp: Verbose: 00000231AE14E0C0: Adding header 'X-Epic-Correlation-ID: FN-P9nfctKxi0uoaQ2uMHwA_g' +[2018.11.29-17.16.22:184][168]LogHttp: Verbose: 00000231AE14E0C0: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.22:184][168]LogHttp: Verbose: 00000231AE14E0C0: Adding header 'Content-Length: 0' +[2018.11.29-17.16.22:184][168]LogHttp: Verbose: 00000231AE14E0C0: Adding header 'Expect: ' +[2018.11.29-17.16.22:184][168]LogHttp: 00000231AE14E0C0: Starting GET request to URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/public/account?accountId=6c9320e13012459c912b7f93b1b65bdf' +[2018.11.29-17.16.22:184][168]LogHttp: Verbose: 00000231AE14E0C0: request (easy handle:0000023195CD5560) has been added to threaded queue for processing +[2018.11.29-17.16.22:189][168]LogHttp: Verbose: 00000231AE14E0C0: request (easy handle:0000023195CD5560) has started threaded processing +[2018.11.29-17.16.22:189][168]LogHttp: VeryVerbose: 00000231AE14E0C0: 'Hostname account-public-service-gamedev.ol.epicgames.net was found in DNS cache' +[2018.11.29-17.16.22:189][168]LogHttp: VeryVerbose: 00000231AE14E0C0: ' Trying 10.40.238.51...' +[2018.11.29-17.16.22:189][168]LogHttp: VeryVerbose: 00000231AE14E0C0: 'TCP_NODELAY set' +[2018.11.29-17.16.22:189][168]LogCommonInput: Verbose: Input suspension: Stopped +[2018.11.29-17.16.22:195][169]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:195][169]LogHttp: Verbose: 00000231EBED2A40: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/events/tournamentandhistory/e6f5091c3b2f4c359cf2aad75c424de0/NONE/WindowsClient' +[2018.11.29-17.16.22:195][169]LogHttp: Verbose: 00000231EBED2A40: Verb='GET' +[2018.11.29-17.16.22:195][169]LogHttp: Verbose: 00000231EBED2A40: Custom headers are present +[2018.11.29-17.16.22:195][169]LogHttp: Verbose: 00000231EBED2A40: Payload size=0 +[2018.11.29-17.16.22:195][169]LogHttp: Verbose: 00000231EBED2A40: Adding header 'X-Epic-Correlation-ID: FORT-D43D405A4718CCA5597C849E416C7AAE' +[2018.11.29-17.16.22:195][169]LogHttp: Verbose: 00000231EBED2A40: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.22:195][169]LogHttp: Verbose: 00000231EBED2A40: Adding header 'Content-Length: 0' +[2018.11.29-17.16.22:195][169]LogHttp: Verbose: 00000231EBED2A40: Adding header 'Expect: ' +[2018.11.29-17.16.22:195][169]LogHttp: 00000231EBED2A40: Starting GET request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/events/tournamentandhistory/e6f5091c3b2f4c359cf2aad75c424de0/NONE/WindowsClient' +[2018.11.29-17.16.22:195][169]LogHttp: Verbose: 00000231EBED2A40: request (easy handle:00000231A22A5560) has been added to threaded queue for processing +[2018.11.29-17.16.22:207][170]LogHttp: Verbose: 00000231EBED2A40: request (easy handle:00000231A22A5560) has started threaded processing +[2018.11.29-17.16.22:208][170]LogHttp: VeryVerbose: 00000231EBED2A40: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.22:208][170]LogHttp: VeryVerbose: 00000231EBED2A40: 'Re-using existing connection! (#7) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.22:208][170]LogHttp: VeryVerbose: 00000231EBED2A40: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#7)' +[2018.11.29-17.16.22:208][170]LogHttp: VeryVerbose: 00000231EBED2A40: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:208][170]LogHttp: VeryVerbose: 00000231EBED2A40: Sent header (1023 bytes) - GET /fortnite/api/game/v2/events/tournamentandhistory/e6f5091c3b2f4c359cf2aad75c424de0/NONE/WindowsClient HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FORT-D43D405A4718CCA5597C849E416C7AAEUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydk +[2018.11.29-17.16.22:219][170]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:219][170]LogHttp: Verbose: 00000231AA9C8440: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/ClientQuestLogin?profileId=athena&rvn=236' +[2018.11.29-17.16.22:219][170]LogHttp: Verbose: 00000231AA9C8440: Verb='POST' +[2018.11.29-17.16.22:219][170]LogHttp: Verbose: 00000231AA9C8440: Custom headers are present +[2018.11.29-17.16.22:219][170]LogHttp: Verbose: 00000231AA9C8440: Payload size=4 +[2018.11.29-17.16.22:220][170]LogHttp: Verbose: 00000231AA9C8440: Adding header 'Accept: */*' +[2018.11.29-17.16.22:220][170]LogHttp: Verbose: 00000231AA9C8440: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.22:220][170]LogHttp: Verbose: 00000231AA9C8440: Adding header 'X-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}' +[2018.11.29-17.16.22:220][170]LogHttp: Verbose: 00000231AA9C8440: Adding header 'X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119' +[2018.11.29-17.16.22:220][170]LogHttp: Verbose: 00000231AA9C8440: Adding header 'X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":239}]' +[2018.11.29-17.16.22:220][170]LogHttp: Verbose: 00000231AA9C8440: Adding header 'X-Epic-Correlation-ID: FN-FNBqcgweqUiIfATdP4Mo_w' +[2018.11.29-17.16.22:220][170]LogHttp: Verbose: 00000231AA9C8440: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.22:220][170]LogHttp: Verbose: 00000231AA9C8440: Adding header 'Content-Length: 4' +[2018.11.29-17.16.22:220][170]LogHttp: Verbose: 00000231AA9C8440: Adding header 'Expect: ' +[2018.11.29-17.16.22:220][170]LogHttp: 00000231AA9C8440: Starting POST request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/ClientQuestLogin?profileId=athena&rvn=236' +[2018.11.29-17.16.22:220][170]LogHttp: Verbose: 00000231AA9C8440: request (easy handle:00000231A48F0010) has been added to threaded queue for processing +[2018.11.29-17.16.22:225][171]LogHttp: Verbose: 00000231AA9C8440: request (easy handle:00000231A48F0010) has started threaded processing +[2018.11.29-17.16.22:225][171]LogHttp: VeryVerbose: 00000231AA9C8440: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.22:225][171]LogHttp: VeryVerbose: 00000231AA9C8440: 'Hostname fortnite-public-service-latest-gamedev.ol.epicgames.net was found in DNS cache' +[2018.11.29-17.16.22:225][171]LogHttp: VeryVerbose: 00000231AA9C8440: ' Trying 10.40.132.204...' +[2018.11.29-17.16.22:225][171]LogHttp: VeryVerbose: 00000231AA9C8440: 'TCP_NODELAY set' +[2018.11.29-17.16.22:242][171]LogHttp: VeryVerbose: 00000231969C3440: Received SSL data (5 bytes) +[2018.11.29-17.16.22:242][171]LogHttp: VeryVerbose: 00000231969C3440: Received header (17 bytes) +[2018.11.29-17.16.22:242][171]LogHttp: Verbose: 00000231969C3440: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.22:242][171]LogHttp: VeryVerbose: 00000231969C3440: Received header (32 bytes) +[2018.11.29-17.16.22:242][171]LogHttp: Verbose: 00000231969C3440: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.22:242][171]LogHttp: VeryVerbose: 00000231969C3440: Received header (37 bytes) +[2018.11.29-17.16.22:242][171]LogHttp: Verbose: 00000231969C3440: Received response header 'Date: Thu, 29 Nov 2018 17:16:22 GMT'. +[2018.11.29-17.16.22:242][171]LogHttp: VeryVerbose: 00000231969C3440: Received header (67 bytes) +[2018.11.29-17.16.22:242][171]LogHttp: Verbose: 00000231969C3440: Received response header 'ETag: "DA12F7F6417D8A510A891FA32BA3297B|2018-11-29T00:00:00.000Z"'. +[2018.11.29-17.16.22:242][171]LogHttp: VeryVerbose: 00000231969C3440: Received header (31 bytes) +[2018.11.29-17.16.22:242][171]LogHttp: Verbose: 00000231969C3440: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.22:242][171]LogHttp: VeryVerbose: 00000231969C3440: Received header (50 bytes) +[2018.11.29-17.16.22:242][171]LogHttp: Verbose: 00000231969C3440: Received response header 'X-Epic-Correlation-ID: FN-DiQpi4H62EOrc-duD7E2Rw'. +[2018.11.29-17.16.22:242][171]LogHttp: VeryVerbose: 00000231969C3440: Received header (52 bytes) +[2018.11.29-17.16.22:242][171]LogHttp: Verbose: 00000231969C3440: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.22:242][171]LogHttp: VeryVerbose: 00000231969C3440: Received header (75 bytes) +[2018.11.29-17.16.22:242][171]LogHttp: Verbose: 00000231969C3440: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.22:242][171]LogHttp: VeryVerbose: 00000231969C3440: Received header (28 bytes) +[2018.11.29-17.16.22:242][171]LogHttp: Verbose: 00000231969C3440: Received response header 'transfer-encoding: chunked'. +[2018.11.29-17.16.22:242][171]LogHttp: VeryVerbose: 00000231969C3440: Received header (24 bytes) +[2018.11.29-17.16.22:242][171]LogHttp: Verbose: 00000231969C3440: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.22:242][171]LogHttp: Verbose: 00000231969C3440: Received response header ''. +[2018.11.29-17.16.22:242][171]LogHttp: VeryVerbose: 00000231969C3440: Received header (2 bytes) +[2018.11.29-17.16.22:242][171]LogHttp: VeryVerbose: 00000231969C3440: Received data (14091 bytes) +[2018.11.29-17.16.22:243][171]LogHttp: Verbose: 00000231969C3440: ReceiveResponseBodyCallback: 14083 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=14083, Response->TotalBytesRead=0, Response->GetContentLength()=0, SizeToDownload=14083 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:246][171]LogHttp: VeryVerbose: 00000231969C3440: Received SSL data (5 bytes) +[2018.11.29-17.16.22:246][171]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:246][171]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:246][171]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:246][171]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:246][171]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:246][171]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:246][171]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:246][171]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:246][171]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:246][171]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:247][171]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:262][172]LogHttp: VeryVerbose: 00000231AE14E0C0: 'Connected to account-public-service-gamedev.ol.epicgames.net (10.40.238.51) port 443 (#10)' +[2018.11.29-17.16.22:262][172]LogHttp: VeryVerbose: 00000231AA9C8440: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#11)' +[2018.11.29-17.16.22:268][172]LogHttp: VeryVerbose: 00000231AE14E0C0: 'ALPN, offering http/1.1' +[2018.11.29-17.16.22:268][172]LogHttp: VeryVerbose: 00000231AE14E0C0: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.22:270][172]LogHttp: VeryVerbose: 00000231AE14E0C0: 'SSL re-using session ID' +[2018.11.29-17.16.22:270][172]LogHttp: VeryVerbose: 00000231AE14E0C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:270][172]LogHttp: VeryVerbose: 00000231AE14E0C0: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.22:270][172]LogHttp: VeryVerbose: 00000231AE14E0C0: Sent SSL data (512 bytes) +[2018.11.29-17.16.22:270][172]LogHttp: VeryVerbose: 00000231AA9C8440: 'ALPN, offering http/1.1' +[2018.11.29-17.16.22:270][172]LogHttp: VeryVerbose: 00000231AA9C8440: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.22:273][172]LogHttp: VeryVerbose: 00000231AA9C8440: 'SSL re-using session ID' +[2018.11.29-17.16.22:273][172]LogHttp: VeryVerbose: 00000231AA9C8440: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:273][172]LogHttp: VeryVerbose: 00000231AA9C8440: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.22:273][172]LogHttp: VeryVerbose: 00000231AA9C8440: Sent SSL data (512 bytes) +[2018.11.29-17.16.22:282][173]LogHttp: VeryVerbose: 00000231969C3440: Received data (16384 bytes) +[2018.11.29-17.16.22:282][173]LogHttp: Verbose: 00000231969C3440: ReceiveResponseBodyCallback: 30461 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=16378, Response->TotalBytesRead=14083, Response->GetContentLength()=0, SizeToDownload=16378 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:287][173]LogHttp: VeryVerbose: 00000231969C3440: Received SSL data (5 bytes) +[2018.11.29-17.16.22:287][173]LogHttp: VeryVerbose: 00000231969C3440: Received data (12568 bytes) +[2018.11.29-17.16.22:287][173]LogHttp: Verbose: 00000231969C3440: ReceiveResponseBodyCallback: 43027 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=12566, Response->TotalBytesRead=30461, Response->GetContentLength()=0, SizeToDownload=12566 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:292][173]LogHttp: VeryVerbose: 00000231969C3440: Received SSL data (5 bytes) +[2018.11.29-17.16.22:292][173]LogHttp: VeryVerbose: 00000231969C3440: Received data (3816 bytes) +[2018.11.29-17.16.22:292][173]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=365 BytesLeft=0 +[2018.11.29-17.16.22:292][173]LogHttp: Verbose: 00000231969C3440: ReceiveResponseBodyCallback: 46837 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=3810, Response->TotalBytesRead=43027, Response->GetContentLength()=0, SizeToDownload=3810 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:292][173]LogHttp: VeryVerbose: 00000231EBED2A40: Received SSL data (5 bytes) +[2018.11.29-17.16.22:292][173]LogHttp: VeryVerbose: 00000231EBED2A40: Received header (17 bytes) +[2018.11.29-17.16.22:292][173]LogHttp: Verbose: 00000231EBED2A40: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.22:292][173]LogHttp: VeryVerbose: 00000231EBED2A40: Received header (32 bytes) +[2018.11.29-17.16.22:292][173]LogHttp: Verbose: 00000231EBED2A40: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.22:292][173]LogHttp: VeryVerbose: 00000231EBED2A40: Received header (37 bytes) +[2018.11.29-17.16.22:292][173]LogHttp: Verbose: 00000231EBED2A40: Received response header 'Date: Thu, 29 Nov 2018 17:16:22 GMT'. +[2018.11.29-17.16.22:292][173]LogHttp: VeryVerbose: 00000231EBED2A40: Received header (31 bytes) +[2018.11.29-17.16.22:292][173]LogHttp: Verbose: 00000231EBED2A40: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.22:292][173]LogHttp: VeryVerbose: 00000231EBED2A40: Received header (62 bytes) +[2018.11.29-17.16.22:292][173]LogHttp: Verbose: 00000231EBED2A40: Received response header 'X-Epic-Correlation-ID: FORT-D43D405A4718CCA5597C849E416C7AAE'. +[2018.11.29-17.16.22:292][173]LogHttp: VeryVerbose: 00000231EBED2A40: Received header (52 bytes) +[2018.11.29-17.16.22:292][173]LogHttp: Verbose: 00000231EBED2A40: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.22:292][173]LogHttp: VeryVerbose: 00000231EBED2A40: Received header (75 bytes) +[2018.11.29-17.16.22:292][173]LogHttp: Verbose: 00000231EBED2A40: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.22:292][173]LogHttp: VeryVerbose: 00000231EBED2A40: Received header (20 bytes) +[2018.11.29-17.16.22:293][173]LogHttp: Verbose: 00000231EBED2A40: Received response header 'Content-Length: 49'. +[2018.11.29-17.16.22:293][173]LogHttp: VeryVerbose: 00000231EBED2A40: Received header (24 bytes) +[2018.11.29-17.16.22:293][173]LogHttp: Verbose: 00000231EBED2A40: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.22:293][173]LogHttp: Verbose: 00000231EBED2A40: Received response header ''. +[2018.11.29-17.16.22:293][173]LogHttp: VeryVerbose: 00000231EBED2A40: Received header (2 bytes) +[2018.11.29-17.16.22:293][173]LogHttp: VeryVerbose: 00000231EBED2A40: Received data (49 bytes) +[2018.11.29-17.16.22:293][173]LogHttp: Verbose: 00000231EBED2A40: ReceiveResponseBodyCallback: 49 bytes out of 49 received. (SizeInBlocks=1, BlockSizeInBytes=49, Response->TotalBytesRead=0, Response->GetContentLength()=49, SizeToDownload=49 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:293][173]LogHttp: VeryVerbose: 00000231EBED2A40: 'Connection #7 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.22:293][173]LogHttp: Verbose: Request 00000231EBED2A40 (easy handle:00000231A22A5560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.22:297][173]LogHttp: VeryVerbose: 00000231969C3440: Received SSL data (5 bytes) +[2018.11.29-17.16.22:297][173]LogHttp: VeryVerbose: 00000231969C3440: Received data (16384 bytes) +[2018.11.29-17.16.22:297][173]LogHttp: Verbose: 00000231969C3440: ReceiveResponseBodyCallback: 63221 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=16384, Response->TotalBytesRead=46837, Response->GetContentLength()=0, SizeToDownload=16384 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:302][173]LogHttp: VeryVerbose: 00000231969C3440: Received SSL data (5 bytes) +[2018.11.29-17.16.22:302][173]LogHttp: VeryVerbose: 00000231969C3440: Received data (16384 bytes) +[2018.11.29-17.16.22:302][173]LogHttp: Verbose: 00000231969C3440: ReceiveResponseBodyCallback: 73427 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=10206, Response->TotalBytesRead=63221, Response->GetContentLength()=0, SizeToDownload=10206 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:302][173]LogHttp: Verbose: 00000231969C3440: ReceiveResponseBodyCallback: 79597 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=6170, Response->TotalBytesRead=73427, Response->GetContentLength()=0, SizeToDownload=6170 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:302][173]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: RECV: e6f5091c3b2f4c359cf2aad75c424de0@gamedev.ol.epicgames.net/V2:FortniteDevLatest:WIN::02893B0E4C31D665986F7F914616016E +[2018.11.29-17.16.22:302][173]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: Bind successful. +[2018.11.29-17.16.22:302][173]LogXmpp: VeryVerbose: libstrophe[71688] conn debug: SENT: +[2018.11.29-17.16.22:302][173]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:302][173]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:302][173]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:302][173]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:302][173]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:302][173]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:302][173]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:302][173]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:302][173]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:302][173]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:302][173]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:302][173]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:302][173]LogHttp: 00000231EBED2A40: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/events/tournamentandhistory/e6f5091c3b2f4c359cf2aad75c424de0/NONE/WindowsClient, HTTP code: 200, content length: 49, actual payload size: 49 +[2018.11.29-17.16.22:302][173]LogHttp: Verbose: 00000231EBED2A40 Response Header Content-Type: application/json +[2018.11.29-17.16.22:302][173]LogHttp: Verbose: 00000231EBED2A40 Response Header Date: Thu, 29 Nov 2018 17:16:22 GMT +[2018.11.29-17.16.22:302][173]LogHttp: Verbose: 00000231EBED2A40 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.22:302][173]LogHttp: Verbose: 00000231EBED2A40 Response Header X-Epic-Correlation-ID: FORT-D43D405A4718CCA5597C849E416C7AAE +[2018.11.29-17.16.22:302][173]LogHttp: Verbose: 00000231EBED2A40 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.22:302][173]LogHttp: Verbose: 00000231EBED2A40 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.22:303][173]LogHttp: Verbose: 00000231EBED2A40 Response Header Content-Length: 49 +[2018.11.29-17.16.22:303][173]LogHttp: Verbose: 00000231EBED2A40 Response Header Connection: keep-alive +[2018.11.29-17.16.22:303][173]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:309][174]LogHttp: VeryVerbose: 00000231969C3440: Received SSL data (5 bytes) +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231969C3440: Received data (16384 bytes) +[2018.11.29-17.16.22:312][174]LogHttp: Verbose: 00000231969C3440: ReceiveResponseBodyCallback: 95981 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=16384, Response->TotalBytesRead=79597, Response->GetContentLength()=0, SizeToDownload=16384 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: Received SSL data (5 bytes) +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: Received SSL data (96 bytes) +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: Received SSL data (5 bytes) +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: Received SSL data (1 bytes) +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: Received SSL data (5 bytes) +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: Received SSL data (16 bytes) +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: Sent SSL data (1 bytes) +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: Sent SSL data (16 bytes) +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: 'Server certificate:' +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: ' subjectAltName: host "account-public-service-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.22:312][174]LogHttp: VeryVerbose: 00000231AE14E0C0: ' SSL certificate verify ok.' +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AE14E0C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AE14E0C0: Sent header (1023 bytes) - GET /account/api/public/account?accountId=6c9320e13012459c912b7f93b1b65bdf HTTP/1.1Host: account-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/jsonX-Epic-Correlation-ID: FN-P9nfctKxi0uoaQ2uMHwA_gUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmb +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: Received SSL data (5 bytes) +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: Received SSL data (89 bytes) +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: Received SSL data (5 bytes) +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: Received SSL data (1 bytes) +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: Received SSL data (5 bytes) +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: Received SSL data (16 bytes) +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: Sent SSL data (1 bytes) +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: Sent SSL data (16 bytes) +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: 'ALPN, server did not agree to a protocol' +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: 'Server certificate:' +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: ' subjectAltName: host "fortnite-public-service-latest-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.16.22:314][174]LogHttp: VeryVerbose: 00000231AA9C8440: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.22:315][174]LogHttp: VeryVerbose: 00000231AA9C8440: ' SSL certificate verify ok.' +[2018.11.29-17.16.22:315][174]LogHttp: VeryVerbose: 00000231AA9C8440: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:315][174]LogHttp: VeryVerbose: 00000231AA9C8440: Sent header (1023 bytes) - POST /fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/ClientQuestLogin?profileId=athena&rvn=236 HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept-Encoding: deflate, gzipAccept: */*Content-Type: application/jsonX-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":239}]X-Epic-Correlation-ID: FN-FNBqcgweqUiIfATdP4Mo_wUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2Ii +[2018.11.29-17.16.22:315][174]LogHttp: Verbose: 00000231AA9C8440: UploadCallback: 4 bytes out of 4 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=4 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:316][174]LogHttp: VeryVerbose: 00000231AA9C8440: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:316][174]LogHttp: VeryVerbose: 00000231AA9C8440: Sent data (4 bytes) +[2018.11.29-17.16.22:316][174]LogHttp: VeryVerbose: 00000231AA9C8440: 'We are completely uploaded and fine' +[2018.11.29-17.16.22:316][174]LogHttp: VeryVerbose: 00000231969C3440: Received SSL data (5 bytes) +[2018.11.29-17.16.22:316][174]LogHttp: VeryVerbose: 00000231969C3440: Received data (16384 bytes) +[2018.11.29-17.16.22:316][174]LogHttp: Verbose: 00000231969C3440: ReceiveResponseBodyCallback: 105275 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=9294, Response->TotalBytesRead=95981, Response->GetContentLength()=0, SizeToDownload=9294 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:316][174]LogHttp: Verbose: 00000231969C3440: ReceiveResponseBodyCallback: 112357 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=7082, Response->TotalBytesRead=105275, Response->GetContentLength()=0, SizeToDownload=7082 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:321][174]LogHttp: VeryVerbose: 00000231969C3440: Received SSL data (5 bytes) +[2018.11.29-17.16.22:326][174]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::SendFromQueue: Wrote 94 bytes, 0 bytes remaining in this packet +[2018.11.29-17.16.22:327][174]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:327][174]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:327][174]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:327][174]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:327][174]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:327][174]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:328][174]LogOnlineGame: Verbose: McpUtils request https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/events/tournamentandhistory/e6f5091c3b2f4c359cf2aad75c424de0/NONE/WindowsClient complete. code=200 +[2018.11.29-17.16.22:339][175]LogHttp: VeryVerbose: 00000231969C3440: Received data (16384 bytes) +[2018.11.29-17.16.22:339][175]LogHttp: Verbose: 00000231969C3440: ReceiveResponseBodyCallback: 128741 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=16384, Response->TotalBytesRead=112357, Response->GetContentLength()=0, SizeToDownload=16384 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:339][175]LogHttp: VeryVerbose: 00000231969C3440: Received SSL data (5 bytes) +[2018.11.29-17.16.22:339][175]LogHttp: VeryVerbose: 00000231969C3440: Received data (8363 bytes) +[2018.11.29-17.16.22:339][175]LogHttp: Verbose: 00000231969C3440: ReceiveResponseBodyCallback: 137097 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=8356, Response->TotalBytesRead=128741, Response->GetContentLength()=0, SizeToDownload=8356 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:339][175]LogHttp: VeryVerbose: 00000231969C3440: 'Connection #3 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.22:339][175]LogHttp: Verbose: Request 00000231969C3440 (easy handle:00000231A1665560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.22:351][175]LogHttp: VeryVerbose: 00000231AE14E0C0: Received SSL data (5 bytes) +[2018.11.29-17.16.22:351][175]LogHttp: VeryVerbose: 00000231AE14E0C0: Received header (17 bytes) +[2018.11.29-17.16.22:351][175]LogHttp: Verbose: 00000231AE14E0C0: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.22:351][175]LogHttp: VeryVerbose: 00000231AE14E0C0: Received header (37 bytes) +[2018.11.29-17.16.22:351][175]LogHttp: Verbose: 00000231AE14E0C0: Received response header 'Date: Thu, 29 Nov 2018 17:16:22 GMT'. +[2018.11.29-17.16.22:351][175]LogHttp: VeryVerbose: 00000231AE14E0C0: Received header (32 bytes) +[2018.11.29-17.16.22:351][175]LogHttp: Verbose: 00000231AE14E0C0: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.22:351][175]LogHttp: VeryVerbose: 00000231AE14E0C0: Received header (21 bytes) +[2018.11.29-17.16.22:351][175]LogHttp: Verbose: 00000231AE14E0C0: Received response header 'Content-Length: 110'. +[2018.11.29-17.16.22:351][175]LogHttp: VeryVerbose: 00000231AE14E0C0: Received header (24 bytes) +[2018.11.29-17.16.22:351][175]LogHttp: Verbose: 00000231AE14E0C0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.22:351][175]LogHttp: VeryVerbose: 00000231AE14E0C0: Received header (49 bytes) +[2018.11.29-17.16.22:351][175]LogHttp: Verbose: 00000231AE14E0C0: Received response header 'Cache-Control: no-cache, no-store, no-transform'. +[2018.11.29-17.16.22:351][175]LogHttp: VeryVerbose: 00000231AE14E0C0: Received header (52 bytes) +[2018.11.29-17.16.22:351][175]LogHttp: Verbose: 00000231AE14E0C0: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.22:351][175]LogHttp: VeryVerbose: 00000231AE14E0C0: Received header (50 bytes) +[2018.11.29-17.16.22:351][175]LogHttp: Verbose: 00000231AE14E0C0: Received response header 'X-Epic-Correlation-ID: FN-P9nfctKxi0uoaQ2uMHwA_g'. +[2018.11.29-17.16.22:351][175]LogHttp: Verbose: 00000231AE14E0C0: Received response header ''. +[2018.11.29-17.16.22:351][175]LogHttp: VeryVerbose: 00000231AE14E0C0: Received header (2 bytes) +[2018.11.29-17.16.22:351][175]LogHttp: VeryVerbose: 00000231AE14E0C0: Received data (110 bytes) +[2018.11.29-17.16.22:352][175]LogHttp: Verbose: 00000231AE14E0C0: ReceiveResponseBodyCallback: 110 bytes out of 110 received. (SizeInBlocks=1, BlockSizeInBytes=110, Response->TotalBytesRead=0, Response->GetContentLength()=110, SizeToDownload=110 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:352][175]LogHttp: VeryVerbose: 00000231AE14E0C0: 'Connection #10 to host account-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.22:352][175]LogHttp: Verbose: Request 00000231AE14E0C0 (easy handle:0000023195CD5560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.22:352][175]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:352][175]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:352][175]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:352][175]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:352][175]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:352][175]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:352][175]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:352][175]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:352][175]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:352][175]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:352][175]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:352][175]LogHttp: 00000231969C3440: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/storefront/v2/catalog?rvn=204, HTTP code: 200, content length: -1, actual payload size: 137097 +[2018.11.29-17.16.22:353][175]LogHttp: Verbose: 00000231969C3440 Response Header Content-Type: application/json +[2018.11.29-17.16.22:353][175]LogHttp: Verbose: 00000231969C3440 Response Header Date: Thu, 29 Nov 2018 17:16:22 GMT +[2018.11.29-17.16.22:353][175]LogHttp: Verbose: 00000231969C3440 Response Header ETag: "DA12F7F6417D8A510A891FA32BA3297B|2018-11-29T00:00:00.000Z" +[2018.11.29-17.16.22:353][175]LogHttp: Verbose: 00000231969C3440 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.22:353][175]LogHttp: Verbose: 00000231969C3440 Response Header X-Epic-Correlation-ID: FN-DiQpi4H62EOrc-duD7E2Rw +[2018.11.29-17.16.22:353][175]LogHttp: Verbose: 00000231969C3440 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.22:353][175]LogHttp: Verbose: 00000231969C3440 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.22:353][175]LogHttp: Verbose: 00000231969C3440 Response Header transfer-encoding: chunked +[2018.11.29-17.16.22:353][175]LogHttp: Verbose: 00000231969C3440 Response Header Connection: keep-alive +[2018.11.29-17.16.22:353][175]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:353][175]LogHttp: 00000231AE14E0C0: request has been successfully processed. URL: https://account-public-service-gamedev.ol.epicgames.net/account/api/public/account?accountId=6c9320e13012459c912b7f93b1b65bdf, HTTP code: 200, content length: 110, actual payload size: 110 +[2018.11.29-17.16.22:353][175]LogHttp: Verbose: 00000231AE14E0C0 Response Header Date: Thu, 29 Nov 2018 17:16:22 GMT +[2018.11.29-17.16.22:353][175]LogHttp: Verbose: 00000231AE14E0C0 Response Header Content-Type: application/json +[2018.11.29-17.16.22:353][175]LogHttp: Verbose: 00000231AE14E0C0 Response Header Content-Length: 110 +[2018.11.29-17.16.22:353][175]LogHttp: Verbose: 00000231AE14E0C0 Response Header Connection: keep-alive +[2018.11.29-17.16.22:353][175]LogHttp: Verbose: 00000231AE14E0C0 Response Header Cache-Control: no-cache, no-store, no-transform +[2018.11.29-17.16.22:354][175]LogHttp: Verbose: 00000231AE14E0C0 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.22:354][175]LogHttp: Verbose: 00000231AE14E0C0 Response Header X-Epic-Correlation-ID: FN-P9nfctKxi0uoaQ2uMHwA_g +[2018.11.29-17.16.22:354][175]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Received SSL data (5 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Received header (17 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: Verbose: 00000231AA9C8440: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Received header (32 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: Verbose: 00000231AA9C8440: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Received header (37 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: Verbose: 00000231AA9C8440: Received response header 'Date: Thu, 29 Nov 2018 17:16:22 GMT'. +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Received header (31 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: Verbose: 00000231AA9C8440: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Received header (50 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: Verbose: 00000231AA9C8440: Received response header 'X-Epic-Correlation-ID: FN-FNBqcgweqUiIfATdP4Mo_w'. +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Received header (52 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: Verbose: 00000231AA9C8440: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Received header (75 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: Verbose: 00000231AA9C8440: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Received header (35 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: Verbose: 00000231AA9C8440: Received response header 'X-EpicGames-Profile-Revision: 236'. +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Received header (21 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: Verbose: 00000231AA9C8440: Received response header 'Content-Length: 465'. +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Received header (24 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: Verbose: 00000231AA9C8440: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.22:376][176]LogHttp: Verbose: 00000231AA9C8440: Received response header ''. +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Received header (2 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Received data (465 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: Verbose: 00000231AA9C8440: ReceiveResponseBodyCallback: 465 bytes out of 465 received. (SizeInBlocks=1, BlockSizeInBytes=465, Response->TotalBytesRead=0, Response->GetContentLength()=465, SizeToDownload=465 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: 'Connection cache is full, closing the oldest one.' +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: 'Closing connection 9' +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: Sent SSL data (2 bytes) +[2018.11.29-17.16.22:376][176]LogHttp: VeryVerbose: 00000231AA9C8440: 'Connection #11 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.22:376][176]LogHttp: Verbose: Request 00000231AA9C8440 (easy handle:00000231A48F0010) has completed (code:0) and has been marked as such +[2018.11.29-17.16.22:379][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:379][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:379][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:379][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:379][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:379][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:379][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:379][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:379][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:379][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:379][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:379][176]LogHttp: 00000231AA9C8440: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/ClientQuestLogin?profileId=athena&rvn=236, HTTP code: 200, content length: 465, actual payload size: 465 +[2018.11.29-17.16.22:379][176]LogHttp: Verbose: 00000231AA9C8440 Response Header Content-Type: application/json +[2018.11.29-17.16.22:379][176]LogHttp: Verbose: 00000231AA9C8440 Response Header Date: Thu, 29 Nov 2018 17:16:22 GMT +[2018.11.29-17.16.22:379][176]LogHttp: Verbose: 00000231AA9C8440 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.22:379][176]LogHttp: Verbose: 00000231AA9C8440 Response Header X-Epic-Correlation-ID: FN-FNBqcgweqUiIfATdP4Mo_w +[2018.11.29-17.16.22:379][176]LogHttp: Verbose: 00000231AA9C8440 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.22:379][176]LogHttp: Verbose: 00000231AA9C8440 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.22:379][176]LogHttp: Verbose: 00000231AA9C8440 Response Header X-EpicGames-Profile-Revision: 236 +[2018.11.29-17.16.22:379][176]LogHttp: Verbose: 00000231AA9C8440 Response Header Content-Length: 465 +[2018.11.29-17.16.22:379][176]LogHttp: Verbose: 00000231AA9C8440 Response Header Connection: keep-alive +[2018.11.29-17.16.22:380][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:380][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:380][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:391][176]LogCatalogHelper: Found 21 RealMoney offers needing queried in catalog (115 total offers) +[2018.11.29-17.16.22:392][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:392][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:392][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:392][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:392][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:392][176]LogParty: FSocialQuery_UserInfo completed query for [1] users on subsystem [Primary] with error [] +[2018.11.29-17.16.22:392][176]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:392][176]LogHttp: Verbose: 00000231AB3081C0: URL='https://catalogv2-public-service-gamedev.ol.epicgames.net/catalog/api/shared/bulk/offers?id=3b4c5df9efa5415b941cf74262865e4e&id=559f2ba95f874ec987d0ebfd2cc9c70a&id=4daadb392f1c4ee2b5a3af443e614d2a&id=ede05b3c97e9475a8d9be91da65750f0&id=d900ad5da7ec4eac86918bcfa0c3e698&id=8ca6dbe417c9470783e9e2293cc0f4a9&id=84aba7b08b734e7c90a0112173b1f7fb&id=3c8c7982474145e9ab639354fdbf628d&id=494b1e73046543d6ba53c4574fd1b54c&id=bf5dfcaa2e354fc482142f6ee0fcd61f&id=f5c0e8ab6c9a4530999041e89e9b6934&id=9aa9f44cd8c24652953a1b204755b193&id=e2f25dae43604a839dd6f2c21b675d5e&id=d2da86026c71429a9cf5e76dfd89a1d3&id=e852b1940299435884365cec7dc3a608&id=35759d71512b47e5b2825669f1d9166a&id=c8319a037f9840e8b7549de480efb9c7&id=f05c43f7c1d24f5fbb1a6fa5a5a60edb&id=57f0419c4e4a4ea4858b2f37a98d5315&id=41134f4ff35a45a4923604cbb15e487d&id=85125898f3914946a9443bcce4667660&returnItemDetails=false&country=US&locale=en' +[2018.11.29-17.16.22:393][176]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=183 BytesLeft=0 +[2018.11.29-17.16.22:393][176]LogHttp: Verbose: 00000231AB3081C0: Verb='GET' +[2018.11.29-17.16.22:393][176]LogHttp: Verbose: 00000231AB3081C0: Custom headers are present +[2018.11.29-17.16.22:393][176]LogHttp: Verbose: 00000231AB3081C0: Payload size=0 +[2018.11.29-17.16.22:393][176]LogHttp: Verbose: 00000231AB3081C0: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.22:393][176]LogHttp: Verbose: 00000231AB3081C0: Adding header 'X-Epic-Correlation-ID: FN-tK-e3CWOcEKMkpHv289k5w' +[2018.11.29-17.16.22:393][176]LogHttp: Verbose: 00000231AB3081C0: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.22:393][176]LogHttp: Verbose: 00000231AB3081C0: Adding header 'Content-Length: 0' +[2018.11.29-17.16.22:393][176]LogHttp: Verbose: 00000231AB3081C0: Adding header 'Expect: ' +[2018.11.29-17.16.22:393][176]LogHttp: 00000231AB3081C0: Starting GET request to URL='https://catalogv2-public-service-gamedev.ol.epicgames.net/catalog/api/shared/bulk/offers?id=3b4c5df9efa5415b941cf74262865e4e&id=559f2ba95f874ec987d0ebfd2cc9c70a&id=4daadb392f1c4ee2b5a3af443e614d2a&id=ede05b3c97e9475a8d9be91da65750f0&id=d900ad5da7ec4eac86918bcfa0c3e698&id=8ca6dbe417c9470783e9e2293cc0f4a9&id=84aba7b08b734e7c90a0112173b1f7fb&id=3c8c7982474145e9ab639354fdbf628d&id=494b1e73046543d6ba53c4574fd1b54c&id=bf5dfcaa2e354fc482142f6ee0fcd61f&id=f5c0e8ab6c9a4530999041e89e9b6934&id=9aa9f44cd8c24652953a1b204755b193&id=e2f25dae43604a839dd6f2c21b675d5e&id=d2da86026c71429a9cf5e76dfd89a1d3&id=e852b1940299435884365cec7dc3a608&id=35759d71512b47e5b2825669f1d9166a&id=c8319a037f9840e8b7549de480efb9c7&id=f05c43f7c1d24f5fbb1a6fa5a5a60edb&id=57f0419c4e4a4ea4858b2f37a98d5315&id=41134f4ff35a45a4923604cbb15e487d&id=85125898f3914946a9443bcce4667660&returnItemDetails=false&country=US&locale=en' +[2018.11.29-17.16.22:393][176]LogHttp: Verbose: 00000231AB3081C0: request (easy handle:00000231A2815560) has been added to threaded queue for processing +[2018.11.29-17.16.22:394][176]LogProfileSys: UMcpProfile::HandleProfileUpdate updated lock expiration on Account MCP:e6f5091c3b2f4c359cf2aad75c424de0 for ProfileId common_core to --- +[2018.11.29-17.16.22:394][176]LogProfileSys: UMcpProfile::HandleProfileUpdate updated lock expiration on Account MCP:e6f5091c3b2f4c359cf2aad75c424de0 for ProfileId athena to --- +[2018.11.29-17.16.22:395][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:395][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:395][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:395][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:395][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:395][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:395][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:395][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:396][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:396][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:396][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:396][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:396][176]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.22:398][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:398][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:399][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:399][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:399][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:399][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:399][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:399][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:400][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:400][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:400][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:400][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:400][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:400][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:400][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:400][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:400][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:414][176]LogHttp: Verbose: 00000231AB3081C0: request (easy handle:00000231A2815560) has started threaded processing +[2018.11.29-17.16.22:414][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:415][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:415][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:415][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:415][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:415][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:415][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:416][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:416][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:416][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:416][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:416][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:416][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:416][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:417][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:417][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:417][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:417][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:417][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:417][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:418][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:418][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:418][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:418][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:418][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:418][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:418][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:418][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:418][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:419][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:419][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:419][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:419][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:419][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:419][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:419][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:420][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:420][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:420][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:420][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:420][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:420][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:420][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:420][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:421][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.22:421][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:421][176]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.22:423][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:423][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:423][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:423][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:427][176]LogSlate: Took 0.004175 seconds to synchronously load lazily loaded font '../../../Engine/Content/Slate/Fonts/DroidSansFallback.ttf' (3848K) +[2018.11.29-17.16.22:427][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:427][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:427][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:427][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:428][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:428][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:428][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:428][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:428][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:428][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:428][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:428][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:428][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:428][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:428][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:428][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:428][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:428][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:428][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:429][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:429][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:429][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:429][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:429][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:429][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:429][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:429][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:429][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:429][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:429][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:429][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:429][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:429][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:429][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:429][176]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:429][176]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:435][177]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: RECV: +[2018.11.29-17.16.22:435][177]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: Session establishment successful. +[2018.11.29-17.16.22:435][177]LogXmpp: Strophe XMPP thread received state change Was: ProcessingLogin Now: LoggedIn +[2018.11.29-17.16.22:439][177]LogHttp: VeryVerbose: 00000231AB3081C0: ' Trying 10.40.237.153...' +[2018.11.29-17.16.22:439][177]LogHttp: VeryVerbose: 00000231AB3081C0: 'TCP_NODELAY set' +[2018.11.29-17.16.22:439][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:439][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:439][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:439][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:439][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:439][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:439][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:439][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:439][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:439][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:439][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:439][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:439][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:439][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:440][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:440][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:440][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:440][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:440][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:440][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:440][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:440][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:440][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:440][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:440][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:440][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:440][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:440][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:440][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:440][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:441][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:441][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:441][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:441][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:441][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:441][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:441][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:441][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:441][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:441][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:441][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:441][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:441][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:441][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:441][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:441][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:441][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:442][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:442][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:442][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:442][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:442][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:442][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:442][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:442][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:442][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:442][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:442][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:442][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:442][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:442][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:442][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:442][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:442][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:443][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:443][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:443][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:443][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:443][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:443][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:443][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:443][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:443][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:443][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:443][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:443][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:443][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:443][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:443][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:443][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:443][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:443][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:443][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:444][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:444][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:444][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:444][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:444][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:444][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:444][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:444][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:444][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:444][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:444][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:444][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:444][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:444][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:444][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:444][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:444][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:444][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:444][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:445][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:445][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:445][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:445][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:445][177]LogStreaming: Warning: Failed to read file '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' error. +[2018.11.29-17.16.22:445][177]LogSlate: Warning: GetFontFace failed to load or process '../../../Engine/Content/Slate/Fonts/Roboto-Regular.ttf' with face index 0 +[2018.11.29-17.16.22:460][178]LogXmpp: Strophe processing LoginStatus change Was: ProcessingLogin Now: LoggedIn +[2018.11.29-17.16.22:460][178]LogXmpp: Logged IN JID=e6f5091c3b2f4c359cf2aad75c424de0:gamedev.ol.epicgames.net:V2:FortniteDevLatest:WIN::02893B0E4C31D665986F7F914616016E +[2018.11.29-17.16.22:460][178]LogOnlineParty: OSS: FOnlinePartySystemMcp::OnXmppLoginChanged - logged in user e6f5091c3b2f4c359cf2aad75c424de0 +[2018.11.29-17.16.22:460][178]LogOnlineParty: OSS: FOnlinePartySystemMcp::OnLoggedIntoXmpp - Updating party data user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 state=Disconnected +[2018.11.29-17.16.22:460][178]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.updatepartyconfiguration user=e6f5091c3b2f4c359cf2aad75c424de0 to=all payload={"partyId":"C9AE807B4F9D1F30F1535488AB79E7A8","presencePermissions":-253,"invitePermissions":3,"partyFlags":3,"notAcceptingMembersReason":0,"maxMembers":4,"password":"","accessKey":"1A9601624B2510433E8340B1FAAD2362"} +[2018.11.29-17.16.22:461][178]LogParty: Verbose: Persistent party state changed to Active +[2018.11.29-17.16.22:461][178]LogOnlineParty: Warning: OSS: FOnlinePartySystemMcp::PublishPartyInfoToPresence failure to publish presence user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.22:461][178]LogOnlineIdentity: OSS: FOnlineIdentityMcp::OnXmppLoginChanged e6f5091c3b2f4c359cf2aad75c424de0:gamedev.ol.epicgames.net:V2:FortniteDevLatest:WIN::02893B0E4C31D665986F7F914616016E loggedin +[2018.11.29-17.16.22:461][178]LogXmpp: VeryVerbose: libstrophe[71688] conn debug: SENT: {"Status":"","bIsPlaying":false,"bIsJoinable":false,"bHasVoiceSupport":false,"SessionId":"","Properties":{}} +[2018.11.29-17.16.22:461][178]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.16.22:480][179]LogHttp: VeryVerbose: 00000231AB3081C0: 'Connected to catalogv2-public-service-gamedev.ol.epicgames.net (10.40.237.153) port 443 (#12)' +[2018.11.29-17.16.22:485][179]LogHttp: VeryVerbose: 00000231AB3081C0: 'ALPN, offering http/1.1' +[2018.11.29-17.16.22:485][179]LogHttp: VeryVerbose: 00000231AB3081C0: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.22:487][179]LogHttp: VeryVerbose: 00000231AB3081C0: 'TLSv1.2 (OUT), TLS header, Certificate Status (22):' +[2018.11.29-17.16.22:487][179]LogHttp: VeryVerbose: 00000231AB3081C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:487][179]LogHttp: VeryVerbose: 00000231AB3081C0: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.22:487][179]LogHttp: VeryVerbose: 00000231AB3081C0: Sent SSL data (512 bytes) +[2018.11.29-17.16.22:508][181]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::SendFromQueue: Wrote 210 bytes, 0 bytes remaining in this packet +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: Received SSL data (5 bytes) +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: Received SSL data (89 bytes) +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: Received SSL data (5 bytes) +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: 'TLSv1.2 (IN), TLS handshake, Certificate (11):' +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: Received SSL data (4568 bytes) +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: Received SSL data (5 bytes) +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: 'TLSv1.2 (IN), TLS handshake, Server key exchange (12):' +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: Received SSL data (333 bytes) +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: Received SSL data (5 bytes) +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: 'TLSv1.2 (IN), TLS handshake, Server finished (14):' +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: Received SSL data (4 bytes) +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: 'TLSv1.2 (OUT), TLS handshake, Client key exchange (16):' +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: Sent SSL data (70 bytes) +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: Sent SSL data (1 bytes) +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.22:525][182]LogHttp: VeryVerbose: 00000231AB3081C0: Sent SSL data (16 bytes) +[2018.11.29-17.16.22:560][184]LogHttp: VeryVerbose: 00000231AB3081C0: Received SSL data (5 bytes) +[2018.11.29-17.16.22:560][184]LogHttp: VeryVerbose: 00000231AB3081C0: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: Received SSL data (1 bytes) +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: Received SSL data (5 bytes) +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: Received SSL data (16 bytes) +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: 'ALPN, server did not agree to a protocol' +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: 'Server certificate:' +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: ' subjectAltName: host "catalogv2-public-service-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: ' SSL certificate verify ok.' +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:561][184]LogHttp: VeryVerbose: 00000231AB3081C0: Sent header (1023 bytes) - GET /catalog/api/shared/bulk/offers?id=3b4c5df9efa5415b941cf74262865e4e&id=559f2ba95f874ec987d0ebfd2cc9c70a&id=4daadb392f1c4ee2b5a3af443e614d2a&id=ede05b3c97e9475a8d9be91da65750f0&id=d900ad5da7ec4eac86918bcfa0c3e698&id=8ca6dbe417c9470783e9e2293cc0f4a9&id=84aba7b08b734e7c90a0112173b1f7fb&id=3c8c7982474145e9ab639354fdbf628d&id=494b1e73046543d6ba53c4574fd1b54c&id=bf5dfcaa2e354fc482142f6ee0fcd61f&id=f5c0e8ab6c9a4530999041e89e9b6934&id=9aa9f44cd8c24652953a1b204755b193&id=e2f25dae43604a839dd6f2c21b675d5e&id=d2da86026c71429a9cf5e76dfd89a1d3&id=e852b1940299435884365cec7dc3a608&id=35759d71512b47e5b2825669f1d9166a&id=c8319a037f9840e8b7549de480efb9c7&id=f05c43f7c1d24f5fbb1a6fa5a5a60edb&id=57f0419c4e4a4ea4858b2f37a98d5315&id=41134f4ff35a45a4923604cbb15e487d&id=85125898f3914946a9443bcce4667660&returnItemDetails=false&country=US&locale=en HTTP/1.1Host: catalogv2-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/jsonX-Epic-Correlation-ID: FN-tK-e3CWOcEKMkpHv +[2018.11.29-17.16.22:611][187]LogHttp: VeryVerbose: 00000231AB3081C0: Received SSL data (5 bytes) +[2018.11.29-17.16.22:611][187]LogHttp: VeryVerbose: 00000231AB3081C0: Received header (17 bytes) +[2018.11.29-17.16.22:611][187]LogHttp: Verbose: 00000231AB3081C0: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.22:611][187]LogHttp: VeryVerbose: 00000231AB3081C0: Received header (24 bytes) +[2018.11.29-17.16.22:611][187]LogHttp: Verbose: 00000231AB3081C0: Received response header 'Content-Encoding: gzip'. +[2018.11.29-17.16.22:611][187]LogHttp: VeryVerbose: 00000231AB3081C0: Received header (32 bytes) +[2018.11.29-17.16.22:611][187]LogHttp: Verbose: 00000231AB3081C0: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.22:611][187]LogHttp: VeryVerbose: 00000231AB3081C0: Received header (37 bytes) +[2018.11.29-17.16.22:611][187]LogHttp: Verbose: 00000231AB3081C0: Received response header 'Date: Thu, 29 Nov 2018 17:16:22 GMT'. +[2018.11.29-17.16.22:611][187]LogHttp: VeryVerbose: 00000231AB3081C0: Received header (23 bytes) +[2018.11.29-17.16.22:611][187]LogHttp: Verbose: 00000231AB3081C0: Received response header 'Vary: Accept-Encoding'. +[2018.11.29-17.16.22:611][187]LogHttp: VeryVerbose: 00000231AB3081C0: Received header (50 bytes) +[2018.11.29-17.16.22:611][187]LogHttp: Verbose: 00000231AB3081C0: Received response header 'X-Epic-Correlation-ID: FN-tK-e3CWOcEKMkpHv289k5w'. +[2018.11.29-17.16.22:611][187]LogHttp: VeryVerbose: 00000231AB3081C0: Received header (22 bytes) +[2018.11.29-17.16.22:611][187]LogHttp: Verbose: 00000231AB3081C0: Received response header 'Content-Length: 6984'. +[2018.11.29-17.16.22:611][187]LogHttp: VeryVerbose: 00000231AB3081C0: Received header (24 bytes) +[2018.11.29-17.16.22:611][187]LogHttp: Verbose: 00000231AB3081C0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.22:611][187]LogHttp: Verbose: 00000231AB3081C0: Received response header ''. +[2018.11.29-17.16.22:611][187]LogHttp: VeryVerbose: 00000231AB3081C0: Received header (2 bytes) +[2018.11.29-17.16.22:611][187]LogHttp: VeryVerbose: 00000231AB3081C0: Received data (6984 bytes) +[2018.11.29-17.16.22:611][187]LogHttp: Verbose: 00000231AB3081C0: ReceiveResponseBodyCallback: 16384 bytes out of 6984 received. (SizeInBlocks=1, BlockSizeInBytes=16384, Response->TotalBytesRead=0, Response->GetContentLength()=6984, SizeToDownload=16384 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:611][187]LogHttp: Verbose: 00000231AB3081C0: ReceiveResponseBodyCallback: 32768 bytes out of 6984 received. (SizeInBlocks=1, BlockSizeInBytes=16384, Response->TotalBytesRead=16384, Response->GetContentLength()=6984, SizeToDownload=16384 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:612][187]LogHttp: Verbose: 00000231AB3081C0: ReceiveResponseBodyCallback: 49152 bytes out of 6984 received. (SizeInBlocks=1, BlockSizeInBytes=16384, Response->TotalBytesRead=32768, Response->GetContentLength()=6984, SizeToDownload=16384 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:612][187]LogHttp: Verbose: 00000231AB3081C0: ReceiveResponseBodyCallback: 55243 bytes out of 6984 received. (SizeInBlocks=1, BlockSizeInBytes=6091, Response->TotalBytesRead=49152, Response->GetContentLength()=6984, SizeToDownload=6091 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:612][187]LogHttp: VeryVerbose: 00000231AB3081C0: 'Connection cache is full, closing the oldest one.' +[2018.11.29-17.16.22:612][187]LogHttp: VeryVerbose: 00000231AB3081C0: 'Closing connection 8' +[2018.11.29-17.16.22:612][187]LogHttp: VeryVerbose: 00000231AB3081C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:612][187]LogHttp: VeryVerbose: 00000231AB3081C0: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.16.22:612][187]LogHttp: VeryVerbose: 00000231AB3081C0: Sent SSL data (2 bytes) +[2018.11.29-17.16.22:612][187]LogHttp: VeryVerbose: 00000231AB3081C0: 'Connection #12 to host catalogv2-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.22:612][187]LogHttp: Verbose: Request 00000231AB3081C0 (easy handle:00000231A2815560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.22:612][187]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:612][187]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:612][187]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:612][187]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:612][187]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:612][187]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:612][187]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:613][187]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:613][187]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:613][187]LogHttp: 00000231AB3081C0: request has been successfully processed. URL: https://catalogv2-public-service-gamedev.ol.epicgames.net/catalog/api/shared/bulk/offers?id=3b4c5df9efa5415b941cf74262865e4e&id=559f2ba95f874ec987d0ebfd2cc9c70a&id=4daadb392f1c4ee2b5a3af443e614d2a&id=ede05b3c97e9475a8d9be91da65750f0&id=d900ad5da7ec4eac86918bcfa0c3e698&id=8ca6dbe417c9470783e9e2293cc0f4a9&id=84aba7b08b734e7c90a0112173b1f7fb&id=3c8c7982474145e9ab639354fdbf628d&id=494b1e73046543d6ba53c4574fd1b54c&id=bf5dfcaa2e354fc482142f6ee0fcd61f&id=f5c0e8ab6c9a4530999041e89e9b6934&id=9aa9f44cd8c24652953a1b204755b193&id=e2f25dae43604a839dd6f2c21b675d5e&id=d2da86026c71429a9cf5e76dfd89a1d3&id=e852b1940299435884365cec7dc3a608&id=35759d71512b47e5b2825669f1d9166a&id=c8319a037f9840e8b7549de480efb9c7&id=f05c43f7c1d24f5fbb1a6fa5a5a60edb&id=57f0419c4e4a4ea4858b2f37a98d5315&id=41134f4ff35a45a4923604cbb15e487d&id=85125898f3914946a9443bcce4667660&returnItemDetails=false&country=US&locale=en, HTTP code: 200, content length: 6984, actual payload size: 55243 +[2018.11.29-17.16.22:613][187]LogHttp: Verbose: 00000231AB3081C0 Response Header Content-Encoding: gzip +[2018.11.29-17.16.22:613][187]LogHttp: Verbose: 00000231AB3081C0 Response Header Content-Type: application/json +[2018.11.29-17.16.22:613][187]LogHttp: Verbose: 00000231AB3081C0 Response Header Date: Thu, 29 Nov 2018 17:16:22 GMT +[2018.11.29-17.16.22:613][187]LogHttp: Verbose: 00000231AB3081C0 Response Header Vary: Accept-Encoding +[2018.11.29-17.16.22:613][187]LogHttp: Verbose: 00000231AB3081C0 Response Header X-Epic-Correlation-ID: FN-tK-e3CWOcEKMkpHv289k5w +[2018.11.29-17.16.22:613][187]LogHttp: Verbose: 00000231AB3081C0 Response Header Content-Length: 6984 +[2018.11.29-17.16.22:613][187]LogHttp: Verbose: 00000231AB3081C0 Response Header Connection: keep-alive +[2018.11.29-17.16.22:613][187]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:626][188]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:626][188]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:631][188]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=419 BytesLeft=0 +[2018.11.29-17.16.22:632][188]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:632][188]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:632][188]LogHttp: Verbose: 00000231AA9C1500: URL='https://priceengine-public-service-gamedev.ol.epicgames.net/priceengine/api/shared/offers/price' +[2018.11.29-17.16.22:632][188]LogHttp: Verbose: 00000231AA9C1500: Verb='POST' +[2018.11.29-17.16.22:632][188]LogHttp: Verbose: 00000231AA9C1500: Custom headers are present +[2018.11.29-17.16.22:632][188]LogHttp: Verbose: 00000231AA9C1500: Payload size=1359 +[2018.11.29-17.16.22:632][188]LogHttp: Verbose: 00000231AA9C1500: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.22:632][188]LogHttp: Verbose: 00000231AA9C1500: Adding header 'X-Epic-Correlation-ID: FN--g7_0nCkhE__W6cVl-S9Eg' +[2018.11.29-17.16.22:632][188]LogHttp: Verbose: 00000231AA9C1500: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.22:632][188]LogHttp: Verbose: 00000231AA9C1500: Adding header 'Content-Length: 1359' +[2018.11.29-17.16.22:632][188]LogHttp: Verbose: 00000231AA9C1500: Adding header 'Expect: ' +[2018.11.29-17.16.22:632][188]LogHttp: 00000231AA9C1500: Starting POST request to URL='https://priceengine-public-service-gamedev.ol.epicgames.net/priceengine/api/shared/offers/price' +[2018.11.29-17.16.22:633][188]LogHttp: Verbose: 00000231AA9C1500: request (easy handle:00000231A8CC0010) has been added to threaded queue for processing +[2018.11.29-17.16.22:644][189]LogHttp: Verbose: 00000231AA9C1500: request (easy handle:00000231A8CC0010) has started threaded processing +[2018.11.29-17.16.22:644][189]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: RECV: {"Status":"","bIsPlaying":false,"bIsJoinable":false,"bHasVoiceSupport":false,"SessionId":"","Properties":{}} +[2018.11.29-17.16.22:644][189]LogXmpp: Verbose: Received Strophe XMPP Stanza presence +[2018.11.29-17.16.22:644][189]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.16.22:644][189]LogXmpp: VeryVerbose: presence Stanza handled by Presence +[2018.11.29-17.16.22:693][192]LogHttp: VeryVerbose: 00000231AA9C1500: ' Trying 10.40.132.96...' +[2018.11.29-17.16.22:693][192]LogHttp: VeryVerbose: 00000231AA9C1500: 'TCP_NODELAY set' +[2018.11.29-17.16.22:742][195]LogHttp: VeryVerbose: 00000231AA9C1500: 'Connected to priceengine-public-service-gamedev.ol.epicgames.net (10.40.132.96) port 443 (#13)' +[2018.11.29-17.16.22:742][195]LogHttp: VeryVerbose: 00000231AA9C1500: 'ALPN, offering http/1.1' +[2018.11.29-17.16.22:742][195]LogHttp: VeryVerbose: 00000231AA9C1500: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.22:742][195]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (OUT), TLS header, Certificate Status (22):' +[2018.11.29-17.16.22:742][195]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:742][195]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.22:742][195]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (512 bytes) +[2018.11.29-17.16.22:793][198]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (5 bytes) +[2018.11.29-17.16.22:793][198]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.22:793][198]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (89 bytes) +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (5 bytes) +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (IN), TLS handshake, Certificate (11):' +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (4568 bytes) +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (5 bytes) +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (IN), TLS handshake, Server key exchange (12):' +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (333 bytes) +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (5 bytes) +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (IN), TLS handshake, Server finished (14):' +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (4 bytes) +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (OUT), TLS handshake, Client key exchange (16):' +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (70 bytes) +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (1 bytes) +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.22:794][198]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (16 bytes) +[2018.11.29-17.16.22:829][200]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (5 bytes) +[2018.11.29-17.16.22:829][200]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.22:829][200]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (1 bytes) +[2018.11.29-17.16.22:829][200]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (5 bytes) +[2018.11.29-17.16.22:829][200]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.22:829][200]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (16 bytes) +[2018.11.29-17.16.22:829][200]LogHttp: VeryVerbose: 00000231AA9C1500: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.22:829][200]LogHttp: VeryVerbose: 00000231AA9C1500: 'ALPN, server did not agree to a protocol' +[2018.11.29-17.16.22:830][200]LogHttp: VeryVerbose: 00000231AA9C1500: 'Server certificate:' +[2018.11.29-17.16.22:830][200]LogHttp: VeryVerbose: 00000231AA9C1500: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.16.22:830][200]LogHttp: VeryVerbose: 00000231AA9C1500: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.16.22:830][200]LogHttp: VeryVerbose: 00000231AA9C1500: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.16.22:830][200]LogHttp: VeryVerbose: 00000231AA9C1500: ' subjectAltName: host "priceengine-public-service-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.16.22:830][200]LogHttp: VeryVerbose: 00000231AA9C1500: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.22:830][200]LogHttp: VeryVerbose: 00000231AA9C1500: ' SSL certificate verify ok.' +[2018.11.29-17.16.22:830][200]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:845][201]LogHttp: VeryVerbose: 00000231AA9C1500: Sent header (1023 bytes) - POST /priceengine/api/shared/offers/price HTTP/1.1Host: priceengine-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/jsonX-Epic-Correlation-ID: FN--g7_0nCkhE__W6cVl-S9EgUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM0RoMXFQVm9LNXp2M1J0Tj +[2018.11.29-17.16.22:845][201]LogHttp: Verbose: 00000231AA9C1500: UploadCallback: 1359 bytes out of 1359 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=1359 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:845][201]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:845][201]LogHttp: VeryVerbose: 00000231AA9C1500: Sent data (1359 bytes) +[2018.11.29-17.16.22:845][201]LogHttp: VeryVerbose: 00000231AA9C1500: 'We are completely uploaded and fine' +[2018.11.29-17.16.22:845][201]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:845][201]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:978][209]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (5 bytes) +[2018.11.29-17.16.22:978][209]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (17 bytes) +[2018.11.29-17.16.22:978][209]LogHttp: Verbose: 00000231AA9C1500: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.22:979][209]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (32 bytes) +[2018.11.29-17.16.22:979][209]LogHttp: Verbose: 00000231AA9C1500: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.22:979][209]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (37 bytes) +[2018.11.29-17.16.22:979][209]LogHttp: Verbose: 00000231AA9C1500: Received response header 'Date: Thu, 29 Nov 2018 17:16:22 GMT'. +[2018.11.29-17.16.22:979][209]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (50 bytes) +[2018.11.29-17.16.22:979][209]LogHttp: Verbose: 00000231AA9C1500: Received response header 'X-Epic-Correlation-ID: FN--g7_0nCkhE__W6cVl-S9Eg'. +[2018.11.29-17.16.22:979][209]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (52 bytes) +[2018.11.29-17.16.22:979][209]LogHttp: Verbose: 00000231AA9C1500: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.22:979][209]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (22 bytes) +[2018.11.29-17.16.22:979][209]LogHttp: Verbose: 00000231AA9C1500: Received response header 'Content-Length: 8733'. +[2018.11.29-17.16.22:979][209]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (24 bytes) +[2018.11.29-17.16.22:979][209]LogHttp: Verbose: 00000231AA9C1500: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.22:979][209]LogHttp: Verbose: 00000231AA9C1500: Received response header ''. +[2018.11.29-17.16.22:979][209]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (2 bytes) +[2018.11.29-17.16.22:979][209]LogHttp: VeryVerbose: 00000231AA9C1500: Received data (8733 bytes) +[2018.11.29-17.16.22:979][209]LogHttp: Verbose: 00000231AA9C1500: ReceiveResponseBodyCallback: 8733 bytes out of 8733 received. (SizeInBlocks=1, BlockSizeInBytes=8733, Response->TotalBytesRead=0, Response->GetContentLength()=8733, SizeToDownload=8733 (<-this will get returned from the callback)) +[2018.11.29-17.16.22:979][209]LogHttp: VeryVerbose: 00000231AA9C1500: 'Connection cache is full, closing the oldest one.' +[2018.11.29-17.16.22:980][209]LogHttp: VeryVerbose: 00000231AA9C1500: 'Closing connection 3' +[2018.11.29-17.16.22:980][209]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (5 bytes) +[2018.11.29-17.16.22:980][209]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.16.22:980][209]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (2 bytes) +[2018.11.29-17.16.22:980][209]LogHttp: VeryVerbose: 00000231AA9C1500: 'Connection #13 to host priceengine-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.22:980][209]LogHttp: Verbose: Request 00000231AA9C1500 (easy handle:00000231A8CC0010) has completed (code:0) and has been marked as such +[2018.11.29-17.16.22:980][209]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:980][209]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.22:980][209]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:980][209]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:980][209]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:980][209]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:980][209]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:980][209]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:980][209]LogHttp: 00000231AA9C1500: request has been successfully processed. URL: https://priceengine-public-service-gamedev.ol.epicgames.net/priceengine/api/shared/offers/price, HTTP code: 200, content length: 8733, actual payload size: 8733 +[2018.11.29-17.16.22:980][209]LogHttp: Verbose: 00000231AA9C1500 Response Header Content-Type: application/json +[2018.11.29-17.16.22:980][209]LogHttp: Verbose: 00000231AA9C1500 Response Header Date: Thu, 29 Nov 2018 17:16:22 GMT +[2018.11.29-17.16.22:980][209]LogHttp: Verbose: 00000231AA9C1500 Response Header X-Epic-Correlation-ID: FN--g7_0nCkhE__W6cVl-S9Eg +[2018.11.29-17.16.22:980][209]LogHttp: Verbose: 00000231AA9C1500 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.22:980][209]LogHttp: Verbose: 00000231AA9C1500 Response Header Content-Length: 8733 +[2018.11.29-17.16.22:980][209]LogHttp: Verbose: 00000231AA9C1500 Response Header Connection: keep-alive +[2018.11.29-17.16.22:980][209]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:993][210]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.22:993][210]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.22:995][210]LogCatalogHelper: RefreshCatalog complete (HTTP 200) +[2018.11.29-17.16.22:995][210]LogCatalogHelper: Catalog will next expire at 2018.11.30-00.00.00 (Current Server Time 2018.11.29-17.16.22) +[2018.11.29-17.16.22:995][210]LogMcpContext: AthenaDirectAcquisitionScreen_C::TriggerRefresh(bRefreshOffersPending at time of call = 0) +[2018.11.29-17.16.22:998][210]LogFortStore: Error: [FortStorefront]: Attempting to load missing asset: /Game/Items/CardPacks/CardPack_Jackpot_Winter2018_Tickets.CardPack_Jackpot_Winter2018_Tickets +[2018.11.29-17.16.22:999][210]LogStreaming: Error: Couldn't find file for package /Game/Items/CardPacks/CardPack_Jackpot_Winter2018_Tickets requested by async loading code. NameToLoad: /Game/Items/CardPacks/CardPack_Jackpot_Winter2018_Tickets +[2018.11.29-17.16.23:000][210]LogStreaming: Error: This will hitch streaming because it ends up searching the disk instead of finding the file in the pak file. +[2018.11.29-17.16.23:000][210]LogStreaming: Error: Found 0 dependent packages... +[2018.11.29-17.16.23:009][210]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.23:012][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete() about to gather catalog entries +[2018.11.29-17.16.23:012][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete is adding offer id v2:/20ae6b9301fdaa7f9a436452ef024482cd423b399c72db7e7cd1c1be7e9c3d9f (devname [VIRTUAL]1 x Wukong, 1 x Royale Flags, 1 x Dragon Axe, 1 x Royale Dragon for -1 MtxCurrency) from store BRWeeklyStorefront +[2018.11.29-17.16.23:012][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete is adding offer id v2:/0468e16e32880ec07bdaa3a0c8159613b4c2bde2a7a532d37dc879d1d94a11a2 (devname [VIRTUAL]1 x Slushy Soldier, 1 x Slushy Jr. for 1 MtxCurrency) from store BRWeeklyStorefront +[2018.11.29-17.16.23:012][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete is adding offer id v2:/fffdb942625d0a32ed5785e2a6e681b9d666ee4c8b620b42b7068021446bb18b (devname [VIRTUAL]1 x Rex, 1 x Scaly, 1 x Bitemark, 1 x Pterodactyl for -1 MtxCurrency) from store BRWeeklyStorefront +[2018.11.29-17.16.23:013][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete is adding offer id v2:/421c36063abad89df9b378639cb641991a819751ec315d5456fee9441a7a71a6 (devname [VIRTUAL]1 x Waypoint, 1 x Signal Hub for 1 MtxCurrency) from store BRWeeklyStorefront +[2018.11.29-17.16.23:013][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete is adding offer id v2:/33e9ff93e710741b84a87a5950425516837bcd3dcdb0a12abb8229c365ce15c9 (devname [VIRTUAL]1 x Cloudbreaker for 1 MtxCurrency) from store BRWeeklyStorefront +[2018.11.29-17.16.23:013][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete is adding offer id v2:/29c89b0704960e23bd78bfaa8185974600634394f8ac97d434e9d85c2dacf3f9 (devname [VIRTUAL]1 x Highland Warrior, 1 x Buckler, 1 x Silver Fang, 1 x Storm Sigil for -1 MtxCurrency) from store BRWeeklyStorefront +[2018.11.29-17.16.23:013][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete is adding offer id v2:/d4ecf74e869d96a40c4b1386b22a1347668161834d22c8ef09809aaf3c831d7b (devname [VIRTUAL]1 x Leviathan, 1 x Fish Tank, 1 x Global Axe, 1 x Planetary Probe for -1 MtxCurrency) from store BRWeeklyStorefront +[2018.11.29-17.16.23:013][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete is adding offer id v2:/218f6a8b3dee9b8c5d1cca4f72b8380bea05f45dec8b831f28d633e7400e747d (devname [VIRTUAL]1 x Wingtip for 1 MtxCurrency) from store BRWeeklyStorefront +[2018.11.29-17.16.23:013][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete is adding offer id v2:/592f4a4b77ebed9544bb33cf0318ccb5c4176aedb57612ab14e642d9f7f981e4 (devname [VIRTUAL]1 x Icicle for 1 MtxCurrency) from store BRWeeklyStorefront +[2018.11.29-17.16.23:013][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete is adding offer id v2:/72eb74052cb973daae67b508e4cba88d37e5592ef13dd56b973069cbca154931 (devname [VIRTUAL]1 x Snowfall for 1 MtxCurrency) from store BRWeeklyStorefront +[2018.11.29-17.16.23:013][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete is adding offer id v2:/947a01db94886da22d221c009382976da8f9e147f159b492fbd27168584ec618 (devname [VIRTUAL]1 x Ground Pound for 1 MtxCurrency) from store BRDailyStorefront +[2018.11.29-17.16.23:013][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete is adding offer id v2:/9f3ab88c0e1e06af73d0b45a6bb4d2547c54030b7a5161e3a86cf657ffb5509e (devname [VIRTUAL]1 x Accolades for 1 MtxCurrency) from store BRDailyStorefront +[2018.11.29-17.16.23:013][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete is adding offer id v2:/04db476e284cdc3537d80f8bc19cf7fbc293390710020172f8ce2db6b2094960 (devname [VIRTUAL]1 x Get Funky for 1 MtxCurrency) from store BRDailyStorefront +[2018.11.29-17.16.23:013][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete is adding offer id v2:/ea67f737ce0c5a9d8ee4359f3899c7b86f16d355aff8edd0187060078c582d29 (devname [VIRTUAL]1 x Backstroke for 1 MtxCurrency) from store BRDailyStorefront +[2018.11.29-17.16.23:013][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::OnFreshenCatalogComplete() is done gathering catalog entries +[2018.11.29-17.16.23:013][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::HandleOffersRead() is passed 14 offers +[2018.11.29-17.16.23:013][211]LogMcpContext: AthenaDirectAcquisitionScreen_C::StartLoadingMtxOfferData() +[2018.11.29-17.16.23:025][212]LogStreaming: Error: Couldn't find file for package /Game/Catalog/DisplayAssets/DA_Featured_Pickaxe_ID_134_Snowman requested by async loading code. NameToLoad: /Game/Catalog/DisplayAssets/DA_Featured_Pickaxe_ID_134_Snowman +[2018.11.29-17.16.23:025][212]LogStreaming: Error: This will hitch streaming because it ends up searching the disk instead of finding the file in the pak file. +[2018.11.29-17.16.23:025][212]LogStreaming: Error: Found 0 dependent packages... +[2018.11.29-17.16.23:025][212]LogStreaming: Error: Couldn't find file for package /Game/Catalog/DisplayAssets/DA_Featured_CID_292_Athena_Commando_F_Dieselpunk02 requested by async loading code. NameToLoad: /Game/Catalog/DisplayAssets/DA_Featured_CID_292_Athena_Commando_F_Dieselpunk02 +[2018.11.29-17.16.23:025][212]LogStreaming: Error: This will hitch streaming because it ends up searching the disk instead of finding the file in the pak file. +[2018.11.29-17.16.23:025][212]LogStreaming: Error: Found 0 dependent packages... +[2018.11.29-17.16.23:025][212]LogStreaming: Error: Couldn't find file for package /Game/Catalog/DisplayAssets/DA_Featured_CID_291_Athena_Commando_M_Dieselpunk02 requested by async loading code. NameToLoad: /Game/Catalog/DisplayAssets/DA_Featured_CID_291_Athena_Commando_M_Dieselpunk02 +[2018.11.29-17.16.23:025][212]LogStreaming: Error: This will hitch streaming because it ends up searching the disk instead of finding the file in the pak file. +[2018.11.29-17.16.23:025][212]LogStreaming: Error: Found 0 dependent packages... +[2018.11.29-17.16.23:025][212]LogStreaming: Error: Couldn't find file for package /Game/Catalog/DisplayAssets/DA_Featured_CID_290_Athena_Commando_F_BlueBadass requested by async loading code. NameToLoad: /Game/Catalog/DisplayAssets/DA_Featured_CID_290_Athena_Commando_F_BlueBadass +[2018.11.29-17.16.23:025][212]LogStreaming: Error: This will hitch streaming because it ends up searching the disk instead of finding the file in the pak file. +[2018.11.29-17.16.23:025][212]LogStreaming: Error: Found 0 dependent packages... +[2018.11.29-17.16.23:025][212]LogStreaming: Error: Couldn't find file for package /Game/Catalog/DisplayAssets/DA_Featured_CID_280_Athena_Commando_M_Snowman requested by async loading code. NameToLoad: /Game/Catalog/DisplayAssets/DA_Featured_CID_280_Athena_Commando_M_Snowman +[2018.11.29-17.16.23:025][212]LogStreaming: Error: This will hitch streaming because it ends up searching the disk instead of finding the file in the pak file. +[2018.11.29-17.16.23:025][212]LogStreaming: Error: Found 0 dependent packages... +[2018.11.29-17.16.23:075][214]LogMcpContext: AthenaDirectAcquisitionScreen_C::HandleOfferDataLoaded() +[2018.11.29-17.16.23:076][214]LogMcpContext: AthenaDirectAcquisitionScreen_C::HandleOfferDataLoaded() is generating widgets for 8 offers +[2018.11.29-17.16.23:076][214]LogUMG: Display: Widget Class AthenaDirectAcquisitionOfferWidget_C - Loaded Fast Template. +[2018.11.29-17.16.23:076][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:076][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:077][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:078][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:078][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:078][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:078][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:079][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:079][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:079][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:079][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:079][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:079][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:079][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:079][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:079][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:079][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:079][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:079][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:080][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:080][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:080][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:080][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:080][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:080][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:080][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:080][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:080][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:080][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:080][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:081][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:081][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:081][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:081][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:081][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:081][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:081][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:081][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:081][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:081][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:081][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:081][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:081][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:082][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:082][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:082][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:082][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:082][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:082][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:082][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:082][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:082][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:082][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:083][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:083][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:083][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:083][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:083][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:083][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:083][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:083][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:083][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:083][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:083][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:083][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:084][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:084][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:084][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:084][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:084][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:084][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:084][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:084][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:084][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:084][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:084][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:084][214]LogUMG: Display: Widget Class StoreMain_MTXOffer_C - Loaded Fast Template. +[2018.11.29-17.16.23:085][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:085][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:085][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:085][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:085][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:085][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:085][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:085][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:085][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:085][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:086][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:086][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:086][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:086][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:086][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:086][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:086][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:086][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:086][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:086][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:086][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:087][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:088][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:089][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:090][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:091][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:092][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:092][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:092][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:092][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:092][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:092][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:092][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.23:092][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:092][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:092][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:093][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:093][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:093][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:093][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:093][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:093][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.23:093][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.23:093][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.23:093][214]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.24:231][283]LogFort: UFortUIStateWidget_Frontend::CheckForGifts : Called +[2018.11.29-17.16.24:232][283]LogFort: UFortUIStateWidget_Frontend::CheckForGifts : Gifting flow was off, turning it on +[2018.11.29-17.16.24:232][283]LogFort: UFortUIStateWidget_Frontend::CheckForGifts : No message, checking for gift box +[2018.11.29-17.16.24:232][283]LogFort: UFortUIStateWidget_Frontend::CheckForGifts : No message or giftbox available, abandoning flow +[2018.11.29-17.16.26:752][435]LogUAC: GetLAID returned 7002a30141898b3e98fefe8d1876feb5 from provider OtherPartitionRecovery +[2018.11.29-17.16.30:281][646]LogFort: MapPreload: Scanning for map assets to preload +[2018.11.29-17.16.30:287][646]LogFort: MapPreload: Finished scanning for map assets to preload. Found 385 packages in 0.01 seconds (deps 0.00 s, ptoa 0.00 s, filter 0.00) +[2018.11.29-17.16.30:287][646]FortClientBot: {"event": "StateChange", "oldstate": "Idle", "newstate": "PreloadingMap", "bot": "LoadBot07063", "timeinstate":14.587} +[2018.11.29-17.16.31:521][721]LogXmpp: VeryVerbose: libstrophe[71688] conn debug: SENT: {"Status":"Battle Royale Lobby - 1 / 4","bIsPlaying":false,"bIsJoinable":false,"bHasVoiceSupport":false,"SessionId":"","Properties":{"FortBasicInfo_j":{"homeBaseRating":1},"FortLFG_I":"0","FortPartySize_i":1,"FortSubGame_i":1,"InUnjoinableMatch_b":false,"FortGameplayStats_j":{"state":"","playlist":"None","numKills":0,"bFellToDeath":false}}} +[2018.11.29-17.16.31:521][721]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.16.31:557][723]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::SendFromQueue: Wrote 444 bytes, 0 bytes remaining in this packet +[2018.11.29-17.16.31:655][729]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=653 BytesLeft=0 +[2018.11.29-17.16.31:655][729]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: RECV: {"Status":"Battle Royale Lobby - 1 / 4","bIsPlaying":false,"bIsJoinable":false,"bHasVoiceSupport":false,"SessionId":"","Properties":{"FortBasicInfo_j":{"homeBaseRating":1},"FortLFG_I":"0","FortPartySize_i":1,"FortSubGame_i":1,"InUnjoinableMatch_b":false,"FortGameplayStats_j":{"state":"","playlist":"None","numKills":0,"bFellToDeath":false}}} +[2018.11.29-17.16.31:655][729]LogXmpp: Verbose: Received Strophe XMPP Stanza presence +[2018.11.29-17.16.31:655][729]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.16.31:656][729]LogXmpp: VeryVerbose: presence Stanza handled by Presence +[2018.11.29-17.16.32:642][787]LogFort: MapPreload: Finished preloading 764 assets, took 2.361086 seconds +[2018.11.29-17.16.34:860][920]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.34:861][920]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.34:861][920]LogHttp: Verbose: 00000231AA9C1500: URL='https://fortnitecontent-website-gamedev.ol.epicgames.net/content/api/pages/fortnite-game' +[2018.11.29-17.16.34:861][920]LogHttp: Verbose: 00000231AA9C1500: Verb='GET' +[2018.11.29-17.16.34:861][920]LogHttp: Verbose: 00000231AA9C1500: Custom headers are present +[2018.11.29-17.16.34:861][920]LogHttp: Verbose: 00000231AA9C1500: Payload size=0 +[2018.11.29-17.16.34:861][920]LogHttp: Verbose: 00000231AA9C1500: Adding header 'Accept-Language: en' +[2018.11.29-17.16.34:861][920]LogHttp: Verbose: 00000231AA9C1500: Adding header 'Accept-Platform: Windows' +[2018.11.29-17.16.34:861][920]LogHttp: Verbose: 00000231AA9C1500: Adding header 'Accept-Region: NONE' +[2018.11.29-17.16.34:861][920]LogHttp: Verbose: 00000231AA9C1500: Adding header 'Accept-Version: UE4' +[2018.11.29-17.16.34:861][920]LogHttp: Verbose: 00000231AA9C1500: Adding header 'User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.34:861][920]LogHttp: Verbose: 00000231AA9C1500: Adding header 'Content-Length: 0' +[2018.11.29-17.16.34:861][920]LogHttp: Verbose: 00000231AA9C1500: Adding header 'Expect: ' +[2018.11.29-17.16.34:861][920]LogHttp: 00000231AA9C1500: Starting GET request to URL='https://fortnitecontent-website-gamedev.ol.epicgames.net/content/api/pages/fortnite-game' +[2018.11.29-17.16.34:861][920]LogHttp: Verbose: 00000231AA9C1500: request (easy handle:00000231A23DAAB0) has been added to threaded queue for processing +[2018.11.29-17.16.34:868][921]LogHttp: Verbose: 00000231AA9C1500: request (easy handle:00000231A23DAAB0) has started threaded processing +[2018.11.29-17.16.34:880][922]LogHttp: VeryVerbose: 00000231AA9C1500: ' Trying 10.40.237.207...' +[2018.11.29-17.16.34:880][922]LogHttp: VeryVerbose: 00000231AA9C1500: 'TCP_NODELAY set' +[2018.11.29-17.16.34:930][925]LogHttp: VeryVerbose: 00000231AA9C1500: 'Connected to fortnitecontent-website-gamedev.ol.epicgames.net (10.40.237.207) port 443 (#14)' +[2018.11.29-17.16.34:930][925]LogHttp: VeryVerbose: 00000231AA9C1500: 'ALPN, offering http/1.1' +[2018.11.29-17.16.34:930][925]LogHttp: VeryVerbose: 00000231AA9C1500: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.34:947][926]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (OUT), TLS header, Certificate Status (22):' +[2018.11.29-17.16.34:947][926]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (5 bytes) +[2018.11.29-17.16.34:947][926]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.34:947][926]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (512 bytes) +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (5 bytes) +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (89 bytes) +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (5 bytes) +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (IN), TLS handshake, Certificate (11):' +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (4568 bytes) +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (5 bytes) +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (IN), TLS handshake, Server key exchange (12):' +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (333 bytes) +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (5 bytes) +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (IN), TLS handshake, Server finished (14):' +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (4 bytes) +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (5 bytes) +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (OUT), TLS handshake, Client key exchange (16):' +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (70 bytes) +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (5 bytes) +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (1 bytes) +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (5 bytes) +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.34:981][928]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (16 bytes) +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (5 bytes) +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (1 bytes) +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (5 bytes) +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (16 bytes) +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: 'ALPN, server did not agree to a protocol' +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: 'Server certificate:' +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: ' subjectAltName: host "fortnitecontent-website-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: ' SSL certificate verify ok.' +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (5 bytes) +[2018.11.29-17.16.35:029][931]LogHttp: VeryVerbose: 00000231AA9C1500: Sent header (320 bytes) - GET /content/api/pages/fortnite-game HTTP/1.1Host: fortnitecontent-website-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipAccept-Language: enAccept-Platform: WindowsAccept-Region: NONEAccept-Version: UE4User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Length: 0 +[2018.11.29-17.16.35:314][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received SSL data (5 bytes) +[2018.11.29-17.16.35:314][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (17 bytes) +[2018.11.29-17.16.35:314][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.35:314][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (38 bytes) +[2018.11.29-17.16.35:314][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'Cache-control: no-cache="set-cookie"'. +[2018.11.29-17.16.35:314][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (24 bytes) +[2018.11.29-17.16.35:314][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'Content-Encoding: gzip'. +[2018.11.29-17.16.35:314][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (47 bytes) +[2018.11.29-17.16.35:314][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'Content-Type: application/json; charset=utf-8'. +[2018.11.29-17.16.35:314][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (37 bytes) +[2018.11.29-17.16.35:314][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'Date: Thu, 29 Nov 2018 17:16:35 GMT'. +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (44 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'ETag: W/"a066-sD5iEcDUcDWCuMPb+3V7c/dKmvg"'. +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: 'Added cookie AWSELB="2FB5AFF90807521573A7EE5EB7E4FD4836B8F933C5C2600A0E1B4475F80F0F0D1C4A27C4D08E79A60D2C34941DD6D9C765244A49767104B7E1915951892355E78C7154AAA4" for domain fortnitecontent-website-gamedev.ol.epicgames.net, path /, expire 1543598195' +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (180 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'Set-Cookie: AWSELB=2FB5AFF90807521573A7EE5EB7E4FD4836B8F933C5C2600A0E1B4475F80F0F0D1C4A27C4D08E79A60D2C34941DD6D9C765244A49767104B7E1915951892355E78C7154AAA4;PATH=/;MAX-AGE=86400'. +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (45 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'Strict-Transport-Security: max-age=15552000'. +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (23 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'Vary: Accept-Encoding'. +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (25 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'X-Cache-Status: EXPIRED'. +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (33 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'X-Content-Type-Options: nosniff'. +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (29 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'X-DNS-Prefetch-Control: off'. +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (28 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'X-Download-Options: noopen'. +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (61 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'x-epic-correlation-id: 85f3c880-f3fa-11e8-b53a-b98d2428b849'. +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (29 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'X-Frame-Options: SAMEORIGIN'. +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (33 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'X-XSS-Protection: 1; mode=block'. +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (22 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'Content-Length: 8554'. +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (24 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: Received response header ''. +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received header (2 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Received data (8554 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: ReceiveResponseBodyCallback: 16384 bytes out of 8554 received. (SizeInBlocks=1, BlockSizeInBytes=16384, Response->TotalBytesRead=0, Response->GetContentLength()=8554, SizeToDownload=16384 (<-this will get returned from the callback)) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: ReceiveResponseBodyCallback: 32768 bytes out of 8554 received. (SizeInBlocks=1, BlockSizeInBytes=16384, Response->TotalBytesRead=16384, Response->GetContentLength()=8554, SizeToDownload=16384 (<-this will get returned from the callback)) +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: 00000231AA9C1500: ReceiveResponseBodyCallback: 41062 bytes out of 8554 received. (SizeInBlocks=1, BlockSizeInBytes=8294, Response->TotalBytesRead=32768, Response->GetContentLength()=8554, SizeToDownload=8294 (<-this will get returned from the callback)) +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: 'Connection cache is full, closing the oldest one.' +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: 'Closing connection 10' +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (5 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: Sent SSL data (2 bytes) +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: 00000231AA9C1500: 'Connection #14 to host fortnitecontent-website-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.35:315][948]LogHttp: Verbose: Request 00000231AA9C1500 (easy handle:00000231A23DAAB0) has completed (code:0) and has been marked as such +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.35:315][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:316][948]LogHttp: 00000231AA9C1500: request has been successfully processed. URL: https://fortnitecontent-website-gamedev.ol.epicgames.net/content/api/pages/fortnite-game, HTTP code: 200, content length: 8554, actual payload size: 41062 +[2018.11.29-17.16.35:316][948]LogHttp: Verbose: 00000231AA9C1500 Response Header Cache-control: no-cache="set-cookie" +[2018.11.29-17.16.35:316][948]LogHttp: Verbose: 00000231AA9C1500 Response Header Content-Encoding: gzip +[2018.11.29-17.16.35:316][948]LogHttp: Verbose: 00000231AA9C1500 Response Header Content-Type: application/json; charset=utf-8 +[2018.11.29-17.16.35:316][948]LogHttp: Verbose: 00000231AA9C1500 Response Header Date: Thu, 29 Nov 2018 17:16:35 GMT +[2018.11.29-17.16.35:316][948]LogHttp: Verbose: 00000231AA9C1500 Response Header ETag: W/"a066-sD5iEcDUcDWCuMPb+3V7c/dKmvg" +[2018.11.29-17.16.35:316][948]LogHttp: Verbose: 00000231AA9C1500 Response Header Strict-Transport-Security: max-age=15552000 +[2018.11.29-17.16.35:316][948]LogHttp: Verbose: 00000231AA9C1500 Response Header Vary: Accept-Encoding +[2018.11.29-17.16.35:316][948]LogHttp: Verbose: 00000231AA9C1500 Response Header X-Cache-Status: EXPIRED +[2018.11.29-17.16.35:316][948]LogHttp: Verbose: 00000231AA9C1500 Response Header X-Content-Type-Options: nosniff +[2018.11.29-17.16.35:316][948]LogHttp: Verbose: 00000231AA9C1500 Response Header X-DNS-Prefetch-Control: off +[2018.11.29-17.16.35:316][948]LogHttp: Verbose: 00000231AA9C1500 Response Header X-Download-Options: noopen +[2018.11.29-17.16.35:317][948]LogHttp: Verbose: 00000231AA9C1500 Response Header x-epic-correlation-id: 85f3c880-f3fa-11e8-b53a-b98d2428b849 +[2018.11.29-17.16.35:317][948]LogHttp: Verbose: 00000231AA9C1500 Response Header X-Frame-Options: SAMEORIGIN +[2018.11.29-17.16.35:317][948]LogHttp: Verbose: 00000231AA9C1500 Response Header X-XSS-Protection: 1; mode=block +[2018.11.29-17.16.35:317][948]LogHttp: Verbose: 00000231AA9C1500 Response Header Content-Length: 8554 +[2018.11.29-17.16.35:317][948]LogHttp: Verbose: 00000231AA9C1500 Response Header Connection: keep-alive +[2018.11.29-17.16.35:317][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.35:326][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.35:326][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:291][546]FortClientBot: {"event": "BotStatus", "bot": "LoadBot07063", "statusvalue": 5, "statusstring": "PreloadingMap", "timeincurrentstate": 15 } +[2018.11.29-17.16.45:291][546]LogOnlineGame: [UFortMatchmakingV2::StartMatchmaking] Starting matchmaking to bucket: '6834:0:NONE:playlist_defaultsolo' +[2018.11.29-17.16.45:291][546]LogOnlineGame: [UFortMatchmakingV2::StartTimeToMatchPhase] Starting Phase: 'ConnectToService' +[2018.11.29-17.16.45:291][546]LogMatchmakingServiceClient: StartMatchmaking - Starting matchmaking to bucket: '6834:0:NONE:playlist_defaultsolo' +[2018.11.29-17.16.45:291][546]LogOnlineGame: [UFortMatchmakingV2::OnMatchmakingStartedInternal] Matchmaking started +[2018.11.29-17.16.45:292][546]LogParty: Verbose: Party [C9AE807B4F9D1F30F1535488AB79E7A8, LocalOwner (LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0)), Leader (LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0))] attempting to update party config +[2018.11.29-17.16.45:292][546]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.updatepartyconfiguration user=e6f5091c3b2f4c359cf2aad75c424de0 to=all payload={"partyId":"C9AE807B4F9D1F30F1535488AB79E7A8","presencePermissions":-1834389757,"invitePermissions":32515,"partyFlags":2,"notAcceptingMembersReason":1,"maxMembers":4,"password":"","accessKey":"1A9601624B2510433E8340B1FAAD2362"} +[2018.11.29-17.16.45:292][546]LogOnlineParty: Display: OSS: Publishing party to presence PartyId(C9AE807B4F9D1F30F1535488AB79E7A8) AccessKey(1A9601624B2510433E8340B1FAAD2362) HasPassword(0) IsAcceptingMembers(0) NotAcceptingReason(1) +[2018.11.29-17.16.45:292][546]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::PublishPartyInfoToPresence success to publish presence user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.45:292][546]LogOnlineParty: Verbose: OSS: UpdateParty request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.45:292][546]LogParty: Verbose: [C9AE807B4F9D1F30F1535488AB79E7A8] Party config updated Succeeded +[2018.11.29-17.16.45:292][546]LogMatchmakingServiceClient: ChangeState - 'None' -> 'ObtainingTicket' +[2018.11.29-17.16.45:292][546]LogOnlineGame: [UFortMatchmakingV2::OnMatchmakingStateChangedInternal] OldState: None, NewState: ObtainingTicket +[2018.11.29-17.16.45:292][546]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:292][546]LogMatchmakingServiceClient: ObtainTicket - Sending ticket request: "https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/matchmakingservice/ticket/player/e6f5091c3b2f4c359cf2aad75c424de0?partyPlayerIds=e6f5091c3b2f4c359cf2aad75c424de0&bucketId=6834%3A0%3ANONE%3Aplaylist_defaultsolo&player.platform=Windows&player.subregions=&player.option.fillTeam=true&party.WIN=true" +[2018.11.29-17.16.45:292][546]LogProfileSys: MCP-Profile: Dispatching request to https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=238 +[2018.11.29-17.16.45:292][546]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:293][546]LogProfileSys: MCP-Profile: Command EquipBattleRoyaleCustomization queued to send +[2018.11.29-17.16.45:293][546]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:293][546]LogProfileSys: MCP-Profile: Command EquipBattleRoyaleCustomization queued to send +[2018.11.29-17.16.45:293][546]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:293][546]LogProfileSys: MCP-Profile: Command EquipBattleRoyaleCustomization queued to send +[2018.11.29-17.16.45:293][546]FortClientBot: {"event": "StateChange", "oldstate": "PreloadingMap", "newstate": "LookingForMatch", "bot": "LoadBot07063", "timeinstate":15.010} +[2018.11.29-17.16.45:297][547]LogOnlineParty: Verbose: OSS: UpdatePartyData request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.45:297][547]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.data user=e6f5091c3b2f4c359cf2aad75c424de0 to all +[2018.11.29-17.16.45:297][547]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:297][547]LogHttp: Verbose: 00000231A4060240: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/matchmakingservice/ticket/player/e6f5091c3b2f4c359cf2aad75c424de0?partyPlayerIds=e6f5091c3b2f4c359cf2aad75c424de0&bucketId=6834%3A0%3ANONE%3Aplaylist_defaultsolo&player.platform=Windows&player.subregions=&player.option.fillTeam=true&party.WIN=true' +[2018.11.29-17.16.45:297][547]LogHttp: Verbose: 00000231A4060240: Verb='GET' +[2018.11.29-17.16.45:297][547]LogHttp: Verbose: 00000231A4060240: Custom headers are present +[2018.11.29-17.16.45:297][547]LogHttp: Verbose: 00000231A4060240: Payload size=0 +[2018.11.29-17.16.45:297][547]LogHttp: Verbose: 00000231A4060240: Adding header 'X-Epic-Correlation-ID: FN-kR8LDRWXXEG5IotpR3h6mg' +[2018.11.29-17.16.45:297][547]LogHttp: Verbose: 00000231A4060240: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.45:297][547]LogHttp: Verbose: 00000231A4060240: Adding header 'Content-Length: 0' +[2018.11.29-17.16.45:297][547]LogHttp: Verbose: 00000231A4060240: Adding header 'Expect: ' +[2018.11.29-17.16.45:297][547]LogHttp: 00000231A4060240: Starting GET request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/matchmakingservice/ticket/player/e6f5091c3b2f4c359cf2aad75c424de0?partyPlayerIds=e6f5091c3b2f4c359cf2aad75c424de0&bucketId=6834%3A0%3ANONE%3Aplaylist_defaultsolo&player.platform=Windows&player.subregions=&player.option.fillTeam=true&party.WIN=true' +[2018.11.29-17.16.45:297][547]LogHttp: Verbose: 00000231A4060240: request (easy handle:00000231A8CC0010) has been added to threaded queue for processing +[2018.11.29-17.16.45:311][548]LogHttp: Verbose: 00000231A4060240: request (easy handle:00000231A8CC0010) has started threaded processing +[2018.11.29-17.16.45:311][548]LogHttp: VeryVerbose: 00000231A4060240: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.45:311][548]LogHttp: VeryVerbose: 00000231A4060240: 'Re-using existing connection! (#7) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.45:312][548]LogHttp: VeryVerbose: 00000231A4060240: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#7)' +[2018.11.29-17.16.45:312][548]LogHttp: VeryVerbose: 00000231A4060240: Sent SSL data (5 bytes) +[2018.11.29-17.16.45:312][548]LogHttp: VeryVerbose: 00000231A4060240: Sent header (1023 bytes) - GET /fortnite/api/game/v2/matchmakingservice/ticket/player/e6f5091c3b2f4c359cf2aad75c424de0?partyPlayerIds=e6f5091c3b2f4c359cf2aad75c424de0&bucketId=6834%3A0%3ANONE%3Aplaylist_defaultsolo&player.platform=Windows&player.subregions=&player.option.fillTeam=true&party.WIN=true HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-kR8LDRWXXEG5IotpR3h6mgUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6Rj +[2018.11.29-17.16.45:312][548]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:312][548]LogHttp: Verbose: 00000231A41D6140: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=238' +[2018.11.29-17.16.45:312][548]LogHttp: Verbose: 00000231A41D6140: Verb='POST' +[2018.11.29-17.16.45:312][548]LogHttp: Verbose: 00000231A41D6140: Custom headers are present +[2018.11.29-17.16.45:312][548]LogHttp: Verbose: 00000231A41D6140: Payload size=124 +[2018.11.29-17.16.45:312][548]LogHttp: Verbose: 00000231A41D6140: Adding header 'Accept: */*' +[2018.11.29-17.16.45:312][548]LogHttp: Verbose: 00000231A41D6140: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.45:312][548]LogHttp: Verbose: 00000231A41D6140: Adding header 'X-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}' +[2018.11.29-17.16.45:312][548]LogHttp: Verbose: 00000231A41D6140: Adding header 'X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119' +[2018.11.29-17.16.45:312][548]LogHttp: Verbose: 00000231A41D6140: Adding header 'X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":240}]' +[2018.11.29-17.16.45:312][548]LogHttp: Verbose: 00000231A41D6140: Adding header 'X-Epic-Correlation-ID: FN-fHvtpPLtvkKqEcusqgFXsQ' +[2018.11.29-17.16.45:312][548]LogHttp: Verbose: 00000231A41D6140: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.45:312][548]LogHttp: Verbose: 00000231A41D6140: Adding header 'Content-Length: 124' +[2018.11.29-17.16.45:312][548]LogHttp: Verbose: 00000231A41D6140: Adding header 'Expect: ' +[2018.11.29-17.16.45:312][548]LogHttp: 00000231A41D6140: Starting POST request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=238' +[2018.11.29-17.16.45:312][548]LogHttp: Verbose: 00000231A41D6140: request (easy handle:00000231A22A0010) has been added to threaded queue for processing +[2018.11.29-17.16.45:328][549]LogHttp: Verbose: 00000231A41D6140: request (easy handle:00000231A22A0010) has started threaded processing +[2018.11.29-17.16.45:328][549]LogHttp: VeryVerbose: 00000231A41D6140: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.45:328][549]LogHttp: VeryVerbose: 00000231A41D6140: 'Re-using existing connection! (#11) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.45:328][549]LogHttp: VeryVerbose: 00000231A41D6140: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#11)' +[2018.11.29-17.16.45:328][549]LogHttp: VeryVerbose: 00000231A41D6140: Sent SSL data (5 bytes) +[2018.11.29-17.16.45:328][549]LogHttp: VeryVerbose: 00000231A41D6140: Sent header (1023 bytes) - POST /fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=238 HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept-Encoding: deflate, gzipAccept: */*Content-Type: application/jsonX-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":240}]X-Epic-Correlation-ID: FN-fHvtpPLtvkKqEcusqgFXsQUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2Ni +[2018.11.29-17.16.45:329][549]LogHttp: Verbose: 00000231A41D6140: UploadCallback: 124 bytes out of 124 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=124 (<-this will get returned from the callback)) +[2018.11.29-17.16.45:329][549]LogHttp: VeryVerbose: 00000231A41D6140: Sent SSL data (5 bytes) +[2018.11.29-17.16.45:329][549]LogHttp: VeryVerbose: 00000231A41D6140: Sent data (124 bytes) +[2018.11.29-17.16.45:329][549]LogHttp: VeryVerbose: 00000231A41D6140: 'We are completely uploaded and fine' +[2018.11.29-17.16.45:329][549]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:329][549]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:345][550]LogHttp: VeryVerbose: 00000231A4060240: Received SSL data (5 bytes) +[2018.11.29-17.16.45:345][550]LogHttp: VeryVerbose: 00000231A4060240: Received header (17 bytes) +[2018.11.29-17.16.45:345][550]LogHttp: Verbose: 00000231A4060240: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.45:345][550]LogHttp: VeryVerbose: 00000231A4060240: Received header (32 bytes) +[2018.11.29-17.16.45:345][550]LogHttp: Verbose: 00000231A4060240: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.45:345][550]LogHttp: VeryVerbose: 00000231A4060240: Received header (37 bytes) +[2018.11.29-17.16.45:345][550]LogHttp: Verbose: 00000231A4060240: Received response header 'Date: Thu, 29 Nov 2018 17:16:45 GMT'. +[2018.11.29-17.16.45:345][550]LogHttp: VeryVerbose: 00000231A4060240: Received header (31 bytes) +[2018.11.29-17.16.45:345][550]LogHttp: Verbose: 00000231A4060240: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.45:345][550]LogHttp: VeryVerbose: 00000231A4060240: Received header (50 bytes) +[2018.11.29-17.16.45:345][550]LogHttp: Verbose: 00000231A4060240: Received response header 'X-Epic-Correlation-ID: FN-kR8LDRWXXEG5IotpR3h6mg'. +[2018.11.29-17.16.45:345][550]LogHttp: VeryVerbose: 00000231A4060240: Received header (52 bytes) +[2018.11.29-17.16.45:345][550]LogHttp: Verbose: 00000231A4060240: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.45:345][550]LogHttp: VeryVerbose: 00000231A4060240: Received header (75 bytes) +[2018.11.29-17.16.45:345][550]LogHttp: Verbose: 00000231A4060240: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.45:345][550]LogHttp: VeryVerbose: 00000231A4060240: Received header (21 bytes) +[2018.11.29-17.16.45:345][550]LogHttp: Verbose: 00000231A4060240: Received response header 'Content-Length: 716'. +[2018.11.29-17.16.45:345][550]LogHttp: VeryVerbose: 00000231A4060240: Received header (24 bytes) +[2018.11.29-17.16.45:345][550]LogHttp: Verbose: 00000231A4060240: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.45:345][550]LogHttp: Verbose: 00000231A4060240: Received response header ''. +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: 00000231A4060240: Received header (2 bytes) +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: 00000231A4060240: Received data (716 bytes) +[2018.11.29-17.16.45:346][550]LogHttp: Verbose: 00000231A4060240: ReceiveResponseBodyCallback: 716 bytes out of 716 received. (SizeInBlocks=1, BlockSizeInBytes=716, Response->TotalBytesRead=0, Response->GetContentLength()=716, SizeToDownload=716 (<-this will get returned from the callback)) +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: 00000231A4060240: 'Connection #7 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.45:346][550]LogHttp: Verbose: Request 00000231A4060240 (easy handle:00000231A8CC0010) has completed (code:0) and has been marked as such +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:346][550]LogHttp: 00000231A4060240: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/matchmakingservice/ticket/player/e6f5091c3b2f4c359cf2aad75c424de0?partyPlayerIds=e6f5091c3b2f4c359cf2aad75c424de0&bucketId=6834%3A0%3ANONE%3Aplaylist_defaultsolo&player.platform=Windows&player.subregions=&player.option.fillTeam=true&party.WIN=true, HTTP code: 200, content length: 716, actual payload size: 716 +[2018.11.29-17.16.45:346][550]LogHttp: Verbose: 00000231A4060240 Response Header Content-Type: application/json +[2018.11.29-17.16.45:346][550]LogHttp: Verbose: 00000231A4060240 Response Header Date: Thu, 29 Nov 2018 17:16:45 GMT +[2018.11.29-17.16.45:346][550]LogHttp: Verbose: 00000231A4060240 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.45:346][550]LogHttp: Verbose: 00000231A4060240 Response Header X-Epic-Correlation-ID: FN-kR8LDRWXXEG5IotpR3h6mg +[2018.11.29-17.16.45:346][550]LogHttp: Verbose: 00000231A4060240 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.45:346][550]LogHttp: Verbose: 00000231A4060240 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.45:346][550]LogHttp: Verbose: 00000231A4060240 Response Header Content-Length: 716 +[2018.11.29-17.16.45:346][550]LogHttp: Verbose: 00000231A4060240 Response Header Connection: keep-alive +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:346][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:346][550]LogMatchmakingServiceClient: ObtainTicket_HttpRequestComplete - bSuceeded: 1 +[2018.11.29-17.16.45:347][550]LogMatchmakingServiceClient: ChangeState - 'ObtainingTicket' -> 'ConnectingToService' +[2018.11.29-17.16.45:347][550]LogOnlineGame: [UFortMatchmakingV2::OnMatchmakingStateChangedInternal] OldState: ObtainingTicket, NewState: ConnectingToService +[2018.11.29-17.16.45:347][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:347][550]LogHttp: Verbose: 00000231A4060240: HTTP request canceled. URL=https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/matchmakingservice/ticket/player/e6f5091c3b2f4c359cf2aad75c424de0?partyPlayerIds=e6f5091c3b2f4c359cf2aad75c424de0&bucketId=6834%3A0%3ANONE%3Aplaylist_defaultsolo&player.platform=Windows&player.subregions=&player.option.fillTeam=true&party.WIN=true +[2018.11.29-17.16.45:347][550]LogHttp: 00000231A4060240: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/matchmakingservice/ticket/player/e6f5091c3b2f4c359cf2aad75c424de0?partyPlayerIds=e6f5091c3b2f4c359cf2aad75c424de0&bucketId=6834%3A0%3ANONE%3Aplaylist_defaultsolo&player.platform=Windows&player.subregions=&player.option.fillTeam=true&party.WIN=true, HTTP code: 200, content length: 716, actual payload size: 716 +[2018.11.29-17.16.45:347][550]LogHttp: Verbose: 00000231A4060240 Response Header Content-Type: application/json +[2018.11.29-17.16.45:347][550]LogHttp: Verbose: 00000231A4060240 Response Header Date: Thu, 29 Nov 2018 17:16:45 GMT +[2018.11.29-17.16.45:347][550]LogHttp: Verbose: 00000231A4060240 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.45:347][550]LogHttp: Verbose: 00000231A4060240 Response Header X-Epic-Correlation-ID: FN-kR8LDRWXXEG5IotpR3h6mg +[2018.11.29-17.16.45:347][550]LogHttp: Verbose: 00000231A4060240 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.45:347][550]LogHttp: Verbose: 00000231A4060240 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.45:347][550]LogHttp: Verbose: 00000231A4060240 Response Header Content-Length: 716 +[2018.11.29-17.16.45:347][550]LogHttp: Verbose: 00000231A4060240 Response Header Connection: keep-alive +[2018.11.29-17.16.45:347][550]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:347][550]LogWebSockets: VeryVerbose: FLwsWebSocket[2]: Constructed url=wss://matchmaking-public-service-gamedev.ol.epicgames.net:443 protocols=wss +[2018.11.29-17.16.45:347][550]LogMatchmakingServiceClient: ConnectToMatchmakingService - Connecting to service: "wss://matchmaking-public-service-gamedev.ol.epicgames.net:443" +[2018.11.29-17.16.45:347][550]LogWebSockets: Verbose: FLwsWebSocket[2]::Connect: setting State=StartConnecting url=wss://matchmaking-public-service-gamedev.ol.epicgames.net:443 bWantsMessageEvents=1 bWantsRawMessageEvents=0 +[2018.11.29-17.16.45:378][552]LogWebSockets: Verbose: FLwsWebSocket[2]::ConnectInternal: setting State=Connecting PreviousState=StartConnecting +[2018.11.29-17.16.45:379][552]LogWebSockets: Verbose: FLwsWebSocket[2]::ConnectInternal: lws_client_connect_via_info succeeded +[2018.11.29-17.16.45:413][554]LogHttp: VeryVerbose: 00000231A41D6140: Received SSL data (5 bytes) +[2018.11.29-17.16.45:413][554]LogHttp: VeryVerbose: 00000231A41D6140: Received header (17 bytes) +[2018.11.29-17.16.45:413][554]LogHttp: Verbose: 00000231A41D6140: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.45:413][554]LogHttp: VeryVerbose: 00000231A41D6140: Received header (32 bytes) +[2018.11.29-17.16.45:413][554]LogHttp: Verbose: 00000231A41D6140: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.45:413][554]LogHttp: VeryVerbose: 00000231A41D6140: Received header (37 bytes) +[2018.11.29-17.16.45:413][554]LogHttp: Verbose: 00000231A41D6140: Received response header 'Date: Thu, 29 Nov 2018 17:16:45 GMT'. +[2018.11.29-17.16.45:413][554]LogHttp: VeryVerbose: 00000231A41D6140: Received header (31 bytes) +[2018.11.29-17.16.45:413][554]LogHttp: Verbose: 00000231A41D6140: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.45:413][554]LogHttp: VeryVerbose: 00000231A41D6140: Received header (50 bytes) +[2018.11.29-17.16.45:413][554]LogHttp: Verbose: 00000231A41D6140: Received response header 'X-Epic-Correlation-ID: FN-fHvtpPLtvkKqEcusqgFXsQ'. +[2018.11.29-17.16.45:414][554]LogHttp: VeryVerbose: 00000231A41D6140: Received header (52 bytes) +[2018.11.29-17.16.45:414][554]LogHttp: Verbose: 00000231A41D6140: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.45:414][554]LogHttp: VeryVerbose: 00000231A41D6140: Received header (75 bytes) +[2018.11.29-17.16.45:414][554]LogHttp: Verbose: 00000231A41D6140: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.45:414][554]LogHttp: VeryVerbose: 00000231A41D6140: Received header (35 bytes) +[2018.11.29-17.16.45:414][554]LogHttp: Verbose: 00000231A41D6140: Received response header 'X-EpicGames-Profile-Revision: 238'. +[2018.11.29-17.16.45:414][554]LogHttp: VeryVerbose: 00000231A41D6140: Received header (21 bytes) +[2018.11.29-17.16.45:414][554]LogHttp: Verbose: 00000231A41D6140: Received response header 'Content-Length: 280'. +[2018.11.29-17.16.45:414][554]LogHttp: VeryVerbose: 00000231A41D6140: Received header (24 bytes) +[2018.11.29-17.16.45:414][554]LogHttp: Verbose: 00000231A41D6140: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.45:414][554]LogHttp: Verbose: 00000231A41D6140: Received response header ''. +[2018.11.29-17.16.45:414][554]LogHttp: VeryVerbose: 00000231A41D6140: Received header (2 bytes) +[2018.11.29-17.16.45:414][554]LogHttp: VeryVerbose: 00000231A41D6140: Received data (280 bytes) +[2018.11.29-17.16.45:414][554]LogHttp: Verbose: 00000231A41D6140: ReceiveResponseBodyCallback: 280 bytes out of 280 received. (SizeInBlocks=1, BlockSizeInBytes=280, Response->TotalBytesRead=0, Response->GetContentLength()=280, SizeToDownload=280 (<-this will get returned from the callback)) +[2018.11.29-17.16.45:414][554]LogHttp: VeryVerbose: 00000231A41D6140: 'Connection cache is full, closing the oldest one.' +[2018.11.29-17.16.45:414][554]LogHttp: VeryVerbose: 00000231A41D6140: 'Closing connection 12' +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: 00000231A41D6140: Sent SSL data (5 bytes) +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: 00000231A41D6140: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: 00000231A41D6140: Sent SSL data (2 bytes) +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: 00000231A41D6140: 'Connection #11 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.45:415][554]LogHttp: Verbose: Request 00000231A41D6140 (easy handle:00000231A22A0010) has completed (code:0) and has been marked as such +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:415][554]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:416][554]LogHttp: 00000231A41D6140: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=238, HTTP code: 200, content length: 280, actual payload size: 280 +[2018.11.29-17.16.45:416][554]LogHttp: Verbose: 00000231A41D6140 Response Header Content-Type: application/json +[2018.11.29-17.16.45:416][554]LogHttp: Verbose: 00000231A41D6140 Response Header Date: Thu, 29 Nov 2018 17:16:45 GMT +[2018.11.29-17.16.45:416][554]LogHttp: Verbose: 00000231A41D6140 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.45:416][554]LogHttp: Verbose: 00000231A41D6140 Response Header X-Epic-Correlation-ID: FN-fHvtpPLtvkKqEcusqgFXsQ +[2018.11.29-17.16.45:416][554]LogHttp: Verbose: 00000231A41D6140 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.45:416][554]LogHttp: Verbose: 00000231A41D6140 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.45:416][554]LogHttp: Verbose: 00000231A41D6140 Response Header X-EpicGames-Profile-Revision: 238 +[2018.11.29-17.16.45:416][554]LogHttp: Verbose: 00000231A41D6140 Response Header Content-Length: 280 +[2018.11.29-17.16.45:416][554]LogHttp: Verbose: 00000231A41D6140 Response Header Connection: keep-alive +[2018.11.29-17.16.45:416][554]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:416][554]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:416][554]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:424][554]LogProfileSys: UMcpProfile::HandleProfileUpdate updated lock expiration on Account MCP:e6f5091c3b2f4c359cf2aad75c424de0 for ProfileId athena to --- +[2018.11.29-17.16.45:425][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.45:425][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.45:425][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.45:426][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.45:426][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.45:427][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.45:427][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.45:427][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.45:427][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.45:427][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.45:427][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.45:427][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.45:427][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.45:427][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.45:427][554]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.45:428][554]LogProfileSys: MCP-Profile: Dispatching request to https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=239 +[2018.11.29-17.16.45:432][555]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:432][555]LogHttp: Verbose: 00000231A44827C0: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=239' +[2018.11.29-17.16.45:432][555]LogHttp: Verbose: 00000231A44827C0: Verb='POST' +[2018.11.29-17.16.45:432][555]LogHttp: Verbose: 00000231A44827C0: Custom headers are present +[2018.11.29-17.16.45:432][555]LogHttp: Verbose: 00000231A44827C0: Payload size=131 +[2018.11.29-17.16.45:432][555]LogHttp: Verbose: 00000231A44827C0: Adding header 'Accept: */*' +[2018.11.29-17.16.45:432][555]LogHttp: Verbose: 00000231A44827C0: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.45:432][555]LogHttp: Verbose: 00000231A44827C0: Adding header 'X-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}' +[2018.11.29-17.16.45:432][555]LogHttp: Verbose: 00000231A44827C0: Adding header 'X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119' +[2018.11.29-17.16.45:432][555]LogHttp: Verbose: 00000231A44827C0: Adding header 'X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":241}]' +[2018.11.29-17.16.45:432][555]LogHttp: Verbose: 00000231A44827C0: Adding header 'X-Epic-Correlation-ID: FN-3hr4DjxqRUGdTZXrJB5gyQ' +[2018.11.29-17.16.45:433][555]LogHttp: Verbose: 00000231A44827C0: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.45:433][555]LogHttp: Verbose: 00000231A44827C0: Adding header 'Content-Length: 131' +[2018.11.29-17.16.45:433][555]LogHttp: Verbose: 00000231A44827C0: Adding header 'Expect: ' +[2018.11.29-17.16.45:433][555]LogHttp: 00000231A44827C0: Starting POST request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=239' +[2018.11.29-17.16.45:433][555]LogHttp: Verbose: 00000231A44827C0: request (easy handle:0000023181F3AAB0) has been added to threaded queue for processing +[2018.11.29-17.16.45:445][556]LogHttp: Verbose: 00000231A44827C0: request (easy handle:0000023181F3AAB0) has started threaded processing +[2018.11.29-17.16.45:445][556]LogHttp: VeryVerbose: 00000231A44827C0: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.45:445][556]LogHttp: VeryVerbose: 00000231A44827C0: 'Re-using existing connection! (#7) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.45:445][556]LogHttp: VeryVerbose: 00000231A44827C0: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#7)' +[2018.11.29-17.16.45:445][556]LogHttp: VeryVerbose: 00000231A44827C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.45:445][556]LogHttp: VeryVerbose: 00000231A44827C0: Sent header (1023 bytes) - POST /fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=239 HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept-Encoding: deflate, gzipAccept: */*Content-Type: application/jsonX-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":241}]X-Epic-Correlation-ID: FN-3hr4DjxqRUGdTZXrJB5gyQUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2Ni +[2018.11.29-17.16.45:445][556]LogHttp: Verbose: 00000231A44827C0: UploadCallback: 131 bytes out of 131 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=131 (<-this will get returned from the callback)) +[2018.11.29-17.16.45:445][556]LogHttp: VeryVerbose: 00000231A44827C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.45:445][556]LogHttp: VeryVerbose: 00000231A44827C0: Sent data (131 bytes) +[2018.11.29-17.16.45:445][556]LogHttp: VeryVerbose: 00000231A44827C0: 'We are completely uploaded and fine' +[2018.11.29-17.16.45:446][556]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:446][556]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: 00000231A44827C0: Received SSL data (5 bytes) +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: 00000231A44827C0: Received header (17 bytes) +[2018.11.29-17.16.45:479][558]LogHttp: Verbose: 00000231A44827C0: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: 00000231A44827C0: Received header (32 bytes) +[2018.11.29-17.16.45:479][558]LogHttp: Verbose: 00000231A44827C0: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: 00000231A44827C0: Received header (37 bytes) +[2018.11.29-17.16.45:479][558]LogHttp: Verbose: 00000231A44827C0: Received response header 'Date: Thu, 29 Nov 2018 17:16:45 GMT'. +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: 00000231A44827C0: Received header (31 bytes) +[2018.11.29-17.16.45:479][558]LogHttp: Verbose: 00000231A44827C0: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: 00000231A44827C0: Received header (50 bytes) +[2018.11.29-17.16.45:479][558]LogHttp: Verbose: 00000231A44827C0: Received response header 'X-Epic-Correlation-ID: FN-3hr4DjxqRUGdTZXrJB5gyQ'. +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: 00000231A44827C0: Received header (52 bytes) +[2018.11.29-17.16.45:479][558]LogHttp: Verbose: 00000231A44827C0: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: 00000231A44827C0: Received header (75 bytes) +[2018.11.29-17.16.45:479][558]LogHttp: Verbose: 00000231A44827C0: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: 00000231A44827C0: Received header (35 bytes) +[2018.11.29-17.16.45:479][558]LogHttp: Verbose: 00000231A44827C0: Received response header 'X-EpicGames-Profile-Revision: 239'. +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: 00000231A44827C0: Received header (21 bytes) +[2018.11.29-17.16.45:479][558]LogHttp: Verbose: 00000231A44827C0: Received response header 'Content-Length: 186'. +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: 00000231A44827C0: Received header (24 bytes) +[2018.11.29-17.16.45:479][558]LogHttp: Verbose: 00000231A44827C0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.45:479][558]LogHttp: Verbose: 00000231A44827C0: Received response header ''. +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: 00000231A44827C0: Received header (2 bytes) +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: 00000231A44827C0: Received data (186 bytes) +[2018.11.29-17.16.45:479][558]LogHttp: Verbose: 00000231A44827C0: ReceiveResponseBodyCallback: 186 bytes out of 186 received. (SizeInBlocks=1, BlockSizeInBytes=186, Response->TotalBytesRead=0, Response->GetContentLength()=186, SizeToDownload=186 (<-this will get returned from the callback)) +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: 00000231A44827C0: 'Connection #7 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.45:479][558]LogHttp: Verbose: Request 00000231A44827C0 (easy handle:0000023181F3AAB0) has completed (code:0) and has been marked as such +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:479][558]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:480][558]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:480][558]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:480][558]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:480][558]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:480][558]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:480][558]LogHttp: 00000231A44827C0: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=239, HTTP code: 200, content length: 186, actual payload size: 186 +[2018.11.29-17.16.45:480][558]LogHttp: Verbose: 00000231A44827C0 Response Header Content-Type: application/json +[2018.11.29-17.16.45:480][558]LogHttp: Verbose: 00000231A44827C0 Response Header Date: Thu, 29 Nov 2018 17:16:45 GMT +[2018.11.29-17.16.45:480][558]LogHttp: Verbose: 00000231A44827C0 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.45:480][558]LogHttp: Verbose: 00000231A44827C0 Response Header X-Epic-Correlation-ID: FN-3hr4DjxqRUGdTZXrJB5gyQ +[2018.11.29-17.16.45:480][558]LogHttp: Verbose: 00000231A44827C0 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.45:480][558]LogHttp: Verbose: 00000231A44827C0 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.45:480][558]LogHttp: Verbose: 00000231A44827C0 Response Header X-EpicGames-Profile-Revision: 239 +[2018.11.29-17.16.45:480][558]LogHttp: Verbose: 00000231A44827C0 Response Header Content-Length: 186 +[2018.11.29-17.16.45:480][558]LogHttp: Verbose: 00000231A44827C0 Response Header Connection: keep-alive +[2018.11.29-17.16.45:480][558]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:480][558]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:480][558]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:491][558]LogProfileSys: UMcpProfile::HandleProfileUpdate updated lock expiration on Account MCP:e6f5091c3b2f4c359cf2aad75c424de0 for ProfileId athena to --- +[2018.11.29-17.16.45:491][558]LogProfileSys: MCP-Profile: Dispatching request to https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=239 +[2018.11.29-17.16.45:496][559]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:497][559]LogHttp: Verbose: 00000231A41D7040: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=239' +[2018.11.29-17.16.45:497][559]LogHttp: Verbose: 00000231A41D7040: Verb='POST' +[2018.11.29-17.16.45:497][559]LogHttp: Verbose: 00000231A41D7040: Custom headers are present +[2018.11.29-17.16.45:497][559]LogHttp: Verbose: 00000231A41D7040: Payload size=132 +[2018.11.29-17.16.45:497][559]LogHttp: Verbose: 00000231A41D7040: Adding header 'Accept: */*' +[2018.11.29-17.16.45:497][559]LogHttp: Verbose: 00000231A41D7040: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.45:497][559]LogHttp: Verbose: 00000231A41D7040: Adding header 'X-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}' +[2018.11.29-17.16.45:497][559]LogHttp: Verbose: 00000231A41D7040: Adding header 'X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119' +[2018.11.29-17.16.45:497][559]LogHttp: Verbose: 00000231A41D7040: Adding header 'X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":241}]' +[2018.11.29-17.16.45:497][559]LogHttp: Verbose: 00000231A41D7040: Adding header 'X-Epic-Correlation-ID: FN-6XMJi7lSZ0edNHkte4RV4Q' +[2018.11.29-17.16.45:497][559]LogHttp: Verbose: 00000231A41D7040: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.45:497][559]LogHttp: Verbose: 00000231A41D7040: Adding header 'Content-Length: 132' +[2018.11.29-17.16.45:497][559]LogHttp: Verbose: 00000231A41D7040: Adding header 'Expect: ' +[2018.11.29-17.16.45:497][559]LogHttp: 00000231A41D7040: Starting POST request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=239' +[2018.11.29-17.16.45:497][559]LogHttp: Verbose: 00000231A41D7040: request (easy handle:00000231BFD15560) has been added to threaded queue for processing +[2018.11.29-17.16.45:512][560]LogHttp: Verbose: 00000231A41D7040: request (easy handle:00000231BFD15560) has started threaded processing +[2018.11.29-17.16.45:512][560]LogHttp: VeryVerbose: 00000231A41D7040: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.45:512][560]LogHttp: VeryVerbose: 00000231A41D7040: 'Re-using existing connection! (#7) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.45:512][560]LogHttp: VeryVerbose: 00000231A41D7040: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#7)' +[2018.11.29-17.16.45:512][560]LogHttp: VeryVerbose: 00000231A41D7040: Sent SSL data (5 bytes) +[2018.11.29-17.16.45:512][560]LogHttp: VeryVerbose: 00000231A41D7040: Sent header (1023 bytes) - POST /fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=239 HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept-Encoding: deflate, gzipAccept: */*Content-Type: application/jsonX-EpicGames-AnalyticsSessionId: {058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}X-EpicGames-GameSessionId: FRONTEND-D82C7D9743CE4BB7F8846694F8B24119X-EpicGames-ProfileRevisions: [{"profileId":"common_public","clientCommandRevision":0},{"profileId":"common_core","clientCommandRevision":30},{"profileId":"athena","clientCommandRevision":241}]X-Epic-Correlation-ID: FN-6XMJi7lSZ0edNHkte4RV4QUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2Ni +[2018.11.29-17.16.45:512][560]LogHttp: Verbose: 00000231A41D7040: UploadCallback: 132 bytes out of 132 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=132 (<-this will get returned from the callback)) +[2018.11.29-17.16.45:512][560]LogHttp: VeryVerbose: 00000231A41D7040: Sent SSL data (5 bytes) +[2018.11.29-17.16.45:512][560]LogHttp: VeryVerbose: 00000231A41D7040: Sent data (132 bytes) +[2018.11.29-17.16.45:512][560]LogHttp: VeryVerbose: 00000231A41D7040: 'We are completely uploaded and fine' +[2018.11.29-17.16.45:512][560]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:512][560]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:561][563]LogHttp: VeryVerbose: 00000231A41D7040: Received SSL data (5 bytes) +[2018.11.29-17.16.45:561][563]LogHttp: VeryVerbose: 00000231A41D7040: Received header (17 bytes) +[2018.11.29-17.16.45:561][563]LogHttp: Verbose: 00000231A41D7040: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.45:561][563]LogHttp: VeryVerbose: 00000231A41D7040: Received header (32 bytes) +[2018.11.29-17.16.45:561][563]LogHttp: Verbose: 00000231A41D7040: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.45:561][563]LogHttp: VeryVerbose: 00000231A41D7040: Received header (37 bytes) +[2018.11.29-17.16.45:561][563]LogHttp: Verbose: 00000231A41D7040: Received response header 'Date: Thu, 29 Nov 2018 17:16:45 GMT'. +[2018.11.29-17.16.45:561][563]LogHttp: VeryVerbose: 00000231A41D7040: Received header (31 bytes) +[2018.11.29-17.16.45:561][563]LogHttp: Verbose: 00000231A41D7040: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.45:561][563]LogHttp: VeryVerbose: 00000231A41D7040: Received header (50 bytes) +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040: Received response header 'X-Epic-Correlation-ID: FN-6XMJi7lSZ0edNHkte4RV4Q'. +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: 00000231A41D7040: Received header (52 bytes) +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: 00000231A41D7040: Received header (75 bytes) +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: 00000231A41D7040: Received header (35 bytes) +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040: Received response header 'X-EpicGames-Profile-Revision: 239'. +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: 00000231A41D7040: Received header (21 bytes) +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040: Received response header 'Content-Length: 186'. +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: 00000231A41D7040: Received header (24 bytes) +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040: Received response header ''. +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: 00000231A41D7040: Received header (2 bytes) +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: 00000231A41D7040: Received data (186 bytes) +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040: ReceiveResponseBodyCallback: 186 bytes out of 186 received. (SizeInBlocks=1, BlockSizeInBytes=186, Response->TotalBytesRead=0, Response->GetContentLength()=186, SizeToDownload=186 (<-this will get returned from the callback)) +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: 00000231A41D7040: 'Connection #7 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: Request 00000231A41D7040 (easy handle:00000231BFD15560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:562][563]LogHttp: 00000231A41D7040: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/profile/e6f5091c3b2f4c359cf2aad75c424de0/client/EquipBattleRoyaleCustomization?profileId=athena&rvn=239, HTTP code: 200, content length: 186, actual payload size: 186 +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040 Response Header Content-Type: application/json +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040 Response Header Date: Thu, 29 Nov 2018 17:16:45 GMT +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040 Response Header X-Epic-Correlation-ID: FN-6XMJi7lSZ0edNHkte4RV4Q +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040 Response Header X-EpicGames-Profile-Revision: 239 +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040 Response Header Content-Length: 186 +[2018.11.29-17.16.45:562][563]LogHttp: Verbose: 00000231A41D7040 Response Header Connection: keep-alive +[2018.11.29-17.16.45:562][563]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:578][564]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.45:578][564]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.45:591][564]LogWebSockets: Verbose: FLwsWebSocket[2]::LwsCallback: Received LWS_CALLBACK_CLIENT_ESTABLISHED, setting State=Connected PreviousState=Connecting +[2018.11.29-17.16.45:591][564]LogProfileSys: UMcpProfile::HandleProfileUpdate updated lock expiration on Account MCP:e6f5091c3b2f4c359cf2aad75c424de0 for ProfileId athena to --- +[2018.11.29-17.16.45:595][565]LogMatchmakingServiceClient: HandleWebSocketConnected - Connected to service +[2018.11.29-17.16.45:595][565]LogMatchmakingServiceClient: StartPinging - Pinging service at interval: 30.00 seconds +[2018.11.29-17.16.45:613][566]LogWebSockets: VeryVerbose: FLwsWebSocket[2]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=56 BytesLeft=0 +[2018.11.29-17.16.45:613][566]LogMatchmakingServiceClient: Verbose: HandleWebSocketMessage - Received message: "{"payload":{"state":"Connecting"},"name":"StatusUpdate"}" +[2018.11.29-17.16.45:613][566]LogMatchmakingServiceClient: HandleStatusUpdateMessage - Handling status update: 'Connecting' +[2018.11.29-17.16.45:613][566]LogMatchmakingServiceClient: HandleConnectingStatusUpdate - Registering with matchmaking service +[2018.11.29-17.16.45:613][566]LogOnlineGame: [UFortMatchmakingV2::OnMatchmakingConnectingStatusUpdatedInternal] Connecting to matchmaking service... +[2018.11.29-17.16.45:661][569]LogWebSockets: VeryVerbose: FLwsWebSocket[2]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=55 BytesLeft=0 +[2018.11.29-17.16.45:661][569]LogMatchmakingServiceClient: Verbose: HandleWebSocketMessage - Received message: "{"payload":{"state":"QueueFull"},"name":"StatusUpdate"}" +[2018.11.29-17.16.45:661][569]LogMatchmakingServiceClient: HandleStatusUpdateMessage - Handling status update: 'QueueFull' +[2018.11.29-17.16.45:661][569]LogMatchmakingServiceClient: ChangeState - 'ConnectingToService' -> 'QueueFull' +[2018.11.29-17.16.45:661][569]LogOnlineGame: [UFortMatchmakingV2::OnMatchmakingStateChangedInternal] OldState: ConnectingToService, NewState: QueueFull +[2018.11.29-17.16.45:662][569]LogOnlineGame: [UFortMatchmakingV2::StartTimeToMatchPhase] Ending Phase: 'ConnectToService' +[2018.11.29-17.16.45:662][569]LogOnlineGame: [UFortMatchmakingV2::StartTimeToMatchPhase] Starting Phase: 'InQueue' +[2018.11.29-17.16.45:662][569]LogMatchmakingServiceClient: HandleQueueFullStatusUpdate - Queue is currently full, waiting to be enqueued +[2018.11.29-17.16.46:280][606]LogXmpp: VeryVerbose: libstrophe[71688] conn debug: SENT: {"Status":"Battle Royale Lobby - 1 / 4","bIsPlaying":false,"bIsJoinable":false,"bHasVoiceSupport":false,"SessionId":"","Properties":{"FortBasicInfo_j":{"homeBaseRating":1},"FortLFG_I":"0","FortPartySize_i":1,"FortSubGame_i":1,"InUnjoinableMatch_b":false,"FortGameplayStats_j":{"state":"","playlist":"None","numKills":0,"bFellToDeath":false},"party.joininfodata.286331153_j":{"sourceId":"e6f5091c3b2f4c359cf2aad75c424de0","sourceDisplayName":"LoadBot07063","sourcePlatform":"WIN","partyId":"C9AE807B4F9D1F30F1535488AB79E7A8","partyTypeId":286331153,"key":"1A9601624B2510433E8340B1FAAD2362","appId":"FortniteDevLatest","buildId":"6834","partyFlags":4,"notAcceptingReason":1}}} +[2018.11.29-17.16.46:280][606]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.16.46:295][607]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::SendFromQueue: Wrote 776 bytes, 0 bytes remaining in this packet +[2018.11.29-17.16.46:361][611]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=985 BytesLeft=0 +[2018.11.29-17.16.46:362][611]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: RECV: {"Status":"Battle Royale Lobby - 1 / 4","bIsPlaying":false,"bIsJoinable":false,"bHasVoiceSupport":false,"SessionId":"","Properties":{"FortBasicInfo_j":{"homeBaseRating":1},"FortLFG_I":"0","FortPartySize_i":1,"FortSubGame_i":1,"InUnjoinableMatch_b":false,"FortGameplayStats_j":{"state":"","playlist":"None","numKills":0,"bFellToDeath":false},"party.joininfodata.286331153_j":{"sourceId":"e6f5091c3b2f4c359cf2aad75c424de0","sourceDisplayName":"LoadBot07063","sourcePlatform":"WIN","partyId":"C9AE807B4F9D1F30F1535488AB79E7A8","partyTypeId":286331153,"key":"1A9601624B2510433E8340B1FAAD2362","appId":"FortniteDevLatest","buildId":"6834","partyFlags":4,"notAcceptingReason":1}}} +[2018.11.29-17.16.46:362][611]LogXmpp: Verbose: Received Strophe XMPP Stanza presence +[2018.11.29-17.16.46:362][611]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.16.46:362][611]LogXmpp: VeryVerbose: presence Stanza handled by Presence +[2018.11.29-17.16.49:661][809]LogWebSockets: VeryVerbose: FLwsWebSocket[2]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=91 BytesLeft=0 +[2018.11.29-17.16.49:662][809]LogWebSockets: VeryVerbose: FLwsWebSocket[2]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=185 BytesLeft=0 +[2018.11.29-17.16.49:662][809]LogMatchmakingServiceClient: Verbose: HandleWebSocketMessage - Received message: "{"payload":{"totalPlayers":1,"connectedPlayers":1,"state":"Waiting"},"name":"StatusUpdate"}" +[2018.11.29-17.16.49:662][809]LogMatchmakingServiceClient: HandleStatusUpdateMessage - Handling status update: 'Waiting' +[2018.11.29-17.16.49:662][809]LogMatchmakingServiceClient: HandleWaitingStatusUpdate - 1 / 1 players connected +[2018.11.29-17.16.49:662][809]LogMatchmakingServiceClient: ChangeState - 'QueueFull' -> 'WaitingForParty' +[2018.11.29-17.16.49:662][809]LogOnlineGame: [UFortMatchmakingV2::OnMatchmakingStateChangedInternal] OldState: QueueFull, NewState: WaitingForParty +[2018.11.29-17.16.49:662][809]LogOnlineGame: [UFortMatchmakingV2::OnMatchmakingWaitingStatusUpdatedInternal] Received waiting status update +[2018.11.29-17.16.49:662][809]LogMatchmakingServiceClient: Verbose: HandleWebSocketMessage - Received message: "{"payload":{"ticketId":"31632b09f88b3092e8cf1c1865149df8","queuedPlayers":1,"estimatedWaitSec":0,"status":{"ticket.status.canStartMatch":"true"},"state":"Queued"},"name":"StatusUpdate"}" +[2018.11.29-17.16.49:662][809]LogMatchmakingServiceClient: HandleStatusUpdateMessage - Handling status update: 'Queued' +[2018.11.29-17.16.49:662][809]LogMatchmakingServiceClient: HandleQueuedStatusUpdate - TicketId: '31632b09f88b3092e8cf1c1865149df8', NumQueuedPlayers: 1, EstimatedWaitTime: +00:00:00.000 +[2018.11.29-17.16.49:662][809]LogMatchmakingServiceClient: ChangeState - 'WaitingForParty' -> 'InQueue' +[2018.11.29-17.16.49:662][809]LogOnlineGame: [UFortMatchmakingV2::OnMatchmakingStateChangedInternal] OldState: WaitingForParty, NewState: InQueue +[2018.11.29-17.16.49:662][809]LogOnlineGame: [UFortMatchmakingV2::OnMatchmakingQueuedStatusUpdatedInternal] Received queue status update +[2018.11.29-17.16.49:662][809]FortClientBot: Ticket: 31632b09f88b3092e8cf1c1865149df8, InQueue: 1 +[2018.11.29-17.16.49:662][809]FortClientBot: Desired Queue Size of 1 reached! Flushing Queue! +[2018.11.29-17.16.49:662][809]LogMatchmakingServiceClient: Verbose: SendWebSocketMessage - Sending message: "{"name":"Exec","payload":{"command":"flush"}}" +[2018.11.29-17.16.49:695][811]LogWebSockets: VeryVerbose: FLwsWebSocket[2]::SendFromQueue: Wrote 45 bytes, 0 bytes remaining in this packet +[2018.11.29-17.16.49:763][815]LogWebSockets: VeryVerbose: FLwsWebSocket[2]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=108 BytesLeft=0 +[2018.11.29-17.16.49:764][815]LogMatchmakingServiceClient: Verbose: HandleWebSocketMessage - Received message: "{"payload":{"matchId":"41c9ba3d637d965cdd630db02f458cc7","state":"SessionAssignment"},"name":"StatusUpdate"}" +[2018.11.29-17.16.49:764][815]LogMatchmakingServiceClient: HandleStatusUpdateMessage - Handling status update: 'SessionAssignment' +[2018.11.29-17.16.49:764][815]LogMatchmakingServiceClient: HandleSessionAssignmentStatusUpdate - Waiting for session assignment +[2018.11.29-17.16.49:764][815]LogMatchmakingServiceClient: ChangeState - 'InQueue' -> 'InSessionAssignment' +[2018.11.29-17.16.49:764][815]LogOnlineGame: [UFortMatchmakingV2::OnMatchmakingStateChangedInternal] OldState: InQueue, NewState: InSessionAssignment +[2018.11.29-17.16.49:764][815]LogOnlineGame: [UFortMatchmakingV2::StartTimeToMatchPhase] Ending Phase: 'InQueue' +[2018.11.29-17.16.49:764][815]LogOnlineGame: [UFortMatchmakingV2::StartTimeToMatchPhase] Starting Phase: 'InSessionAssignment' +[2018.11.29-17.16.49:764][815]LogOnlineGame: [UFortMatchmakingV2::OnMatchmakingSessionAssignmentStatusUpdatedInternal] Waiting for session assignment... +[2018.11.29-17.16.51:880][942]LogWebSockets: VeryVerbose: FLwsWebSocket[2]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=136 BytesLeft=0 +[2018.11.29-17.16.51:880][942]LogWebSockets: Verbose: FLwsWebSocket[2]::LwsCallback: Received LWS_CALLBACK_WS_PEER_INITIATED_CLOSE, setting State=Closed CloseStatus=1000 Reason=service.success.0 bPeerSpecifiedReason=1 PreviousState=Connected +[2018.11.29-17.16.51:880][942]LogWebSockets: Verbose: Lws(Notice): lws_ws_handshake_client: client_rx_sm exited, DROPPING 1 +[2018.11.29-17.16.51:880][942]LogWebSockets: Verbose: FLwsWebSocket[2]::LwsCallback: Received LWS_CALLBACK_WSI_DESTROY, State=Closed +[2018.11.29-17.16.51:880][942]LogMatchmakingServiceClient: Verbose: HandleWebSocketMessage - Received message: "{"payload":{"matchId":"41c9ba3d637d965cdd630db02f458cc7","sessionId":"f65b90c13f5a4bf285ef088b8cef6283","joinDelaySec":0},"name":"Play"}" +[2018.11.29-17.16.51:880][942]LogMatchmakingServiceClient: HandlePlayMessage - Received session assignment: 'f65b90c13f5a4bf285ef088b8cef6283', JoinDelaySec: 0 +[2018.11.29-17.16.51:881][942]LogWebSockets: Verbose: FLwsWebSocket[2]::GameThreadFinalize: setting State=None PreviousState=Closed +[2018.11.29-17.16.51:881][942]LogMatchmakingServiceClient: HandleWebSocketConnectionClosed - Status: 1000, Message: "service.success.0" +[2018.11.29-17.16.51:881][942]LogMatchmakingServiceClient: StopPinging - Stopping ping timer +[2018.11.29-17.16.51:881][942]LogMatchmakingServiceClient: HandleWebSocketConnectionClosed - Throttling server join request by 0.000000 seconds +[2018.11.29-17.16.51:881][942]LogMatchmakingServiceClient: HandleWebSocketConnectionClosed - Join delay elapsed! +[2018.11.29-17.16.51:881][942]LogMatchmakingServiceClient: ChangeState - 'InSessionAssignment' -> 'Finished' +[2018.11.29-17.16.51:881][942]LogOnlineGame: [UFortMatchmakingV2::OnMatchmakingStateChangedInternal] OldState: InSessionAssignment, NewState: Finished +[2018.11.29-17.16.51:881][942]LogMatchmakingServiceClient: DisconnectFromMatchmakingService - Disconnecting from service +[2018.11.29-17.16.51:881][942]LogWebSockets: VeryVerbose: FLwsWebSocket[2]: Destroyed +[2018.11.29-17.16.51:881][942]LogMatchmakingServiceClient: Finalize - bSuccess: 1 +[2018.11.29-17.16.51:881][942]LogOnlineGame: [UFortMatchmakingV2::StartTimeToMatchPhase] Ending Phase: 'InSessionAssignment' +[2018.11.29-17.16.51:881][942]LogOnlineGame: [UFortMatchmakingV2::StartTimeToMatchPhase] Starting Phase: 'JoinSession' +[2018.11.29-17.16.51:881][942]LogOnlineParty: Verbose: OSS: UpdatePartyData request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.51:882][942]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.51:882][942]LogOnlineSession: OSS: Sending Find Single Session request. url=https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/matchmaking/session/f65b90c13f5a4bf285ef088b8cef6283, sessionid=f65b90c13f5a4bf285ef088b8cef6283 +[2018.11.29-17.16.51:882][942]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.data user=e6f5091c3b2f4c359cf2aad75c424de0 to all +[2018.11.29-17.16.51:882][942]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.51:882][942]LogHttp: Verbose: 00000231F147E5C0: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/matchmaking/session/f65b90c13f5a4bf285ef088b8cef6283' +[2018.11.29-17.16.51:882][942]LogHttp: Verbose: 00000231F147E5C0: Verb='GET' +[2018.11.29-17.16.51:882][942]LogHttp: Verbose: 00000231F147E5C0: Custom headers are present +[2018.11.29-17.16.51:882][942]LogHttp: Verbose: 00000231F147E5C0: Payload size=0 +[2018.11.29-17.16.51:882][942]LogHttp: Verbose: 00000231F147E5C0: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.51:882][942]LogHttp: Verbose: 00000231F147E5C0: Adding header 'X-Epic-Correlation-ID: FN-Ww29iC9aoECdhAsUHgCtdA' +[2018.11.29-17.16.51:882][942]LogHttp: Verbose: 00000231F147E5C0: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.51:883][942]LogHttp: Verbose: 00000231F147E5C0: Adding header 'Content-Length: 0' +[2018.11.29-17.16.51:883][942]LogHttp: Verbose: 00000231F147E5C0: Adding header 'Expect: ' +[2018.11.29-17.16.51:883][942]LogHttp: 00000231F147E5C0: Starting GET request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/matchmaking/session/f65b90c13f5a4bf285ef088b8cef6283' +[2018.11.29-17.16.51:883][942]LogHttp: Verbose: 00000231F147E5C0: request (easy handle:00000231A23DAAB0) has been added to threaded queue for processing +[2018.11.29-17.16.51:912][944]LogHttp: Verbose: 00000231F147E5C0: request (easy handle:00000231A23DAAB0) has started threaded processing +[2018.11.29-17.16.51:912][944]LogHttp: VeryVerbose: 00000231F147E5C0: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.51:912][944]LogHttp: VeryVerbose: 00000231F147E5C0: 'Re-using existing connection! (#7) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.51:912][944]LogHttp: VeryVerbose: 00000231F147E5C0: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#7)' +[2018.11.29-17.16.51:912][944]LogHttp: VeryVerbose: 00000231F147E5C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.51:912][944]LogHttp: VeryVerbose: 00000231F147E5C0: Sent header (1023 bytes) - GET /fortnite/api/matchmaking/session/f65b90c13f5a4bf285ef088b8cef6283 HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/jsonX-Epic-Correlation-ID: FN-Ww29iC9aoECdhAsUHgCtdAUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRd +[2018.11.29-17.16.51:982][948]LogHttp: VeryVerbose: 00000231F147E5C0: Received SSL data (5 bytes) +[2018.11.29-17.16.51:982][948]LogHttp: VeryVerbose: 00000231F147E5C0: Received header (17 bytes) +[2018.11.29-17.16.51:982][948]LogHttp: Verbose: 00000231F147E5C0: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.51:982][948]LogHttp: VeryVerbose: 00000231F147E5C0: Received header (32 bytes) +[2018.11.29-17.16.51:982][948]LogHttp: Verbose: 00000231F147E5C0: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.51:982][948]LogHttp: VeryVerbose: 00000231F147E5C0: Received header (37 bytes) +[2018.11.29-17.16.51:982][948]LogHttp: Verbose: 00000231F147E5C0: Received response header 'Date: Thu, 29 Nov 2018 17:16:51 GMT'. +[2018.11.29-17.16.51:983][948]LogHttp: VeryVerbose: 00000231F147E5C0: Received header (31 bytes) +[2018.11.29-17.16.51:983][948]LogHttp: Verbose: 00000231F147E5C0: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.51:983][948]LogHttp: VeryVerbose: 00000231F147E5C0: Received header (50 bytes) +[2018.11.29-17.16.51:983][948]LogHttp: Verbose: 00000231F147E5C0: Received response header 'X-Epic-Correlation-ID: FN-Ww29iC9aoECdhAsUHgCtdA'. +[2018.11.29-17.16.51:983][948]LogHttp: VeryVerbose: 00000231F147E5C0: Received header (52 bytes) +[2018.11.29-17.16.51:983][948]LogHttp: Verbose: 00000231F147E5C0: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.51:983][948]LogHttp: VeryVerbose: 00000231F147E5C0: Received header (75 bytes) +[2018.11.29-17.16.51:983][948]LogHttp: Verbose: 00000231F147E5C0: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.51:983][948]LogHttp: VeryVerbose: 00000231F147E5C0: Received header (21 bytes) +[2018.11.29-17.16.51:983][948]LogHttp: Verbose: 00000231F147E5C0: Received response header 'Content-Length: 926'. +[2018.11.29-17.16.51:983][948]LogHttp: VeryVerbose: 00000231F147E5C0: Received header (24 bytes) +[2018.11.29-17.16.51:983][948]LogHttp: Verbose: 00000231F147E5C0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.51:983][948]LogHttp: Verbose: 00000231F147E5C0: Received response header ''. +[2018.11.29-17.16.51:984][948]LogHttp: VeryVerbose: 00000231F147E5C0: Received header (2 bytes) +[2018.11.29-17.16.51:984][948]LogHttp: VeryVerbose: 00000231F147E5C0: Received data (926 bytes) +[2018.11.29-17.16.51:984][948]LogHttp: Verbose: 00000231F147E5C0: ReceiveResponseBodyCallback: 926 bytes out of 926 received. (SizeInBlocks=1, BlockSizeInBytes=926, Response->TotalBytesRead=0, Response->GetContentLength()=926, SizeToDownload=926 (<-this will get returned from the callback)) +[2018.11.29-17.16.51:984][948]LogHttp: VeryVerbose: 00000231F147E5C0: 'Connection #7 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.51:984][948]LogHttp: Verbose: Request 00000231F147E5C0 (easy handle:00000231A23DAAB0) has completed (code:0) and has been marked as such +[2018.11.29-17.16.51:984][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.51:984][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.51:984][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.51:985][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.51:985][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.51:985][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.51:985][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.51:985][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.51:985][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.51:985][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.51:985][948]LogHttp: 00000231F147E5C0: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/matchmaking/session/f65b90c13f5a4bf285ef088b8cef6283, HTTP code: 200, content length: 926, actual payload size: 926 +[2018.11.29-17.16.51:985][948]LogHttp: Verbose: 00000231F147E5C0 Response Header Content-Type: application/json +[2018.11.29-17.16.51:985][948]LogHttp: Verbose: 00000231F147E5C0 Response Header Date: Thu, 29 Nov 2018 17:16:51 GMT +[2018.11.29-17.16.51:985][948]LogHttp: Verbose: 00000231F147E5C0 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.51:985][948]LogHttp: Verbose: 00000231F147E5C0 Response Header X-Epic-Correlation-ID: FN-Ww29iC9aoECdhAsUHgCtdA +[2018.11.29-17.16.51:985][948]LogHttp: Verbose: 00000231F147E5C0 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.51:985][948]LogHttp: Verbose: 00000231F147E5C0 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.51:985][948]LogHttp: Verbose: 00000231F147E5C0 Response Header Content-Length: 926 +[2018.11.29-17.16.51:985][948]LogHttp: Verbose: 00000231F147E5C0 Response Header Connection: keep-alive +[2018.11.29-17.16.51:985][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.51:986][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.51:986][948]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.52:012][950]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.52:012][950]LogOnlineGame: Verbose: MCP-Utils: Dispatching request to https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/matchmaking/account/e6f5091c3b2f4c359cf2aad75c424de0/session/f65b90c13f5a4bf285ef088b8cef6283 +[2018.11.29-17.16.52:012][950]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.52:012][950]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.52:012][950]LogHttp: Verbose: 00000231F1479E80: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/matchmaking/account/e6f5091c3b2f4c359cf2aad75c424de0/session/f65b90c13f5a4bf285ef088b8cef6283' +[2018.11.29-17.16.52:012][950]LogHttp: Verbose: 00000231F1479E80: Verb='GET' +[2018.11.29-17.16.52:012][950]LogHttp: Verbose: 00000231F1479E80: Custom headers are present +[2018.11.29-17.16.52:012][950]LogHttp: Verbose: 00000231F1479E80: Payload size=0 +[2018.11.29-17.16.52:012][950]LogHttp: Verbose: 00000231F1479E80: Adding header 'X-Epic-Correlation-ID: FORT-41E41BD2497BF9A8E766888D795C1149' +[2018.11.29-17.16.52:012][950]LogHttp: Verbose: 00000231F1479E80: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.52:012][950]LogHttp: Verbose: 00000231F1479E80: Adding header 'Content-Length: 0' +[2018.11.29-17.16.52:012][950]LogHttp: Verbose: 00000231F1479E80: Adding header 'Expect: ' +[2018.11.29-17.16.52:012][950]LogHttp: 00000231F1479E80: Starting GET request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/matchmaking/account/e6f5091c3b2f4c359cf2aad75c424de0/session/f65b90c13f5a4bf285ef088b8cef6283' +[2018.11.29-17.16.52:012][950]LogHttp: Verbose: 00000231F1479E80: request (easy handle:00000231F8455560) has been added to threaded queue for processing +[2018.11.29-17.16.52:045][952]LogHttp: Verbose: 00000231F1479E80: request (easy handle:00000231F8455560) has started threaded processing +[2018.11.29-17.16.52:045][952]LogHttp: VeryVerbose: 00000231F1479E80: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.52:045][952]LogHttp: VeryVerbose: 00000231F1479E80: 'Re-using existing connection! (#7) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.52:045][952]LogHttp: VeryVerbose: 00000231F1479E80: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#7)' +[2018.11.29-17.16.52:045][952]LogHttp: VeryVerbose: 00000231F1479E80: Sent SSL data (5 bytes) +[2018.11.29-17.16.52:045][952]LogHttp: VeryVerbose: 00000231F1479E80: Sent header (1023 bytes) - GET /fortnite/api/game/v2/matchmaking/account/e6f5091c3b2f4c359cf2aad75c424de0/session/f65b90c13f5a4bf285ef088b8cef6283 HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FORT-41E41BD2497BF9A8E766888D795C1149User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1 +[2018.11.29-17.16.52:196][961]LogHttp: VeryVerbose: 00000231F1479E80: Received SSL data (5 bytes) +[2018.11.29-17.16.52:196][961]LogHttp: VeryVerbose: 00000231F1479E80: Received header (17 bytes) +[2018.11.29-17.16.52:196][961]LogHttp: Verbose: 00000231F1479E80: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.16.52:196][961]LogHttp: VeryVerbose: 00000231F1479E80: Received header (32 bytes) +[2018.11.29-17.16.52:196][961]LogHttp: Verbose: 00000231F1479E80: Received response header 'Content-Type: application/json'. +[2018.11.29-17.16.52:196][961]LogHttp: VeryVerbose: 00000231F1479E80: Received header (37 bytes) +[2018.11.29-17.16.52:196][961]LogHttp: Verbose: 00000231F1479E80: Received response header 'Date: Thu, 29 Nov 2018 17:16:52 GMT'. +[2018.11.29-17.16.52:196][961]LogHttp: VeryVerbose: 00000231F1479E80: Received header (31 bytes) +[2018.11.29-17.16.52:196][961]LogHttp: Verbose: 00000231F1479E80: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.52:196][961]LogHttp: VeryVerbose: 00000231F1479E80: Received header (62 bytes) +[2018.11.29-17.16.52:196][961]LogHttp: Verbose: 00000231F1479E80: Received response header 'X-Epic-Correlation-ID: FORT-41E41BD2497BF9A8E766888D795C1149'. +[2018.11.29-17.16.52:196][961]LogHttp: VeryVerbose: 00000231F1479E80: Received header (52 bytes) +[2018.11.29-17.16.52:196][961]LogHttp: Verbose: 00000231F1479E80: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: 00000231F1479E80: Received header (75 bytes) +[2018.11.29-17.16.52:197][961]LogHttp: Verbose: 00000231F1479E80: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: 00000231F1479E80: Received header (21 bytes) +[2018.11.29-17.16.52:197][961]LogHttp: Verbose: 00000231F1479E80: Received response header 'Content-Length: 148'. +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: 00000231F1479E80: Received header (24 bytes) +[2018.11.29-17.16.52:197][961]LogHttp: Verbose: 00000231F1479E80: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.52:197][961]LogHttp: Verbose: 00000231F1479E80: Received response header ''. +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: 00000231F1479E80: Received header (2 bytes) +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: 00000231F1479E80: Received data (148 bytes) +[2018.11.29-17.16.52:197][961]LogHttp: Verbose: 00000231F1479E80: ReceiveResponseBodyCallback: 148 bytes out of 148 received. (SizeInBlocks=1, BlockSizeInBytes=148, Response->TotalBytesRead=0, Response->GetContentLength()=148, SizeToDownload=148 (<-this will get returned from the callback)) +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: 00000231F1479E80: 'Connection #7 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.52:197][961]LogHttp: Verbose: Request 00000231F1479E80 (easy handle:00000231F8455560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:197][961]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:197][961]LogHttp: 00000231F1479E80: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/game/v2/matchmaking/account/e6f5091c3b2f4c359cf2aad75c424de0/session/f65b90c13f5a4bf285ef088b8cef6283, HTTP code: 200, content length: 148, actual payload size: 148 +[2018.11.29-17.16.52:197][961]LogHttp: Verbose: 00000231F1479E80 Response Header Content-Type: application/json +[2018.11.29-17.16.52:197][961]LogHttp: Verbose: 00000231F1479E80 Response Header Date: Thu, 29 Nov 2018 17:16:52 GMT +[2018.11.29-17.16.52:197][961]LogHttp: Verbose: 00000231F1479E80 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.52:197][961]LogHttp: Verbose: 00000231F1479E80 Response Header X-Epic-Correlation-ID: FORT-41E41BD2497BF9A8E766888D795C1149 +[2018.11.29-17.16.52:197][961]LogHttp: Verbose: 00000231F1479E80 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.52:198][961]LogHttp: Verbose: 00000231F1479E80 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.52:198][961]LogHttp: Verbose: 00000231F1479E80 Response Header Content-Length: 148 +[2018.11.29-17.16.52:198][961]LogHttp: Verbose: 00000231F1479E80 Response Header Connection: keep-alive +[2018.11.29-17.16.52:198][961]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.52:213][962]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:213][962]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.52:214][962]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.52:214][962]LogOnlineSession: OSS: Sending JoinInternetSession request. url=https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/matchmaking/session/f65b90c13f5a4bf285ef088b8cef6283/join?accountId=e6f5091c3b2f4c359cf2aad75c424de0 +[2018.11.29-17.16.52:214][962]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.52:214][962]LogHttp: Verbose: 00000231F1474340: URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/matchmaking/session/f65b90c13f5a4bf285ef088b8cef6283/join?accountId=e6f5091c3b2f4c359cf2aad75c424de0' +[2018.11.29-17.16.52:214][962]LogHttp: Verbose: 00000231F1474340: Verb='POST' +[2018.11.29-17.16.52:214][962]LogHttp: Verbose: 00000231F1474340: Custom headers are present +[2018.11.29-17.16.52:214][962]LogHttp: Verbose: 00000231F1474340: Payload size=0 +[2018.11.29-17.16.52:214][962]LogHttp: Verbose: 00000231F1474340: Adding header 'Content-Type: application/json' +[2018.11.29-17.16.52:214][962]LogHttp: Verbose: 00000231F1474340: Adding header 'X-Epic-Correlation-ID: FN-WhhdoIPCK06eW_Zmatma8Q' +[2018.11.29-17.16.52:214][962]LogHttp: Verbose: 00000231F1474340: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.52:214][962]LogHttp: Verbose: 00000231F1474340: Adding header 'Content-Length: 0' +[2018.11.29-17.16.52:215][962]LogHttp: Verbose: 00000231F1474340: Adding header 'Expect: ' +[2018.11.29-17.16.52:215][962]LogHttp: 00000231F1474340: Starting POST request to URL='https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/matchmaking/session/f65b90c13f5a4bf285ef088b8cef6283/join?accountId=e6f5091c3b2f4c359cf2aad75c424de0' +[2018.11.29-17.16.52:215][962]LogHttp: Verbose: 00000231F1474340: request (easy handle:00000231936D5560) has been added to threaded queue for processing +[2018.11.29-17.16.52:229][963]LogHttp: Verbose: 00000231F1474340: request (easy handle:00000231936D5560) has started threaded processing +[2018.11.29-17.16.52:229][963]LogHttp: VeryVerbose: 00000231F1474340: 'Found bundle for host fortnite-public-service-latest-gamedev.ol.epicgames.net: 0x2318b9f7900 [can pipeline]' +[2018.11.29-17.16.52:229][963]LogHttp: VeryVerbose: 00000231F1474340: 'Re-using existing connection! (#7) with host fortnite-public-service-latest-gamedev.ol.epicgames.net' +[2018.11.29-17.16.52:230][963]LogHttp: VeryVerbose: 00000231F1474340: 'Connected to fortnite-public-service-latest-gamedev.ol.epicgames.net (10.40.132.204) port 443 (#7)' +[2018.11.29-17.16.52:230][963]LogHttp: VeryVerbose: 00000231F1474340: Sent SSL data (5 bytes) +[2018.11.29-17.16.52:230][963]LogHttp: VeryVerbose: 00000231F1474340: Sent header (1023 bytes) - POST /fortnite/api/matchmaking/session/f65b90c13f5a4bf285ef088b8cef6283/join?accountId=e6f5091c3b2f4c359cf2aad75c424de0 HTTP/1.1Host: fortnite-public-service-latest-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/jsonX-Epic-Correlation-ID: FN-WhhdoIPCK06eW_Zmatma8QUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJn +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: 00000231F1474340: Received SSL data (5 bytes) +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: 00000231F1474340: Received header (25 bytes) +[2018.11.29-17.16.52:662][989]LogHttp: Verbose: 00000231F1474340: Received response header 'HTTP/1.1 204 No Content'. +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: 00000231F1474340: Received header (37 bytes) +[2018.11.29-17.16.52:662][989]LogHttp: Verbose: 00000231F1474340: Received response header 'Date: Thu, 29 Nov 2018 17:16:52 GMT'. +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: 00000231F1474340: Received header (31 bytes) +[2018.11.29-17.16.52:662][989]LogHttp: Verbose: 00000231F1474340: Received response header 'Server: Jetty(9.4.z-SNAPSHOT)'. +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: 00000231F1474340: Received header (50 bytes) +[2018.11.29-17.16.52:662][989]LogHttp: Verbose: 00000231F1474340: Received response header 'X-Epic-Correlation-ID: FN-WhhdoIPCK06eW_Zmatma8Q'. +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: 00000231F1474340: Received header (52 bytes) +[2018.11.29-17.16.52:662][989]LogHttp: Verbose: 00000231F1474340: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: 00000231F1474340: Received header (75 bytes) +[2018.11.29-17.16.52:662][989]LogHttp: Verbose: 00000231F1474340: Received response header 'X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424'. +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: 00000231F1474340: Received header (24 bytes) +[2018.11.29-17.16.52:662][989]LogHttp: Verbose: 00000231F1474340: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.52:662][989]LogHttp: Verbose: 00000231F1474340: Received response header ''. +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: 00000231F1474340: Received header (2 bytes) +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: 00000231F1474340: 'Connection #7 to host fortnite-public-service-latest-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.16.52:662][989]LogHttp: Verbose: Request 00000231F1474340 (easy handle:00000231936D5560) has completed (code:0) and has been marked as such +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:662][989]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:662][989]LogHttp: 00000231F1474340: request has been successfully processed. URL: https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/matchmaking/session/f65b90c13f5a4bf285ef088b8cef6283/join?accountId=e6f5091c3b2f4c359cf2aad75c424de0, HTTP code: 204, content length: 0, actual payload size: 0 +[2018.11.29-17.16.52:662][989]LogHttp: Verbose: 00000231F1474340 Response Header Date: Thu, 29 Nov 2018 17:16:52 GMT +[2018.11.29-17.16.52:662][989]LogHttp: Verbose: 00000231F1474340 Response Header Server: Jetty(9.4.z-SNAPSHOT) +[2018.11.29-17.16.52:662][989]LogHttp: Verbose: 00000231F1474340 Response Header X-Epic-Correlation-ID: FN-WhhdoIPCK06eW_Zmatma8Q +[2018.11.29-17.16.52:663][989]LogHttp: Verbose: 00000231F1474340 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.16.52:663][989]LogHttp: Verbose: 00000231F1474340 Response Header X-EpicGames-McpVersion: gamedevlatest Main-dev.main build 4786 cl 4610424 +[2018.11.29-17.16.52:663][989]LogHttp: Verbose: 00000231F1474340 Response Header Connection: keep-alive +[2018.11.29-17.16.52:663][989]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.52:679][990]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.52:680][990]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.52:680][990]LogOnlineSession: OSS: JoinSessionUrl request complete. url=https://fortnite-public-service-latest-gamedev.ol.epicgames.net/fortnite/api/matchmaking/session/f65b90c13f5a4bf285ef088b8cef6283/join?accountId=e6f5091c3b2f4c359cf2aad75c424de0 code=204 response= +[2018.11.29-17.16.52:696][991]LogOnlineGame: [UFortMatchmakingV2::OnJoinSessionComplete] Result: Success +[2018.11.29-17.16.52:696][991]LogOnlineGame: [UFortMatchmakingV2::StartTimeToMatchPhase] Ending Phase: 'JoinSession' +[2018.11.29-17.16.52:696][991]LogOnlineGame: [UFortMatchmakingV2::StartTimeToMatchPhase] Starting Phase: 'LoadMap' +[2018.11.29-17.16.52:696][991]FortClientBot: {"event": "StateChange", "oldstate": "LookingForMatch", "newstate": "InLobby", "bot": "LoadBot07063", "timeinstate":7.400} +[2018.11.29-17.16.52:696][991]LogParty: Verbose: Party [C9AE807B4F9D1F30F1535488AB79E7A8, LocalOwner (LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0)), Leader (LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0))] attempting to update party config +[2018.11.29-17.16.52:696][991]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.updatepartyconfiguration user=e6f5091c3b2f4c359cf2aad75c424de0 to=all payload={"partyId":"C9AE807B4F9D1F30F1535488AB79E7A8","presencePermissions":-1834389757,"invitePermissions":32515,"partyFlags":3,"notAcceptingMembersReason":0,"maxMembers":4,"password":"","accessKey":"1A9601624B2510433E8340B1FAAD2362"} +[2018.11.29-17.16.52:696][991]LogOnlineParty: Display: OSS: Publishing party to presence PartyId(C9AE807B4F9D1F30F1535488AB79E7A8) AccessKey(1A9601624B2510433E8340B1FAAD2362) HasPassword(0) IsAcceptingMembers(1) NotAcceptingReason(0) +[2018.11.29-17.16.52:696][991]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::PublishPartyInfoToPresence success to publish presence user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.52:696][991]LogOnlineParty: Verbose: OSS: UpdateParty request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.52:696][991]LogParty: Verbose: [C9AE807B4F9D1F30F1535488AB79E7A8] Party config updated Succeeded +[2018.11.29-17.16.52:697][991]LogOnlineGame: [UFortMatchmakingV2::CleanupMatchmaking] Cleaning up matchmaking session +[2018.11.29-17.16.52:697][991]LogOnlineParty: Verbose: OSS: UpdatePartyData request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.52:708][991]LogGameMode: Display: Match State Changed from InProgress to LeavingMap +[2018.11.29-17.16.52:708][991]LogGameState: Match State Changed from InProgress to LeavingMap +[2018.11.29-17.16.52:708][991]LogNet: Browse: 10.1.168.34//Game/Maps/Frontend?EncryptionToken=e6f5091c3b2f4c359cf2aad75c424de0:f65b90c13f5a4bf285ef088b8cef6283 +[2018.11.29-17.16.52:708][991]LogInit: WinSock: Socket queue 1048576 / 1048576 +[2018.11.29-17.16.52:709][991]PacketHandlerLog: Loaded PacketHandler component: OodleHandlerComponent () +[2018.11.29-17.16.52:709][991]PacketHandlerLog: Loaded PacketHandler component: AESHandlerComponent () +[2018.11.29-17.16.52:709][991]PacketHandlerLog: Loaded PacketHandler component: Engine.EngineHandlerComponentFactory (StatelessConnectHandlerComponent) +[2018.11.29-17.16.52:741][991]LogNet: Game client on port 7777, rate 30000 +[2018.11.29-17.16.52:743][991]LogCore: Display: Setting hang detector multiplier to 3.0000s. New hang duration: 90.0000s. New present duration: 0.0000s. +[2018.11.29-17.16.52:743][991]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.52:745][991]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.52:745][991]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.52:745][991]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.52:745][991]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.52:746][991]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.52:746][991]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.52:746][991]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.52:746][991]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.52:746][991]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.52:746][991]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.52:746][991]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.52:746][991]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.52:746][991]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.52:761][992]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.data user=e6f5091c3b2f4c359cf2aad75c424de0 to all +[2018.11.29-17.16.52:794][994]LogHandshake: SendChallengeResponse. Timestamp: 52.642056, Cookie: 059155093048067017143232230233105070241139117177033140033077 +[2018.11.29-17.16.52:879][999]LogNetVersion: DeveloperNetworkVersion: FortniteGame 1.0.0, EngineNetVer: 6, GameNetVer: 0 (Checksum: 842311525) +[2018.11.29-17.16.52:879][999]LogNetVersion: Checksum from delegate: 842311525 +[2018.11.29-17.16.52:879][999]LogNet: UPendingNetGame::SendInitialJoin: Sending hello. [UNetConnection] RemoteAddr: 10.1.168.34:7777, Name: IpConnection_2147478707, Driver: PendingNetDriver IpNetDriver_2147478708, IsServer: NO, PC: NULL, Owner: NULL, UniqueId: INVALID +[2018.11.29-17.16.53:078][ 11]LogOnlineGame: Client adding GameAccountId/AuthTicket for local player to login url. FortGameOptions=[AuthTicket=eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM0RoMXFQVm9LNXp2M1J0TjZCUUM3QUJ1UGJTcTRpdjRjbWJGV3BtXC9CTHRGSjBqVE83ZTJPdkNlcU5rT1AyakFHdFJJYmdXWHBieFZyZzF1WUJGc0g0ZGJHYnhkeEZwR21IZlU5dGRvSUtsWklUcjViazdYNWZVOXQzbXRZeEU0dkF0Mkp0SVY5SjcxSzV1OXVkSnpRWWZVWlJ3YnRkWlJ1U0p2YUREaCtIV3JneFFcL3dNWlp2SEhDeTVnamN5Q1ZMUFMzOHhMdmtJXC9TVG9yMU4yWEFMWFArRFdHdHZveHMwWUZiNUZOalFydnFcLzRibDhEejVScmluTDZWNDUrUnVrOU5hamNXSTZ6UnQxQVZnekF0SlwvcnYzR3lmTko0NjJQVElXT29OR1NkWG54bTVLZHFONUVpVHQ0T0Q0U2JVOE9LSWFINEJyNUM0SXF6VXpvT204S09PVHNWUmVBcW13RnZDOEYzV3RETjZlSnBXR2NVZ3Q3aDViczdpY2FNOVQ1TjNuU1Q4M2pVNUV6OUVjbGZ5WG5hem54NWxsc3FLbXBTUlhDM0JvbUFtVFNuWGFPallTaFpkUnR6b3NTZlBlNHRqVzN0Nll5Qmg5eURBQTZYcURKZWcyTUthUEhPTXRMQXEwdVR5UzNMWXBkZk50OE0rR241eDhSUUJQOXF6N0JhRjVPQlJoREZFKzVOVTlGUnFPUmtlYyt3ZXBjNjNGZkU2OXJveVpwVm45WHBcL0VOK1RNYnF0cEY1UngzVFQwWXV4cWxWbG91TGVVZHVqYjVOaGNrRFwvamp1czExcFlJMFV2NlQzb3VsVG1tdEllWVYwd1dwUEM3Z3g2Mll4OUEzQmZaa0U2OVJoTFI3ZDNkekpmZ2w3Z255RDlOMFpnS1wvbStiOXZQRXZjdUNrNUYzWGR2bnVhQU5ZVE9XRXl0aVUrUkQ0TU5qcnBUcTQ3T2xlR3JLQ0dIcTVGMHZlT0tSMm11cUtvcXZ1Zkx1ZUt4OHZ0NFh0N1phNG52a3ZcL2dKWWl2IiwiaWFpIjoiZTZmNTA5MWMzYjJmNGMzNTljZjJhYWQ3NWM0MjRkZTAiLCJjbHN2YyI6ImZvcnRuaXRlIiwibHB2IjoxNTQzNTExNzc3LCJ0IjoicyIsImljIjp0cnVlLCJleHAiOjE1NDM1NDA1NzcsImlhdCI6MTU0MzUxMTc3NywianRpIjoiY2UzZTg2M2I0NTA2NDQyMWI0NDlmMTcyOWYwNjNmNWYifQ.AQ0XBAer5ZnmzSHTYzFrjeKuvgDS-n1kPlO1m8NGn6RIfRymLo4DuWK_yQTvoKMd1XvRR6wG5qTqtjaiobKxgL8D?ASID={058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}?Platform=WIN?AnalyticsPlat=Windows?bIsFirstServerJoin=1] +[2018.11.29-17.16.53:094][ 12]LogNet: Welcomed by server (Level: /Game/Athena/Maps/Athena_Terrain, Game: /Game/Athena/Athena_GameMode.Athena_GameMode_C) +[2018.11.29-17.16.53:122][ 12]LogFortMemory: UFortAssetManager::ChangeLoadState() changing bundle state to (Client, ClientAthena, Zone) +[2018.11.29-17.16.54:182][ 12]LogLoad: LoadMap: 10.1.168.34//Game/Athena/Maps/Athena_Terrain?EncryptionToken=e6f5091c3b2f4c359cf2aad75c424de0:f65b90c13f5a4bf285ef088b8cef6283?game=/Game/Athena/Athena_GameMode.Athena_GameMode_C +[2018.11.29-17.16.54:183][ 12]LogFort: SetIsDisconnecting: Player Disconnecting State Change OldState: 0 NewState: 1 +[2018.11.29-17.16.54:183][ 12]LogParty: Display: HandleZonePlayerStateRemoved: [MCP:e6f5091c3b2f4c359cf2aad75c424de0] +[2018.11.29-17.16.54:184][ 12]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] AnalyticsET URL:datarouter/api/v1/public/data?SessionID={058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}&AppID=Fortnite.DevLatest&AppVersion=1.0.0 - UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3|e6f5091c3b2f4c359cf2aad75c424de0|e04d67a7-16cd-41f9-b939-be602538533a|fa55e3108f3fc66d6c4ff7eb4398e2a9|&AppEnvironment=datacollector-binary&UploadType=eteventstream. Payload:{"Events":[{"EventName":"Quest.TEMP_QuestGranted","DateOffset":"+00:00:34.232","GameSessionID":"FRONTEND-D82C7D9743CE4BB7F8846694F8B24119","Platform":"Windows","ProviderType":"Client","GameState":"FortGameStateFrontEnd-Athena","TemplateId":"Quest:quest_br_play_min1elimination","ItemId":"4f21ba37-eaeb-4e92-b547-07b3be1a8abc","Type":"AthenaChallengeBundleQuest"},{"EventName":"Quest.TEMP_QuestGranted","DateOffset":"+00:00:34.232","GameSessionID":"FRONTEND-D82C7D9743CE4BB7F8846694F8B24119","Platform":"Windows","ProviderType":"Client","GameState":"FortGameStateFrontEnd-Athena","TemplateId":"Quest:quest_br_dance_scavengerhunt_forbidden","ItemId":"628347ae-37a2-4fe5-900f-d39416aac1bb","Type":"AthenaChallengeBundleQuest"},{"EventName":"Social.PartyPrivacyUpdated","DateOffset":"+00:00:33.730","GameSessionID":"FRONTEND-D82C7D9743CE4BB7F8846694F8B24119","Platform":"Windows","ProviderType":"Client","GameState":"FortGameStateFrontEnd-Athena","PartyType":"Public","IsFriendsOnly":"false","IsInviteOnly":"false","SubGame":"Athena"},{"EventName":"Core.SettingsSnapshot","DateOffset":"+00:00:33.712","GameSessionID":"FRONTEND-D82C7D9743CE4BB7F8846694F8B24119","Platform":"Windows","ProviderType":"Client","GameState":"FortGameStateFrontEnd-Athena","WindowMode":"WindowedFullscreen","DisplayResolution":"1920x1200 16:10","FrameRateLimit":"60 FPS","VideoQuality":"-1","ThreeDResolution":"0.52381","ViewDistance":"far","Shadows":"high","AntiAliasing":"high","Textures":"high","Effects":"high","PostProcessing":"high","VSync":"Off","MotionBlur":"On","ShowGrass":"On","ShowFPS":"Off","Language":"English","Region":"Auto","MouseSensitivityYaw":"0.28","MouseSensitivityPitch":"0.196","ControllerLookSensitivityYaw":"0.5","ControllerLookSensitivityPitch":"0.5","MouseTargetingMultiplier":"1.0","MouseScopedMultiplier":"1.0","GamepadTargetingMultiplier":"0.65","GamepadScopedMultiplier":"0.65","GamepadBuildingMultiplier":"1.0","InvertPitch":"Off","StreamerMode":"Off","HiddenMatchmakingDelay":"0.0","HUDScale":"1.0","ShowViewerCount":"On","FirstPersonCamera":"Off","PeripheralLighting":"On","ShowGlobalChat":"On","ToggleSprint":"Off","SprintByDefault":"Off","SprintCancelsReload":"Off","TapInteract":"Off","ToggleTargeting":"Off","AutoEquipBetterItems":"On","EquipFirstBuildingPieceWhenSwappingQuickbars":"On","EquipFirstBuildingPieceWhenSwappingQuickbarsAthena":"Off","AimAssist":"On","EditModeAimAssist":"On","TurboBuild":"On","AutoChangeMaterial":"On","GamepadAutoRun":"On","CrossplayPreference":"Off","AutoOpenDoors":"Off","AutoPickupWeaponsConsolePC":"Off","AutoSortConsumablesToRight":"Off","EnableTryBuildOnFocus":"Off","EditButtonHoldTime":"0.2","ShowHeadAccessories":"On","ShowBackpack":"On","ForceFeedback":"On","ShadowPlayHighlights":"On","ReplayRecording":"On","ReplayRecordingLargeTeams":"Off","GammaValue":"inf","MusicVolume":"0.5","SoundFXVolume":"0.5","DialogVolume":"0.5","VoiceChatVolume":"1.0","CinematicsVolume":"0.5","Subtitles":"On","Quality":"High","VoiceChat":"On","PushToTalk":"On","VoiceChatInputDevice":"0","VoiceChatOutputDevice":"0","AllowBackgroundAudio":"Off","ColorBlindMode":"Off","ColorBlindStrength":"0.0","IgnoreGamepadInput":"Off","VisualizeSoundEffects":"Off","CampaignInputPreset":"Combat Pro","AthenaInputPreset":"Combat Pro","CPU":"GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz"},{"EventName":"AutoLogin","DateOffset":"+00:00:33.712","GameSessionID":"FRONTEND-D82C7D9743CE4BB7F8846694F8B24119","Platform":"Windows","ProviderType":"Client","GameState":"FortGameStateFrontEnd-Athena","StartTime":"17165851.252937","Duration":"2.707334","Result":"Success","bResultIsFatal":"false"},{"EventName":"UI.InteractivityReport","DateOffset":"+00:00:32.087","GameSessionID":"FRONTEND-D82C7D9743CE4BB7F8846694F8B24119","Platform":"Windows","ProviderType":"Client","GameState":"FortGameStateFrontEnd-Athena","TotalInteractiveTime":"4.93","TotalNonInteractiveTime":"37.689999","Phases":[{"Name":"InitialLoad","TimeSpent":36.07,"Interactable":false,"FirstTime":true},{"Name":"Login","TimeSpent":2.02,"Interactable":true,"FirstTime":true},{"Name":"AthenaGameplay","TimeSpent":2.9,"Interactable":true,"FirstTime":true},{"Name":"LoginToGameModeTransition","TimeSpent":1.62,"Interactable":false,"FirstTime":true},{"Name":"AthenaGameplay","TimeSpent":0,"Interactable":true,"FirstTime":false}]},{"EventName":"Store.CatalogChanged","DateOffset":"+00:00:31.175","GameSessionID":"FRONTEND-D82C7D9743CE4BB7F8846694F8B24119","Platform":"Windows","ProviderType":"Client","GameState":"FortGameStateFrontEnd-Athena","NewOffers":"CardPack_Bronze_Personnel:-1;-1,CardPack_Bronze_Personnel:-1;-1,CardPack_Bronze_Personnel:-1;-1,CardPack_Bronze_Melee:-1;-1,CardPack_Bronze_Ranged:-1;-1,CardPack_Bronze:-1;-1,CardPack_Bronze_Personnel:-1;-1,CardPack_Bronze_Traps:-1;-1,CardPack_Bronze:-1;-1,CardPack_Event_Founders:-1;-1,CardPack_Event_Founders:-1;-1,CardPack_Event_Founders:-1;-1,CardPack_Event_Founders:-1;-1,CardPack_Event_Founders:-1;-1,CardPack_Event_Founders:-1;-1,CardPack_Event_Founders:-1;-1,CardPack_Event_Founders:-1;-1,CardPack_Event_Founders:-1;-1,CardPack_Event_Founders:-1;-1,CardPack_Event_Founders:-1;-1,CardPack_Event_Founders:-1;-1,CardPack_Event_Founders:-1;-1,CardPack_Bronze_Personnel:-1;-1,CardPack_Bronze_Personnel:-1;-1,CardPack_Bronze_Personnel:-1;-1,CardPack_Bronze_Melee:-1;-1,CardPack_Bronze_Ranged:-1;-1,CardPack_Bronze:-1;-1,CardPack_Bronze_Personnel:-1;-1,CardPack_Bronze_Traps:-1;-1,CardPack_Jackpot:-1;-1,CardPack_Bronze:-1;-1,CardPack_Basic:-1;-1,CardPack_Bronze_Personnel:-1;-1,CardPack_Bronze_Ranged:-1;-1,CardPack_Bronze_Personnel:-1;-1,CardPack_Bronze_Personnel:-1;-1,CardPack_Bronze_Melee:-1;-1,CardPack_Bronze_Ranged:-1;-1,CardPack_Bronze:-1;-1,CardPack_Bronze_Personnel:-1;-1,CardPack_Bronze_Traps:-1;-1,CardPack_Bronze:-1;-1,CardPack_Bronze:0;1,CardPack_Bronze_Traps:200;2"},{"EventName":"Athena.MatchmakingClientResult","DateOffset":"+00:00:01.488","GameSessionID":"FRONTEND-D82C7D9743CE4BB7F8846694F8B24119","Platform":"Windows","ProviderType":"Client","GameState":"FortGameStateFrontEnd-Athena","Result":"Success","ErrorCode":"","CancelReason":"Unknown","BuildId":"6834","HotfixId":"0","RegionId":"NONE","PlaylistId":"-1","PlaylistName":"Playlist_DefaultSolo","TicketId":"31632b09f88b3092e8cf1c1865149df8","MatchId":"41c9ba3d637d965cdd630db02f458cc7","SessionId":"f65b90c13f5a4bf285ef088b8cef6283","WaitTimeInSec":"7","SubregionIds":"","PreferredSubregionId":""},{"EventName":"Core.ClientLogout","DateOffset":"+00:00:00.000","GameSessionID":"FRONTEND-D82C7D9743CE4BB7F8846694F8B24119","Platform":"Windows","ProviderType":"Client","GameState":"FortGameStateFrontEnd-Athena","Reason":"Destroyed","Vivox.NumActivations":"0","Vivox.SecondsSpentActivated":"0"}]} +[2018.11.29-17.16.54:185][ 12]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.54:185][ 12]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.54:185][ 12]LogHttp: Verbose: 00000231A1D7A9C0: URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.16.54:185][ 12]LogHttp: Verbose: 00000231A1D7A9C0: Verb='POST' +[2018.11.29-17.16.54:185][ 12]LogHttp: Verbose: 00000231A1D7A9C0: Custom headers are present +[2018.11.29-17.16.54:185][ 12]LogHttp: Verbose: 00000231A1D7A9C0: Payload size=6706 +[2018.11.29-17.16.54:185][ 12]LogHttp: Verbose: 00000231A1D7A9C0: Adding header 'Content-Type: application/json; charset=utf-8' +[2018.11.29-17.16.54:186][ 12]LogHttp: Verbose: 00000231A1D7A9C0: Adding header 'User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.54:186][ 12]LogHttp: Verbose: 00000231A1D7A9C0: Adding header 'Content-Length: 6706' +[2018.11.29-17.16.54:186][ 12]LogHttp: Verbose: 00000231A1D7A9C0: Adding header 'Expect: ' +[2018.11.29-17.16.54:186][ 12]LogHttp: 00000231A1D7A9C0: Starting POST request to URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.16.54:186][ 12]LogHttp: Verbose: 00000231A1D7A9C0: request (easy handle:00000231B4160010) has been added to threaded queue for processing +[2018.11.29-17.16.54:186][ 12]LogConsoleResponse: Scalability mode 1 is now INACTIVE. +[2018.11.29-17.16.54:186][ 12]LogFortPlayerRegistration: UFortRegisteredPlayerInfo::UnbindFromPlayerController trying to initialize ability system actor +[2018.11.29-17.16.54:209][ 12]LogHttp: Verbose: 00000231A1D7A9C0: request (easy handle:00000231B4160010) has started threaded processing +[2018.11.29-17.16.54:209][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'Hostname datarouter.ol.epicgames.com was found in DNS cache' +[2018.11.29-17.16.54:209][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: ' Trying 18.235.16.110...' +[2018.11.29-17.16.54:209][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'TCP_NODELAY set' +[2018.11.29-17.16.54:209][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'Connected to datarouter.ol.epicgames.com (18.235.16.110) port 443 (#15)' +[2018.11.29-17.16.54:220][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'ALPN, offering http/1.1' +[2018.11.29-17.16.54:220][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.16.54:220][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'SSL re-using session ID' +[2018.11.29-17.16.54:220][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.54:220][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.16.54:220][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Sent SSL data (512 bytes) +[2018.11.29-17.16.54:220][ 12]LogGarbage: Collecting garbage (GCheckForIllegalMarkPendingKill = 1) +[2018.11.29-17.16.54:230][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Received SSL data (5 bytes) +[2018.11.29-17.16.54:230][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.16.54:230][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Received SSL data (96 bytes) +[2018.11.29-17.16.54:230][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Received SSL data (5 bytes) +[2018.11.29-17.16.54:230][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.54:230][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Received SSL data (1 bytes) +[2018.11.29-17.16.54:230][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Received SSL data (5 bytes) +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Received SSL data (16 bytes) +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Sent SSL data (1 bytes) +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Sent SSL data (16 bytes) +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'Server certificate:' +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: ' subject: CN=*.ol.epicgames.com' +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: ' start date: Mar 12 00:00:00 2018 GMT' +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: ' expire date: Apr 12 12:00:00 2019 GMT' +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: ' subjectAltName: host "datarouter.ol.epicgames.com" matched cert's "*.ol.epicgames.com"' +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: ' SSL certificate verify ok.' +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Sent header (582 bytes) - POST /datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream HTTP/1.1Host: datarouter.ol.epicgames.comAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/json; charset=utf-8User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Length: 6706 +[2018.11.29-17.16.54:231][ 12]LogHttp: Verbose: 00000231A1D7A9C0: UploadCallback: 6706 bytes out of 6706 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=6706 (<-this will get returned from the callback)) +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.54:231][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Sent data (6706 bytes) +[2018.11.29-17.16.54:232][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'We are completely uploaded and fine' +[2018.11.29-17.16.54:232][ 12]LogGarbage: 9.904810 ms for Verify GC Assumptions +[2018.11.29-17.16.54:266][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Received SSL data (5 bytes) +[2018.11.29-17.16.54:266][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Received header (25 bytes) +[2018.11.29-17.16.54:266][ 12]LogHttp: Verbose: 00000231A1D7A9C0: Received response header 'HTTP/1.1 204 No Content'. +[2018.11.29-17.16.54:266][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Received header (37 bytes) +[2018.11.29-17.16.54:266][ 12]LogHttp: Verbose: 00000231A1D7A9C0: Received response header 'Date: Thu, 29 Nov 2018 17:16:54 GMT'. +[2018.11.29-17.16.54:266][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Received header (24 bytes) +[2018.11.29-17.16.54:266][ 12]LogHttp: Verbose: 00000231A1D7A9C0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.54:266][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Received header (32 bytes) +[2018.11.29-17.16.54:266][ 12]LogHttp: Verbose: 00000231A1D7A9C0: Received response header 'Access-Control-Allow-Origin: *'. +[2018.11.29-17.16.54:266][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Received header (61 bytes) +[2018.11.29-17.16.54:266][ 12]LogHttp: Verbose: 00000231A1D7A9C0: Received response header 'X-Epic-Correlation-ID: 10e5f5c4-ba02-4dcd-bcc0-82f69a43f801'. +[2018.11.29-17.16.54:266][ 12]LogHttp: Verbose: 00000231A1D7A9C0: Received response header ''. +[2018.11.29-17.16.54:266][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Received header (2 bytes) +[2018.11.29-17.16.54:266][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'Connection cache is full, closing the oldest one.' +[2018.11.29-17.16.54:266][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'Closing connection 13' +[2018.11.29-17.16.54:266][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Sent SSL data (5 bytes) +[2018.11.29-17.16.54:266][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.16.54:266][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: Sent SSL data (2 bytes) +[2018.11.29-17.16.54:266][ 12]LogHttp: VeryVerbose: 00000231A1D7A9C0: 'Connection #15 to host datarouter.ol.epicgames.com left intact' +[2018.11.29-17.16.54:266][ 12]LogHttp: Verbose: Request 00000231A1D7A9C0 (easy handle:00000231B4160010) has completed (code:0) and has been marked as such +[2018.11.29-17.16.54:266][ 12]LogGarbage: 33.931446 ms for GC +[2018.11.29-17.16.54:266][ 12]LogGarbage: 0.000604 ms for dissolving GC clusters +[2018.11.29-17.16.54:267][ 12]LogGarbage: 1.026103 ms for Gather Unreachable Objects (63790 objects collected including 0 cluster objects from 0 clusters) +[2018.11.29-17.16.54:317][ 12]LogGarbage: 49.262920 ms for unhashing unreachable objects. Items 63790 (63790/63790) +[2018.11.29-17.16.54:410][ 12]LogGarbage: GC purged 63790 objects (547747 -> 483957) +[2018.11.29-17.16.54:450][ 12]LogUObjectHash: Compacting FUObjectHashTables data took 40.59ms +[2018.11.29-17.16.54:493][ 12]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Athena_Corrupted +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Athena_ForagedItems +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Athena_KillVolumes +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Athena_LocationVolumes +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Athena_POI_Foundations +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Athena_Streaming_Grid +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Audio/Athena_Terrain_Audio +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Background/Athena_Background +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Landscape/Athena_Terrain_LS_00 +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Landscape/Athena_Terrain_LS_01 +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Landscape/Athena_Terrain_LS_02 +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Landscape/Athena_Terrain_LS_03 +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Landscape/Athena_Terrain_LS_04 +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Landscape/Athena_Terrain_LS_05 +[2018.11.29-17.16.54:765][ 12]LogStreaming: Display: /Game/Athena/Maps/Athena_Terrain is prestreaming /Game/Athena/Maps/Streaming/Athena_GameplayActors +[2018.11.29-17.16.56:458][ 12]LogFortWorld: World Generation random stream initialized using seed 1488 +[2018.11.29-17.16.56:488][ 12]LogLevelActorContainer: Created LevelActorCluster (3) for /Game/Athena/Maps/Landscape/Athena_Terrain_LS_00.Athena_Terrain_LS_00:PersistentLevel with 22 objects, 0 referenced clusters and 5 mutable objects. +[2018.11.29-17.16.56:512][ 12]LogLevelActorContainer: Created LevelActorCluster (2) for /Game/Athena/Maps/Background/Athena_Background.Athena_Background:PersistentLevel with 8 objects, 0 referenced clusters and 5 mutable objects. +[2018.11.29-17.16.56:544][ 12]LogLevelActorContainer: Created LevelActorCluster (1) for /Game/Athena/Maps/Athena_Terrain.Athena_Terrain:PersistentLevel with 874 objects, 0 referenced clusters and 280 mutable objects. +[2018.11.29-17.16.56:545][ 12]LogWorld: Bringing World /Game/Athena/Maps/Athena_Terrain.Athena_Terrain up for play (max tick rate 60) at 2018.11.29-12.16.56 +[2018.11.29-17.16.56:562][ 12]LogWorld: Bringing up level for play took: 0.041898 +[2018.11.29-17.16.56:563][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:563][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:563][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.56:563][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.56:563][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.56:563][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:563][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:563][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:563][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.56:563][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:563][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.56:563][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:563][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.56:563][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.56:564][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:565][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:565][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:565][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:565][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:565][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:565][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:565][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:565][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.56:565][ 12]LogOutputDevice: Warning: + +Script Stack (0 frames): + +[2018.11.29-17.16.57:308][ 12]LogStats: FPlatformStackWalk::StackWalkAndDump - 0.743 s +[2018.11.29-17.16.57:308][ 12]LogOutputDevice: Error: === Handled ensure: === +[2018.11.29-17.16.57:308][ 12]LogOutputDevice: Error: +[2018.11.29-17.16.57:308][ 12]LogOutputDevice: Error: Ensure condition failed: OwningFortPlayer [File:d:\Epic\Kairos\FortniteGame\Source\FortniteUI\Private\FortKeybindWidget.cpp] [Line: 567] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: Stack: +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff79731a916 FortniteClient.exe!UFortKeybindWidget::SetupHoldKeybind() [d:\epic\kairos\fortnitegame\source\fortniteui\private\fortkeybindwidget.cpp:567] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff79732cc60 FortniteClient.exe!UFortKeybindWidget::UpdateKeybindWidget() [d:\epic\kairos\fortnitegame\source\fortniteui\private\fortkeybindwidget.cpp:382] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff7972f21fd FortniteClient.exe!UFortKeybindWidget::NativePreConstruct() [d:\epic\kairos\fortnitegame\source\fortniteui\private\fortkeybindwidget.cpp:128] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c3a922 FortniteClient.exe!UUserWidget::OnWidgetRebuilt() [d:\epic\kairos\engine\source\runtime\umg\private\userwidget.cpp:947] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c761f8 FortniteClient.exe!UWidget::TakeWidget_Private() [d:\epic\kairos\engine\source\runtime\umg\private\components\widget.cpp:784] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794be5271 FortniteClient.exe!UHorizontalBoxSlot::BuildSlot() [d:\epic\kairos\engine\source\runtime\umg\private\components\horizontalboxslot.cpp:27] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c47c77 FortniteClient.exe!UHorizontalBox::RebuildWidget() [d:\epic\kairos\engine\source\runtime\umg\private\components\horizontalbox.cpp:64] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c75c02 FortniteClient.exe!UWidget::TakeWidget_Private() [d:\epic\kairos\engine\source\runtime\umg\private\components\widget.cpp:722] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794be6321 FortniteClient.exe!UVerticalBoxSlot::BuildSlot() [d:\epic\kairos\engine\source\runtime\umg\private\components\verticalboxslot.cpp:27] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c50f57 FortniteClient.exe!UVerticalBox::RebuildWidget() [d:\epic\kairos\engine\source\runtime\umg\private\components\verticalbox.cpp:64] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c75c02 FortniteClient.exe!UWidget::TakeWidget_Private() [d:\epic\kairos\engine\source\runtime\umg\private\components\widget.cpp:722] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c5089c FortniteClient.exe!UUserWidget::RebuildWidget() [d:\epic\kairos\engine\source\runtime\umg\private\userwidget.cpp:928] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c75c02 FortniteClient.exe!UWidget::TakeWidget_Private() [d:\epic\kairos\engine\source\runtime\umg\private\components\widget.cpp:722] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794be5511 FortniteClient.exe!UOverlaySlot::BuildSlot() [d:\epic\kairos\engine\source\runtime\umg\private\components\overlayslot.cpp:26] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c4b5c0 FortniteClient.exe!UOverlay::RebuildWidget() [d:\epic\kairos\engine\source\runtime\umg\private\components\overlay.cpp:64] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c75c02 FortniteClient.exe!UWidget::TakeWidget_Private() [d:\epic\kairos\engine\source\runtime\umg\private\components\widget.cpp:722] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c4c7fd FortniteClient.exe!USafeZone::RebuildWidget() [d:\epic\kairos\engine\source\runtime\umg\private\components\safezone.cpp:102] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c75c02 FortniteClient.exe!UWidget::TakeWidget_Private() [d:\epic\kairos\engine\source\runtime\umg\private\components\widget.cpp:722] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c5089c FortniteClient.exe!UUserWidget::RebuildWidget() [d:\epic\kairos\engine\source\runtime\umg\private\userwidget.cpp:928] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c75c02 FortniteClient.exe!UWidget::TakeWidget_Private() [d:\epic\kairos\engine\source\runtime\umg\private\components\widget.cpp:722] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c4abf5 FortniteClient.exe!UNamedSlot::RebuildWidget() [d:\epic\kairos\engine\source\runtime\umg\private\components\namedslot.cpp:51] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c75c02 FortniteClient.exe!UWidget::TakeWidget_Private() [d:\epic\kairos\engine\source\runtime\umg\private\components\widget.cpp:722] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794be5511 FortniteClient.exe!UOverlaySlot::BuildSlot() [d:\epic\kairos\engine\source\runtime\umg\private\components\overlayslot.cpp:26] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c4b5c0 FortniteClient.exe!UOverlay::RebuildWidget() [d:\epic\kairos\engine\source\runtime\umg\private\components\overlay.cpp:64] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c75c02 FortniteClient.exe!UWidget::TakeWidget_Private() [d:\epic\kairos\engine\source\runtime\umg\private\components\widget.cpp:722] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c5089c FortniteClient.exe!UUserWidget::RebuildWidget() [d:\epic\kairos\engine\source\runtime\umg\private\userwidget.cpp:928] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794c75c02 FortniteClient.exe!UWidget::TakeWidget_Private() [d:\epic\kairos\engine\source\runtime\umg\private\components\widget.cpp:722] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff794bdf760 FortniteClient.exe!UUserWidget::AddToScreen() [d:\epic\kairos\engine\source\runtime\umg\private\userwidget.cpp:1109] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff79785930c FortniteClient.exe!UFortUIManagerWidget_NUI::AddUIToViewport() [d:\epic\kairos\fortnitegame\source\fortniteui\private\uimanager\fortuimanagerwidget_nui.cpp:171] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff791814f81 FortniteClient.exe!UFortGameInstance::AddUIToViewport() [d:\epic\kairos\fortnitegame\source\fortnitegame\private\fortgameinstance.cpp:990] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff79183e779 FortniteClient.exe!UFortGameInstance::OnPostLoadMap() [d:\epic\kairos\fortnitegame\source\fortnitegame\private\fortgameinstance.cpp:1018] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff79182166d FortniteClient.exe!TBaseUObjectMethodDelegateInstance<0,UFortGameInstance,void __cdecl(UWorld *)>::ExecuteIfSafe() [d:\epic\kairos\engine\source\runtime\core\public\delegates\delegateinstancesimpl.h:679] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff7962982ce FortniteClient.exe!TBaseMulticastDelegate::Broadcast() [d:\epic\kairos\engine\source\runtime\core\public\delegates\delegatesignatureimpl.inl:974] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff7963052d7 FortniteClient.exe!UEngine::LoadMap() [d:\epic\kairos\engine\source\runtime\engine\private\unrealengine.cpp:12378] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff79633f7b1 FortniteClient.exe!UEngine::TickWorldTravel() [d:\epic\kairos\engine\source\runtime\engine\private\unrealengine.cpp:11840] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff79568caf4 FortniteClient.exe!UGameEngine::Tick() [d:\epic\kairos\engine\source\runtime\engine\private\gameengine.cpp:1579] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff791854697 FortniteClient.exe!UFortEngine::Tick() [d:\epic\kairos\fortnitegame\source\fortnitegame\private\fortengine.cpp:511] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff78fd9885d FortniteClient.exe!FEngineLoop::Tick() [d:\epic\kairos\engine\source\runtime\launch\private\launchengineloop.cpp:3929] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff78fda7c7f FortniteClient.exe!GuardedMain() [d:\epic\kairos\engine\source\runtime\launch\private\launch.cpp:179] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff78fda7d3a FortniteClient.exe!GuardedMainWrapper() [d:\epic\kairos\engine\source\runtime\launch\private\windows\launchwindows.cpp:145] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff78fdb79b1 FortniteClient.exe!WinMain() [d:\epic\kairos\engine\source\runtime\launch\private\windows\launchwindows.cpp:276] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ff798164a52 FortniteClient.exe!__scrt_common_main_seh() [d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ffc1bb71fe4 KERNEL32.DLL!UnknownFunction [] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: [Callstack] 0x00007ffc1bcacb31 ntdll.dll!UnknownFunction [] +[2018.11.29-17.16.57:309][ 12]LogOutputDevice: Error: +[2018.11.29-17.16.57:312][ 12]LogStats: SubmitErrorReport - 0.000 s +[2018.11.29-17.16.57:606][ 12]LogWindows: Warning: CreateProc failed: The system cannot find the file specified. (0x00000002) +[2018.11.29-17.16.57:606][ 12]LogWindows: Warning: URL: ../../../Engine/Binaries/Win64/CrashReportClient.exe "D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Crashes/UE4CC-Windows-C58980F04E9A4CBAD9844196DD30D0F3_0000" -Unattended -AppName=UE4-FortniteGame -CrashGUID=UE4CC-Windows-C58980F04E9A4CBAD9844196DD30D0F3_0000 -DebugSymbols=..\..\..\Engine\Intermediate\Symbols +[2018.11.29-17.16.57:606][ 12]LogStats: SendNewReport - 0.295 s +[2018.11.29-17.16.57:606][ 12]LogStats: FDebug::EnsureFailed - 1.041 s +[2018.11.29-17.16.57:607][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:607][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:607][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:607][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:607][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:607][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:607][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:608][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:608][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:608][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:608][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:608][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:608][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:608][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:608][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:609][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:609][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:609][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:609][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:609][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:609][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:609][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:609][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:610][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:610][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:610][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:610][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:610][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:610][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:610][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:610][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:611][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:611][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:611][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:611][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:611][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:611][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:611][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:611][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:612][ 12]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:612][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:612][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:612][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:613][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:613][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:615][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:615][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:617][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.57:622][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:622][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:622][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:622][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:622][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:622][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:622][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:622][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:622][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:623][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:623][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:623][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:623][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:623][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:623][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:624][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:625][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:625][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:626][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:626][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:626][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:626][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:626][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:626][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:631][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.57:631][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:631][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:632][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:632][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:632][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:632][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:634][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:634][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:634][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:634][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:635][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:635][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:636][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:636][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:636][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:637][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:637][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:637][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:637][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:637][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:637][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:637][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:637][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:637][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:637][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:637][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:637][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:637][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:638][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:638][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:640][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:640][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:642][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:645][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.57:645][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.57:646][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:646][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:646][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:646][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:646][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:646][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:646][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:646][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:646][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:646][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:646][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.57:646][ 12]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.57:647][ 12]LogLoad: Took 3.465249 seconds to LoadMap(/Game/Athena/Maps/Athena_Terrain) +[2018.11.29-17.16.57:668][ 13]LogXmpp: VeryVerbose: libstrophe[71688] conn debug: SENT: {"Status":"Battle Royale Lobby - 1 / 4","bIsPlaying":true,"bIsJoinable":false,"bHasVoiceSupport":false,"SessionId":"f65b90c13f5a4bf285ef088b8cef6283","Properties":{"FortBasicInfo_j":{"homeBaseRating":1},"FortLFG_I":"0","FortPartySize_i":1,"FortSubGame_i":1,"InUnjoinableMatch_b":false,"FortGameplayStats_j":{"state":"","playlist":"None","numKills":0,"bFellToDeath":false},"party.joininfodata.286331153_j":{"sourceId":"e6f5091c3b2f4c359cf2aad75c424de0","sourceDisplayName":"LoadBot07063","sourcePlatform":"WIN","partyId":"C9AE807B4F9D1F30F1535488AB79E7A8","partyTypeId":286331153,"key":"1A9601624B2510433E8340B1FAAD2362","appId":"FortniteDevLatest","buildId":"6834","partyFlags":6,"notAcceptingReason":0}}} +[2018.11.29-17.16.57:668][ 13]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.16.57:668][ 13]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.57:669][ 13]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.57:669][ 13]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.57:669][ 13]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.57:669][ 13]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.57:669][ 13]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.57:669][ 13]LogHttp: 00000231A1D7A9C0: request has been successfully processed. URL: https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream, HTTP code: 204, content length: 0, actual payload size: 0 +[2018.11.29-17.16.57:669][ 13]LogHttp: Verbose: 00000231A1D7A9C0 Response Header Date: Thu, 29 Nov 2018 17:16:54 GMT +[2018.11.29-17.16.57:669][ 13]LogHttp: Verbose: 00000231A1D7A9C0 Response Header Connection: keep-alive +[2018.11.29-17.16.57:669][ 13]LogHttp: Verbose: 00000231A1D7A9C0 Response Header Access-Control-Allow-Origin: * +[2018.11.29-17.16.57:669][ 13]LogHttp: Verbose: 00000231A1D7A9C0 Response Header X-Epic-Correlation-ID: 10e5f5c4-ba02-4dcd-bcc0-82f69a43f801 +[2018.11.29-17.16.57:669][ 13]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.57:693][ 14]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::SendFromQueue: Wrote 807 bytes, 0 bytes remaining in this packet +[2018.11.29-17.16.57:745][ 14]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.57:745][ 14]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.57:745][ 14]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] ET response for [https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream]. Code: 204. Payload: +[2018.11.29-17.16.57:745][ 14]LogFort: Server log filename sent: FortniteGame.log +[2018.11.29-17.16.57:752][ 14]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.57:754][ 14]LogFortPlayerRegistration: BindToPlayerController trying to initialize ability system actor +[2018.11.29-17.16.57:754][ 14]LogFortPlayerRegistration: InitializeAbilitySystemActor initialized with invalid zone state for LoadBot07063! +[2018.11.29-17.16.57:754][ 14]LogFortPlayerRegistration: BindToPlayerController failed to update ability system actor for LoadBot07063. Trying to register to do it later. +[2018.11.29-17.16.57:754][ 14]LogFort: UFortRegisteredPlayerInfo is requesting a refresh for LoadBot07063. +[2018.11.29-17.16.57:754][ 14]LogFort: UFortRegisteredPlayerInfo::SynchronizeProfile is adding FFortProfileSynchronizeRequest : RequestId [2]. +[2018.11.29-17.16.57:754][ 14]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [2]) Request.RequestId [2] initial WaitingFor flags [0]. +[2018.11.29-17.16.57:754][ 14]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [2]) Request.RequestId [2] final WaitingFor flags [0]. +[2018.11.29-17.16.57:754][ 14]LogFort: UFortRegisteredPlayerInfo::UpdateSynchronizeRequest(IN RequestId [2]) is removing FFortProfileSynchronizeRequest : Request.RequestId [2]. +[2018.11.29-17.16.57:754][ 14]LogFort: Initialized MCP profile for Athena_PlayerController_C_2147478528 (force sync: no) +[2018.11.29-17.16.57:754][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:754][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:754][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:754][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:754][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:755][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:755][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:755][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:755][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:755][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:755][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:755][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:755][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:755][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:755][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:755][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:755][ 14]LogConsoleResponse: Display: Apply Settings: +[2018.11.29-17.16.57:755][ 14]LogConfig: Applying CVar settings from Section [ViewDistanceQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.16.57:755][ 14]LogConfig: Setting CVar [[r.SkeletalMeshLODBias:0]] +[2018.11.29-17.16.57:755][ 14]LogConfig: Setting CVar [[r.ViewDistanceScale:1.67]] +[2018.11.29-17.16.57:755][ 14]LogConfig: Setting CVar [[Fort.Scalability.AIBudget:8,16]] +[2018.11.29-17.16.57:755][ 14]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget:5,10,10,75]] +[2018.11.29-17.16.57:755][ 14]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget.URORates:0,1,2,3]] +[2018.11.29-17.16.57:755][ 14]LogConfig: Setting CVar [[Fort.Scalability.AthenaPlayerBudget.SkelMeshMinLOD:0,1,1,2]] +[2018.11.29-17.16.57:755][ 14]LogConfig: Setting CVar [[Fort.Scalability.BucketDistances:50,100,250,500]] +[2018.11.29-17.16.57:755][ 14]LogConfig: Setting CVar [[Fort.Scalability.PlayerCosmeticPropBudget:0]] +[2018.11.29-17.16.57:755][ 14]LogConfig: Setting CVar [[Fort.Scalability.TieUROToLODs:1]] +[2018.11.29-17.16.57:755][ 14]LogConfig: Setting CVar [[Fort.Scalability.EnableAnimCurveOptimizations:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[Athena.Scalability.SecondarySkelMeshTickingThreshold:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[p.AnimDynamicsLODThreshold:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[p.RigidBodyLODThreshold:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.StaticMeshLODDistanceScale:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.ViewDistanceScale.SecondaryScale:1.0]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.HLOD.DistanceOverride:40000,35000]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[Athena.Scalability.HLODProxyMaxDrawDistance:0.0]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMaxAngle:80.0]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMaxAngleScale:1.0]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMinAngle:15.0]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.ViewDistanceScale.FieldOfViewMinAngleScale:2.0]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[Athena.EnableProxyPredictionPawnLOD:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[Athena.EnableProxySimulatedStepUpLOD:0]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[Athena.EnableProxySimulatedStepUpMinNormalZ:0.1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[Athena.ForceThrottledSimulatedFloorChecks:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[Athena.NetworkSmoothingSkipFramesLowestLOD:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[Athena.NetworkSmoothingSkipFramesInvisible:4]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_Players:50]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_AI:50]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[Athena.NetworkSmoothingRelevancyThrottleThreshold_Combined:50]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.NeverOcclusionTestDistance:1250]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[a.Budget.Enabled:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[a.Budget.BudgetMs:1.5]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Applying CVar settings from Section [AntiAliasingQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.PostProcessAAQuality:3]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.Tonemapper.Sharpen:0.5]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Applying CVar settings from Section [ShadowQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.LightFunctionQuality:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.ShadowQuality:5]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.Shadow.CSM.MaxCascades:2]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.Shadow.MaxResolution:1024]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.Shadow.MaxCSMResolution:2048]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.Shadow.RadiusThreshold:0.04]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.Shadow.DistanceScale:0.85]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.Shadow.CSM.TransitionScale:0.8]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.Shadow.PreShadowResolutionFactor:0.5]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.DistanceFieldShadowing:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.DistanceFieldAO:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.AOQuality:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.VolumetricFog:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.VolumetricFog.GridPixelSize:16]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.VolumetricFog.GridSizeZ:64]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.VolumetricFog.HistoryMissSupersampleCount:4]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.LightMaxDrawDistanceScale:.5]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.CapsuleShadows:1]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.SimpleForwardShading:0]] +[2018.11.29-17.16.57:756][ 14]LogConsoleManager: Warning: Setting the console variable 'r.SimpleForwardShading' with 'SetByScalability' was ignored as it is lower priority than the previous 'SetByConsole'. Value remains '0' +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.Shadow.MaxNumPointShadowCacheUpdatesPerFrame:2]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[r.Shadow.MaxNumSpotShadowCacheUpdatesPerFrame:4]] +[2018.11.29-17.16.57:756][ 14]LogConfig: Setting CVar [[Fort.TODDirectionalLightUpdateRate:0]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Applying CVar settings from Section [PostProcessQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.MotionBlurQuality:3]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.AmbientOcclusionMipLevelFactor:0.6]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.AmbientOcclusionMaxQuality:100]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.AmbientOcclusionLevels:-1]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.AmbientOcclusionRadiusScale:1.5]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.DepthOfFieldQuality:2]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.RenderTargetPoolMin:400]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.LensFlareQuality:2]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.SceneColorFringeQuality:1]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.EyeAdaptationQuality:1]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.BloomQuality:5]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.FastBlurThreshold:3]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.Upscale.Quality:2]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.Tonemapper.GrainQuantization:1]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.LightShaftQuality:0]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.Filter.SizeScale:0.8]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.Tonemapper.Quality:5]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.DOF.Gather.AccumulatorQuality:0 ; lower gathering accumulator quality]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.DOF.Gather.PostfilterMethod:2 ; Max3x3 postfilering method]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.DOF.Gather.EnableBokehSettings:0 ; no bokeh simulation when gathering]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.DOF.Gather.RingCount:4 ; medium number of samples when gathering]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.DOF.Scatter.ForegroundCompositing:1 ; additive foreground scattering]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.DOF.Scatter.BackgroundCompositing:1 ; no background occlusion]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.DOF.Scatter.EnableBokehSettings:0 ; no bokeh simulation when scattering]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.DOF.Scatter.MaxSpriteRatio:0.04 ; only a maximum of 4% of scattered bokeh]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.DOF.Recombine.Quality:0 ; no slight out of focus]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.DOF.TemporalAAQuality:0 ; faster temporal accumulation]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.DOF.Kernel.MaxForegroundRadius:0.012 ; required because of AccumulatorQuality=0]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.DOF.Kernel.MaxBackgroundRadius:0.012 ; required because of AccumulatorQuality=0]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.AmbientOcclusion.Compute:0]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Applying CVar settings from Section [TextureQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.Streaming.MipBias:0]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.Streaming.AmortizeCPUToGPUCopy:0]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.Streaming.MaxNumTexturesToStreamPerFrame:0]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.Streaming.Boost:1]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.MaxAnisotropy:4]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.Streaming.LimitPoolSizeToVRAM:1]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.Streaming.PoolSize:800]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.Streaming.MaxEffectiveScreenSize:0]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Applying CVar settings from Section [EffectsQuality@2] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.TranslucencyLightingVolumeDim:48]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.RefractionQuality:2]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.SSR.Quality:2]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.SceneColorFormat:3]] +[2018.11.29-17.16.57:757][ 14]LogConfig: Setting CVar [[r.DetailMode:1]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[r.TranslucencyVolumeBlur:1]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[r.MaterialQualityLevel:1 ; High quality]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[r.SSS.Scale:1]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[r.SSS.SampleSet:1]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[r.SSS.Quality:-1]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[r.SSS.HalfRes:1]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[r.EmitterSpawnRateScale:0.5]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[r.ParticleLightQuality:1]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[Fort.Wind:1]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_Low:0.85]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_Medium:0.7]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[fx.Significance.EmitterLevel_High:0.3]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[fx.Significance.MaxRange:14000]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[p.AnimDynamicsWind:1]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[r.SeparateTranslucency:1]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Applying CVar settings from Section [FoliageQuality@3] File [D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Config/WindowsClient/Scalability.ini] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[foliage.DensityScale:1.0]] +[2018.11.29-17.16.57:758][ 14]LogConfig: Setting CVar [[grass.DensityScale:1.0]] +[2018.11.29-17.16.57:758][ 14]LogRHI: Display: Applied New ShaderPipelineCache GameUsageMask [Material=1 | Shadow=2 | Foliage=3] +[2018.11.29-17.16.57:759][ 14]LogFortChat: *!* UFortChatManager::AttemptJoinReservedChatRooms - SubGame: Athena, DeltaSeconds: 0.000000 +[2018.11.29-17.16.57:759][ 14]LogFortChat: *!* UFortChatManager::AttemptJoinReservedChatRooms - ShouldRequestRooms: 0, ChatRestricted: 0 +[2018.11.29-17.16.57:759][ 14]LogFortChat: NOT joinining general chat, requesting rooms is currently disabled +[2018.11.29-17.16.57:759][ 14]LogFortChat: *!* UFortChatManager::DisableGlobalChatRoom - DisableReason: 1 +[2018.11.29-17.16.57:759][ 14]LogFortChat: *!* UFortChatRoomJoinHelper::DisableChatRoom - DisableReason +[2018.11.29-17.16.57:759][ 14]LogFortChat: *!* UFortChatManager::DisableFounderChatRoom - DisableReason: 1 +[2018.11.29-17.16.57:759][ 14]LogFortChat: *!* UFortChatRoomJoinHelper::DisableChatRoom - DisableReason +[2018.11.29-17.16.57:759][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:759][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:759][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:759][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:759][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:759][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:760][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:760][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:760][ 14]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=1016 BytesLeft=0 +[2018.11.29-17.16.57:760][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:760][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:760][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:760][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:760][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:760][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:760][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:760][ 14]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.16.57:763][ 14]LogFort: ClientOnGenericPlayerInitialization +[2018.11.29-17.16.57:763][ 14]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.16.57:763][ 14]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] team member data updated, team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.16.57:763][ 14]LogParty: Display: Got bad homebase data +[2018.11.29-17.16.57:763][ 14]LogParty: Verbose: Handling party reservation approvals after load into game. +[2018.11.29-17.16.57:764][ 14]LogOnlineGame: Verbose: AFortPlayerController::ClientSetInviteFlags_Implementation called on +[2018.11.29-17.16.57:764][ 14]LogOnlineSession: MCP: UpdateInternetSession complete, skipping online refresh. +[2018.11.29-17.16.57:766][ 14]LogOnlineSession: MCP: Player e6f5091c3b2f4c359cf2aad75c424de0 already registered in session GameSession +[2018.11.29-17.16.57:767][ 14]FortClientBot: Client Smoke Bot received Athena player controller. ShouldExitGameFromLobby set. +[2018.11.29-17.16.57:768][ 14]LogFort: GetOrInitializeHero called with valid player info +[2018.11.29-17.16.57:768][ 14]LogFortPlayerRegistration: BindToState(AFortPlayerState* State) trying to initialize ability system actor +[2018.11.29-17.16.57:768][ 14]LogFortPlayerRegistration: InitializeAbilitySystemActor initialized with valid zone state for LoadBot07063 +[2018.11.29-17.16.57:768][ 14]LogParty: Verbose: PopulateRejoinablePlayersFromPartyState: Adding player MCP:e6f5091c3b2f4c359cf2aad75c424de0 to our rejoinable list +[2018.11.29-17.16.57:768][ 14]LogParty: Verbose: OnRep_PlayerState: No PartyJoinInfo +[2018.11.29-17.16.57:768][ 14]LogFort: AddSquadMember: LoadBot07063 256 [no platform id] +[2018.11.29-17.16.57:770][ 15]LogOnlineParty: Verbose: OSS: UpdatePartyMemberData request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.57:771][ 15]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.16.57:771][ 15]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] team member data updated, team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.16.57:771][ 15]LogParty: Display: Got bad homebase data +[2018.11.29-17.16.57:771][ 15]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.memberdata user=e6f5091c3b2f4c359cf2aad75c424de0 to all +[2018.11.29-17.16.57:771][ 15]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: RECV: {"Status":"Battle Royale Lobby - 1 / 4","bIsPlaying":true,"bIsJoinable":false,"bHasVoiceSupport":false,"SessionId":"f65b90c13f5a4bf285ef088b8cef6283","Properties":{"FortBasicInfo_j":{"homeBaseRating":1},"FortLFG_I":"0","FortPartySize_i":1,"FortSubGame_i":1,"InUnjoinableMatch_b":false,"FortGameplayStats_j":{"state":"","playlist":"None","numKills":0,"bFellToDeath":false},"party.joininfodata.286331153_j":{"sourceId":"e6f5091c3b2f4c359cf2aad75c424de0","sourceDisplayName":"LoadBot07063","sourcePlatform":"WIN","partyId":"C9AE807B4F9D1F30F1535488AB79E7A8","partyTypeId":286331153,"key":"1A9601624B2510433E8340B1FAAD2362","appId":"FortniteDevLatest","buildId":"6834","partyFlags":6,"notAcceptingReason":0}}} +[2018.11.29-17.16.57:771][ 15]LogXmpp: Verbose: Received Strophe XMPP Stanza presence +[2018.11.29-17.16.57:771][ 15]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.16.57:771][ 15]LogXmpp: VeryVerbose: presence Stanza handled by Presence +[2018.11.29-17.16.57:827][ 18]LogParty: Display: HandleZonePlayerStateInitialized: [MCP:e6f5091c3b2f4c359cf2aad75c424de0] +[2018.11.29-17.16.57:830][ 18]LogFort: AddSquadMember: LoadBot07063 256 [no platform id] +[2018.11.29-17.16.57:844][ 18]LogFortMusic: Warning: Trying to assign a bank to a music manager that doesn't yet exist. +[2018.11.29-17.16.57:845][ 18]LogChartCreation: Started creating FPS charts at 17165891.331585 seconds +[2018.11.29-17.16.57:846][ 18]LogHealthSnapshot: ======= Snapshot: Waiting to Start (Athena_GameState_C, Difficulty 0.00) ======= +[2018.11.29-17.16.57:846][ 18]LogHealthSnapshot: Games Played: 0 +[2018.11.29-17.16.57:846][ 18]LogHealthSnapshot: CPU Memory: Used 1212.35MB, Peak 1212.35MB +[2018.11.29-17.16.57:846][ 18]LogHealthSnapshot: Physical Memory: Used 2280.43MB, Peak 2293.81MB +[2018.11.29-17.16.57:846][ 18]LogHealthSnapshot: ========================================================= +[2018.11.29-17.16.57:846][ 18]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] AnalyticsET URL:datarouter/api/v1/public/data?SessionID={058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}&AppID=Fortnite.DevLatest&AppVersion=1.0.0 - UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3|e6f5091c3b2f4c359cf2aad75c424de0|e04d67a7-16cd-41f9-b939-be602538533a|fa55e3108f3fc66d6c4ff7eb4398e2a9|&AppEnvironment=datacollector-binary&UploadType=eteventstream. Payload:{"Events":[{"EventName":"Core.GameSessionIDChanged","DateOffset":"+00:00:00.000","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"FortGameStateFrontEnd-Athena","PreviousGameSessionID":"FRONTEND-D82C7D9743CE4BB7F8846694F8B24119"},{"EventName":"Core.GameStateClassNameChanged","DateOffset":"+00:00:00.000","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","PreviousGameStateClassName":"FortGameStateFrontEnd-Athena"}]} +[2018.11.29-17.16.57:847][ 18]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.57:847][ 18]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.57:847][ 18]LogHttp: Verbose: 00000231F3A6C680: URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.16.57:847][ 18]LogHttp: Verbose: 00000231F3A6C680: Verb='POST' +[2018.11.29-17.16.57:847][ 18]LogHttp: Verbose: 00000231F3A6C680: Custom headers are present +[2018.11.29-17.16.57:847][ 18]LogHttp: Verbose: 00000231F3A6C680: Payload size=555 +[2018.11.29-17.16.57:847][ 18]LogHttp: Verbose: 00000231F3A6C680: Adding header 'Content-Type: application/json; charset=utf-8' +[2018.11.29-17.16.57:847][ 18]LogHttp: Verbose: 00000231F3A6C680: Adding header 'User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.16.57:847][ 18]LogHttp: Verbose: 00000231F3A6C680: Adding header 'Content-Length: 555' +[2018.11.29-17.16.57:847][ 18]LogHttp: Verbose: 00000231F3A6C680: Adding header 'Expect: ' +[2018.11.29-17.16.57:847][ 18]LogHttp: 00000231F3A6C680: Starting POST request to URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.16.57:847][ 18]LogHttp: Verbose: 00000231F3A6C680: request (easy handle:00000231F5BFAAB0) has been added to threaded queue for processing +[2018.11.29-17.16.57:847][ 18]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.16.57:847][ 18]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] team member data updated, team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.16.57:847][ 18]LogParty: Display: Got bad homebase data +[2018.11.29-17.16.57:848][ 18]LogFort: PLAYLIST: Playlist Object replicated to client in AFortGameStateAthena::OnRep_CurrentPlaylistInfo() PlaylistName is Playlist_DefaultSolo (Client Only) +[2018.11.29-17.16.57:848][ 18]LogFort: PLAYLIST: Playlist Object is loading its assets in AFortGameStateAthena::LoadCurrentPlaylistData(), PlaylistName is Playlist_DefaultSolo (Client Side) +[2018.11.29-17.16.57:849][ 18]LogFort: PLAYLIST: Playlist Object finished loading its assets in AFortGameStateAthena::OnPlaylistDataLoadCompleted(), PlaylistName is Playlist_DefaultSolo (Server AND Client) +[2018.11.29-17.16.57:853][ 19]LogOnlineParty: Verbose: OSS: UpdatePartyMemberData request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.57:853][ 19]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.16.57:853][ 19]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] team member data updated, team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.16.57:854][ 19]LogParty: Display: Got bad homebase data +[2018.11.29-17.16.57:854][ 19]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.memberdata user=e6f5091c3b2f4c359cf2aad75c424de0 to all +[2018.11.29-17.16.57:855][ 19]FortClientBot: {"event": "SetDeterministicFlightPath", "bot": "LoadBot07063"} +[2018.11.29-17.16.57:855][ 19]FortClientBot: {"event": "SetCosmetics", "bot": "LoadBot07063"} +[2018.11.29-17.16.57:873][ 21]LogHttp: Verbose: 00000231F3A6C680: request (easy handle:00000231F5BFAAB0) has started threaded processing +[2018.11.29-17.16.57:873][ 21]LogHttp: VeryVerbose: 00000231F3A6C680: 'Found bundle for host datarouter.ol.epicgames.com: 0x231a91dc070 [can pipeline]' +[2018.11.29-17.16.57:873][ 21]LogHttp: VeryVerbose: 00000231F3A6C680: 'Re-using existing connection! (#15) with host datarouter.ol.epicgames.com' +[2018.11.29-17.16.57:873][ 21]LogHttp: VeryVerbose: 00000231F3A6C680: 'Connected to datarouter.ol.epicgames.com (18.235.16.110) port 443 (#15)' +[2018.11.29-17.16.57:873][ 21]LogHttp: VeryVerbose: 00000231F3A6C680: Sent SSL data (5 bytes) +[2018.11.29-17.16.57:873][ 21]LogHttp: VeryVerbose: 00000231F3A6C680: Sent header (581 bytes) - POST /datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream HTTP/1.1Host: datarouter.ol.epicgames.comAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/json; charset=utf-8User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Length: 555 +[2018.11.29-17.16.57:873][ 21]LogHttp: Verbose: 00000231F3A6C680: UploadCallback: 555 bytes out of 555 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=555 (<-this will get returned from the callback)) +[2018.11.29-17.16.57:873][ 21]LogHttp: VeryVerbose: 00000231F3A6C680: Sent SSL data (5 bytes) +[2018.11.29-17.16.57:873][ 21]LogHttp: VeryVerbose: 00000231F3A6C680: Sent data (555 bytes) +[2018.11.29-17.16.57:873][ 21]LogHttp: VeryVerbose: 00000231F3A6C680: 'We are completely uploaded and fine' +[2018.11.29-17.16.57:873][ 21]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.57:873][ 21]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.16.57:891][ 22]LogHttp: VeryVerbose: 00000231F3A6C680: Received SSL data (5 bytes) +[2018.11.29-17.16.57:892][ 22]LogHttp: VeryVerbose: 00000231F3A6C680: Received header (25 bytes) +[2018.11.29-17.16.57:892][ 22]LogHttp: Verbose: 00000231F3A6C680: Received response header 'HTTP/1.1 204 No Content'. +[2018.11.29-17.16.57:892][ 22]LogHttp: VeryVerbose: 00000231F3A6C680: Received header (37 bytes) +[2018.11.29-17.16.57:892][ 22]LogHttp: Verbose: 00000231F3A6C680: Received response header 'Date: Thu, 29 Nov 2018 17:16:57 GMT'. +[2018.11.29-17.16.57:892][ 22]LogHttp: VeryVerbose: 00000231F3A6C680: Received header (24 bytes) +[2018.11.29-17.16.57:892][ 22]LogHttp: Verbose: 00000231F3A6C680: Received response header 'Connection: keep-alive'. +[2018.11.29-17.16.57:892][ 22]LogHttp: VeryVerbose: 00000231F3A6C680: Received header (32 bytes) +[2018.11.29-17.16.57:892][ 22]LogHttp: Verbose: 00000231F3A6C680: Received response header 'Access-Control-Allow-Origin: *'. +[2018.11.29-17.16.57:892][ 22]LogHttp: VeryVerbose: 00000231F3A6C680: Received header (61 bytes) +[2018.11.29-17.16.57:892][ 22]LogHttp: Verbose: 00000231F3A6C680: Received response header 'X-Epic-Correlation-ID: b90e9c05-cc47-4811-893b-e90645aace4c'. +[2018.11.29-17.16.57:892][ 22]LogHttp: Verbose: 00000231F3A6C680: Received response header ''. +[2018.11.29-17.16.57:892][ 22]LogHttp: VeryVerbose: 00000231F3A6C680: Received header (2 bytes) +[2018.11.29-17.16.57:892][ 22]LogHttp: VeryVerbose: 00000231F3A6C680: 'Connection #15 to host datarouter.ol.epicgames.com left intact' +[2018.11.29-17.16.57:892][ 22]LogHttp: Verbose: Request 00000231F3A6C680 (easy handle:00000231F5BFAAB0) has completed (code:0) and has been marked as such +[2018.11.29-17.16.57:893][ 22]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.57:893][ 22]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.57:893][ 22]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.57:893][ 22]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.57:893][ 22]LogHttp: 00000231F3A6C680: request has been successfully processed. URL: https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream, HTTP code: 204, content length: 0, actual payload size: 0 +[2018.11.29-17.16.57:893][ 22]LogHttp: Verbose: 00000231F3A6C680 Response Header Date: Thu, 29 Nov 2018 17:16:57 GMT +[2018.11.29-17.16.57:893][ 22]LogHttp: Verbose: 00000231F3A6C680 Response Header Connection: keep-alive +[2018.11.29-17.16.57:893][ 22]LogHttp: Verbose: 00000231F3A6C680 Response Header Access-Control-Allow-Origin: * +[2018.11.29-17.16.57:893][ 22]LogHttp: Verbose: 00000231F3A6C680 Response Header X-Epic-Correlation-ID: b90e9c05-cc47-4811-893b-e90645aace4c +[2018.11.29-17.16.57:893][ 22]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.57:893][ 22]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.16.57:893][ 22]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.16.57:893][ 22]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] ET response for [https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream]. Code: 204. Payload: +[2018.11.29-17.16.58:374][ 50]LogFortDayNight: AFortTimeOfDayManager::PostInitializeComponents: World is "Athena_Terrain", this is "TODM_BR_C_2147478235" +[2018.11.29-17.16.58:375][ 50]LogFortDayNight: SetupTimeOfDayCallbacks: World is "Athena_Terrain", FortTimeOfDayManager is "TODM_BR_C_2147478235" +[2018.11.29-17.16.58:528][ 59]LogFort: OnRep_bHasServerFinishedLoading 1 +[2018.11.29-17.16.58:613][ 64]LogFort: World Inventory received +[2018.11.29-17.16.58:679][ 69]LogGauntlet: Display: Changed state to Gauntlet_Zone_Athena +[2018.11.29-17.16.58:761][ 73]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.16.58:808][ 73]LogFort: OnReadyToStartMatch +[2018.11.29-17.16.58:809][ 73]LogFort: ClearCachedReports IN OnReadyToStartMatch! +[2018.11.29-17.16.58:809][ 73]LogFort: Warning: AFortPlayerController::OnRep_QuickBar Slot [0] is empty. +[2018.11.29-17.16.58:809][ 73]WindowsVideoRecordingSystem: Verbose: FWindowsVideoRecordingSystem::FWindowsVideoRecordingSystem +[2018.11.29-17.16.58:809][ 73]WindowsVideoRecordingSystem: Verbose: FWindowsVideoRecordingSystem::EnableRecording +[2018.11.29-17.16.58:809][ 73]WindowsVideoRecordingSystem: Verbose: FWindowsVideoRecordingSystem::NewRecording +[2018.11.29-17.16.58:809][ 73]WindowsVideoRecordingSystem: Verbose: FWindowsVideoRecordingSystem::IsEnabled +[2018.11.29-17.16.58:809][ 73]HighlightRecorder: recording started, ring buffer 30.00 secs +[2018.11.29-17.16.58:840][ 73]WindowsMediaEncoder: Registering the first listener +[2018.11.29-17.16.58:840][ 73]WindowsMediaEncoder: Starting +[2018.11.29-17.16.58:840][ 73]WMF: AudioEncoder config: 2 channels, 48000 Hz, 24.00 Kbps +[2018.11.29-17.16.58:844][ 73]WindowsMediaEncoder: Capping FPS 60 +[2018.11.29-17.16.58:844][ 73]NvVideoEncoder: VideoEncoder config: 1920x1080, 60 FPS, 5.00 Mbps +[2018.11.29-17.16.58:947][ 73]HighlightRecorder: paused +[2018.11.29-17.16.58:947][ 73]WindowsVideoRecordingSystem: Verbose: FWindowsVideoRecordingSystem::StartRecording +[2018.11.29-17.16.58:947][ 73]WindowsVideoRecordingSystem: FWindowsVideoRecordingSystem::StartRecording: starting a recording +[2018.11.29-17.16.58:947][ 73]HighlightRecorder: resumed after 0.000 s +[2018.11.29-17.16.58:947][ 73]LogOnlineGame: [UFortMatchmakingV2::StartTimeToMatchPhase] Ending Phase: 'LoadMap' +[2018.11.29-17.16.58:947][ 73]LogOnlineGame: [UFortMatchmakingV2::StartTimeToMatchPhase] Recording time to match metrics +[2018.11.29-17.16.58:947][ 73]LogOnlineGame: TimeInPhase Stats +[2018.11.29-17.16.58:947][ 73]LogOnlineGame: TimeToMatchTracker +ConnectToService: 0.37 +InQueue: 4.10 +InSessionAssignment: 2.12 +JoinSession: 0.81 +LoadMap: 6.25 +[2018.11.29-17.16.58:947][ 73]LogOnlineGame: [UFortMatchmakingV2::ResetTimeToMatch] Resetting time to match metrics +[2018.11.29-17.16.58:949][ 73]LogFortUI: Display: [UFortUIManagerWidget_NUI::NativeTick] change state to Athena with current values CurrentState: Invalid and NextState: Invalid +[2018.11.29-17.16.58:949][ 73]LogFortUI: Display: [UFortUIManagerWidget_NUI::SetUIState] states from: Invalid to Athena +[2018.11.29-17.16.58:949][ 73]LogUMG: Display: Widget Class AthenaHUD_C - Loaded Fast Template. +[2018.11.29-17.16.58:950][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:950][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:972][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.58:972][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.58:972][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.58:972][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.58:981][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.58:981][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.58:984][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:984][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:984][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:984][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:984][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:984][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:984][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:984][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:984][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:984][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:985][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:985][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:985][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:985][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:985][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:985][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:985][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:985][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:985][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:985][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:985][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:985][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:985][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:986][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:986][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:986][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:986][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:986][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:986][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:987][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:987][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:987][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:987][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:987][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:987][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:987][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:987][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:987][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:988][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:988][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:988][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:988][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:988][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:988][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:988][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:988][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:989][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:989][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:989][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:989][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:989][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:989][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:989][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:989][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:990][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:990][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:990][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:990][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:990][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:990][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:990][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:990][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:991][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:991][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:991][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:991][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:991][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:991][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:991][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:991][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:992][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:992][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:992][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:992][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:992][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:992][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:992][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:992][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:993][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:993][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:993][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:993][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:993][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:993][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:994][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:994][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:994][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.58:994][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.58:995][ 73]LogFortUI: Display: [UFortUIManagerWidget_NUI::TransitionToNextState] Switching states from: Invalid to Athena +[2018.11.29-17.16.58:996][ 73]LogUMG: Display: Widget Class BuildingInfoIndicator_C - Loaded Fast Template. +[2018.11.29-17.16.58:997][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.58:997][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.59:000][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:000][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:000][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:000][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:001][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.59:001][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.59:001][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:001][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:001][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:001][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:002][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:002][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:003][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:003][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:003][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:004][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:004][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:004][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:004][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:005][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:005][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:005][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:005][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:005][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:005][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:006][ 73]LogUMG: Display: Widget Class InterestIndicatorWidget_C - Loaded Fast Template. +[2018.11.29-17.16.59:006][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:006][ 73]LogUMG: Display: Widget Class VehicleInfoIndicator_C - Loaded Fast Template. +[2018.11.29-17.16.59:006][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.59:007][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.59:007][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.59:007][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.16.59:007][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:007][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:007][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:008][ 73]LogUMG: Display: Widget Class CreativeInfoIndicator_C - Loaded Fast Template. +[2018.11.29-17.16.59:009][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:009][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:010][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:010][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:010][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:010][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:011][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:011][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:011][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:011][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:011][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:012][ 73]LogUMG: Display: Widget Class AthenaInteractionIndicator_C - Loaded Fast Template. +[2018.11.29-17.16.59:013][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:013][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Window'. Using FWindowStyle defaults instead. +[2018.11.29-17.16.59:014][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:014][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:014][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:014][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:014][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:015][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:015][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:015][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:015][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:015][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:016][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:016][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:016][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:016][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:017][ 73]LogUMG: Display: Widget Class VehicleChangeSeatIndicator_C - Loaded Fast Template. +[2018.11.29-17.16.59:018][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:018][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:018][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:019][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:019][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:019][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:020][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:020][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:021][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:022][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:022][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:022][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:022][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:022][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:023][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:023][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:023][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:024][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:024][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:024][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:024][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:024][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:025][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:025][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:025][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:025][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:025][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:026][ 73]LogBlueprintUserMessages: [TeamInfo] AthenaTeamInfo ClearSquadMembers +[2018.11.29-17.16.59:027][ 73]LogUMG: Display: Widget Class AthenaQuestUpdateEntry_C - Loaded Fast Template. +[2018.11.29-17.16.59:028][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:029][ 73]LogUMG: Display: Widget Class AthenaHUDFeedbackLine_C - Loaded Fast Template. +[2018.11.29-17.16.59:030][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:032][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:032][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:032][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:032][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:033][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:033][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:033][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:035][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:036][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:037][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:039][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:039][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:040][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:040][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:040][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:040][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:040][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:040][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:040][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:041][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:041][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:041][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:041][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:042][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:042][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:042][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:042][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:042][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:043][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:043][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:043][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:043][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:043][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:044][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:044][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:044][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:044][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:044][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:045][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:045][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:045][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:045][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:045][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:047][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:047][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:047][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:047][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:047][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:048][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:048][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:048][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:048][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:049][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:049][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:049][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:049][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:050][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:050][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:051][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:051][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:052][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:052][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:052][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:053][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:053][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:053][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:053][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:054][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:054][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:055][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:055][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:055][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:055][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:056][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:056][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:056][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:056][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:057][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:057][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:057][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:057][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:057][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:057][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:058][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:058][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:058][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:058][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:058][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:058][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:058][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:058][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:058][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:058][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:059][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:059][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:059][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:059][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:059][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:059][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:060][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:060][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:060][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:060][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:060][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:060][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:060][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:060][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:061][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:061][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:061][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:061][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:061][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:061][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:061][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:062][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:062][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:062][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:062][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:062][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:062][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:062][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:062][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:063][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:063][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:063][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:063][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:063][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:063][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:063][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:063][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:064][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:064][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:064][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:065][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:065][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:065][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:065][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:065][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:065][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:065][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:065][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:067][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:068][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:068][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:068][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:069][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:069][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:070][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:070][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:071][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:071][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:072][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:072][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:072][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:073][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:073][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Window'. Using FWindowStyle defaults instead. +[2018.11.29-17.16.59:073][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:073][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:073][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:073][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:074][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:074][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:074][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:074][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:074][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:074][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:075][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:075][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:075][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:075][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:075][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:075][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:075][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:075][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:075][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:075][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:075][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:075][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:075][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:076][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:076][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:076][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:076][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:076][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:076][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:076][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:076][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:076][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:076][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:076][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:076][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:077][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:077][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:077][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:077][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:077][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:077][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:077][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:077][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:077][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:077][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:078][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:078][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:078][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:078][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:078][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:078][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:078][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:078][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:078][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:078][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:079][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:079][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:079][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:079][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:079][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:079][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:079][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:079][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:079][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:080][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:080][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:080][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:080][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:080][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:080][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:080][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:080][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:080][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:080][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:080][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:080][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:081][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:081][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:081][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:081][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:081][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:081][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:081][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:081][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:081][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:081][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:082][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:082][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:082][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:082][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:082][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:082][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:082][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:082][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:082][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:082][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:083][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:083][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:083][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:083][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:083][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:083][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:083][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:083][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:083][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:083][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:083][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:083][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:083][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:083][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:084][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:084][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:084][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:084][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:084][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:084][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:084][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:084][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:085][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:085][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:085][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:085][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:086][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:087][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:087][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:087][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:087][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:087][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:087][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:087][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:087][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:087][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:087][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:087][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:087][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:088][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:088][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:088][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:088][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:088][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:088][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:088][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:088][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:088][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:088][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:088][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:088][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:089][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:090][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:091][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:092][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:093][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:094][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:094][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:094][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:094][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:094][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:094][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:094][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:094][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:094][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:094][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:094][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:094][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:094][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:094][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:095][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:096][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:096][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:096][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:096][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:096][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:096][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:096][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:096][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:096][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:096][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:096][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:096][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:097][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:097][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:097][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:097][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:097][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:097][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:097][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:097][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:097][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:097][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:097][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:097][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:098][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:099][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:100][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:100][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:100][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:100][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:100][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:100][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:100][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:101][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:101][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:101][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:101][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:101][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:101][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:101][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:101][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:101][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:101][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:101][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:102][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:102][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:102][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:102][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:102][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:102][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:102][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:102][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:102][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:103][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:103][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:103][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:103][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:103][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:103][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:103][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:103][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:103][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableTextBox'. Using FEditableTextBoxStyle defaults instead. +[2018.11.29-17.16.59:103][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableTextBox'. Using FEditableTextBoxStyle defaults instead. +[2018.11.29-17.16.59:103][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:103][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:103][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:104][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:104][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:104][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:104][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:104][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:104][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:104][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:104][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:104][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:105][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:105][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:105][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:105][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:105][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:105][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:105][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:105][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:105][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:105][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:106][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:106][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:106][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:106][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:107][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:108][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:109][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:110][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:110][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:110][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:110][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:110][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:110][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:110][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:110][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:110][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:110][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:110][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:110][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:111][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:111][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:111][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:111][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:111][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:111][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:111][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:111][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:111][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:111][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:111][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:112][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:113][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:113][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:113][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:113][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:113][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:113][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:113][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:113][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:113][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:113][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:113][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:114][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:115][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:115][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:115][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:115][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:115][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:115][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:115][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:115][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:115][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:115][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:115][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:115][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:116][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.59:116][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:116][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.59:116][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:116][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:117][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:117][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:117][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:117][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:117][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:117][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:117][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:117][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:117][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:117][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:117][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:117][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:117][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:118][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalEditableText'. Using FEditableTextStyle defaults instead. +[2018.11.29-17.16.59:118][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:118][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:118][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:118][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:118][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:118][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:118][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:118][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:118][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:118][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:118][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:118][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:118][ 73]LogDataTable: Warning: UDataTable::FindRow : 'UFortGlobalUIContext::GetHealthyGamingData' requested row 'US' not in DataTable '/Game/UI/Foundation/Config/HealthyGamingData.HealthyGamingData'. +[2018.11.29-17.16.59:118][ 73]LogUMG: Display: Widget Class AthenaGameOverWidget_C - Loaded Fast Template. +[2018.11.29-17.16.59:119][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:119][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:119][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:119][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:119][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:119][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:119][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:119][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:119][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:119][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:119][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NoBorder'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:120][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.16.59:121][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:122][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:122][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:122][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:122][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:122][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:122][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:122][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:123][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:123][ 73]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:124][ 73]LogUMG: Display: Widget Class KairosLayer_C - Loaded Fast Template. +[2018.11.29-17.16.59:228][ 78]LogFortPlayerRegistration: InitializeAbilitySystemActor initialized with valid zone state for LoadBot07063 +[2018.11.29-17.16.59:251][ 80]LogHealthSnapshot: ======= Snapshot: Start of Match (Athena_GameState_C, Difficulty 0.00) ======= +[2018.11.29-17.16.59:251][ 80]LogHealthSnapshot: Games Played: 0 +[2018.11.29-17.16.59:251][ 80]LogHealthSnapshot: CPU Memory: Used 1233.77MB, Peak 1233.77MB +[2018.11.29-17.16.59:251][ 80]LogHealthSnapshot: Physical Memory: Used 2321.73MB, Peak 2353.27MB +[2018.11.29-17.16.59:251][ 80]LogHealthSnapshot: ========================================================= +[2018.11.29-17.16.59:258][ 80]LogFort: AFortPlayerState::OnRep_bHasStartedPlaying - [LoadBot07063] has replicated to the client bHasStartedPlaying=[1] (removed in shipping!) +[2018.11.29-17.16.59:266][ 81]LogOnlineParty: Verbose: OSS: UpdatePartyMemberData request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.16.59:267][ 81]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.memberdata user=e6f5091c3b2f4c359cf2aad75c424de0 to all +[2018.11.29-17.16.59:276][ 81]LogOutputDevice: Warning: + +Script Stack (0 frames): + +[2018.11.29-17.16.59:317][ 81]LogStats: FPlatformStackWalk::StackWalkAndDump - 0.041 s +[2018.11.29-17.16.59:317][ 81]LogOutputDevice: Error: === Handled ensure: === +[2018.11.29-17.16.59:317][ 81]LogOutputDevice: Error: +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: Ensure condition failed: false [File:d:\epic\kairos\fortnitegame\source\fortnitegame\public\Pawns/FortPawn.h] [Line: 917] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: Attempted to get pawn stats but couldn't find them! Either no stats are specified for the pawn (FortPlayerPawnAthena_2147477823), or code asked for the wrong type of stats! DataTable address: 0, Row Name: None +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: Stack: +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff79138c20c FortniteClient.exe!AFortPawn::GetPawnStats() [d:\epic\kairos\fortnitegame\source\fortnitegame\public\pawns\fortpawn.h:916] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff791f0fc7a FortniteClient.exe!AFortPawn::PostInitializeComponents() [d:\epic\kairos\fortnitegame\source\fortnitegame\private\pawns\fortpawn.cpp:2534] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff791f1004e FortniteClient.exe!AFortPlayerPawn::PostInitializeComponents() [d:\epic\kairos\fortnitegame\source\fortnitegame\private\pawns\fortplayerpawn.cpp:703] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff791425695 FortniteClient.exe!AFortPlayerPawnAthena::PostInitializeComponents() [d:\epic\kairos\fortnitegame\source\fortnitegame\private\athena\fortplayerpawnathena.cpp:338] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff794f758e5 FortniteClient.exe!AActor::PostActorConstruction() [d:\epic\kairos\engine\source\runtime\engine\private\actor.cpp:3088] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff794f56149 FortniteClient.exe!AActor::FinishSpawning() [d:\epic\kairos\engine\source\runtime\engine\private\actor.cpp:3015] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff794f799e1 FortniteClient.exe!AActor::PostSpawnInitialize() [d:\epic\kairos\engine\source\runtime\engine\private\actor.cpp:2956] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff79588dfd3 FortniteClient.exe!UWorld::SpawnActor() [d:\epic\kairos\engine\source\runtime\engine\private\levelactor.cpp:472] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff79588e962 FortniteClient.exe!UWorld::SpawnActor() [d:\epic\kairos\engine\source\runtime\engine\private\levelactor.cpp:296] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff7976d36e3 FortniteClient.exe!UKairosViewport::PopulateHeroPawns() [d:\epic\kairos\fortnitegame\source\fortniteui\private\kairos\kairosviewport.cpp:824] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff79768a5da FortniteClient.exe!TBaseUObjectMethodDelegateInstance<0,UKairosViewport,TTypeWrapper __cdecl(void)>::Execute() [d:\epic\kairos\engine\source\runtime\core\public\delegates\delegateinstancesimpl.h:618] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff79633d516 FortniteClient.exe!FTimerManager::Tick() [d:\epic\kairos\engine\source\runtime\engine\private\timermanager.cpp:595] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff7958933a2 FortniteClient.exe!UWorld::Tick() [d:\epic\kairos\engine\source\runtime\engine\private\leveltick.cpp:1604] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff79568cbe6 FortniteClient.exe!UGameEngine::Tick() [d:\epic\kairos\engine\source\runtime\engine\private\gameengine.cpp:1589] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff791854697 FortniteClient.exe!UFortEngine::Tick() [d:\epic\kairos\fortnitegame\source\fortnitegame\private\fortengine.cpp:511] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff78fd9885d FortniteClient.exe!FEngineLoop::Tick() [d:\epic\kairos\engine\source\runtime\launch\private\launchengineloop.cpp:3929] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff78fda7c7f FortniteClient.exe!GuardedMain() [d:\epic\kairos\engine\source\runtime\launch\private\launch.cpp:179] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff78fda7d3a FortniteClient.exe!GuardedMainWrapper() [d:\epic\kairos\engine\source\runtime\launch\private\windows\launchwindows.cpp:145] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff78fdb79b1 FortniteClient.exe!WinMain() [d:\epic\kairos\engine\source\runtime\launch\private\windows\launchwindows.cpp:276] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ff798164a52 FortniteClient.exe!__scrt_common_main_seh() [d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ffc1bb71fe4 KERNEL32.DLL!UnknownFunction [] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: [Callstack] 0x00007ffc1bcacb31 ntdll.dll!UnknownFunction [] +[2018.11.29-17.16.59:318][ 81]LogOutputDevice: Error: +[2018.11.29-17.16.59:323][ 81]LogStats: SubmitErrorReport - 0.000 s +[2018.11.29-17.16.59:606][ 81]LogWindows: Warning: CreateProc failed: The system cannot find the file specified. (0x00000002) +[2018.11.29-17.16.59:606][ 81]LogWindows: Warning: URL: ../../../Engine/Binaries/Win64/CrashReportClient.exe "D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Crashes/UE4CC-Windows-C58980F04E9A4CBAD9844196DD30D0F3_0001" -Unattended -AppName=UE4-FortniteGame -CrashGUID=UE4CC-Windows-C58980F04E9A4CBAD9844196DD30D0F3_0001 -DebugSymbols=..\..\..\Engine\Intermediate\Symbols +[2018.11.29-17.16.59:606][ 81]LogStats: SendNewReport - 0.283 s +[2018.11.29-17.16.59:606][ 81]LogStats: FDebug::EnsureFailed - 0.330 s +[2018.11.29-17.16.59:611][ 81]LogFort: Display: [FortCustomizationAssetLoader F_Med_Head1_ATH] Finished loading. 2 assets loaded. +[2018.11.29-17.16.59:620][ 82]LogFort: Attempting to add harvesting tool WID_Harvest_Pickaxe_Athena_C_T01 to quickbar 2 in slot -3. +[2018.11.29-17.16.59:620][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:620][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:620][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:621][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:621][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:621][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:622][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:622][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:622][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:622][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:622][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:622][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:623][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:623][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:623][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:624][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:624][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:624][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:625][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:625][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:625][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:625][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:625][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:625][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:626][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:626][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:626][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:626][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:626][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:626][ 82]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.16.59:627][ 82]LogFort: QuickBarItemAddedToInventory. Item: FortWorldItem_2147477818 Harvesting Tool with GUID: 502716082 1210026747 1851506616 1341528115 +[2018.11.29-17.16.59:627][ 82]LogFort: QuickBarItemAddedToInventory. Item: FortWorldItem_2147477817 with GUID: 1391287435 1292668537 -989092465 -382222061 +[2018.11.29-17.16.59:628][ 82]LogFort: QuickBarItemAddedToInventory. Item: FortWorldItem_2147477816 with GUID: 1029422476 1213784337 -363043140 -53006083 +[2018.11.29-17.16.59:628][ 82]LogFort: QuickBarItemAddedToInventory. Item: FortWorldItem_2147477815 with GUID: -1600433222 1278011242 -247173985 2057970780 +[2018.11.29-17.16.59:628][ 82]LogFort: QuickBarItemAddedToInventory. Item: FortWorldItem_2147477814 with GUID: -8724478 1181013106 -2014099580 717380754 +[2018.11.29-17.16.59:750][ 89]LogFort: Display: [FortCustomizationAssetLoader M_Med_Soldier_Head_TV13] Finished loading. 9 assets loaded. +[2018.11.29-17.16.59:756][ 90]LogXmpp: VeryVerbose: libstrophe[71688] conn debug: SENT: {"Status":"Playing Battle Royale - 1 Left - 1 / 4","bIsPlaying":true,"bIsJoinable":false,"bHasVoiceSupport":false,"SessionId":"f65b90c13f5a4bf285ef088b8cef6283","Properties":{"FortBasicInfo_j":{"homeBaseRating":1},"FortLFG_I":"0","FortPartySize_i":1,"FortSubGame_i":1,"InUnjoinableMatch_b":true,"FortGameplayStats_j":{"state":"","playlist":"None","numKills":0,"bFellToDeath":false},"party.joininfodata.286331153_j":{"sourceId":"e6f5091c3b2f4c359cf2aad75c424de0","sourceDisplayName":"LoadBot07063","sourcePlatform":"WIN","partyId":"C9AE807B4F9D1F30F1535488AB79E7A8","partyTypeId":286331153,"key":"1A9601624B2510433E8340B1FAAD2362","appId":"FortniteDevLatest","buildId":"6834","partyFlags":6,"notAcceptingReason":0},"Event_PlayersAlive_s":"1","Event_PartySize_s":"1","Event_PartyMaxSize_s":"4"}} +[2018.11.29-17.16.59:756][ 90]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.16.59:765][ 91]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::SendFromQueue: Wrote 895 bytes, 0 bytes remaining in this packet +[2018.11.29-17.16.59:870][ 97]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=1104 BytesLeft=0 +[2018.11.29-17.16.59:870][ 97]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: RECV: {"Status":"Playing Battle Royale - 1 Left - 1 / 4","bIsPlaying":true,"bIsJoinable":false,"bHasVoiceSupport":false,"SessionId":"f65b90c13f5a4bf285ef088b8cef6283","Properties":{"FortBasicInfo_j":{"homeBaseRating":1},"FortLFG_I":"0","FortPartySize_i":1,"FortSubGame_i":1,"InUnjoinableMatch_b":true,"FortGameplayStats_j":{"state":"","playlist":"None","numKills":0,"bFellToDeath":false},"party.joininfodata.286331153_j":{"sourceId":"e6f5091c3b2f4c359cf2aad75c424de0","sourceDisplayName":"LoadBot07063","sourcePlatform":"WIN","partyId":"C9AE807B4F9D1F30F1535488AB79E7A8","partyTypeId":286331153,"key":"1A9601624B2510433E8340B1FAAD2362","appId":"FortniteDevLatest","buildId":"6834","partyFlags":6,"notAcceptingReason":0},"Event_PlayersAlive_s":"1","Event_PartySize_s":"1","Event_PartyMaxSize_s":"4"}} +[2018.11.29-17.16.59:870][ 97]LogXmpp: Verbose: Received Strophe XMPP Stanza presence +[2018.11.29-17.16.59:870][ 97]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.16.59:870][ 97]LogXmpp: VeryVerbose: presence Stanza handled by Presence +[2018.11.29-17.17.00:145][113]LogLevelActorContainer: Created LevelActorCluster (0) for /Temp/Game/Athena/Maps/POI/Athena_POI_Lobby_001_3f5ab45c.Athena_POI_Lobby_001:PersistentLevel with 110 objects, 0 referenced clusters and 12 mutable objects. +[2018.11.29-17.17.01:778][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:778][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.17.01:778][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:779][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.17.01:779][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.17.01:779][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:779][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.17.01:779][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:780][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.17.01:780][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:780][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:780][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:780][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.17.01:780][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:780][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.17.01:780][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:780][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:780][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:781][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:781][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.17.01:781][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:781][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.17.01:781][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.17.01:782][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:782][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.17.01:782][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:782][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.17.01:782][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:782][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:782][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:783][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.17.01:783][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:783][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.17.01:783][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:783][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:783][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:784][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:784][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.17.01:784][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:784][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.17.01:784][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.17.01:784][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:784][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.17.01:785][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:785][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.17.01:785][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:785][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:785][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:785][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.17.01:785][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:785][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.17.01:785][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:785][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.01:785][211]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.02:194][236]LogFortLoadingScreen: Garbage Collecting before dropping load screen +[2018.11.29-17.17.02:194][236]LogCore: Display: Setting hang detector multiplier to 1.0000s. New hang duration: 30.0000s. New present duration: 0.0000s. +[2018.11.29-17.17.02:194][236]LogFortLoadingScreen: Hiding loading screen when 'IsShowingInitialLoadingScreen()' is false. +[2018.11.29-17.17.02:194][236]LogFortLoadingScreen: Reason for Showing/Hiding LoadingScreen is unknown! +[2018.11.29-17.17.02:197][236]PacketHandlerLog: DDoS detection status: detection enabled: 0 analytics enabled: 0 +[2018.11.29-17.17.02:197][236]LogNet: AddClientConnection: Added client connection: [UNetConnection] RemoteAddr: UDemoNetConnection, Name: DemoNetConnection_2147476469, Driver: DemoNetDriver DemoNetDriver_2147476470, IsServer: YES, PC: NULL, Owner: NULL, UniqueId: INVALID +[2018.11.29-17.17.02:198][236]LogFort: Display: Wrote SubGame=Athena to replay header +[2018.11.29-17.17.02:199][236]LogFortMusic: Warning: Trying to assign a bank to a music manager that doesn't yet exist. +[2018.11.29-17.17.02:200][236]LogDemo: Num Network Actors: 1307 +[2018.11.29-17.17.02:206][237]LogGarbage: Collecting garbage (GCheckForIllegalMarkPendingKill = 1) +[2018.11.29-17.17.02:214][237]LogGarbage: 7.368382 ms for Verify GC Assumptions +[2018.11.29-17.17.02:240][237]LogGarbage: 26.128049 ms for GC +[2018.11.29-17.17.02:241][237]LogGarbage: 0.407543 ms for Gather Unreachable Objects (2403 objects collected including 0 cluster objects from 0 clusters) +[2018.11.29-17.17.02:243][237]LogGarbage: 2.286167 ms for unhashing unreachable objects. Items 2403 (2403/2403) +[2018.11.29-17.17.02:251][237]LogGarbage: GC purged 2403 objects (532996 -> 530593) +[2018.11.29-17.17.02:283][237]LogUObjectHash: Compacting FUObjectHashTables data took 32.44ms +[2018.11.29-17.17.02:297][237]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.02:297][237]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.02:297][237]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.02:297][237]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.02:297][237]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.02:297][237]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.02:297][237]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.02:297][237]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.02:297][237]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.02:304][238]LogDemo: Exceeded maximum desired recording time. Max: 1.800ms. +[2018.11.29-17.17.07:841][570]LogBlueprintUserMessages: [BP_FixedItem_Spawner_2] BP_FixedItem_Spawner: Sword Enabled = 0 +[2018.11.29-17.17.07:842][570]LogSlate: Took 0.000293 seconds to synchronously load lazily loaded font '../../../Engine/Content/EngineFonts/Faces/RobotoRegular.ufont' (155K) +[2018.11.29-17.17.09:259][655]LogInit: Selected Device Profile: [WindowsClient] +[2018.11.29-17.17.09:259][655]LogInit: Selected Device Profile: [WindowsClient] +[2018.11.29-17.17.09:259][655]LogInit: Selected Device Profile: [WindowsClient] +[2018.11.29-17.17.09:274][656]LogInit: Selected Device Profile: [WindowsClient] +[2018.11.29-17.17.09:274][656]LogInit: Selected Device Profile: [WindowsClient] +[2018.11.29-17.17.14:275][956]LogFort: Native Action Role(ROLE_SimulatedProxy) Can't stop Gameplay.Action.Player.DBNO, not active! +[2018.11.29-17.17.14:275][956]LogFort: Native Action Role(ROLE_SimulatedProxy) Can't stop Gameplay.Action.Player.DBNOAthena, not active! +[2018.11.29-17.17.14:276][956]LogFort: Warning: FQuickBar::RefreshEquippedItemDefinitions could not find Item with GUID 1029422476 1213784337 -363043140 -53006083 +[2018.11.29-17.17.14:276][956]LogFort: Warning: FQuickBar::RefreshEquippedItemDefinitions could not find Item with GUID -1600433222 1278011242 -247173985 2057970780 +[2018.11.29-17.17.14:276][956]LogFort: Warning: FQuickBar::RefreshEquippedItemDefinitions could not find Item with GUID -8724478 1181013106 -2014099580 717380754 +[2018.11.29-17.17.14:277][956]LogFort: Warning: FQuickBar::RefreshEquippedItemDefinitions could not find Item with GUID -1600433222 1278011242 -247173985 2057970780 +[2018.11.29-17.17.14:277][956]LogFort: Warning: FQuickBar::RefreshEquippedItemDefinitions could not find Item with GUID -8724478 1181013106 -2014099580 717380754 +[2018.11.29-17.17.14:277][956]LogFort: Warning: FQuickBar::RefreshEquippedItemDefinitions could not find Item with GUID -8724478 1181013106 -2014099580 717380754 +[2018.11.29-17.17.14:316][958]LogFort: EnterAircraft: Athena_PlayerController_C_2147478528 +[2018.11.29-17.17.14:317][958]LogFortAnalyticsEvent: Display: Core.EndGamePhase_ClientMetrics: CurrentGamePhaseName: Warmup DurationSec: 15.064671 CPU: GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz NetworkType: 0 PingRTT: 11 PacketOverhead: 28 InRate: 4052 OutRate: 2182 InPacketsRate: 30 OutPacketRate: 56 InPacketsLostPercentage: 0.00 OutPacketsLostPercentage: 0.00 InBunchesRate: 63 OutBunchesRate: 63 TotalMovementCorrectionDistanceV2: 0 AverageMovementCorrectionDistance: 0 TotalNumMovementCorrectionsPerMinute: 0.000000 OutAcksRate: 60 RPCsCalledRate: 11 +[2018.11.29-17.17.14:332][959]LogInit: Selected Device Profile: [WindowsClient] +[2018.11.29-17.17.14:332][959]LogInit: Selected Device Profile: [WindowsClient] +[2018.11.29-17.17.17:957][177]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.17.17:957][177]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.17.17:957][177]LogHttp: Verbose: 00000231F147FC40: URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/verify' +[2018.11.29-17.17.17:957][177]LogHttp: Verbose: 00000231F147FC40: Verb='GET' +[2018.11.29-17.17.17:957][177]LogHttp: Verbose: 00000231F147FC40: Custom headers are present +[2018.11.29-17.17.17:957][177]LogHttp: Verbose: 00000231F147FC40: Payload size=0 +[2018.11.29-17.17.17:957][177]LogHttp: Verbose: 00000231F147FC40: Adding header 'X-Epic-Correlation-ID: FN-Eg326kTZok_SA-yKKWSJug' +[2018.11.29-17.17.17:957][177]LogHttp: Verbose: 00000231F147FC40: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.17.17:957][177]LogHttp: Verbose: 00000231F147FC40: Adding header 'Content-Type: application/json' +[2018.11.29-17.17.17:958][177]LogHttp: Verbose: 00000231F147FC40: Adding header 'Content-Length: 0' +[2018.11.29-17.17.17:958][177]LogHttp: Verbose: 00000231F147FC40: Adding header 'Expect: ' +[2018.11.29-17.17.17:958][177]LogHttp: 00000231F147FC40: Starting GET request to URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/verify' +[2018.11.29-17.17.17:958][177]LogHttp: Verbose: 00000231F147FC40: request (easy handle:00000231AE43AAB0) has been added to threaded queue for processing +[2018.11.29-17.17.17:991][179]LogHttp: Verbose: 00000231F147FC40: request (easy handle:00000231AE43AAB0) has started threaded processing +[2018.11.29-17.17.17:991][179]LogHttp: VeryVerbose: 00000231F147FC40: 'Hostname in DNS cache was stale, zapped' +[2018.11.29-17.17.18:007][180]LogHttp: VeryVerbose: 00000231F147FC40: ' Trying 10.40.239.9...' +[2018.11.29-17.17.18:007][180]LogHttp: VeryVerbose: 00000231F147FC40: 'TCP_NODELAY set' +[2018.11.29-17.17.18:043][182]LogHttp: VeryVerbose: 00000231F147FC40: 'Connected to account-public-service-gamedev.ol.epicgames.net (10.40.239.9) port 443 (#16)' +[2018.11.29-17.17.18:058][183]LogHttp: VeryVerbose: 00000231F147FC40: 'ALPN, offering http/1.1' +[2018.11.29-17.17.18:059][183]LogHttp: VeryVerbose: 00000231F147FC40: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.17.18:059][183]LogHttp: VeryVerbose: 00000231F147FC40: 'SSL re-using session ID' +[2018.11.29-17.17.18:059][183]LogHttp: VeryVerbose: 00000231F147FC40: Sent SSL data (5 bytes) +[2018.11.29-17.17.18:059][183]LogHttp: VeryVerbose: 00000231F147FC40: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.17.18:059][183]LogHttp: VeryVerbose: 00000231F147FC40: Sent SSL data (512 bytes) +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: Received SSL data (5 bytes) +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: Received SSL data (104 bytes) +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: Received SSL data (5 bytes) +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: 'TLSv1.2 (IN), TLS handshake, Certificate (11):' +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: Received SSL data (4568 bytes) +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: Received SSL data (5 bytes) +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: 'TLSv1.2 (IN), TLS handshake, Server key exchange (12):' +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: Received SSL data (333 bytes) +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: Received SSL data (5 bytes) +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: 'TLSv1.2 (IN), TLS handshake, Server finished (14):' +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: Received SSL data (4 bytes) +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: Sent SSL data (5 bytes) +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: 'TLSv1.2 (OUT), TLS handshake, Client key exchange (16):' +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: Sent SSL data (70 bytes) +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: Sent SSL data (5 bytes) +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: Sent SSL data (1 bytes) +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: Sent SSL data (5 bytes) +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.17.18:090][185]LogHttp: VeryVerbose: 00000231F147FC40: Sent SSL data (16 bytes) +[2018.11.29-17.17.18:125][187]LogHttp: VeryVerbose: 00000231F147FC40: Received SSL data (5 bytes) +[2018.11.29-17.17.18:125][187]LogHttp: VeryVerbose: 00000231F147FC40: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.17.18:125][187]LogHttp: VeryVerbose: 00000231F147FC40: Received SSL data (1 bytes) +[2018.11.29-17.17.18:125][187]LogHttp: VeryVerbose: 00000231F147FC40: Received SSL data (5 bytes) +[2018.11.29-17.17.18:125][187]LogHttp: VeryVerbose: 00000231F147FC40: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.17.18:125][187]LogHttp: VeryVerbose: 00000231F147FC40: Received SSL data (16 bytes) +[2018.11.29-17.17.18:125][187]LogHttp: VeryVerbose: 00000231F147FC40: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.17.18:125][187]LogHttp: VeryVerbose: 00000231F147FC40: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.17.18:125][187]LogHttp: VeryVerbose: 00000231F147FC40: 'old SSL session ID is stale, removing' +[2018.11.29-17.17.18:125][187]LogHttp: VeryVerbose: 00000231F147FC40: 'Server certificate:' +[2018.11.29-17.17.18:125][187]LogHttp: VeryVerbose: 00000231F147FC40: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.17.18:125][187]LogHttp: VeryVerbose: 00000231F147FC40: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.17.18:125][187]LogHttp: VeryVerbose: 00000231F147FC40: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.17.18:125][187]LogHttp: VeryVerbose: 00000231F147FC40: ' subjectAltName: host "account-public-service-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.17.18:126][187]LogHttp: VeryVerbose: 00000231F147FC40: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.17.18:126][187]LogHttp: VeryVerbose: 00000231F147FC40: ' SSL certificate verify ok.' +[2018.11.29-17.17.18:126][187]LogHttp: VeryVerbose: 00000231F147FC40: Sent SSL data (5 bytes) +[2018.11.29-17.17.18:126][187]LogHttp: VeryVerbose: 00000231F147FC40: Sent header (1023 bytes) - GET /account/api/oauth/verify HTTP/1.1Host: account-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-Eg326kTZok_SA-yKKWSJugUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Type: application/jsonAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM0RoMXFQVm9LNXp2M1J0TjZCUUM3QUJ1UGJTcT +[2018.11.29-17.17.18:175][190]LogHttp: VeryVerbose: 00000231F147FC40: Received SSL data (5 bytes) +[2018.11.29-17.17.18:175][190]LogHttp: VeryVerbose: 00000231F147FC40: Received header (17 bytes) +[2018.11.29-17.17.18:175][190]LogHttp: Verbose: 00000231F147FC40: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.17.18:175][190]LogHttp: VeryVerbose: 00000231F147FC40: Received header (37 bytes) +[2018.11.29-17.17.18:175][190]LogHttp: Verbose: 00000231F147FC40: Received response header 'Date: Thu, 29 Nov 2018 17:17:18 GMT'. +[2018.11.29-17.17.18:175][190]LogHttp: VeryVerbose: 00000231F147FC40: Received header (32 bytes) +[2018.11.29-17.17.18:175][190]LogHttp: Verbose: 00000231F147FC40: Received response header 'Content-Type: application/json'. +[2018.11.29-17.17.18:175][190]LogHttp: VeryVerbose: 00000231F147FC40: Received header (28 bytes) +[2018.11.29-17.17.18:176][190]LogHttp: Verbose: 00000231F147FC40: Received response header 'Transfer-Encoding: chunked'. +[2018.11.29-17.17.18:176][190]LogHttp: VeryVerbose: 00000231F147FC40: Received header (24 bytes) +[2018.11.29-17.17.18:176][190]LogHttp: Verbose: 00000231F147FC40: Received response header 'Connection: keep-alive'. +[2018.11.29-17.17.18:176][190]LogHttp: VeryVerbose: 00000231F147FC40: Received header (23 bytes) +[2018.11.29-17.17.18:176][190]LogHttp: Verbose: 00000231F147FC40: Received response header 'Vary: Accept-Encoding'. +[2018.11.29-17.17.18:176][190]LogHttp: VeryVerbose: 00000231F147FC40: Received header (49 bytes) +[2018.11.29-17.17.18:176][190]LogHttp: Verbose: 00000231F147FC40: Received response header 'Cache-Control: no-cache, no-store, no-transform'. +[2018.11.29-17.17.18:176][190]LogHttp: VeryVerbose: 00000231F147FC40: Received header (52 bytes) +[2018.11.29-17.17.18:176][190]LogHttp: Verbose: 00000231F147FC40: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.17.18:176][190]LogHttp: VeryVerbose: 00000231F147FC40: Received header (50 bytes) +[2018.11.29-17.17.18:176][190]LogHttp: Verbose: 00000231F147FC40: Received response header 'X-Epic-Correlation-ID: FN-Eg326kTZok_SA-yKKWSJug'. +[2018.11.29-17.17.18:176][190]LogHttp: VeryVerbose: 00000231F147FC40: Received header (22 bytes) +[2018.11.29-17.17.18:176][190]LogHttp: Verbose: 00000231F147FC40: Received response header 'X-Epic-From-Cache: 1'. +[2018.11.29-17.17.18:176][190]LogHttp: VeryVerbose: 00000231F147FC40: Received header (24 bytes) +[2018.11.29-17.17.18:176][190]LogHttp: Verbose: 00000231F147FC40: Received response header 'Content-Encoding: gzip'. +[2018.11.29-17.17.18:176][190]LogHttp: Verbose: 00000231F147FC40: Received response header ''. +[2018.11.29-17.17.18:176][190]LogHttp: VeryVerbose: 00000231F147FC40: Received header (2 bytes) +[2018.11.29-17.17.18:176][190]LogHttp: VeryVerbose: 00000231F147FC40: Received data (1855 bytes) +[2018.11.29-17.17.18:177][190]LogHttp: Verbose: 00000231F147FC40: ReceiveResponseBodyCallback: 2584 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=2584, Response->TotalBytesRead=0, Response->GetContentLength()=0, SizeToDownload=2584 (<-this will get returned from the callback)) +[2018.11.29-17.17.18:177][190]LogHttp: VeryVerbose: 00000231F147FC40: Received SSL data (5 bytes) +[2018.11.29-17.17.18:177][190]LogHttp: VeryVerbose: 00000231F147FC40: Received data (5 bytes) +[2018.11.29-17.17.18:177][190]LogHttp: VeryVerbose: 00000231F147FC40: 'Connection cache is full, closing the oldest one.' +[2018.11.29-17.17.18:177][190]LogHttp: VeryVerbose: 00000231F147FC40: 'Closing connection 14' +[2018.11.29-17.17.18:177][190]LogHttp: VeryVerbose: 00000231F147FC40: Sent SSL data (5 bytes) +[2018.11.29-17.17.18:177][190]LogHttp: VeryVerbose: 00000231F147FC40: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.17.18:177][190]LogHttp: VeryVerbose: 00000231F147FC40: Sent SSL data (2 bytes) +[2018.11.29-17.17.18:177][190]LogHttp: VeryVerbose: 00000231F147FC40: 'Connection #16 to host account-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.17.18:177][190]LogHttp: Verbose: Request 00000231F147FC40 (easy handle:00000231AE43AAB0) has completed (code:0) and has been marked as such +[2018.11.29-17.17.18:179][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.17.18:179][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.17.18:179][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.18:179][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.18:179][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.18:179][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.18:179][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.18:179][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.18:179][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.18:179][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.18:179][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.18:179][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.18:180][190]LogHttp: 00000231F147FC40: request has been successfully processed. URL: https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/verify, HTTP code: 200, content length: -1, actual payload size: 2584 +[2018.11.29-17.17.18:180][190]LogHttp: Verbose: 00000231F147FC40 Response Header Date: Thu, 29 Nov 2018 17:17:18 GMT +[2018.11.29-17.17.18:180][190]LogHttp: Verbose: 00000231F147FC40 Response Header Content-Type: application/json +[2018.11.29-17.17.18:180][190]LogHttp: Verbose: 00000231F147FC40 Response Header Transfer-Encoding: chunked +[2018.11.29-17.17.18:180][190]LogHttp: Verbose: 00000231F147FC40 Response Header Connection: keep-alive +[2018.11.29-17.17.18:180][190]LogHttp: Verbose: 00000231F147FC40 Response Header Vary: Accept-Encoding +[2018.11.29-17.17.18:180][190]LogHttp: Verbose: 00000231F147FC40 Response Header Cache-Control: no-cache, no-store, no-transform +[2018.11.29-17.17.18:180][190]LogHttp: Verbose: 00000231F147FC40 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.17.18:180][190]LogHttp: Verbose: 00000231F147FC40 Response Header X-Epic-Correlation-ID: FN-Eg326kTZok_SA-yKKWSJug +[2018.11.29-17.17.18:180][190]LogHttp: Verbose: 00000231F147FC40 Response Header X-Epic-From-Cache: 1 +[2018.11.29-17.17.18:180][190]LogHttp: Verbose: 00000231F147FC40 Response Header Content-Encoding: gzip +[2018.11.29-17.17.18:180][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.17.18:180][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.18:180][190]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.17.21:245][374]FortClientBot: {"event": "BotSetJumpTimer", "bot": "LoadBot07063", "delay": "7.00"} +[2018.11.29-17.17.22:306][437]LogLocalFileReplay: FLocalFileNetworkReplayStreamer::FlushStream. StreamChunkIndex: 0, Size: 167016 +[2018.11.29-17.17.27:256][734]FortClientBot: {"event": "BotStatus", "bot": "", "statusvalue": 0, "statusstring": "ControllerInitialized", "timeincurrentstate": 30 } +[2018.11.29-17.17.27:259][735]FortClientBot: {"event": "BotStatus", "bot": "LoadBot07063", "statusvalue": 9, "statusstring": "InMatch", "timeincurrentstate": 30 , "xPos": "-1", "yPos":"-1"} +[2018.11.29-17.17.28:242][794]FortClientBot: {"event": "BotHasJumped", "bot": "LoadBot07063"} +[2018.11.29-17.17.28:327][798]LogFort: Attempting to add harvesting tool WID_Harvest_Pickaxe_Athena_C_T01 to quickbar 2 in slot -3. +[2018.11.29-17.17.28:327][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:328][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:328][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:328][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:328][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:328][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:329][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:329][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:329][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:330][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:330][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:330][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:331][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:331][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:331][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:331][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:331][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:331][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:332][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:332][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:332][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:332][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:332][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:332][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:333][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:333][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:333][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:334][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:334][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:334][798]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.17.28:334][798]LogFort: Cannot execute inventory item - due to blocked ActionPlayerChangeEquipment tag +[2018.11.29-17.17.28:334][798]LogFort: QuickBarItemAddedToInventory. Item: FortWorldItem_2147475313 Harvesting Tool with GUID: -327522162 1228193610 -52278653 -2114632038 +[2018.11.29-17.17.28:335][798]LogFort: QuickBarItemAddedToInventory. Item: FortWorldItem_2147475312 with GUID: 542218653 1304455014 527338886 -412100472 +[2018.11.29-17.17.28:335][798]LogFort: QuickBarItemAddedToInventory. Item: FortWorldItem_2147475311 with GUID: 1419129305 1133229924 1869570475 1368360009 +[2018.11.29-17.17.28:335][798]LogFort: QuickBarItemAddedToInventory. Item: FortWorldItem_2147475310 with GUID: -437271388 1203319546 -669572216 823232609 +[2018.11.29-17.17.28:335][798]LogFort: QuickBarItemAddedToInventory. Item: FortWorldItem_2147475309 with GUID: 1455812115 1203219457 -986444145 -1832405394 +[2018.11.29-17.17.28:338][798]LogFortPlayerRegistration: InitializeAbilitySystemActor initialized with valid zone state for LoadBot07063 +[2018.11.29-17.17.28:338][798]LogFort: ExitAircraft: Athena_PlayerController_C_2147478528 (Pawn PlayerPawn_Athena_C_2147475319) +[2018.11.29-17.17.28:429][804]LogFort: Cannot execute inventory item - due to blocked ActionPlayerChangeEquipment tag +[2018.11.29-17.17.29:108][839]LogLevelActorContainer: Created LevelActorCluster (4) for /Temp/Game/Athena/Maps/Streaming/Sublevel_X3Y1_2612ae00.Sublevel_X3Y1:PersistentLevel with 34 objects, 0 referenced clusters and 10 mutable objects. +[2018.11.29-17.17.29:196][844]LogLevelActorContainer: Created LevelActorCluster (5) for /Temp/Game/Athena/Maps/POI/Athena_POI_CommunityPark_001_7af70eac.Athena_POI_CommunityPark_001:PersistentLevel with 526 objects, 0 referenced clusters and 52 mutable objects. +[2018.11.29-17.17.29:223][846]LogDemo: Exceeded maximum desired recording time. Max: 1.800ms. +[2018.11.29-17.17.29:413][855]LogFortWorld: World Generation random stream initialized using seed 17120 +[2018.11.29-17.17.29:526][861]LogLevelActorContainer: Created LevelActorCluster (6) for /Temp/Game/Athena/Maps/POI/Athena_POI_Lake_003_19f667d8.Athena_POI_Lake_003:PersistentLevel with 1166 objects, 0 referenced clusters and 84 mutable objects. +[2018.11.29-17.17.29:579][864]LogLevelActorContainer: Created LevelActorCluster (13) for /Temp/Game/Athena/Maps/Buildings/5x5/Athena_SUB_5x5_House_y_b883a5f1.Athena_SUB_5x5_House_y:PersistentLevel with 6 objects, 0 referenced clusters and 5 mutable objects. +[2018.11.29-17.17.29:661][869]LogLevelActorContainer: Created LevelActorCluster (11) for /Temp/Game/Athena/Maps/Buildings/3x3/Athena_SUB_3x3_GasStation_a_ec691a9b.Athena_SUB_3x3_GasStation_a:PersistentLevel with 24 objects, 0 referenced clusters and 7 mutable objects. +[2018.11.29-17.17.29:679][870]LogLevelActorContainer: Created LevelActorCluster (10) for /Temp/Game/Athena/Maps/Buildings/3x3/Athena_SUB_3x3_House_l_2ad8f1b1.Athena_SUB_3x3_House_l:PersistentLevel with 16 objects, 0 referenced clusters and 9 mutable objects. +[2018.11.29-17.17.29:767][875]LogLevelActorContainer: Created LevelActorCluster (9) for /Temp/Game/Athena/Maps/Buildings/5x5/Athena_SUB_5x5_House2_a_8d477e14.Athena_SUB_5x5_House2_a:PersistentLevel with 36 objects, 0 referenced clusters and 11 mutable objects. +[2018.11.29-17.17.29:779][876]LogLevelActorContainer: Created LevelActorCluster (8) for /Temp/Game/Athena/Maps/Buildings/3x3/Athena_SUB_3x3_House_g_2657fe6d.Athena_SUB_3x3_House_g:PersistentLevel with 32 objects, 0 referenced clusters and 10 mutable objects. +[2018.11.29-17.17.29:813][878]LogLevelActorContainer: Created LevelActorCluster (7) for /Temp/Game/Athena/Maps/Streaming/Sublevel_X3Y2_10a7933d.Sublevel_X3Y2:PersistentLevel with 18 objects, 0 referenced clusters and 9 mutable objects. +[2018.11.29-17.17.29:929][885]LogLevelActorContainer: Created LevelActorCluster (12) for /Temp/Game/Athena/Maps/Streaming/Sublevel_X4Y2_8fff0f93.Sublevel_X4Y2:PersistentLevel with 50 objects, 0 referenced clusters and 10 mutable objects. +[2018.11.29-17.17.30:037][891]LogLevelActorContainer: Created LevelActorCluster (14) for /Temp/Game/Athena/Maps/Buildings/3x3/Athena_SUB_3x3_GasStation_a_2d0e52de.Athena_SUB_3x3_GasStation_a:PersistentLevel with 24 objects, 0 referenced clusters and 7 mutable objects. +[2018.11.29-17.17.30:099][895]LogLevelActorContainer: Created LevelActorCluster (15) for /Temp/Game/Athena/Maps/POI/Athena_POI_Lair_002_d201d995.Athena_POI_Lair_002:PersistentLevel with 512 objects, 0 referenced clusters and 41 mutable objects. +[2018.11.29-17.17.30:252][904]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] AnalyticsET URL:datarouter/api/v1/public/data?SessionID={058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}&AppID=Fortnite.DevLatest&AppVersion=1.0.0 - UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3|e6f5091c3b2f4c359cf2aad75c424de0|e04d67a7-16cd-41f9-b939-be602538533a|fa55e3108f3fc66d6c4ff7eb4398e2a9|&AppEnvironment=datacollector-binary&UploadType=eteventstream. Payload:{"Events":[{"EventName":"Athena.TimeToMatch","DateOffset":"+00:00:31.305","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","PartyId":"C9AE807B4F9D1F30F1535488AB79E7A8","BuildId":"6834","HotfixId":"0","RegionId":"NONE","PlaylistName":"Playlist_DefaultSolo","BucketId":"6834:0:NONE:playlist_defaultsolo","TicketId":"31632b09f88b3092e8cf1c1865149df8","MatchId":"41c9ba3d637d965cdd630db02f458cc7","Phase_ConnectToService":{"Order":0,"UserInput":false,"DidSkip":false,"Time":0.37010027468204498},"Phase_InQueue":{"Order":1,"UserInput":false,"DidSkip":false,"Time":4.1023108623921871},"Phase_InSessionAssignment":{"Order":2,"UserInput":false,"DidSkip":false,"Time":2.1172827929258347},"Phase_JoinSession":{"Order":3,"UserInput":false,"DidSkip":false,"Time":0.81466503441333771},"Phase_LoadMap":{"Order":4,"UserInput":false,"DidSkip":false,"Time":6.2511870078742504},"TotalTime":"13.655546","NonUserInputTime":"13.655546","UserInputTime":"0","CPU":"GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:15.974","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Items/Art_noLOD/Meshes/S_Loot_Stone"},{"EventName":"Core.EndGamePhase_ClientMetrics","DateOffset":"+00:00:15.935","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","GamePhaseName":"Warmup","DurationSec":"15.064671","CPU":"GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz","NetworkType":"Unknown","PingRTT":"11","PacketOverhead":"28","InRate":"4052","OutRate":"2182","InPacketsRate":"30","OutPacketRate":"56","InPacketsLostPercentage":"0","OutPacketsLostPercentage":"0","InBunchesRate":"63","OutBunchesRate":"63","TotalMovementCorrectionDistanceV2":"0","AverageMovementCorrectionDistance":"0","TotalNumMovementCorrectionsPerMinute":"0","OutAcksRate":"60","RPCsCalledRate":"11","RegionId":"NONE","SubRegionId":"","AthenaGamePhase":"Aircraft","AthenaMatchTimeSec":"0.019852","AthenaMapName":"Athena_Terrain","PlaylistName":"Playlist_DefaultSolo"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:01.302","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Athena/Sounds/Weapons/PickAxes/Vuvuzela/PA_Vuvuzela_Swing_06"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:01.293","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_Impact_Sounds/Soccer/Soccer_Ball_Won_Game_Stadium_03"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:01.290","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_Impact_Sounds/Soccer/SoccerBall_Hit_03"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:01.285","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_Impact_Sounds/Demolition/Metal_Cannon_ImpactFinal02"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:01.266","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_Doors/World/Door_PicketFence_Open_04"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:01.261","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_Impact_Sounds/Demolition/Exterior_Props/fence_impact_04"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:01.190","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_Doors/World/door_residential_open_C4"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:01.188","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_Doors/World/door_residential_close_C3"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:00.910","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Athena/Sounds/Events/CubeIsland/CubeIsland_Water_Distant_01"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:00.847","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_Impact_Sounds/Demolition/Interior_Props/oil_drum_impact_03"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:00.742","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Athena/Sounds/Quests/Doorbells/Doorbell_Click_04"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:00.740","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_Doors/World/door_residential_close_A3"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:00.724","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_Doors/World/door_residential_open_A3"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:00.389","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Athena/Sounds/Toys/Toys_GolfBall_Bounce_17"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:00.047","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Trans_AmbientLoops/Fire/Fire_Torch_03"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:00.011","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Athena/Sounds/Weapons/PickAxes/Balloon/PA_Balloon_Swing_06"}]} +[2018.11.29-17.17.30:253][904]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.17.30:253][904]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.17.30:253][904]LogHttp: Verbose: 00000231EB5A72C0: URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.17.30:253][904]LogHttp: Verbose: 00000231EB5A72C0: Verb='POST' +[2018.11.29-17.17.30:253][904]LogHttp: Verbose: 00000231EB5A72C0: Custom headers are present +[2018.11.29-17.17.30:253][904]LogHttp: Verbose: 00000231EB5A72C0: Payload size=6781 +[2018.11.29-17.17.30:253][904]LogHttp: Verbose: 00000231EB5A72C0: Adding header 'Content-Type: application/json; charset=utf-8' +[2018.11.29-17.17.30:253][904]LogHttp: Verbose: 00000231EB5A72C0: Adding header 'User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.17.30:253][904]LogHttp: Verbose: 00000231EB5A72C0: Adding header 'Content-Length: 6781' +[2018.11.29-17.17.30:253][904]LogHttp: Verbose: 00000231EB5A72C0: Adding header 'Expect: ' +[2018.11.29-17.17.30:253][904]LogHttp: 00000231EB5A72C0: Starting POST request to URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.17.30:253][904]LogHttp: Verbose: 00000231EB5A72C0: request (easy handle:00000231EB7D0010) has been added to threaded queue for processing +[2018.11.29-17.17.30:257][904]LogFortWorld: World Generation random stream initialized using seed 29754 +[2018.11.29-17.17.30:276][905]LogHttp: Verbose: 00000231EB5A72C0: request (easy handle:00000231EB7D0010) has started threaded processing +[2018.11.29-17.17.30:276][905]LogHttp: VeryVerbose: 00000231EB5A72C0: 'Found bundle for host datarouter.ol.epicgames.com: 0x231a91dc070 [can pipeline]' +[2018.11.29-17.17.30:276][905]LogHttp: VeryVerbose: 00000231EB5A72C0: 'Re-using existing connection! (#15) with host datarouter.ol.epicgames.com' +[2018.11.29-17.17.30:277][905]LogHttp: VeryVerbose: 00000231EB5A72C0: 'Connected to datarouter.ol.epicgames.com (18.235.16.110) port 443 (#15)' +[2018.11.29-17.17.30:277][905]LogHttp: VeryVerbose: 00000231EB5A72C0: Sent SSL data (5 bytes) +[2018.11.29-17.17.30:277][905]LogHttp: VeryVerbose: 00000231EB5A72C0: Sent header (582 bytes) - POST /datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream HTTP/1.1Host: datarouter.ol.epicgames.comAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/json; charset=utf-8User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Length: 6781 +[2018.11.29-17.17.30:277][905]LogHttp: Verbose: 00000231EB5A72C0: UploadCallback: 6781 bytes out of 6781 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=6781 (<-this will get returned from the callback)) +[2018.11.29-17.17.30:277][905]LogHttp: VeryVerbose: 00000231EB5A72C0: Sent SSL data (5 bytes) +[2018.11.29-17.17.30:277][905]LogHttp: VeryVerbose: 00000231EB5A72C0: Sent data (6781 bytes) +[2018.11.29-17.17.30:277][905]LogHttp: VeryVerbose: 00000231EB5A72C0: 'We are completely uploaded and fine' +[2018.11.29-17.17.30:277][905]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.17.30:277][905]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.17.30:285][905]LogLevelActorContainer: Created LevelActorCluster (16) for /Temp/Game/Athena/Maps/Buildings/5x5/Athena_SUB_5x5_House_q_8053ede4.Athena_SUB_5x5_House_q:PersistentLevel with 8 objects, 0 referenced clusters and 7 mutable objects. +[2018.11.29-17.17.30:287][906]LogHttp: VeryVerbose: 00000231EB5A72C0: Received SSL data (5 bytes) +[2018.11.29-17.17.30:287][906]LogHttp: VeryVerbose: 00000231EB5A72C0: Received header (25 bytes) +[2018.11.29-17.17.30:287][906]LogHttp: Verbose: 00000231EB5A72C0: Received response header 'HTTP/1.1 204 No Content'. +[2018.11.29-17.17.30:287][906]LogHttp: VeryVerbose: 00000231EB5A72C0: Received header (37 bytes) +[2018.11.29-17.17.30:287][906]LogHttp: Verbose: 00000231EB5A72C0: Received response header 'Date: Thu, 29 Nov 2018 17:17:30 GMT'. +[2018.11.29-17.17.30:287][906]LogHttp: VeryVerbose: 00000231EB5A72C0: Received header (24 bytes) +[2018.11.29-17.17.30:287][906]LogHttp: Verbose: 00000231EB5A72C0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.17.30:287][906]LogHttp: VeryVerbose: 00000231EB5A72C0: Received header (32 bytes) +[2018.11.29-17.17.30:287][906]LogHttp: Verbose: 00000231EB5A72C0: Received response header 'Access-Control-Allow-Origin: *'. +[2018.11.29-17.17.30:287][906]LogHttp: VeryVerbose: 00000231EB5A72C0: Received header (61 bytes) +[2018.11.29-17.17.30:287][906]LogHttp: Verbose: 00000231EB5A72C0: Received response header 'X-Epic-Correlation-ID: e9dce717-2258-4462-8897-ff401e1512a2'. +[2018.11.29-17.17.30:287][906]LogHttp: Verbose: 00000231EB5A72C0: Received response header ''. +[2018.11.29-17.17.30:287][906]LogHttp: VeryVerbose: 00000231EB5A72C0: Received header (2 bytes) +[2018.11.29-17.17.30:287][906]LogHttp: VeryVerbose: 00000231EB5A72C0: 'Connection #15 to host datarouter.ol.epicgames.com left intact' +[2018.11.29-17.17.30:287][906]LogHttp: Verbose: Request 00000231EB5A72C0 (easy handle:00000231EB7D0010) has completed (code:0) and has been marked as such +[2018.11.29-17.17.30:294][906]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.30:294][906]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.30:295][906]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.30:295][906]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.30:295][906]LogHttp: 00000231EB5A72C0: request has been successfully processed. URL: https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream, HTTP code: 204, content length: 0, actual payload size: 0 +[2018.11.29-17.17.30:295][906]LogHttp: Verbose: 00000231EB5A72C0 Response Header Date: Thu, 29 Nov 2018 17:17:30 GMT +[2018.11.29-17.17.30:295][906]LogHttp: Verbose: 00000231EB5A72C0 Response Header Connection: keep-alive +[2018.11.29-17.17.30:295][906]LogHttp: Verbose: 00000231EB5A72C0 Response Header Access-Control-Allow-Origin: * +[2018.11.29-17.17.30:295][906]LogHttp: Verbose: 00000231EB5A72C0 Response Header X-Epic-Correlation-ID: e9dce717-2258-4462-8897-ff401e1512a2 +[2018.11.29-17.17.30:295][906]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.17.30:296][906]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.17.30:296][906]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.17.30:296][906]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] ET response for [https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream]. Code: 204. Payload: +[2018.11.29-17.17.30:362][909]LogLevelActorContainer: Created LevelActorCluster (17) for /Temp/Game/Athena/Maps/POI/Athena_POI_Cemetery_002_350f9d0a.Athena_POI_Cemetery_002:PersistentLevel with 18 objects, 0 referenced clusters and 7 mutable objects. +[2018.11.29-17.17.30:382][910]LogLevelActorContainer: Created LevelActorCluster (18) for /Temp/Game/Athena/Maps/Buildings/5x5/Athena_SUB_5x5_House_m_c7147cfa.Athena_SUB_5x5_House_m:PersistentLevel with 6 objects, 0 referenced clusters and 5 mutable objects. +[2018.11.29-17.17.30:445][914]LogLevelActorContainer: Created LevelActorCluster (19) for /Temp/Game/Athena/Maps/Buildings/5x5/Athena_SUB_5x5_House_g_d7639ae5.Athena_SUB_5x5_House_g:PersistentLevel with 12 objects, 0 referenced clusters and 5 mutable objects. +[2018.11.29-17.17.30:480][916]LogLevelActorContainer: Created LevelActorCluster (20) for /Temp/Game/Athena/Maps/Streaming/Sublevel_X4Y0_8f8f5ed9.Sublevel_X4Y0:PersistentLevel with 12 objects, 0 referenced clusters and 4 mutable objects. +[2018.11.29-17.17.30:543][920]LogLevelActorContainer: Created LevelActorCluster (21) for /Temp/Game/Athena/Maps/Streaming/Sublevel_X3Y0_11c7c328.Sublevel_X3Y0:PersistentLevel with 60 objects, 0 referenced clusters and 16 mutable objects. +[2018.11.29-17.17.30:759][931]LogLevelActorContainer: Created LevelActorCluster (22) for /Temp/Game/Athena/Maps/POI/Athena_POI_Lake_003b_59ac2dcf.Athena_POI_Lake_003b:PersistentLevel with 88 objects, 0 referenced clusters and 23 mutable objects. +[2018.11.29-17.17.30:857][937]LogLevelActorContainer: Created LevelActorCluster (23) for /Temp/Game/Athena/Maps/Buildings/5x5/Athena_REM_5x5_Special_HermitHouse_a_c746db50.Athena_REM_5x5_Special_HermitHouse_a:PersistentLevel with 6 objects, 0 referenced clusters and 5 mutable objects. +[2018.11.29-17.17.31:119][951]LogLevelActorContainer: Created LevelActorCluster (24) for /Temp/Game/Athena/Maps/POI/Athena_POI_City_001_336e530d.Athena_POI_City_001:PersistentLevel with 598 objects, 0 referenced clusters and 66 mutable objects. +[2018.11.29-17.17.31:153][953]LogLevelActorContainer: Created LevelActorCluster (25) for /Temp/Game/Athena/Maps/POI/Athena_POI_REC_001_2d9db526.Athena_POI_REC_001:PersistentLevel with 24 objects, 0 referenced clusters and 5 mutable objects. +[2018.11.29-17.17.42:322][623]LogLocalFileReplay: FLocalFileNetworkReplayStreamer::FlushStream. StreamChunkIndex: 1, Size: 105137 +[2018.11.29-17.17.49:804][ 72]LogFortAnalyticsEvent: Display: Core.EndGamePhase_ClientMetrics: CurrentGamePhaseName: Aircraft DurationSec: 35.485965 CPU: GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz NetworkType: 0 PingRTT: 1 PacketOverhead: 28 InRate: 2949 OutRate: 3312 InPacketsRate: 30 OutPacketRate: 59 InPacketsLostPercentage: 0.00 OutPacketsLostPercentage: 0.00 InBunchesRate: 26 OutBunchesRate: 26 TotalMovementCorrectionDistanceV2: 0 AverageMovementCorrectionDistance: 0 TotalNumMovementCorrectionsPerMinute: 0.000000 OutAcksRate: 61 RPCsCalledRate: 56 +[2018.11.29-17.17.57:271][520]FortClientBot: {"event": "BotStatus", "bot": "", "statusvalue": 0, "statusstring": "ControllerInitialized", "timeincurrentstate": 60 } +[2018.11.29-17.17.57:274][521]FortClientBot: {"event": "BotStatus", "bot": "LoadBot07063", "statusvalue": 9, "statusstring": "InMatch", "timeincurrentstate": 60 , "xPos": "71297", "yPos":"-78998", "health":"1.000", "enemyTarget":"None", "structureTarget":"None"} +[2018.11.29-17.17.57:839][554]LogFortMemory: Heartbeat - CPU:1441.37MB (Peak: 2588.52MB) +[2018.11.29-17.17.59:876][677]LogXmpp: Verbose: Sending Client-To-Server XMPP Ping +[2018.11.29-17.17.59:876][677]LogXmpp: VeryVerbose: libstrophe[71688] conn debug: SENT: +[2018.11.29-17.17.59:876][677]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.17.59:876][677]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.17.59:892][678]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::SendFromQueue: Wrote 241 bytes, 0 bytes remaining in this packet +[2018.11.29-17.18.00:007][685]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=233 BytesLeft=0 +[2018.11.29-17.18.00:007][685]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: RECV: +[2018.11.29-17.18.00:007][685]LogXmpp: Verbose: Received Strophe XMPP Stanza iq +[2018.11.29-17.18.00:007][685]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.18.00:007][685]LogXmpp: VeryVerbose: iq Stanza handled by Ping +[2018.11.29-17.18.00:025][686]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Pong +[2018.11.29-17.18.02:206][816]LogFortMemory: Heartbeat - CPU:1440.90MB (Peak: 2588.52MB) +[2018.11.29-17.18.02:209][817]LogDemo: Starting checkpoint. Actors: 131 +[2018.11.29-17.18.02:323][823]LogLocalFileReplay: FLocalFileNetworkReplayStreamer::FlushStream. StreamChunkIndex: 2, Size: 51816 +[2018.11.29-17.18.02:341][825]LogDemo: Finished checkpoint. Actors: 131, GuidCacheSize: 166798, TotalSize: 200700, TotalCheckpointSaveFrames: 8, TotalCheckpointTimeInMS: 8.24, TotalCheckpointTimeWithOverheadInMS: 10.25 +[2018.11.29-17.18.03:309][883]LogNet: NotifyStreamingLevelUnload: Level /Temp/Game/Athena/Maps/POI/Athena_POI_Lobby_001_3f5ab45c.Athena_POI_Lobby_001:PersistentLevel +[2018.11.29-17.18.03:313][883]LogGarbage: Collecting garbage (GCheckForIllegalMarkPendingKill = 1) +[2018.11.29-17.18.03:323][883]LogGarbage: 9.763226 ms for Verify GC Assumptions +[2018.11.29-17.18.03:360][883]LogGarbage: 37.162509 ms for GC +[2018.11.29-17.18.03:360][883]LogGarbage: 0.001208 ms for dissolving GC clusters +[2018.11.29-17.18.03:361][883]LogGarbage: 0.496297 ms for Gather Unreachable Objects (6360 objects collected including 0 cluster objects from 0 clusters) +[2018.11.29-17.18.03:369][884]LogGarbage: 2.003301 ms for incrementally unhashing unreachable objects. Items 1551 (1551/6360) +[2018.11.29-17.18.03:386][885]LogGarbage: 2.009037 ms for incrementally unhashing unreachable objects. Items 1711 (3262/6360) +[2018.11.29-17.18.03:405][886]LogGarbage: 2.002396 ms for incrementally unhashing unreachable objects. Items 1121 (4383/6360) +[2018.11.29-17.18.03:420][887]LogGarbage: 2.010245 ms for incrementally unhashing unreachable objects. Items 1521 (5904/6360) +[2018.11.29-17.18.03:435][888]LogGarbage: 0.945802 ms for incrementally unhashing unreachable objects. Items 456 (6360/6360) +[2018.11.29-17.18.03:620][899]LogGarbage: GC purged 6360 objects (564739 -> 558379) +[2018.11.29-17.18.18:158][771]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.18.18:159][771]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.18.18:159][771]LogHttp: Verbose: 00000231EF45FEC0: URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/verify' +[2018.11.29-17.18.18:159][771]LogHttp: Verbose: 00000231EF45FEC0: Verb='GET' +[2018.11.29-17.18.18:159][771]LogHttp: Verbose: 00000231EF45FEC0: Custom headers are present +[2018.11.29-17.18.18:159][771]LogHttp: Verbose: 00000231EF45FEC0: Payload size=0 +[2018.11.29-17.18.18:159][771]LogHttp: Verbose: 00000231EF45FEC0: Adding header 'X-Epic-Correlation-ID: FN-BDGlSva5Y0_5Hpq41WHA2g' +[2018.11.29-17.18.18:159][771]LogHttp: Verbose: 00000231EF45FEC0: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.18.18:159][771]LogHttp: Verbose: 00000231EF45FEC0: Adding header 'Content-Type: application/json' +[2018.11.29-17.18.18:159][771]LogHttp: Verbose: 00000231EF45FEC0: Adding header 'Content-Length: 0' +[2018.11.29-17.18.18:159][771]LogHttp: Verbose: 00000231EF45FEC0: Adding header 'Expect: ' +[2018.11.29-17.18.18:159][771]LogHttp: 00000231EF45FEC0: Starting GET request to URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/verify' +[2018.11.29-17.18.18:159][771]LogHttp: Verbose: 00000231EF45FEC0: request (easy handle:00000231901F5560) has been added to threaded queue for processing +[2018.11.29-17.18.18:192][773]LogHttp: Verbose: 00000231EF45FEC0: request (easy handle:00000231901F5560) has started threaded processing +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Connection 16 seems to be dead!' +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Closing connection 16' +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (5 bytes) +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (2 bytes) +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Connection 7 seems to be dead!' +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Closing connection 7' +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (5 bytes) +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (2 bytes) +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Connection 11 seems to be dead!' +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Closing connection 11' +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (5 bytes) +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.18.18:192][773]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (2 bytes) +[2018.11.29-17.18.18:208][774]LogHttp: VeryVerbose: 00000231EF45FEC0: ' Trying 10.40.239.9...' +[2018.11.29-17.18.18:208][774]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TCP_NODELAY set' +[2018.11.29-17.18.18:242][776]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Connected to account-public-service-gamedev.ol.epicgames.net (10.40.239.9) port 443 (#17)' +[2018.11.29-17.18.18:259][777]LogHttp: VeryVerbose: 00000231EF45FEC0: 'ALPN, offering http/1.1' +[2018.11.29-17.18.18:259][777]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.18.18:259][777]LogHttp: VeryVerbose: 00000231EF45FEC0: 'SSL re-using session ID' +[2018.11.29-17.18.18:259][777]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (5 bytes) +[2018.11.29-17.18.18:259][777]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.18.18:259][777]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (512 bytes) +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (5 bytes) +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (96 bytes) +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (5 bytes) +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (1 bytes) +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (5 bytes) +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (16 bytes) +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (5 bytes) +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (1 bytes) +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (5 bytes) +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (16 bytes) +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Server certificate:' +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: ' subjectAltName: host "account-public-service-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: ' SSL certificate verify ok.' +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (5 bytes) +[2018.11.29-17.18.18:292][779]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent header (1023 bytes) - GET /account/api/oauth/verify HTTP/1.1Host: account-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-BDGlSva5Y0_5Hpq41WHA2gUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Type: application/jsonAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM0RoMXFQVm9LNXp2M1J0TjZCUUM3QUJ1UGJTcT +[2018.11.29-17.18.18:342][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (5 bytes) +[2018.11.29-17.18.18:342][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (17 bytes) +[2018.11.29-17.18.18:343][782]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.18.18:343][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (37 bytes) +[2018.11.29-17.18.18:343][782]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'Date: Thu, 29 Nov 2018 17:18:18 GMT'. +[2018.11.29-17.18.18:343][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (32 bytes) +[2018.11.29-17.18.18:343][782]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'Content-Type: application/json'. +[2018.11.29-17.18.18:343][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (28 bytes) +[2018.11.29-17.18.18:343][782]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'Transfer-Encoding: chunked'. +[2018.11.29-17.18.18:343][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (24 bytes) +[2018.11.29-17.18.18:343][782]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.18.18:343][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (23 bytes) +[2018.11.29-17.18.18:343][782]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'Vary: Accept-Encoding'. +[2018.11.29-17.18.18:343][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (49 bytes) +[2018.11.29-17.18.18:343][782]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'Cache-Control: no-cache, no-store, no-transform'. +[2018.11.29-17.18.18:343][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (52 bytes) +[2018.11.29-17.18.18:343][782]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.18.18:343][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (50 bytes) +[2018.11.29-17.18.18:343][782]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'X-Epic-Correlation-ID: FN-BDGlSva5Y0_5Hpq41WHA2g'. +[2018.11.29-17.18.18:343][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (22 bytes) +[2018.11.29-17.18.18:343][782]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'X-Epic-From-Cache: 1'. +[2018.11.29-17.18.18:343][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (24 bytes) +[2018.11.29-17.18.18:343][782]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'Content-Encoding: gzip'. +[2018.11.29-17.18.18:343][782]LogHttp: Verbose: 00000231EF45FEC0: Received response header ''. +[2018.11.29-17.18.18:343][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (2 bytes) +[2018.11.29-17.18.18:343][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received data (1855 bytes) +[2018.11.29-17.18.18:343][782]LogHttp: Verbose: 00000231EF45FEC0: ReceiveResponseBodyCallback: 2584 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=2584, Response->TotalBytesRead=0, Response->GetContentLength()=0, SizeToDownload=2584 (<-this will get returned from the callback)) +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (5 bytes) +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: 00000231EF45FEC0: Received data (5 bytes) +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Connection #17 to host account-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.18.18:345][782]LogHttp: Verbose: Request 00000231EF45FEC0 (easy handle:00000231901F5560) has completed (code:0) and has been marked as such +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.18:345][782]LogHttp: 00000231EF45FEC0: request has been successfully processed. URL: https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/verify, HTTP code: 200, content length: -1, actual payload size: 2584 +[2018.11.29-17.18.18:345][782]LogHttp: Verbose: 00000231EF45FEC0 Response Header Date: Thu, 29 Nov 2018 17:18:18 GMT +[2018.11.29-17.18.18:345][782]LogHttp: Verbose: 00000231EF45FEC0 Response Header Content-Type: application/json +[2018.11.29-17.18.18:345][782]LogHttp: Verbose: 00000231EF45FEC0 Response Header Transfer-Encoding: chunked +[2018.11.29-17.18.18:345][782]LogHttp: Verbose: 00000231EF45FEC0 Response Header Connection: keep-alive +[2018.11.29-17.18.18:345][782]LogHttp: Verbose: 00000231EF45FEC0 Response Header Vary: Accept-Encoding +[2018.11.29-17.18.18:345][782]LogHttp: Verbose: 00000231EF45FEC0 Response Header Cache-Control: no-cache, no-store, no-transform +[2018.11.29-17.18.18:345][782]LogHttp: Verbose: 00000231EF45FEC0 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.18.18:345][782]LogHttp: Verbose: 00000231EF45FEC0 Response Header X-Epic-Correlation-ID: FN-BDGlSva5Y0_5Hpq41WHA2g +[2018.11.29-17.18.18:345][782]LogHttp: Verbose: 00000231EF45FEC0 Response Header X-Epic-From-Cache: 1 +[2018.11.29-17.18.18:345][782]LogHttp: Verbose: 00000231EF45FEC0 Response Header Content-Encoding: gzip +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.18:345][782]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.18.22:324][ 20]LogLocalFileReplay: FLocalFileNetworkReplayStreamer::FlushStream. StreamChunkIndex: 3, Size: 71779 +[2018.11.29-17.18.27:280][316]FortClientBot: {"event": "BotStatus", "bot": "", "statusvalue": 0, "statusstring": "ControllerInitialized", "timeincurrentstate": 90 } +[2018.11.29-17.18.27:284][317]FortClientBot: {"event": "BotStatus", "bot": "LoadBot07063", "statusvalue": 9, "statusstring": "InMatch", "timeincurrentstate": 90 , "xPos": "71297", "yPos":"-78998", "health":"1.000", "enemyTarget":"None", "structureTarget":"None"} +[2018.11.29-17.18.30:504][510]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] AnalyticsET URL:datarouter/api/v1/public/data?SessionID={058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}&AppID=Fortnite.DevLatest&AppVersion=1.0.0 - UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3|e6f5091c3b2f4c359cf2aad75c424de0|e04d67a7-16cd-41f9-b939-be602538533a|fa55e3108f3fc66d6c4ff7eb4398e2a9|&AppEnvironment=datacollector-binary&UploadType=eteventstream. Payload:{"Events":[{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:59.998","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_Impact_Sounds/Demolition/Interior_Props/Computer_Impact_03"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:59.673","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_Doors/World/metal_fence_big_open_02"},{"EventName":"Core.EndGamePhase_ClientMetrics","DateOffset":"+00:00:40.700","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","GamePhaseName":"Aircraft","DurationSec":"35.485965","CPU":"GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz","NetworkType":"Unknown","PingRTT":"1","PacketOverhead":"28","InRate":"2949","OutRate":"3312","InPacketsRate":"30","OutPacketRate":"59","InPacketsLostPercentage":"0","OutPacketsLostPercentage":"0","InBunchesRate":"26","OutBunchesRate":"26","TotalMovementCorrectionDistanceV2":"0","AverageMovementCorrectionDistance":"0","TotalNumMovementCorrectionsPerMinute":"0","OutAcksRate":"61","RPCsCalledRate":"56","RegionId":"NONE","SubRegionId":"","AthenaGamePhase":"SafeZones","AthenaMatchTimeSec":"35.500473","AthenaMapName":"Athena_Terrain","PlaylistName":"Playlist_DefaultSolo"},{"EventName":"BotContextLocationPerMinute","DateOffset":"+00:00:33.230","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","AccountName":"LoadBot07063","Location":"InMatch","TimeInState":"60.01622"},{"EventName":"PlayerContextLocationPerMinute","DateOffset":"+00:00:32.665","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","Locations":"-116614.688,-121561.180,3917.150,0.000;-116614.688,-121561.180,3917.150,0.000;-116614.688,-121561.180,3917.150,0.000;0.000,0.000,0.000,3.566;0.000,0.000,0.000,8.632;0.000,0.000,0.000,13.621;71299.008,-79000.531,76174.328,18.586;71297.484,-78997.859,70174.180,23.583;71297.484,-78997.859,64173.973,28.622;71297.484,-78997.859,58173.734,33.618;71297.484,-78997.859,52173.516,38.551;71297.484,-78997.859,46173.387,43.565","Location":"InGame","IsIdle":"false","RegionId":"NONE","SubRegionId":"","PreferredSubRegionId":"","PlayerLevel":"0","NetworkType":"Unknown","TemperatureLevel":"-1","BatteryLevel":"-1","IsRunningOnBattery":"false","CPU":"GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz","AthenaGamePhase":"SafeZones","AthenaSafeZoneCenter":"0.000,0.000,0.000","AthenaSafeZoneRadius":"0","AthenaSafeZoneState":"None","AthenaSafeZonePhase":"0","AthenaMatchTimeSec":"43.564812","AthenaPlayersLeft":"1","AthenaTeamsLeft":"1","AthenaMapName":"Athena_Terrain","PlaylistName":"Playlist_DefaultSolo","AthenaTeamNumber":"1","AthenaTeammatesLeft":"0","AthenaPlayerStatus":"Alive","PlayerLocation":"71297.484,-78997.859,46173.387","PlayerPOITags":"","SocialPartyCount":"1","SocialPartyPlatforms":"PC"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:26.640","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Athena/Items/ForagedItems/Rift/BGA_RiftPortal_Athena"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:19.088","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Athena/Environments/Meshes/S_Rocket_Ammo"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:19.085","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Foley_Loot/Ingredients/Munitions/Rockets_Collect_Surreal"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:19.021","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_Gadgets/Teleporter/grenade_pickup_Athena_Cue"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:18.920","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Items/Art_noLOD/Meshes/MedKit"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:18.820","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Athena/Items/Consumables/ShieldSmall/Items_SmallShieldPotion_01"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:18.434","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_Gadgets/Teleporter/bandage_pickup_Athena_Cue"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:18.433","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Sounds/Fort_GamePlay_Sounds/Explosives/Grenade_Sticky_Pickup_Cue"}]} +[2018.11.29-17.18.30:505][510]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.18.30:505][510]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.18.30:505][510]LogHttp: Verbose: 00000231EF45FEC0: URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.18.30:505][510]LogHttp: Verbose: 00000231EF45FEC0: Verb='POST' +[2018.11.29-17.18.30:506][510]LogHttp: Verbose: 00000231EF45FEC0: Custom headers are present +[2018.11.29-17.18.30:506][510]LogHttp: Verbose: 00000231EF45FEC0: Payload size=5437 +[2018.11.29-17.18.30:506][510]LogHttp: Verbose: 00000231EF45FEC0: Adding header 'Content-Type: application/json; charset=utf-8' +[2018.11.29-17.18.30:506][510]LogHttp: Verbose: 00000231EF45FEC0: Adding header 'User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.18.30:506][510]LogHttp: Verbose: 00000231EF45FEC0: Adding header 'Content-Length: 5437' +[2018.11.29-17.18.30:506][510]LogHttp: Verbose: 00000231EF45FEC0: Adding header 'Expect: ' +[2018.11.29-17.18.30:506][510]LogHttp: 00000231EF45FEC0: Starting POST request to URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.18.30:506][510]LogHttp: Verbose: 00000231EF45FEC0: request (easy handle:00000231901F5560) has been added to threaded queue for processing +[2018.11.29-17.18.30:519][511]LogHttp: Verbose: 00000231EF45FEC0: request (easy handle:00000231901F5560) has started threaded processing +[2018.11.29-17.18.30:519][511]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Connection 15 seems to be dead!' +[2018.11.29-17.18.30:519][511]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Closing connection 15' +[2018.11.29-17.18.30:519][511]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (5 bytes) +[2018.11.29-17.18.30:519][511]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.18.30:519][511]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (2 bytes) +[2018.11.29-17.18.30:521][511]LogHttp: VeryVerbose: 00000231EF45FEC0: ' Trying 34.194.131.148...' +[2018.11.29-17.18.30:521][511]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TCP_NODELAY set' +[2018.11.29-17.18.30:535][512]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Connected to datarouter.ol.epicgames.com (34.194.131.148) port 443 (#18)' +[2018.11.29-17.18.30:550][513]LogHttp: VeryVerbose: 00000231EF45FEC0: 'ALPN, offering http/1.1' +[2018.11.29-17.18.30:550][513]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.18.30:550][513]LogHttp: VeryVerbose: 00000231EF45FEC0: 'SSL re-using session ID' +[2018.11.29-17.18.30:550][513]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (5 bytes) +[2018.11.29-17.18.30:550][513]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.18.30:550][513]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (512 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (5 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (104 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (5 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (IN), TLS handshake, Certificate (11):' +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (4568 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (5 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (IN), TLS handshake, Server key exchange (12):' +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (333 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (5 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (IN), TLS handshake, Server finished (14):' +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (4 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (5 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (OUT), TLS handshake, Client key exchange (16):' +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (70 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (5 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (1 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (5 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (16 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (5 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (1 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (5 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (16 bytes) +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.18.30:566][514]LogHttp: VeryVerbose: 00000231EF45FEC0: 'old SSL session ID is stale, removing' +[2018.11.29-17.18.30:567][514]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Server certificate:' +[2018.11.29-17.18.30:567][514]LogHttp: VeryVerbose: 00000231EF45FEC0: ' subject: CN=*.ol.epicgames.com' +[2018.11.29-17.18.30:567][514]LogHttp: VeryVerbose: 00000231EF45FEC0: ' start date: Mar 12 00:00:00 2018 GMT' +[2018.11.29-17.18.30:567][514]LogHttp: VeryVerbose: 00000231EF45FEC0: ' expire date: Apr 12 12:00:00 2019 GMT' +[2018.11.29-17.18.30:567][514]LogHttp: VeryVerbose: 00000231EF45FEC0: ' subjectAltName: host "datarouter.ol.epicgames.com" matched cert's "*.ol.epicgames.com"' +[2018.11.29-17.18.30:567][514]LogHttp: VeryVerbose: 00000231EF45FEC0: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.18.30:567][514]LogHttp: VeryVerbose: 00000231EF45FEC0: ' SSL certificate verify ok.' +[2018.11.29-17.18.30:567][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (5 bytes) +[2018.11.29-17.18.30:567][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent header (582 bytes) - POST /datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream HTTP/1.1Host: datarouter.ol.epicgames.comAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/json; charset=utf-8User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Length: 5437 +[2018.11.29-17.18.30:567][514]LogHttp: Verbose: 00000231EF45FEC0: UploadCallback: 5437 bytes out of 5437 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=5437 (<-this will get returned from the callback)) +[2018.11.29-17.18.30:567][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent SSL data (5 bytes) +[2018.11.29-17.18.30:567][514]LogHttp: VeryVerbose: 00000231EF45FEC0: Sent data (5437 bytes) +[2018.11.29-17.18.30:567][514]LogHttp: VeryVerbose: 00000231EF45FEC0: 'We are completely uploaded and fine' +[2018.11.29-17.18.30:568][514]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.18.30:568][514]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.18.30:583][515]LogHttp: VeryVerbose: 00000231EF45FEC0: Received SSL data (5 bytes) +[2018.11.29-17.18.30:583][515]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (25 bytes) +[2018.11.29-17.18.30:583][515]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'HTTP/1.1 204 No Content'. +[2018.11.29-17.18.30:583][515]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (37 bytes) +[2018.11.29-17.18.30:583][515]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'Date: Thu, 29 Nov 2018 17:18:30 GMT'. +[2018.11.29-17.18.30:583][515]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (24 bytes) +[2018.11.29-17.18.30:583][515]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'Connection: keep-alive'. +[2018.11.29-17.18.30:583][515]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (32 bytes) +[2018.11.29-17.18.30:583][515]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'Access-Control-Allow-Origin: *'. +[2018.11.29-17.18.30:583][515]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (61 bytes) +[2018.11.29-17.18.30:583][515]LogHttp: Verbose: 00000231EF45FEC0: Received response header 'X-Epic-Correlation-ID: 7b89aee8-116f-4e9a-ae76-dffa32cb432d'. +[2018.11.29-17.18.30:583][515]LogHttp: Verbose: 00000231EF45FEC0: Received response header ''. +[2018.11.29-17.18.30:583][515]LogHttp: VeryVerbose: 00000231EF45FEC0: Received header (2 bytes) +[2018.11.29-17.18.30:583][515]LogHttp: VeryVerbose: 00000231EF45FEC0: 'Connection #18 to host datarouter.ol.epicgames.com left intact' +[2018.11.29-17.18.30:584][515]LogHttp: Verbose: Request 00000231EF45FEC0 (easy handle:00000231901F5560) has completed (code:0) and has been marked as such +[2018.11.29-17.18.30:584][515]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.30:584][515]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.30:584][515]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.30:584][515]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.30:584][515]LogHttp: 00000231EF45FEC0: request has been successfully processed. URL: https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream, HTTP code: 204, content length: 0, actual payload size: 0 +[2018.11.29-17.18.30:584][515]LogHttp: Verbose: 00000231EF45FEC0 Response Header Date: Thu, 29 Nov 2018 17:18:30 GMT +[2018.11.29-17.18.30:584][515]LogHttp: Verbose: 00000231EF45FEC0 Response Header Connection: keep-alive +[2018.11.29-17.18.30:584][515]LogHttp: Verbose: 00000231EF45FEC0 Response Header Access-Control-Allow-Origin: * +[2018.11.29-17.18.30:584][515]LogHttp: Verbose: 00000231EF45FEC0 Response Header X-Epic-Correlation-ID: 7b89aee8-116f-4e9a-ae76-dffa32cb432d +[2018.11.29-17.18.30:584][515]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.18.30:601][516]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.18.30:601][516]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.18.30:601][516]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] ET response for [https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream]. Code: 204. Payload: +[2018.11.29-17.18.42:333][219]LogLocalFileReplay: FLocalFileNetworkReplayStreamer::FlushStream. StreamChunkIndex: 4, Size: 52244 +[2018.11.29-17.18.45:632][417]LogInit: Selected Device Profile: [WindowsClient] +[2018.11.29-17.18.45:632][417]LogInit: Selected Device Profile: [WindowsClient] +[2018.11.29-17.18.46:168][418]LogCore: Error: Hitch detected on gamethread (frame hasn't finished for 501.93ms): +[2018.11.29-17.18.46:168][418]LogCore: Error: ------Stack start +[2018.11.29-17.18.46:168][418]LogCore: Error: 0x00007ff797c5e719 +[2018.11.29-17.18.46:168][418]LogCore: Error: 0x00007ff797c5bef7 +[2018.11.29-17.18.46:168][418]LogCore: Error: 0x00007ff797c5ce15 +[2018.11.29-17.18.46:168][418]LogCore: Error: 0x00007ff797c52eb6 +[2018.11.29-17.18.46:168][418]LogCore: Error: 0x00007ff797c53d6d +[2018.11.29-17.18.46:168][418]LogCore: Error: 0x00007ff797c46f8b +[2018.11.29-17.18.46:168][418]LogCore: Error: 0x00007ff797c476c1 +[2018.11.29-17.18.46:168][418]LogCore: Error: 0x00007ff793344559 +[2018.11.29-17.18.46:168][418]LogCore: Error: 0x00007ff793345072 +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ff79629dd18 +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ff792be9f69 +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ff795750597 +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ff7957055b6 +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ff7962ab1d0 +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ff79567bdb0 +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ff79568dd68 +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ff791854697 +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ff78fd9885d +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ff78fda7c7f +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ff78fda7d3a +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ff78fdb79b1 +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ff798164a52 +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ffc1bb71fe4 +[2018.11.29-17.18.46:169][418]LogCore: Error: 0x00007ffc1bcacb31 +[2018.11.29-17.18.46:169][418]LogCore: Error: ------Stack end +[2018.11.29-17.18.46:170][418]LogCore: Error: ## Stack tracing took 0.012368 seconds. +[2018.11.29-17.18.46:170][418]LogCore: Error: Leaving hitch detector (+ 514.35ms) +[2018.11.29-17.18.46:172][418]LogFortHitches: HITCHHUNTER: Hitch in RenderThread of 540.3 ms has been detected this frame. Number of Draw Calls this Frame: 1575 +[2018.11.29-17.18.57:422][ 82]FortClientBot: {"event": "BotStatus", "bot": "", "statusvalue": 0, "statusstring": "ControllerInitialized", "timeincurrentstate": 120 } +[2018.11.29-17.18.57:789][104]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.18.57:790][104]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.18.57:790][104]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.18.57:790][104]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.18.57:790][104]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.18.57:790][104]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.18.57:791][104]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.18.57:791][104]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.18.57:791][104]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.18.57:791][104]LogFort: QuickBarItemAddedToInventory. Item: FortWorldItem_2147473459 Bandage with GUID: -531658875 1186386899 1734084518 829587739 +[2018.11.29-17.18.57:973][115]LogFortMemory: Heartbeat - CPU:1450.52MB (Peak: 2678.38MB) +[2018.11.29-17.19.00:033][239]LogXmpp: Verbose: Sending Client-To-Server XMPP Ping +[2018.11.29-17.19.00:033][239]LogXmpp: VeryVerbose: libstrophe[71688] conn debug: SENT: +[2018.11.29-17.19.00:033][239]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.19.00:033][239]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.19.00:042][240]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::SendFromQueue: Wrote 241 bytes, 0 bytes remaining in this packet +[2018.11.29-17.19.00:109][244]LogWebSockets: VeryVerbose: FLwsWebSocket[1]::LwsCallback: Received LWS_CALLBACK_CLIENT_RECEIVE Length=233 BytesLeft=0 +[2018.11.29-17.19.00:112][244]LogXmpp: VeryVerbose: libstrophe[71688] xmpp debug: RECV: +[2018.11.29-17.19.00:112][244]LogXmpp: Verbose: Received Strophe XMPP Stanza iq +[2018.11.29-17.19.00:112][244]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Ping +[2018.11.29-17.19.00:112][244]LogXmpp: VeryVerbose: iq Stanza handled by Ping +[2018.11.29-17.19.00:112][244]LogXmpp: VeryVerbose: Resetting timer for Client-To-Server XMPP Pong +[2018.11.29-17.19.02:340][377]LogFortMemory: Heartbeat - CPU:1451.76MB (Peak: 2678.38MB) +[2018.11.29-17.19.02:341][377]LogLocalFileReplay: FLocalFileNetworkReplayStreamer::FlushStream. StreamChunkIndex: 5, Size: 53883 +[2018.11.29-17.19.02:343][378]LogDemo: Starting checkpoint. Actors: 136 +[2018.11.29-17.19.02:515][388]LogLocalFileReplay: FLocalFileNetworkReplayStreamer::FlushStream. StreamChunkIndex: 6, Size: 385 +[2018.11.29-17.19.02:515][388]LogDemo: Finished checkpoint. Actors: 136, GuidCacheSize: 181351, TotalSize: 237913, TotalCheckpointSaveFrames: 10, TotalCheckpointTimeInMS: 11.41, TotalCheckpointTimeWithOverheadInMS: 18.26 +[2018.11.29-17.19.04:427][503]LogGarbage: Collecting garbage (GCheckForIllegalMarkPendingKill = 1) +[2018.11.29-17.19.04:436][503]LogGarbage: 8.648369 ms for Verify GC Assumptions +[2018.11.29-17.19.04:470][503]LogGarbage: 33.861107 ms for GC +[2018.11.29-17.19.04:470][503]LogGarbage: 0.499618 ms for Gather Unreachable Objects (419 objects collected including 0 cluster objects from 0 clusters) +[2018.11.29-17.19.04:477][504]LogGarbage: 0.546712 ms for incrementally unhashing unreachable objects. Items 419 (419/419) +[2018.11.29-17.19.04:543][508]LogGarbage: GC purged 419 objects (561813 -> 561394) +[2018.11.29-17.19.08:874][767]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.08:874][767]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.08:874][767]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.08:874][767]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.08:874][767]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.08:874][767]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.08:875][767]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.08:875][767]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.08:875][767]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.08:875][767]LogFort: QuickBarItemAddedToInventory. Item: FortWorldItem_2147473445 Burst Assault Rifle with GUID: 750583645 1241699915 430332062 -368431970 +[2018.11.29-17.19.13:880][ 67]LogSlate: Took 0.000259 seconds to synchronously load lazily loaded font '../../../FortniteGame/Content/UI/Foundation/Fonts/NotoSans-Fortnite-Regular.ufont' (23K) +[2018.11.29-17.19.16:874][247]LogSlate: Took 0.000283 seconds to synchronously load lazily loaded font '../../../FortniteGame/Content/UI/Foundation/Fonts/NotoSans-Fortnite-Bold.ufont' (23K) +[2018.11.29-17.19.18:327][335]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.19.18:327][335]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.19.18:327][335]LogHttp: Verbose: 00000231AEDE2400: URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/verify' +[2018.11.29-17.19.18:327][335]LogHttp: Verbose: 00000231AEDE2400: Verb='GET' +[2018.11.29-17.19.18:327][335]LogHttp: Verbose: 00000231AEDE2400: Custom headers are present +[2018.11.29-17.19.18:327][335]LogHttp: Verbose: 00000231AEDE2400: Payload size=0 +[2018.11.29-17.19.18:327][335]LogHttp: Verbose: 00000231AEDE2400: Adding header 'X-Epic-Correlation-ID: FN-VEpC3LlE9kSlCFNNnByFrg' +[2018.11.29-17.19.18:327][335]LogHttp: Verbose: 00000231AEDE2400: Adding header 'User-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.19.18:327][335]LogHttp: Verbose: 00000231AEDE2400: Adding header 'Content-Type: application/json' +[2018.11.29-17.19.18:327][335]LogHttp: Verbose: 00000231AEDE2400: Adding header 'Content-Length: 0' +[2018.11.29-17.19.18:327][335]LogHttp: Verbose: 00000231AEDE2400: Adding header 'Expect: ' +[2018.11.29-17.19.18:327][335]LogHttp: 00000231AEDE2400: Starting GET request to URL='https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/verify' +[2018.11.29-17.19.18:327][335]LogHttp: Verbose: 00000231AEDE2400: request (easy handle:00000231EC450010) has been added to threaded queue for processing +[2018.11.29-17.19.18:360][337]LogHttp: Verbose: 00000231AEDE2400: request (easy handle:00000231EC450010) has started threaded processing +[2018.11.29-17.19.18:360][337]LogHttp: VeryVerbose: 00000231AEDE2400: 'Connection 17 seems to be dead!' +[2018.11.29-17.19.18:360][337]LogHttp: VeryVerbose: 00000231AEDE2400: 'Closing connection 17' +[2018.11.29-17.19.18:360][337]LogHttp: VeryVerbose: 00000231AEDE2400: Sent SSL data (5 bytes) +[2018.11.29-17.19.18:360][337]LogHttp: VeryVerbose: 00000231AEDE2400: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.19.18:360][337]LogHttp: VeryVerbose: 00000231AEDE2400: Sent SSL data (2 bytes) +[2018.11.29-17.19.18:360][337]LogHttp: VeryVerbose: 00000231AEDE2400: ' Trying 10.40.238.51...' +[2018.11.29-17.19.18:360][337]LogHttp: VeryVerbose: 00000231AEDE2400: 'TCP_NODELAY set' +[2018.11.29-17.19.18:411][340]LogHttp: VeryVerbose: 00000231AEDE2400: 'Connected to account-public-service-gamedev.ol.epicgames.net (10.40.238.51) port 443 (#19)' +[2018.11.29-17.19.18:411][340]LogHttp: VeryVerbose: 00000231AEDE2400: 'ALPN, offering http/1.1' +[2018.11.29-17.19.18:411][340]LogHttp: VeryVerbose: 00000231AEDE2400: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.19.18:411][340]LogHttp: VeryVerbose: 00000231AEDE2400: 'SSL re-using session ID' +[2018.11.29-17.19.18:411][340]LogHttp: VeryVerbose: 00000231AEDE2400: Sent SSL data (5 bytes) +[2018.11.29-17.19.18:411][340]LogHttp: VeryVerbose: 00000231AEDE2400: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.19.18:411][340]LogHttp: VeryVerbose: 00000231AEDE2400: Sent SSL data (512 bytes) +[2018.11.29-17.19.18:461][343]LogHttp: VeryVerbose: 00000231AEDE2400: Received SSL data (5 bytes) +[2018.11.29-17.19.18:461][343]LogHttp: VeryVerbose: 00000231AEDE2400: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.19.18:461][343]LogHttp: VeryVerbose: 00000231AEDE2400: Received SSL data (104 bytes) +[2018.11.29-17.19.18:461][343]LogHttp: VeryVerbose: 00000231AEDE2400: Received SSL data (5 bytes) +[2018.11.29-17.19.18:461][343]LogHttp: VeryVerbose: 00000231AEDE2400: 'TLSv1.2 (IN), TLS handshake, Certificate (11):' +[2018.11.29-17.19.18:461][343]LogHttp: VeryVerbose: 00000231AEDE2400: Received SSL data (4568 bytes) +[2018.11.29-17.19.18:461][343]LogHttp: VeryVerbose: 00000231AEDE2400: Received SSL data (5 bytes) +[2018.11.29-17.19.18:461][343]LogHttp: VeryVerbose: 00000231AEDE2400: 'TLSv1.2 (IN), TLS handshake, Server key exchange (12):' +[2018.11.29-17.19.18:461][343]LogHttp: VeryVerbose: 00000231AEDE2400: Received SSL data (333 bytes) +[2018.11.29-17.19.18:461][343]LogHttp: VeryVerbose: 00000231AEDE2400: Received SSL data (5 bytes) +[2018.11.29-17.19.18:461][343]LogHttp: VeryVerbose: 00000231AEDE2400: 'TLSv1.2 (IN), TLS handshake, Server finished (14):' +[2018.11.29-17.19.18:461][343]LogHttp: VeryVerbose: 00000231AEDE2400: Received SSL data (4 bytes) +[2018.11.29-17.19.18:462][343]LogHttp: VeryVerbose: 00000231AEDE2400: Sent SSL data (5 bytes) +[2018.11.29-17.19.18:462][343]LogHttp: VeryVerbose: 00000231AEDE2400: 'TLSv1.2 (OUT), TLS handshake, Client key exchange (16):' +[2018.11.29-17.19.18:462][343]LogHttp: VeryVerbose: 00000231AEDE2400: Sent SSL data (70 bytes) +[2018.11.29-17.19.18:462][343]LogHttp: VeryVerbose: 00000231AEDE2400: Sent SSL data (5 bytes) +[2018.11.29-17.19.18:462][343]LogHttp: VeryVerbose: 00000231AEDE2400: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.19.18:462][343]LogHttp: VeryVerbose: 00000231AEDE2400: Sent SSL data (1 bytes) +[2018.11.29-17.19.18:462][343]LogHttp: VeryVerbose: 00000231AEDE2400: Sent SSL data (5 bytes) +[2018.11.29-17.19.18:463][343]LogHttp: VeryVerbose: 00000231AEDE2400: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.19.18:463][343]LogHttp: VeryVerbose: 00000231AEDE2400: Sent SSL data (16 bytes) +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: Received SSL data (5 bytes) +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: Received SSL data (1 bytes) +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: Received SSL data (5 bytes) +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: Received SSL data (16 bytes) +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: 'old SSL session ID is stale, removing' +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: 'Server certificate:' +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: ' subject: CN=*.ol.epicgames.net' +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: ' start date: Apr 3 00:00:00 2018 GMT' +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: ' expire date: May 3 12:00:00 2019 GMT' +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: ' subjectAltName: host "account-public-service-gamedev.ol.epicgames.net" matched cert's "*.ol.epicgames.net"' +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: ' SSL certificate verify ok.' +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: Sent SSL data (5 bytes) +[2018.11.29-17.19.18:511][346]LogHttp: VeryVerbose: 00000231AEDE2400: Sent header (1023 bytes) - GET /account/api/oauth/verify HTTP/1.1Host: account-public-service-gamedev.ol.epicgames.netAccept: */*Accept-Encoding: deflate, gzipX-Epic-Correlation-ID: FN-VEpC3LlE9kSlCFNNnByFrgUser-Agent: Fortnite/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Type: application/jsonAuthorization: bearer eg1~eyJraWQiOiJzRktqaDlwS3d5R1pRWkNvOF81NDFFSGNXdmNWLVpHdlFKRjdjTm55MS1NIiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJmb3J0bml0ZSIsInN1YiI6ImU2ZjUwOTFjM2IyZjRjMzU5Y2YyYWFkNzVjNDI0ZGUwIiwiZHZpZCI6ImZhNTVlMzEwOGYzZmM2NmQ2YzRmZjdlYjQzOThlMmE5IiwiY2xpZCI6ImVjNjg0YjhjNjg3ZjQ3OWZhZGVhM2NiMmFkODNmNWM2IiwiYW0iOiJwYXNzd29yZCIsInAiOiJlTnF0VnR0T0l6RU1cL1o4S0lWcW1zRVRxQStLeVFtSUYydTdEdmxWdTRtbXpUWk5Sa2lubDc5ZkpYSmdwSFRwQTM5cHhZdnZZeDhjeFZob3RjT1BSZWFrWFRKZ1hyUXlJeVhCOGtqdTBqOUo1bGhycnRmVEk4Q0lkbjEwTitmbDhsQ2I4Zkh6RjB4R0F1Qnp6WkpRSVBKdU1UdXF6bVRXcFZJZnZzRUdJQlp5YlhIdVc1WE1sT2F2K0RzZ2o1Z3E4QmI0SytaVjJJVjJtNEJVV0ZuR05kTEJIWmlaQVZYS0RGZGJnSWNUTzBEcWpnVG4wNGJ1cm94OTBTcGRydkZ5WlhEaHZMQ3lRdVZmbmNVMUJPM0RoMXFQVm9LNXp2M1J0TjZCUUM3QUJ1UGJTcT +[2018.11.29-17.19.18:576][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received SSL data (5 bytes) +[2018.11.29-17.19.18:576][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received header (17 bytes) +[2018.11.29-17.19.18:576][350]LogHttp: Verbose: 00000231AEDE2400: Received response header 'HTTP/1.1 200 OK'. +[2018.11.29-17.19.18:576][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received header (37 bytes) +[2018.11.29-17.19.18:576][350]LogHttp: Verbose: 00000231AEDE2400: Received response header 'Date: Thu, 29 Nov 2018 17:19:18 GMT'. +[2018.11.29-17.19.18:576][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received header (32 bytes) +[2018.11.29-17.19.18:576][350]LogHttp: Verbose: 00000231AEDE2400: Received response header 'Content-Type: application/json'. +[2018.11.29-17.19.18:576][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received header (28 bytes) +[2018.11.29-17.19.18:576][350]LogHttp: Verbose: 00000231AEDE2400: Received response header 'Transfer-Encoding: chunked'. +[2018.11.29-17.19.18:576][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received header (24 bytes) +[2018.11.29-17.19.18:576][350]LogHttp: Verbose: 00000231AEDE2400: Received response header 'Connection: keep-alive'. +[2018.11.29-17.19.18:576][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received header (23 bytes) +[2018.11.29-17.19.18:576][350]LogHttp: Verbose: 00000231AEDE2400: Received response header 'Vary: Accept-Encoding'. +[2018.11.29-17.19.18:576][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received header (49 bytes) +[2018.11.29-17.19.18:576][350]LogHttp: Verbose: 00000231AEDE2400: Received response header 'Cache-Control: no-cache, no-store, no-transform'. +[2018.11.29-17.19.18:576][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received header (52 bytes) +[2018.11.29-17.19.18:577][350]LogHttp: Verbose: 00000231AEDE2400: Received response header 'X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9'. +[2018.11.29-17.19.18:577][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received header (50 bytes) +[2018.11.29-17.19.18:577][350]LogHttp: Verbose: 00000231AEDE2400: Received response header 'X-Epic-Correlation-ID: FN-VEpC3LlE9kSlCFNNnByFrg'. +[2018.11.29-17.19.18:577][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received header (22 bytes) +[2018.11.29-17.19.18:577][350]LogHttp: Verbose: 00000231AEDE2400: Received response header 'X-Epic-From-Cache: 1'. +[2018.11.29-17.19.18:577][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received header (24 bytes) +[2018.11.29-17.19.18:577][350]LogHttp: Verbose: 00000231AEDE2400: Received response header 'Content-Encoding: gzip'. +[2018.11.29-17.19.18:577][350]LogHttp: Verbose: 00000231AEDE2400: Received response header ''. +[2018.11.29-17.19.18:577][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received header (2 bytes) +[2018.11.29-17.19.18:577][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received data (1855 bytes) +[2018.11.29-17.19.18:577][350]LogHttp: Verbose: 00000231AEDE2400: ReceiveResponseBodyCallback: 2584 bytes out of 0 received. (SizeInBlocks=1, BlockSizeInBytes=2584, Response->TotalBytesRead=0, Response->GetContentLength()=0, SizeToDownload=2584 (<-this will get returned from the callback)) +[2018.11.29-17.19.18:577][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received SSL data (5 bytes) +[2018.11.29-17.19.18:577][350]LogHttp: VeryVerbose: 00000231AEDE2400: Received data (5 bytes) +[2018.11.29-17.19.18:577][350]LogHttp: VeryVerbose: 00000231AEDE2400: 'Connection #19 to host account-public-service-gamedev.ol.epicgames.net left intact' +[2018.11.29-17.19.18:577][350]LogHttp: Verbose: Request 00000231AEDE2400 (easy handle:00000231EC450010) has completed (code:0) and has been marked as such +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.18:578][350]LogHttp: 00000231AEDE2400: request has been successfully processed. URL: https://account-public-service-gamedev.ol.epicgames.net/account/api/oauth/verify, HTTP code: 200, content length: -1, actual payload size: 2584 +[2018.11.29-17.19.18:578][350]LogHttp: Verbose: 00000231AEDE2400 Response Header Date: Thu, 29 Nov 2018 17:19:18 GMT +[2018.11.29-17.19.18:578][350]LogHttp: Verbose: 00000231AEDE2400 Response Header Content-Type: application/json +[2018.11.29-17.19.18:578][350]LogHttp: Verbose: 00000231AEDE2400 Response Header Transfer-Encoding: chunked +[2018.11.29-17.19.18:578][350]LogHttp: Verbose: 00000231AEDE2400 Response Header Connection: keep-alive +[2018.11.29-17.19.18:578][350]LogHttp: Verbose: 00000231AEDE2400 Response Header Vary: Accept-Encoding +[2018.11.29-17.19.18:578][350]LogHttp: Verbose: 00000231AEDE2400 Response Header Cache-Control: no-cache, no-store, no-transform +[2018.11.29-17.19.18:578][350]LogHttp: Verbose: 00000231AEDE2400 Response Header X-Epic-Device-ID: fa55e3108f3fc66d6c4ff7eb4398e2a9 +[2018.11.29-17.19.18:578][350]LogHttp: Verbose: 00000231AEDE2400 Response Header X-Epic-Correlation-ID: FN-VEpC3LlE9kSlCFNNnByFrg +[2018.11.29-17.19.18:578][350]LogHttp: Verbose: 00000231AEDE2400 Response Header X-Epic-From-Cache: 1 +[2018.11.29-17.19.18:578][350]LogHttp: Verbose: 00000231AEDE2400 Response Header Content-Encoding: gzip +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.18:578][350]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.19.22:523][585]LogLocalFileReplay: FLocalFileNetworkReplayStreamer::FlushStream. StreamChunkIndex: 7, Size: 47655 +[2018.11.29-17.19.23:088][619]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.23:654][653]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.24:254][689]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.24:838][724]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.27:437][880]FortClientBot: {"event": "BotStatus", "bot": "", "statusvalue": 0, "statusstring": "ControllerInitialized", "timeincurrentstate": 150 } +[2018.11.29-17.19.29:942][ 31]LogCommonInput: UCommonInputSubsystem::SetCurrentInputType(): Using Gamepad +[2018.11.29-17.19.29:942][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:942][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:942][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:942][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:942][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:942][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:942][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:942][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:944][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:945][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'SendMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:945][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:945][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'DismissMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:945][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:945][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'RecordReply' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:945][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.29:945][ 31]LogDataTable: Warning: UDataTable::FindRow : 'CommonUIUtils::GetInputActionData couldn't find the row passed in, check data table if its missing.' requested row 'PlayMessage' not in DataTable '/Game/UI/Foundation/Input/InputActionDataTable.InputActionDataTable'. +[2018.11.29-17.19.32:975][213]FortClientBot: Smoke test complete. Returning to main menu. +[2018.11.29-17.19.32:991][214]FortClientBot: Smoke test complete. Returning to main menu. +[2018.11.29-17.19.33:008][215]FortClientBot: Smoke test complete. Returning to main menu. +[2018.11.29-17.19.33:022][215]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] AnalyticsET URL:datarouter/api/v1/public/data?SessionID={058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}&AppID=Fortnite.DevLatest&AppVersion=1.0.0 - UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3|e6f5091c3b2f4c359cf2aad75c424de0|e04d67a7-16cd-41f9-b939-be602538533a|fa55e3108f3fc66d6c4ff7eb4398e2a9|&AppEnvironment=datacollector-binary&UploadType=eteventstream. Payload:{"Events":[{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:46.487","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/Athena/Items/ForagedItems/SpookyMist/CBGA_SpookyMist"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:35.231","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/UI/Foundation/Textures/Icons/Items/T-Icon-MedBandage-L"},{"EventName":"PlayerContextLocationPerMinute","DateOffset":"+00:00:35.049","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","Locations":"71297.484,-78997.859,40173.309,48.587;71297.484,-78997.859,34182.234,53.588;71297.484,-78997.859,28175.555,58.615;71297.484,-78997.859,22172.820,63.558;71297.484,-78997.859,16172.766,68.588;71297.484,-78997.859,11631.097,73.582;71297.484,-78997.859,9130.637,78.582;71297.484,-78997.859,6630.084,83.621;71297.484,-78997.859,4129.417,88.620;73617.094,-83015.875,2605.209,93.549;73644.672,-83004.703,2576.938,98.689;73704.781,-82976.023,2593.845,103.730","Location":"InGame","IsIdle":"true","RegionId":"NONE","SubRegionId":"","PreferredSubRegionId":"","PlayerLevel":"0","NetworkType":"Unknown","TemperatureLevel":"-1","BatteryLevel":"-1","IsRunningOnBattery":"false","CPU":"GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz","AthenaGamePhase":"SafeZones","AthenaSafeZoneCenter":"0.000,0.000,0.000","AthenaSafeZoneRadius":"0","AthenaSafeZoneState":"None","AthenaSafeZonePhase":"0","AthenaMatchTimeSec":"103.730423","AthenaPlayersLeft":"1","AthenaTeamsLeft":"1","AthenaMapName":"Athena_Terrain","PlaylistName":"Playlist_DefaultSolo","AthenaTeamNumber":"1","AthenaTeammatesLeft":"0","AthenaPlayerStatus":"Alive","PlayerLocation":"73704.781,-82976.023,2593.845","PlayerPOITags":"Athena.Location.POI.PleasantPark","SocialPartyCount":"1","SocialPartyPlatforms":"PC"},{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:24.147","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/UI/Foundation/Textures/Icons/Weapons/Items/T-Icon-Weapons-SK-Raptor-L"},{"EventName":"Combat.ClientPlayerDeath","DateOffset":"+00:00:00.000","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","AthenaGamePhase":"SafeZones","AthenaSafeZoneCenter":"0.000,0.000,0.000","AthenaSafeZoneRadius":"0","AthenaSafeZoneState":"None","AthenaSafeZonePhase":"0","AthenaMatchTimeSec":"138.72612","AthenaPlayersLeft":"1","AthenaTeamsLeft":"1","AthenaMapName":"Athena_Terrain","PlaylistName":"Playlist_DefaultSolo","AthenaTeamNumber":"1","AthenaTeammatesLeft":"0","AthenaPlayerStatus":"Alive","PlayerLocation":"73617.094,-83015.875,2605.209","PlayerPOITags":""}]} +[2018.11.29-17.19.33:022][215]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.19.33:022][215]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.19.33:022][215]LogHttp: Verbose: 00000231EB5ABA00: URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.19.33:022][215]LogHttp: Verbose: 00000231EB5ABA00: Verb='POST' +[2018.11.29-17.19.33:022][215]LogHttp: Verbose: 00000231EB5ABA00: Custom headers are present +[2018.11.29-17.19.33:022][215]LogHttp: Verbose: 00000231EB5ABA00: Payload size=3006 +[2018.11.29-17.19.33:022][215]LogHttp: Verbose: 00000231EB5ABA00: Adding header 'Content-Type: application/json; charset=utf-8' +[2018.11.29-17.19.33:022][215]LogHttp: Verbose: 00000231EB5ABA00: Adding header 'User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.19.33:022][215]LogHttp: Verbose: 00000231EB5ABA00: Adding header 'Content-Length: 3006' +[2018.11.29-17.19.33:022][215]LogHttp: Verbose: 00000231EB5ABA00: Adding header 'Expect: ' +[2018.11.29-17.19.33:022][215]LogHttp: 00000231EB5ABA00: Starting POST request to URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.19.33:022][215]LogHttp: Verbose: 00000231EB5ABA00: request (easy handle:00000231EC450010) has been added to threaded queue for processing +[2018.11.29-17.19.33:023][215]LogCommonUI: Pushing AthenaGameOverWidget_C_2147477900 into widget stack MainContentStack +[2018.11.29-17.19.33:023][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:023][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:023][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:023][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:023][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:023][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:024][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:024][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.19.33:024][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:025][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:025][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:025][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:025][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:025][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:025][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:025][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:025][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:026][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:026][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Window'. Using FWindowStyle defaults instead. +[2018.11.29-17.19.33:026][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.19.33:026][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:026][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.19.33:026][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.19.33:026][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:027][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.19.33:027][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:027][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.19.33:027][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:027][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.19.33:027][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.19.33:027][215]LogCommonInput: Verbose: InternalPushActivatablePanel : Adding push for new activatable panel AthenaGameOverWidget_C_2147477900: +[2018.11.29-17.19.33:027][215]LogCommonInput: Verbose: Input suspension: Started +[2018.11.29-17.19.33:027][215]LogCommonInput: Verbose: Begin StartNextOperation +[2018.11.29-17.19.33:027][215]LogCommonInput: Verbose: StartNextOperation: activatable panel pushed on stack for panel: AthenaGameOverWidget_C_2147477900 +[2018.11.29-17.19.33:028][215]LogCommonInput: Verbose: StartNextOperation: begin intro for panel: AthenaGameOverWidget_C_2147477900 +[2018.11.29-17.19.33:028][215]LogCommonInput: Verbose: OnPrePanelActivated: panel activated complete: AthenaGameOverWidget_C_2147477900 +[2018.11.29-17.19.33:028][215]LogCommonInput: Verbose: Begin StartNextOperation +[2018.11.29-17.19.33:028][215]LogCommonInput: Verbose: StartNextOperation: Finished, Clearing pending ops +[2018.11.29-17.19.33:028][215]LogCommonUI: CommonWidgetStack: MainContentStack + AthenaGameOverWidget_C_2147477900 +ActiveWidgetIndex: 0 +[2018.11.29-17.19.33:028][215]LogBlueprintUserMessages: [PlayerRankEmblem] survivalbannerstonewoodcomplete defaultcolor16 - 1 +[2018.11.29-17.19.33:028][215]WindowsVideoRecordingSystem: Verbose: FWindowsVideoRecordingSystem::GetCurrentRecordingSeconds: reporting 154.080597 +[2018.11.29-17.19.33:029][215]LogOutputDevice: Warning: + +Script Stack (1 frames): +FortPlayerControllerZone.ClientOnPawnDied + +[2018.11.29-17.19.33:063][215]LogHttp: Verbose: 00000231EB5ABA00: request (easy handle:00000231EC450010) has started threaded processing +[2018.11.29-17.19.33:063][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'Connection 18 seems to be dead!' +[2018.11.29-17.19.33:063][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'Closing connection 18' +[2018.11.29-17.19.33:063][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Sent SSL data (5 bytes) +[2018.11.29-17.19.33:063][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'TLSv1.2 (OUT), TLS alert, Client hello (1):' +[2018.11.29-17.19.33:063][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Sent SSL data (2 bytes) +[2018.11.29-17.19.33:063][215]LogHttp: VeryVerbose: 00000231EB5ABA00: ' Trying 34.232.136.228...' +[2018.11.29-17.19.33:063][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'TCP_NODELAY set' +[2018.11.29-17.19.33:064][215]LogStats: FPlatformStackWalk::StackWalkAndDump - 0.035 s +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: === Handled ensure: === +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: Ensure condition failed: -StartDeltaMs + EndDeltaMs == GRecordingBufferSeconds * 1000 [File:D:\Epic\Kairos\FortniteGame\Plugins\HighlightFeature\Source\Private\GenericHighlightFeature.cpp] [Line: 92] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: Stack: +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff790d1fc11 FortniteClient.exe!FGenericHighlightFeature::RegisterVideoHighlight() [d:\epic\kairos\fortnitegame\plugins\highlightfeature\source\private\generichighlightfeature.cpp:92] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff7913a332a FortniteClient.exe!AFortPlayerControllerAthena::ClientOnPawnDied_Implementation() [d:\epic\kairos\fortnitegame\source\fortnitegame\private\athena\fortplayercontrollerathena.cpp:6002] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff7927e9282 FortniteClient.exe!AFortPlayerControllerZone::execClientOnPawnDied() [d:\epic\kairos\fortnitegame\source\fortnitegame\public\player\fortplayercontrollerzone.h:172] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff792f51969 FortniteClient.exe!UFunction::Invoke() [d:\epic\kairos\engine\source\runtime\coreuobject\private\uobject\class.cpp:4645] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff793188dd1 FortniteClient.exe!UObject::ProcessEvent() [d:\epic\kairos\engine\source\runtime\coreuobject\private\uobject\scriptcore.cpp:1480] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff794f7a25b FortniteClient.exe!AActor::ProcessEvent() [d:\epic\kairos\engine\source\runtime\engine\private\actor.cpp:734] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff79550e7b4 FortniteClient.exe!FObjectReplicator::ReceivedRPC() [d:\epic\kairos\engine\source\runtime\engine\private\datareplication.cpp:943] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff795509119 FortniteClient.exe!FObjectReplicator::ReceivedBunch() [d:\epic\kairos\engine\source\runtime\engine\private\datareplication.cpp:776] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff7954fbdf3 FortniteClient.exe!UActorChannel::ProcessBunch() [d:\epic\kairos\engine\source\runtime\engine\private\datachannel.cpp:2528] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff795509ce8 FortniteClient.exe!UActorChannel::ReceivedBunch() [d:\epic\kairos\engine\source\runtime\engine\private\datachannel.cpp:2386] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff79550dbb5 FortniteClient.exe!UChannel::ReceivedNextBunch() [d:\epic\kairos\engine\source\runtime\engine\private\datachannel.cpp:757] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff79550f3e2 FortniteClient.exe!UChannel::ReceivedRawBunch() [d:\epic\kairos\engine\source\runtime\engine\private\datachannel.cpp:443] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff7959a628e FortniteClient.exe!UNetConnection::ReceivedPacket() [d:\epic\kairos\engine\source\runtime\engine\private\netconnection.cpp:1813] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff7959a7521 FortniteClient.exe!UNetConnection::ReceivedRawPacket() [d:\epic\kairos\engine\source\runtime\engine\private\netconnection.cpp:1018] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff7902bbb74 FortniteClient.exe!UIpNetDriver::TickDispatch() [d:\epic\kairos\engine\plugins\online\onlinesubsystemutils\source\onlinesubsystemutils\private\ipnetdriver.cpp:270] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff79597da4d FortniteClient.exe!TBaseUObjectMethodDelegateInstance<0,UNetDriver,void __cdecl(float)>::ExecuteIfSafe() [d:\epic\kairos\engine\source\runtime\core\public\delegates\delegateinstancesimpl.h:679] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff7920fd39e FortniteClient.exe!TBaseMulticastDelegate::Broadcast() [d:\epic\kairos\engine\source\runtime\core\public\delegates\delegatesignatureimpl.inl:974] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff79589154f FortniteClient.exe!UWorld::Tick() [d:\epic\kairos\engine\source\runtime\engine\private\leveltick.cpp:1424] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff79568cbe6 FortniteClient.exe!UGameEngine::Tick() [d:\epic\kairos\engine\source\runtime\engine\private\gameengine.cpp:1589] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff791854697 FortniteClient.exe!UFortEngine::Tick() [d:\epic\kairos\fortnitegame\source\fortnitegame\private\fortengine.cpp:511] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff78fd9885d FortniteClient.exe!FEngineLoop::Tick() [d:\epic\kairos\engine\source\runtime\launch\private\launchengineloop.cpp:3929] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff78fda7c7f FortniteClient.exe!GuardedMain() [d:\epic\kairos\engine\source\runtime\launch\private\launch.cpp:179] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff78fda7d3a FortniteClient.exe!GuardedMainWrapper() [d:\epic\kairos\engine\source\runtime\launch\private\windows\launchwindows.cpp:145] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff78fdb79b1 FortniteClient.exe!WinMain() [d:\epic\kairos\engine\source\runtime\launch\private\windows\launchwindows.cpp:276] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ff798164a52 FortniteClient.exe!__scrt_common_main_seh() [d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ffc1bb71fe4 KERNEL32.DLL!UnknownFunction [] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: [Callstack] 0x00007ffc1bcacb31 ntdll.dll!UnknownFunction [] +[2018.11.29-17.19.33:064][215]LogOutputDevice: Error: +[2018.11.29-17.19.33:069][215]LogStats: SubmitErrorReport - 0.000 s +[2018.11.29-17.19.33:331][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'Connected to datarouter.ol.epicgames.com (34.232.136.228) port 443 (#20)' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'ALPN, offering http/1.1' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'SSL re-using session ID' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Sent SSL data (5 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'TLSv1.2 (OUT), TLS handshake, Client hello (1):' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Sent SSL data (512 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received SSL data (5 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'TLSv1.2 (IN), TLS handshake, Server hello (2):' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received SSL data (104 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received SSL data (5 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'TLSv1.2 (IN), TLS handshake, Certificate (11):' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received SSL data (4568 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received SSL data (5 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'TLSv1.2 (IN), TLS handshake, Server key exchange (12):' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received SSL data (333 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received SSL data (5 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'TLSv1.2 (IN), TLS handshake, Server finished (14):' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received SSL data (4 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Sent SSL data (5 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'TLSv1.2 (OUT), TLS handshake, Client key exchange (16):' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Sent SSL data (70 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Sent SSL data (5 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'TLSv1.2 (OUT), TLS change cipher, Client hello (1):' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Sent SSL data (1 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Sent SSL data (5 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'TLSv1.2 (OUT), TLS handshake, Finished (20):' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Sent SSL data (16 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received SSL data (5 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'TLSv1.2 (IN), TLS change cipher, Client hello (1):' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received SSL data (1 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received SSL data (5 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'TLSv1.2 (IN), TLS handshake, Finished (20):' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received SSL data (16 bytes) +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'ALPN, server accepted to use http/1.1' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'old SSL session ID is stale, removing' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'Server certificate:' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: ' subject: CN=*.ol.epicgames.com' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: ' start date: Mar 12 00:00:00 2018 GMT' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: ' expire date: Apr 12 12:00:00 2019 GMT' +[2018.11.29-17.19.33:332][215]LogHttp: VeryVerbose: 00000231EB5ABA00: ' subjectAltName: host "datarouter.ol.epicgames.com" matched cert's "*.ol.epicgames.com"' +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: ' issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon' +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: ' SSL certificate verify ok.' +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Sent SSL data (5 bytes) +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Sent header (582 bytes) - POST /datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream HTTP/1.1Host: datarouter.ol.epicgames.comAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/json; charset=utf-8User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Length: 3006 +[2018.11.29-17.19.33:333][215]LogHttp: Verbose: 00000231EB5ABA00: UploadCallback: 3006 bytes out of 3006 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=3006 (<-this will get returned from the callback)) +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Sent SSL data (5 bytes) +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Sent data (3006 bytes) +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'We are completely uploaded and fine' +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received SSL data (5 bytes) +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received header (25 bytes) +[2018.11.29-17.19.33:333][215]LogHttp: Verbose: 00000231EB5ABA00: Received response header 'HTTP/1.1 204 No Content'. +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received header (37 bytes) +[2018.11.29-17.19.33:333][215]LogHttp: Verbose: 00000231EB5ABA00: Received response header 'Date: Thu, 29 Nov 2018 17:19:33 GMT'. +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received header (24 bytes) +[2018.11.29-17.19.33:333][215]LogHttp: Verbose: 00000231EB5ABA00: Received response header 'Connection: keep-alive'. +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received header (32 bytes) +[2018.11.29-17.19.33:333][215]LogHttp: Verbose: 00000231EB5ABA00: Received response header 'Access-Control-Allow-Origin: *'. +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received header (61 bytes) +[2018.11.29-17.19.33:333][215]LogHttp: Verbose: 00000231EB5ABA00: Received response header 'X-Epic-Correlation-ID: 25908d1e-bfb1-4d32-bb3c-b5eaaeaffc3c'. +[2018.11.29-17.19.33:333][215]LogHttp: Verbose: 00000231EB5ABA00: Received response header ''. +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: Received header (2 bytes) +[2018.11.29-17.19.33:333][215]LogHttp: VeryVerbose: 00000231EB5ABA00: 'Connection #20 to host datarouter.ol.epicgames.com left intact' +[2018.11.29-17.19.33:333][215]LogHttp: Verbose: Request 00000231EB5ABA00 (easy handle:00000231EC450010) has completed (code:0) and has been marked as such +[2018.11.29-17.19.33:344][215]LogWindows: Warning: CreateProc failed: The system cannot find the file specified. (0x00000002) +[2018.11.29-17.19.33:344][215]LogWindows: Warning: URL: ../../../Engine/Binaries/Win64/CrashReportClient.exe "D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Crashes/UE4CC-Windows-C58980F04E9A4CBAD9844196DD30D0F3_0002" -Unattended -AppName=UE4-FortniteGame -CrashGUID=UE4CC-Windows-C58980F04E9A4CBAD9844196DD30D0F3_0002 -DebugSymbols=..\..\..\Engine\Intermediate\Symbols +[2018.11.29-17.19.33:344][215]LogStats: SendNewReport - 0.275 s +[2018.11.29-17.19.33:344][215]LogStats: FDebug::EnsureFailed - 0.316 s +[2018.11.29-17.19.33:344][215]WindowsVideoRecordingSystem: Verbose: FWindowsVideoRecordingSystem::FinalizeRecording +[2018.11.29-17.19.33:344][215]HighlightRecorder: start saving to D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/VideoCaptures/f65b90c13f5a4bf285ef088b8cef6283_1.mp4, max duration 3600.000 +[2018.11.29-17.19.33:358][215]LogFort: Cannot execute inventory item - due to blocked ActionPlayerChangeEquipment tag +[2018.11.29-17.19.33:365][215]WMF: Error: `MFCreateSinkWriterFromURL(Filename, nullptr, nullptr, &Writer)` failed: 0x8007007B - The filename, directory name, or volume label syntax is incorrect. + + +[2018.11.29-17.19.33:365][215]HighlightRecorder: saving to D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/VideoCaptures/f65b90c13f5a4bf285ef088b8cef6283_1.mp4 failed, took 0.015 msecs +[2018.11.29-17.19.33:365][215]WindowsVideoRecordingSystem: Verbose: FWindowsVideoRecordingSystem::FinalizeCallbackOnGameThread +[2018.11.29-17.19.33:365][215]LogGenericHighlightFeature: Warning: RegisterVideoRecordingFinalized: Failed +[2018.11.29-17.19.33:367][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.19.33:367][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:367][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.19.33:367][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:367][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.19.33:367][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:367][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.19.33:367][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:367][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:367][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'Button'. Using FButtonStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBox'. Using FScrollBoxStyle defaults instead. +[2018.11.29-17.19.33:368][215]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ScrollBar'. Using FScrollBarStyle defaults instead. +[2018.11.29-17.19.33:372][215]LogSlate: FSceneViewport::OnFocusLost() reason 2 +[2018.11.29-17.19.33:385][216]FortClientBot: {"event": "BotDeadOrWon", "bot": "LoadBot07063"} +[2018.11.29-17.19.33:385][216]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.19.33:385][216]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.19.33:386][216]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.33:386][216]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.33:386][216]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.33:386][216]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.33:386][216]LogHttp: 00000231EB5ABA00: request has been successfully processed. URL: https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream, HTTP code: 204, content length: 0, actual payload size: 0 +[2018.11.29-17.19.33:386][216]LogHttp: Verbose: 00000231EB5ABA00 Response Header Date: Thu, 29 Nov 2018 17:19:33 GMT +[2018.11.29-17.19.33:386][216]LogHttp: Verbose: 00000231EB5ABA00 Response Header Connection: keep-alive +[2018.11.29-17.19.33:386][216]LogHttp: Verbose: 00000231EB5ABA00 Response Header Access-Control-Allow-Origin: * +[2018.11.29-17.19.33:386][216]LogHttp: Verbose: 00000231EB5ABA00 Response Header X-Epic-Correlation-ID: 25908d1e-bfb1-4d32-bb3c-b5eaaeaffc3c +[2018.11.29-17.19.33:386][216]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.19.33:386][216]LogHttp: VeryVerbose: FHttpRequestImpl::OnHeaderReceived() +[2018.11.29-17.19.33:386][216]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.19.33:386][216]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] ET response for [https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream]. Code: 204. Payload: +[2018.11.29-17.19.33:386][216]LogFortHitches: HITCHHUNTER: Hitch in GameThread of 365.3 ms has been detected this frame. Number of Draw Calls this Frame: 722 +[2018.11.29-17.19.33:393][217]LogDemo: Exceeded maximum desired recording time. Max: 1.800ms. +[2018.11.29-17.19.33:405][217]LogCommonInput: Verbose: Input suspension: Stopped +[2018.11.29-17.19.33:920][248]LogFort: ClientSendEndBattleRoyaleMatchForPlayer_Implementation: 1 +[2018.11.29-17.19.38:037][495]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.19.38:037][495]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] team member data updated, team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.19.38:037][495]LogParty: Display: Got bad homebase data +[2018.11.29-17.19.38:041][496]LogOnlineParty: Verbose: OSS: UpdatePartyMemberData request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.19.38:041][496]FortClientBot: {"event": "BotLeaveMatch", "bot": "LoadBot07063"} +[2018.11.29-17.19.38:041][496]LogOnlineGame: FortPC::ReturnToMainMenu() +[2018.11.29-17.19.38:041][496]LogHealthSnapshot: ======= Snapshot: End of Match (Athena_GameState_C, Difficulty 0.00) ======= +[2018.11.29-17.19.38:041][496]LogHealthSnapshot: Games Played: 1 +[2018.11.29-17.19.38:041][496]LogHealthSnapshot: MeasuredPerfTime: 148.78 secs +[2018.11.29-17.19.38:041][496]LogHealthSnapshot: MVP: 0.00%, AvgFPS:59.42, HitchesPerMinute: 0.81, Avg Hitch 13.44ms +[2018.11.29-17.19.38:041][496]LogHealthSnapshot: FT: Avg: 16.83ms, Max: 540.33ms, Min: 16.57ms +[2018.11.29-17.19.38:041][496]LogHealthSnapshot: GT: Avg 5.25ms, Hitches/Min: 0.40, Bound Frames: 0.01% +[2018.11.29-17.19.38:041][496]LogHealthSnapshot: RT: Avg 10.99ms, Hitches/Min: 0.40, Bound Frames: 0.10% +[2018.11.29-17.19.38:041][496]LogHealthSnapshot: RHIT:Avg 0.00ms, Hitches/Min: 0.00, Bound Frames: 0.00% +[2018.11.29-17.19.38:041][496]LogHealthSnapshot: GPU: Avg 16.67ms, Hitches/Min: 0.00, Bound Frames: 0.08% +[2018.11.29-17.19.38:041][496]LogHealthSnapshot: DrawCalls: Avg: 2206, Max: 7111, Min: 686 +[2018.11.29-17.19.38:042][496]LogHealthSnapshot: DrawnPrims: Avg: 1348786, Max: 2696986, Min: 629685 +[2018.11.29-17.19.38:042][496]LogHealthSnapshot: CPU Memory: Used 1457.37MB, Peak 1457.37MB +[2018.11.29-17.19.38:042][496]LogHealthSnapshot: Physical Memory: Used 2654.63MB, Peak 2678.38MB +[2018.11.29-17.19.38:042][496]LogHealthSnapshot: ========================================================= +[2018.11.29-17.19.38:042][496]LogFort: SetIsDisconnecting: Player Disconnecting State Change OldState: 0 NewState: 1 +[2018.11.29-17.19.38:042][496]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.19.38:042][496]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] team member data updated, team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.19.38:042][496]LogParty: Display: Got bad homebase data +[2018.11.29-17.19.38:042][496]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.memberdata user=e6f5091c3b2f4c359cf2aad75c424de0 to all +[2018.11.29-17.19.38:055][496]LogCore: Display: Setting hang detector multiplier to 3.0000s. New hang duration: 90.0000s. New present duration: 0.0000s. +[2018.11.29-17.19.38:055][496]LogStreaming: Display: Flushing async loaders. +[2018.11.29-17.19.38:063][496]LogSlateStyle: Warning: Unable to find Slate Widget Style 'ProgressBar'. Using FProgressBarStyle defaults instead. +[2018.11.29-17.19.38:063][496]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.38:063][496]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.38:064][496]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.38:064][496]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.38:064][496]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.38:064][496]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.38:064][496]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.38:064][496]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.38:064][496]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.38:064][496]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.38:065][496]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.38:065][496]LogSlateStyle: Warning: Unable to find Slate Widget Style 'NormalText'. Using FTextBlockStyle defaults instead. +[2018.11.29-17.19.38:073][497]FortClientBot: {"event": "BotLeaveMatch", "bot": "LoadBot07063"} +[2018.11.29-17.19.38:073][497]LogOnlineGame: FortPC::ReturnToMainMenu() +[2018.11.29-17.19.38:079][498]FortClientBot: {"event": "BotLeaveMatch", "bot": "LoadBot07063"} +[2018.11.29-17.19.38:079][498]LogOnlineGame: FortPC::ReturnToMainMenu() +[2018.11.29-17.19.38:092][498]LogOnlineGame: FortPC::ClientReturnToMainMenuWithTextReason() [MCP:e6f5091c3b2f4c359cf2aad75c424de0] Reason: +[2018.11.29-17.19.38:092][498]LogFort: [HandleDisconnectInternal] bHandlingDisconnect: false +[2018.11.29-17.19.38:092][498]LogFort: [CleanupPartyForMainMenu] Changing state to Returning to Frontend and Clearing Primary Game Session ID +[2018.11.29-17.19.38:092][498]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.19.38:092][498]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] team member data updated, team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.19.38:092][498]LogParty: Display: Got bad homebase data +[2018.11.29-17.19.38:092][498]LogParty: Verbose: Party [C9AE807B4F9D1F30F1535488AB79E7A8, LocalOwner (LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0)), Leader (LoadBot07063 (MCP:e6f5091c3b2f4c359cf2aad75c424de0))] attempting to update party config +[2018.11.29-17.19.38:093][498]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.updatepartyconfiguration user=e6f5091c3b2f4c359cf2aad75c424de0 to=all payload={"partyId":"C9AE807B4F9D1F30F1535488AB79E7A8","presencePermissions":-1834389757,"invitePermissions":32515,"partyFlags":2,"notAcceptingMembersReason":1,"maxMembers":4,"password":"","accessKey":"1A9601624B2510433E8340B1FAAD2362"} +[2018.11.29-17.19.38:093][498]LogOnlineParty: Display: OSS: Publishing party to presence PartyId(C9AE807B4F9D1F30F1535488AB79E7A8) AccessKey(1A9601624B2510433E8340B1FAAD2362) HasPassword(0) IsAcceptingMembers(0) NotAcceptingReason(1) +[2018.11.29-17.19.38:093][498]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::PublishPartyInfoToPresence success to publish presence user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.19.38:093][498]LogOnlineParty: Verbose: OSS: UpdateParty request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.19.38:093][498]LogParty: Verbose: [C9AE807B4F9D1F30F1535488AB79E7A8] Party config updated Succeeded +[2018.11.29-17.19.38:098][499]LogOnlineParty: Verbose: OSS: UpdatePartyMemberData request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.19.38:099][499]LogOnlineParty: Verbose: OSS: UpdatePartyData request success. user=e6f5091c3b2f4c359cf2aad75c424de0 party=C9AE807B4F9D1F30F1535488AB79E7A8 +[2018.11.29-17.19.38:099][499]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.data user=e6f5091c3b2f4c359cf2aad75c424de0 to all +[2018.11.29-17.19.38:099][499]LogParty: Display: UpdateChangeCallbacks: Getting Team Member Info for [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0]. +[2018.11.29-17.19.38:100][499]LogParty: Display: [LoadBot07063] Id [MCP:e6f5091c3b2f4c359cf2aad75c424de0] team member data updated, team [MAX] at index [0] in [LoadBot07063]'s game. +[2018.11.29-17.19.38:100][499]LogParty: Display: Got bad homebase data +[2018.11.29-17.19.38:100][499]LogOnlineParty: Verbose: OSS: FOnlinePartySystemMcp::XmppMessage SendToParty success type=com.epicgames.party.memberdata user=e6f5091c3b2f4c359cf2aad75c424de0 to all +[2018.11.29-17.19.38:100][499]FortClientBot: {"event": "BotLeaveMatch", "bot": "LoadBot07063"} +[2018.11.29-17.19.38:100][499]LogOnlineGame: FortPC::ReturnToMainMenu() +[2018.11.29-17.19.38:112][500]FortClientBot: {"event": "BotLeaveMatch", "bot": "LoadBot07063"} +[2018.11.29-17.19.38:112][500]LogOnlineGame: FortPC::ReturnToMainMenu() +[2018.11.29-17.19.38:125][500]LogOnlineGame: FortPC::ClientReturnToMainMenuWithTextReason() [MCP:e6f5091c3b2f4c359cf2aad75c424de0] Reason: +[2018.11.29-17.19.38:125][500]LogFort: [HandleDisconnectInternal] bHandlingDisconnect: true +[2018.11.29-17.19.38:125][500]LogOnlineGame: FortPC::ClientReturnToMainMenuWithTextReason() [MCP:e6f5091c3b2f4c359cf2aad75c424de0] Reason: +[2018.11.29-17.19.38:125][500]LogFort: [HandleDisconnectInternal] bHandlingDisconnect: true +[2018.11.29-17.19.38:130][501]FortClientBot: {"event": "BotLeaveMatch", "bot": "LoadBot07063"} +[2018.11.29-17.19.38:130][501]LogOnlineGame: FortPC::ReturnToMainMenu() +[2018.11.29-17.19.38:140][501]LogNet: Browse: /Game/Maps/Frontend?closed +[2018.11.29-17.19.38:140][501]LogNet: Connection failed; returning to Entry +[2018.11.29-17.19.38:140][501]LogFortPerformance: Display: Athena Client End of zone performance report at 2018.11.29-12.19.38 (match #1) (sending to analytics) +[2018.11.29-17.19.38:142][501]LogFortPerformance: Display: Overall: 8840 frames, 0.8 hitches/min, 59.4 avg FPS, 0.0 MVP30 +[2018.11.29-17.19.38:142][501]LogInit: Selected Device Profile: [WindowsClient] +[2018.11.29-17.19.38:142][501]LogInit: Selected Device Profile: [WindowsClient] +[2018.11.29-17.19.38:143][501]LogFortPerformance: Display: Starting bad match detection. +[2018.11.29-17.19.38:143][501]LogFortPerformance: Display: Using trigger: HitchTime_500_2000_Count GreaterThan 0.000000 +[2018.11.29-17.19.38:143][501]LogFortPerformance: Display: Using trigger: HitchTime_2000_AndAbove_Count GreaterThan 0.000000 +[2018.11.29-17.19.38:143][501]LogInit: Selected Device Profile: [WindowsClient] +[2018.11.29-17.19.38:143][501]LogFortPerformance: Display: Including chart: Athena_FlyingPhase +[2018.11.29-17.19.38:143][501]LogFortPerformance: Display: Including chart: Athena_ZonePhase_0 +[2018.11.29-17.19.38:143][501]LogFortPerformance: Warning: Bad Match Attribute: BadMatchReasons: HitchTime_500_2000_Count +[2018.11.29-17.19.38:143][501]LogFortPerformance: Warning: Bad Match Attribute: HitchTime_500_2000_Count: 1 +[2018.11.29-17.19.38:143][501]LogFortPerformance: Warning: Bad Match Attribute: PlaylistName: Playlist_DefaultSolo +[2018.11.29-17.19.38:143][501]LogFortPerformance: Warning: Bad Match Attribute: RegionId: NONE +[2018.11.29-17.19.38:143][501]LogFortPerformance: Warning: Bad Match Attribute: CPU: GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz +[2018.11.29-17.19.38:143][501]LogFortPerformance: Warning: Bad Match Attribute: Reported: false +[2018.11.29-17.19.38:143][501]LogFortPerformance: Warning: Bad Match Attribute: GameSessionID: f65b90c13f5a4bf285ef088b8cef6283 +[2018.11.29-17.19.38:143][501]LogFortPerformance: Warning: Bad Match Attribute: Platform: Windows +[2018.11.29-17.19.38:143][501]LogFortPerformance: Warning: Bad Match Attribute: ProviderType: Client +[2018.11.29-17.19.38:143][501]LogFortPerformance: Warning: Bad Match Attribute: GameState: Athena_GameState_C +[2018.11.29-17.19.38:143][501]LogFortPerformance: Display: Bad match detected but reporting skipped due to probability-based rate limiting. +[2018.11.29-17.19.38:159][501]LogFortMemory: UFortAssetManager::ChangeLoadState() changing bundle state to (Client, ClientAthena, Menu) +[2018.11.29-17.19.38:891][501]LogStreaming: Warning: Took 126.34ms to ProcessLoadedPackages +[2018.11.29-17.19.38:914][501]LogLoad: LoadMap: /Game/Maps/Frontend?closed +[2018.11.29-17.19.38:915][501]LogNet: World NetDriver shutdown IpNetDriver_2147478708 [GameNetDriver] +[2018.11.29-17.19.38:915][501]LogNet: DestroyNamedNetDriver IpNetDriver_2147478708 [GameNetDriver] +[2018.11.29-17.19.38:917][501]LogNet: UNetConnection::Close: [UNetConnection] RemoteAddr: 10.1.168.34:7777, Name: IpConnection_2147478707, Driver: GameNetDriver IpNetDriver_2147478708, IsServer: NO, PC: Athena_PlayerController_C_2147478528, Owner: Athena_PlayerController_C_2147478528, UniqueId: MCP:e6f5091c3b2f4c359cf2aad75c424de0, Channels: 36, Time: 2018.11.29-17.19.38 +[2018.11.29-17.19.38:917][501]LogNet: UChannel::Close: Sending CloseBunch. ChIndex == 0. Name: [UChannel] ChIndex: 0, Closing: 0 [UNetConnection] RemoteAddr: 10.1.168.34:7777, Name: IpConnection_2147478707, Driver: GameNetDriver IpNetDriver_2147478708, IsServer: NO, PC: Athena_PlayerController_C_2147478528, Owner: Athena_PlayerController_C_2147478528, UniqueId: MCP:e6f5091c3b2f4c359cf2aad75c424de0 +[2018.11.29-17.19.38:918][501]LogExit: GameNetDriver IpNetDriver_2147478708 shut down +[2018.11.29-17.19.38:918][501]LogDemo: StopDemo: Demo stopped at frame 9246 +[2018.11.29-17.19.38:918][501]LogNet: UNetConnection::Close: [UNetConnection] RemoteAddr: UDemoNetConnection, Name: DemoNetConnection_2147476469, Driver: DemoNetDriver DemoNetDriver_2147476470, IsServer: YES, PC: BP_ReplayPC_Athena_C_2147476467, Owner: BP_ReplayPC_Athena_C_2147476467, UniqueId: INVALID, Channels: 407, Time: 2018.11.29-17.19.38 +[2018.11.29-17.19.38:918][501]LogLocalFileReplay: FLocalFileNetworkReplayStreamer::FlushStream. StreamChunkIndex: 8, Size: 37453 +[2018.11.29-17.19.38:918][501]LogNet: DestroyNamedNetDriver DemoNetDriver_2147476470 [DemoNetDriver] +[2018.11.29-17.19.38:921][501]LogFort: SetIsDisconnecting: Player Disconnecting State Change OldState: 0 NewState: 1 +[2018.11.29-17.19.38:922][501]LogAnalytics: VeryVerbose: [Fortnite.DevLatest] AnalyticsET URL:datarouter/api/v1/public/data?SessionID={058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F}&AppID=Fortnite.DevLatest&AppVersion=1.0.0 - UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3|e6f5091c3b2f4c359cf2aad75c424de0|e04d67a7-16cd-41f9-b939-be602538533a|fa55e3108f3fc66d6c4ff7eb4398e2a9|&AppEnvironment=datacollector-binary&UploadType=eteventstream. Payload:{"Events":[{"EventName":"Athena.ClientUnexpectedAsynchronousLoad","DateOffset":"+00:00:05.894","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","File":"/Game/UI/Foundation/Textures/Banner/Event_Special/T-Banners-Icons-Survival-Stonewood-L"},{"EventName":"Core.EndZone_Client","DateOffset":"+00:00:00.830","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","TemperatureLevel":"-1","PSOHitchCount":"0","PSOMissesSize":"0","PSOMisses":"","CPU":"GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz","BatteryLevel":"-1","FoundationsShownBeforeRelevancy":"36","FoundationsShownAfterRelevancy":"0","FoundationsFailedToLoad":"1","BuildingWallTooLowLocations":""},{"EventName":"Core.EndZone_Client","DateOffset":"+00:00:00.797","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","TemperatureLevel":"-1","PSOHitchCount":"0","PSOMissesSize":"0","PSOMisses":"","CPU":"GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz","BatteryLevel":"-1","FoundationsShownBeforeRelevancy":"36","FoundationsShownAfterRelevancy":"0","FoundationsFailedToLoad":"1","BuildingWallTooLowLocations":""},{"EventName":"Core.EndZone_Client","DateOffset":"+00:00:00.797","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","TemperatureLevel":"-1","PSOHitchCount":"0","PSOMissesSize":"0","PSOMisses":"","CPU":"GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz","BatteryLevel":"-1","FoundationsShownBeforeRelevancy":"36","FoundationsShownAfterRelevancy":"0","FoundationsFailedToLoad":"1","BuildingWallTooLowLocations":""},{"EventName":"Core.EndZonePerfStats","DateOffset":"+00:00:00.780","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","AvgFPS":"59.417267","PercentSpentHitching":"0.022624","Hitch_60_100_HitchCount":"0","Hitch_100_150_HitchCount":"0","Hitch_150_500_HitchCount":"1","Hitch_500_2000_HitchCount":"1","Hitch_2000_Plus_HitchCount":"0","RegionId":"NONE","NumMatchesPlayed":"1","ConsoleFPSMode":"30FPS","BuildType":"Development","OS":"Windows 10 (Release 1709) ","CPU":"GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz","DeviceProfile":"WindowsClient","GPUAdapter":"NVIDIA GeForce GTX 1080","GPUVendorID":"4318","GPUDeviceID":"7040","GPURevisionID":"161","GPUDriverVerI":"24.21.13.9777","GPUDriverVerU":"397.77","TotalPhysical":"101436329984","TotalVirtual":"140737488224256","PeakPhysical":"2808483840","PeakVirtual":"4784488448","CPU_NumCoresP":"6","CPU_NumCoresL":"12","RHIFeatureLevel":"SM5","ScalabilityLevel":"Mixed","ResolutionQuality":"66.666672","ViewDistanceQuality":"2","AntiAliasingQuality":"2","ShadowQuality":"2","PostProcessQuality":"2","TextureQuality":"2","FXQuality":"2","FoliageQuality":"3","ScreenPct":"66.666702","WindowMode":"WindowedFullscreen","SizeX":"1920","SizeY":"1200","VSync":"0","FrameRateLimit":"60","AthenaGamePhase":"SafeZones","AthenaMatchTimeSec":"143.89946","AthenaMapName":"Athena_Terrain","PlaylistName":"Playlist_DefaultSolo","GamePhase":"OverallChart","FrameCount":"8840","TimeMeasured":"148.778301","FramesDisregarded":"0","TimeDisregarded":"0","FlushAsyncLoadTime":"0","FlushAsyncLoadCalls":"0","MaxFlushAsyncLoadTime":"0","SyncLoadCount":"0","TotalGameBoundHitches":"1","TotalRenderBoundHitches":"1","TotalGPUBoundHitches":"0","TotalRHIBoundHitches":"0","TotalGameBoundFrames":"1","TotalRenderBoundFrames":"9","TotalGPUBoundFrames":"7","TotalRHIBoundFrames":"0","TotalGameThreadTime":"46.383095","TotalRenderThreadTime":"97.144962","TotalGPUTime":"147.382247","TotalRHIThreadTime":"0","StartTemp":"-1","StopTemp":"-1","StartBatteryLevel":"-1","StopBatteryLevel":"-1","HitchesPerMinute":"0.806569","AvgFrameTime":"0.01683","PercentFramesHitching":"0.022624","MVP20":"0","MVP30":"0","MVP60":"0.963477","TotalHitches":"2"},{"EventName":"Core.ClientPerformance","DateOffset":"+00:00:00.780","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","RegionId":"NONE","NumMatchesPlayed":"1","ConsoleFPSMode":"30FPS","BuildType":"Development","OS":"Windows 10 (Release 1709) ","CPU":"GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz","DeviceProfile":"WindowsClient","GPUAdapter":"NVIDIA GeForce GTX 1080","GPUVendorID":"4318","GPUDeviceID":"7040","GPURevisionID":"161","GPUDriverVerI":"24.21.13.9777","GPUDriverVerU":"397.77","TotalPhysical":"101436329984","TotalVirtual":"140737488224256","PeakPhysical":"2808483840","PeakVirtual":"4784488448","CPU_NumCoresP":"6","CPU_NumCoresL":"12","RHIFeatureLevel":"SM5","ScalabilityLevel":"Mixed","ResolutionQuality":"66.666672","ViewDistanceQuality":"2","AntiAliasingQuality":"2","ShadowQuality":"2","PostProcessQuality":"2","TextureQuality":"2","FXQuality":"2","FoliageQuality":"3","ScreenPct":"66.666702","WindowMode":"WindowedFullscreen","SizeX":"1920","SizeY":"1200","VSync":"0","FrameRateLimit":"60","AthenaGamePhase":"SafeZones","AthenaMatchTimeSec":"143.89946","AthenaMapName":"Athena_Terrain","PlaylistName":"Playlist_DefaultSolo","GamePhase":"Athena_WarmupPhase","FrameCount":"303","TimeMeasured":"5.058159","FramesDisregarded":"0","TimeDisregarded":"0","FlushAsyncLoadTime":"0","FlushAsyncLoadCalls":"0","MaxFlushAsyncLoadTime":"0","SyncLoadCount":"0","TotalGameBoundHitches":"0","TotalRenderBoundHitches":"0","TotalGPUBoundHitches":"0","TotalRHIBoundHitches":"0","TotalGameBoundFrames":"0","TotalRenderBoundFrames":"0","TotalGPUBoundFrames":"0","TotalRHIBoundFrames":"0","TotalGameThreadTime":"1.459075","TotalRenderThreadTime":"2.164942","TotalGPUTime":"5.07167","TotalRHIThreadTime":"0","StartTemp":"-1","StopTemp":"-1","StartBatteryLevel":"-1","StopBatteryLevel":"-1","HitchesPerMinute":"0","AvgFrameTime":"0.016694","PercentFramesHitching":"0","MVP20":"0","MVP30":"0","MVP60":"0","TotalHitches":"0","FrameTimes":[{"Bin":"0_15","Count":0,"Sum":0.00000},{"Bin":"15_20","Count":302,"Sum":5.03499},{"Bin":"20_30","Count":1,"Sum":0.02317},{"Bin":"30_35","Count":0,"Sum":0.00000},{"Bin":"35_60","Count":0,"Sum":0.00000},{"Bin":"60_100","Count":0,"Sum":0.00000},{"Bin":"100_1000","Count":0,"Sum":0.00000},{"Bin":"1000_Plus","Count":0,"Sum":0.00000}],"Hitches":[{"Bin":"60_100","Count":0,"Sum":0.00000},{"Bin":"100_150","Count":0,"Sum":0.00000},{"Bin":"150_500","Count":0,"Sum":0.00000},{"Bin":"500_2000","Count":0,"Sum":0.00000},{"Bin":"2000_Plus","Count":0,"Sum":0.00000}],"DynRes":[{"Bin":"60_70","Count":0,"Sum":0.00000},{"Bin":"70_80","Count":0,"Sum":0.00000},{"Bin":"80_90","Count":0,"Sum":0.00000},{"Bin":"90_100","Count":0,"Sum":0.00000},{"Bin":"100_Plus","Count":303,"Sum":30300.00000}]},{"EventName":"Core.ClientPerformance","DateOffset":"+00:00:00.780","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","RegionId":"NONE","NumMatchesPlayed":"1","ConsoleFPSMode":"30FPS","BuildType":"Development","OS":"Windows 10 (Release 1709) ","CPU":"GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz","DeviceProfile":"WindowsClient","GPUAdapter":"NVIDIA GeForce GTX 1080","GPUVendorID":"4318","GPUDeviceID":"7040","GPURevisionID":"161","GPUDriverVerI":"24.21.13.9777","GPUDriverVerU":"397.77","TotalPhysical":"101436329984","TotalVirtual":"140737488224256","PeakPhysical":"2808483840","PeakVirtual":"4784488448","CPU_NumCoresP":"6","CPU_NumCoresL":"12","RHIFeatureLevel":"SM5","ScalabilityLevel":"Mixed","ResolutionQuality":"66.666672","ViewDistanceQuality":"2","AntiAliasingQuality":"2","ShadowQuality":"2","PostProcessQuality":"2","TextureQuality":"2","FXQuality":"2","FoliageQuality":"3","ScreenPct":"66.666702","WindowMode":"WindowedFullscreen","SizeX":"1920","SizeY":"1200","VSync":"0","FrameRateLimit":"60","AthenaGamePhase":"SafeZones","AthenaMatchTimeSec":"143.89946","AthenaMapName":"Athena_Terrain","PlaylistName":"Playlist_DefaultSolo","GamePhase":"Athena_FlyingPhase","FrameCount":"5458","TimeMeasured":"91.299076","FramesDisregarded":"0","TimeDisregarded":"0","FlushAsyncLoadTime":"0","FlushAsyncLoadCalls":"0","MaxFlushAsyncLoadTime":"0","SyncLoadCount":"0","TotalGameBoundHitches":"0","TotalRenderBoundHitches":"0","TotalGPUBoundHitches":"0","TotalRHIBoundHitches":"0","TotalGameBoundFrames":"0","TotalRenderBoundFrames":"4","TotalGPUBoundFrames":"3","TotalRHIBoundFrames":"0","TotalGameThreadTime":"28.275997","TotalRenderThreadTime":"58.749833","TotalGPUTime":"89.849663","TotalRHIThreadTime":"0","StartTemp":"-1","StopTemp":"-1","StartBatteryLevel":"-1","StopBatteryLevel":"-1","HitchesPerMinute":"0","AvgFrameTime":"0.016728","PercentFramesHitching":"0","MVP20":"0","MVP30":"0","MVP60":"0.346905","TotalHitches":"0","FrameTimes":[{"Bin":"0_15","Count":0,"Sum":0.00000},{"Bin":"15_20","Count":5435,"Sum":90.62797},{"Bin":"20_30","Count":16,"Sum":0.36187},{"Bin":"30_35","Count":2,"Sum":0.06402},{"Bin":"35_60","Count":5,"Sum":0.24522},{"Bin":"60_100","Count":0,"Sum":0.00000},{"Bin":"100_1000","Count":0,"Sum":0.00000},{"Bin":"1000_Plus","Count":0,"Sum":0.00000}],"Hitches":[{"Bin":"60_100","Count":0,"Sum":0.00000},{"Bin":"100_150","Count":0,"Sum":0.00000},{"Bin":"150_500","Count":0,"Sum":0.00000},{"Bin":"500_2000","Count":0,"Sum":0.00000},{"Bin":"2000_Plus","Count":0,"Sum":0.00000}],"DynRes":[{"Bin":"60_70","Count":0,"Sum":0.00000},{"Bin":"70_80","Count":0,"Sum":0.00000},{"Bin":"80_90","Count":0,"Sum":0.00000},{"Bin":"90_100","Count":0,"Sum":0.00000},{"Bin":"100_Plus","Count":5458,"Sum":545800.00000}]},{"EventName":"Core.ClientPerformance","DateOffset":"+00:00:00.780","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","RegionId":"NONE","NumMatchesPlayed":"1","ConsoleFPSMode":"30FPS","BuildType":"Development","OS":"Windows 10 (Release 1709) ","CPU":"GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz","DeviceProfile":"WindowsClient","GPUAdapter":"NVIDIA GeForce GTX 1080","GPUVendorID":"4318","GPUDeviceID":"7040","GPURevisionID":"161","GPUDriverVerI":"24.21.13.9777","GPUDriverVerU":"397.77","TotalPhysical":"101436329984","TotalVirtual":"140737488224256","PeakPhysical":"2808483840","PeakVirtual":"4784488448","CPU_NumCoresP":"6","CPU_NumCoresL":"12","RHIFeatureLevel":"SM5","ScalabilityLevel":"Mixed","ResolutionQuality":"66.666672","ViewDistanceQuality":"2","AntiAliasingQuality":"2","ShadowQuality":"2","PostProcessQuality":"2","TextureQuality":"2","FXQuality":"2","FoliageQuality":"3","ScreenPct":"66.666702","WindowMode":"WindowedFullscreen","SizeX":"1920","SizeY":"1200","VSync":"0","FrameRateLimit":"60","AthenaGamePhase":"SafeZones","AthenaMatchTimeSec":"143.89946","AthenaMapName":"Athena_Terrain","PlaylistName":"Playlist_DefaultSolo","GamePhase":"Athena_ZonePhase_0","FrameCount":"3079","TimeMeasured":"52.421066","FramesDisregarded":"0","TimeDisregarded":"0","FlushAsyncLoadTime":"0","FlushAsyncLoadCalls":"0","MaxFlushAsyncLoadTime":"0","SyncLoadCount":"0","TotalGameBoundHitches":"1","TotalRenderBoundHitches":"1","TotalGPUBoundHitches":"0","TotalRHIBoundHitches":"0","TotalGameBoundFrames":"1","TotalRenderBoundFrames":"5","TotalGPUBoundFrames":"4","TotalRHIBoundFrames":"0","TotalGameThreadTime":"16.648023","TotalRenderThreadTime":"36.230187","TotalGPUTime":"52.460914","TotalRHIThreadTime":"0","StartTemp":"-1","StopTemp":"-1","StartBatteryLevel":"-1","StopBatteryLevel":"-1","HitchesPerMinute":"2.289156","AvgFrameTime":"0.017025","PercentFramesHitching":"0.064956","MVP20":"0","MVP30":"0","MVP60":"2.098569","TotalHitches":"2","FrameTimes":[{"Bin":"0_15","Count":0,"Sum":0.00000},{"Bin":"15_20","Count":3070,"Sum":51.17621},{"Bin":"20_30","Count":1,"Sum":0.02038},{"Bin":"30_35","Count":1,"Sum":0.03015},{"Bin":"35_60","Count":3,"Sum":0.15886},{"Bin":"60_100","Count":2,"Sum":0.12987},{"Bin":"100_1000","Count":2,"Sum":0.90559},{"Bin":"1000_Plus","Count":0,"Sum":0.00000}],"Hitches":[{"Bin":"60_100","Count":0,"Sum":0.00000},{"Bin":"100_150","Count":0,"Sum":0.00000},{"Bin":"150_500","Count":1,"Sum":0.36526},{"Bin":"500_2000","Count":1,"Sum":0.54033},{"Bin":"2000_Plus","Count":0,"Sum":0.00000}],"DynRes":[{"Bin":"60_70","Count":0,"Sum":0.00000},{"Bin":"70_80","Count":0,"Sum":0.00000},{"Bin":"80_90","Count":0,"Sum":0.00000},{"Bin":"90_100","Count":0,"Sum":0.00000},{"Bin":"100_Plus","Count":3079,"Sum":307900.00000}]},{"EventName":"Core.BadMatchDetected","DateOffset":"+00:00:00.779","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","BadMatchReasons":"HitchTime_500_2000_Count","HitchTime_500_2000_Count":"1","PlaylistName":"Playlist_DefaultSolo","RegionId":"NONE","CPU":"GenuineIntel|Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz","Reported":"false"},{"EventName":"Core.ClientLogout","DateOffset":"+00:00:00.000","GameSessionID":"f65b90c13f5a4bf285ef088b8cef6283","Platform":"Windows","ProviderType":"Client","GameState":"Athena_GameState_C","Reason":"Destroyed","Vivox.NumActivations":"0","Vivox.SecondsSpentActivated":"0","AthenaGamePhase":"SafeZones","AthenaSafeZoneCenter":"0.000,0.000,0.000","AthenaSafeZoneRadius":"0","AthenaSafeZoneState":"None","AthenaSafeZonePhase":"0","AthenaMatchTimeSec":"143.89946","AthenaPlayersLeft":"0","AthenaTeamsLeft":"0","AthenaMapName":"Athena_Terrain","PlaylistName":"Playlist_DefaultSolo","AthenaTeamNumber":"1","AthenaTeammatesLeft":"0","AthenaPlayerStatus":"Dead","PlayerLocation":"","PlayerPOITags":""}]} +[2018.11.29-17.19.38:923][501]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.19.38:923][501]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() +[2018.11.29-17.19.38:923][501]LogHttp: Verbose: 00000231AA628A80: URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.19.38:923][501]LogHttp: Verbose: 00000231AA628A80: Verb='POST' +[2018.11.29-17.19.38:923][501]LogHttp: Verbose: 00000231AA628A80: Custom headers are present +[2018.11.29-17.19.38:923][501]LogHttp: Verbose: 00000231AA628A80: Payload size=13581 +[2018.11.29-17.19.38:923][501]LogHttp: Verbose: 00000231AA628A80: Adding header 'Content-Type: application/json; charset=utf-8' +[2018.11.29-17.19.38:923][501]LogHttp: Verbose: 00000231AA628A80: Adding header 'User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bit' +[2018.11.29-17.19.38:923][501]LogHttp: Verbose: 00000231AA628A80: Adding header 'Content-Length: 13581' +[2018.11.29-17.19.38:923][501]LogHttp: Verbose: 00000231AA628A80: Adding header 'Expect: ' +[2018.11.29-17.19.38:923][501]LogHttp: 00000231AA628A80: Starting POST request to URL='https://datarouter.ol.epicgames.com/datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream' +[2018.11.29-17.19.38:924][501]LogHttp: Verbose: 00000231AA628A80: request (easy handle:00000231EC5A0010) has been added to threaded queue for processing +[2018.11.29-17.19.38:924][501]LogFortPlayerRegistration: UFortRegisteredPlayerInfo::UnbindFromPlayerController trying to initialize ability system actor +[2018.11.29-17.19.38:924][501]LogSpawn: Warning: SpawnActor failed because we are in the process of tearing down the world +[2018.11.29-17.19.38:924][501]LogFortPlayerRegistration: InitializeAbilitySystemActor initialized with proxy for LoadBot07063 +[2018.11.29-17.19.38:924][501]LogFort: LeaveVoiceChat +[2018.11.29-17.19.38:925][501]WindowsVideoRecordingSystem: Verbose: FWindowsVideoRecordingSystem::FinalizeRecording +[2018.11.29-17.19.38:926][501]WindowsVideoRecordingSystem: Verbose: FWindowsVideoRecordingSystem::FinalizeCallbackOnGameThread +[2018.11.29-17.19.38:944][501]LogHttp: Verbose: 00000231AA628A80: request (easy handle:00000231EC5A0010) has started threaded processing +[2018.11.29-17.19.38:944][501]LogHttp: VeryVerbose: 00000231AA628A80: 'Found bundle for host datarouter.ol.epicgames.com: 0x231a91dc070 [can pipeline]' +[2018.11.29-17.19.38:944][501]LogHttp: VeryVerbose: 00000231AA628A80: 'Re-using existing connection! (#20) with host datarouter.ol.epicgames.com' +[2018.11.29-17.19.38:945][501]LogHttp: VeryVerbose: 00000231AA628A80: 'Connected to datarouter.ol.epicgames.com (34.232.136.228) port 443 (#20)' +[2018.11.29-17.19.38:945][501]LogHttp: VeryVerbose: 00000231AA628A80: Sent SSL data (5 bytes) +[2018.11.29-17.19.38:945][501]LogHttp: VeryVerbose: 00000231AA628A80: Sent header (583 bytes) - POST /datarouter/api/v1/public/data?SessionID=%7B058B0AB1-42C1-6350-7C1B-A3B14BB0CE5F%7D&AppID=Fortnite.DevLatest&AppVersion=1.0.0%20-%20UE4-CL-0&UserID=accb3c904505355102cf80b4f2cb03d3%7Ce6f5091c3b2f4c359cf2aad75c424de0%7Ce04d67a7-16cd-41f9-b939-be602538533a%7Cfa55e3108f3fc66d6c4ff7eb4398e2a9%7C&AppEnvironment=datacollector-binary&UploadType=eteventstream HTTP/1.1Host: datarouter.ol.epicgames.comAccept: */*Accept-Encoding: deflate, gzipContent-Type: application/json; charset=utf-8User-Agent: FortniteGame/UE4-CL-0 Windows/10.0.16299.1.256.64bitContent-Length: 13581 +[2018.11.29-17.19.38:945][501]LogHttp: Verbose: 00000231AA628A80: UploadCallback: 13581 bytes out of 13581 sent. (SizeInBlocks=1, BlockSizeInBytes=16384, SizeToSendThisTime=13581 (<-this will get returned from the callback)) +[2018.11.29-17.19.38:945][501]LogHttp: VeryVerbose: 00000231AA628A80: Sent SSL data (5 bytes) +[2018.11.29-17.19.38:945][501]LogHttp: VeryVerbose: 00000231AA628A80: Sent data (13581 bytes) +[2018.11.29-17.19.38:945][501]LogHttp: VeryVerbose: 00000231AA628A80: 'We are completely uploaded and fine' +[2018.11.29-17.19.38:945][501]LogChartCreation: Stopped creating FPS charts at 17166052.429329 seconds +[2018.11.29-17.19.39:001][501]LogHttp: VeryVerbose: 00000231AA628A80: Received SSL data (5 bytes) +[2018.11.29-17.19.39:001][501]LogHttp: VeryVerbose: 00000231AA628A80: Received header (25 bytes) +[2018.11.29-17.19.39:001][501]LogHttp: Verbose: 00000231AA628A80: Received response header 'HTTP/1.1 204 No Content'. +[2018.11.29-17.19.39:001][501]LogHttp: VeryVerbose: 00000231AA628A80: Received header (37 bytes) +[2018.11.29-17.19.39:001][501]LogHttp: Verbose: 00000231AA628A80: Received response header 'Date: Thu, 29 Nov 2018 17:19:38 GMT'. +[2018.11.29-17.19.39:001][501]LogHttp: VeryVerbose: 00000231AA628A80: Received header (24 bytes) +[2018.11.29-17.19.39:001][501]LogHttp: Verbose: 00000231AA628A80: Received response header 'Connection: keep-alive'. +[2018.11.29-17.19.39:001][501]LogHttp: VeryVerbose: 00000231AA628A80: Received header (32 bytes) +[2018.11.29-17.19.39:001][501]LogHttp: Verbose: 00000231AA628A80: Received response header 'Access-Control-Allow-Origin: *'. +[2018.11.29-17.19.39:001][501]LogHttp: VeryVerbose: 00000231AA628A80: Received header (61 bytes) +[2018.11.29-17.19.39:001][501]LogHttp: Verbose: 00000231AA628A80: Received response header 'X-Epic-Correlation-ID: dbd02eed-389c-4c4b-b655-1fa77623d1fb'. +[2018.11.29-17.19.39:001][501]LogHttp: Verbose: 00000231AA628A80: Received response header ''. +[2018.11.29-17.19.39:001][501]LogHttp: VeryVerbose: 00000231AA628A80: Received header (2 bytes) +[2018.11.29-17.19.39:001][501]LogHttp: VeryVerbose: 00000231AA628A80: 'Connection #20 to host datarouter.ol.epicgames.com left intact' +[2018.11.29-17.19.39:001][501]LogHttp: Verbose: Request 00000231AA628A80 (easy handle:00000231EC5A0010) has completed (code:0) and has been marked as such +[2018.11.29-17.19.39:041][501]LogGarbage: Collecting garbage (GCheckForIllegalMarkPendingKill = 1) +[2018.11.29-17.19.39:052][501]LogGarbage: 11.064648 ms for Verify GC Assumptions +[2018.11.29-17.19.39:085][501]LogGarbage: 32.212217 ms for GC +[2018.11.29-17.19.39:085][501]LogGarbage: 0.000604 ms for dissolving GC clusters +[2018.11.29-17.19.39:086][501]LogGarbage: 0.921350 ms for Gather Unreachable Objects (73715 objects collected including 0 cluster objects from 0 clusters) +[2018.11.29-17.19.39:203][501]LogGarbage: 116.576987 ms for unhashing unreachable objects. Items 73715 (73715/73715) +[2018.11.29-17.19.39:354][501]LogGarbage: GC purged 73715 objects (564662 -> 490947) +[2018.11.29-17.19.39:396][501]LogUObjectHash: Compacting FUObjectHashTables data took 41.45ms +[2018.11.29-17.19.39:442][501]LogLoad: World /Engine/Transient.World_2147477891 not cleaned up by garbage collection! +[2018.11.29-17.19.50:878][501]LogReferenceChain: World /Engine/Transient.World_2147477891 is not currently reachable. +[2018.11.29-17.19.52:184][501]LogLoad: (Object is not currently rooted) + + +[2018.11.29-17.19.52:184][501]LogOutputDevice: Warning: + +Script Stack (0 frames): + +[2018.11.29-17.19.52:184][501]LogWindows: Windows GetLastError: The operation completed successfully. (0) +[2018.11.29-17.19.52:508][501]LogWindows: Warning: CreateProc failed: The system cannot find the file specified. (0x00000002) +[2018.11.29-17.19.52:508][501]LogWindows: Warning: URL: ../../../Engine/Binaries/Win64/CrashReportClient.exe "D:/Epic/Kairos/GauntletTemp/PCTemp/LocalDevice0_UserDir/Saved/Crashes/UE4CC-Windows-C58980F04E9A4CBAD9844196DD30D0F3_0003" -Unattended -AppName=UE4-FortniteGame -CrashGUID=UE4CC-Windows-C58980F04E9A4CBAD9844196DD30D0F3_0003 -DebugSymbols=..\..\..\Engine\Intermediate\Symbols +[2018.11.29-17.19.52:508][501]LogWindows: Error: === Critical error: === +[2018.11.29-17.19.52:509][501]LogWindows: Error: +[2018.11.29-17.19.52:509][501]LogWindows: Error: Fatal error: [File:d:\Epic\Kairos\Engine\Source\Runtime\Engine\Private\UnrealEngine.cpp] [Line: 13042] +[2018.11.29-17.19.52:509][501]LogWindows: Error: World /Engine/Transient.World_2147477891 not cleaned up by garbage collection! +[2018.11.29-17.19.52:509][501]LogWindows: Error: (Object is not currently rooted) +[2018.11.29-17.19.52:509][501]LogWindows: Error: +[2018.11.29-17.19.52:509][501]LogWindows: Error: +[2018.11.29-17.19.52:509][501]LogWindows: Error: +[2018.11.29-17.19.52:509][501]LogWindows: Error: [Callstack] 0x00007ffc189750d8 KERNELBASE.dll!UnknownFunction [] +[2018.11.29-17.19.52:509][501]LogWindows: Error: [Callstack] 0x00007ff792e2bf16 FortniteClient.exe!FWindowsErrorOutputDevice::Serialize() [d:\epic\kairos\engine\source\runtime\core\private\windows\windowserroroutputdevice.cpp:63] +[2018.11.29-17.19.52:509][501]LogWindows: Error: [Callstack] 0x00007ff792c0c1d7 FortniteClient.exe!FOutputDevice::LogfImpl() [d:\epic\kairos\engine\source\runtime\core\private\misc\outputdevice.cpp:71] +[2018.11.29-17.19.52:510][501]LogWindows: Error: [Callstack] 0x00007ff792b2b0f9 FortniteClient.exe!FDebug::AssertFailed() [d:\epic\kairos\engine\source\runtime\core\private\misc\assertionmacros.cpp:419] +[2018.11.29-17.19.52:510][501]LogWindows: Error: [Callstack] 0x00007ff79634a466 FortniteClient.exe!UEngine::VerifyLoadMapWorldCleanup() [d:\epic\kairos\engine\source\runtime\engine\private\unrealengine.cpp:13042] +[2018.11.29-17.19.52:510][501]LogWindows: Error: [Callstack] 0x00007ff796303899 FortniteClient.exe!UEngine::LoadMap() [d:\epic\kairos\engine\source\runtime\engine\private\unrealengine.cpp:12076] +[2018.11.29-17.19.52:510][501]LogWindows: Error: [Callstack] 0x00007ff796299380 FortniteClient.exe!UEngine::Browse() [d:\epic\kairos\engine\source\runtime\engine\private\unrealengine.cpp:11574] +[2018.11.29-17.19.52:510][501]LogWindows: Error: [Callstack] 0x00007ff79633f4cf FortniteClient.exe!UEngine::TickWorldTravel() [d:\epic\kairos\engine\source\runtime\engine\private\unrealengine.cpp:11801] +[2018.11.29-17.19.52:510][501]LogWindows: Error: [Callstack] 0x00007ff79568caf4 FortniteClient.exe!UGameEngine::Tick() [d:\epic\kairos\engine\source\runtime\engine\private\gameengine.cpp:1579] +[2018.11.29-17.19.52:510][501]LogWindows: Error: [Callstack] 0x00007ff791854697 FortniteClient.exe!UFortEngine::Tick() [d:\epic\kairos\fortnitegame\source\fortnitegame\private\fortengine.cpp:511] +[2018.11.29-17.19.52:510][501]LogWindows: Error: [Callstack] 0x00007ff78fd9885d FortniteClient.exe!FEngineLoop::Tick() [d:\epic\kairos\engine\source\runtime\launch\private\launchengineloop.cpp:3929] +[2018.11.29-17.19.52:511][501]LogWindows: Error: [Callstack] 0x00007ff78fda7c7f FortniteClient.exe!GuardedMain() [d:\epic\kairos\engine\source\runtime\launch\private\launch.cpp:179] +[2018.11.29-17.19.52:511][501]LogWindows: Error: [Callstack] 0x00007ff78fda7d3a FortniteClient.exe!GuardedMainWrapper() [d:\epic\kairos\engine\source\runtime\launch\private\windows\launchwindows.cpp:145] +[2018.11.29-17.19.52:511][501]LogWindows: Error: [Callstack] 0x00007ff78fdb79b1 FortniteClient.exe!WinMain() [d:\epic\kairos\engine\source\runtime\launch\private\windows\launchwindows.cpp:276] +[2018.11.29-17.19.52:511][501]LogWindows: Error: [Callstack] 0x00007ff798164a52 FortniteClient.exe!__scrt_common_main_seh() [d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288] +[2018.11.29-17.19.52:511][501]LogWindows: Error: [Callstack] 0x00007ffc1bb71fe4 KERNEL32.DLL!UnknownFunction [] +[2018.11.29-17.19.52:511][501]LogWindows: Error: [Callstack] 0x00007ffc1bcacb31 ntdll.dll!UnknownFunction [] +[2018.11.29-17.19.52:511][501]LogWindows: Error: +[2018.11.29-17.19.52:519][501]LogExit: Executing StaticShutdownAfterError +[2018.11.29-17.19.52:550][501]LogWindows: FPlatformMisc::RequestExit(1) +[2018.11.29-17.19.52:550][501]LogHttp: VeryVerbose: FHttpRequestImpl::OnProcessRequestComplete() +[2018.11.29-17.19.52:550][501]LogHttp: VeryVerbose: FHttpRequestImpl::OnRequestProgress() diff --git a/Engine/Source/Programs/AutomationTool/Gauntlet/SelfTest/Unreal/Gauntlet.SelfTest.LogParserTest.cs b/Engine/Source/Programs/AutomationTool/Gauntlet/SelfTest/Unreal/Gauntlet.SelfTest.LogParserTest.cs index b7898df161f7..01e66c4c426d 100644 --- a/Engine/Source/Programs/AutomationTool/Gauntlet/SelfTest/Unreal/Gauntlet.SelfTest.LogParserTest.cs +++ b/Engine/Source/Programs/AutomationTool/Gauntlet/SelfTest/Unreal/Gauntlet.SelfTest.LogParserTest.cs @@ -122,9 +122,9 @@ namespace Gauntlet.SelfTest { public override void TickTest() { - foreach (var Platform in new[] { "Win64Client", "PS4Client" }) + foreach (var Platform in new[] { "Win64", "PS4" }) { - UnrealLogParser Parser = new UnrealLogParser(GetFileContents("OrionLogWithFatalError" + Platform + ".txt")); + UnrealLogParser Parser = new UnrealLogParser(GetFileContents(Platform + "FatalError" + ".txt")); UnrealLogParser.CallstackMessage FatalError = Parser.GetFatalError(); diff --git a/Engine/Source/Programs/AutomationTool/Gauntlet/Unreal/Utils/Gauntlet.UnrealLogParser.cs b/Engine/Source/Programs/AutomationTool/Gauntlet/Unreal/Utils/Gauntlet.UnrealLogParser.cs index 20de869f98b4..3193a477b01a 100644 --- a/Engine/Source/Programs/AutomationTool/Gauntlet/Unreal/Utils/Gauntlet.UnrealLogParser.cs +++ b/Engine/Source/Programs/AutomationTool/Gauntlet/Unreal/Utils/Gauntlet.UnrealLogParser.cs @@ -469,7 +469,7 @@ namespace Gauntlet SearchContent = SearchContent.Substring(EOL + 1); - } while (LinesWithoutBacktrace < 5); + } while (LinesWithoutBacktrace < 10); if (Backtrace.Count > 0) { diff --git a/Engine/Source/Programs/AutomationTool/Scripts/CopyBuildToStagingDirectory.Automation.cs b/Engine/Source/Programs/AutomationTool/Scripts/CopyBuildToStagingDirectory.Automation.cs index 93e1ef3cb6d1..18a862a54bf2 100644 --- a/Engine/Source/Programs/AutomationTool/Scripts/CopyBuildToStagingDirectory.Automation.cs +++ b/Engine/Source/Programs/AutomationTool/Scripts/CopyBuildToStagingDirectory.Automation.cs @@ -1262,11 +1262,6 @@ public partial class Project : CommandUtils { CopyManifestFilesToStageDir(SC.FilesToStage.NonUFSFiles, SC.StageDirectory, SC.DebugStageDirectory, "NonUFSFiles", SC.StageTargetPlatform.GetFilesForCRCCheck(), SC.StageTargetPlatform.PlatformType.ToString()); - if (!Params.NoDebugInfo) - { - CopyManifestFilesToStageDir(SC.FilesToStage.NonUFSDebugFiles, SC.DebugStageDirectory, SC.DebugStageDirectory, "DebugFiles", SC.StageTargetPlatform.GetFilesForCRCCheck(), SC.StageTargetPlatform.PlatformType.ToString()); - } - bool bStageUnrealFileSystemFiles = !Params.CookOnTheFly && !Params.UsePak(SC.StageTargetPlatform) && !Params.FileServer; if (bStageUnrealFileSystemFiles) { @@ -1285,6 +1280,13 @@ public partial class Project : CommandUtils } CopyManifestFilesToStageDir(UFSFiles, SC.StageDirectory, SC.DebugStageDirectory, "UFSFiles", SC.StageTargetPlatform.GetFilesForCRCCheck(), SC.StageTargetPlatform.PlatformType.ToString()); } + + // Copy debug files last + // they do not respect the DeployLowerCaseFilenames() setting, but if copied to a case-insensitive staging directory first they determine the casing for outer directories (like Engine/Content) + if (!Params.NoDebugInfo) + { + CopyManifestFilesToStageDir(SC.FilesToStage.NonUFSDebugFiles, SC.DebugStageDirectory, SC.DebugStageDirectory, "DebugFiles", SC.StageTargetPlatform.GetFilesForCRCCheck(), SC.StageTargetPlatform.PlatformType.ToString()); + } } // Pak file rules to apply to a list of files @@ -2316,10 +2318,10 @@ public partial class Project : CommandUtils bool bExcludeFromPaks = false; List PakList = new List(); - string OriginalFilename = StagingFile.Key; - string NoExtension = CombinePaths(Path.GetDirectoryName(OriginalFilename), Path.GetFileNameWithoutExtension(OriginalFilename)); - string OriginalReplaceSlashes = OriginalFilename.Replace('/', '\\'); - string NoExtensionReplaceSlashes = NoExtension.Replace('/', '\\'); + string OriginalFilename = StagingFile.Key; + string NoExtension = CombinePaths(Path.GetDirectoryName(OriginalFilename), Path.GetFileNameWithoutExtension(OriginalFilename)); + string OriginalReplaceSlashes = OriginalFilename.Replace('/', '\\'); + string NoExtensionReplaceSlashes = NoExtension.Replace('/', '\\'); // First read manifest for (int ChunkIndex = 0; ChunkIndex < ChunkDefinitions.Count; ++ChunkIndex) @@ -2327,9 +2329,9 @@ public partial class Project : CommandUtils ChunkDefinition Chunk = ChunkDefinitions[ChunkIndex]; if (Chunk.Manifest.Contains(OriginalFilename) || - Chunk.Manifest.Contains(OriginalReplaceSlashes) || - Chunk.Manifest.Contains(NoExtension) || - Chunk.Manifest.Contains(NoExtensionReplaceSlashes)) + Chunk.Manifest.Contains(OriginalReplaceSlashes) || + Chunk.Manifest.Contains(NoExtension) || + Chunk.Manifest.Contains(NoExtensionReplaceSlashes)) { PakList.Add(Chunk.ChunkName); } diff --git a/Engine/Source/Programs/AutomationTool/Scripts/RunP4Reconcile.Automation.cs b/Engine/Source/Programs/AutomationTool/Scripts/RunP4Reconcile.Automation.cs index 16f93cb57a51..b3f996e2cfb2 100644 --- a/Engine/Source/Programs/AutomationTool/Scripts/RunP4Reconcile.Automation.cs +++ b/Engine/Source/Programs/AutomationTool/Scripts/RunP4Reconcile.Automation.cs @@ -27,6 +27,7 @@ namespace AutomationTool { throw new AutomationException("-Description must be defined!"); } + string FileType = ParseParamValue("FileType", null); diff --git a/Engine/Source/Programs/AutomationTool/Scripts/RunProjectCommand.Automation.cs b/Engine/Source/Programs/AutomationTool/Scripts/RunProjectCommand.Automation.cs index 8749a995974e..bc1edfddb277 100644 --- a/Engine/Source/Programs/AutomationTool/Scripts/RunProjectCommand.Automation.cs +++ b/Engine/Source/Programs/AutomationTool/Scripts/RunProjectCommand.Automation.cs @@ -881,10 +881,7 @@ public partial class Project : CommandUtils { TempCmdLine += "-nullrhi "; } - if (Params.Deploy && !Params.CookOnTheFly && (SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.PS4)) - { - TempCmdLine += "-deployedbuild "; - } + TempCmdLine += SC.StageTargetPlatform.GetLaunchExtraCommandLine(Params); TempCmdLine += "-CrashForUAT "; TempCmdLine += Params.RunCommandline; diff --git a/Engine/Source/Programs/AutomationTool/Scripts/SharedCookedBuild.cs b/Engine/Source/Programs/AutomationTool/Scripts/SharedCookedBuild.cs index 795378f92d73..4dd3283b50d0 100644 --- a/Engine/Source/Programs/AutomationTool/Scripts/SharedCookedBuild.cs +++ b/Engine/Source/Programs/AutomationTool/Scripts/SharedCookedBuild.cs @@ -250,6 +250,14 @@ public class SharedCookedBuild { CopySharedCookedBuildForTargetInternal(CookedBuildPath, CookPlatform, LocalPath, bOnlyCopyAssetRegistry); } + else if( FindBestSharedCookedBuild(ref CookedBuildPath, ProjectFullPath, TargetPlatform, TargetPlatform.ToString(), BuildCl) ) + { + CopySharedCookedBuildForTargetInternal(CookedBuildPath, TargetPlatform.ToString(), LocalPath, bOnlyCopyAssetRegistry); + } + else + { + throw new AutomationException("Can't find cooked build for {0} {1} {2}", BuildCl, CookPlatform, TargetPlatform.ToString()); + } return; } diff --git a/Engine/Source/Programs/IOS/UnrealLaunchDaemon/Private/IOS/IOSLaunchDaemonAppMain.cpp b/Engine/Source/Programs/IOS/UnrealLaunchDaemon/Private/IOS/IOSLaunchDaemonAppMain.cpp index a4bf102ce1b5..096ffd3f983a 100644 --- a/Engine/Source/Programs/IOS/UnrealLaunchDaemon/Private/IOS/IOSLaunchDaemonAppMain.cpp +++ b/Engine/Source/Programs/IOS/UnrealLaunchDaemon/Private/IOS/IOSLaunchDaemonAppMain.cpp @@ -46,15 +46,7 @@ void FAppEntry::PreInit(IOSAppDelegate* AppDelegate, UIApplication* Application) AppDelegate.RootView = [pController view]; - if (AppDelegate.OSVersion >= 6.0f) - { - // this probably works back to OS4, but would need testing - [AppDelegate.Window setRootViewController:pController]; - } - else - { - [AppDelegate.Window addSubview:AppDelegate.RootView]; - } + [AppDelegate.Window setRootViewController:pController]; } void FAppEntry::PlatformInit() diff --git a/Engine/Source/Programs/IOS/UnrealLaunchDaemon/Private/IOS/IOSLaunchDaemonView.cpp b/Engine/Source/Programs/IOS/UnrealLaunchDaemon/Private/IOS/IOSLaunchDaemonView.cpp index 31bc375625a8..efafcf5a040c 100644 --- a/Engine/Source/Programs/IOS/UnrealLaunchDaemon/Private/IOS/IOSLaunchDaemonView.cpp +++ b/Engine/Source/Programs/IOS/UnrealLaunchDaemon/Private/IOS/IOSLaunchDaemonView.cpp @@ -177,12 +177,7 @@ self.view = [[IOSLaunchDaemonView alloc] initWithFrame:Frame]; // settings copied from InterfaceBuilder -#if defined(__IPHONE_7_0) - if ([IOSAppDelegate GetDelegate].OSVersion >= 7.0) - { - self.edgesForExtendedLayout = UIRectEdgeNone; - } -#endif + self.edgesForExtendedLayout = UIRectEdgeNone; self.wantsFullScreenLayout = YES; self.view.clearsContextBeforeDrawing = NO; diff --git a/Engine/Source/Programs/SlateViewer/Private/IOS/IOSSlateViewerMain.cpp b/Engine/Source/Programs/SlateViewer/Private/IOS/IOSSlateViewerMain.cpp index 48a2721b73d0..80b685cf4601 100644 --- a/Engine/Source/Programs/SlateViewer/Private/IOS/IOSSlateViewerMain.cpp +++ b/Engine/Source/Programs/SlateViewer/Private/IOS/IOSSlateViewerMain.cpp @@ -43,15 +43,7 @@ void FAppEntry::PreInit(IOSAppDelegate* AppDelegate, UIApplication* Application) // point to the GL view we want to use AppDelegate.RootView = [AppDelegate.SlateController view]; - if (AppDelegate.OSVersion >= 6.0f) - { - // this probably works back to OS4, but would need testing - [AppDelegate.Window setRootViewController:AppDelegate.SlateController]; - } - else - { - [AppDelegate.Window addSubview:AppDelegate.RootView]; - } + [AppDelegate.Window setRootViewController:AppDelegate.SlateController]; } diff --git a/Engine/Source/Programs/UnrealBuildTool/Configuration/ModuleRules.cs b/Engine/Source/Programs/UnrealBuildTool/Configuration/ModuleRules.cs index d01c0f4ef089..f6fe75f38aa8 100644 --- a/Engine/Source/Programs/UnrealBuildTool/Configuration/ModuleRules.cs +++ b/Engine/Source/Programs/UnrealBuildTool/Configuration/ModuleRules.cs @@ -119,6 +119,23 @@ namespace UnrealBuildTool Any, } + /// + /// Control visibility of symbols in this module for special cases + /// + public enum SymbolVisibility + { + /// + /// Standard visibility rules + /// + Default, + + /// + /// Make sure symbols in this module are visible in Dll builds + /// + VisibileForDll, + } + + /// /// Information about a file which is required by the target at runtime, and must be moved around with it. /// @@ -704,6 +721,11 @@ namespace UnrealBuildTool /// public CppStandardVersion CppStandard = CppStandardVersion.Default; + /// + /// Control visibility of symbols + /// + public SymbolVisibility ModuleSymbolVisibility = ModuleRules.SymbolVisibility.Default; + /// /// The current engine directory /// diff --git a/Engine/Source/Programs/UnrealBuildTool/Configuration/TargetRules.cs b/Engine/Source/Programs/UnrealBuildTool/Configuration/TargetRules.cs index c570c74001a0..43adf1dfd31c 100644 --- a/Engine/Source/Programs/UnrealBuildTool/Configuration/TargetRules.cs +++ b/Engine/Source/Programs/UnrealBuildTool/Configuration/TargetRules.cs @@ -281,6 +281,7 @@ namespace UnrealBuildTool /// Whether this target should be compiled as a DLL. Requires LinkType to be set to TargetLinkType.Monolithic. /// [RequiresUniqueBuildEnvironment] + [CommandLine("-CompileAsDll")] public bool bShouldCompileAsDLL = false; /// diff --git a/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildModule.cs b/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildModule.cs index ee67a148d82b..62c9b2a28a8e 100644 --- a/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildModule.cs +++ b/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildModule.cs @@ -474,7 +474,7 @@ namespace UnrealBuildTool { if(Rules.Target.LinkType == TargetLinkType.Monolithic) { - if (Rules.Target.bShouldCompileAsDLL && Rules.Target.bHasExports) + if (Rules.Target.bShouldCompileAsDLL && (Rules.Target.bHasExports || Rules.ModuleSymbolVisibility == ModuleRules.SymbolVisibility.VisibileForDll)) { Definitions.Add(ModuleApiDefine + "=DLLEXPORT"); } diff --git a/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildModuleCPP.cs b/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildModuleCPP.cs index 34c2c6018f57..465d345ccbec 100644 --- a/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildModuleCPP.cs +++ b/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildModuleCPP.cs @@ -258,6 +258,11 @@ namespace UnrealBuildTool // If the module is precompiled, read the object files from the manifest if(Rules.bUsePrecompiled && Target.LinkType == TargetLinkType.Monolithic) { + if(!FileReference.Exists(PrecompiledManifestLocation)) + { + throw new BuildException("Missing precompiled manifest for '{0}'. This module was most likely not flagged for being included in a precompiled build - set 'PrecompileForTargets = PrecompileTargetsType.Any;' in {0}.build.cs to override.", Name); + } + PrecompiledManifest Manifest = PrecompiledManifest.Read(PrecompiledManifestLocation); foreach(FileReference OutputFile in Manifest.OutputFiles) { diff --git a/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildPlatform.cs b/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildPlatform.cs index 6d3a254dd6ec..03b7c5e62046 100644 --- a/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildPlatform.cs +++ b/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildPlatform.cs @@ -687,7 +687,7 @@ namespace UnrealBuildTool ProjIni.GetBool(Section, Key, out Project); if (Default != Project) { - Log.TraceInformationOnce(Key + " is not set to default. (" + Default + " vs. " + Project + ")"); + Log.TraceInformationOnce("{0} is not set to default. (Base: {1} vs. {2}: {3})", Key, Default, Path.GetFileName(ProjectDirectoryName.FullName), Project); return false; } } @@ -700,7 +700,7 @@ namespace UnrealBuildTool ProjIni.GetInt32(Section, Key, out Project); if (Default != Project) { - Log.TraceInformationOnce(Key + " is not set to default. (" + Default + " vs. " + Project + ")"); + Log.TraceInformationOnce("{0} is not set to default. (Base: {1} vs. {2}: {3})", Key, Default, Path.GetFileName(ProjectDirectoryName.FullName), Project); return false; } } @@ -713,7 +713,7 @@ namespace UnrealBuildTool ProjIni.GetString(Section, Key, out Project); if (Default != Project) { - Log.TraceInformationOnce(Key + " is not set to default. (" + Default + " vs. " + Project + ")"); + Log.TraceInformationOnce("{0} is not set to default. (Base: {1} vs. {2}: {3})", Key, Default, Path.GetFileName(ProjectDirectoryName.FullName), Project); return false; } } diff --git a/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildTarget.cs b/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildTarget.cs index 4d1573c58807..8fb543e7f41f 100644 --- a/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildTarget.cs +++ b/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildTarget.cs @@ -982,15 +982,22 @@ namespace UnrealBuildTool // Create the receipt TargetReceipt Receipt = new TargetReceipt(ProjectFile, TargetName, TargetType, Platform, Configuration, Version); - // Set the launch executable if there is one - foreach(KeyValuePair Pair in BuildProducts) + if (!Rules.bShouldCompileAsDLL) { - if(Pair.Value == BuildProductType.Executable) + // Set the launch executable if there is one + foreach (KeyValuePair Pair in BuildProducts) { - Receipt.Launch = Pair.Key; - break; + if (Pair.Value == BuildProductType.Executable) + { + Receipt.Launch = Pair.Key; + break; + } } } + else + { + Receipt.AdditionalProperties.Add(new ReceiptProperty("CompileAsDll", "true")); + } // Find all the build products and modules from this binary foreach (KeyValuePair BuildProductPair in BuildProducts) diff --git a/Engine/Source/Programs/UnrealBuildTool/Platform/Android/AndroidExports.cs b/Engine/Source/Programs/UnrealBuildTool/Platform/Android/AndroidExports.cs index 98344a4d17c2..99a0a344b209 100644 --- a/Engine/Source/Programs/UnrealBuildTool/Platform/Android/AndroidExports.cs +++ b/Engine/Source/Programs/UnrealBuildTool/Platform/Android/AndroidExports.cs @@ -61,9 +61,19 @@ namespace UnrealBuildTool /// /// /// + /// /// + /// /// - bool PrepForUATPackageOrDeploy(FileReference ProjectFile, string ProjectName, DirectoryReference ProjectDirectory, string ExecutablePath, string EngineDirectory, bool bForDistribution, string CookFlavor, bool bIsDataDeploy); + bool PrepForUATPackageOrDeploy(FileReference ProjectFile, string ProjectName, DirectoryReference ProjectDirectory, string ExecutablePath, string EngineDirectory, bool bForDistribution, string CookFlavor, UnrealTargetConfiguration Configuration, bool bIsDataDeploy, bool bSkipGradleBuild); + + /// + /// + /// + /// + /// + /// + bool SavePackageInfo(string ProjectName, string ProjectDirectoryFullName, TargetType Type); } /// diff --git a/Engine/Source/Programs/UnrealBuildTool/Platform/Android/AndroidToolChain.cs b/Engine/Source/Programs/UnrealBuildTool/Platform/Android/AndroidToolChain.cs index d2b1d2087039..a232e5cb2cca 100644 --- a/Engine/Source/Programs/UnrealBuildTool/Platform/Android/AndroidToolChain.cs +++ b/Engine/Source/Programs/UnrealBuildTool/Platform/Android/AndroidToolChain.cs @@ -1570,8 +1570,9 @@ namespace UnrealBuildTool int OutputPathIndex = ArchIndex * GPUArchitectures.Count + GPUArchIndex; // Android will have an array of outputs - if (LinkEnvironment.OutputFilePaths.Count < OutputPathIndex || - !LinkEnvironment.OutputFilePaths[OutputPathIndex].GetFileNameWithoutExtension().EndsWith(Arch + GPUArchitecture)) + if (!LinkEnvironment.bIsBuildingDLL && // DLL compiles don't have the Arch embedded in the name + (LinkEnvironment.OutputFilePaths.Count < OutputPathIndex || + !LinkEnvironment.OutputFilePaths[OutputPathIndex].GetFileNameWithoutExtension().EndsWith(Arch + GPUArchitecture))) { throw new BuildException("The OutputFilePaths array didn't match the Arches array in AndroidToolChain.LinkAllFiles"); } diff --git a/Engine/Source/Programs/UnrealBuildTool/Platform/Android/UEBuildAndroid.cs b/Engine/Source/Programs/UnrealBuildTool/Platform/Android/UEBuildAndroid.cs index 72b010902c52..1fc40654b250 100644 --- a/Engine/Source/Programs/UnrealBuildTool/Platform/Android/UEBuildAndroid.cs +++ b/Engine/Source/Programs/UnrealBuildTool/Platform/Android/UEBuildAndroid.cs @@ -277,7 +277,17 @@ namespace UnrealBuildTool { foreach (string GPUArchitecture in GPUArchitectures) { - AllBinaries.Add(new FileReference(AndroidToolChain.InlineArchName(BinaryName.FullName, Architecture, GPUArchitecture))); + string BinaryPath; + if (Target.bShouldCompileAsDLL) + { + BinaryPath = Path.Combine(BinaryName.Directory.FullName, Target.Configuration.ToString(), "libUE4.so"); + } + else + { + BinaryPath = AndroidToolChain.InlineArchName(BinaryName.FullName, Architecture, GPUArchitecture); + } + + AllBinaries.Add(new FileReference(BinaryPath)); } } diff --git a/Engine/Source/Programs/UnrealBuildTool/Platform/Android/UEDeployAndroid.cs b/Engine/Source/Programs/UnrealBuildTool/Platform/Android/UEDeployAndroid.cs index ba995f329ab6..1bd834e90b29 100644 --- a/Engine/Source/Programs/UnrealBuildTool/Platform/Android/UEDeployAndroid.cs +++ b/Engine/Source/Programs/UnrealBuildTool/Platform/Android/UEDeployAndroid.cs @@ -1151,7 +1151,7 @@ namespace UnrealBuildTool switch (UE4Arch) { case "-armv7": return "armeabi-v7a"; - case "-arm64": return "arm64-v8a"; + case "-arm64": return "arm64-v8a"; case "-x64": return "x86_64"; case "-x86": return "x86"; @@ -1164,15 +1164,15 @@ namespace UnrealBuildTool switch (NDKArch) { case "armeabi-v7a": return "-armv7"; - case "arm64-v8a": return "-arm64"; - case "x86": return "-x86"; - case "arm64": return "-arm64"; + case "arm64-v8a": return "-arm64"; + case "x86": return "-x86"; + case "arm64": return "-arm64"; case "x86_64": case "x64": return "-x64"; -// default: throw new BuildException("Unknown NDK architecture '{0}'", NDKArch); - // future-proof by returning armv7 for unknown - default: return "-armv7"; + // default: throw new BuildException("Unknown NDK architecture '{0}'", NDKArch); + // future-proof by returning armv7 for unknown + default: return "-armv7"; } } @@ -1941,6 +1941,10 @@ namespace UnrealBuildTool { // Remove unused image SafeDeleteFile(PortraitFilename); + + // Remove optional extended resource + string PortraitXmlFilename = UE4BuildPath + ResolutionPath + "splashscreen_p.xml"; + SafeDeleteFile(PortraitXmlFilename); } string LandscapeFilename = UE4BuildPath + ResolutionPath + "splashscreen_landscape.png"; @@ -1955,6 +1959,10 @@ namespace UnrealBuildTool { // Remove unused image SafeDeleteFile(LandscapeFilename); + + // Remove optional extended resource + string LandscapeXmlFilename = UE4BuildPath + ResolutionPath + "splashscreen_l.xml"; + SafeDeleteFile(LandscapeXmlFilename); } } } @@ -2137,7 +2145,7 @@ namespace UnrealBuildTool if (!Ini.TryGetValue("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "MaxAspectRatio", out MaxAspectRatioValue)) { MaxAspectRatioValue = 2.1f; - } + } string Orientation; Ini.GetString("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "Orientation", out Orientation); bool EnableFullScreen; @@ -2279,7 +2287,7 @@ namespace UnrealBuildTool case "_Multi": //need to check ini to determine which are supported Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bMultiTargetFormat_ETC1", out bETC1Enabled); - Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bMultiTargetFormat_ETC1a", out bETC1aEnabled); + Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bMultiTargetFormat_ETC1a", out bETC1aEnabled); Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bMultiTargetFormat_ETC2", out bETC2Enabled); Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bMultiTargetFormat_DXT", out bDXTEnabled); Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bMultiTargetFormat_ATC", out bATCEnabled); @@ -2289,9 +2297,9 @@ namespace UnrealBuildTool case "_ETC1": bETC1Enabled = true; break; - case "_ETC1a": - bETC1aEnabled = true; - break; + case "_ETC1a": + bETC1aEnabled = true; + break; case "_ETC2": bETC2Enabled = true; break; @@ -2498,7 +2506,7 @@ namespace UnrealBuildTool // Max supported aspect ratio string MaxAspectRatioString = MaxAspectRatioValue.ToString("f", System.Globalization.CultureInfo.InvariantCulture); - Text.AppendLine(string.Format("\t\t", MaxAspectRatioString)); + Text.AppendLine(string.Format("\t\t", MaxAspectRatioString)); Text.AppendLine("\t"); @@ -2516,8 +2524,11 @@ namespace UnrealBuildTool } else { - // need just the number part of the sdk - Text.AppendLine(string.Format("\t", MinSDKVersion, TargetSDKVersion)); + if (!bGradleEnabled) + { + // need just the number part of the sdk + Text.AppendLine(string.Format("\t", MinSDKVersion, TargetSDKVersion)); + } Text.AppendLine("\t"); Text.AppendLine("\t"); Text.AppendLine("\t"); @@ -2784,24 +2795,24 @@ namespace UnrealBuildTool return false; } - private bool RequiresOBB(bool bDisallowPackageInAPK, string OBBLocation) - { - if (bDisallowPackageInAPK) - { - Log.TraceInformation("APK contains data."); - return false; - } - else if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("uebp_LOCAL_ROOT"))) - { - Log.TraceInformation("On build machine."); - return true; - } - else - { - Log.TraceInformation("Looking for OBB."); - return File.Exists(OBBLocation); - } - } + private bool RequiresOBB(bool bDisallowPackageInAPK, string OBBLocation) + { + if (bDisallowPackageInAPK) + { + Log.TraceInformation("APK contains data."); + return false; + } + else if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("uebp_LOCAL_ROOT"))) + { + Log.TraceInformation("On build machine."); + return true; + } + else + { + Log.TraceInformation("Looking for OBB."); + return File.Exists(OBBLocation); + } + } private void PatchAntBatIfNeeded() { @@ -2981,7 +2992,214 @@ namespace UnrealBuildTool return true; } - private void MakeApk(AndroidToolChain ToolChain, string ProjectName, TargetType InTargetType, string ProjectDirectory, string OutputPath, string EngineDirectory, bool bForDistribution, string CookFlavor, bool bMakeSeparateApks, bool bIncrementalPackage, bool bDisallowPackagingDataInApk, bool bDisallowExternalFilesDir) + private void CreateGradlePropertiesFiles(AndroidToolChain ToolChain, string Arch, string CompileSDKVersion, string BuildToolsVersion, string PackageName, string DestApkName, string NDKArch, + string UE4BuildFilesPath, string GameBuildFilesPath, string UE4BuildGradleAppPath, string UE4BuildPath, string UE4BuildGradlePath, bool bForDistribution) + { + // Create gradle.properties + StringBuilder GradleProperties = new StringBuilder(); + + int StoreVersion = GetStoreVersion(); + string VersionDisplayName = GetVersionDisplayName(); + int MinSDKVersion; + ConfigHierarchy Ini = GetConfigCacheIni(ConfigHierarchyType.Engine); + Ini.GetInt32("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "MinSDKVersion", out MinSDKVersion); + int TargetSDKVersion = MinSDKVersion; + Ini.GetInt32("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "TargetSDKVersion", out TargetSDKVersion); + + // Make sure minSdkVersion is at least 13 (need this for appcompat-v13 used by AndroidPermissions) + // this may be changed by active plugins (Google Play Services 11.0.4 needs 14 for example) + if (MinSDKVersion < MinimumSDKLevelForGradle) + { + MinSDKVersion = MinimumSDKLevelForGradle; + } + if (TargetSDKVersion < MinSDKVersion) + { + TargetSDKVersion = MinSDKVersion; + } + + // 64-bit targets must be android-21 or higher + int NDKLevelInt = ToolChain.GetNdkApiLevelInt(); + if (NDKLevelInt < 21) + { + if (Arch == "-arm64" || Arch == "-x64") + { + NDKLevelInt = 21; + } + } + + // fix up the MinSdkVersion + if (NDKLevelInt > 19) + { + if (MinSDKVersion < 21) + { + MinSDKVersion = 21; + Log.TraceInformation("Fixing minSdkVersion; NDK level above 19 requires minSdkVersion of 21 (arch={0})", Arch.Substring(1)); + } + } + + GradleProperties.AppendLine("org.gradle.daemon=false"); + GradleProperties.AppendLine("org.gradle.jvmargs=-XX:MaxHeapSize=4096m -Xmx9216m"); + GradleProperties.AppendLine(string.Format("COMPILE_SDK_VERSION={0}", CompileSDKVersion)); + GradleProperties.AppendLine(string.Format("BUILD_TOOLS_VERSION={0}", BuildToolsVersion)); + GradleProperties.AppendLine(string.Format("PACKAGE_NAME={0}", PackageName)); + GradleProperties.AppendLine(string.Format("MIN_SDK_VERSION={0}", MinSDKVersion.ToString())); + GradleProperties.AppendLine(string.Format("TARGET_SDK_VERSION={0}", TargetSDKVersion.ToString())); + GradleProperties.AppendLine(string.Format("STORE_VERSION={0}", StoreVersion.ToString())); + GradleProperties.AppendLine(string.Format("VERSION_DISPLAY_NAME={0}", VersionDisplayName)); + + if (DestApkName != null) + { + GradleProperties.AppendLine(string.Format("OUTPUT_PATH={0}", Path.GetDirectoryName(DestApkName).Replace("\\", "/"))); + GradleProperties.AppendLine(string.Format("OUTPUT_FILENAME={0}", Path.GetFileName(DestApkName))); + } + + // add any Gradle properties from UPL + string GradlePropertiesUPL = UPL.ProcessPluginNode(NDKArch, "gradleProperties", ""); + GradleProperties.AppendLine(GradlePropertiesUPL); + + StringBuilder GradleBuildAdditionsContent = new StringBuilder(); + GradleBuildAdditionsContent.AppendLine("apply from: 'aar-imports.gradle'"); + GradleBuildAdditionsContent.AppendLine("apply from: 'projects.gradle'"); + + GradleBuildAdditionsContent.AppendLine("android {"); + GradleBuildAdditionsContent.AppendLine("\tdefaultConfig {"); + GradleBuildAdditionsContent.AppendLine("\t\tndk {"); + GradleBuildAdditionsContent.AppendLine(string.Format("\t\t\tabiFilter \"{0}\"", NDKArch)); + GradleBuildAdditionsContent.AppendLine("\t\t}"); + GradleBuildAdditionsContent.AppendLine("\t}"); + + if (bForDistribution) + { + bool bDisableV2Signing = false; + + if (IsPackagingForGearVR()) + { + bDisableV2Signing = true; + Log.TraceInformation("Disabling v2Signing for Gear VR APK"); + } + + string KeyAlias, KeyStore, KeyStorePassword, KeyPassword; + Ini.GetString("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "KeyStore", out KeyStore); + Ini.GetString("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "KeyAlias", out KeyAlias); + Ini.GetString("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "KeyStorePassword", out KeyStorePassword); + Ini.GetString("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "KeyPassword", out KeyPassword); + + if (string.IsNullOrEmpty(KeyStore) || string.IsNullOrEmpty(KeyAlias) || string.IsNullOrEmpty(KeyStorePassword)) + { + throw new BuildException("DistributionSigning settings are not all set. Check the DistributionSettings section in the Android tab of Project Settings"); + } + + if (string.IsNullOrEmpty(KeyPassword) || KeyPassword == "_sameaskeystore_") + { + KeyPassword = KeyStorePassword; + } + + // Make sure the keystore file exists + string KeyStoreFilename = Path.Combine(UE4BuildPath, KeyStore); + if (!File.Exists(KeyStoreFilename)) + { + throw new BuildException("Keystore file is missing. Check the DistributionSettings section in the Android tab of Project Settings"); + } + + GradleProperties.AppendLine(string.Format("STORE_FILE={0}", KeyStoreFilename.Replace("\\", "/"))); + GradleProperties.AppendLine(string.Format("STORE_PASSWORD={0}", KeyStorePassword)); + GradleProperties.AppendLine(string.Format("KEY_ALIAS={0}", KeyAlias)); + GradleProperties.AppendLine(string.Format("KEY_PASSWORD={0}", KeyPassword)); + + GradleBuildAdditionsContent.AppendLine("\tsigningConfigs {"); + GradleBuildAdditionsContent.AppendLine("\t\trelease {"); + GradleBuildAdditionsContent.AppendLine(string.Format("\t\t\tstoreFile file('{0}')", KeyStoreFilename.Replace("\\", "/"))); + GradleBuildAdditionsContent.AppendLine(string.Format("\t\t\tstorePassword '{0}'", KeyStorePassword)); + GradleBuildAdditionsContent.AppendLine(string.Format("\t\t\tkeyAlias '{0}'", KeyAlias)); + GradleBuildAdditionsContent.AppendLine(string.Format("\t\t\tkeyPassword '{0}'", KeyPassword)); + if (bDisableV2Signing) + { + GradleBuildAdditionsContent.AppendLine("\t\t\tv2SigningEnabled false"); + } + GradleBuildAdditionsContent.AppendLine("\t\t}"); + GradleBuildAdditionsContent.AppendLine("\t}"); + + // Generate the Proguard file contents and write it + string ProguardContents = GenerateProguard(NDKArch, UE4BuildFilesPath, GameBuildFilesPath); + string ProguardFilename = Path.Combine(UE4BuildGradleAppPath, "proguard-rules.pro"); + SafeDeleteFile(ProguardFilename); + File.WriteAllText(ProguardFilename, ProguardContents); + } + else + { + // empty just for Gradle not to complain + GradleProperties.AppendLine("STORE_FILE="); + GradleProperties.AppendLine("STORE_PASSWORD="); + GradleProperties.AppendLine("KEY_ALIAS="); + GradleProperties.AppendLine("KEY_PASSWORD="); + + // empty just for Gradle not to complain + GradleBuildAdditionsContent.AppendLine("\tsigningConfigs {"); + GradleBuildAdditionsContent.AppendLine("\t\trelease {"); + GradleBuildAdditionsContent.AppendLine("\t\t}"); + GradleBuildAdditionsContent.AppendLine("\t}"); + } + + GradleBuildAdditionsContent.AppendLine("\tbuildTypes {"); + GradleBuildAdditionsContent.AppendLine("\t\trelease {"); + GradleBuildAdditionsContent.AppendLine("\t\t\tsigningConfig signingConfigs.release"); + if (GradlePropertiesUPL.Contains("DISABLE_MINIFY=1")) + { + GradleBuildAdditionsContent.AppendLine("\t\t\tminifyEnabled false"); + } + else + { + GradleBuildAdditionsContent.AppendLine("\t\t\tminifyEnabled true"); + } + if (GradlePropertiesUPL.Contains("DISABLE_PROGUARD=1")) + { + GradleBuildAdditionsContent.AppendLine("\t\t\tuseProguard false"); + } + else + { + GradleBuildAdditionsContent.AppendLine("\t\t\tproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'"); + } + GradleBuildAdditionsContent.AppendLine("\t\t}"); + GradleBuildAdditionsContent.AppendLine("\t\tdebug {"); + GradleBuildAdditionsContent.AppendLine("\t\t\tdebuggable true"); + GradleBuildAdditionsContent.AppendLine("\t\t}"); + GradleBuildAdditionsContent.AppendLine("\t}"); + GradleBuildAdditionsContent.AppendLine("}"); + + // Add any UPL app buildGradleAdditions + GradleBuildAdditionsContent.Append(UPL.ProcessPluginNode(NDKArch, "buildGradleAdditions", "")); + + string GradleBuildAdditionsFilename = Path.Combine(UE4BuildGradleAppPath, "buildAdditions.gradle"); + File.WriteAllText(GradleBuildAdditionsFilename, GradleBuildAdditionsContent.ToString()); + + string GradlePropertiesFilename = Path.Combine(UE4BuildGradlePath, "gradle.properties"); + File.WriteAllText(GradlePropertiesFilename, GradleProperties.ToString()); + + // Add lint if requested (note depreciation warnings can be suppressed with @SuppressWarnings("deprecation") + string GradleBaseBuildAdditionsContents = ""; + bool bEnableLint = false; + Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bEnableLint", out bEnableLint); + if (bEnableLint) + { + GradleBaseBuildAdditionsContents = + "allprojects {\n" + + "\ttasks.withType(JavaCompile) {\n" + + "\t\toptions.compilerArgs << \"-Xlint:unchecked\" << \"-Xlint:deprecation\"\n" + + "\t}\n" + + "}\n\n"; + } + + // Create baseBuildAdditions.gradle from plugins baseBuildGradleAdditions + string GradleBaseBuildAdditionsFilename = Path.Combine(UE4BuildGradlePath, "baseBuildAdditions.gradle"); + File.WriteAllText(GradleBaseBuildAdditionsFilename, UPL.ProcessPluginNode(NDKArch, "baseBuildGradleAdditions", GradleBaseBuildAdditionsContents)); + + // Create buildscriptAdditions.gradle from plugins buildscriptGradleAdditions + string GradleBuildScriptAdditionsFilename = Path.Combine(UE4BuildGradlePath, "buildscriptAdditions.gradle"); + File.WriteAllText(GradleBuildScriptAdditionsFilename, UPL.ProcessPluginNode(NDKArch, "buildscriptGradleAdditions", "")); + } + + private void MakeApk(AndroidToolChain ToolChain, string ProjectName, TargetType InTargetType, string ProjectDirectory, string OutputPath, string EngineDirectory, bool bForDistribution, string CookFlavor, + UnrealTargetConfiguration Configuration, bool bMakeSeparateApks, bool bIncrementalPackage, bool bDisallowPackagingDataInApk, bool bDisallowExternalFilesDir, bool bSkipGradleBuild) { Log.TraceInformation("\n===={0}====PREPARING TO MAKE APK=================================================================", DateTime.Now.ToString()); @@ -3074,10 +3292,10 @@ namespace UnrealBuildTool } WriteJavaDownloadSupportFiles(UE4DownloadShimFileName, templates, new Dictionary{ - { "$$GameName$$", ProjectName }, - { "$$PublicKey$$", GetPublicKey() }, - { "$$PackageName$$",PackageName } - }); + { "$$GameName$$", ProjectName }, + { "$$PublicKey$$", GetPublicKey() }, + { "$$PackageName$$",PackageName } + }); // Sometimes old files get left behind if things change, so we'll do a clean up pass { @@ -3194,8 +3412,8 @@ namespace UnrealBuildTool } } - // only check input dependencies if the build settings already match - if (bBuildSettingsMatch) + // only check input dependencies if the build settings already match (if we don't run gradle, there is no Apk file to check against) + if (bBuildSettingsMatch && !bSkipGradleBuild) { // check if so's are up to date against various inputs List JavaFiles = new List{ @@ -3214,26 +3432,6 @@ namespace UnrealBuildTool List Arches = ToolChain.GetAllArchitectures(); List GPUArchitectures = ToolChain.GetAllGPUArchitectures(); - // figure out the configuration from output filename - string Configuration = "Development"; - string OutputConfig = Path.GetFileNameWithoutExtension(OutputPath); - if (OutputConfig.EndsWith("-Debug")) - { - Configuration = "Debug"; - } - else if (OutputConfig.EndsWith("-Test")) - { - Configuration = "Test"; - } - else if (OutputConfig.EndsWith("-DebugGame")) - { - Configuration = "Debug"; - } - else if (OutputConfig.EndsWith("-Shipping")) - { - Configuration = "Shipping"; - } - // Initialize UPL contexts for each architecture enabled List NDKArches = new List(); foreach (string Arch in Arches) @@ -3244,7 +3442,8 @@ namespace UnrealBuildTool NDKArches.Add(NDKArch); } } - UPL.Init(NDKArches, bForDistribution, EngineDirectory, UE4BuildPath, ProjectDirectory, Configuration); + + UPL.Init(NDKArches, bForDistribution, EngineDirectory, UE4BuildPath, ProjectDirectory, Configuration.ToString()); IEnumerable> BuildList = null; @@ -3252,7 +3451,7 @@ namespace UnrealBuildTool { BuildList = from Arch in Arches from GPUArch in GPUArchitectures - let manifest = GenerateManifest(ToolChain, ProjectName, InTargetType, EngineDirectory, bForDistribution, bPackageDataInsideApk, GameBuildFilesPath, RequiresOBB(bDisallowPackagingDataInApk, ObbFileLocation), bDisableVerifyOBBOnStartUp, Arch, GPUArch, CookFlavor, bUseExternalFilesDir, Configuration, SDKLevelInt) + let manifest = GenerateManifest(ToolChain, ProjectName, InTargetType, EngineDirectory, bForDistribution, bPackageDataInsideApk, GameBuildFilesPath, RequiresOBB(bDisallowPackagingDataInApk, ObbFileLocation), bDisableVerifyOBBOnStartUp, Arch, GPUArch, CookFlavor, bUseExternalFilesDir, Configuration.ToString(), SDKLevelInt) select Tuple.Create(Arch, GPUArch, manifest); } else @@ -3260,7 +3459,7 @@ namespace UnrealBuildTool BuildList = from Arch in Arches from GPUArch in GPUArchitectures let manifestFile = Path.Combine(IntermediateAndroidPath, Arch + "_" + GPUArch + "_AndroidManifest.xml") - let manifest = GenerateManifest(ToolChain, ProjectName, InTargetType, EngineDirectory, bForDistribution, bPackageDataInsideApk, GameBuildFilesPath, RequiresOBB(bDisallowPackagingDataInApk, ObbFileLocation), bDisableVerifyOBBOnStartUp, Arch, GPUArch, CookFlavor, bUseExternalFilesDir, Configuration, SDKLevelInt) + let manifest = GenerateManifest(ToolChain, ProjectName, InTargetType, EngineDirectory, bForDistribution, bPackageDataInsideApk, GameBuildFilesPath, RequiresOBB(bDisallowPackagingDataInApk, ObbFileLocation), bDisableVerifyOBBOnStartUp, Arch, GPUArch, CookFlavor, bUseExternalFilesDir, Configuration.ToString(), SDKLevelInt) let OldManifest = File.Exists(manifestFile) ? File.ReadAllText(manifestFile) : "" where manifest != OldManifest select Tuple.Create(Arch, GPUArch, manifest); @@ -3415,6 +3614,12 @@ namespace UnrealBuildTool string AntVerbosity; Ini.GetString("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "AntVerbosity", out AntVerbosity); + // use Gradle for compile/package + string UE4BuildGradlePath = Path.Combine(UE4BuildPath, "gradle"); + string UE4BuildGradleAppPath = Path.Combine(UE4BuildGradlePath, "app"); + string UE4BuildGradleMainPath = Path.Combine(UE4BuildGradleAppPath, "src", "main"); + string CompileSDKVersion = SDKAPILevel.Replace("android-", ""); + foreach (Tuple build in BuildList) { string Arch = build.Item1; @@ -3422,14 +3627,6 @@ namespace UnrealBuildTool string Manifest = build.Item3; string NDKArch = GetNDKArch(Arch); - string SourceSOName = AndroidToolChain.InlineArchName(OutputPath, Arch, GPUArchitecture); - // if the source binary was UE4Game, replace it with the new project name, when re-packaging a binary only build - string ApkFilename = Path.GetFileNameWithoutExtension(OutputPath).Replace("UE4Game", ProjectName); - string DestApkName = Path.Combine(ProjectDirectory, "Binaries/Android/") + ApkFilename + ".apk"; - - // As we are always making seperate APKs we need to put the architecture into the name - DestApkName = AndroidToolChain.InlineArchName(DestApkName, Arch, GPUArchitecture); - // Write the manifest to the correct locations (cache and real) String ManifestFile = Path.Combine(IntermediateAndroidPath, Arch + "_" + GPUArchitecture + "_AndroidManifest.xml"); File.WriteAllText(ManifestFile, Manifest); @@ -3454,105 +3651,95 @@ namespace UnrealBuildTool // update GameActivity.java if out of date UpdateGameActivity(Arch, NDKArch, EngineDirectory, UE4BuildPath); - // Copy the generated .so file from the binaries directory to the jni folder - if (!File.Exists(SourceSOName)) + // we don't actually need the SO for the bSkipGradleBuild case + string FinalSOName = null; + string DestApkDirectory = Path.Combine(ProjectDirectory, "Binaries/Android"); + string DestApkName = null; + if (bSkipGradleBuild) { - throw new BuildException("Can't make an APK without the compiled .so [{0}]", SourceSOName); - } - if (!Directory.Exists(UE4BuildPath + "/jni")) - { - throw new BuildException("Can't make an APK without the jni directory [{0}/jni]", UE4BuildFilesPath); - } - - String FinalSOName; - - if (bGradleEnabled) - { - string JniDir = UE4BuildPath + "/jni/" + NDKArch; - FinalSOName = JniDir + "/libUE4.so"; - - // clear out libs directory like ndk-build would have - string LibsDir = Path.Combine(UE4BuildPath, "libs"); - DeleteDirectory(LibsDir); - MakeDirectoryIfRequired(LibsDir); - - // check to see if libUE4.so needs to be copied - if (BuildListComboTotal > 1 || FilesAreDifferent(SourceSOName, FinalSOName)) - { - Log.TraceInformation("\nCopying new .so {0} file to jni folder...", SourceSOName); - Directory.CreateDirectory(JniDir); - // copy the binary to the standard .so location - File.Copy(SourceSOName, FinalSOName, true); - File.SetLastWriteTimeUtc(FinalSOName, File.GetLastWriteTimeUtc(SourceSOName)); - } + FinalSOName = OutputPath; } else { - if (HasNDKPath) + string SourceSOName = AndroidToolChain.InlineArchName(OutputPath, Arch, GPUArchitecture); + // if the source binary was UE4Game, replace it with the new project name, when re-packaging a binary only build + string ApkFilename = Path.GetFileNameWithoutExtension(OutputPath).Replace("UE4Game", ProjectName); + DestApkName = Path.Combine(DestApkDirectory, ApkFilename + ".apk"); + + // As we are always making seperate APKs we need to put the architecture into the name + DestApkName = AndroidToolChain.InlineArchName(DestApkName, Arch, GPUArchitecture); + + if (!File.Exists(SourceSOName)) { - string LibDir = UE4BuildPath + "/jni/" + NDKArch; - FinalSOName = LibDir + "/libUE4.so"; + throw new BuildException("Can't make an APK without the compiled .so [{0}]", SourceSOName); + } + if (!Directory.Exists(UE4BuildPath + "/jni")) + { + throw new BuildException("Can't make an APK without the jni directory [{0}/jni]", UE4BuildFilesPath); + } + + if (bGradleEnabled) + { + string JniDir = UE4BuildPath + "/jni/" + NDKArch; + FinalSOName = JniDir + "/libUE4.so"; + + // clear out libs directory like ndk-build would have + string LibsDir = Path.Combine(UE4BuildPath, "libs"); + DeleteDirectory(LibsDir); + MakeDirectoryIfRequired(LibsDir); // check to see if libUE4.so needs to be copied if (BuildListComboTotal > 1 || FilesAreDifferent(SourceSOName, FinalSOName)) { Log.TraceInformation("\nCopying new .so {0} file to jni folder...", SourceSOName); - Directory.CreateDirectory(LibDir); + Directory.CreateDirectory(JniDir); // copy the binary to the standard .so location File.Copy(SourceSOName, FinalSOName, true); + File.SetLastWriteTimeUtc(FinalSOName, File.GetLastWriteTimeUtc(SourceSOName)); } } else { - // if no NDK, we don't need any of the debugger stuff, so we just copy the .so to where it will end up - FinalSOName = UE4BuildPath + "/libs/" + NDKArch + "/libUE4.so"; - - // check to see if libUE4.so needs to be copied - if (BuildListComboTotal > 1 || FilesAreDifferent(SourceSOName, FinalSOName)) + if (HasNDKPath) { - Log.TraceInformation("\nCopying .so {0} file to jni folder...", SourceSOName); - Directory.CreateDirectory(Path.GetDirectoryName(FinalSOName)); - File.Copy(SourceSOName, FinalSOName, true); + string LibDir = UE4BuildPath + "/jni/" + NDKArch; + FinalSOName = LibDir + "/libUE4.so"; + + // check to see if libUE4.so needs to be copied + if (BuildListComboTotal > 1 || FilesAreDifferent(SourceSOName, FinalSOName)) + { + Log.TraceInformation("\nCopying new .so {0} file to jni folder...", SourceSOName); + Directory.CreateDirectory(LibDir); + // copy the binary to the standard .so location + File.Copy(SourceSOName, FinalSOName, true); + } + } + else + { + // if no NDK, we don't need any of the debugger stuff, so we just copy the .so to where it will end up + FinalSOName = UE4BuildPath + "/libs/" + NDKArch + "/libUE4.so"; + + // check to see if libUE4.so needs to be copied + if (BuildListComboTotal > 1 || FilesAreDifferent(SourceSOName, FinalSOName)) + { + Log.TraceInformation("\nCopying .so {0} file to jni folder...", SourceSOName); + Directory.CreateDirectory(Path.GetDirectoryName(FinalSOName)); + File.Copy(SourceSOName, FinalSOName, true); + } } } - } - // remove any read only flags - FileInfo DestFileInfo = new FileInfo(FinalSOName); - DestFileInfo.Attributes = DestFileInfo.Attributes & ~FileAttributes.ReadOnly; - File.SetLastWriteTimeUtc(FinalSOName, File.GetLastWriteTimeUtc(SourceSOName)); - - // if we need to run ndk-build, do it now (Ant-only) - if (!bGradleEnabled && HasNDKPath) - { - string LibSOName = UE4BuildPath + "/libs/" + NDKArch + "/libUE4.so"; - // always delete libs up to this point so fat binaries and incremental builds work together (otherwise we might end up with multiple - // so files in an apk that doesn't want them) - // note that we don't want to delete all libs, just the ones we copied - TimeSpan Diff = File.GetLastWriteTimeUtc(LibSOName) - File.GetLastWriteTimeUtc(FinalSOName); - if (!File.Exists(LibSOName) || Diff.TotalSeconds < -1 || Diff.TotalSeconds > 1) - { - foreach (string Lib in Directory.EnumerateFiles(UE4BuildPath + "/libs", "libUE4*.so", SearchOption.AllDirectories)) - { - File.Delete(Lib); - } - - string CommandLine = "APP_ABI=\"" + NDKArch + " " + "\""; - if (!bForDistribution) - { - CommandLine += " NDK_DEBUG=1"; - } - RunCommandLineProgramWithException(UE4BuildPath, NDKBuildPath, CommandLine, "Preparing native code for debugging...", true); - - File.SetLastWriteTimeUtc(LibSOName, File.GetLastWriteTimeUtc(FinalSOName)); - } + // remove any read only flags + FileInfo DestFileInfo = new FileInfo(FinalSOName); + DestFileInfo.Attributes = DestFileInfo.Attributes & ~FileAttributes.ReadOnly; + File.SetLastWriteTimeUtc(FinalSOName, File.GetLastWriteTimeUtc(SourceSOName)); } // after ndk-build is called, we can now copy in the stl .so (ndk-build deletes old files) // copy libgnustl_shared.so to library (use 4.8 if possible, otherwise 4.6) CopySTL(ToolChain, UE4BuildPath, Arch, NDKArch, bForDistribution, bGradleEnabled); CopyGfxDebugger(UE4BuildPath, Arch, NDKArch); - CopyVulkanValidationLayers(UE4BuildPath, Arch, NDKArch, Configuration); + CopyVulkanValidationLayers(UE4BuildPath, Arch, NDKArch, Configuration.ToString()); // copy postbuild plugin files UPL.ProcessPluginNode(NDKArch, "resourceCopies", ""); @@ -3561,6 +3748,7 @@ namespace UnrealBuildTool Log.TraceInformation("\n===={0}====PERFORMING FINAL APK PACKAGE OPERATION================================================", DateTime.Now.ToString()); + if (!bGradleEnabled) { // use Ant for compile/package @@ -3619,14 +3807,6 @@ namespace UnrealBuildTool } else { - // use Gradle for compile/package - // ini file to get settings from - string UE4BuildGradlePath = Path.Combine(UE4BuildPath, "gradle"); - string UE4BuildGradleAppPath = Path.Combine(UE4BuildGradlePath, "app"); - string UE4BuildGradleMainPath = Path.Combine(UE4BuildGradleAppPath, "src", "main"); - - string CompileSDKVersion = SDKAPILevel.Replace("android-", ""); - // check if any plugins want to increase the required compile SDK version string CompileSDKMin = UPL.ProcessPluginNode(NDKArch, "minimumSDKAPI", ""); if (CompileSDKMin != "") @@ -3686,7 +3866,7 @@ namespace UnrealBuildTool break; } - CleanCopyDirectory(Path.Combine(UE4BuildPath, "jni"), Path.Combine(UE4BuildGradleMainPath, "jniLibs"), Excludes); // has debug symbols + CleanCopyDirectory(Path.Combine(UE4BuildPath, "jni"), Path.Combine(UE4BuildGradleMainPath, "jniLibs"), Excludes); // has debug symbols CleanCopyDirectory(Path.Combine(UE4BuildPath, "libs"), Path.Combine(UE4BuildGradleMainPath, "libs"), Excludes); CleanCopyDirectory(Path.Combine(UE4BuildPath, "assets"), Path.Combine(UE4BuildGradleMainPath, "assets")); @@ -3707,275 +3887,83 @@ namespace UnrealBuildTool LocalProperties.AppendLine(string.Format("sdk.dir={0}", Environment.GetEnvironmentVariable("ANDROID_HOME").Replace("\\", "/"))); File.WriteAllText(LocalPropertiesFilename, LocalProperties.ToString()); - // Create gradle.properties - StringBuilder GradleProperties = new StringBuilder(); + CreateGradlePropertiesFiles(ToolChain, Arch, CompileSDKVersion, BuildToolsVersion, PackageName, DestApkName, NDKArch, + UE4BuildFilesPath, GameBuildFilesPath, UE4BuildGradleAppPath, UE4BuildPath, UE4BuildGradlePath, bForDistribution); - int StoreVersion = GetStoreVersion(); - string VersionDisplayName = GetVersionDisplayName(); - int MinSDKVersion; - Ini.GetInt32("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "MinSDKVersion", out MinSDKVersion); - int TargetSDKVersion = MinSDKVersion; - Ini.GetInt32("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "TargetSDKVersion", out TargetSDKVersion); - - // Make sure minSdkVersion is at least 13 (need this for appcompat-v13 used by AndroidPermissions) - // this may be changed by active plugins (Google Play Services 11.0.4 needs 14 for example) - if (MinSDKVersion < MinimumSDKLevelForGradle) + if (!bSkipGradleBuild) { - MinSDKVersion = MinimumSDKLevelForGradle; - } - if (TargetSDKVersion < MinSDKVersion) - { - TargetSDKVersion = MinSDKVersion; - } - - // 64-bit targets must be android-21 or higher - int NDKLevelInt = ToolChain.GetNdkApiLevelInt(); - if (NDKLevelInt < 21) - { - if (Arch == "-arm64" || Arch == "-x64") + string GradleScriptPath = Path.Combine(UE4BuildGradlePath, "gradlew"); + if (Utils.IsRunningOnMono) { - NDKLevelInt = 21; - } - } - - // fix up the MinSdkVersion - if (NDKLevelInt > 19) - { - if (MinSDKVersion < 21) - { - MinSDKVersion = 21; - Log.TraceInformation("Fixing minSdkVersion; NDK level above 19 requires minSdkVersion of 21 (arch={0})", Arch.Substring(1)); - } - } - - GradleProperties.AppendLine("org.gradle.daemon=false"); - GradleProperties.AppendLine("org.gradle.jvmargs=-Xmx8192m"); - GradleProperties.AppendLine(string.Format("COMPILE_SDK_VERSION={0}", CompileSDKVersion)); - GradleProperties.AppendLine(string.Format("BUILD_TOOLS_VERSION={0}", BuildToolsVersion)); - GradleProperties.AppendLine(string.Format("PACKAGE_NAME={0}", PackageName)); - GradleProperties.AppendLine(string.Format("MIN_SDK_VERSION={0}", MinSDKVersion.ToString())); - GradleProperties.AppendLine(string.Format("TARGET_SDK_VERSION={0}", TargetSDKVersion.ToString())); - GradleProperties.AppendLine(string.Format("STORE_VERSION={0}", StoreVersion.ToString())); - GradleProperties.AppendLine(string.Format("VERSION_DISPLAY_NAME={0}", VersionDisplayName)); - - GradleProperties.AppendLine(string.Format("OUTPUT_PATH={0}", Path.GetDirectoryName(DestApkName).Replace("\\", "/"))); - GradleProperties.AppendLine(string.Format("OUTPUT_FILENAME={0}", Path.GetFileName(DestApkName))); - - // add any Gradle properties from UPL - string GradlePropertiesUPL = UPL.ProcessPluginNode(NDKArch, "gradleProperties", ""); - GradleProperties.AppendLine(GradlePropertiesUPL); - - StringBuilder GradleBuildAdditionsContent = new StringBuilder(); - GradleBuildAdditionsContent.AppendLine("apply from: 'aar-imports.gradle'"); - GradleBuildAdditionsContent.AppendLine("apply from: 'projects.gradle'"); - - GradleBuildAdditionsContent.AppendLine("android {"); - GradleBuildAdditionsContent.AppendLine("\tdefaultConfig {"); - GradleBuildAdditionsContent.AppendLine("\t\tndk {"); - GradleBuildAdditionsContent.AppendLine(string.Format("\t\t\tabiFilter \"{0}\"", NDKArch)); - GradleBuildAdditionsContent.AppendLine("\t\t}"); - GradleBuildAdditionsContent.AppendLine("\t}"); - - if (bForDistribution) - { - bool bDisableV2Signing = false; - - if (IsPackagingForGearVR()) - { - bDisableV2Signing = true; - Log.TraceInformation("Disabling v2Signing for Gear VR APK"); - } - - string KeyAlias, KeyStore, KeyStorePassword, KeyPassword; - Ini.GetString("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "KeyStore", out KeyStore); - Ini.GetString("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "KeyAlias", out KeyAlias); - Ini.GetString("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "KeyStorePassword", out KeyStorePassword); - Ini.GetString("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "KeyPassword", out KeyPassword); - - if (string.IsNullOrEmpty(KeyStore) || string.IsNullOrEmpty(KeyAlias) || string.IsNullOrEmpty(KeyStorePassword)) - { - throw new BuildException("DistributionSigning settings are not all set. Check the DistributionSettings section in the Android tab of Project Settings"); - } - - if (string.IsNullOrEmpty(KeyPassword) || KeyPassword == "_sameaskeystore_") - { - KeyPassword = KeyStorePassword; - } - - // Make sure the keystore file exists - string KeyStoreFilename = Path.Combine(UE4BuildPath, KeyStore); - if (!File.Exists(KeyStoreFilename)) - { - throw new BuildException("Keystore file is missing. Check the DistributionSettings section in the Android tab of Project Settings"); - } - - GradleProperties.AppendLine(string.Format("STORE_FILE={0}", KeyStoreFilename.Replace("\\", "/"))); - GradleProperties.AppendLine(string.Format("STORE_PASSWORD={0}", KeyStorePassword)); - GradleProperties.AppendLine(string.Format("KEY_ALIAS={0}", KeyAlias)); - GradleProperties.AppendLine(string.Format("KEY_PASSWORD={0}", KeyPassword)); - - GradleBuildAdditionsContent.AppendLine("\tsigningConfigs {"); - GradleBuildAdditionsContent.AppendLine("\t\trelease {"); - GradleBuildAdditionsContent.AppendLine(string.Format("\t\t\tstoreFile file('{0}')", KeyStoreFilename.Replace("\\", "/"))); - GradleBuildAdditionsContent.AppendLine(string.Format("\t\t\tstorePassword '{0}'", KeyStorePassword)); - GradleBuildAdditionsContent.AppendLine(string.Format("\t\t\tkeyAlias '{0}'", KeyAlias)); - GradleBuildAdditionsContent.AppendLine(string.Format("\t\t\tkeyPassword '{0}'", KeyPassword)); - if (bDisableV2Signing) - { - GradleBuildAdditionsContent.AppendLine("\t\t\tv2SigningEnabled false"); - } - GradleBuildAdditionsContent.AppendLine("\t\t}"); - GradleBuildAdditionsContent.AppendLine("\t}"); - - // Generate the Proguard file contents and write it - string ProguardContents = GenerateProguard(NDKArch, UE4BuildFilesPath, GameBuildFilesPath); - string ProguardFilename = Path.Combine(UE4BuildGradleAppPath, "proguard-rules.pro"); - SafeDeleteFile(ProguardFilename); - File.WriteAllText(ProguardFilename, ProguardContents); - } - else - { - // empty just for Gradle not to complain - GradleProperties.AppendLine("STORE_FILE="); - GradleProperties.AppendLine("STORE_PASSWORD="); - GradleProperties.AppendLine("KEY_ALIAS="); - GradleProperties.AppendLine("KEY_PASSWORD="); - - // empty just for Gradle not to complain - GradleBuildAdditionsContent.AppendLine("\tsigningConfigs {"); - GradleBuildAdditionsContent.AppendLine("\t\trelease {"); - GradleBuildAdditionsContent.AppendLine("\t\t}"); - GradleBuildAdditionsContent.AppendLine("\t}"); - } - - GradleBuildAdditionsContent.AppendLine("\tbuildTypes {"); - GradleBuildAdditionsContent.AppendLine("\t\trelease {"); - GradleBuildAdditionsContent.AppendLine("\t\t\tsigningConfig signingConfigs.release"); - if (GradlePropertiesUPL.Contains("DISABLE_MINIFY=1")) - { - GradleBuildAdditionsContent.AppendLine("\t\t\tminifyEnabled false"); - } - else - { - GradleBuildAdditionsContent.AppendLine("\t\t\tminifyEnabled true"); - } - if (GradlePropertiesUPL.Contains("DISABLE_PROGUARD=1")) - { - GradleBuildAdditionsContent.AppendLine("\t\t\tuseProguard false"); - } - else - { - GradleBuildAdditionsContent.AppendLine("\t\t\tproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'"); - } - GradleBuildAdditionsContent.AppendLine("\t\t}"); - GradleBuildAdditionsContent.AppendLine("\t\tdebug {"); - GradleBuildAdditionsContent.AppendLine("\t\t\tdebuggable true"); - GradleBuildAdditionsContent.AppendLine("\t\t}"); - GradleBuildAdditionsContent.AppendLine("\t}"); - GradleBuildAdditionsContent.AppendLine("}"); - - // Add any UPL app buildGradleAdditions - GradleBuildAdditionsContent.Append(UPL.ProcessPluginNode(NDKArch, "buildGradleAdditions", "")); - - string GradleBuildAdditionsFilename = Path.Combine(UE4BuildGradleAppPath, "buildAdditions.gradle"); - File.WriteAllText(GradleBuildAdditionsFilename, GradleBuildAdditionsContent.ToString()); - - string GradlePropertiesFilename = Path.Combine(UE4BuildGradlePath, "gradle.properties"); - File.WriteAllText(GradlePropertiesFilename, GradleProperties.ToString()); - - // Add lint if requested (note depreciation warnings can be suppressed with @SuppressWarnings("deprecation") - string GradleBaseBuildAdditionsContents = ""; - bool bEnableLint = false; - Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bEnableLint", out bEnableLint); - if (bEnableLint) - { - GradleBaseBuildAdditionsContents = - "allprojects {\n" + - "\ttasks.withType(JavaCompile) {\n" + - "\t\toptions.compilerArgs << \"-Xlint:unchecked\" << \"-Xlint:deprecation\"\n" + - "\t}\n" + - "}\n\n"; - } - - // Create baseBuildAdditions.gradle from plugins baseBuildGradleAdditions - string GradleBaseBuildAdditionsFilename = Path.Combine(UE4BuildGradlePath, "baseBuildAdditions.gradle"); - File.WriteAllText(GradleBaseBuildAdditionsFilename, UPL.ProcessPluginNode(NDKArch, "baseBuildGradleAdditions", GradleBaseBuildAdditionsContents)); - - // Create buildscriptAdditions.gradle from plugins buildscriptGradleAdditions - string GradleBuildScriptAdditionsFilename = Path.Combine(UE4BuildGradlePath, "buildscriptAdditions.gradle"); - File.WriteAllText(GradleBuildScriptAdditionsFilename, UPL.ProcessPluginNode(NDKArch, "buildscriptGradleAdditions", "")); - - string GradleScriptPath = Path.Combine(UE4BuildGradlePath, "gradlew"); - if (Utils.IsRunningOnMono) - { - // fix permissions for Mac/Linux - RunCommandLineProgramWithException(UE4BuildGradlePath, "/bin/sh", string.Format("-c 'chmod 0755 \"{0}\"'", GradleScriptPath.Replace("'", "'\"'\"'")), "Fix gradlew permissions"); - } - else - { - if (CreateRunGradle(UE4BuildGradlePath)) - { - GradleScriptPath = Path.Combine(UE4BuildGradlePath, "rungradle.bat"); + // fix permissions for Mac/Linux + RunCommandLineProgramWithException(UE4BuildGradlePath, "/bin/sh", string.Format("-c 'chmod 0755 \"{0}\"'", GradleScriptPath.Replace("'", "'\"'\"'")), "Fix gradlew permissions"); } else { - GradleScriptPath = Path.Combine(UE4BuildGradlePath, "gradlew.bat"); + if (CreateRunGradle(UE4BuildGradlePath)) + { + GradleScriptPath = Path.Combine(UE4BuildGradlePath, "rungradle.bat"); + } + else + { + GradleScriptPath = Path.Combine(UE4BuildGradlePath, "gradlew.bat"); + } } - } - string GradleBuildType = bForDistribution ? ":app:assembleRelease" : ":app:assembleDebug"; + string GradleBuildType = bForDistribution ? ":app:assembleRelease" : ":app:assembleDebug"; - // collect optional additional Gradle parameters from plugins - string GradleOptions = UPL.ProcessPluginNode(NDKArch, "gradleParameters", GradleBuildType); // "--stacktrace --debug " + GradleBuildType); + // collect optional additional Gradle parameters from plugins + string GradleOptions = UPL.ProcessPluginNode(NDKArch, "gradleParameters", GradleBuildType); // "--stacktrace --debug " + GradleBuildType); - // check for Android Studio project, call Gradle if doesn't exist (assume user will build with Android Studio) - string GradleAppImlFilename = Path.Combine(UE4BuildGradlePath, "app.iml"); - if (!File.Exists(GradleAppImlFilename)) - { - // make sure destination exists - Directory.CreateDirectory(Path.GetDirectoryName(DestApkName)); - - // Use gradle to build the .apk file - string ShellExecutable = BuildHostPlatform.Current.Shell.FullName; - string ShellParametersBegin = (BuildHostPlatform.Current.ShellType == ShellType.Sh) ? "-c '" : "/c "; - string ShellParametersEnd = (BuildHostPlatform.Current.ShellType == ShellType.Sh) ? "'" : ""; - RunCommandLineProgramWithExceptionAndFiltering(UE4BuildGradlePath, ShellExecutable, ShellParametersBegin + "\"" + GradleScriptPath + "\" " + GradleOptions + ShellParametersEnd, "Making .apk with Gradle..."); - - // For build machine run a clean afterward to clean up intermediate files (does not remove final APK) - if (bIsBuildMachine) + // check for Android Studio project, call Gradle if doesn't exist (assume user will build with Android Studio) + string GradleAppImlFilename = Path.Combine(UE4BuildGradlePath, "app.iml"); + if (!File.Exists(GradleAppImlFilename)) { - //GradleOptions = "tasks --all"; - //RunCommandLineProgramWithException(UE4BuildGradlePath, ShellExecutable, ShellParametersBegin + "\"" + GradleScriptPath + "\" " + GradleOptions + ShellParametersEnd, "Listing all tasks..."); + // make sure destination exists + Directory.CreateDirectory(Path.GetDirectoryName(DestApkName)); - GradleOptions = "clean"; - RunCommandLineProgramWithException(UE4BuildGradlePath, ShellExecutable, ShellParametersBegin + "\"" + GradleScriptPath + "\" " + GradleOptions + ShellParametersEnd, "Cleaning Gradle intermediates..."); + // Use gradle to build the .apk file + string ShellExecutable = Utils.IsRunningOnMono ? "/bin/sh" : "cmd.exe"; + string ShellParametersBegin = Utils.IsRunningOnMono ? "-c '" : "/c "; + string ShellParametersEnd = Utils.IsRunningOnMono ? "'" : ""; + RunCommandLineProgramWithExceptionAndFiltering(UE4BuildGradlePath, ShellExecutable, ShellParametersBegin + "\"" + GradleScriptPath + "\" " + GradleOptions + ShellParametersEnd, "Making .apk with Gradle..."); + + // For build machine run a clean afterward to clean up intermediate files (does not remove final APK) + if (bIsBuildMachine) + { + //GradleOptions = "tasks --all"; + //RunCommandLineProgramWithException(UE4BuildGradlePath, ShellExecutable, ShellParametersBegin + "\"" + GradleScriptPath + "\" " + GradleOptions + ShellParametersEnd, "Listing all tasks..."); + + GradleOptions = "clean"; + RunCommandLineProgramWithException(UE4BuildGradlePath, ShellExecutable, ShellParametersBegin + "\"" + GradleScriptPath + "\" " + GradleOptions + ShellParametersEnd, "Cleaning Gradle intermediates..."); + } + } + else + { + Log.TraceInformation("============================================================================================="); + Log.TraceInformation("Android Studio project found, skipping Gradle; complete creation of APK in Android Studio!!!!"); + Log.TraceInformation("Delete '{0} if you want to have UnrealBuildTool run Gradle for future runs.", GradleAppImlFilename); + Log.TraceInformation("============================================================================================="); } } - else + + bool bBuildWithHiddenSymbolVisibility = false; + bool bSaveSymbols = false; + Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildWithHiddenSymbolVisibility", out bBuildWithHiddenSymbolVisibility); + Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bSaveSymbols", out bSaveSymbols); +bSaveSymbols = true; + if (bSaveSymbols || (Configuration == UnrealTargetConfiguration.Shipping && bBuildWithHiddenSymbolVisibility)) { - Log.TraceInformation("============================================================================================="); - Log.TraceInformation("Android Studio project found, skipping Gradle; complete creation of APK in Android Studio!!!!"); - Log.TraceInformation("Delete '{0} if you want to have UnrealBuildTool run Gradle for future runs.", GradleAppImlFilename); - Log.TraceInformation("============================================================================================="); + // Copy .so with symbols to + int StoreVersion = GetStoreVersion(); + string SymbolSODirectory = Path.Combine(DestApkDirectory, ProjectName + "_Symbols_v" + StoreVersion + "/" + ProjectName + Arch + GPUArchitecture); + string SymbolifiedSOPath = Path.Combine(SymbolSODirectory, Path.GetFileName(FinalSOName)); + MakeDirectoryIfRequired(SymbolifiedSOPath); + + File.Copy(FinalSOName, SymbolifiedSOPath, true); } } - - bool bBuildWithHiddenSymbolVisibility = false; - bool bSaveSymbols = false; - Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bBuildWithHiddenSymbolVisibility", out bBuildWithHiddenSymbolVisibility); - Ini.GetBool("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "bSaveSymbols", out bSaveSymbols); - if (bSaveSymbols || (Configuration == "Shipping" && bBuildWithHiddenSymbolVisibility)) - { - // Copy .so with symbols to - int StoreVersion = GetStoreVersion(); - string SymbolSODirectory = Path.Combine(Path.GetDirectoryName(DestApkName), ProjectName + "_Symbols_v" + StoreVersion + "/" + ProjectName + Arch + GPUArchitecture); - string SymbolifiedSOPath = Path.Combine(SymbolSODirectory, Path.GetFileName(FinalSOName)); - MakeDirectoryIfRequired(SymbolifiedSOPath); - - File.Copy(FinalSOName, SymbolifiedSOPath, true); - } } - } private void PrepareToSignApk(string BuildPath) @@ -4029,6 +4017,11 @@ namespace UnrealBuildTool public override bool PrepTargetForDeployment(TargetReceipt Receipt) { + DirectoryReference ProjectDirectory = DirectoryReference.FromFile(Receipt.ProjectFile) ?? UnrealBuildTool.EngineDirectory; + string TargetName = (Receipt.ProjectFile == null ? Receipt.TargetName : Receipt.ProjectFile.GetFileNameWithoutAnyExtensions()); + + SavePackageInfo(TargetName, ProjectDirectory.FullName, Receipt.TargetType); + AndroidToolChain ToolChain = ((AndroidPlatform)UEBuildPlatform.GetBuildPlatform(Receipt.Platform)).CreateTempToolChainForProject(Receipt.ProjectFile) as AndroidToolChain; // get the receipt @@ -4040,12 +4033,13 @@ namespace UnrealBuildTool // we need to strip architecture from any of the output paths string BaseSoName = ToolChain.RemoveArchName(OutputPaths[0].FullName); + bool bShouldCompileAsDll = Receipt.HasValueForAdditionalProperty("CompileAsDll", "true"); + // make an apk at the end of compiling, so that we can run without packaging (debugger, cook on the fly, etc) string RelativeEnginePath = UnrealBuildTool.EngineDirectory.MakeRelativeTo(DirectoryReference.GetCurrentDirectory()); - string TargetName = (Receipt.ProjectFile == null ? Receipt.TargetName : Receipt.ProjectFile.GetFileNameWithoutAnyExtensions()); - DirectoryReference ProjectDirectory = DirectoryReference.FromFile(Receipt.ProjectFile) ?? UnrealBuildTool.EngineDirectory; - MakeApk(ToolChain, TargetName, Receipt.TargetType, ProjectDirectory.FullName, BaseSoName, RelativeEnginePath, bForDistribution: false, CookFlavor: "", - bMakeSeparateApks: ShouldMakeSeparateApks(), bIncrementalPackage: true, bDisallowPackagingDataInApk: false, bDisallowExternalFilesDir: true); + + MakeApk(ToolChain, TargetName, Receipt.TargetType, ProjectDirectory.FullName, BaseSoName, RelativeEnginePath, bForDistribution: false, CookFlavor: "", Configuration: Receipt.Configuration, + bMakeSeparateApks: ShouldMakeSeparateApks(), bIncrementalPackage: true, bDisallowPackagingDataInApk: false, bDisallowExternalFilesDir: true, bSkipGradleBuild: bShouldCompileAsDll); // if we made any non-standard .apk files, the generated debugger settings may be wrong if (ShouldMakeSeparateApks() && (OutputPaths.Count > 1 || !OutputPaths[0].FullName.Contains("-armv7-es2"))) @@ -4057,6 +4051,25 @@ namespace UnrealBuildTool return true; } + // Store generated package name in a text file for builds that do not generate an apk file + public bool SavePackageInfo(string TargetName, string ProjectDirectory, TargetType InTargetType) + { + string PackageName = GetPackageName(TargetName); + string DestPackageNameFileName = Path.Combine(ProjectDirectory, "Binaries", "Android", "packageInfo.txt"); + + string[] PackageInfoSource = new string[4]; + PackageInfoSource[0] = PackageName; + PackageInfoSource[1] = GetStoreVersion().ToString(); + PackageInfoSource[2] = GetVersionDisplayName(); + PackageInfoSource[3] = string.Format("name='com.epicgames.ue4.GameActivity.AppType' value='{0}'", InTargetType == TargetType.Game ? "" : InTargetType.ToString()); + + Log.TraceInformation("Writing packageInfo pkgName:{0} storeVersion:{1} versionDisplayName:{2} to {3}", PackageInfoSource[0], PackageInfoSource[1], PackageInfoSource[2], DestPackageNameFileName); + + File.WriteAllLines(DestPackageNameFileName, PackageInfoSource); + + return true; + } + public static bool ShouldMakeSeparateApks() { // @todo android fat binary: Currently, there isn't much utility in merging multiple .so's into a single .apk except for debugging, @@ -4073,7 +4086,7 @@ namespace UnrealBuildTool // return bSeparateApks; } - public bool PrepForUATPackageOrDeploy(FileReference ProjectFile, string ProjectName, DirectoryReference ProjectDirectory, string ExecutablePath, string EngineDirectory, bool bForDistribution, string CookFlavor, bool bIsDataDeploy) + public bool PrepForUATPackageOrDeploy(FileReference ProjectFile, string ProjectName, DirectoryReference ProjectDirectory, string ExecutablePath, string EngineDirectory, bool bForDistribution, string CookFlavor, UnrealTargetConfiguration Configuration, bool bIsDataDeploy, bool bSkipGradleBuild) { //Log.TraceInformation("$$$$$$$$$$$$$$ PrepForUATPackageOrDeploy $$$$$$$$$$$$$$$$$"); @@ -4090,8 +4103,11 @@ namespace UnrealBuildTool // note that we cannot allow the data packaged into the APK if we are doing something like Launch On that will not make an obb // file and instead pushes files directly via deploy AndroidToolChain ToolChain = new AndroidToolChain(ProjectFile, false, null, null); - MakeApk(ToolChain, ProjectName, Type, ProjectDirectory.FullName, ExecutablePath, EngineDirectory, bForDistribution: bForDistribution, CookFlavor: CookFlavor, - bMakeSeparateApks: ShouldMakeSeparateApks(), bIncrementalPackage: false, bDisallowPackagingDataInApk: bIsDataDeploy, bDisallowExternalFilesDir: !bForDistribution || bIsDataDeploy ); + + SavePackageInfo(ProjectName, ProjectDirectory.FullName, Type); + + MakeApk(ToolChain, ProjectName, Type, ProjectDirectory.FullName, ExecutablePath, EngineDirectory, bForDistribution: bForDistribution, CookFlavor: CookFlavor, Configuration: Configuration, + bMakeSeparateApks: ShouldMakeSeparateApks(), bIncrementalPackage: false, bDisallowPackagingDataInApk: bIsDataDeploy, bDisallowExternalFilesDir: !bForDistribution || bIsDataDeploy, bSkipGradleBuild:bSkipGradleBuild); return true; } @@ -4151,10 +4167,17 @@ namespace UnrealBuildTool // check for GameActivity.java.template override SourceFilename = UPL.ProcessPluginNode(NDKArch, "gameActivityReplacement", SourceFilename); + ConfigHierarchy Ini = GetConfigCacheIni(ConfigHierarchyType.Engine); + string LoadLibraryDefaults = ""; + string SuperClassDefault; + if (!Ini.GetString("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "GameActivitySuperClass", out SuperClassDefault)) + { + SuperClassDefault = "NativeActivity"; + } + string AndroidGraphicsDebugger; - ConfigHierarchy Ini = GetConfigCacheIni(ConfigHierarchyType.Engine); Ini.GetString("/Script/AndroidRuntimeSettings.AndroidRuntimeSettings", "AndroidGraphicsDebugger", out AndroidGraphicsDebugger); switch (AndroidGraphicsDebugger.ToLower()) @@ -4188,7 +4211,8 @@ namespace UnrealBuildTool { "//$${gameActivityPostConfigRulesAdditions}$$", UPL.ProcessPluginNode(NDKArch, "gameActivityPostConfigRulesAdditions", "")}, { "//$${gameActivityBeforeConfigRulesAppliedAdditions}$$", UPL.ProcessPluginNode(NDKArch, "gameActivityBeforeConfigRulesAppliedAdditions", "")}, { "//$${gameActivityLoggerCallbackAdditions}$$", UPL.ProcessPluginNode(NDKArch, "gameActivityLoggerCallbackAdditions", "")}, - { "//$${soLoadLibrary}$$", UPL.ProcessPluginNode(NDKArch, "soLoadLibrary", LoadLibraryDefaults)} + { "//$${soLoadLibrary}$$", UPL.ProcessPluginNode(NDKArch, "soLoadLibrary", LoadLibraryDefaults)}, + { "$${gameActivitySuperClass}$$", UPL.ProcessPluginNode(NDKArch, "gameActivitySuperClass", SuperClassDefault)}, }; string[] TemplateSrc = File.ReadAllLines(SourceFilename); @@ -4222,7 +4246,7 @@ namespace UnrealBuildTool if (TemplateDest == null || TemplateSrc.Length != TemplateDest.Length || !TemplateSrc.SequenceEqual(TemplateDest)) { - Log.TraceInformation("\n==== Writing new GameActivity.java file to {0} ====", DestFilename); + Log.TraceInformation("\n==== Writing new GameActivity.java file to {0} ====", DestFilename); File.WriteAllLines(DestFilename, TemplateSrc); } } @@ -4379,12 +4403,9 @@ namespace UnrealBuildTool BuildGradleContent.AppendLine("apply plugin: 'com.android.library'"); BuildGradleContent.AppendLine("android {"); BuildGradleContent.AppendLine(string.Format("\tcompileSdkVersion {0}", CompileSDKVersion)); - BuildGradleContent.AppendLine(string.Format("\tbuildToolsVersion \"{0}\"", BuildToolsVersion)); BuildGradleContent.AppendLine("\tdefaultConfig {"); // Try to get the SDK target from the AndroidManifest.xml - string MinSDK = "9"; - string TargetSDK = "9"; string VersionCode = ""; string VersionName = ""; string ManifestFilename = Path.Combine(LibDir, "AndroidManifest.xml"); @@ -4406,22 +4427,6 @@ namespace UnrealBuildTool { VersionName = VersionNameAttr.Value; } - - XElement UsesSdk = ManifestXML.Root.Element(XName.Get("uses-sdk", ManifestXML.Root.Name.NamespaceName)); - if (UsesSdk != null) - { - XAttribute MinSDKAttr = UsesSdk.Attribute(XName.Get("minSdkVersion", "http://schemas.android.com/apk/res/android")); - if (MinSDKAttr != null) - { - MinSDK = MinSDKAttr.Value; - } - - XAttribute TargetSDKAttr = UsesSdk.Attribute(XName.Get("targetSdkVersion", "http://schemas.android.com/apk/res/android")); - if (TargetSDKAttr != null) - { - TargetSDK = TargetSDKAttr.Value; - } - } } catch (Exception e) { @@ -4429,8 +4434,6 @@ namespace UnrealBuildTool } } - BuildGradleContent.AppendLine(string.Format("\t\tminSdkVersion {0}", MinSDK)); - BuildGradleContent.AppendLine(string.Format("\t\ttargetSdkVersion {0}", TargetSDK)); if (VersionCode != "") { BuildGradleContent.AppendLine(string.Format("\t\tversionCode {0}", VersionCode)); @@ -4506,5 +4509,5 @@ namespace UnrealBuildTool } File.WriteAllText(AARExtractListFilename, AARListContents.ToString()); } - } + } } diff --git a/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/IOSToolChain.cs b/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/IOSToolChain.cs index 307685bf4de4..80c0472dc2e6 100644 --- a/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/IOSToolChain.cs +++ b/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/IOSToolChain.cs @@ -320,7 +320,14 @@ namespace UnrealBuildTool { if(Framework.OutputDirectory != null) { - Result += String.Format(" -F\"{0}\"", Framework.OutputDirectory); + string FrameworkDir = Framework.OutputDirectory.FullName; + // embedded frameworks have a framework inside of this directory, so we use this directory. regular frameworks need to go one up to point to the + // directory containing the framework. -F gives a path to look for the -framework + if (FrameworkDir.Contains("embeddedframework") == false) + { + FrameworkDir = Path.GetDirectoryName(FrameworkDir); + } + Result += String.Format(" -F\"{0}\"", FrameworkDir); } } @@ -519,6 +526,9 @@ namespace UnrealBuildTool Result += " -fsanitize=undefined"; } + // need to tell where to load Framework dylibs + Result += " -rpath @executable_path/Frameworks"; + Result += " " + GetAdditionalLinkerFlags(LinkEnvironment.Configuration); // link in the frameworks @@ -534,7 +544,15 @@ namespace UnrealBuildTool if(Framework.OutputDirectory != null) { // If this framework has a zip specified, we'll need to setup the path as well - Result += String.Format(" -F\"{0}\"", Framework.OutputDirectory); + string FrameworkDir = Framework.OutputDirectory.FullName; + + // embedded frameworks have a framework inside of this directory, so we use this directory. regular frameworks need to go one up to point to the + // directory containing the framework. -F gives a path to look for the -framework + if (FrameworkDir.Contains("embeddedframework") == false) + { + FrameworkDir = Path.GetDirectoryName(FrameworkDir); + } + Result += String.Format(" -F\"{0}\"", FrameworkDir); } Result += " -framework " + Framework.Name; @@ -745,6 +763,18 @@ namespace UnrealBuildTool // build this up over the rest of the function string LinkCommandArguments = LinkEnvironment.bIsBuildingLibrary ? GetArchiveArguments_Global(LinkEnvironment) : GetLinkArguments_Global(LinkEnvironment); + if (LinkEnvironment.bIsBuildingDLL) + { + // @todo roll this put into GetLinkArguments_Global + LinkerPath = IOSLinker; + LinkCommandArguments += " -dynamiclib -Xlinker -export_dynamic -Xlinker -no_deduplicate"; + + string InstallName = LinkEnvironment.InstallName ?? String.Format("@executable_path/Frameworks/{0}", LinkEnvironment.OutputFilePath.MakeRelativeTo(LinkEnvironment.OutputFilePath.Directory.ParentDirectory)); + LinkCommandArguments += string.Format(" -Xlinker -install_name -Xlinker {0}", InstallName); + + LinkCommandArguments += " -Xlinker -rpath -Xlinker @executable_path/Frameworks"; + LinkCommandArguments += " -Xlinker -rpath -Xlinker @loader_path/Frameworks"; + } if (!LinkEnvironment.bIsBuildingLibrary) { @@ -789,7 +819,7 @@ namespace UnrealBuildTool LinkAction.ProducedItems.Add(OutputFile); // Add arguments to generate a map file too - if (!LinkEnvironment.bIsBuildingLibrary && LinkEnvironment.bCreateMapFile) + if ((!LinkEnvironment.bIsBuildingLibrary || LinkEnvironment.bIsBuildingDLL) && LinkEnvironment.bCreateMapFile) { FileItem MapFile = FileItem.GetItemByFileReference(new FileReference(OutputFile.Location.FullName + ".map")); LinkCommandArguments += string.Format(" -Wl,-map,\"{0}\"", MapFile.Location.FullName); @@ -923,6 +953,25 @@ namespace UnrealBuildTool return Arguments.ToString(); } + private static bool IsCompiledAsFramework(string ExecutablePath) + { + // @todo ios: Get the receipt to here which has the property + return ExecutablePath.Contains(".framework"); + } + + private static string GetdSYMPath(FileItem Executable) + { + string ExecutablePath = Executable.AbsolutePath; + // for frameworks, we want to put the .dSYM outside of the framework, and the executable is inside the .framework + if (IsCompiledAsFramework(ExecutablePath)) + { + return Path.Combine(Path.GetDirectoryName(ExecutablePath), "..", Path.GetFileName(ExecutablePath) + ".dSYM"); + } + + // return standard dSYM location + return Path.Combine(Path.GetDirectoryName(ExecutablePath), Path.GetFileName(ExecutablePath) + ".dSYM"); + } + /// /// Generates debug info for a given executable /// @@ -931,7 +980,7 @@ namespace UnrealBuildTool public FileItem GenerateDebugInfo(FileItem Executable, List Actions) { // Make a file item for the source and destination files - string FullDestPathRoot = Path.Combine(Path.GetDirectoryName(Executable.AbsolutePath), Path.GetFileName(Executable.AbsolutePath) + ".dSYM"); + string FullDestPathRoot = GetdSYMPath(Executable); FileItem OutputFile = FileItem.GetItemByPath(FullDestPathRoot); FileItem ZipOutputFile = FileItem.GetItemByPath(FullDestPathRoot + ".zip"); @@ -976,8 +1025,8 @@ namespace UnrealBuildTool public FileItem GeneratePseudoPDB(FileItem Executable, List Actions) { // Make a file item for the source and destination files - string FullDestPathRoot = Path.Combine(Path.GetDirectoryName(Executable.AbsolutePath), Path.GetFileName(Executable.AbsolutePath) + ".udebugsymbols"); - string FulldSYMPathRoot = Path.Combine(Path.GetDirectoryName(Executable.AbsolutePath), Path.GetFileName(Executable.AbsolutePath) + ".dSYM"); + string FulldSYMPathRoot = GetdSYMPath(Executable); + string FullDestPathRoot = Path.ChangeExtension(FulldSYMPathRoot, ".udebugsymbols"); string PathToDWARF = Path.Combine(FulldSYMPathRoot, "Contents", "Resources", "DWARF", Path.GetFileName(Executable.AbsolutePath)); FileItem dSYMFile = FileItem.GetItemByPath(FulldSYMPathRoot); @@ -1304,7 +1353,7 @@ namespace UnrealBuildTool { List OutputFiles = new List(base.PostBuild(Executable, BinaryLinkEnvironment, Actions)); - if (BinaryLinkEnvironment.bIsBuildingLibrary) + if (BinaryLinkEnvironment.bIsBuildingLibrary) { return OutputFiles; } @@ -1338,7 +1387,7 @@ namespace UnrealBuildTool OutputFiles.Add(StripCompleteFile); } - if(ShouldCompileAssetCatalog()) + if(!BinaryLinkEnvironment.bIsBuildingDLL && ShouldCompileAssetCatalog()) { // generate the asset catalog bool bUserImagesExist = false; @@ -1507,7 +1556,7 @@ namespace UnrealBuildTool { ProjectFileGenerator.bGenerateProjectFiles = false; } - } + } public static FileReference GetStagedExecutablePath(FileReference Executable, string TargetName) { @@ -1515,9 +1564,27 @@ namespace UnrealBuildTool } public static void PostBuildSync(IOSPostBuildSyncTarget Target) - { + { IOSProjectSettings ProjectSettings = ((IOSPlatform)UEBuildPlatform.GetBuildPlatform(Target.Platform)).ReadProjectSettings(Target.ProjectFile); + if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) + { + if (IsCompiledAsFramework(Target.OutputPath.FullName)) + { + // make sure the framework has a plist + FileReference PlistSrcLocation = FileReference.Combine(Target.ProjectFile.Directory, "Build", "IOS", "Embedded.plist"); + if (!FileReference.Exists(PlistSrcLocation)) + { + throw new BuildException("Unable to find plist for output framework ({0})", PlistSrcLocation); + } + FileReference PlistDstLocation = FileReference.Combine(Target.OutputPath.Directory, "Info.plist"); + FileReference.Copy(PlistSrcLocation, PlistDstLocation, true); + + // and do nothing else + return; + } + } + string AppName = Target.TargetName; string RemoteShadowDirectoryMac = Target.OutputPath.Directory.FullName; diff --git a/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/UEBuildIOS.cs b/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/UEBuildIOS.cs index 34c02cc2faf5..43b69ab4959b 100644 --- a/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/UEBuildIOS.cs +++ b/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/UEBuildIOS.cs @@ -52,6 +52,11 @@ namespace UnrealBuildTool /// [CommandLine("-ImportCertificatePassword=")] public string ImportCertificatePassword = null; + + /// + /// Cached project settings for the target (set in ResetTarget) + /// + public IOSProjectSettings ProjectSettings = null; } /// @@ -110,6 +115,11 @@ namespace UnrealBuildTool get { return Inner.ImportCertificatePassword; } } + public float RuntimeVersion + { + get { return float.Parse(Inner.ProjectSettings.RuntimeVersion); } + } + #if !__MonoCS__ #pragma warning restore CS1591 #endif @@ -119,7 +129,7 @@ namespace UnrealBuildTool /// /// Stores project-specific IOS settings. Instances of this object are cached by IOSPlatform. /// - class IOSProjectSettings + public class IOSProjectSettings { /// /// The cached project file location @@ -612,7 +622,7 @@ namespace UnrealBuildTool { IOSPlatformSDK SDK; List CachedProjectSettings = new List(); - Dictionary ProvisionCache = new Dictionary(); + Dictionary ProvisionCache = new Dictionary(); // by default, use an empty architecture (which is really just a modifer to the platform for some paths/names) public static string IOSArchitecture = ""; @@ -628,12 +638,28 @@ namespace UnrealBuildTool SDK = InSDK; } - // The current architecture - affects everything about how UBT operates on IOS - public override string GetDefaultArchitecture(FileReference ProjectFile) + // The current architecture - affects everything about how UBT operates on IOS + public override string GetDefaultArchitecture(FileReference ProjectFile) { return IOSArchitecture; } + public override List FinalizeBinaryPaths(FileReference BinaryName, FileReference ProjectFile, ReadOnlyTargetRules Target) + { + List BinaryPaths = new List(); + if(Target.bShouldCompileAsDLL) + { + BinaryPaths.Add(FileReference.Combine(BinaryName.Directory, Target.Configuration.ToString(), Target.Name + ".framework", Target.Name)); + } + else + { + BinaryPaths.Add(BinaryName); + } + return BinaryPaths; + } + + + public override void ResetTarget(TargetRules Target) { // we currently don't have any simulator libs for PhysX @@ -643,9 +669,11 @@ namespace UnrealBuildTool } Target.bCompileAPEX = false; - Target.bCompileNvCloth = false; + Target.bCompileNvCloth = false; Target.bDeployAfterCompile = true; + + Target.IOSPlatform.ProjectSettings = ((IOSPlatform)GetBuildPlatform(Target.Platform)).ReadProjectSettings(Target.ProjectFile); } public override void ValidateTarget(TargetRules Target) @@ -780,6 +808,7 @@ namespace UnrealBuildTool { if (f.Contains("Icon") && Path.GetExtension(f).Contains(".png")) { + Log.TraceInformation("Requiring custom build because project {0} has custom icons", Path.GetFileName(ProjectDirectoryName.FullName)); return true; } } @@ -907,6 +936,12 @@ namespace UnrealBuildTool /// The link environment for this target public override void SetUpEnvironment(ReadOnlyTargetRules Target, CppCompileEnvironment CompileEnvironment, LinkEnvironment LinkEnvironment) { + IOSProjectSettings ProjectSettings = ((IOSPlatform)UEBuildPlatform.GetBuildPlatform(Target.Platform)).ReadProjectSettings(Target.ProjectFile); + if (!ProjectFileGenerator.bGenerateProjectFiles) + { + Log.TraceInformation("Compiling against OS Version {0} [minimum allowed at runtime]", ProjectSettings.RuntimeVersion); + } + CompileEnvironment.Definitions.Add("PLATFORM_IOS=1"); CompileEnvironment.Definitions.Add("PLATFORM_APPLE=1"); CompileEnvironment.Definitions.Add("GLES_SILENCE_DEPRECATION=1"); // suppress GLES "deprecated" warnings until a proper solution is implemented (see UE-65643) @@ -916,7 +951,6 @@ namespace UnrealBuildTool CompileEnvironment.Definitions.Add("WITH_EDITOR=0"); CompileEnvironment.Definitions.Add("USE_NULL_RHI=0"); - IOSProjectSettings ProjectSettings = ((IOSPlatform)UEBuildPlatform.GetBuildPlatform(Target.Platform)).ReadProjectSettings(Target.ProjectFile); if (ProjectSettings.bNotificationsEnabled) { CompileEnvironment.Definitions.Add("NOTIFICATIONS_ENABLED=1"); @@ -953,6 +987,8 @@ namespace UnrealBuildTool CompileEnvironment.Definitions.Add("WITH_SIMULATOR=0"); } + CompileEnvironment.Definitions.Add("HAS_OPENGL_ES=" + ((Target.IOSPlatform.RuntimeVersion < 12.0) ? "1" : "0")); + // if the project has an Oodle compression Dll, enable the decompressor on IOS if (Target.ProjectFile != null) { @@ -965,22 +1001,18 @@ namespace UnrealBuildTool } } + // convert runtime version into standardized integer + float TargetFloat = Target.IOSPlatform.RuntimeVersion; + int IntPart = (int)TargetFloat; + int FracPart = (int)((TargetFloat - IntPart) * 10); + int TargetNum = IntPart * 10000 + FracPart * 100; + CompileEnvironment.Definitions.Add("MINIMUM_UE4_COMPILED_IOS_VERSION=" + TargetNum); + LinkEnvironment.AdditionalFrameworks.Add(new UEBuildFramework("GameKit")); LinkEnvironment.AdditionalFrameworks.Add(new UEBuildFramework("StoreKit")); LinkEnvironment.AdditionalFrameworks.Add(new UEBuildFramework("DeviceCheck")); } - /// - /// Modify the rules for a newly created module, in a target that's being built for this platform. - /// This is not required - but allows for hiding details of a particular platform. - /// - /// The name of the module - /// The module rules - /// The target being build - public override void ModifyModuleRulesForActivePlatform(string ModuleName, ModuleRules Rules, ReadOnlyTargetRules Target) - { - } - /// /// Setup the binaries for this specific platform. /// @@ -1009,7 +1041,14 @@ namespace UnrealBuildTool /// Receipt for the target being deployed public override void Deploy(TargetReceipt Receipt) { - new UEDeployIOS().PrepTargetForDeployment(Receipt); + if (Receipt.HasValueForAdditionalProperty("CompileAsDll", "true")) + { + // IOSToolchain.PostBuildSync handles the copy, nothing else to do here + } + else + { + new UEDeployIOS().PrepTargetForDeployment(Receipt); + } } } diff --git a/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/UEDeployIOS.cs b/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/UEDeployIOS.cs index 442bd34d8f51..b99509d1b021 100644 --- a/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/UEDeployIOS.cs +++ b/Engine/Source/Programs/UnrealBuildTool/Platform/IOS/UEDeployIOS.cs @@ -1260,7 +1260,7 @@ namespace UnrealBuildTool } } - static void SafeFileCopy(FileInfo SourceFile, string DestinationPath, bool bOverwrite) + public static void SafeFileCopy(FileInfo SourceFile, string DestinationPath, bool bOverwrite) { FileInfo DI = new FileInfo(DestinationPath); if (DI.Exists && bOverwrite) diff --git a/Engine/Source/Programs/UnrealBuildTool/Platform/Mac/MacToolChain.cs b/Engine/Source/Programs/UnrealBuildTool/Platform/Mac/MacToolChain.cs index 1d7a9abce14f..c42b304b0ff1 100644 --- a/Engine/Source/Programs/UnrealBuildTool/Platform/Mac/MacToolChain.cs +++ b/Engine/Source/Programs/UnrealBuildTool/Platform/Mac/MacToolChain.cs @@ -792,7 +792,13 @@ namespace UnrealBuildTool if (LinkEnvironment.bIsBuildingDLL) { - LinkCommand += string.Format(" -install_name {0}/{1}", DylibsPath, Path.GetFileName(OutputFile.AbsolutePath)); + // Add the output file to the command-line. + string InstallName = LinkEnvironment.InstallName; + if(InstallName == null) + { + InstallName = string.Format("{0}/{1}", DylibsPath, Path.GetFileName(OutputFile.AbsolutePath)); + } + LinkCommand += string.Format(" -install_name {0}", InstallName); } if (!bIsBuildingLibrary) diff --git a/Engine/Source/Programs/UnrealBuildTool/ProjectFiles/VisualStudioCode/VSCodeProjectFileGenerator.cs b/Engine/Source/Programs/UnrealBuildTool/ProjectFiles/VisualStudioCode/VSCodeProjectFileGenerator.cs index bc9fd2db94e9..49dee8797971 100644 --- a/Engine/Source/Programs/UnrealBuildTool/ProjectFiles/VisualStudioCode/VSCodeProjectFileGenerator.cs +++ b/Engine/Source/Programs/UnrealBuildTool/ProjectFiles/VisualStudioCode/VSCodeProjectFileGenerator.cs @@ -1198,6 +1198,10 @@ namespace UnrealBuildTool { DirectoryReference ProjDir = Target.TargetFilePath.Directory.GetDirectoryName() == "Source" ? Target.TargetFilePath.Directory.ParentDirectory : Target.TargetFilePath.Directory; GetExcludePathsCPP(ProjDir, PathsToExclude); + + DirectoryReference PluginRootDir = DirectoryReference.Combine(ProjDir, "Plugins"); + WriteWorkspaceSettingsFileForPlugins(PluginRootDir, PathsToExclude); + bFoundTarget = true; } } @@ -1225,6 +1229,26 @@ namespace UnrealBuildTool OutFile.Write(FileReference.Combine(VSCodeDir, "settings.json")); } + private void WriteWorkspaceSettingsFileForPlugins(DirectoryReference PluginBaseDir, List PathsToExclude) + { + if (DirectoryReference.Exists(PluginBaseDir)) + { + foreach (DirectoryReference SubDir in DirectoryReference.EnumerateDirectories(PluginBaseDir, "*", SearchOption.TopDirectoryOnly)) + { + string[] UPluginFiles = Directory.GetFiles(SubDir.ToString(), "*.uplugin"); + if (UPluginFiles.Length == 1) + { + DirectoryReference PluginDir = SubDir; + GetExcludePathsCPP(PluginDir, PathsToExclude); + } + else + { + WriteWorkspaceSettingsFileForPlugins(SubDir, PathsToExclude); + } + } + } + } + private void WriteWorkspaceFile(ProjectData ProjectData) { JsonFile WorkspaceFile = new JsonFile(); diff --git a/Engine/Source/Programs/UnrealBuildTool/ProjectFiles/Xcode/XcodeProject.cs b/Engine/Source/Programs/UnrealBuildTool/ProjectFiles/Xcode/XcodeProject.cs index 7b5c0738d53b..3b034a9abaf9 100644 --- a/Engine/Source/Programs/UnrealBuildTool/ProjectFiles/Xcode/XcodeProject.cs +++ b/Engine/Source/Programs/UnrealBuildTool/ProjectFiles/Xcode/XcodeProject.cs @@ -57,7 +57,7 @@ namespace UnrealBuildTool /// class XcodeFileGroup { - public XcodeFileGroup(string InName, string InPath, bool InIsReference = false) + public XcodeFileGroup(string InName, string InPath, bool InIsReference) { GroupName = InName; GroupPath = InPath; @@ -73,6 +73,55 @@ namespace UnrealBuildTool public bool bIsReference; } + class XcodeBuildConfig + { + public XcodeBuildConfig(string InDisplayName, string InBuildTarget, FileReference InMacExecutablePath, FileReference InIOSExecutablePath, FileReference InTVOSExecutablePath, + ProjectTarget InProjectTarget, UnrealTargetConfiguration InBuildConfig) + { + DisplayName = InDisplayName; + MacExecutablePath = InMacExecutablePath; + IOSExecutablePath = InIOSExecutablePath; + TVOSExecutablePath = InTVOSExecutablePath; + BuildTarget = InBuildTarget; + ProjectTarget = InProjectTarget; + BuildConfig = InBuildConfig; + } + + public string DisplayName; + public FileReference MacExecutablePath; + public FileReference IOSExecutablePath; + public FileReference TVOSExecutablePath; + public string BuildTarget; + public ProjectTarget ProjectTarget; + public UnrealTargetConfiguration BuildConfig; + }; + + class XcodeExtensionInfo + { + public XcodeExtensionInfo(string InName) + { + Name = InName; + TargetDependencyGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); + TargetProxyGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); + TargetGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); + ProductGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); + ResourceBuildPhaseGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); + ConfigListGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); + AllConfigs = new Dictionary(); + } + + public string Name; + public string TargetDependencyGuid; + public string TargetProxyGuid; + public string TargetGuid; + public string ProductGuid; + public string ResourceBuildPhaseGuid; + public string ConfigListGuid; + public Dictionary AllConfigs; + + public string ConfigurationContents; + } + class XcodeProjectFile : ProjectFile { FileReference OnlyGameProject; @@ -197,7 +246,7 @@ namespace UnrealBuildTool XcodeFileGroup CurrentGroup; if (!CurrentSubGroups.ContainsKey(CurrentPath)) { - CurrentGroup = new XcodeFileGroup(Path.GetFileName(CurrentPath), CurrentPath); + CurrentGroup = new XcodeFileGroup(Path.GetFileName(CurrentPath), CurrentPath, CurrentPath.EndsWith(".xcassets")); CurrentSubGroups.Add(CurrentPath, CurrentGroup); } else @@ -286,6 +335,185 @@ namespace UnrealBuildTool PBXFileReferenceSection.Append(string.Format("\t\t{0} /* {1} */ = {{isa = PBXFileReference; explicitFileType = wrapper.application; path = {1}; sourceTree = BUILT_PRODUCTS_DIR; }};" + ProjectFileGenerator.NewLine, TargetAppGuid, TargetName)); } + + private void GenerateSectionsWithFrameworks(StringBuilder PBXBuildFileSection, StringBuilder PBXFileReferenceSection, StringBuilder PBXCopyFilesBuildPhaseSection, FileReference UProjectPath) + { + if (UProjectPath != null) + { + // @todo: look also in Project/Build/Frameworks directory! + + ProjectDescriptor Project = ProjectDescriptor.FromFile(UProjectPath); + List AvailablePlugins = Plugins.ReadAvailablePlugins(UnrealBuildTool.EngineDirectory, UProjectPath, Project.AdditionalPluginDirectories); + + // look in each plugin for frameworks + // @todo: Cache this kind of things since every target will re-do this work! + foreach (PluginInfo PI in AvailablePlugins) + { + if (!Plugins.IsPluginEnabledForProject(PI, Project, UnrealTargetPlatform.IOS, UnrealTargetConfiguration.Development, TargetRules.TargetType.Game)) + { + continue; + } + + // for now, we copy and code sign all frameworks, even if the have no code + DirectoryReference FrameworkDir = DirectoryReference.Combine(PI.Directory, "Source/Frameworks"); + if (!DirectoryReference.Exists(FrameworkDir)) + { + FrameworkDir = DirectoryReference.Combine(PI.Directory, "Frameworks"); + } + if (DirectoryReference.Exists(FrameworkDir)) + { + // look at each zip + foreach (FileInfo FI in new System.IO.DirectoryInfo(FrameworkDir.FullName).EnumerateFiles("*.zip")) + { + string Guid = XcodeProjectFileGenerator.MakeXcodeGuid(); + string RefGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); + + // for FI of foo.framework.zip, this will give us foo.framework + string Framework = Path.GetFileNameWithoutExtension(FI.FullName); + + // hunt down in subdirectories for + string FrameworkPath = Path.Combine("../../../Engine/Intermediate/UnzippedFrameworks", PI.Name, "Frameworks", Framework); + + Console.WriteLine(" Plugin {0} has framework {1}, reading from intermediate location {2}!", PI.Name, FI, FrameworkPath); + + PBXBuildFileSection.Append(string.Format("\t\t{0} /* {1} in Embed Frameworks */ = {{isa = PBXBuildFile; fileRef = {2} /* {1} */; settings = {{ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }}; }};" + ProjectFileGenerator.NewLine, + Guid, + Framework, + RefGuid)); + + PBXFileReferenceSection.Append(string.Format("\t\t{0} /* {1} */ = {{isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = \"{1}\"; path = \"{2}\"; sourceTree = SOURCE_ROOT; }};" + ProjectFileGenerator.NewLine, + RefGuid, + Framework, + FrameworkPath)); + + PBXCopyFilesBuildPhaseSection.Append("\t\t\t\t" + Guid + " /* " + Framework + " in Embed Frameworks */," + ProjectFileGenerator.NewLine); + } + } + } + } + } + + private void GenerateSectionsWithExtensions(StringBuilder PBXBuildFileSection, StringBuilder PBXFileReferenceSection, StringBuilder PBXCopyFilesBuildPhaseSection, StringBuilder PBXResourcesBuildPhaseSection, + List AllExtensions, FileReference UProjectPath, List BuildConfigs) + { + if (UProjectPath != null) + { + string ProjectExtensionsDir = Path.Combine(Path.GetDirectoryName(UProjectPath.FullName), "Build/IOS/Extensions"); + string ProjectIntermediateDir = Path.Combine(Path.GetDirectoryName(UProjectPath.FullName), "Intermediate/IOS/Extensions"); + + if (Directory.Exists(ProjectExtensionsDir)) + { + foreach (DirectoryInfo DI in new System.IO.DirectoryInfo(ProjectExtensionsDir).EnumerateDirectories()) + { + Console.WriteLine(" Project {0} has Extension {1}!", UProjectPath, DI); + + // assume each Extension in here will create a resulting Extension.appex + string Extension = DI.Name + ".appex"; + + string ExtensionGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); + + // make an extension info object + XcodeExtensionInfo ExtensionInfo = new XcodeExtensionInfo(DI.Name); + AllExtensions.Add(ExtensionInfo); + + PBXBuildFileSection.Append(string.Format("\t\t{0} /* {1} in Embed App Extensions */ = {{isa = PBXBuildFile; fileRef = {2} /* {1} */; settings = {{ATTRIBUTES = (RemoveHeadersOnCopy, ); }}; }};" + ProjectFileGenerator.NewLine, + ExtensionGuid, + Extension, + ExtensionInfo.ProductGuid)); + + PBXFileReferenceSection.Append(string.Format("\t\t{0} /* {1} */ = {{isa = PBXFileReference; explicitFileType = wrapper.app-extension; path = \"{1}\"; sourceTree = BUILT_PRODUCTS_DIR; }};" + ProjectFileGenerator.NewLine, + ExtensionInfo.ProductGuid, + Extension)); + + PBXCopyFilesBuildPhaseSection.Append(string.Format("\t\t\t\t{0} /* {1} in Embed App Extensions */," + ProjectFileGenerator.NewLine, + ExtensionGuid, + Extension)); + + PBXResourcesBuildPhaseSection.Append("/* Begin PBXResourcesBuildPhase section */" + ProjectFileGenerator.NewLine); + PBXResourcesBuildPhaseSection.Append("\t\t" + ExtensionInfo.ResourceBuildPhaseGuid + " /* Resources */ = {" + ProjectFileGenerator.NewLine); + PBXResourcesBuildPhaseSection.Append("\t\t\tisa = PBXResourcesBuildPhase;" + ProjectFileGenerator.NewLine); + PBXResourcesBuildPhaseSection.Append("\t\t\tbuildActionMask = 2147483647;" + ProjectFileGenerator.NewLine); + PBXResourcesBuildPhaseSection.Append("\t\t\tfiles = (" + ProjectFileGenerator.NewLine); + if (Directory.Exists(Path.Combine(DI.FullName, "Resources"))) + { + DirectoryInfo ResourceDir = new System.IO.DirectoryInfo(Path.Combine(DI.FullName, "Resources")); + foreach (FileSystemInfo FSI in ResourceDir.EnumerateFileSystemInfos()) + { + if (FSI.Name.StartsWith(".")) + { + continue; + } + // for each resource, put it into the File/FileRef section, and into the CopyResuorceBuildPhase + string ResourceGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); + string ResourceRefGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); + PBXBuildFileSection.Append(string.Format("\t\t{0} /* {1} in Embed App Extensions */ = {{isa = PBXBuildFile; fileRef = {2} /* {1} */; }};" + ProjectFileGenerator.NewLine, + ResourceGuid, + FSI.Name, + ResourceRefGuid)); + + // lastKnownFileType = wrapper.app-extension; + PBXFileReferenceSection.Append(string.Format("\t\t{0} /* {1} */ = {{isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = \"{2}\"; sourceTree = \"\"; }};" + ProjectFileGenerator.NewLine, + ResourceRefGuid, + FSI.Name, + // @todo: make this relative path!! + FSI.FullName)); + + PBXResourcesBuildPhaseSection.Append("\t\t\t\t" + ResourceGuid + " /* " + FSI.Name + " in " + ResourceDir.Name + " */," + ProjectFileGenerator.NewLine); + } + } + PBXResourcesBuildPhaseSection.Append("\t\t\t);" + ProjectFileGenerator.NewLine); + PBXResourcesBuildPhaseSection.Append("\t\t\trunOnlyForDeploymentPostprocessing = 0;" + ProjectFileGenerator.NewLine); + PBXResourcesBuildPhaseSection.Append("\t\t};" + ProjectFileGenerator.NewLine); + PBXResourcesBuildPhaseSection.Append("/* End PBXResourcesBuildPhase section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine); + + StringBuilder ConfigSection = new StringBuilder(); + // copy over the configs from the general project to the extension + foreach (XcodeBuildConfig Configuration in BuildConfigs) + { + string ConfigGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); + string ConfigName = Configuration.DisplayName; + + ConfigSection.Append("\t\t" + ConfigGuid + " /* " + ConfigName + " */ = {" + ProjectFileGenerator.NewLine); + ConfigSection.Append("\t\t\tisa = XCBuildConfiguration;" + ProjectFileGenerator.NewLine); + ConfigSection.Append("\t\t\tbuildSettings = {" + ProjectFileGenerator.NewLine); + ConfigSection.Append("\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = \"iMessage App Icon\";" + ProjectFileGenerator.NewLine); + ConfigSection.Append("\t\t\t\tINFOPLIST_FILE = \"" + Path.Combine(DI.FullName, "Info.plist") + "\";" + ProjectFileGenerator.NewLine); + ConfigSection.Append("\t\t\t\tSKIP_INSTALL = YES;" + ProjectFileGenerator.NewLine); + ConfigSection.Append("\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";" + ProjectFileGenerator.NewLine); + + bool bSupportIOS = true; + bool bSupportTVOS = true; + if (bSupportIOS && InstalledPlatformInfo.IsValidPlatform(UnrealTargetPlatform.IOS, EProjectType.Code)) + { + IOSPlatform IOSPlatform = ((IOSPlatform)UEBuildPlatform.GetBuildPlatform(UnrealTargetPlatform.IOS)); + IOSProjectSettings ProjectSettings = IOSPlatform.ReadProjectSettings(UProjectPath); + ConfigSection.Append("\t\t\t\t\"PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]\" = " + ProjectSettings.BundleIdentifier + "." + ExtensionInfo.Name + ";" + ProjectFileGenerator.NewLine); + } + + if (bSupportTVOS && InstalledPlatformInfo.IsValidPlatform(UnrealTargetPlatform.TVOS, EProjectType.Code)) + { + TVOSPlatform TVOSPlatform = ((TVOSPlatform)UEBuildPlatform.GetBuildPlatform(UnrealTargetPlatform.TVOS)); + TVOSProjectSettings ProjectSettings = TVOSPlatform.ReadProjectSettings(UProjectPath); + ConfigSection.Append("\t\t\t\t\"PRODUCT_BUNDLE_IDENTIFIER[sdk=appletvos*]\" = " + ProjectSettings.BundleIdentifier + "." + ExtensionInfo.Name + ";" + ProjectFileGenerator.NewLine); + } + + string IOSRuntimeVersion, TVOSRuntimeVersion; + AppendPlatformConfiguration(ConfigSection, null, ExtensionInfo.Name, UProjectPath, false, bSupportIOS, bSupportTVOS, out IOSRuntimeVersion, out TVOSRuntimeVersion); + + ConfigSection.Append("\t\t\t};" + ProjectFileGenerator.NewLine); + ConfigSection.Append("\t\t\tname = \"" + ConfigName + "\";" + ProjectFileGenerator.NewLine); + ConfigSection.Append("\t\t};" + ProjectFileGenerator.NewLine); + + XcodeBuildConfig Config = new XcodeBuildConfig(ConfigName, ExtensionInfo.Name, null, null, null, null, Configuration.BuildConfig); + ExtensionInfo.AllConfigs.Add(ConfigGuid, Config); + } + + ExtensionInfo.ConfigurationContents = ConfigSection.ToString(); + } + } + } + } + private void AppendGroup(XcodeFileGroup Group, StringBuilder Content) { if (!Group.bIsReference) @@ -365,7 +593,41 @@ namespace UnrealBuildTool return null; } - private void AppendGroupSection(StringBuilder Content, string MainGroupGuid, string ProductRefGroupGuid, string TargetAppGuid, string TargetName) + private void AppendCopyFrameworksBuildPhaseSection(StringBuilder Content, StringBuilder SectionContent, string CopyFilesBuildPhaseGuid) + { + Content.Append("/* Begin PBXCopyFilesBuildPhase section */" + ProjectFileGenerator.NewLine); + Content.Append(string.Format("\t{0} /* Embed Frameworks */ = {{{1}", CopyFilesBuildPhaseGuid, ProjectFileGenerator.NewLine)); + Content.Append("\t\tisa = PBXCopyFilesBuildPhase;" + ProjectFileGenerator.NewLine); + Content.Append("\t\tbuildActionMask = 2147483647;" + ProjectFileGenerator.NewLine); + Content.Append("\t\tdstPath = \"\";" + ProjectFileGenerator.NewLine); + Content.Append("\t\tdstSubfolderSpec = 10;" + ProjectFileGenerator.NewLine); + Content.Append("\t\tfiles = (" + ProjectFileGenerator.NewLine); + Content.Append(SectionContent); + Content.Append("\t\t);" + ProjectFileGenerator.NewLine); + Content.Append("\t\tname = \"Embed Frameworks\";" + ProjectFileGenerator.NewLine); + Content.Append("\t\trunOnlyForDeploymentPostprocessing = 0;" + ProjectFileGenerator.NewLine); + Content.Append("\t};" + ProjectFileGenerator.NewLine); + Content.Append("/* End PBXCopyFilesBuildPhase section */" + ProjectFileGenerator.NewLine); + } + + private void AppendCopyExtensionsBuildPhaseSection(StringBuilder Content, StringBuilder SectionContent, string CopyFilesBuildPhaseGuid) + { + Content.Append("/* Begin PBXCopyFilesBuildPhase section */" + ProjectFileGenerator.NewLine); + Content.Append(string.Format("\t{0} /* Embed App Extensions */ = {{{1}", CopyFilesBuildPhaseGuid, ProjectFileGenerator.NewLine)); + Content.Append("\t\tisa = PBXCopyFilesBuildPhase;" + ProjectFileGenerator.NewLine); + Content.Append("\t\tbuildActionMask = 2147483647;" + ProjectFileGenerator.NewLine); + Content.Append("\t\tdstPath = \"\";" + ProjectFileGenerator.NewLine); + Content.Append("\t\tdstSubfolderSpec = 13;" + ProjectFileGenerator.NewLine); + Content.Append("\t\tfiles = (" + ProjectFileGenerator.NewLine); + Content.Append(SectionContent); + Content.Append("\t\t);" + ProjectFileGenerator.NewLine); + Content.Append("\t\tname = \"Embed App Extensions\";" + ProjectFileGenerator.NewLine); + Content.Append("\t\trunOnlyForDeploymentPostprocessing = 0;" + ProjectFileGenerator.NewLine); + Content.Append("\t};" + ProjectFileGenerator.NewLine); + Content.Append("/* End PBXCopyFilesBuildPhase section */" + ProjectFileGenerator.NewLine); + } + + private void AppendGroupSection(StringBuilder Content, string MainGroupGuid, string ProductRefGroupGuid, string TargetAppGuid, string TargetName, List AllExtensions) { XcodeFileGroup RootGroup = FindRootFileGroup(Groups); if (RootGroup == null) @@ -406,6 +668,10 @@ namespace UnrealBuildTool Content.Append("\t\t\tisa = PBXGroup;" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tchildren = (" + ProjectFileGenerator.NewLine); Content.Append(string.Format("\t\t\t\t{0} /* {1} */,{2}", TargetAppGuid, TargetName, ProjectFileGenerator.NewLine)); + foreach (XcodeExtensionInfo EI in AllExtensions) + { + Content.Append(string.Format("\t\t\t\t{0} /* {1} */,{2}", EI.ProductGuid, EI.Name, ProjectFileGenerator.NewLine)); + } Content.Append("\t\t\t);" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tname = Products;" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tsourceTree = \"\";" + ProjectFileGenerator.NewLine); @@ -439,7 +705,36 @@ namespace UnrealBuildTool Content.Append("/* End PBXLegacyTarget section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine); } - private void AppendRunTargetSection(StringBuilder Content, string TargetName, string TargetGuid, string TargetBuildConfigGuid, string TargetDependencyGuid, string TargetAppGuid) + private void AppendRunTargetSection(StringBuilder Content, string TargetName, string TargetGuid, string TargetBuildConfigGuid, string TargetDependencyGuid, string TargetAppGuid, string CopyFrameworksBuildPhaseGuid, string CopyExtensionsBuildPhaseGuid, List AllExtensions) + { + List DependencyGuids = new List(); + // depends on the Run target if we want one + if (!XcodeProjectFileGenerator.bGeneratingRunIOSProject && !XcodeProjectFileGenerator.bGeneratingRunTVOSProject) + { + DependencyGuids.Add(TargetDependencyGuid); + } + // make sure extensions get built + foreach (XcodeExtensionInfo EI in AllExtensions) + { + DependencyGuids.Add(EI.TargetDependencyGuid); + } + + Dictionary BuildPhases = new Dictionary(); + // add optional build phases + if (!string.IsNullOrEmpty(CopyFrameworksBuildPhaseGuid)) + { + BuildPhases.Add(CopyFrameworksBuildPhaseGuid, "Embed Frameworks"); + } + if (!string.IsNullOrEmpty(CopyExtensionsBuildPhaseGuid)) + { + BuildPhases.Add(CopyExtensionsBuildPhaseGuid, "Embed App Extensions"); + } + + // use generica target section function for an application type + AppendGenericTargetSection(Content, TargetName, TargetGuid, "com.apple.product-type.application", TargetBuildConfigGuid, TargetAppGuid, DependencyGuids, BuildPhases); + } + + private void AppendGenericTargetSection(StringBuilder Content, string TargetName, string TargetGuid, string TargetType, string TargetBuildConfigGuid, string TargetAppGuid, IEnumerable TargetDependencyGuids, Dictionary BuildPhases) { Content.Append("/* Begin PBXNativeTarget section */" + ProjectFileGenerator.NewLine); @@ -447,18 +742,28 @@ namespace UnrealBuildTool Content.Append("\t\t\tisa = PBXNativeTarget;" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tbuildConfigurationList = " + TargetBuildConfigGuid + " /* Build configuration list for PBXNativeTarget \"" + TargetName + "\" */;" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tbuildPhases = (" + ProjectFileGenerator.NewLine); + if (BuildPhases != null) + { + foreach (KeyValuePair BuildPhasePair in BuildPhases) + { + Content.Append("\t\t\t\t" + BuildPhasePair.Key + " /* " + BuildPhasePair.Value + " */, " + ProjectFileGenerator.NewLine); + } + } Content.Append("\t\t\t);" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tdependencies = (" + ProjectFileGenerator.NewLine); - if (!XcodeProjectFileGenerator.bGeneratingRunIOSProject && !XcodeProjectFileGenerator.bGeneratingRunTVOSProject) + if (TargetDependencyGuids != null) { - Content.Append("\t\t\t\t" + TargetDependencyGuid + " /* PBXTargetDependency */," + ProjectFileGenerator.NewLine); + foreach (string DependencyGuid in TargetDependencyGuids) + { + Content.Append("\t\t\t\t" + DependencyGuid + " /* PBXTargetDependency */," + ProjectFileGenerator.NewLine); + } } Content.Append("\t\t\t);" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tname = \"" + TargetName + "\";" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tpassBuildSettingsInEnvironment = 1;" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tproductName = \"" + TargetName + "\";" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tproductReference = \"" + TargetAppGuid + "\";" + ProjectFileGenerator.NewLine); - Content.Append("\t\t\tproductType = \"com.apple.product-type.application\";" + ProjectFileGenerator.NewLine); + Content.Append("\t\t\tproductType = \"" + TargetType + "\";" + ProjectFileGenerator.NewLine); Content.Append("\t\t};" + ProjectFileGenerator.NewLine); Content.Append("/* End PBXNativeTarget section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine); @@ -485,7 +790,18 @@ namespace UnrealBuildTool Content.Append("/* End PBXNativeTarget section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine); } - private void AppendProjectSection(StringBuilder Content, string TargetName, string TargetGuid, string BuildTargetName, string BuildTargetGuid, string IndexTargetName, string IndexTargetGuid, string MainGroupGuid, string ProductRefGroupGuid, string ProjectGuid, string ProjectBuildConfigGuid, FileReference ProjectFile) + private void AppendExtensionTargetSections(StringBuilder ProjectFileContent, List AllExtensions) + { + foreach (XcodeExtensionInfo EI in AllExtensions) + { + Dictionary BuildPhases = new Dictionary(); + BuildPhases.Add(EI.ResourceBuildPhaseGuid, "Resources"); + + AppendGenericTargetSection(ProjectFileContent, EI.Name, EI.TargetGuid, "com.apple.product-type.app-extension.messages-sticker-pack", EI.ConfigListGuid, EI.ProductGuid, null, BuildPhases); + } + } + + private void AppendProjectSection(StringBuilder Content, string TargetName, string TargetGuid, string BuildTargetName, string BuildTargetGuid, string IndexTargetName, string IndexTargetGuid, string MainGroupGuid, string ProductRefGroupGuid, string ProjectGuid, string ProjectBuildConfigGuid, FileReference ProjectFile, List AllExtensions) { Content.Append("/* Begin PBXProject section */" + ProjectFileGenerator.NewLine); @@ -539,6 +855,10 @@ namespace UnrealBuildTool Content.Append("\t\t\t" + TargetGuid + " /* " + TargetName + " */," + ProjectFileGenerator.NewLine); Content.Append("\t\t\t" + BuildTargetGuid + " /* " + BuildTargetName + " */," + ProjectFileGenerator.NewLine); Content.Append("\t\t\t" + IndexTargetGuid + " /* " + IndexTargetName + " */," + ProjectFileGenerator.NewLine); + foreach (XcodeExtensionInfo EI in AllExtensions) + { + Content.Append("\t\t\t" + EI.TargetGuid + " /* " + EI.Name + " */," + ProjectFileGenerator.NewLine); + } Content.Append("\t\t\t);" + ProjectFileGenerator.NewLine); Content.Append("\t\t};" + ProjectFileGenerator.NewLine); @@ -615,41 +935,34 @@ namespace UnrealBuildTool Content.Append("\t\t};" + ProjectFileGenerator.NewLine); } - private void AppendNativeTargetBuildConfiguration(StringBuilder Content, XcodeBuildConfig Config, string ConfigGuid, bool bIsAGame, FileReference ProjectFile) + private void AppendPlatformConfiguration(StringBuilder Content, FileReference MacExecutablePath, string TargetName, FileReference ProjectFile, bool bSupportMac, bool bSupportIOS, bool bSupportTVOS, out string IOSRunTimeVersion, out string TVOSRunTimeVersion, string BinariesSubDir = "/Payload") { - bool bMacOnly = true; - if (Config.ProjectTarget.TargetRules != null && XcodeProjectFileGenerator.ProjectFilePlatform.HasFlag(XcodeProjectFileGenerator.XcodeProjectFilePlatform.iOS)) - { - if (Config.ProjectTarget.SupportedPlatforms.Contains(UnrealTargetPlatform.IOS)) - { - bMacOnly = false; - } - } + string UE4Dir = ConvertPath(Path.GetFullPath(Directory.GetCurrentDirectory() + "../../..")); + string MacExecutableDir = bSupportMac ? ConvertPath(MacExecutablePath.Directory.FullName) : ""; + string MacExecutableFileName = bSupportMac ? MacExecutablePath.GetFileName() : ""; - Content.Append("\t\t" + ConfigGuid + " /* \"" + Config.DisplayName + "\" */ = {" + ProjectFileGenerator.NewLine); - Content.Append("\t\t\tisa = XCBuildConfiguration;" + ProjectFileGenerator.NewLine); - Content.Append("\t\t\tbuildSettings = {" + ProjectFileGenerator.NewLine); + IOSRunTimeVersion = null; + TVOSRunTimeVersion = null; - string UE4Dir = ConvertPath(Path.GetFullPath(Directory.GetCurrentDirectory() + "../../..")); - string MacExecutableDir = ConvertPath(Config.MacExecutablePath.Directory.FullName); - string MacExecutableFileName = Config.MacExecutablePath.GetFileName(); - - if (bMacOnly) + // shortcut for mac only + if (bSupportMac && !bSupportIOS && !bSupportTVOS) { Content.Append("\t\t\t\tVALID_ARCHS = \"x86_64\";" + ProjectFileGenerator.NewLine); Content.Append("\t\t\t\tSUPPORTED_PLATFORMS = \"macosx\";" + ProjectFileGenerator.NewLine); Content.Append("\t\t\t\tPRODUCT_NAME = \"" + MacExecutableFileName + "\";" + ProjectFileGenerator.NewLine); Content.Append("\t\t\t\tCONFIGURATION_BUILD_DIR = \"" + MacExecutableDir + "\";" + ProjectFileGenerator.NewLine); - Content.Append("\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;" + ProjectFileGenerator.NewLine); } else { - string IOSRunTimeVersion = null; + bool bIsUE4Game = TargetName.Equals("UE4Game", StringComparison.InvariantCultureIgnoreCase); + bool bIsUE4Client = TargetName.Equals("UE4Client", StringComparison.InvariantCultureIgnoreCase); + DirectoryReference GameDir = ProjectFile != null ? ProjectFile.Directory : null; + string GamePath = GameDir != null ? ConvertPath(GameDir.FullName) : null; + string IOSRunTimeDevices = null; - string TVOSRunTimeVersion = null; string TVOSRunTimeDevices = null; - string ValidArchs = "x86_64"; - string SupportedPlatforms = "macosx"; + string ValidArchs = bSupportMac ? "x86_64" : ""; + string SupportedPlatforms = bSupportMac ? "macosx" : ""; bool bAutomaticSigning = false; string UUID_IOS = ""; @@ -658,7 +971,9 @@ namespace UnrealBuildTool string TEAM_TVOS = ""; string IOS_CERT = "iPhone Developer"; string TVOS_CERT = "iPhone Developer"; - if (InstalledPlatformInfo.IsValidPlatform(UnrealTargetPlatform.IOS, EProjectType.Code)) + string IOS_BUNDLE = ""; + string TVOS_BUNDLE = ""; + if (bSupportIOS && InstalledPlatformInfo.IsValidPlatform(UnrealTargetPlatform.IOS, EProjectType.Code)) { IOSPlatform IOSPlatform = ((IOSPlatform)UEBuildPlatform.GetBuildPlatform(UnrealTargetPlatform.IOS)); IOSProjectSettings ProjectSettings = IOSPlatform.ReadProjectSettings(ProjectFile); @@ -674,16 +989,17 @@ namespace UnrealBuildTool IOS_CERT = ProvisioningData.SigningCertificate; } TEAM_IOS = ProvisioningData.TeamUUID; + IOS_BUNDLE = ProjectSettings.BundleIdentifier; } - if (InstalledPlatformInfo.IsValidPlatform(UnrealTargetPlatform.TVOS, EProjectType.Code)) + if (bSupportTVOS && InstalledPlatformInfo.IsValidPlatform(UnrealTargetPlatform.TVOS, EProjectType.Code)) { TVOSPlatform TVOSPlatform = ((TVOSPlatform)UEBuildPlatform.GetBuildPlatform(UnrealTargetPlatform.TVOS)); TVOSProjectSettings ProjectSettings = TVOSPlatform.ReadProjectSettings(ProjectFile); TVOSProvisioningData ProvisioningData = TVOSPlatform.ReadProvisioningData(ProjectSettings); TVOSRunTimeVersion = ProjectSettings.RuntimeVersion; TVOSRunTimeDevices = ProjectSettings.RuntimeDevices; - if (ValidArchs == "x86_64") + if (!ValidArchs.Contains("arm64")) { ValidArchs += " arm64 armv7 armv7s"; } @@ -694,15 +1010,19 @@ namespace UnrealBuildTool TVOS_CERT = ProvisioningData.SigningCertificate; } TEAM_TVOS = ProvisioningData.TeamUUID; + TVOS_BUNDLE = ProjectSettings.BundleIdentifier; } - Content.Append("\t\t\t\tVALID_ARCHS = \"" + ValidArchs + "\";" + ProjectFileGenerator.NewLine); - Content.Append("\t\t\t\tSUPPORTED_PLATFORMS = \"" + SupportedPlatforms + "\";" + ProjectFileGenerator.NewLine); - Content.Append("\t\t\t\t\"PRODUCT_NAME[sdk=macosx*]\" = \"" + MacExecutableFileName + "\";" + ProjectFileGenerator.NewLine); + Content.Append("\t\t\t\tVALID_ARCHS = \"" + ValidArchs.Trim() + "\";" + ProjectFileGenerator.NewLine); + Content.Append("\t\t\t\tSUPPORTED_PLATFORMS = \"" + SupportedPlatforms.Trim() + "\";" + ProjectFileGenerator.NewLine); + if (bAutomaticSigning) + { + Content.Append("\t\t\t\tCODE_SIGN_STYLE = Automatic;" + ProjectFileGenerator.NewLine); + } if (IOSRunTimeVersion != null) { Content.Append("\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = " + IOSRunTimeVersion + ";" + ProjectFileGenerator.NewLine); - Content.Append("\t\t\t\t\"PRODUCT_NAME[sdk=iphoneos*]\" = \"" + Config.BuildTarget + "\";" + ProjectFileGenerator.NewLine); // @todo: change to Path.GetFileName(Config.IOSExecutablePath) when we stop using payload + Content.Append("\t\t\t\t\"PRODUCT_NAME[sdk=iphoneos*]\" = \"" + TargetName + "\";" + ProjectFileGenerator.NewLine); // @todo: change to Path.GetFileName(Config.IOSExecutablePath) when we stop using payload Content.Append("\t\t\t\t\"TARGETED_DEVICE_FAMILY[sdk=iphoneos*]\" = \"" + IOSRunTimeDevices + "\";" + ProjectFileGenerator.NewLine); Content.Append("\t\t\t\t\"SDKROOT[sdk=iphoneos]\" = iphoneos;" + ProjectFileGenerator.NewLine); if (!string.IsNullOrEmpty(TEAM_IOS)) @@ -714,11 +1034,12 @@ namespace UnrealBuildTool { Content.Append("\t\t\t\t\"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]\" = \"" + UUID_IOS + "\";" + ProjectFileGenerator.NewLine); } + Content.Append("\t\t\t\t\"PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]\" = " + IOS_BUNDLE + ";"); } if (TVOSRunTimeVersion != null) { Content.Append("\t\t\t\tTVOS_DEPLOYMENT_TARGET = " + TVOSRunTimeVersion + ";" + ProjectFileGenerator.NewLine); - Content.Append("\t\t\t\t\"PRODUCT_NAME[sdk=appletvos*]\" = \"" + Config.BuildTarget + "\";" + ProjectFileGenerator.NewLine); // @todo: change to Path.GetFileName(Config.TVOSExecutablePath) when we stop using payload + Content.Append("\t\t\t\t\"PRODUCT_NAME[sdk=appletvos*]\" = \"" + TargetName + "\";" + ProjectFileGenerator.NewLine); // @todo: change to Path.GetFileName(Config.TVOSExecutablePath) when we stop using payload Content.Append("\t\t\t\t\"TARGETED_DEVICE_FAMILY[sdk=appletvos*]\" = \"" + TVOSRunTimeDevices + "\";" + ProjectFileGenerator.NewLine); Content.Append("\t\t\t\t\"SDKROOT[sdk=appletvos]\" = appletvos;" + ProjectFileGenerator.NewLine); if (!string.IsNullOrEmpty(TEAM_TVOS)) @@ -730,12 +1051,76 @@ namespace UnrealBuildTool { Content.Append("\t\t\t\t\"PROVISIONING_PROFILE_SPECIFIER[sdk=appletvos*]\" = \"" + UUID_TVOS + "\";" + ProjectFileGenerator.NewLine); } + Content.Append("\t\t\t\t\"PRODUCT_BUNDLE_IDENTIFIER[sdk=appletvos*]\" = " + TVOS_BUNDLE + ";"); } + if (bSupportMac) + { + Content.Append("\t\t\t\t\"PRODUCT_NAME[sdk=macosx*]\" = \"" + MacExecutableFileName + "\";" + ProjectFileGenerator.NewLine); Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=macosx*]\" = \"" + MacExecutableDir + "\";" + ProjectFileGenerator.NewLine); Content.Append("\t\t\t\t\"SDKROOT[sdk=macosx]\" = macosx;" + ProjectFileGenerator.NewLine); - Content.Append("\t\t\t\tINFOPLIST_OUTPUT_FORMAT = xml;" + ProjectFileGenerator.NewLine); - Content.Append("\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;" + ProjectFileGenerator.NewLine); + } + if (bIsUE4Game || bIsUE4Client) + { + if (IOSRunTimeVersion != null) + { + Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=iphoneos*]\" = \"" + UE4Dir + "/Engine/Binaries/IOS" + BinariesSubDir + "\";" + ProjectFileGenerator.NewLine); + } + if (TVOSRunTimeVersion != null) + { + Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=appletvos*]\" = \"" + UE4Dir + "/Engine/Binaries/TVOS" + BinariesSubDir + "\";" + ProjectFileGenerator.NewLine); + } + } + else if (ProjectFile != null) + { + if (IOSRunTimeVersion != null) + { + Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=iphoneos*]\" = \"" + GamePath + "/Binaries/IOS" + BinariesSubDir + "\";" + ProjectFileGenerator.NewLine); + } + if (TVOSRunTimeVersion != null) + { + Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=appletvos*]\" = \"" + GamePath + "/Binaries/TVOS" + BinariesSubDir + "\";" + ProjectFileGenerator.NewLine); + } + } + else + { + if (IOSRunTimeVersion != null) + { + Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=iphoneos*]\" = \"" + UE4Dir + "/Engine/Binaries/IOS" + BinariesSubDir + "\";" + ProjectFileGenerator.NewLine); + } + if (TVOSRunTimeVersion != null) + { + Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=appletvos*]\" = \"" + UE4Dir + "/Engine/Binaries/TVOS" + BinariesSubDir + "\";" + ProjectFileGenerator.NewLine); + } + } + + } + } + + private void AppendNativeTargetBuildConfiguration(StringBuilder Content, XcodeBuildConfig Config, string ConfigGuid, FileReference ProjectFile) + { + bool bMacOnly = true; + if (Config.ProjectTarget.TargetRules != null && XcodeProjectFileGenerator.ProjectFilePlatform.HasFlag(XcodeProjectFileGenerator.XcodeProjectFilePlatform.iOS)) + { + if (Config.ProjectTarget.SupportedPlatforms.Contains(UnrealTargetPlatform.IOS)) + { + bMacOnly = false; + } + } + + Content.Append("\t\t" + ConfigGuid + " /* \"" + Config.DisplayName + "\" */ = {" + ProjectFileGenerator.NewLine); + Content.Append("\t\t\tisa = XCBuildConfiguration;" + ProjectFileGenerator.NewLine); + Content.Append("\t\t\tbuildSettings = {" + ProjectFileGenerator.NewLine); + + string UE4Dir = ConvertPath(Path.GetFullPath(Directory.GetCurrentDirectory() + "../../..")); + string MacExecutableDir = ConvertPath(Config.MacExecutablePath.Directory.FullName); + string MacExecutableFileName = Config.MacExecutablePath.GetFileName(); + + string IOSRunTimeVersion, TVOSRunTimeVersion; + AppendPlatformConfiguration(Content, Config.MacExecutablePath, Config.BuildTarget, ProjectFile, true, !bMacOnly, !bMacOnly, out IOSRunTimeVersion, out TVOSRunTimeVersion); + + if (!bMacOnly) + { bool bIsUE4Game = Config.BuildTarget.Equals("UE4Game", StringComparison.InvariantCultureIgnoreCase); bool bIsUE4Client = Config.BuildTarget.Equals("UE4Client", StringComparison.InvariantCultureIgnoreCase); @@ -752,14 +1137,6 @@ namespace UnrealBuildTool TVOSInfoPlistPath = UE4Dir + "/Engine/Intermediate/TVOS/" + Config.BuildTarget + "-Info.plist"; MacInfoPlistPath = UE4Dir + "/Engine/Intermediate/Mac/" + MacExecutableFileName + "-Info.plist"; IOSEntitlementPath = ""; - if (IOSRunTimeVersion != null) - { - Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=iphoneos*]\" = \"" + UE4Dir + "/Engine/Binaries/IOS/Payload\";" + ProjectFileGenerator.NewLine); - } - if (TVOSRunTimeVersion != null) - { - Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=appletvos*]\" = \"" + UE4Dir + "/Engine/Binaries/TVOS/Payload\";" + ProjectFileGenerator.NewLine); - } } else if (bIsUE4Client) { @@ -767,29 +1144,13 @@ namespace UnrealBuildTool TVOSInfoPlistPath = UE4Dir + "/Engine/Intermediate/TVOS/UE4Game-Info.plist"; MacInfoPlistPath = UE4Dir + "/Engine/Intermediate/Mac/" + MacExecutableFileName + "-Info.plist"; IOSEntitlementPath = ""; - if (IOSRunTimeVersion != null) - { - Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=iphoneos*]\" = \"" + UE4Dir + "/Engine/Binaries/IOS/Payload\";" + ProjectFileGenerator.NewLine); } - if (TVOSRunTimeVersion != null) - { - Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=appletvos*]\" = \"" + UE4Dir + "/Engine/Binaries/TVOS/Payload\";" + ProjectFileGenerator.NewLine); - } - } - else if (bIsAGame) + else if (ProjectFile != null) { IOSInfoPlistPath = GamePath + "/Intermediate/IOS/" + Config.BuildTarget + "-Info.plist"; TVOSInfoPlistPath = GamePath + "/Intermediate/TVOS/" + Config.BuildTarget + "-Info.plist"; MacInfoPlistPath = GamePath + "/Intermediate/Mac/" + MacExecutableFileName + "-Info.plist"; IOSEntitlementPath = GamePath + "/Intermediate/IOS/" + Config.BuildTarget + ".entitlements"; - if (IOSRunTimeVersion != null) - { - Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=iphoneos*]\" = \"" + GamePath + "/Binaries/IOS/Payload\";" + ProjectFileGenerator.NewLine); - } - if (TVOSRunTimeVersion != null) - { - Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=appletvos*]\" = \"" + GamePath + "/Binaries/TVOS/Payload\";" + ProjectFileGenerator.NewLine); - } } else { @@ -805,14 +1166,6 @@ namespace UnrealBuildTool TVOSInfoPlistPath = GamePath + "/Intermediate/TVOS/" + Config.BuildTarget + "-Info.plist"; MacInfoPlistPath = GamePath + "/Intermediate/Mac/" + MacExecutableFileName + "-Info.plist"; } - if (IOSRunTimeVersion != null) - { - Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=iphoneos*]\" = \"" + UE4Dir + "/Engine/Binaries/IOS/Payload\";" + ProjectFileGenerator.NewLine); - } - if (TVOSRunTimeVersion != null) - { - Content.Append("\t\t\t\t\"CONFIGURATION_BUILD_DIR[sdk=appletvos*]\" = \"" + UE4Dir + "/Engine/Binaries/TVOS/Payload\";" + ProjectFileGenerator.NewLine); - } } if (XcodeProjectFileGenerator.bGeneratingRunIOSProject) @@ -893,6 +1246,9 @@ namespace UnrealBuildTool } } Content.Append("\t\t\t\tMACOSX_DEPLOYMENT_TARGET = " + MacToolChain.Settings.MacOSVersion + ";" + ProjectFileGenerator.NewLine); + Content.Append("\t\t\t\tINFOPLIST_OUTPUT_FORMAT = xml;" + ProjectFileGenerator.NewLine); + Content.Append("\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;" + ProjectFileGenerator.NewLine); + //#jira UE-50382 Xcode Address Sanitizer feature does not work on iOS // address sanitizer dylib loader depends on the SDKROOT parameter. For macosx or default (missing, translated as macosx), the path is incorrect for iphone/appletv if (XcodeProjectFileGenerator.bGeneratingRunIOSProject) @@ -960,8 +1316,10 @@ namespace UnrealBuildTool Content.Append("\t\t};" + ProjectFileGenerator.NewLine); } + private void AppendXCBuildConfigurationSection(StringBuilder Content, Dictionary ProjectBuildConfigs, Dictionary TargetBuildConfigs, - Dictionary BuildTargetBuildConfigs, Dictionary IndexTargetBuildConfigs, bool bIsAGame, FileReference GameProjectPath) + Dictionary BuildTargetBuildConfigs, Dictionary IndexTargetBuildConfigs, FileReference GameProjectPath, + List AllExtensions) { Content.Append("/* Begin XCBuildConfiguration section */" + ProjectFileGenerator.NewLine); @@ -972,7 +1330,7 @@ namespace UnrealBuildTool foreach (KeyValuePair Config in TargetBuildConfigs) { - AppendNativeTargetBuildConfiguration(Content, Config.Value, Config.Key, bIsAGame, GameProjectPath); + AppendNativeTargetBuildConfiguration(Content, Config.Value, Config.Key, GameProjectPath); } foreach (KeyValuePair Config in BuildTargetBuildConfigs) @@ -982,13 +1340,18 @@ namespace UnrealBuildTool foreach (KeyValuePair Config in IndexTargetBuildConfigs) { - AppendNativeTargetBuildConfiguration(Content, Config.Value, Config.Key, bIsAGame, GameProjectPath); + AppendNativeTargetBuildConfiguration(Content, Config.Value, Config.Key, GameProjectPath); + } + + foreach (XcodeExtensionInfo EI in AllExtensions) + { + Content.Append(EI.ConfigurationContents); } Content.Append("/* End XCBuildConfiguration section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine); } - private void AppendXCConfigurationList(StringBuilder Content, string TypeName, string TargetName, string ConfigListGuid, Dictionary BuildConfigs) + private void AppendXCConfigurationList(StringBuilder Content, string TypeName, string TargetName, string ConfigListGuid, Dictionary BuildConfigs, string Default = "Development") { Content.Append("\t\t" + ConfigListGuid + " /* Build configuration list for " + TypeName + " \"" + TargetName + "\" */ = {" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tisa = XCConfigurationList;" + ProjectFileGenerator.NewLine); @@ -999,14 +1362,15 @@ namespace UnrealBuildTool } Content.Append("\t\t\t);" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tdefaultConfigurationIsVisible = 0;" + ProjectFileGenerator.NewLine); - Content.Append("\t\t\tdefaultConfigurationName = Development;" + ProjectFileGenerator.NewLine); + Content.Append("\t\t\tdefaultConfigurationName = " + Default + ";" + ProjectFileGenerator.NewLine); Content.Append("\t\t};" + ProjectFileGenerator.NewLine); } private void AppendXCConfigurationListSection(StringBuilder Content, string TargetName, string BuildTargetName, string IndexTargetName, string ProjectConfigListGuid, Dictionary ProjectBuildConfigs, string TargetConfigListGuid, Dictionary TargetBuildConfigs, string BuildTargetConfigListGuid, Dictionary BuildTargetBuildConfigs, - string IndexTargetConfigListGuid, Dictionary IndexTargetBuildConfigs) + string IndexTargetConfigListGuid, Dictionary IndexTargetBuildConfigs, + List AllExtensions) { Content.Append("/* Begin XCConfigurationList section */" + ProjectFileGenerator.NewLine); @@ -1015,32 +1379,14 @@ namespace UnrealBuildTool AppendXCConfigurationList(Content, "PBXNativeTarget", TargetName, TargetConfigListGuid, TargetBuildConfigs); AppendXCConfigurationList(Content, "PBXNativeTarget", IndexTargetName, IndexTargetConfigListGuid, IndexTargetBuildConfigs); - Content.Append("/* End XCConfigurationList section */" + ProjectFileGenerator.NewLine); + foreach (XcodeExtensionInfo EI in AllExtensions) + { + AppendXCConfigurationList(Content, "PBXNativeTarget", EI.Name, EI.ConfigListGuid, EI.AllConfigs); } - public struct XcodeBuildConfig - { - public XcodeBuildConfig(string InDisplayName, string InBuildTarget, FileReference InMacExecutablePath, FileReference InIOSExecutablePath, FileReference InTVOSExecutablePath, - ProjectTarget InProjectTarget, UnrealTargetConfiguration InBuildConfig) - { - DisplayName = InDisplayName; - MacExecutablePath = InMacExecutablePath; - IOSExecutablePath = InIOSExecutablePath; - TVOSExecutablePath = InTVOSExecutablePath; - BuildTarget = InBuildTarget; - ProjectTarget = InProjectTarget; - BuildConfig = InBuildConfig; + Content.Append("/* End XCConfigurationList section */" + ProjectFileGenerator.NewLine); } - public string DisplayName; - public FileReference MacExecutablePath; - public FileReference IOSExecutablePath; - public FileReference TVOSExecutablePath; - public string BuildTarget; - public ProjectTarget ProjectTarget; - public UnrealTargetConfiguration BuildConfig; - }; - private List GetSupportedBuildConfigs(List Platforms, List Configurations, PlatformProjectGeneratorCollection PlatformProjectGenerators) { List BuildConfigs = new List(); @@ -1373,6 +1719,8 @@ namespace UnrealBuildTool string MainGroupGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); string ProductRefGroupGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); string SourcesBuildPhaseGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); + string CopyFrameworksBuildPhaseGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); + string CopyExtensionsBuildPhaseGuid = XcodeProjectFileGenerator.MakeXcodeGuid(); // Figure out all the desired configurations List BuildConfigs = GetSupportedBuildConfigs(InPlatforms, InConfigurations, PlatformProjectGenerators); @@ -1381,13 +1729,11 @@ namespace UnrealBuildTool return true; } - bool bIsAGame = false; FileReference GameProjectPath = null; foreach(ProjectTarget Target in ProjectTargets) { if(Target.UnrealProjectFilePath != null) { - bIsAGame = true; GameProjectPath = Target.UnrealProjectFilePath; break; } @@ -1415,7 +1761,13 @@ namespace UnrealBuildTool StringBuilder PBXBuildFileSection = new StringBuilder(); StringBuilder PBXFileReferenceSection = new StringBuilder(); StringBuilder PBXSourcesBuildPhaseSection = new StringBuilder(); + StringBuilder PBXCopyFrameworksBuildPhaseSection = new StringBuilder(); + StringBuilder PBXCopyExtensionsBuildPhaseSection = new StringBuilder(); + StringBuilder PBXResourcesBuildPhaseSection = new StringBuilder(); + List AllExtensions = new List(); GenerateSectionsWithSourceFiles(PBXBuildFileSection, PBXFileReferenceSection, PBXSourcesBuildPhaseSection, TargetAppGuid, TargetName); + GenerateSectionsWithFrameworks(PBXBuildFileSection, PBXFileReferenceSection, PBXCopyFrameworksBuildPhaseSection, GameProjectPath); + GenerateSectionsWithExtensions(PBXBuildFileSection, PBXFileReferenceSection, PBXCopyExtensionsBuildPhaseSection, PBXResourcesBuildPhaseSection, AllExtensions, GameProjectPath, BuildConfigs); StringBuilder ProjectFileContent = new StringBuilder(); @@ -1430,19 +1782,28 @@ namespace UnrealBuildTool AppendBuildFileSection(ProjectFileContent, PBXBuildFileSection); AppendFileReferenceSection(ProjectFileContent, PBXFileReferenceSection); AppendSourcesBuildPhaseSection(ProjectFileContent, PBXSourcesBuildPhaseSection, SourcesBuildPhaseGuid); + AppendCopyFrameworksBuildPhaseSection(ProjectFileContent, PBXCopyFrameworksBuildPhaseSection, CopyFrameworksBuildPhaseGuid); + AppendCopyExtensionsBuildPhaseSection(ProjectFileContent, PBXCopyExtensionsBuildPhaseSection, CopyExtensionsBuildPhaseGuid); + ProjectFileContent.Append(PBXResourcesBuildPhaseSection); AppendContainerItemProxySection(ProjectFileContent, BuildTargetName, BuildTargetGuid, TargetProxyGuid, ProjectGuid); if (!XcodeProjectFileGenerator.bGeneratingRunIOSProject) { AppendTargetDependencySection(ProjectFileContent, BuildTargetName, BuildTargetGuid, TargetDependencyGuid, TargetProxyGuid); } - AppendGroupSection(ProjectFileContent, MainGroupGuid, ProductRefGroupGuid, TargetAppGuid, TargetName); + foreach (XcodeExtensionInfo EI in AllExtensions) + { + AppendContainerItemProxySection(ProjectFileContent, EI.Name, EI.TargetGuid, EI.TargetProxyGuid, ProjectGuid); + AppendTargetDependencySection(ProjectFileContent, EI.Name, EI.TargetGuid, EI.TargetDependencyGuid, EI.TargetProxyGuid); + } + AppendGroupSection(ProjectFileContent, MainGroupGuid, ProductRefGroupGuid, TargetAppGuid, TargetName, AllExtensions); AppendLegacyTargetSection(ProjectFileContent, BuildTargetName, BuildTargetGuid, BuildTargetConfigListGuid, GameProjectPath, bHasEditorConfiguration); - AppendRunTargetSection(ProjectFileContent, TargetName, TargetGuid, TargetConfigListGuid, TargetDependencyGuid, TargetAppGuid); + AppendRunTargetSection(ProjectFileContent, TargetName, TargetGuid, TargetConfigListGuid, TargetDependencyGuid, TargetAppGuid, CopyFrameworksBuildPhaseGuid, CopyExtensionsBuildPhaseGuid, AllExtensions); AppendIndexTargetSection(ProjectFileContent, IndexTargetName, IndexTargetGuid, IndexTargetConfigListGuid, SourcesBuildPhaseGuid); - AppendProjectSection(ProjectFileContent, TargetName, TargetGuid, BuildTargetName, BuildTargetGuid, IndexTargetName, IndexTargetGuid, MainGroupGuid, ProductRefGroupGuid, ProjectGuid, ProjectConfigListGuid, GameProjectPath); - AppendXCBuildConfigurationSection(ProjectFileContent, ProjectBuildConfigs, TargetBuildConfigs, BuildTargetBuildConfigs, IndexTargetBuildConfigs, bIsAGame, GameProjectPath); + AppendExtensionTargetSections(ProjectFileContent, AllExtensions); + AppendProjectSection(ProjectFileContent, TargetName, TargetGuid, BuildTargetName, BuildTargetGuid, IndexTargetName, IndexTargetGuid, MainGroupGuid, ProductRefGroupGuid, ProjectGuid, ProjectConfigListGuid, GameProjectPath, AllExtensions); + AppendXCBuildConfigurationSection(ProjectFileContent, ProjectBuildConfigs, TargetBuildConfigs, BuildTargetBuildConfigs, IndexTargetBuildConfigs, GameProjectPath, AllExtensions); AppendXCConfigurationListSection(ProjectFileContent, TargetName, BuildTargetName, IndexTargetName, ProjectConfigListGuid, ProjectBuildConfigs, - TargetConfigListGuid, TargetBuildConfigs, BuildTargetConfigListGuid, BuildTargetBuildConfigs, IndexTargetConfigListGuid, IndexTargetBuildConfigs); + TargetConfigListGuid, TargetBuildConfigs, BuildTargetConfigListGuid, BuildTargetBuildConfigs, IndexTargetConfigListGuid, IndexTargetBuildConfigs, AllExtensions); ProjectFileContent.Append("\t};" + ProjectFileGenerator.NewLine); ProjectFileContent.Append("\trootObject = " + ProjectGuid + " /* Project object */;" + ProjectFileGenerator.NewLine); diff --git a/Engine/Source/Programs/UnrealBuildTool/System/ConfigHierarchy.cs b/Engine/Source/Programs/UnrealBuildTool/System/ConfigHierarchy.cs index 361bc76a0dfd..5176064cfd60 100644 --- a/Engine/Source/Programs/UnrealBuildTool/System/ConfigHierarchy.cs +++ b/Engine/Source/Programs/UnrealBuildTool/System/ConfigHierarchy.cs @@ -817,7 +817,7 @@ namespace UnrealBuildTool } DirectoryReference UserSettingsFolder = Utils.GetUserSettingDirectory(); // Match FPlatformProcess::UserSettingsDir() - if(UserSettingsFolder != null) + if (UserSettingsFolder != null) { // /UE4/EngineConfig/User* ini yield return FileReference.Combine(UserSettingsFolder, "Unreal Engine", "Engine", "Config", "User" + BaseIniName + ".ini"); diff --git a/Engine/Source/Programs/UnrealBuildTool/System/LinkEnvironment.cs b/Engine/Source/Programs/UnrealBuildTool/System/LinkEnvironment.cs index 9c792fba93e8..a071f4971c93 100644 --- a/Engine/Source/Programs/UnrealBuildTool/System/LinkEnvironment.cs +++ b/Engine/Source/Programs/UnrealBuildTool/System/LinkEnvironment.cs @@ -254,6 +254,11 @@ namespace UnrealBuildTool /// public string BundleVersion; + /// + /// When building a dynamic library on Apple platforms, specifies the installed name for other binaries that link against it. + /// + public string InstallName; + /// /// A list of the object files to be linked. /// @@ -349,6 +354,7 @@ namespace UnrealBuildTool bUseFastPDBLinking = Other.bUseFastPDBLinking; bPrintTimingInfo = Other.bPrintTimingInfo; BundleVersion = Other.BundleVersion; + InstallName = Other.InstallName; InputFiles.AddRange(Other.InputFiles); InputLibraries.AddRange(Other.InputLibraries); DefaultResourceFiles.AddRange(Other.DefaultResourceFiles); diff --git a/Engine/Source/Programs/UnrealBuildTool/System/TargetReceipt.cs b/Engine/Source/Programs/UnrealBuildTool/System/TargetReceipt.cs index aa007b97d3b1..c5bf1ebcdfea 100644 --- a/Engine/Source/Programs/UnrealBuildTool/System/TargetReceipt.cs +++ b/Engine/Source/Programs/UnrealBuildTool/System/TargetReceipt.cs @@ -476,6 +476,28 @@ namespace UnrealBuildTool return StagedFileType.NonUFS; } + /// + /// Checks the Additional properties for one with the given name that matches the given value + /// + /// Property name to search for + /// Value to compare against (with StringComparison.InvariantCultureIgnoreCase) + /// True if any property with PropertyName has a value matching Value + public bool HasValueForAdditionalProperty(string PropertyName, string Value) + { + // get all properties with the given name? + IEnumerable Results = AdditionalProperties.Where(x => x.Name == PropertyName); + foreach (ReceiptProperty Property in Results) + { + // does the property value match? + if (Property.Value.Equals(Value, StringComparison.InvariantCultureIgnoreCase)) + { + return true; + } + } + + return false; + } + /// /// Read a receipt from disk. /// diff --git a/Engine/Source/Programs/UnrealHeaderTool/Private/HeaderParser.cpp b/Engine/Source/Programs/UnrealHeaderTool/Private/HeaderParser.cpp index d3242a8a9102..8c92629fd9b3 100644 --- a/Engine/Source/Programs/UnrealHeaderTool/Private/HeaderParser.cpp +++ b/Engine/Source/Programs/UnrealHeaderTool/Private/HeaderParser.cpp @@ -214,8 +214,9 @@ namespace */ void ParseNetServiceIdentifiers(FFuncInfo& FuncInfo, const TArray& Identifiers) { - static const TCHAR IdTag [] = TEXT("Id"); - static const TCHAR ResponseIdTag[] = TEXT("ResponseId"); + static const TCHAR IdTag [] = TEXT("Id"); + static const TCHAR ResponseIdTag [] = TEXT("ResponseId"); + static const TCHAR JSBridgePriTag[] = TEXT("Priority"); for (const FString& Identifier : Identifiers) { @@ -234,7 +235,8 @@ namespace } FuncInfo.RPCId = TempInt; } - else if (FCString::Strnicmp(IdentifierPtr, ResponseIdTag, ARRAY_COUNT(ResponseIdTag) - 1) == 0) + else if (FCString::Strnicmp(IdentifierPtr, ResponseIdTag, ARRAY_COUNT(ResponseIdTag) - 1) == 0 || + FCString::Strnicmp(IdentifierPtr, JSBridgePriTag, ARRAY_COUNT(JSBridgePriTag) - 1) == 0) { int32 TempInt = FCString::Atoi(Equals + 1); if (TempInt <= 0 || TempInt > MAX_uint16) @@ -6875,7 +6877,7 @@ void FHeaderParser::CompileFunctionDeclaration(FClasses& AllClasses) } } - if (FuncInfo.RPCResponseId > 0) + if (FuncInfo.RPCResponseId > 0 && FuncInfo.EndpointName != TEXT("JSBridge")) { // Look for an existing response function FString* ExistingFunc = UsedRPCIds.Find(FuncInfo.RPCResponseId); diff --git a/Engine/Source/Programs/UnrealHeaderTool/Private/UnrealHeaderToolMain.cpp b/Engine/Source/Programs/UnrealHeaderTool/Private/UnrealHeaderToolMain.cpp index c776aa1c972f..c15f5dc9df4a 100644 --- a/Engine/Source/Programs/UnrealHeaderTool/Private/UnrealHeaderToolMain.cpp +++ b/Engine/Source/Programs/UnrealHeaderTool/Private/UnrealHeaderToolMain.cpp @@ -70,11 +70,13 @@ INT32_MAIN_INT32_ARGC_TCHAR_ARGV() ModuleInfoFilename = FParse::Token(CmdLinePtr, false ); } +#if !NO_LOGGING const static bool bVerbose = FParse::Param(*CmdLine,TEXT("VERBOSE")); if (bVerbose) { LogCompile.SetVerbosity(ELogVerbosity::Verbose); } +#endif // Make sure the engine is properly cleaned up whenever we exit this function ON_SCOPE_EXIT diff --git a/Engine/Source/Programs/UnrealPak/Private/UnrealPak.cpp b/Engine/Source/Programs/UnrealPak/Private/UnrealPak.cpp index 694bb551ab50..b110ea3f17ad 100644 --- a/Engine/Source/Programs/UnrealPak/Private/UnrealPak.cpp +++ b/Engine/Source/Programs/UnrealPak/Private/UnrealPak.cpp @@ -25,3 +25,4 @@ INT32_MAIN_INT32_ARGC_TCHAR_ARGV() return Result; } + diff --git a/Engine/Source/Runtime/Advertising/Android/AndroidAdvertising/AndroidAdvertising_APL.xml b/Engine/Source/Runtime/Advertising/Android/AndroidAdvertising/AndroidAdvertising_APL.xml index d65c1b9c2fc4..d612b252014e 100644 --- a/Engine/Source/Runtime/Advertising/Android/AndroidAdvertising/AndroidAdvertising_APL.xml +++ b/Engine/Source/Runtime/Advertising/Android/AndroidAdvertising/AndroidAdvertising_APL.xml @@ -340,6 +340,8 @@ import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info; } } + private GetAdvertisingIdTask AdTask = null; + private class GetAdvertisingIdTask extends android.os.AsyncTask { @Override @@ -371,6 +373,15 @@ import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info; public String AndroidThunkJava_GetAdvertisingId() { + try + { + AdTask.get(); + } + catch (Exception e) + { + advertisingID = null; + } + return advertisingID; } ]]> @@ -425,11 +436,8 @@ import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info; { if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == 0) { - GetAdvertisingIdTask task = new GetAdvertisingIdTask(); - task.execute(); - - // wait for up to 2 seconds (if we don't wait another plugin may request it and cause us to fail) - task.get(2000, java.util.concurrent.TimeUnit.MILLISECONDS); + AdTask = new GetAdvertisingIdTask(); + AdTask.execute(); } } catch (Exception e) diff --git a/Engine/Source/Runtime/Android/AndroidAudio/Private/AndroidAudioDevice.cpp b/Engine/Source/Runtime/Android/AndroidAudio/Private/AndroidAudioDevice.cpp index 1b20b26a1cdf..8a997c342f64 100644 --- a/Engine/Source/Runtime/Android/AndroidAudio/Private/AndroidAudioDevice.cpp +++ b/Engine/Source/Runtime/Android/AndroidAudio/Private/AndroidAudioDevice.cpp @@ -204,3 +204,27 @@ bool FSLESAudioDevice::IsExernalBackgroundSoundActive() #endif } + +FAndroidSoundBufferNotification& FAndroidSoundBufferNotification::Get() +{ + static FAndroidSoundBufferNotification Instance; + return Instance; +} + +FDelegateHandle FAndroidSoundBufferNotification::AddDelegate(const FOnAndroidSoundBufferEnqueued::FDelegate& InNewDelegate) +{ + FScopeLock Lock(&DelegateLock); + return InternalDelegate.Add(InNewDelegate); +} + +void FAndroidSoundBufferNotification::RemoveDelegate(const FDelegateHandle& Handle) +{ + FScopeLock Lock(&DelegateLock); + InternalDelegate.Remove(Handle); +} + +void FAndroidSoundBufferNotification::Broadcast(const void* AudioData, int32 DataSize, int32 SampleRate, int32 NumChannels) +{ + FScopeLock Lock(&DelegateLock); + InternalDelegate.Broadcast(AudioData, DataSize, SampleRate, NumChannels); +} diff --git a/Engine/Source/Runtime/Android/AndroidAudio/Private/AndroidAudioSource.cpp b/Engine/Source/Runtime/Android/AndroidAudio/Private/AndroidAudioSource.cpp index 2d4a266e1d75..ab941309aad7 100644 --- a/Engine/Source/Runtime/Android/AndroidAudio/Private/AndroidAudioSource.cpp +++ b/Engine/Source/Runtime/Android/AndroidAudio/Private/AndroidAudioSource.cpp @@ -18,8 +18,6 @@ static double GLastRealizeErrorTimeSec = 0.0; int32 GCVarAndroidRealizeErrorWaitThresholdMs = 35; TAutoConsoleVariable CVarAndroidRealizeErrorWaitThresholdMs(TEXT("au.AndroidRealizeErrorWaitThresholdMs"), GCVarAndroidRealizeErrorWaitThresholdMs, TEXT("Sets number of ms to wait before allowing new player request after realize buffer error (default: 35)"), ECVF_Default); - - // Callback that is registered if the source needs to loop void OpenSLBufferQueueCallback( SLAndroidSimpleBufferQueueItf InQueueInterface, void* pContext ) { @@ -36,10 +34,14 @@ void FSLESSoundSource::OnRequeueBufferCallback( SLAndroidSimpleBufferQueueItf In if (!bStreamedSound) { SLresult result = (*SL_PlayerBufferQueue)->Enqueue(SL_PlayerBufferQueue, SLESBuffer->AudioData, SLESBuffer->GetSize() ); - if(result != SL_RESULT_SUCCESS) + if (result != SL_RESULT_SUCCESS) { UE_LOG( LogAndroidAudio, Warning, TEXT("FAILED OPENSL BUFFER Enqueue SL_PlayerBufferQueue (Requeing)")); } + else + { + NotifySoundBufferEnqueued(SLESBuffer->AudioData, SLESBuffer->GetSize()); + } bHasLooped = true; } else @@ -74,11 +76,15 @@ void FSLESSoundSource::OnRequeueBufferCallback( SLAndroidSimpleBufferQueueItf In } SLresult result = (*SL_PlayerBufferQueue)->Enqueue(SL_PlayerBufferQueue, AudioBuffers[BufferInUse].AudioData, AudioBuffers[BufferInUse].AudioDataSize ); - if(result != SL_RESULT_SUCCESS) + if (result != SL_RESULT_SUCCESS) { UE_LOG( LogAndroidAudio, Warning, TEXT("FAILED OPENSL BUFFER Enqueue SL_PlayerBufferQueue (Requeing)")); } - + else + { + NotifySoundBufferEnqueued(AudioBuffers[BufferInUse].AudioData, AudioBuffers[BufferInUse].AudioDataSize); + } + // Switch to the next buffer and decode for the next time the callback fires if we didn't just get the last buffer BufferInUse = !BufferInUse; if (bHasLooped == false || WaveInstance->LoopingMode != LOOP_Never) @@ -93,6 +99,14 @@ void FSLESSoundSource::OnRequeueBufferCallback( SLAndroidSimpleBufferQueueItf In } } +void FSLESSoundSource::NotifySoundBufferEnqueued(const void* Data, int32 DataSize) const +{ + if (SLESBuffer) + { + FAndroidSoundBufferNotification::Get().Broadcast(Data, DataSize, SLESBuffer->SampleRate, SLESBuffer->NumChannels); + } +} + bool FSLESSoundSource::CreatePlayer() { if (GTrackCount >= 12) @@ -207,7 +221,9 @@ bool FSLESSoundSource::EnqueuePCMBuffer( bool bLoop) } return false; } - + + NotifySoundBufferEnqueued(SLESBuffer->AudioData, SLESBuffer->GetSize()); + bStreamedSound = false; bHasLooped = false; bHasPositionUpdated = false; @@ -293,6 +309,8 @@ bool FSLESSoundSource::EnqueuePCMRTBuffer( bool bLoop ) { result = (*SL_PlayerBufferQueue)->Enqueue(SL_PlayerBufferQueue, AudioBuffers[0].AudioData, AudioBuffers[0].AudioDataSize ); if (result != SL_RESULT_SUCCESS) { UE_LOG(LogAndroidAudio, Warning, TEXT("FAILED OPENSL BUFFER Enqueue SL_PlayerBufferQueue 0x%x params( %p, %d)"), result, SLESBuffer->AudioData, int32(SLESBuffer->GetSize())); return false; } + + NotifySoundBufferEnqueued(AudioBuffers[0].AudioData, AudioBuffers[0].AudioDataSize); } else { diff --git a/Engine/Source/Runtime/Android/AndroidAudio/Public/AndroidAudioDevice.h b/Engine/Source/Runtime/Android/AndroidAudio/Public/AndroidAudioDevice.h index a14d4f26db40..a736a9920e29 100644 --- a/Engine/Source/Runtime/Android/AndroidAudio/Public/AndroidAudioDevice.h +++ b/Engine/Source/Runtime/Android/AndroidAudio/Public/AndroidAudioDevice.h @@ -223,8 +223,7 @@ public: * */ void OnRequeueBufferCallback( SLAndroidSimpleBufferQueueItf InQueueInterface ); - - + protected: enum class EDataReadMode : uint8 @@ -270,6 +269,8 @@ protected: /** Decompress through FSLESSoundBuffer, or call USoundWave procedure to generate more PCM data. Returns true/false: did audio loop? */ bool ReadMorePCMData( const int32 BufferIndex, EDataReadMode DataReadMode ); + + void NotifySoundBufferEnqueued(const void* Data, int32 DataSize) const; }; /** @@ -353,3 +354,28 @@ protected: friend class FSLESSoundBuffer; friend class FSLESSoundSource; }; + +DECLARE_MULTICAST_DELEGATE_FourParams(FOnAndroidSoundBufferEnqueued, + const void* /**Data*/, + int32 /**Data Size*/, + int32 /**Sample Rate*/, + int32 /**Num Channels*/); + +/** + Thread-safe wrapper on top of FOnAndroidSoundBufferEnqueued + */ +class FAndroidSoundBufferNotification +{ +public: + static FAndroidSoundBufferNotification& Get(); + + FDelegateHandle AddDelegate(const FOnAndroidSoundBufferEnqueued::FDelegate& InNewDelegate); + + void RemoveDelegate(const FDelegateHandle& Handle); + + void Broadcast(const void* AudioData, int32 DataSize, int32 SampleRate, int32 NumChannels); + +private: + FCriticalSection DelegateLock; + FOnAndroidSoundBufferEnqueued InternalDelegate; +}; diff --git a/Engine/Source/Runtime/Android/AndroidLocalNotification/Private/AndroidLocalNotification.cpp b/Engine/Source/Runtime/Android/AndroidLocalNotification/Private/AndroidLocalNotification.cpp index 507c1a9bb6ff..bb0e6833d8d7 100644 --- a/Engine/Source/Runtime/Android/AndroidLocalNotification/Private/AndroidLocalNotification.cpp +++ b/Engine/Source/Runtime/Android/AndroidLocalNotification/Private/AndroidLocalNotification.cpp @@ -35,11 +35,7 @@ public: #if PLATFORM_ANDROID JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeAppOpenedWithLocalNotification(JNIEnv* jenv, jobject thiz, jstring jactivationEvent, int32 jFireDate) { - - FString ActivationEvent; - const char* ActivationEventChars = jenv->GetStringUTFChars(jactivationEvent, 0); - ActivationEvent = FString(UTF8_TO_TCHAR(ActivationEventChars)); - jenv->ReleaseStringUTFChars(jactivationEvent, ActivationEventChars); + auto ActivationEvent = FJavaHelper::FStringFromParam(jenv, jactivationEvent); int32 FireDate = (int32)jFireDate; diff --git a/Engine/Source/Runtime/Android/AudioMixerAndroid/AudioMixerAndroid.Build.cs b/Engine/Source/Runtime/Android/AudioMixerAndroid/AudioMixerAndroid.Build.cs index 1bf6496ac614..ddaa50f26a55 100644 --- a/Engine/Source/Runtime/Android/AudioMixerAndroid/AudioMixerAndroid.Build.cs +++ b/Engine/Source/Runtime/Android/AudioMixerAndroid/AudioMixerAndroid.Build.cs @@ -15,12 +15,11 @@ public class AudioMixerAndroid : ModuleRules "Core", "CoreUObject", "Engine", + "AudioMixer", } ); - - PrivateDependencyModuleNames.Add("AudioMixer"); - - AddEngineThirdPartyPrivateStaticDependencies(Target, + + AddEngineThirdPartyPrivateStaticDependencies(Target, "UEOgg", "Vorbis", "VorbisFile" diff --git a/Engine/Source/Runtime/Android/AudioMixerAndroid/Private/AudioMixerPlatformAndroid.cpp b/Engine/Source/Runtime/Android/AudioMixerAndroid/Private/AudioMixerPlatformAndroid.cpp index d3b4d519bcfb..0493287a69dc 100644 --- a/Engine/Source/Runtime/Android/AudioMixerAndroid/Private/AudioMixerPlatformAndroid.cpp +++ b/Engine/Source/Runtime/Android/AudioMixerAndroid/Private/AudioMixerPlatformAndroid.cpp @@ -368,10 +368,11 @@ namespace Audio void FMixerPlatformAndroid::SubmitBuffer(const uint8* Buffer) { - SLresult Result = (*SL_PlayerBufferQueue)->Enqueue(SL_PlayerBufferQueue, Buffer, AudioStreamInfo.NumOutputFrames * AudioStreamInfo.DeviceInfo.NumChannels * sizeof(int16)); + const auto BufferSize = AudioStreamInfo.NumOutputFrames * AudioStreamInfo.DeviceInfo.NumChannels * sizeof(int16); + SLresult Result = (*SL_PlayerBufferQueue)->Enqueue(SL_PlayerBufferQueue, Buffer, BufferSize); OPENSLES_LOG_ON_FAIL(Result); } - + FName FMixerPlatformAndroid::GetRuntimeFormat(USoundWave* InSoundWave) { #if WITH_OGGVORBIS diff --git a/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalPipeline.cpp b/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalPipeline.cpp index fdc9626f6585..af64a84694da 100644 --- a/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalPipeline.cpp +++ b/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalPipeline.cpp @@ -537,6 +537,7 @@ static FMetalShaderPipeline* CreateMTLRenderPipeline(bool const bSync, FMetalGra ns::Array ColorAttachments = RenderPipelineDesc.GetColorAttachments(); + uint32 TargetWidth = 0; for (uint32 i = 0; i < NumActiveTargets; i++) { EPixelFormat TargetFormat = (EPixelFormat)Init.RenderTargetFormats[i]; @@ -545,6 +546,7 @@ static FMetalShaderPipeline* CreateMTLRenderPipeline(bool const bSync, FMetalGra UE_LOG(LogMetal, Fatal, TEXT("Pipeline pixel shader expects target %u to be bound but it isn't: %s."), i, *FString(PixelShader->GetSourceCode())); continue; } + TargetWidth += GPixelFormats[TargetFormat].BlockBytes; mtlpp::PixelFormat MetalFormat = (mtlpp::PixelFormat)GPixelFormats[TargetFormat].PlatformFormat; uint32 Flags = Init.RenderTargetFlags[i]; @@ -581,6 +583,12 @@ static FMetalShaderPipeline* CreateMTLRenderPipeline(bool const bSync, FMetalGra Attachment.SetWriteMask(mtlpp::ColorWriteMask::None); } } + + // don't allow a PSO that is too wide + if (!GSupportsWideMRT && TargetWidth > 16) + { + return nil; + } switch(Init.DepthStencilTargetFormat) { diff --git a/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalRenderTarget.cpp b/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalRenderTarget.cpp index 7c534a0484ba..09fb7fc8a99f 100644 --- a/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalRenderTarget.cpp +++ b/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalRenderTarget.cpp @@ -331,13 +331,21 @@ static void ConvertSurfaceDataToFColor(EPixelFormat Format, uint32 Width, uint32 } else if(Format == PF_B8G8R8A8) { - for(uint32 Y = 0; Y < Height; Y++) + const auto DestPitch = sizeof(FColor) * Width; + if (SrcPitch == DestPitch) { - FColor* SrcPtr = (FColor*)(In + Y * SrcPitch); - FColor* DestPtr = Out + Y * Width; - - // Need to copy row wise since the Pitch might not match the Width. - FMemory::Memcpy(DestPtr, SrcPtr, sizeof(FColor) * Width); + FMemory::Memcpy(Out, In, DestPitch * Height); + } + else + { + for(uint32 Y = 0; Y < Height; Y++) + { + FColor* SrcPtr = (FColor*)(In + Y * SrcPitch); + FColor* DestPtr = Out + Y * Width; + + // Need to copy row wise since the Pitch might not match the Width. + FMemory::Memcpy(DestPtr, SrcPtr, sizeof(FColor) * Width); + } } } else if(Format == PF_A2B10G10R10) diff --git a/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalViewport.cpp b/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalViewport.cpp index 6b7c748bf1d0..d1f6ca0bbb3f 100644 --- a/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalViewport.cpp +++ b/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalViewport.cpp @@ -226,12 +226,6 @@ void FMetalViewport::Resize(uint32 InSizeX, uint32 InSizeY, bool bInIsFullscreen } [IOSView UpdateRenderWidth:InSizeX andHeight:InSizeY]; - - // check the size of the window - float ScalingFactor = [IOSView contentScaleFactor]; - CGRect ViewFrame = [IOSView frame]; - check(FMath::TruncToInt(ScalingFactor * ViewFrame.size.width) == InSizeX && - FMath::TruncToInt(ScalingFactor * ViewFrame.size.height) == InSizeY); } #endif diff --git a/Engine/Source/Runtime/ApplicationCore/ApplicationCore.Build.cs b/Engine/Source/Runtime/ApplicationCore/ApplicationCore.Build.cs index cacb78a07457..e7187e100902 100644 --- a/Engine/Source/Runtime/ApplicationCore/ApplicationCore.Build.cs +++ b/Engine/Source/Runtime/ApplicationCore/ApplicationCore.Build.cs @@ -72,8 +72,10 @@ public class ApplicationCore : ModuleRules { PublicIncludePaths.AddRange(new string[] {"Runtime/ApplicationCore/Public/IOS"}); AddEngineThirdPartyPrivateStaticDependencies(Target, "SoundSwitch"); - } + // export ApplicationCore symbols for embedded Dlls + ModuleSymbolVisibility = ModuleRules.SymbolVisibility.VisibileForDll; + } if (!Target.bCompileAgainstApplicationCore) { throw new System.Exception("ApplicationCore cannot be used when Target.bCompileAgainstApplicationCore = false."); diff --git a/Engine/Source/Runtime/ApplicationCore/Private/Android/AndroidApplication.cpp b/Engine/Source/Runtime/ApplicationCore/Private/Android/AndroidApplication.cpp index da202c898f0f..b8ef1e3dc00d 100644 --- a/Engine/Source/Runtime/ApplicationCore/Private/Android/AndroidApplication.cpp +++ b/Engine/Source/Runtime/ApplicationCore/Private/Android/AndroidApplication.cpp @@ -7,6 +7,8 @@ #include "IInputDeviceModule.h" #include "HAL/OutputDevices.h" #include "Misc/AssertionMacros.h" +#include "Android/AndroidMisc.h" +#include "Misc/CoreDelegates.h" DEFINE_LOG_CATEGORY_STATIC(LogAndroidApplication, Log, All); @@ -91,6 +93,50 @@ void FAndroidApplication::PollGameDeviceState( const float TimeDelta ) bWindowSizeChanged = false; } + + HandleDeviceOrientation(); +} + +void FAndroidApplication::HandleDeviceOrientation() +{ + JNIEnv* JEnv = AndroidJavaEnv::GetJavaEnv(); + if (JEnv) + { + static jmethodID getOrientationMethod = 0; + const auto PreviousDeviceOrientation = DeviceOrientation; + + if (getOrientationMethod == 0) + { + jclass MainClass = AndroidJavaEnv::FindJavaClassGlobalRef("com/epicgames/ue4/GameActivity"); + if (MainClass != nullptr) + { + getOrientationMethod = JEnv->GetMethodID(MainClass, "AndroidThunkJava_GetDeviceOrientation", "()I"); + JEnv->DeleteGlobalRef(MainClass); + } + } + + if (getOrientationMethod != 0) + { + const int Orientation = JEnv->CallIntMethod(AndroidJavaEnv::GetGameActivityThis(), getOrientationMethod); + switch (Orientation) + { + case 0: DeviceOrientation = EDeviceScreenOrientation::Portrait; break; + case 1: DeviceOrientation = EDeviceScreenOrientation::LandscapeLeft; break; + case 2: DeviceOrientation = EDeviceScreenOrientation::PortraitUpsideDown; break; + case 3: DeviceOrientation = EDeviceScreenOrientation::LandscapeRight; break; + } + } + + FAndroidMisc::SetDeviceOrientation(DeviceOrientation); + + if (PreviousDeviceOrientation != DeviceOrientation) + { + FCoreDelegates::ApplicationReceivedScreenOrientationChangedNotificationDelegate.Broadcast((int32)DeviceOrientation); + + //we also want to fire off the safe frame event + FCoreDelegates::OnSafeFrameChangedEvent.Broadcast(); + } + } } FPlatformRect FAndroidApplication::GetWorkArea( const FPlatformRect& CurrentWindow ) const diff --git a/Engine/Source/Runtime/ApplicationCore/Private/Android/AndroidJavaMediaPlayer.cpp b/Engine/Source/Runtime/ApplicationCore/Private/Android/AndroidJavaMediaPlayer.cpp index 9a4bd36d1170..69e7cd40c795 100644 --- a/Engine/Source/Runtime/ApplicationCore/Private/Android/AndroidJavaMediaPlayer.cpp +++ b/Engine/Source/Runtime/ApplicationCore/Private/Android/AndroidJavaMediaPlayer.cpp @@ -171,9 +171,7 @@ FJavaAndroidMediaPlayer::FJavaAndroidMediaPlayer(bool swizzlePixels, bool vulkan JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); // get field IDs for FrameUpdateInfo class members - jclass localFrameUpdateInfoClass = FAndroidApplication::FindJavaClass("com/epicgames/ue4/MediaPlayer14$FrameUpdateInfo"); - FrameUpdateInfoClass = (jclass)JEnv->NewGlobalRef(localFrameUpdateInfoClass); - JEnv->DeleteLocalRef(localFrameUpdateInfoClass); + FrameUpdateInfoClass = FAndroidApplication::FindJavaClassGlobalRef("com/epicgames/ue4/MediaPlayer14$FrameUpdateInfo"); FrameUpdateInfo_CurrentPosition = FindField(JEnv, FrameUpdateInfoClass, "CurrentPosition", "I", false); FrameUpdateInfo_FrameReady = FindField(JEnv, FrameUpdateInfoClass, "FrameReady", "Z", false); FrameUpdateInfo_RegionChanged = FindField(JEnv, FrameUpdateInfoClass, "RegionChanged", "Z", false); @@ -183,9 +181,7 @@ FJavaAndroidMediaPlayer::FJavaAndroidMediaPlayer(bool swizzlePixels, bool vulkan FrameUpdateInfo_VOffset = FindField(JEnv, FrameUpdateInfoClass, "VOffset", "F", false); // get field IDs for AudioTrackInfo class members - jclass localAudioTrackInfoClass = FAndroidApplication::FindJavaClass("com/epicgames/ue4/MediaPlayer14$AudioTrackInfo"); - AudioTrackInfoClass = (jclass)JEnv->NewGlobalRef(localAudioTrackInfoClass); - JEnv->DeleteLocalRef(localAudioTrackInfoClass); + AudioTrackInfoClass = FAndroidApplication::FindJavaClassGlobalRef("com/epicgames/ue4/MediaPlayer14$AudioTrackInfo"); AudioTrackInfo_Index = FindField(JEnv, AudioTrackInfoClass, "Index", "I", false); AudioTrackInfo_MimeType = FindField(JEnv, AudioTrackInfoClass, "MimeType", "Ljava/lang/String;", false); AudioTrackInfo_DisplayName = FindField(JEnv, AudioTrackInfoClass, "DisplayName", "Ljava/lang/String;", false); @@ -194,18 +190,14 @@ FJavaAndroidMediaPlayer::FJavaAndroidMediaPlayer(bool swizzlePixels, bool vulkan AudioTrackInfo_SampleRate = FindField(JEnv, AudioTrackInfoClass, "SampleRate", "I", false); // get field IDs for CaptionTrackInfo class members - jclass localCaptionTrackInfoClass = FAndroidApplication::FindJavaClass("com/epicgames/ue4/MediaPlayer14$CaptionTrackInfo"); - CaptionTrackInfoClass = (jclass)JEnv->NewGlobalRef(localCaptionTrackInfoClass); - JEnv->DeleteLocalRef(localCaptionTrackInfoClass); + CaptionTrackInfoClass = FAndroidApplication::FindJavaClassGlobalRef("com/epicgames/ue4/MediaPlayer14$CaptionTrackInfo"); CaptionTrackInfo_Index = FindField(JEnv, CaptionTrackInfoClass, "Index", "I", false); CaptionTrackInfo_MimeType = FindField(JEnv, CaptionTrackInfoClass, "MimeType", "Ljava/lang/String;", false); CaptionTrackInfo_DisplayName = FindField(JEnv, CaptionTrackInfoClass, "DisplayName", "Ljava/lang/String;", false); CaptionTrackInfo_Language = FindField(JEnv, CaptionTrackInfoClass, "Language", "Ljava/lang/String;", false); // get field IDs for VideoTrackInfo class members - jclass localVideoTrackInfoClass = FAndroidApplication::FindJavaClass("com/epicgames/ue4/MediaPlayer14$VideoTrackInfo"); - VideoTrackInfoClass = (jclass)JEnv->NewGlobalRef(localVideoTrackInfoClass); - JEnv->DeleteLocalRef(localVideoTrackInfoClass); + VideoTrackInfoClass = FAndroidApplication::FindJavaClassGlobalRef("com/epicgames/ue4/MediaPlayer14$VideoTrackInfo"); VideoTrackInfo_Index = FindField(JEnv, VideoTrackInfoClass, "Index", "I", false); VideoTrackInfo_MimeType = FindField(JEnv, VideoTrackInfoClass, "MimeType", "Ljava/lang/String;", false); VideoTrackInfo_DisplayName = FindField(JEnv, VideoTrackInfoClass, "DisplayName", "Ljava/lang/String;", false); @@ -216,6 +208,17 @@ FJavaAndroidMediaPlayer::FJavaAndroidMediaPlayer(bool swizzlePixels, bool vulkan VideoTrackInfo_FrameRate = FindField(JEnv, VideoTrackInfoClass, "FrameRate", "F", false); } +FJavaAndroidMediaPlayer::~FJavaAndroidMediaPlayer() +{ + if (auto Env = FAndroidApplication::GetJavaEnv()) + { + Env->DeleteGlobalRef(FrameUpdateInfoClass); + Env->DeleteGlobalRef(AudioTrackInfoClass); + Env->DeleteGlobalRef(CaptionTrackInfoClass); + Env->DeleteGlobalRef(VideoTrackInfoClass); + } +} + int32 FJavaAndroidMediaPlayer::GetDuration() { return CallMethod(GetDurationMethod); @@ -271,7 +274,7 @@ bool FJavaAndroidMediaPlayer::SetDataSource(const FString & Url) { UScale = VScale = 1.0f; UOffset = VOffset = 0.0f; - return CallMethod(SetDataSourceURLMethod, GetJString(Url)); + return CallMethod(SetDataSourceURLMethod, *GetJString(Url)); } bool FJavaAndroidMediaPlayer::SetDataSource(const TSharedRef& Archive) @@ -289,14 +292,14 @@ bool FJavaAndroidMediaPlayer::SetDataSource(const FString& MoviePathOnDevice, in { UScale = VScale = 1.0f; UOffset = VOffset = 0.0f; - return CallMethod(SetDataSourceFileMethod, GetJString(MoviePathOnDevice), offset, size); + return CallMethod(SetDataSourceFileMethod, *GetJString(MoviePathOnDevice), offset, size); } bool FJavaAndroidMediaPlayer::SetDataSource(jobject AssetMgr, const FString& AssetPath, int64 offset, int64 size) { UScale = VScale = 1.0f; UOffset = VOffset = 0.0f; - return CallMethod(SetDataSourceAssetMethod, AssetMgr, GetJString(AssetPath), offset, size); + return CallMethod(SetDataSourceAssetMethod, AssetMgr, *GetJString(AssetPath), offset, size); } bool FJavaAndroidMediaPlayer::Prepare() @@ -371,27 +374,21 @@ bool FJavaAndroidMediaPlayer::GetVideoLastFrameData(void* & outPixels, int64 & o { // This can return an exception in some cases JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); - jobject buffer = JEnv->CallObjectMethod(Object, GetVideoLastFrameDataMethod.Method); + auto buffer = NewScopedJavaObject(JEnv, JEnv->CallObjectMethod(Object, GetVideoLastFrameDataMethod.Method)); if (JEnv->ExceptionCheck()) { JEnv->ExceptionDescribe(); JEnv->ExceptionClear(); - if (nullptr != buffer) - { - // the CallObjectMethod returns a local ref, but Java will still own the real buffer - JEnv->DeleteLocalRef(buffer); - } return false; } - if (nullptr != buffer) + + if (buffer) { - outPixels = JEnv->GetDirectBufferAddress(buffer); - outCount = JEnv->GetDirectBufferCapacity(buffer); - - // the CallObjectMethod returns a local ref, but Java will still own the real buffer - JEnv->DeleteLocalRef(buffer); + outPixels = JEnv->GetDirectBufferAddress(*buffer); + outCount = JEnv->GetDirectBufferCapacity(*buffer); } - if (nullptr == buffer || nullptr == outPixels || 0 == outCount) + + if (!buffer || nullptr == outPixels || 0 == outCount) { return false; } @@ -422,37 +419,31 @@ bool FJavaAndroidMediaPlayer::UpdateVideoFrame(int32 ExternalTextureId, int32 *C { // This can return an exception in some cases JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); - jobject Result = JEnv->CallObjectMethod(Object, UpdateVideoFrameMethod.Method, ExternalTextureId); + auto Result = NewScopedJavaObject(JEnv, JEnv->CallObjectMethod(Object, UpdateVideoFrameMethod.Method, ExternalTextureId)); if (JEnv->ExceptionCheck()) { JEnv->ExceptionDescribe(); JEnv->ExceptionClear(); - if (nullptr != Result) - { - JEnv->DeleteLocalRef(Result); - } *CurrentPosition = -1; *bRegionChanged = false; return false; } - if (nullptr == Result) + if (!Result) { *CurrentPosition = -1; *bRegionChanged = false; return false; } - *CurrentPosition = (int32)JEnv->GetIntField(Result, FrameUpdateInfo_CurrentPosition); - bool bFrameReady = (bool)JEnv->GetBooleanField(Result, FrameUpdateInfo_FrameReady); - *bRegionChanged = (bool)JEnv->GetBooleanField(Result, FrameUpdateInfo_RegionChanged); - UScale = (float)JEnv->GetFloatField(Result, FrameUpdateInfo_UScale); - UOffset = (float)JEnv->GetFloatField(Result, FrameUpdateInfo_UOffset); - VScale = (float)JEnv->GetFloatField(Result, FrameUpdateInfo_VScale); - VOffset = (float)JEnv->GetFloatField(Result, FrameUpdateInfo_VOffset); - - JEnv->DeleteLocalRef(Result); - + *CurrentPosition = (int32)JEnv->GetIntField(*Result, FrameUpdateInfo_CurrentPosition); + bool bFrameReady = (bool)JEnv->GetBooleanField(*Result, FrameUpdateInfo_FrameReady); + *bRegionChanged = (bool)JEnv->GetBooleanField(*Result, FrameUpdateInfo_RegionChanged); + UScale = (float)JEnv->GetFloatField(*Result, FrameUpdateInfo_UScale); + UOffset = (float)JEnv->GetFloatField(*Result, FrameUpdateInfo_UOffset); + VScale = (float)JEnv->GetFloatField(*Result, FrameUpdateInfo_VScale); + VOffset = (float)JEnv->GetFloatField(*Result, FrameUpdateInfo_VOffset); + return bFrameReady; } @@ -515,38 +506,19 @@ bool FJavaAndroidMediaPlayer::GetAudioTracks(TArray& AudioTracks) for (int Index = 0; Index < ElementCount; ++Index) { - jobject Track = JEnv->GetObjectArrayElement(TrackArray, Index); + auto Track = NewScopedJavaObject(JEnv, JEnv->GetObjectArrayElement(TrackArray, Index)); int32 AudioTrackIndex = AudioTracks.AddDefaulted(); FAudioTrack& AudioTrack = AudioTracks[AudioTrackIndex]; - AudioTrack.Index = (int32)JEnv->GetIntField(Track, AudioTrackInfo_Index); + AudioTrack.Index = (int32)JEnv->GetIntField(*Track, AudioTrackInfo_Index); - jstring jsMimeType = (jstring)JEnv->GetObjectField(Track, AudioTrackInfo_MimeType); - CHECK_JNI_RESULT(jsMimeType); - const char * nativeMimeType = JEnv->GetStringUTFChars(jsMimeType, 0); - AudioTrack.MimeType = FString(nativeMimeType); - JEnv->ReleaseStringUTFChars(jsMimeType, nativeMimeType); - JEnv->DeleteLocalRef(jsMimeType); - - jstring jsDisplayName = (jstring)JEnv->GetObjectField(Track, AudioTrackInfo_DisplayName); - CHECK_JNI_RESULT(jsDisplayName); - const char * nativeDisplayName = JEnv->GetStringUTFChars(jsDisplayName, 0); - AudioTrack.DisplayName = FString(nativeDisplayName); - JEnv->ReleaseStringUTFChars(jsDisplayName, nativeDisplayName); - JEnv->DeleteLocalRef(jsDisplayName); - - jstring jsLanguage = (jstring)JEnv->GetObjectField(Track, AudioTrackInfo_Language); - CHECK_JNI_RESULT(jsLanguage); - const char * nativeLanguage = JEnv->GetStringUTFChars(jsLanguage, 0); - AudioTrack.Language = FString(nativeLanguage); - JEnv->ReleaseStringUTFChars(jsLanguage, nativeLanguage); - JEnv->DeleteLocalRef(jsLanguage); - - AudioTrack.Channels = (int32)JEnv->GetIntField(Track, AudioTrackInfo_Channels); - AudioTrack.SampleRate = (int32)JEnv->GetIntField(Track, AudioTrackInfo_SampleRate); - - JEnv->DeleteLocalRef(Track); + AudioTrack.MimeType = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, AudioTrackInfo_MimeType)); + AudioTrack.DisplayName = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, AudioTrackInfo_DisplayName)); + AudioTrack.Language = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, AudioTrackInfo_Language)); + + AudioTrack.Channels = (int32)JEnv->GetIntField(*Track, AudioTrackInfo_Channels); + AudioTrack.SampleRate = (int32)JEnv->GetIntField(*Track, AudioTrackInfo_SampleRate); } JEnv->DeleteGlobalRef(TrackArray); @@ -568,35 +540,16 @@ bool FJavaAndroidMediaPlayer::GetCaptionTracks(TArray& CaptionTra for (int Index = 0; Index < ElementCount; ++Index) { - jobject Track = JEnv->GetObjectArrayElement(TrackArray, Index); + auto Track = NewScopedJavaObject(JEnv, JEnv->GetObjectArrayElement(TrackArray, Index)); int32 CaptionTrackIndex = CaptionTracks.AddDefaulted(); FCaptionTrack& CaptionTrack = CaptionTracks[CaptionTrackIndex]; - CaptionTrack.Index = (int32)JEnv->GetIntField(Track, CaptionTrackInfo_Index); + CaptionTrack.Index = (int32)JEnv->GetIntField(*Track, CaptionTrackInfo_Index); - jstring jsMimeType = (jstring)JEnv->GetObjectField(Track, CaptionTrackInfo_MimeType); - CHECK_JNI_RESULT(jsMimeType); - const char * nativeMimeType = JEnv->GetStringUTFChars(jsMimeType, 0); - CaptionTrack.MimeType = FString(nativeMimeType); - JEnv->ReleaseStringUTFChars(jsMimeType, nativeMimeType); - JEnv->DeleteLocalRef(jsMimeType); - - jstring jsDisplayName = (jstring)JEnv->GetObjectField(Track, CaptionTrackInfo_DisplayName); - CHECK_JNI_RESULT(jsDisplayName); - const char * nativeDisplayName = JEnv->GetStringUTFChars(jsDisplayName, 0); - CaptionTrack.DisplayName = FString(nativeDisplayName); - JEnv->ReleaseStringUTFChars(jsDisplayName, nativeDisplayName); - JEnv->DeleteLocalRef(jsDisplayName); - - jstring jsLanguage = (jstring)JEnv->GetObjectField(Track, CaptionTrackInfo_Language); - CHECK_JNI_RESULT(jsLanguage); - const char * nativeLanguage = JEnv->GetStringUTFChars(jsLanguage, 0); - CaptionTrack.Language = FString(nativeLanguage); - JEnv->ReleaseStringUTFChars(jsLanguage, nativeLanguage); - JEnv->DeleteLocalRef(jsLanguage); - - JEnv->DeleteLocalRef(Track); + CaptionTrack.MimeType = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, CaptionTrackInfo_MimeType)); + CaptionTrack.DisplayName = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, CaptionTrackInfo_DisplayName)); + CaptionTrack.Language = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, CaptionTrackInfo_Language)); } JEnv->DeleteGlobalRef(TrackArray); @@ -618,39 +571,20 @@ bool FJavaAndroidMediaPlayer::GetVideoTracks(TArray& VideoTracks) for (int Index = 0; Index < ElementCount; ++Index) { - jobject Track = JEnv->GetObjectArrayElement(TrackArray, Index); + auto Track = NewScopedJavaObject(JEnv, JEnv->GetObjectArrayElement(TrackArray, Index)); int32 VideoTrackIndex = VideoTracks.AddDefaulted(); FVideoTrack& VideoTrack = VideoTracks[VideoTrackIndex]; - VideoTrack.Index = (int32)JEnv->GetIntField(Track, VideoTrackInfo_Index); + VideoTrack.Index = (int32)JEnv->GetIntField(*Track, VideoTrackInfo_Index); - jstring jsMimeType = (jstring)JEnv->GetObjectField(Track, VideoTrackInfo_MimeType); - CHECK_JNI_RESULT(jsMimeType); - const char * nativeMimeType = JEnv->GetStringUTFChars(jsMimeType, 0); - VideoTrack.MimeType = FString(nativeMimeType); - JEnv->ReleaseStringUTFChars(jsMimeType, nativeMimeType); - JEnv->DeleteLocalRef(jsMimeType); + VideoTrack.MimeType = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, VideoTrackInfo_MimeType)); + VideoTrack.DisplayName = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, VideoTrackInfo_DisplayName)); + VideoTrack.Language = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->GetObjectField(*Track, VideoTrackInfo_Language)); - jstring jsDisplayName = (jstring)JEnv->GetObjectField(Track, VideoTrackInfo_DisplayName); - CHECK_JNI_RESULT(jsDisplayName); - const char * nativeDisplayName = JEnv->GetStringUTFChars(jsDisplayName, 0); - VideoTrack.DisplayName = FString(nativeDisplayName); - JEnv->ReleaseStringUTFChars(jsDisplayName, nativeDisplayName); - JEnv->DeleteLocalRef(jsDisplayName); - - jstring jsLanguage = (jstring)JEnv->GetObjectField(Track, VideoTrackInfo_Language); - CHECK_JNI_RESULT(jsLanguage); - const char * nativeLanguage = JEnv->GetStringUTFChars(jsLanguage, 0); - VideoTrack.Language = FString(nativeLanguage); - JEnv->ReleaseStringUTFChars(jsLanguage, nativeLanguage); - JEnv->DeleteLocalRef(jsLanguage); - - VideoTrack.BitRate = (int32)JEnv->GetIntField(Track, VideoTrackInfo_BitRate); - VideoTrack.Dimensions = FIntPoint((int32)JEnv->GetIntField(Track, VideoTrackInfo_Width), (int32)JEnv->GetIntField(Track, VideoTrackInfo_Height)); - VideoTrack.FrameRate = JEnv->GetFloatField(Track, VideoTrackInfo_FrameRate); - - JEnv->DeleteLocalRef(Track); + VideoTrack.BitRate = (int32)JEnv->GetIntField(*Track, VideoTrackInfo_BitRate); + VideoTrack.Dimensions = FIntPoint((int32)JEnv->GetIntField(*Track, VideoTrackInfo_Width), (int32)JEnv->GetIntField(*Track, VideoTrackInfo_Height)); + VideoTrack.FrameRate = JEnv->GetFloatField(*Track, VideoTrackInfo_FrameRate); } JEnv->DeleteGlobalRef(TrackArray); diff --git a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSAppDelegate.cpp b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSAppDelegate.cpp index 1fac74de64ca..e9a4413e4d40 100644 --- a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSAppDelegate.cpp +++ b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSAppDelegate.cpp @@ -23,6 +23,7 @@ #include "Misc/FeedbackContext.h" #include "Misc/App.h" #include "Algo/AllOf.h" +#include "Misc/App.h" #if USE_MUTE_SWITCH_DETECTION #include "SharkfoodMuteSwitchDetector.h" #include "SharkfoodMuteSwitchDetector.m" @@ -53,6 +54,8 @@ extern bool GShowSplashScreen; FIOSCoreDelegates::FOnOpenURL FIOSCoreDelegates::OnOpenURL; TArray FIOSCoreDelegates::PushNotificationFilters; +static bool GEnabledAudioFeatures[(uint8)EAudioFeature::NumFeatures]; + /* From: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/#//apple_ref/occ/intfm/UIApplicationDelegate/applicationDidEnterBackground: "In practice, you should return from applicationDidEnterBackground: as quickly as possible. If the method does not return before time runs out your app is terminated and purged from memory." @@ -140,6 +143,12 @@ bool FIOSCoreDelegates::PassesPushNotificationFilters(NSDictionary* Payload) }); } +@interface IOSAppDelegate() + +// move private things from header to here + +@end + @implementation IOSAppDelegate #if !UE_BUILD_SHIPPING && !PLATFORM_TVOS @@ -160,16 +169,56 @@ bool FIOSCoreDelegates::PassesPushNotificationFilters(NSDictionary* Payload) @synthesize Window; @synthesize IOSView; -@synthesize IOSController; @synthesize SlateController; @synthesize timer; @synthesize IdleTimerEnableTimer; @synthesize IdleTimerEnablePeriod; @synthesize savedOpenUrlParameters; - @synthesize BackgroundSessionEventCompleteDelegate; + +static IOSAppDelegate* CachedDelegate = nil; + ++ (IOSAppDelegate*)GetDelegate +{ +#if BUILD_EMBEDDED_APP + if (CachedDelegate == nil) + { + UE_LOG(LogIOS, Fatal, TEXT("Currently, a native embedding UE4 must have the AppDelegate subclass from IOSAppDelegate.")); + + // if we are embedded, but CachedDelegate is nil, then that means the delegate was not an IOSAppDelegate subclass, + // so we need to do a switcheroo - but this is unlikely to work well +#if 0 // ALLOW_NATIVE_APP_DELEGATE + SCOPED_BOOT_TIMING("Delegate Switcheroo"); + + id ExistingDelegate = [UIApplication sharedApplication].delegate; + + CachedDelegate = [[IOSAppDelegate alloc] init]; + CachedDelegate.Window = ExistingDelegate.window; + + // @todo critical: The IOSAppDelegate needs to save the old delegate, override EVERY UIApplication function, and call the old delegate's functions for each one + [UIApplication sharedApplication].delegate = CachedDelegate; + + // we will have missd the didFinishLaunchingWithOptions call, so we need to call it now, but we don't have the original launchOptions, nothing we can do now! + [CachedDelegate application:[UIApplication sharedApplication] didFinishLaunchingWithOptions:nil]; +#endif + } +#endif + + return CachedDelegate; +} + +-(id)init +{ + self = [super init]; + CachedDelegate = self; + // default to old style + memset(GEnabledAudioFeatures, 0, sizeof(GEnabledAudioFeatures)); + return self; +} + + -(void)dealloc { #if !UE_BUILD_SHIPPING && !PLATFORM_TVOS @@ -183,61 +232,30 @@ bool FIOSCoreDelegates::PassesPushNotificationFilters(NSDictionary* Payload) #endif [Window release]; [IOSView release]; - [IOSController release]; [SlateController release]; [timer release]; [super dealloc]; } --(void) ParseCommandLineOverrides -{ - //// Check for device type override - //FString IOSDeviceName; - //if ( Parse( appCmdLine(), TEXT("-IOSDevice="), IOSDeviceName) ) - //{ - // for ( int32 DeviceTypeIndex = 0; DeviceTypeIndex < IOS_Unknown; ++DeviceTypeIndex ) - // { - // if ( IOSDeviceName == IPhoneGetDeviceTypeString( (EIOSDevice) DeviceTypeIndex) ) - // { - // GOverrideIOSDevice = (EIOSDevice) DeviceTypeIndex; - // } - // } - //} - - //// Check for iOS version override - //FLOAT IOSVersion = 0.0f; - //if ( Parse( appCmdLine(), TEXT("-IOSVersion="), IOSVersion) ) - //{ - // GOverrideIOSVersion = IOSVersion; - //} - - // check to see if we are using the network file system, if so, disable the idle timer - FString HostIP; -// if (FParse::Value(FCommandLine::Get(), TEXT("-FileHostIP="), HostIP)) - { - [UIApplication sharedApplication].idleTimerDisabled = YES; - } -} - -(void)MainAppThread:(NSDictionary*)launchOptions { - self.bHasStarted = true; - GIsGuarded = false; - GStartTime = FPlatformTime::Seconds(); - - // make sure this thread has an auto release pool setup + // make sure this thread has an auto release pool setup NSAutoreleasePool* AutoreleasePool = [[NSAutoreleasePool alloc] init]; - while(!self.bCommandLineReady) { - usleep(100); + SCOPED_BOOT_TIMING("[IOSAppDelegate MainAppThread setup]"); + + self.bHasStarted = true; + GIsGuarded = false; + GStartTime = FPlatformTime::Seconds(); + + + while(!self.bCommandLineReady) + { + usleep(100); + } } - - - // Look for overrides specified on the command-line - [self ParseCommandLineOverrides]; - FAppEntry::Init(); [self InitIdleTimerSettings]; @@ -339,15 +357,21 @@ bool FIOSCoreDelegates::PassesPushNotificationFilters(NSDictionary* Payload) FAppEntry::Shutdown(); self.bHasStarted = false; + + if(bForceExit) + { + _Exit(0); + //exit(0); // As far as I can tell we run into a lot of trouble trying to run static destructors, so this is a no go :( + } } -(void)timerForSplashScreen { if (!GShowSplashScreen) { - if ([self.Window viewWithTag:2] != nil) + if ([self.Window viewWithTag:200] != nil) { - [[self.Window viewWithTag:2] removeFromSuperview]; + [[self.Window viewWithTag:200] removeFromSuperview]; } [timer invalidate]; } @@ -423,7 +447,7 @@ bool FIOSCoreDelegates::PassesPushNotificationFilters(NSDictionary* Payload) self.bAudioActive = false; FAppEntry::Suspend(true); break; - + case AVAudioSessionInterruptionTypeEnded: FAppEntry::Resume(true); [self ToggleAudioSession:true force:true]; @@ -472,7 +496,79 @@ bool FIOSCoreDelegates::PassesPushNotificationFilters(NSDictionary* Payload) - (void)ToggleAudioSession:(bool)bActive force:(bool)bForce { - if (bActive) + // @todo kairos: resolve old vs new before we go to main + if (true) + { + // we can actually override bActive based on backgrounding behavior, as that's the only time we actually deactivate the session + // @todo kairos: is this a valid check? + bool bIsBackground = GIsSuspended; + bActive = !bIsBackground || [self IsFeatureActive:EAudioFeature::BackgroundAudio]; + + // @todo maybe check the active states, not bForce? + if (self.bAudioActive != bActive || bForce) + { + // enable or disable audio + NSError* ActiveError = nil; + [[AVAudioSession sharedInstance] setActive:bActive error:&ActiveError]; + if (ActiveError) + { + UE_LOG(LogIOSAudioSession, Error, TEXT("Failed to set audio session to active = %d [Error = %s]"), bActive, *FString([ActiveError description])); + } + else + { + self.bAudioActive = bActive; + } + + if (self.bAudioActive) + { + // get the category and settings to use + /*AVAudioSessionCategory*/NSString* Category = AVAudioSessionCategorySoloAmbient; + /*AVAudioSessionMode*/NSString* Mode = AVAudioSessionModeDefault; + AVAudioSessionCategoryOptions Options = 0; + + // attempt to mix with other apps if desired + if ([self IsFeatureActive:EAudioFeature::BackgroundAudio]) + { + Options |= AVAudioSessionCategoryOptionMixWithOthers; + } + + if ([self IsFeatureActive:EAudioFeature::VoiceChat] || ([self IsFeatureActive:EAudioFeature::Playback] && [self IsFeatureActive:EAudioFeature::Record])) + { + Category = AVAudioSessionCategoryPlayAndRecord; + + if ([self IsFeatureActive:EAudioFeature::VoiceChat]) + { + Mode = AVAudioSessionModeVoiceChat; +#if !PLATFORM_TVOS + // allow bluetooth for chatting and such + Options |= AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionAllowBluetoothA2DP; +#endif + } + } + else if ([self IsFeatureActive:EAudioFeature::Playback]) + { + Category = AVAudioSessionCategoryPlayback; + } + else if ([self IsFeatureActive:EAudioFeature::Record]) + { + Category = AVAudioSessionCategoryRecord; + } + else if ([self IsFeatureActive:EAudioFeature::BackgroundAudio]) + { + Category = AVAudioSessionCategoryRecord; + } + + // set the category (the most important part here) + [[AVAudioSession sharedInstance] setCategory:Category mode:Mode options:Options error:&ActiveError]; + if (ActiveError) + { + UE_LOG(LogIOSAudioSession, Error, TEXT("Failed to set audio session category to %s! [Error = %s]"), *FString(Category), *FString([ActiveError description])); + } + } + } + } + // old style below + else if (bActive) { if (bForce || !self.bAudioActive) { @@ -514,9 +610,10 @@ bool FIOSCoreDelegates::PassesPushNotificationFilters(NSDictionary* Payload) else { AVAudioSessionCategoryOptions opts = + AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionAllowBluetoothA2DP | #if !PLATFORM_TVOS - AVAudioSessionCategoryOptionDefaultToSpeaker | + AVAudioSessionCategoryOptionDefaultToSpeaker | #endif AVAudioSessionCategoryOptionMixWithOthers; @@ -587,6 +684,7 @@ bool FIOSCoreDelegates::PassesPushNotificationFilters(NSDictionary* Payload) else { AVAudioSessionCategoryOptions opts = + AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionAllowBluetoothA2DP | #if !PLATFORM_TVOS AVAudioSessionCategoryOptionDefaultToSpeaker | @@ -613,7 +711,32 @@ bool FIOSCoreDelegates::PassesPushNotificationFilters(NSDictionary* Payload) else if ((bForce || self.bAudioActive) && !self.bUsingBackgroundMusic) { NSError* ActiveError = nil; - if (!self.bVoiceChatEnabled) + if (self.bVoiceChatEnabled) + { + AVAudioSessionCategoryOptions opts = + AVAudioSessionCategoryOptionAllowBluetooth | + AVAudioSessionCategoryOptionAllowBluetoothA2DP | +#if !PLATFORM_TVOS + AVAudioSessionCategoryOptionDefaultToSpeaker | +#endif + AVAudioSessionCategoryOptionMixWithOthers; + + // Necessary for voice chat if audio is not active + if (@available(iOS 10, *)) + { + [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord mode:AVAudioSessionModeDefault options:opts error:&ActiveError]; + } + else + { + [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:opts error:&ActiveError]; + } + if (ActiveError) + { + UE_LOG(LogIOSAudioSession, Error, TEXT("Failed to set audio session category!")); + } + ActiveError = nil; + } + else { // Necessary to prevent audio from getting killing when setup for background iPod audio playback [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&ActiveError]; @@ -635,22 +758,37 @@ bool FIOSCoreDelegates::PassesPushNotificationFilters(NSDictionary* Payload) - (void)EnableVoiceChat:(bool)bEnable { - self.bVoiceChatEnabled = false; - - if (FApp::IsUnattended()) + // mobile will prompt for microphone access + if (FApp::IsUnattended()) { return; } - - self.bVoiceChatEnabled = bEnable; - [self ToggleAudioSession : self.bAudioActive force : true]; + [self SetFeature:EAudioFeature::VoiceChat Active:bEnable]; } - (bool)IsVoiceChatEnabled { - return self.bVoiceChatEnabled; + return [self IsFeatureActive:EAudioFeature::VoiceChat]; } + +- (void)SetFeature:(EAudioFeature)Feature Active:(bool)bIsActive +{ + if (GEnabledAudioFeatures[(uint8)Feature] != bIsActive) + { + GEnabledAudioFeatures[(uint8)Feature] = bIsActive; + + // actually set the session + [self ToggleAudioSession:self.bAudioActive force:true]; + } +} + +- (bool)IsFeatureActive:(EAudioFeature)Feature +{ + return GEnabledAudioFeatures[(uint8)Feature]; +} + + - (int)GetAudioVolume { float vol = [[AVAudioSession sharedInstance] outputVolume]; @@ -709,14 +847,18 @@ bool FIOSCoreDelegates::PassesPushNotificationFilters(NSDictionary* Payload) return self.ThermalState; } -/** - * @return the single app delegate object - */ -+ (IOSAppDelegate*)GetDelegate +- (UIViewController*) IOSController { - return (IOSAppDelegate*)[UIApplication sharedApplication].delegate; + // walk the responder chain until we get to a non-view, that's the VC + UIResponder *Responder = IOSView; + while ([Responder isKindOfClass:[UIView class]]) + { + Responder = [Responder nextResponder]; + } + return (UIViewController*)Responder; } + bool GIsSuspended = 0; - (void)ToggleSuspend:(bool)bSuspend { @@ -748,6 +890,12 @@ bool GIsSuspended = 0; } } +- (void)ForceExit +{ + GIsRequestingExit = true; + bForceExit = true; +} + - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.bDeviceInPortraitMode = false; @@ -776,7 +924,7 @@ static FAutoConsoleVariableRef CVarGEnableThermalsReport( printf("========= This app is in %s mode\n", self.bDeviceInPortraitMode ? "PORTRAIT" : "LANDSCAPE"); #endif - // check OS version to make sure we have the API + // check OS version to make sure we have the API OSVersion = [[[UIDevice currentDevice] systemVersion] floatValue]; if (!FPlatformMisc::IsDebuggerPresent() || GAlwaysReportCrash) { @@ -784,6 +932,10 @@ static FAutoConsoleVariableRef CVarGEnableThermalsReport( InstallSignalHandlers(); } + self.savedOpenUrlParameters = [[NSMutableArray alloc] init]; + self.PeakMemoryTimer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(RecordPeakMemory) userInfo:nil repeats:YES]; + +#if !BUILD_EMBEDDED_APP // create the main landscape window object CGRect MainFrame = [[UIScreen mainScreen] bounds]; self.Window = [[UIWindow alloc] initWithFrame:MainFrame]; @@ -805,7 +957,6 @@ static FAutoConsoleVariableRef CVarGEnableThermalsReport( NSMutableString* PngString = [[NSMutableString alloc] init]; [ImageString appendString:@"Default"]; - self.savedOpenUrlParameters = [[NSMutableArray alloc] init]; FPlatformMisc::EIOSDevice Device = FPlatformMisc::GetIOSDeviceType(); @@ -971,9 +1122,17 @@ static FAutoConsoleVariableRef CVarGEnableThermalsReport( UIImage* imageToDisplay = [UIImage imageWithCGImage: [image CGImage] scale: 1.0 orientation: orient]; UIImageView* imageView = [[UIImageView alloc] initWithImage: imageToDisplay]; imageView.frame = MainFrame; - imageView.tag = 2; + imageView.tag = 200; [self.Window addSubview: imageView]; GShowSplashScreen = true; + + timer = [NSTimer scheduledTimerWithTimeInterval: 0.05f target:self selector:@selector(timerForSplashScreen) userInfo:nil repeats:YES]; + + [self StartGameThread]; + + self.CommandLineParseTimer = [NSTimer scheduledTimerWithTimeInterval:0.01f target:self selector:@selector(NoUrlCommandLine) userInfo:nil repeats:NO]; + +#endif #if !PLATFORM_TVOS #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0 @@ -998,19 +1157,12 @@ static FAutoConsoleVariableRef CVarGEnableThermalsReport( } } #endif -#endif - - timer = [NSTimer scheduledTimerWithTimeInterval: 0.05f target:self selector:@selector(timerForSplashScreen) userInfo:nil repeats:YES]; - - self.PeakMemoryTimer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(RecordPeakMemory) userInfo:nil repeats:YES]; - - // create a new thread (the pointer will be retained forever) - NSThread* GameThread = [[NSThread alloc] initWithTarget:self selector:@selector(MainAppThread:) object:launchOptions]; - [GameThread setStackSize:GAME_THREAD_STACK_SIZE]; - [GameThread start]; - self.CommandLineParseTimer = [NSTimer scheduledTimerWithTimeInterval:0.01f target:self selector:@selector(NoUrlCommandLine) userInfo:nil repeats:NO]; -#if !UE_BUILD_SHIPPING && !PLATFORM_TVOS + // Register for device orientation changes + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; + +#if !UE_BUILD_SHIPPING // make a history buffer self.ConsoleHistoryValues = [[NSMutableArray alloc] init]; @@ -1052,7 +1204,8 @@ static FAutoConsoleVariableRef CVarGEnableThermalsReport( } -#endif +#endif // UE_BUILD_SHIPPING +#endif // !TVOS #if !PLATFORM_TVOS if (@available(iOS 11, *)) @@ -1075,25 +1228,48 @@ static FAutoConsoleVariableRef CVarGEnableThermalsReport( [self InitializeAudioSession]; -#if !PLATFORM_TVOS - // Register for device orientation changes - [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil]; -#endif - return YES; } +- (void) StartGameThread +{ + // create a new thread (the pointer will be retained forever) + NSThread* GameThread = [[NSThread alloc] initWithTarget:self selector:@selector(MainAppThread:) object:self.launchOptions]; + [GameThread setStackSize:GAME_THREAD_STACK_SIZE]; + [GameThread start]; + + // this can be slow (1/3 of a second!), so don't make the game thread stall loading for it + // check to see if we are using the network file system, if so, disable the idle timer + FString HostIP; +// if (FParse::Value(FCommandLine::Get(), TEXT("-FileHostIP="), HostIP)) + { + [UIApplication sharedApplication].idleTimerDisabled = YES; + } +} + +#if !PLATFORM_TVOS +extern EDeviceScreenOrientation ConvertFromUIInterfaceOrientation(UIInterfaceOrientation Orientation); +#endif + - (void) didRotate:(NSNotification *)notification { #if !PLATFORM_TVOS - UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; - + // get the interfaec orientation + NSNumber* OrientationNumber = [notification.userInfo objectForKey:UIApplicationStatusBarOrientationUserInfoKey]; + UIInterfaceOrientation Orientation = (UIInterfaceOrientation)[OrientationNumber intValue]; + + NSLog(@"didRotate orientation = %d, statusBar = %d", (int)Orientation, (int)[[UIApplication sharedApplication] statusBarOrientation]); + + Orientation = [[UIApplication sharedApplication] statusBarOrientation]; + + extern UIInterfaceOrientation GInterfaceOrientation; + GInterfaceOrientation = Orientation; + if (bEngineInit) { - FFunctionGraphTask::CreateAndDispatchWhenReady([orientation]() + FFunctionGraphTask::CreateAndDispatchWhenReady([Orientation]() { - FCoreDelegates::ApplicationReceivedScreenOrientationChangedNotificationDelegate.Broadcast((int32)orientation); + FCoreDelegates::ApplicationReceivedScreenOrientationChangedNotificationDelegate.Broadcast((int32)ConvertFromUIInterfaceOrientation(Orientation)); //we also want to fire off the safe frame event FCoreDelegates::OnSafeFrameChangedEvent.Broadcast(); @@ -1218,7 +1394,13 @@ FCriticalSection RenderSuspend; If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. */ - FCoreDelegates::ApplicationWillEnterBackgroundDelegate.Broadcast(); + FIOSAsyncTask* AsyncTask = [[FIOSAsyncTask alloc] init]; + AsyncTask.GameThreadCallback = ^ bool(void) + { + FCoreDelegates::ApplicationWillEnterBackgroundDelegate.Broadcast(); + return true; + }; + [AsyncTask FinishedTask]; } - (void)applicationWillEnterForeground:(UIApplication *)application @@ -1226,7 +1408,13 @@ FCriticalSection RenderSuspend; /* Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. */ - FCoreDelegates::ApplicationHasEnteredForegroundDelegate.Broadcast(); + FIOSAsyncTask* AsyncTask = [[FIOSAsyncTask alloc] init]; + AsyncTask.GameThreadCallback = ^ bool(void) + { + FCoreDelegates::ApplicationHasEnteredForegroundDelegate.Broadcast(); + return true; + }; + [AsyncTask FinishedTask]; } extern double GCStartTime; @@ -1238,8 +1426,8 @@ extern double GCStartTime; Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. */ RenderSuspend.Unlock(); - [self ToggleAudioSession:true force:true]; [self ToggleSuspend : false]; + [self ToggleAudioSession:true force:true]; if (bEngineInit) { diff --git a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSApplication.cpp b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSApplication.cpp index a6771c0a0143..3c19958bf261 100644 --- a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSApplication.cpp +++ b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSApplication.cpp @@ -11,12 +11,11 @@ #include "IInputDevice.h" #include "Misc/ScopeLock.h" #include "HAL/IConsoleManager.h" - -FCriticalSection FIOSApplication::CriticalSection; -bool FIOSApplication::bOrientationChanged = false; +#include "IOS/IOSAsyncTask.h" FIOSApplication* FIOSApplication::CreateIOSApplication() { + SCOPED_BOOT_TIMING("FIOSApplication::CreateIOSApplication"); return new FIOSApplication(); } @@ -82,22 +81,6 @@ void FIOSApplication::PollGameDeviceState( const float TimeDelta ) (*DeviceIt)->Tick(TimeDelta); (*DeviceIt)->SendControllerEvents(); } - - FScopeLock Lock(&CriticalSection); - if(bOrientationChanged && Windows.Num() > 0) - { - int32 WindowX,WindowY, WindowWidth,WindowHeight; - Windows[0]->GetFullScreenInfo(WindowX, WindowY, WindowWidth, WindowHeight); - - GenericApplication::GetMessageHandler()->OnSizeChanged(Windows[0],WindowWidth,WindowHeight, false); - GenericApplication::GetMessageHandler()->OnResizingWindow(Windows[0]); - CacheDisplayMetrics(); - FDisplayMetrics DisplayMetrics; - FDisplayMetrics::RebuildDisplayMetrics(DisplayMetrics); - BroadcastDisplayMetricsChanged(DisplayMetrics); - FCoreDelegates::OnSafeFrameChangedEvent.Broadcast(); - bOrientationChanged = false; - } } FPlatformRect FIOSApplication::GetWorkArea( const FPlatformRect& CurrentWindow ) const @@ -132,22 +115,26 @@ void FDisplayMetrics::RebuildDisplayMetrics(FDisplayMetrics& OutDisplayMetrics) //we need to set these according to the orientation TAutoConsoleVariable* CVar_Left = nullptr; - TAutoConsoleVariable* CVar_Top = &CVarSafeZone_Landscape_Top; + TAutoConsoleVariable* CVar_Top = nullptr; TAutoConsoleVariable* CVar_Right = nullptr; - TAutoConsoleVariable* CVar_Bottom = &CVarSafeZone_Landscape_Bottom; + TAutoConsoleVariable* CVar_Bottom = nullptr; //making an assumption that the "normal" landscape mode is Landscape right if (CachedOrientation == UIInterfaceOrientationLandscapeLeft) { CVar_Left = &CVarSafeZone_Landscape_Left; CVar_Right = &CVarSafeZone_Landscape_Right; + CVar_Top = &CVarSafeZone_Landscape_Top; + CVar_Bottom = &CVarSafeZone_Landscape_Bottom; } else if (CachedOrientation == UIInterfaceOrientationLandscapeRight) { CVar_Left = &CVarSafeZone_Landscape_Right; CVar_Right = &CVarSafeZone_Landscape_Left; + CVar_Top = &CVarSafeZone_Landscape_Top; + CVar_Bottom = &CVarSafeZone_Landscape_Bottom; } - + // of the CVars are set, use their values. If not, use what comes from iOS const float Inset_Left = (!CVar_Left || CVar_Left->AsVariable()->GetFloat() < 0.0f) ? CachedInsets.left : CVar_Left->AsVariable()->GetFloat(); const float Inset_Top = (!CVar_Top || CVar_Top->AsVariable()->GetFloat() < 0.0f) ? CachedInsets.top : CVar_Top->AsVariable()->GetFloat(); @@ -190,10 +177,30 @@ TSharedRef< FGenericWindow > FIOSApplication::MakeWindow() } #if !PLATFORM_TVOS -void FIOSApplication::OrientationChanged(UIDeviceOrientation orientation) +void FIOSApplication::OrientationChanged(UIInterfaceOrientation orientation) { - FScopeLock Lock(&CriticalSection); - bOrientationChanged = true; + // this is called on the IOS thread. It turns out that it's possible for the resolution to change AGAIN by the time the game + // thread processes the resize, so we queue up the current size from the ios thread, send that to the RHI to resize to that + // (and no longer checking if it matches current frame size, because it may not). If another resize happens, that new size + // will get queued up here and sent to RHI, so eventually the size will be correct + FPlatformRect WindowRect = FIOSWindow::GetScreenRect(); + int32 WindowWidth = WindowRect.Right - WindowRect.Left; + int32 WindowHeight = WindowRect.Bottom - WindowRect.Top; + + // queue up the size as we see it now all the way to the RHI + [FIOSAsyncTask CreateTaskWithBlock : ^ bool(void) + { + FIOSApplication* App = [IOSAppDelegate GetDelegate].IOSApplication; + + App->GetMessageHandler()->OnSizeChanged(App->Windows[0],WindowWidth,WindowHeight, false); + App->GetMessageHandler()->OnResizingWindow(App->Windows[0]); + App->CacheDisplayMetrics(); + FDisplayMetrics DisplayMetrics; + FDisplayMetrics::RebuildDisplayMetrics(DisplayMetrics); + App->BroadcastDisplayMetricsChanged(DisplayMetrics); + FCoreDelegates::OnSafeFrameChangedEvent.Broadcast(); + return true; + }]; } #endif diff --git a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSFeedbackContext.cpp b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSFeedbackContext.cpp new file mode 100644 index 000000000000..c1ba61d39883 --- /dev/null +++ b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSFeedbackContext.cpp @@ -0,0 +1,28 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "IOS/IOSFeedbackContext.h" + +FIOSFeedbackContext::FIOSFeedbackContext() + : FFeedbackContext() +{ } + +void FIOSFeedbackContext::Serialize( const TCHAR* V, ELogVerbosity::Type Verbosity, const class FName& Category ) +{ + if( !GLog->IsRedirectingTo( this ) ) + { + GLog->Serialize( V, Verbosity, Category ); + } +} + +bool FIOSFeedbackContext::YesNof(const FText& Question) +{ + if( ( GIsSilent != true ) && ( FApp::IsUnattended() != true ) ) + { + FPlatformMisc::LowLevelOutputDebugStringf( *(Question.ToString()) ); + return false; + } + else + { + return false; + } +} diff --git a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSInputInterface.cpp b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSInputInterface.cpp index 358a23ae69f6..9eaa8dd168e5 100644 --- a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSInputInterface.cpp +++ b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSInputInterface.cpp @@ -6,6 +6,7 @@ #include "Misc/ScopeLock.h" #include "HAL/IConsoleManager.h" #include "HAL/PlatformTime.h" +#include "Misc/EmbeddedCommunication.h" #import @@ -43,9 +44,12 @@ FIOSInputInterface::FIOSInputInterface( const TSharedRef< FGenericApplicationMes , bAllowControllers(true) , LastHapticValue(0.0f) { + SCOPED_BOOT_TIMING("FIOSInputInterface::FIOSInputInterface"); + #if !PLATFORM_TVOS MotionManager = nil; ReferenceAttitude = nil; + bPauseMotion = false; #endif GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bTreatRemoteAsSeparateController"), bTreatRemoteAsSeparateController, GEngineIni); @@ -53,7 +57,7 @@ FIOSInputInterface::FIOSInputInterface( const TSharedRef< FGenericApplicationMes GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bUseRemoteAsVirtualJoystick"), bUseRemoteAsVirtualJoystick, GEngineIni); GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bUseRemoteAbsoluteDpadValues"), bUseRemoteAbsoluteDpadValues, GEngineIni); GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bAllowControllers"), bAllowControllers, GEngineIni); - + [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification* Notification) { HandleConnection(Notification.object); @@ -65,10 +69,40 @@ FIOSInputInterface::FIOSInputInterface( const TSharedRef< FGenericApplicationMes }]; - [GCController startWirelessControllerDiscoveryWithCompletionHandler:^{ }]; - + dispatch_async(dispatch_get_main_queue(), ^ + { + [GCController startWirelessControllerDiscoveryWithCompletionHandler:^{ }]; + }); + FMemory::Memzero(Controllers, sizeof(Controllers)); + FEmbeddedDelegates::GetNativeToEmbeddedParamsDelegateForSubsystem(TEXT("iosinput")).AddLambda([this](const FEmbeddedCallParamsHelper& Message) + { + FString Error; +#if !PLATFORM_TVOS + + // execute any console commands + if (Message.Command == TEXT("stopmotion")) + { + [MotionManager release]; + MotionManager = nil; + + bPauseMotion = true; + } + else if (Message.Command == TEXT("startmotion")) + { + bPauseMotion = false; + } + else +#endif + { + Error = TEXT("Unknown iosinput command ") + Message.Command; + } + + Message.OnCompleteDelegate({}, Error); + }); + + #if !PLATFORM_TVOS HapticFeedbackSupportLevel = [[[UIDevice currentDevice] valueForKey:@"_feedbackSupportLevel"] intValue]; #else @@ -547,94 +581,97 @@ void FIOSInputInterface::QueueKeyInput(int32 Key, int32 Char) void FIOSInputInterface::GetMovementData(FVector& Attitude, FVector& RotationRate, FVector& Gravity, FVector& Acceleration) { #if !PLATFORM_TVOS - // initialize on first use - if (MotionManager == nil) + if (!bPauseMotion) { - // Look to see if we can create the motion manager - MotionManager = [[CMMotionManager alloc] init]; - - // Check to see if the device supports full motion (gyro + accelerometer) - if (MotionManager.deviceMotionAvailable) + // initialize on first use + if (MotionManager == nil) { - MotionManager.deviceMotionUpdateInterval = 0.02; + // Look to see if we can create the motion manager + MotionManager = [[CMMotionManager alloc] init]; - // Start the Device updating motion - [MotionManager startDeviceMotionUpdates]; + // Check to see if the device supports full motion (gyro + accelerometer) + if (MotionManager.deviceMotionAvailable) + { + MotionManager.deviceMotionUpdateInterval = 0.02; + + // Start the Device updating motion + [MotionManager startDeviceMotionUpdates]; + } + else + { + [MotionManager startAccelerometerUpdates]; + CenterPitch = CenterPitch = 0; + bIsCalibrationRequested = false; + } + } + + // do we have full motion data? + if (MotionManager.deviceMotionActive) + { + // Grab the values + CMAttitude* CurrentAttitude = MotionManager.deviceMotion.attitude; + CMRotationRate CurrentRotationRate = MotionManager.deviceMotion.rotationRate; + CMAcceleration CurrentGravity = MotionManager.deviceMotion.gravity; + CMAcceleration CurrentUserAcceleration = MotionManager.deviceMotion.userAcceleration; + + // apply a reference attitude if we have been calibrated away from default + if (ReferenceAttitude) + { + [CurrentAttitude multiplyByInverseOfAttitude : ReferenceAttitude]; + } + + // convert to UE3 + Attitude = FVector(float(CurrentAttitude.pitch), float(CurrentAttitude.yaw), float(CurrentAttitude.roll)); + RotationRate = FVector(float(CurrentRotationRate.x), float(CurrentRotationRate.y), float(CurrentRotationRate.z)); + Gravity = FVector(float(CurrentGravity.x), float(CurrentGravity.y), float(CurrentGravity.z)); + Acceleration = FVector(float(CurrentUserAcceleration.x), float(CurrentUserAcceleration.y), float(CurrentUserAcceleration.z)); } else { - [MotionManager startAccelerometerUpdates]; - CenterPitch = CenterPitch = 0; - bIsCalibrationRequested = false; + // get the plain accleration + CMAcceleration RawAcceleration = [MotionManager accelerometerData].acceleration; + FVector NewAcceleration(RawAcceleration.x, RawAcceleration.y, RawAcceleration.z); + + // storage for keeping the accelerometer values over time (for filtering) + static bool bFirstAccel = true; + + // how much of the previous frame's acceleration to keep + const float VectorFilter = bFirstAccel ? 0.0f : 0.85f; + bFirstAccel = false; + + // apply new accelerometer values to last frames + FilteredAccelerometer = FilteredAccelerometer * VectorFilter + (1.0f - VectorFilter) * NewAcceleration; + + // create an normalized acceleration vector + FVector FinalAcceleration = -FilteredAccelerometer.GetSafeNormal(); + + // calculate Roll/Pitch + float CurrentPitch = FMath::Atan2(FinalAcceleration.Y, FinalAcceleration.Z); + float CurrentRoll = -FMath::Atan2(FinalAcceleration.X, FinalAcceleration.Z); + + // if we want to calibrate, use the current values as center + if (bIsCalibrationRequested) + { + CenterPitch = CurrentPitch; + CenterRoll = CurrentRoll; + bIsCalibrationRequested = false; + } + + CurrentPitch -= CenterPitch; + CurrentRoll -= CenterRoll; + + Attitude = FVector(CurrentPitch, 0, CurrentRoll); + RotationRate = FVector(LastPitch - CurrentPitch, 0, LastRoll - CurrentRoll); + Gravity = FVector(0, 0, 0); + + // use the raw acceleration for acceleration + Acceleration = NewAcceleration; + + // remember for next time (for rotation rate) + LastPitch = CurrentPitch; + LastRoll = CurrentRoll; } } - - // do we have full motion data? - if (MotionManager.deviceMotionActive) - { - // Grab the values - CMAttitude* CurrentAttitude = MotionManager.deviceMotion.attitude; - CMRotationRate CurrentRotationRate = MotionManager.deviceMotion.rotationRate; - CMAcceleration CurrentGravity = MotionManager.deviceMotion.gravity; - CMAcceleration CurrentUserAcceleration = MotionManager.deviceMotion.userAcceleration; - - // apply a reference attitude if we have been calibrated away from default - if (ReferenceAttitude) - { - [CurrentAttitude multiplyByInverseOfAttitude : ReferenceAttitude]; - } - - // convert to UE3 - Attitude = FVector(float(CurrentAttitude.pitch), float(CurrentAttitude.yaw), float(CurrentAttitude.roll)); - RotationRate = FVector(float(CurrentRotationRate.x), float(CurrentRotationRate.y), float(CurrentRotationRate.z)); - Gravity = FVector(float(CurrentGravity.x), float(CurrentGravity.y), float(CurrentGravity.z)); - Acceleration = FVector(float(CurrentUserAcceleration.x), float(CurrentUserAcceleration.y), float(CurrentUserAcceleration.z)); - } - else - { - // get the plain accleration - CMAcceleration RawAcceleration = [MotionManager accelerometerData].acceleration; - FVector NewAcceleration(RawAcceleration.x, RawAcceleration.y, RawAcceleration.z); - - // storage for keeping the accelerometer values over time (for filtering) - static bool bFirstAccel = true; - - // how much of the previous frame's acceleration to keep - const float VectorFilter = bFirstAccel ? 0.0f : 0.85f; - bFirstAccel = false; - - // apply new accelerometer values to last frames - FilteredAccelerometer = FilteredAccelerometer * VectorFilter + (1.0f - VectorFilter) * NewAcceleration; - - // create an normalized acceleration vector - FVector FinalAcceleration = -FilteredAccelerometer.GetSafeNormal(); - - // calculate Roll/Pitch - float CurrentPitch = FMath::Atan2(FinalAcceleration.Y, FinalAcceleration.Z); - float CurrentRoll = -FMath::Atan2(FinalAcceleration.X, FinalAcceleration.Z); - - // if we want to calibrate, use the current values as center - if (bIsCalibrationRequested) - { - CenterPitch = CurrentPitch; - CenterRoll = CurrentRoll; - bIsCalibrationRequested = false; - } - - CurrentPitch -= CenterPitch; - CurrentRoll -= CenterRoll; - - Attitude = FVector(CurrentPitch, 0, CurrentRoll); - RotationRate = FVector(LastPitch - CurrentPitch, 0, LastRoll - CurrentRoll); - Gravity = FVector(0, 0, 0); - - // use the raw acceleration for acceleration - Acceleration = NewAcceleration; - - // remember for next time (for rotation rate) - LastPitch = CurrentPitch; - LastRoll = CurrentRoll; - } #endif } diff --git a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSPlatformApplicationMisc.cpp b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSPlatformApplicationMisc.cpp index a788d0f046b7..0ae70c901937 100644 --- a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSPlatformApplicationMisc.cpp +++ b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSPlatformApplicationMisc.cpp @@ -10,6 +10,7 @@ #include "IOS/IOSView.h" #include "IOS/IOSInputInterface.h" #include "IOS/IOSErrorOutputDevice.h" +#include "IOS/IOSFeedbackContext.h" FIOSApplication* FIOSPlatformApplicationMisc::CachedApplication = nullptr; @@ -152,6 +153,12 @@ void FIOSPlatformApplicationMisc::LoadPreInitModules() FModuleManager::Get().LoadModule(TEXT("AudioMixerAudioUnit")); } +class FFeedbackContext* FIOSPlatformApplicationMisc::GetFeedbackContext() +{ + static FIOSFeedbackContext Singleton; + return &Singleton; +} + class FOutputDeviceError* FIOSPlatformApplicationMisc::GetErrorOutputDevice() { static FIOSErrorOutputDevice Singleton; diff --git a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSPlatformSurvey.cpp b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSPlatformSurvey.cpp index 7e4aeaa20a33..f886046071d9 100644 --- a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSPlatformSurvey.cpp +++ b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSPlatformSurvey.cpp @@ -23,10 +23,6 @@ bool FIOSPlatformSurvey::GetSurveyResults(FHardwareSurveyResults& OutResults, bo // display 0 is max size CGRect MainFrame = [[UIScreen mainScreen] bounds]; - if ([IOSAppDelegate GetDelegate].OSVersion < 8.0f && ![IOSAppDelegate GetDelegate].bDeviceInPortraitMode) - { - Swap(MainFrame.size.width, MainFrame.size.height); - } float Scale = [[UIScreen mainScreen] scale]; OutResults.Displays[0].CurrentModeWidth = MainFrame.size.width * Scale; OutResults.Displays[0].CurrentModeHeight = MainFrame.size.height * Scale; diff --git a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSView.cpp b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSView.cpp index 459e11cb9b46..d3d289465430 100644 --- a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSView.cpp +++ b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSView.cpp @@ -3,8 +3,6 @@ #include "IOS/IOSView.h" #include "IOS/IOSAppDelegate.h" #include "IOS/IOSApplication.h" -#include "IOS/IOSInputInterface.h" -#include "Delegates/Delegate.h" #include "Misc/ConfigCacheIni.h" #include "HAL/IConsoleManager.h" #include "Misc/CommandLine.h" @@ -16,6 +14,8 @@ #import #import +#include "IOS/IOSCommandLineHelper.h" + #if HAS_METAL id GMetalDevice = nil; #endif @@ -83,11 +83,48 @@ id GMetalDevice = nil; @synthesize secureTextEntry = bSecureTextEntry; @synthesize SwapCount, OnScreenColorRenderBuffer, OnScreenColorRenderBufferMSAA, markedTextStyle; + + + +#if BUILD_EMBEDDED_APP + ++(void)StartupEmbeddedUnreal +{ + // special initialization code for embedded view + + //// LaunchIOS replacement /// + FIOSCommandLineHelper::InitCommandArgs(TEXT("")); + + //#if !PLATFORM_TVOS + // // reset badge count on launch + // Application.applicationIconBadgeNumber = 0; + //#endif + + IOSAppDelegate* AppDelegate = [IOSAppDelegate GetDelegate]; + + [AppDelegate NoUrlCommandLine]; + [AppDelegate StartGameThread]; +} + +#endif + + + +#if !HAS_METAL && !HAS_OPENGL_ES +#error One of HAS_METAL or HAS_OPENGL_ES must be defined +#endif + /** * @return The Layer Class for the window */ + (Class)layerClass { +#if BUILD_EMBEDDED_APP + SCOPED_BOOT_TIMING("MetalLayer class"); + GMetalDevice = MTLCreateSystemDefaultDevice(); + return [CAMetalLayer class]; +#endif + #if HAS_METAL // make sure the project setting has enabled Metal support (per-project user settings in the editor) bool bSupportsMetal = false; @@ -97,12 +134,13 @@ id GMetalDevice = nil; // does commandline override? bool bForceES2 = FParse::Param(FCommandLine::Get(), TEXT("ES2")); - + bool bTriedToInit = false; // the check for the function pointer itself is to determine if the Metal framework exists, before calling it if ((bSupportsMetal || bSupportsMetalMRT) && !bForceES2 && MTLCreateSystemDefaultDevice != NULL) { + SCOPED_BOOT_TIMING("CreateMetalDevice"); // if the device is unable to run with Metal (pre-A7), this will return nil GMetalDevice = MTLCreateSystemDefaultDevice(); @@ -128,73 +166,124 @@ id GMetalDevice = nil; else #endif { +#if HAS_OPENGL_ES return [CAEAGLLayer class]; +#else + return nil; +#endif } } +- (id)initInternal:(CGRect)Frame +{ + SCOPED_BOOT_TIMING("[FIOSView initInternal]"); + + // figure out if we should start up GL or Metal +#if HAS_METAL + // if the device is valid, we know Metal is usable (see +layerClass) + MetalDevice = GMetalDevice; + if (MetalDevice != nil) + { + bIsUsingMetal = true; + + // grab the MetalLayer and typecast it to match what's in layerClass + CAMetalLayer* MetalLayer = (CAMetalLayer*)self.layer; + MetalLayer.presentsWithTransaction = NO; + MetalLayer.drawsAsynchronously = YES; + + // set a background color to make sure the layer appears + CGFloat components[] = { 0.0, 0.0, 0.0, 1 }; + MetalLayer.backgroundColor = CGColorCreate(CGColorSpaceCreateDeviceRGB(), components); + + // set the device on the rendering layer and provide a pixel format + MetalLayer.device = MetalDevice; + MetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; + MetalLayer.framebufferOnly = NO; + + } + else +#endif + { +#if HAS_OPENGL_ES + bIsUsingMetal = false; + + // Get the layer + CAEAGLLayer *EaglLayer = (CAEAGLLayer *)self.layer; + EaglLayer.opaque = YES; + NSMutableDictionary* Dict = [NSMutableDictionary dictionary]; + [Dict setValue : [NSNumber numberWithBool : NO] forKey : kEAGLDrawablePropertyRetainedBacking]; + [Dict setValue : kEAGLColorFormatRGBA8 forKey : kEAGLDrawablePropertyColorFormat]; + EaglLayer.drawableProperties = Dict; + + // Initialize a single, static OpenGL ES 2.0 context, shared by all EAGLView objects + Context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + + // delete this on failure + if (!Context || ![EAGLContext setCurrentContext : Context]) + { + [self release]; + return nil; + } +#endif + } + + NSLog(@"::: Created a UIView that will support %@ :::", bIsUsingMetal ? @"Metal" : @"@GLES"); + + // Initialize some variables + SwapCount = 0; + +#if PLATFORM_TVOS + // @todo tvos: This may need to be exposed to the game so that when you click Menu it will background the app + // this is basically the same way Android handles the Back button (maybe we should pass Menu button as back... maybe) + // @todo embedded: this will not work, because this view hasn't been added to a hierarchy yet, so the IOSController is guaranteed to be null. DELAY THIS + AppDelegate.IOSController.controllerUserInteractionEnabled = NO; +#endif + +// self.userInteractionEnabled = YES; +// self.clearsContextBeforeDrawing = NO; + self.multipleTouchEnabled = YES; + + FMemory::Memzero(AllTouches, sizeof(AllTouches)); + [self setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; + bIsInitialized = false; + + + [self InitKeyboard]; + +#if BUILD_EMBEDDED_APP + //// FAppEntry::PreInit replacement /// + IOSAppDelegate* AppDelegate = [IOSAppDelegate GetDelegate]; + + AppDelegate.RootView = self; + while (AppDelegate.RootView.superview != nil) + { + AppDelegate.RootView = AppDelegate.RootView.superview; + } + AppDelegate.IOSView = self; + + // initialize the backbuffer of the view (so the RHI can use it) + [self CreateFramebuffer:YES]; + +#endif + + + return self; +} + +- (id)initWithCoder:(NSCoder*)Decoder +{ + if ((self = [super initWithCoder:Decoder])) + { + self = [self initInternal:self.frame]; + } + return self; +} - (id)initWithFrame:(CGRect)Frame { if ((self = [super initWithFrame:Frame])) { - // figure out if we should start up GL or Metal -#if HAS_METAL - // if the device is valid, we know Metal is usable (see +layerClass) - MetalDevice = GMetalDevice; - if (MetalDevice != nil) - { - bIsUsingMetal = true; - - // grab the MetalLayer and typecast it to match what's in layerClass - CAMetalLayer* MetalLayer = (CAMetalLayer*)self.layer; - MetalLayer.presentsWithTransaction = NO; - MetalLayer.drawsAsynchronously = YES; - - // set a background color to make sure the layer appears - CGFloat components[] = { 0.0, 0.0, 0.0, 1 }; - MetalLayer.backgroundColor = CGColorCreate(CGColorSpaceCreateDeviceRGB(), components); - - // set the device on the rendering layer and provide a pixel format - MetalLayer.device = MetalDevice; - MetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; - MetalLayer.framebufferOnly = NO; - - } - else -#endif - { - bIsUsingMetal = false; - - // Get the layer - CAEAGLLayer *EaglLayer = (CAEAGLLayer *)self.layer; - EaglLayer.opaque = YES; - NSMutableDictionary* Dict = [NSMutableDictionary dictionary]; - [Dict setValue : [NSNumber numberWithBool : NO] forKey : kEAGLDrawablePropertyRetainedBacking]; - [Dict setValue : kEAGLColorFormatRGBA8 forKey : kEAGLDrawablePropertyColorFormat]; - EaglLayer.drawableProperties = Dict; - - // Initialize a single, static OpenGL ES 2.0 context, shared by all EAGLView objects - Context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - - // delete this on failure - if (!Context || ![EAGLContext setCurrentContext : Context]) - { - [self release]; - return nil; - } - } - - NSLog(@"::: Created a UIView that will support %@ :::", bIsUsingMetal ? @"Metal" : @"@GLES"); - - // Initialize some variables - SwapCount = 0; - - FMemory::Memzero(AllTouches, sizeof(AllTouches)); - [self setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; - bIsInitialized = false; - - - [self InitKeyboard]; + self = [self initInternal:self.frame]; } return self; } @@ -258,6 +347,7 @@ id GMetalDevice = nil; else #endif { +#if HAS_OPENGL_ES // make sure this is current [self MakeCurrent]; @@ -299,6 +389,7 @@ id GMetalDevice = nil; IPhoneBackBufferMemSize = singleBufferSize * 3/*iphone back buffer system is tripple buffered*/; UE_LOG(LogIOS, Log, TEXT("IPhone Back Buffer Size: %i MB"), (IPhoneBackBufferMemSize / 1024) / 1024.f); +#endif #endif } @@ -313,7 +404,7 @@ id GMetalDevice = nil; - (void)layoutSubviews { #if !PLATFORM_TVOS - UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; + auto orientation = [[UIApplication sharedApplication] statusBarOrientation]; FIOSApplication::OrientationChanged(orientation); #endif } @@ -325,20 +416,15 @@ id GMetalDevice = nil; { if (MetalDevice != nil) { - // grab the MetalLayer and typecast it to match what's in layerClass + // grab the MetalLayer and typecast it to match what's in layerClass, then set the new size CAMetalLayer* MetalLayer = (CAMetalLayer*)self.layer; - CGSize drawableSize = CGSizeMake(Width, Height); - checkf( FMath::TruncToInt(drawableSize.width) == FMath::TruncToInt(self.bounds.size.width * self.contentScaleFactor) && - FMath::TruncToInt(drawableSize.height) == FMath::TruncToInt(self.bounds.size.height * self.contentScaleFactor), - TEXT("[IOSView UpdateRenderWidth:andHeight:] passed in size doesn't match what we expected. Width: %d, Expected Width = %d (%.2f * %.2f). Height = %d, Expected Height = %d (%.2f * %.2f)"), - FMath::TruncToInt(drawableSize.width), FMath::TruncToInt(self.bounds.size.width * self.contentScaleFactor), (float)self.bounds.size.width, self.contentScaleFactor, - FMath::TruncToInt(drawableSize.height), FMath::TruncToInt(self.bounds.size.height * self.contentScaleFactor), (float)self.bounds.size.height, self.contentScaleFactor); - MetalLayer.drawableSize = drawableSize; + MetalLayer.drawableSize = CGSizeMake(Width, Height);; } return; } #endif +#if HAS_OPENGL_ES // Allocate color buffer based on the current layer size glBindRenderbuffer(GL_RENDERBUFFER, OnScreenColorRenderBuffer); check(glGetError() == 0); @@ -348,6 +434,7 @@ id GMetalDevice = nil; glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, OnScreenColorRenderBuffer); check(glGetError() == 0); check(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); +#endif } #if HAS_METAL @@ -364,6 +451,7 @@ id GMetalDevice = nil; // nothing to do here for Metal if (!bIsUsingMetal) { +#if HAS_OPENGL_ES // toss framebuffers if(ResolveFrameBuffer) { @@ -382,7 +470,8 @@ id GMetalDevice = nil; // glDeleteRenderbuffers(1, &OnScreenColorRenderBufferMSAA); // OnScreenColorRenderBufferMSAA = 0; // } -// } +// +#endif } // we are ready to be re-initialized @@ -394,7 +483,9 @@ id GMetalDevice = nil; { if (!bIsUsingMetal) { +#if HAS_OPENGL_ES [EAGLContext setCurrentContext:Context]; +#endif } } @@ -402,7 +493,9 @@ id GMetalDevice = nil; { if (!bIsUsingMetal) { +#if HAS_OPENGL_ES [EAGLContext setCurrentContext:nil]; +#endif } } @@ -410,6 +503,7 @@ id GMetalDevice = nil; { if (!bIsUsingMetal) { +#if HAS_OPENGL_ES // // We may need this in the MSAA case // GLint CurrentFramebuffer = 0; // // @todo-mobile: Fix this when we have MSAA support @@ -442,6 +536,7 @@ id GMetalDevice = nil; // // Restore the DRAW framebuffer object // glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, CurrentFramebuffer); // } +#endif } // increment our swap counter @@ -476,6 +571,100 @@ id GMetalDevice = nil; return -1; } + +-(void)HandleTouchAtLoc:(CGPoint)Loc PrevLoc:(CGPoint)PrevLoc TouchIndex:(int)TouchIndex Force:(float)Force Type:(TouchType)Type TouchesArray:(TArray&)TouchesArray +{ + const CGFloat Scale = self.contentScaleFactor; + + // init some things on begin + if (Type == TouchBegan) + { + PreviousForces[TouchIndex] = -1.0; + HasMoved[TouchIndex] = 0; + + NumActiveTouches++; + } + + float PreviousForce = PreviousForces[TouchIndex]; + + // make a new touch event struct + TouchInput TouchMessage; + TouchMessage.Handle = TouchIndex; + TouchMessage.Type = Type; + TouchMessage.Position = FVector2D(FMath::Min(self.frame.size.width - 1, Loc.x), FMath::Min(self.frame.size.height - 1, Loc.y)) * Scale; + TouchMessage.LastPosition = FVector2D(FMath::Min(self.frame.size.width - 1, PrevLoc.x), FMath::Min(self.frame.size.height - 1, PrevLoc.y)) * Scale; + TouchMessage.Force = Type != TouchEnded ? Force : 0.0f; + + // skip moves that didn't actually move - this will help input handling to skip over the first + // move since it is likely a big pop from the TouchBegan location (iOS filters out small movements + // on first press) + if (Type != TouchMoved || (PrevLoc.x != Loc.x || PrevLoc.y != Loc.y)) + { + // track first move event, for helping with "pop" on the filtered small movements + if (HasMoved[TouchIndex] == 0 && Type == TouchMoved) + { + TouchInput FirstMoveMessage = TouchMessage; + FirstMoveMessage.Type = FirstMove; + HasMoved[TouchIndex] = 1; + + TouchesArray.Add(FirstMoveMessage); + } + + TouchesArray.Add(TouchMessage); + } + + // if the force changed, send an event! + if (PreviousForce != Force) + { + TouchInput ForceMessage = TouchMessage; + ForceMessage.Type = ForceChanged; + PreviousForces[TouchIndex] = Force; + + TouchesArray.Add(ForceMessage); + } + + // clear out the touch when it ends + if (Type == TouchEnded) + { + AllTouches[TouchIndex] = nil; + NumActiveTouches--; + } + +#if !UE_BUILD_SHIPPING +#if WITH_SIMULATOR + // use 2 on the simulator so that Option-Click will bring up console (option-click is for doing pinch gestures, which we don't care about, atm) + if( NumActiveTouches >= 2 ) +#else + // If there are 3 active touches, bring up the console + if( NumActiveTouches >= 4 ) +#endif + { + bool bShowConsole = true; + GConfig->GetBool(TEXT("/Script/Engine.InputSettings"), TEXT("bShowConsoleOnFourFingerTap"), bShowConsole, GInputIni); + + if (bShowConsole) + { + // disable the integrated keyboard when launching the console + /* if (bIsUsingIntegratedKeyboard) + { + // press the console key twice to get the big one up + // @todo keyboard: Find a direct way to bering this up (it can get into a bad state where two presses won't do it correctly) + // and also the ` key could be changed via .ini + FIOSInputInterface::QueueKeyInput('`', '`'); + FIOSInputInterface::QueueKeyInput('`', '`'); + + [self ActivateKeyboard:true]; + } + else*/ + { + // Route the command to the main iOS thread (all UI must go to the main thread) + [[IOSAppDelegate GetDelegate] performSelectorOnMainThread:@selector(ShowConsole) withObject:nil waitUntilDone:NO]; + } + } + } +#endif +} + /** * Pass touch events to the input queue for slate to pull off of, and trigger the debug console. * @@ -484,15 +673,13 @@ id GMetalDevice = nil; */ -(void) HandleTouches:(NSSet*)Touches ofType:(TouchType)Type { - CGFloat Scale = self.contentScaleFactor; - TArray TouchesArray; for (UITouch* Touch in Touches) { // get info from the touch CGPoint Loc = [Touch locationInView:self]; CGPoint PrevLoc = [Touch previousLocationInView:self]; - + // convert TOuch pointer to a unique 0 based index int32 TouchIndex = [self GetTouchIndex:Touch]; if (TouchIndex < 0) @@ -500,70 +687,21 @@ id GMetalDevice = nil; continue; } - // init some things on begin - if (Type == TouchBegan) - { - PreviousForces[TouchIndex] = -1.0; - HasMoved[TouchIndex] = 0; - } - - float Force = Touch.force; - float PreviousForce = PreviousForces[TouchIndex]; - + // map larger values to 1..10, so 10 is a max across platforms if (Force > 1.0f) { Force = 10.0f * Force / Touch.maximumPossibleForce; } - - // Handle devices without force touch + + // Handle devices without force touch if ((Type == TouchBegan || Type == TouchMoved) && Force == 0.f) { Force = 1.f; } - - // make a new touch event struct - TouchInput TouchMessage; - TouchMessage.Handle = TouchIndex; - TouchMessage.Type = Type; - TouchMessage.Position = FVector2D(FMath::Min(self.frame.size.width - 1, Loc.x), FMath::Min(self.frame.size.height - 1, Loc.y)) * Scale; - TouchMessage.LastPosition = FVector2D(FMath::Min(self.frame.size.width - 1, PrevLoc.x), FMath::Min(self.frame.size.height - 1, PrevLoc.y)) * Scale; - TouchMessage.Force = Type != TouchEnded ? Force : 0.0f; - // skip moves that didn't actually move - this will help input handling to skip over the first - // move since it is likely a big pop from the TouchBegan location (iOS filters out small movements - // on first press) - if (Type != TouchMoved || (PrevLoc.x != Loc.x || PrevLoc.y != Loc.y)) - { - // track first move event, for helping with "pop" on the filtered small movements - if (HasMoved[TouchIndex] == 0 && Type == TouchMoved) - { - TouchInput FirstMoveMessage = TouchMessage; - FirstMoveMessage.Type = FirstMove; - HasMoved[TouchIndex] = 1; - - TouchesArray.Add(FirstMoveMessage); - } - - TouchesArray.Add(TouchMessage); - } - - // if the force changed, send an event! - if (PreviousForce != Force) - { - TouchInput ForceMessage = TouchMessage; - ForceMessage.Type = ForceChanged; - PreviousForces[TouchIndex] = Force; - - TouchesArray.Add(ForceMessage); - } - - // clear out the touch when it ends - if (Type == TouchEnded) - { - AllTouches[TouchIndex] = nil; - } + [self HandleTouchAtLoc:Loc PrevLoc:PrevLoc TouchIndex:TouchIndex Force:Force Type:Type TouchesArray:TouchesArray]; } FIOSInputInterface::QueueTouchInput(TouchesArray); @@ -577,43 +715,8 @@ id GMetalDevice = nil; */ - (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { - NumActiveTouches += touches.count; [self HandleTouches:touches ofType:TouchBegan]; - -#if !UE_BUILD_SHIPPING -#if WITH_SIMULATOR - // use 2 on the simulator so that Option-Click will bring up console (option-click is for doing pinch gestures, which we don't care about, atm) - if( NumActiveTouches >= 2 ) -#else - // If there are 3 active touches, bring up the console - if( NumActiveTouches >= 4 ) -#endif - { - bool bShowConsole = true; - GConfig->GetBool(TEXT("/Script/Engine.InputSettings"), TEXT("bShowConsoleOnFourFingerTap"), bShowConsole, GInputIni); - - if (bShowConsole) - { - // disable the integrated keyboard when launching the console -/* if (bIsUsingIntegratedKeyboard) - { - // press the console key twice to get the big one up - // @todo keyboard: Find a direct way to bering this up (it can get into a bad state where two presses won't do it correctly) - // and also the ` key could be changed via .ini - FIOSInputInterface::QueueKeyInput('`', '`'); - FIOSInputInterface::QueueKeyInput('`', '`'); - - [self ActivateKeyboard:true]; - } - else*/ - { - // Route the command to the main iOS thread (all UI must go to the main thread) - [[IOSAppDelegate GetDelegate] performSelectorOnMainThread:@selector(ShowConsole) withObject:nil waitUntilDone:NO]; - } - } } -#endif -} - (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event { @@ -622,13 +725,11 @@ id GMetalDevice = nil; - (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { - NumActiveTouches -= touches.count; [self HandleTouches:touches ofType:TouchEnded]; } - (void) touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event { - NumActiveTouches -= touches.count; [self HandleTouches:touches ofType:TouchEnded]; } @@ -1028,9 +1129,6 @@ id GMetalDevice = nil; } - - - @end @@ -1053,12 +1151,7 @@ id GMetalDevice = nil; self.view = [[UIView alloc] initWithFrame:Frame]; // settings copied from InterfaceBuilder -#if defined(__IPHONE_7_0) - if ([IOSAppDelegate GetDelegate].OSVersion >= 7.0) - { - self.edgesForExtendedLayout = UIRectEdgeNone; - } -#endif + self.edgesForExtendedLayout = UIRectEdgeNone; self.view.clearsContextBeforeDrawing = NO; #if !PLATFORM_TVOS diff --git a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSWindow.cpp b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSWindow.cpp index a54105c06378..00b0464f3042 100644 --- a/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSWindow.cpp +++ b/Engine/Source/Runtime/ApplicationCore/Private/IOS/IOSWindow.cpp @@ -70,7 +70,7 @@ void FIOSWindow::Initialize( class FIOSApplication* const Application, const TSh FPlatformRect FIOSWindow::GetScreenRect() { // get the main view's frame - IOSAppDelegate* AppDelegate = (IOSAppDelegate*)[[UIApplication sharedApplication] delegate]; + IOSAppDelegate* AppDelegate = [IOSAppDelegate GetDelegate]; UIView* View = AppDelegate.IOSView; CGRect Frame = [View frame]; CGFloat Scale = View.contentScaleFactor; diff --git a/Engine/Source/Runtime/ApplicationCore/Private/Mac/MacApplication.cpp b/Engine/Source/Runtime/ApplicationCore/Private/Mac/MacApplication.cpp index 2a94dadec0ea..a81972825356 100644 --- a/Engine/Source/Runtime/ApplicationCore/Private/Mac/MacApplication.cpp +++ b/Engine/Source/Runtime/ApplicationCore/Private/Mac/MacApplication.cpp @@ -1951,16 +1951,20 @@ TCHAR FMacApplication::TranslateCharCode(TCHAR CharCode, uint32 KeyCode) const void FMacApplication::CloseQueuedWindows() { + // OnWindowClose may call PumpMessages, which would reenter this function, so make a local copy of SlateWindowsToClose array to avoid infinite recursive calls + TArray> LocalWindowsToClose; + { FScopeLock Lock(&WindowsToCloseMutex); + LocalWindowsToClose = SlateWindowsToClose; + SlateWindowsToClose.Empty(); + } - if (SlateWindowsToClose.Num() > 0) + if (LocalWindowsToClose.Num() > 0) + { + for (TSharedRef Window : LocalWindowsToClose) { - for (TSharedRef Window : SlateWindowsToClose) - { - MessageHandler->OnWindowClose(Window); - } - SlateWindowsToClose.Empty(); + MessageHandler->OnWindowClose(Window); } } diff --git a/Engine/Source/Runtime/ApplicationCore/Private/Mac/MacWindow.cpp b/Engine/Source/Runtime/ApplicationCore/Private/Mac/MacWindow.cpp index 69ae6e60aa50..d4dcc93a2c75 100644 --- a/Engine/Source/Runtime/ApplicationCore/Private/Mac/MacWindow.cpp +++ b/Engine/Source/Runtime/ApplicationCore/Private/Mac/MacWindow.cpp @@ -623,8 +623,8 @@ void FMacWindow::ApplySizeAndModeChanges(int32 X, int32 Y, int32 Width, int32 He WindowHandle.TargetWindowMode = WindowMode; const float DPIScaleFactor = FPlatformApplicationMisc::GetDPIScaleFactorAtPoint(X, Y); - Width /= DPIScaleFactor; - Height /= DPIScaleFactor; + Width = FMath::CeilToInt(Width / DPIScaleFactor); + Height = FMath::CeilToInt(Height / DPIScaleFactor); const FVector2D CocoaPosition = FMacApplication::ConvertSlatePositionToCocoa(X, Y); NSRect Rect = NSMakeRect(CocoaPosition.X, CocoaPosition.Y - Height + 1, FMath::Max(Width, 0), FMath::Max(Height, 0)); diff --git a/Engine/Source/Runtime/ApplicationCore/Public/Android/AndroidApplication.h b/Engine/Source/Runtime/ApplicationCore/Public/Android/AndroidApplication.h index 24906093d25f..1a87a1630055 100644 --- a/Engine/Source/Runtime/ApplicationCore/Public/Android/AndroidApplication.h +++ b/Engine/Source/Runtime/ApplicationCore/Public/Android/AndroidApplication.h @@ -65,6 +65,10 @@ public: { return AndroidJavaEnv::FindJavaClass(name); } + static FORCEINLINE jclass FindJavaClassGlobalRef(const char* name) + { + return AndroidJavaEnv::FindJavaClassGlobalRef(name); + } static FORCEINLINE void DetachJavaEnv() { AndroidJavaEnv::DetachJavaEnv(); @@ -117,6 +121,9 @@ private: static bool bWindowSizeChanged; static FAndroidApplication* _application; + + EDeviceScreenOrientation DeviceOrientation; + void HandleDeviceOrientation(); }; PRAGMA_ENABLE_DEPRECATION_WARNINGS diff --git a/Engine/Source/Runtime/ApplicationCore/Public/Android/AndroidJavaMediaPlayer.h b/Engine/Source/Runtime/ApplicationCore/Public/Android/AndroidJavaMediaPlayer.h index 9626b7b8d1c3..cce63f0f2a9e 100644 --- a/Engine/Source/Runtime/ApplicationCore/Public/Android/AndroidJavaMediaPlayer.h +++ b/Engine/Source/Runtime/ApplicationCore/Public/Android/AndroidJavaMediaPlayer.h @@ -68,6 +68,7 @@ public: public: FJavaAndroidMediaPlayer(bool swizzlePixels, bool vulkanRenderer, bool needTrackInfo); + virtual ~FJavaAndroidMediaPlayer(); int32 GetDuration(); void Reset(); void Stop(); diff --git a/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSAppDelegate.h b/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSAppDelegate.h index 0e815d88d665..d1d79fff157f 100644 --- a/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSAppDelegate.h +++ b/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSAppDelegate.h @@ -15,6 +15,18 @@ #define USE_MUTE_SWITCH_DETECTION 0 +enum class EAudioFeature : uint8 +{ + ExternalAudio, // background music, music app, etc + VoiceChat, + Playback, + Record, + BackgroundAudio, + + NumFeatures, +}; + + // Predicate to decide whether a push notification message should be processed DECLARE_DELEGATE_RetVal_OneParam(bool, FPushNotificationFilter, NSDictionary*); @@ -68,6 +80,7 @@ namespace FAppEntry extern int32 gLaunchLocalNotificationFireDate; } +APPLICATIONCORE_API @interface IOSAppDelegate : UIResponder = __IPHONE_10_0 UNUserNotificationCenterDelegate, #endif -UITextFieldDelegate> + UITextFieldDelegate> +{ + bool bForceExit; +} /** Window object */ @property (strong, retain, nonatomic) UIWindow *Window; @@ -87,7 +103,7 @@ UITextFieldDelegate> @property class FIOSApplication* IOSApplication; /** The controller to handle rotation of the view */ -@property (retain) IOSViewController* IOSController; +@property (readonly) UIViewController* IOSController; /** The view controlled by the auto-rotating controller */ @property (retain) UIView* RootView; @@ -122,7 +138,7 @@ UITextFieldDelegate> @property (nonatomic, retain) UIAlertView* ConsoleAlert; #endif #ifdef __IPHONE_8_0 - @property (nonatomic, assign) UIAlertController* ConsoleAlertController; + @property (nonatomic, retain) UIAlertController* ConsoleAlertController; #endif @property (nonatomic, retain) NSMutableArray* ConsoleHistoryValues; @property (nonatomic, assign) int ConsoleHistoryValuesIndex; @@ -149,8 +165,8 @@ UITextFieldDelegate> -(bool)IsIdleTimerEnabled; -(void)EnableIdleTimer:(bool)bEnable; - --(void) ParseCommandLineOverrides; +-(void)StartGameThread; +-(void)NoUrlCommandLine; -(int)GetAudioVolume; -(bool)AreHeadphonesPluggedIn; @@ -178,6 +194,9 @@ UITextFieldDelegate> - (void)EnableVoiceChat:(bool)bEnable; - (bool)IsVoiceChatEnabled; +- (void)SetFeature:(EAudioFeature)Feature Active:(bool)bIsActive; +- (bool)IsFeatureActive:(EAudioFeature)Mode; + @property (atomic) bool bAudioActive; @property (atomic) bool bVoiceChatEnabled; @@ -186,6 +205,7 @@ UITextFieldDelegate> @property (atomic) bool bHasStarted; - (void)ToggleSuspend:(bool)bSuspend; +- (void)ForceExit; @property (nonatomic, copy) void(^BackgroundSessionEventCompleteDelegate)(); diff --git a/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSApplication.h b/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSApplication.h index 1597a559a121..f9c34289b862 100644 --- a/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSApplication.h +++ b/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSApplication.h @@ -28,7 +28,7 @@ public: virtual void AddExternalInputDevice(TSharedPtr InputDevice); #if !PLATFORM_TVOS - static void OrientationChanged(UIDeviceOrientation orientation); + static void OrientationChanged(UIInterfaceOrientation orientation); #endif virtual IInputInterface* GetInputInterface() override { return (IInputInterface*)InputInterface.Get(); } diff --git a/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSFeedbackContext.h b/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSFeedbackContext.h new file mode 100644 index 000000000000..9c7f0d76348a --- /dev/null +++ b/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSFeedbackContext.h @@ -0,0 +1,20 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once +#include "Misc/App.h" +#include "Misc/FeedbackContext.h" +#include "Misc/OutputDeviceRedirector.h" + +/** + * Feedback context implementation for IOS. + */ +class FIOSFeedbackContext : public FFeedbackContext +{ +public: + + /** Default constructor. */ + FIOSFeedbackContext(); + + virtual void Serialize( const TCHAR* V, ELogVerbosity::Type Verbosity, const class FName& Category ) override; + virtual bool YesNof(const FText& Question) override; +}; diff --git a/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSInputInterface.h b/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSInputInterface.h index f0d1c1c8fa4f..2e935263471c 100644 --- a/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSInputInterface.h +++ b/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSInputInterface.h @@ -63,7 +63,7 @@ public: */ void SendControllerEvents(); - static void QueueTouchInput(const TArray& InTouchEvents); + static APPLICATIONCORE_API void QueueTouchInput(const TArray& InTouchEvents); static void QueueKeyInput(int32 Key, int32 Char); //~ Begin Exec Interface @@ -154,6 +154,9 @@ private: #if !PLATFORM_TVOS /** Access to the ios devices motion */ CMMotionManager* MotionManager; + + /** Is motion paused or not? */ + bool bPauseMotion; /** Access to the ios devices tilt information */ CMAttitude* ReferenceAttitude; diff --git a/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSPlatformApplicationMisc.h b/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSPlatformApplicationMisc.h index fc57d8582239..13e4edec2046 100644 --- a/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSPlatformApplicationMisc.h +++ b/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSPlatformApplicationMisc.h @@ -8,6 +8,7 @@ struct APPLICATIONCORE_API FIOSPlatformApplicationMisc : public FGenericPlatform { static void LoadPreInitModules(); + static class FFeedbackContext* GetFeedbackContext(); static class FOutputDeviceError* GetErrorOutputDevice(); static class GenericApplication* CreateApplication(); static bool IsScreensaverEnabled(); diff --git a/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSView.h b/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSView.h index d9a3f331bd4f..3e37ea1c4fde 100644 --- a/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSView.h +++ b/Engine/Source/Runtime/ApplicationCore/Public/IOS/IOSView.h @@ -3,6 +3,9 @@ #pragma once #include "CoreTypes.h" +#include "Delegates/Delegate.h" +#include "IOS/IOSInputInterface.h" + #import #import @@ -25,6 +28,8 @@ struct FKeyboardConfig bSecureTextEntry(NO) {} }; + +APPLICATIONCORE_API @interface FIOSView : UIView { @public @@ -42,13 +47,14 @@ struct FKeyboardConfig bool HasMoved[10]; +#if HAS_OPENGL_ES //// GL MEMBERS // the GL context EAGLContext* Context; // the internal MSAA FBO used to resolve the color buffer at present-time GLuint ResolveFrameBuffer; - +#endif //// METAL MEMBERS #if HAS_METAL @@ -75,6 +81,8 @@ struct FKeyboardConfig BOOL bSecureTextEntry; volatile int32 KeyboardShowCount; + + } @@ -99,12 +107,20 @@ struct FKeyboardConfig - (id)MakeDrawable; #endif - //// KEYBOARD FUNCTIONALITY -(void)InitKeyboard; -(void)ActivateKeyboard:(bool)bInSendEscapeOnClose; -(void)ActivateKeyboard:(bool)bInSendEscapeOnClose keyboardConfig:(FKeyboardConfig)KeyboardConfig; -(void)DeactivateKeyboard; + +// callable from outside to fake locations +-(void)HandleTouchAtLoc:(CGPoint)Loc PrevLoc:(CGPoint)PrevLoc TouchIndex:(int)TouchIndex Force:(float)Force Type:(TouchType)Type TouchesArray:(TArray&)TouchesArray; + +#if BUILD_EMBEDDED_APP +// startup UE before we have a view - so that we don't need block on Metal device creation, which can take .5-1.5 seconds! ++(void)StartupEmbeddedUnreal; +#endif + @end diff --git a/Engine/Source/Runtime/AssetRegistry/Private/AssetRegistry.cpp b/Engine/Source/Runtime/AssetRegistry/Private/AssetRegistry.cpp index fc4ec27878e1..1724291ae46a 100644 --- a/Engine/Source/Runtime/AssetRegistry/Private/AssetRegistry.cpp +++ b/Engine/Source/Runtime/AssetRegistry/Private/AssetRegistry.cpp @@ -2990,4 +2990,4 @@ bool UAssetRegistryImpl::SetPrimaryAssetIdForObjectPath(const FName ObjectPath, const FAssetData* UAssetRegistryImpl::GetCachedAssetDataForObjectPath(const FName ObjectPath) const { return State.GetAssetByObjectPath(ObjectPath); -} +} \ No newline at end of file diff --git a/Engine/Source/Runtime/AudioMixer/Classes/Generators/AudioGenerator.h b/Engine/Source/Runtime/AudioMixer/Classes/Generators/AudioGenerator.h new file mode 100644 index 000000000000..d437b111e508 --- /dev/null +++ b/Engine/Source/Runtime/AudioMixer/Classes/Generators/AudioGenerator.h @@ -0,0 +1,55 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "UObject/ObjectMacros.h" +#include "UObject/Object.h" + +#include "AudioGenerator.generated.h" + +struct FAudioGeneratorHandle +{ + int32 Id; + + FAudioGeneratorHandle() + : Id(INDEX_NONE) + {} +}; + +typedef TFunction FOnAudioGenerate; + +UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent)) +class AUDIOMIXER_API UAudioGenerator : public UObject +{ + GENERATED_BODY() + +public: + UAudioGenerator(); + virtual ~UAudioGenerator(); + + // Returns the sample rate of the generator + int32 GetSampleRate() const { return SampleRate; } + + // Returns the number of channels of the generator + int32 GetNumChannels() const { return NumChannels; } + + // Adds a generator delegate. Returns a handle for the generator delegate, so it can be removed. + FAudioGeneratorHandle AddGeneratorDelegate(FOnAudioGenerate InFunction); + + // Removes the given audio generator delegate handle + void RemoveGeneratorDelegate(FAudioGeneratorHandle InHandle); + +protected: + + // Called by derived classes to initialize the sample rate and num channels of the generator + void Init(int32 InSampleRate, int32 InNumChannels); + + // Called by derived classes when new audio is generated + void OnGeneratedAudio(const float* InAudio, int32 NumSamples); + + FCriticalSection CritSect; + int32 SampleRate; + int32 NumChannels; + TMap OnGeneratedMap; +}; \ No newline at end of file diff --git a/Engine/Source/Runtime/AudioMixer/Private/DSP/OpusEncoder.cpp b/Engine/Source/Runtime/AudioMixer/Private/DSP/OpusEncoder.cpp index 46ccde150f05..122182f347e7 100644 --- a/Engine/Source/Runtime/AudioMixer/Private/DSP/OpusEncoder.cpp +++ b/Engine/Source/Runtime/AudioMixer/Private/DSP/OpusEncoder.cpp @@ -428,7 +428,7 @@ bool FOpusEncoder::EncodeChunk(const TArray& InAudio, TArray& OutB return true; } -#endif +#endif // PLATFORM_IOS } bool FOpusEncoder::EndFile(TArray& OutBytes) diff --git a/Engine/Source/Runtime/AudioMixer/Private/Generators/AudioGenerator.cpp b/Engine/Source/Runtime/AudioMixer/Private/Generators/AudioGenerator.cpp new file mode 100644 index 000000000000..59cb3eae1a00 --- /dev/null +++ b/Engine/Source/Runtime/AudioMixer/Private/Generators/AudioGenerator.cpp @@ -0,0 +1,45 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "Generators/AudioGenerator.h" + +UAudioGenerator::UAudioGenerator() +{ +} + +UAudioGenerator::~UAudioGenerator() +{ +} + +FAudioGeneratorHandle UAudioGenerator::AddGeneratorDelegate(FOnAudioGenerate InFunction) +{ + static int32 Id = 0; + + FAudioGeneratorHandle NewHandle; + NewHandle.Id = Id++; + + FScopeLock Lock(&CritSect); + OnGeneratedMap.Add(NewHandle.Id, MoveTemp(InFunction)); + return NewHandle; +} + +void UAudioGenerator::RemoveGeneratorDelegate(FAudioGeneratorHandle InHandle) +{ + FScopeLock Lock(&CritSect); + OnGeneratedMap.Remove(InHandle.Id); +} + +void UAudioGenerator::Init(int32 InSampleRate, int32 InNumChannels) +{ + SampleRate = InSampleRate; + NumChannels = InNumChannels; +} + +void UAudioGenerator::OnGeneratedAudio(const float* InAudio, int32 NumSamples) +{ + FScopeLock Lock(&CritSect); + for (auto& It : OnGeneratedMap) + { + It.Value(InAudio, NumSamples); + } +} + diff --git a/Engine/Source/Runtime/AudioMixer/Public/Components/SynthComponent.h b/Engine/Source/Runtime/AudioMixer/Public/Components/SynthComponent.h index 793319685f07..140a8b9b6f86 100644 --- a/Engine/Source/Runtime/AudioMixer/Public/Components/SynthComponent.h +++ b/Engine/Source/Runtime/AudioMixer/Public/Components/SynthComponent.h @@ -17,6 +17,13 @@ #include "DSP/SinOsc.h" #endif +/** Simple interface class to allow objects to route audio between them. */ +class IAudioBufferListener +{ +public: + virtual void OnGeneratedBuffer(const float* AudioBuffer, const int32 NumSamples, const int32 NumChannels) = 0; +}; + class USynthComponent; class USoundConcurrency; @@ -192,6 +199,10 @@ public: void OnAudioComponentEnvelopeValue(const UAudioComponent* AudioComponent, const USoundWave* SoundWave, const float EnvelopeValue); + // Adds and removes audio buffer listener + void AddAudioBufferListener(IAudioBufferListener* InAudioBufferListener); + void RemoveAudioBufferListener(IAudioBufferListener* InAudioBufferListener); + protected: // Method to execute parameter changes on game thread in audio render thread diff --git a/Engine/Source/Runtime/AudioPlatformConfiguration/AudioPlatformConfiguration.Build.cs b/Engine/Source/Runtime/AudioPlatformConfiguration/AudioPlatformConfiguration.Build.cs index d16e066aefac..5b6c533fc0d7 100644 --- a/Engine/Source/Runtime/AudioPlatformConfiguration/AudioPlatformConfiguration.Build.cs +++ b/Engine/Source/Runtime/AudioPlatformConfiguration/AudioPlatformConfiguration.Build.cs @@ -16,12 +16,7 @@ namespace UnrealBuildTool.Rules PrivateIncludePathModuleNames.Add("Engine"); - if (Target.Type == TargetType.Editor && Target.Platform != UnrealTargetPlatform.Linux) - { - AddEngineThirdPartyPrivateStaticDependencies(Target, - "UELibSampleRate" - ); - } + AddEngineThirdPartyPrivateStaticDependencies(Target, "UELibSampleRate"); } } } diff --git a/Engine/Source/Runtime/AudioPlatformConfiguration/Private/AudioResampler.cpp b/Engine/Source/Runtime/AudioPlatformConfiguration/Private/AudioResampler.cpp index 944ab0a5c950..4c740ddfd7f6 100644 --- a/Engine/Source/Runtime/AudioPlatformConfiguration/Private/AudioResampler.cpp +++ b/Engine/Source/Runtime/AudioPlatformConfiguration/Private/AudioResampler.cpp @@ -3,7 +3,11 @@ #include "AudioResampler.h" // Convenience macro for the case in which LibSampleRate needs to be built for limited platforms. +#ifndef WITH_LIBSAMPLERATE #define WITH_LIBSAMPLERATE (WITH_EDITOR && !PLATFORM_LINUX) +#endif + +DEFINE_LOG_CATEGORY(LogAudioResampler); #if WITH_LIBSAMPLERATE #include "samplerate.h" @@ -16,19 +20,19 @@ namespace Audio { if (OutData.OutBuffer == nullptr) { - UE_LOG(LogTemp, Error, TEXT("Please specify an output buffer when using Resample().")); + UE_LOG(LogAudioResampler, Error, TEXT("Please specify an output buffer when using Resample().")); return false; } if (InParameters.SourceSampleRate <= 0.0f || InParameters.DestinationSampleRate <= 0.0f) { - UE_LOG(LogTemp, Error, TEXT("Please use non-zero, positive sample rates when calling Resample().")); + UE_LOG(LogAudioResampler, Error, TEXT("Please use non-zero, positive sample rates when calling Resample().")); return false; } if (OutData.OutBuffer->Num() < GetOutputBufferSize(InParameters)) { - UE_LOG(LogTemp, Error, TEXT("Insufficient space in output buffer: Please allocate space for %d samples."), GetOutputBufferSize(InParameters)); + UE_LOG(LogAudioResampler, Error, TEXT("Insufficient space in output buffer: Please allocate space for %d samples."), GetOutputBufferSize(InParameters)); return false; } @@ -82,4 +86,156 @@ namespace Audio #endif //WITH_LIBSAMPLERATE return true; } + + class FResamplerImpl + { + public: + FResamplerImpl(); + ~FResamplerImpl(); + + void Init(EResamplingMethod ResamplingMethod, float StartingSampleRateRatio, int32 InNumChannels); + void SetSampleRateRatio(float InRatio); + int32 ProcessAudio(float* InAudioBuffer, int32 InSamples, bool bEndOfInput, float* OutAudioBuffer, int32 MaxOutputFrames, int32& OutNumFrames); + +#if WITH_LIBSAMPLERATE + float CurrentSampleRateRatio; + SRC_STATE* LibSRCState; + SRC_DATA Data; +#endif + + }; + +#if WITH_LIBSAMPLERATE + FResamplerImpl::FResamplerImpl() + : CurrentSampleRateRatio(-1.0f) + , LibSRCState(nullptr) + { + } + + FResamplerImpl::~FResamplerImpl() + { + if (LibSRCState) + { + LibSRCState = src_delete(LibSRCState); + } + check(!LibSRCState); + } + + void FResamplerImpl::Init(EResamplingMethod ResamplingMethod, float StartingSampleRateRatio, int32 InNumChannels) + { + int32 ErrorResult = 0; + + // Reset the SRC state if we already have one + if (LibSRCState) + { + ErrorResult = src_reset(LibSRCState); + if (ErrorResult != 0) + { + const char* ErrorString = src_strerror(ErrorResult); + UE_LOG(LogAudioResampler, Error, TEXT("Failed to reset sample converter state: %s."), ErrorString); + return; + } + } + // Otherwise create a new one + else + { + LibSRCState = src_new((int32)ResamplingMethod, InNumChannels, &ErrorResult); + if (!LibSRCState) + { + const char* ErrorString = src_strerror(ErrorResult); + UE_LOG(LogAudioResampler, Error, TEXT("Failed to create a sample rate convertor state object: %s."), ErrorString); + } + } + + if (LibSRCState) + { + ErrorResult = src_set_ratio(LibSRCState, StartingSampleRateRatio); + if (ErrorResult != 0) + { + const char* ErrorString = src_strerror(ErrorResult); + UE_LOG(LogAudioResampler, Error, TEXT("Failed to set sample rate ratio: %s."), ErrorString); + } + } + + CurrentSampleRateRatio = StartingSampleRateRatio; + } + + void FResamplerImpl::SetSampleRateRatio(float InRatio) + { + CurrentSampleRateRatio = FMath::Max(InRatio, 0.00001f); + } + + int32 FResamplerImpl::ProcessAudio(float* InAudioBuffer, int32 InSamples, bool bEndOfInput, float* OutAudioBuffer, int32 MaxOutputFrames, int32& OutNumFrames) + { + if (LibSRCState) + { + Data.data_in = InAudioBuffer; + Data.input_frames = InSamples; + Data.data_out = OutAudioBuffer; + Data.output_frames = MaxOutputFrames; + Data.src_ratio = (double)CurrentSampleRateRatio; + Data.end_of_input = bEndOfInput ? 1 : 0; + + int32 ErrorResult = src_process(LibSRCState, &Data); + if (ErrorResult != 0) + { + const char* ErrorString = src_strerror(ErrorResult); + UE_LOG(LogAudioResampler, Error, TEXT("Failed to process audio: %s."), ErrorString); + return ErrorResult; + } + + OutNumFrames = Data.output_frames_gen; + } + return 0; + } + +#else + // Null implementation + FResamplerImpl::FResamplerImpl() {} + FResamplerImpl::~FResamplerImpl() {} + void FResamplerImpl::Init(EResamplingMethod ResamplingMethod, float StartingSampleRateRatio, int32 InNumChannels) {} + void FResamplerImpl::SetSampleRateRatio(float InRatio) {} + int32 FResamplerImpl::ProcessAudio(float* InAudioBuffer, int32 InSamples, bool bEndOfInput, float* OutAudioBuffer, int32 MaxOutputFrames, int32& OutNumFrames) { return 0; } +#endif + + FResampler::FResampler() + { + Impl = CreateImpl(); + } + + FResampler::~FResampler() + { + + } + + void FResampler::Init(EResamplingMethod ResamplingMethod, float StartingSampleRateRatio, int32 InNumChannels) + { + if (Impl.IsValid()) + { + Impl->Init(ResamplingMethod, StartingSampleRateRatio, InNumChannels); + } + } + + void FResampler::SetSampleRateRatio(float InRatio) + { + if (Impl.IsValid()) + { + Impl->SetSampleRateRatio(InRatio); + } + } + + int32 FResampler::ProcessAudio(float* InAudioBuffer, int32 InSamples, bool bEndOfInput, float* OutAudioBuffer, int32 MaxOutputFrames, int32& OutNumFrames) + { + if (Impl.IsValid()) + { + return Impl->ProcessAudio(InAudioBuffer, InSamples, bEndOfInput, OutAudioBuffer, MaxOutputFrames, OutNumFrames); + } + return 0; + } + + TUniquePtr FResampler::CreateImpl() + { + return TUniquePtr(new FResamplerImpl()); + } } + diff --git a/Engine/Source/Runtime/AudioPlatformConfiguration/Public/AudioResampler.h b/Engine/Source/Runtime/AudioPlatformConfiguration/Public/AudioResampler.h index 13b0f342f189..44dd2a01aafd 100644 --- a/Engine/Source/Runtime/AudioPlatformConfiguration/Public/AudioResampler.h +++ b/Engine/Source/Runtime/AudioPlatformConfiguration/Public/AudioResampler.h @@ -11,6 +11,8 @@ #define AUDIO_BUFFER_ALIGNMENT 16 #endif +DECLARE_LOG_CATEGORY_EXTERN(LogAudioResampler, Warning, All); + namespace Audio { typedef TArray> AlignedFloatBuffer; @@ -28,7 +30,7 @@ namespace Audio struct FResamplingParameters { EResamplingMethod ResamplerMethod; - int NumChannels; + int32 NumChannels; float SourceSampleRate; float DestinationSampleRate; AlignedFloatBuffer& InputBuffer; @@ -40,9 +42,9 @@ namespace Audio float ResultingSampleRate; - int InputFramesUsed; + int32 InputFramesUsed; - int OutputFramesGenerated; + int32 OutputFramesGenerated; FResamplerResults() : OutBuffer(nullptr) @@ -57,6 +59,24 @@ namespace Audio // Simple, inline resampler. Returns true on success, false otherwise. AUDIOPLATFORMCONFIGURATION_API bool Resample(const FResamplingParameters& InParameters, FResamplerResults& OutData); + + + class FResamplerImpl; + + class AUDIOPLATFORMCONFIGURATION_API FResampler + { + public: + FResampler(); + ~FResampler(); + + void Init(EResamplingMethod ResamplingMethod, float StartingSampleRateRatio, int32 InNumChannels); + void SetSampleRateRatio(float InRatio); + int32 ProcessAudio(float* InAudioBuffer, int32 InSamples, bool bEndOfInput, float* OutAudioBuffer, int32 MaxOutputFrames, int32& OutNumFrames); + + private: + TUniquePtr CreateImpl(); + TUniquePtr Impl; + }; } diff --git a/Engine/Source/Runtime/AugmentedReality/Private/ARBlueprintLibrary.cpp b/Engine/Source/Runtime/AugmentedReality/Private/ARBlueprintLibrary.cpp index bcfe0b9dbc61..adaef9809595 100644 --- a/Engine/Source/Runtime/AugmentedReality/Private/ARBlueprintLibrary.cpp +++ b/Engine/Source/Runtime/AugmentedReality/Private/ARBlueprintLibrary.cpp @@ -8,14 +8,14 @@ #include "ARPin.h" #include "ARTrackable.h" -TSharedPtr UARBlueprintLibrary::RegisteredARSystem = nullptr; +TWeakPtr UARBlueprintLibrary::RegisteredARSystem = nullptr; EARTrackingQuality UARBlueprintLibrary::GetTrackingQuality() { auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return ARSystem->GetTrackingQuality(); + return ARSystem.Pin()->GetTrackingQuality(); } else { @@ -23,6 +23,27 @@ EARTrackingQuality UARBlueprintLibrary::GetTrackingQuality() } } +EARTrackingQualityReason UARBlueprintLibrary::GetTrackingQualityReason() +{ + // @todo merge-check +// auto ARSystem = GetARSystem(); +// if (ARSystem.IsValid()) +// { +// return ARSystem->GetTrackingQualityReason(); +// } +// else + { + return EARTrackingQualityReason::None; + } +} + +bool UARBlueprintLibrary::IsARSupported(void) +{ + // @todo merge-check +// return GetARSystem().IsValid() && GetARSystem()->IsARAvailable(); + return true; +} + void UARBlueprintLibrary::StartARSession(UARSessionConfig* SessionConfig) { if (SessionConfig == nullptr) @@ -39,7 +60,7 @@ void UARBlueprintLibrary::StartARSession(UARSessionConfig* SessionConfig) auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - ARSystem->StartARSession(SessionConfig); + ARSystem.Pin()->StartARSession(SessionConfig); } else { @@ -54,7 +75,7 @@ void UARBlueprintLibrary::PauseARSession() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - ARSystem->PauseARSession(); + ARSystem.Pin()->PauseARSession(); } } @@ -63,7 +84,7 @@ void UARBlueprintLibrary::StopARSession() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - ARSystem->StopARSession(); + ARSystem.Pin()->StopARSession(); } } @@ -72,7 +93,7 @@ FARSessionStatus UARBlueprintLibrary::GetARSessionStatus() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return ARSystem->GetARSessionStatus(); + return ARSystem.Pin()->GetARSessionStatus(); } else { @@ -84,7 +105,7 @@ UARSessionConfig* UARBlueprintLibrary::GetSessionConfig() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return &ARSystem->AccessSessionConfig(); + return &ARSystem.Pin()->AccessSessionConfig(); } else { @@ -98,7 +119,7 @@ void UARBlueprintLibrary::SetAlignmentTransform( const FTransform& InAlignmentTr auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return ARSystem->SetAlignmentTransform( InAlignmentTransform ); + return ARSystem.Pin()->SetAlignmentTransform( InAlignmentTransform ); } } @@ -116,7 +137,7 @@ TArray UARBlueprintLibrary::LineTraceTrackedObjects( const FVect (bTestPlaneExtents ? EARLineTraceChannels::PlaneUsingExtent : EARLineTraceChannels::None ) | (bTestPlaneBoundaryPolygon ? EARLineTraceChannels::PlaneUsingBoundaryPolygon : EARLineTraceChannels::None); - Result = ARSystem->LineTraceTrackedObjects(ScreenCoord, ActiveTraceChannels); + Result = ARSystem.Pin()->LineTraceTrackedObjects(ScreenCoord, ActiveTraceChannels); } return Result; @@ -135,7 +156,7 @@ TArray UARBlueprintLibrary::LineTraceTrackedObjects3D(const FVec (bTestPlaneExtents ? EARLineTraceChannels::PlaneUsingExtent : EARLineTraceChannels::None) | (bTestPlaneBoundaryPolygon ? EARLineTraceChannels::PlaneUsingBoundaryPolygon : EARLineTraceChannels::None); - Result = ARSystem->LineTraceTrackedObjects(Start, End, ActiveTraceChannels); + Result = ARSystem.Pin()->LineTraceTrackedObjects(Start, End, ActiveTraceChannels); } return Result; @@ -148,7 +169,7 @@ TArray UARBlueprintLibrary::GetAllGeometries() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - Geometries = ARSystem->GetAllTrackedGeometries(); + Geometries = ARSystem.Pin()->GetAllTrackedGeometries(); } return Geometries; } @@ -160,7 +181,7 @@ TArray UARBlueprintLibrary::GetAllPins() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - Pins = ARSystem->GetAllPins(); + Pins = ARSystem.Pin()->GetAllPins(); } return Pins; } @@ -170,7 +191,7 @@ bool UARBlueprintLibrary::IsSessionTypeSupported(EARSessionType SessionType) auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return ARSystem->IsSessionTypeSupported(SessionType); + return ARSystem.Pin()->IsSessionTypeSupported(SessionType); } return false; } @@ -200,7 +221,7 @@ UARLightEstimate* UARBlueprintLibrary::GetCurrentLightEstimate() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return ARSystem->GetCurrentLightEstimate(); + return ARSystem.Pin()->GetCurrentLightEstimate(); } return nullptr; } @@ -210,7 +231,7 @@ UARPin* UARBlueprintLibrary::PinComponent( USceneComponent* ComponentToPin, cons auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return ARSystem->PinComponent( ComponentToPin, PinToWorldTransform, TrackedGeometry, DebugName ); + return ARSystem.Pin()->PinComponent( ComponentToPin, PinToWorldTransform, TrackedGeometry, DebugName ); } return nullptr; } @@ -220,7 +241,7 @@ UARPin* UARBlueprintLibrary::PinComponentToTraceResult( USceneComponent* Compone auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return ARSystem->PinComponent( ComponentToPin, TraceResult, DebugName ); + return ARSystem.Pin()->PinComponent( ComponentToPin, TraceResult, DebugName ); } return nullptr; } @@ -230,13 +251,14 @@ void UARBlueprintLibrary::UnpinComponent( USceneComponent* ComponentToUnpin ) auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - TArray AllPins = ARSystem->GetAllPins(); + auto PinnedARSystem = ARSystem.Pin(); + TArray AllPins = PinnedARSystem->GetAllPins(); const int32 AllPinsCount = AllPins.Num(); for (int32 i=0; iGetPinnedComponent() == ComponentToUnpin) { - ARSystem->RemovePin( AllPins[i] ); + PinnedARSystem->RemovePin( AllPins[i] ); return; } } @@ -248,19 +270,19 @@ void UARBlueprintLibrary::RemovePin( UARPin* PinToRemove ) auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return ARSystem->RemovePin( PinToRemove ); + return ARSystem.Pin()->RemovePin( PinToRemove ); } } -void UARBlueprintLibrary::RegisterAsARSystem(const TSharedPtr& NewARSystem) +void UARBlueprintLibrary::RegisterAsARSystem(const TSharedRef& NewARSystem) { RegisteredARSystem = NewARSystem; } -const TSharedPtr& UARBlueprintLibrary::GetARSystem() +const TWeakPtr& UARBlueprintLibrary::GetARSystem() { return RegisteredARSystem; } @@ -299,7 +321,7 @@ UARTextureCameraImage* UARBlueprintLibrary::GetCameraImage() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - Image = ARSystem->GetCameraImage(); + Image = ARSystem.Pin()->GetCameraImage(); } return Image; } @@ -311,7 +333,7 @@ UARTextureCameraDepth* UARBlueprintLibrary::GetCameraDepth() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - Depth = ARSystem->GetCameraDepth(); + Depth = ARSystem.Pin()->GetCameraDepth(); } return Depth; } @@ -323,7 +345,8 @@ TArray UARBlueprintLibrary::GetAllTrackedPlanes() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - for (UARTrackedGeometry* Geo : ARSystem->GetAllTrackedGeometries()) + auto PinnedARSystem = ARSystem.Pin(); + for (UARTrackedGeometry* Geo : PinnedARSystem->GetAllTrackedGeometries()) { if (UARPlaneGeometry* Item = Cast(Geo)) { @@ -341,7 +364,8 @@ TArray UARBlueprintLibrary::GetAllTrackedPoints() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - for (UARTrackedGeometry* Geo : ARSystem->GetAllTrackedGeometries()) + auto PinnedARSystem = ARSystem.Pin(); + for (UARTrackedGeometry* Geo : PinnedARSystem->GetAllTrackedGeometries()) { if (UARTrackedPoint* Item = Cast(Geo)) { @@ -359,7 +383,8 @@ TArray UARBlueprintLibrary::GetAllTrackedImages() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - for (UARTrackedGeometry* Geo : ARSystem->GetAllTrackedGeometries()) + auto PinnedARSystem = ARSystem.Pin(); + for (UARTrackedGeometry* Geo : PinnedARSystem->GetAllTrackedGeometries()) { if (UARTrackedImage* Item = Cast(Geo)) { @@ -377,7 +402,8 @@ TArray UARBlueprintLibrary::GetAllTrackedEnvironmen auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - for (UARTrackedGeometry* Geo : ARSystem->GetAllTrackedGeometries()) + auto PinnedARSystem = ARSystem.Pin(); + for (UARTrackedGeometry* Geo : PinnedARSystem->GetAllTrackedGeometries()) { if (UAREnvironmentCaptureProbe* Item = Cast(Geo)) { @@ -393,7 +419,7 @@ bool UARBlueprintLibrary::AddManualEnvironmentCaptureProbe(FVector Location, FVe auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return ARSystem->AddManualEnvironmentCaptureProbe(Location, Extent); + return ARSystem.Pin()->AddManualEnvironmentCaptureProbe(Location, Extent); } return false; } @@ -403,7 +429,7 @@ EARWorldMappingState UARBlueprintLibrary::GetWorldMappingStatus() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return ARSystem->GetWorldMappingStatus(); + return ARSystem.Pin()->GetWorldMappingStatus(); } return EARWorldMappingState::NotAvailable; } @@ -413,7 +439,7 @@ TSharedPtr UARBlueprintLibrary::Save auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return ARSystem->SaveWorld(); + return ARSystem.Pin()->SaveWorld(); } return TSharedPtr(); @@ -424,7 +450,7 @@ TSharedPtr UARBlueprintLibr auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return ARSystem->GetCandidateObject(Location, Extent); + return ARSystem.Pin()->GetCandidateObject(Location, Extent); } return TSharedPtr(); @@ -435,7 +461,7 @@ TArray UARBlueprintLibrary::GetPointCloud() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return ARSystem->GetPointCloud(); + return ARSystem.Pin()->GetPointCloud(); } return TArray(); } @@ -445,7 +471,7 @@ TArray UARBlueprintLibrary::GetSupportedVideoFormats(EARSessionT auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - return ARSystem->GetSupportedVideoFormats(SessionType); + return ARSystem.Pin()->GetSupportedVideoFormats(SessionType); } return TArray(); } @@ -455,7 +481,7 @@ UARCandidateImage* UARBlueprintLibrary::AddRuntimeCandidateImage(UARSessionConfi auto ARSystem = GetARSystem(); if (ensure(ARSystem.IsValid())) { - return ARSystem->AddRuntimeCandidateImage(SessionConfig, CandidateTexture, FriendlyName, PhysicalWidth); + return ARSystem.Pin()->AddRuntimeCandidateImage(SessionConfig, CandidateTexture, FriendlyName, PhysicalWidth); } else { diff --git a/Engine/Source/Runtime/AugmentedReality/Private/ARBlueprintProxy.cpp b/Engine/Source/Runtime/AugmentedReality/Private/ARBlueprintProxy.cpp index 6d28c40d1d1e..0b0d55810a3f 100644 --- a/Engine/Source/Runtime/AugmentedReality/Private/ARBlueprintProxy.cpp +++ b/Engine/Source/Runtime/AugmentedReality/Private/ARBlueprintProxy.cpp @@ -3,7 +3,7 @@ #include "ARBlueprintProxy.h" #include "ARSystem.h" -TSharedPtr UARBaseAsyncTaskBlueprintProxy::RegisteredARSystem = nullptr; +TWeakPtr UARBaseAsyncTaskBlueprintProxy::RegisteredARSystem = nullptr; UARBaseAsyncTaskBlueprintProxy::UARBaseAsyncTaskBlueprintProxy(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) @@ -35,13 +35,13 @@ void UARBaseAsyncTaskBlueprintProxy::Tick(float DeltaTime) } } -void UARBaseAsyncTaskBlueprintProxy::RegisterAsARSystem(const TSharedPtr& NewARSystem) +void UARBaseAsyncTaskBlueprintProxy::RegisterAsARSystem(const TSharedRef& NewARSystem) { RegisteredARSystem = NewARSystem; } -const TSharedPtr& UARBaseAsyncTaskBlueprintProxy::GetARSystem() +const TWeakPtr& UARBaseAsyncTaskBlueprintProxy::GetARSystem() { return RegisteredARSystem; } @@ -58,7 +58,7 @@ void UARSaveWorldAsyncTaskBlueprintProxy::Activate() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - SaveWorldTask = ARSystem->SaveWorld(); + SaveWorldTask = ARSystem.Pin()->SaveWorld(); AsyncTask = SaveWorldTask; } else @@ -92,7 +92,7 @@ void UARGetCandidateObjectAsyncTaskBlueprintProxy::Activate() auto ARSystem = GetARSystem(); if (ARSystem.IsValid()) { - CandidateObjectTask = ARSystem->GetCandidateObject(Location, Extent); + CandidateObjectTask = ARSystem.Pin()->GetCandidateObject(Location, Extent); AsyncTask = CandidateObjectTask; } else diff --git a/Engine/Source/Runtime/AugmentedReality/Private/ARSupportInterface.cpp b/Engine/Source/Runtime/AugmentedReality/Private/ARSupportInterface.cpp index 499febba3d2b..752e34e85715 100644 --- a/Engine/Source/Runtime/AugmentedReality/Private/ARSupportInterface.cpp +++ b/Engine/Source/Runtime/AugmentedReality/Private/ARSupportInterface.cpp @@ -17,16 +17,11 @@ FARSupportInterface ::FARSupportInterface (IARSystemSupport* InARImplementation, { } - FARSupportInterface ::~FARSupportInterface () { IModularFeatures::Get().UnregisterModularFeature(FARSupportInterface ::GetModularFeatureName(), this); - - UARBlueprintLibrary::RegisterAsARSystem(nullptr); - UARBaseAsyncTaskBlueprintProxy::RegisterAsARSystem(nullptr); } - void FARSupportInterface ::InitializeARSystem() { // Register our ability to support Unreal AR API. @@ -34,8 +29,8 @@ void FARSupportInterface ::InitializeARSystem() if (ARImplemention) { - UARBlueprintLibrary::RegisterAsARSystem(MakeShareable(this)); - UARBaseAsyncTaskBlueprintProxy::RegisterAsARSystem(MakeShareable(this)); + UARBlueprintLibrary::RegisterAsARSystem(AsShared()); + UARBaseAsyncTaskBlueprintProxy::RegisterAsARSystem(AsShared()); ARImplemention->OnARSystemInitialized(); } diff --git a/Engine/Source/Runtime/AugmentedReality/Public/ARBlueprintLibrary.h b/Engine/Source/Runtime/AugmentedReality/Public/ARBlueprintLibrary.h index e50751963d1e..1da8cf99d20f 100644 --- a/Engine/Source/Runtime/AugmentedReality/Public/ARBlueprintLibrary.h +++ b/Engine/Source/Runtime/AugmentedReality/Public/ARBlueprintLibrary.h @@ -12,6 +12,7 @@ #include "ARBlueprintLibrary.generated.h" + UCLASS(meta=(ScriptName="ARLibrary")) class AUGMENTEDREALITY_API UARBlueprintLibrary : public UBlueprintFunctionLibrary { @@ -19,6 +20,13 @@ class AUGMENTEDREALITY_API UARBlueprintLibrary : public UBlueprintFunctionLibrar public: + /** + * Checks if the current device can support AR + * + */ + UFUNCTION(BlueprintCallable, Category = "AR AugmentedReality|Session", meta = (DisplayName="Is AR Supported", Keywords = "ar augmentedreality augmented reality session start run running")) + static bool IsARSupported(); + /** * Begin a new Augmented Reality session. Subsequently, use the \c GetARSessionStatus() function to figure out the status of the session. * @@ -84,11 +92,15 @@ public: */ UFUNCTION(BlueprintCallable, Category = "AR AugmentedReality|Trace Result", meta = (AdvancedDisplay = "1", Keywords = "ar augmentedreality augmented reality tracking tracing linetrace")) static TArray LineTraceTrackedObjects3D(const FVector Start, const FVector End, bool bTestFeaturePoints = true, bool bTestGroundPlane = true, bool bTestPlaneExtents = true, bool bTestPlaneBoundaryPolygon = true); - + /** @return how well the tracking system is performing at the moment */ UFUNCTION(BlueprintPure, Category = "AR AugmentedReality|Tracking", meta = (DisplayName="Get AR Tracking Quality", Keywords = "ar augmentedreality augmented reality tracking quality")) static EARTrackingQuality GetTrackingQuality(); + /** @return The reason for the current limited tracking state */ + UFUNCTION(BlueprintPure, Category = "AR AugmentedReality|Tracking", meta = (DisplayName="Get AR Tracking Quality Reason", Keywords = "ar augmentedreality augmented reality tracking quality reason")) + static EARTrackingQualityReason GetTrackingQualityReason(); + /** @return a list of all the real-world geometry as currently seen by the Augmented Reality system */ UFUNCTION(BlueprintCallable, Category = "AR AugmentedReality|Tracking", meta = (DisplayName="Get All AR Geometries", Keywords = "ar augmentedreality augmented reality tracking geometry anchor")) static TArray GetAllGeometries(); @@ -219,11 +231,11 @@ public: static UARCandidateImage* AddRuntimeCandidateImage(UARSessionConfig* SessionConfig, UTexture2D* CandidateTexture, FString FriendlyName, float PhysicalWidth); public: - static void RegisterAsARSystem(const TSharedPtr& NewArSystem); + static void RegisterAsARSystem(const TSharedRef& NewArSystem); private: - static const TSharedPtr& GetARSystem(); - static TSharedPtr RegisteredARSystem; + static const TWeakPtr& GetARSystem(); + static TWeakPtr RegisteredARSystem; }; diff --git a/Engine/Source/Runtime/AugmentedReality/Public/ARBlueprintProxy.h b/Engine/Source/Runtime/AugmentedReality/Public/ARBlueprintProxy.h index e902ab5575ba..33ce3688787a 100644 --- a/Engine/Source/Runtime/AugmentedReality/Public/ARBlueprintProxy.h +++ b/Engine/Source/Runtime/AugmentedReality/Public/ARBlueprintProxy.h @@ -31,10 +31,10 @@ public: virtual void ReportSuccess() { check(0); } virtual void ReportFailure() { check(0); } - static void RegisterAsARSystem(const TSharedPtr& NewArSystem); + static void RegisterAsARSystem(const TSharedRef& NewArSystem); protected: - static const TSharedPtr& GetARSystem(); + static const TWeakPtr& GetARSystem(); /** The async task to check during Tick() */ TSharedPtr AsyncTask; @@ -42,7 +42,7 @@ private: /** True until the async task completes, then false */ bool bShouldTick; - static TSharedPtr RegisteredARSystem; + static TWeakPtr RegisteredARSystem; }; DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FARSaveWorldPin, const TArray&, SavedWorld); diff --git a/Engine/Source/Runtime/AugmentedReality/Public/ARSupportInterface.h b/Engine/Source/Runtime/AugmentedReality/Public/ARSupportInterface.h index 663071b3afea..216bc45cde1b 100644 --- a/Engine/Source/Runtime/AugmentedReality/Public/ARSupportInterface.h +++ b/Engine/Source/Runtime/AugmentedReality/Public/ARSupportInterface.h @@ -16,7 +16,7 @@ DECLARE_MULTICAST_DELEGATE_OneParam(FARSystemOnAlignmentTransformUpdated, const * Composition Components for tracking system features */ -class AUGMENTEDREALITY_API FARSupportInterface : public FGCObject, public IModularFeature +class AUGMENTEDREALITY_API FARSupportInterface : public TSharedFromThis, public FGCObject, public IModularFeature { public: FARSupportInterface (IARSystemSupport* InARImplementation, IXRTrackingSystem* InXRTrackingSystem); diff --git a/Engine/Source/Runtime/AugmentedReality/Public/ARSystem.h b/Engine/Source/Runtime/AugmentedReality/Public/ARSystem.h index 852fab83b88e..a168cfbba082 100644 --- a/Engine/Source/Runtime/AugmentedReality/Public/ARSystem.h +++ b/Engine/Source/Runtime/AugmentedReality/Public/ARSystem.h @@ -54,6 +54,10 @@ public: /** @return the tracking quality; if unable to determine tracking quality, return EARTrackingQuality::NotAvailable */ virtual EARTrackingQuality OnGetTrackingQuality() const = 0; + /** @return the reason of limited tracking quality; if the state is not limited, return EARTrackingQualityReason::None */ + // @todo merge-check +// virtual EARTrackingQualityReason OnGetTrackingQualityReason() const = 0; + /** * Start the AR system. * @@ -72,6 +76,9 @@ public: /** @return the info about whether the session is running normally or encountered some kind of error. */ virtual FARSessionStatus OnGetARSessionStatus() const = 0; + /** Returns true/false based on whether AR features are available */ +// virtual bool IsARAvailable() const = 0; + /** * Set a transform that will align the Tracking Space origin to the World Space origin. * This is useful for supporting static geometry and static lighting in AR. @@ -88,7 +95,7 @@ public: */ virtual TArray OnLineTraceTrackedObjects( const FVector2D ScreenCoord, EARLineTraceChannels TraceChannels ) = 0; virtual TArray OnLineTraceTrackedObjects( const FVector Start, const FVector End, EARLineTraceChannels TraceChannels ) = 0; - + /** @return a TArray of all the tracked geometries known to your ar system */ virtual TArray OnGetAllTrackedGeometries() const = 0; @@ -135,16 +142,16 @@ public: /** @return The list of supported video formats for this device and session type */ virtual TArray OnGetSupportedVideoFormats(EARSessionType SessionType) const = 0; - + /** @return the current point cloud data for the ar scene */ virtual TArray OnGetPointCloud() const = 0; - + /** Add candidate image at runtime @return True if it added the iamge successfully */ virtual bool OnAddRuntimeCandidateImage(UARSessionConfig* SessionConfig, UTexture2D* CandidateTexture, FString FriendlyName, float PhysicalWidth) = 0; virtual void* GetARSessionRawPointer() = 0; virtual void* GetGameThreadARFrameRawPointer() = 0; - + public: virtual ~IARSystemSupport(){} diff --git a/Engine/Source/Runtime/AugmentedReality/Public/ARTypes.h b/Engine/Source/Runtime/AugmentedReality/Public/ARTypes.h index 80c289a23865..3bb18be2c7a4 100644 --- a/Engine/Source/Runtime/AugmentedReality/Public/ARTypes.h +++ b/Engine/Source/Runtime/AugmentedReality/Public/ARTypes.h @@ -68,6 +68,25 @@ enum class EARTrackingQuality : uint8 OrientationAndPosition }; +UENUM(BlueprintType, Category="AR AugmentedReality", meta=(Experimental)) +enum class EARTrackingQualityReason : uint8 +{ + /** Current Tracking is not limited */ + None, + + /** The AR session has not yet gathered enough camera or motion data to provide tracking information. */ + Initializing, + + /** The AR session is attempting to resume after an interruption. */ + Relocalizing, + + /** The device is moving too fast for accurate image-based position tracking. */ + ExcessiveMotion, + + /** The scene visible to the camera does not contain enough distinguishable features for image-based position tracking. */ + InsufficientFeatures +}; + /** * Describes the current status of the AR session. */ diff --git a/Engine/Source/Runtime/Core/Core.Build.cs b/Engine/Source/Runtime/Core/Core.Build.cs index 3ef24ef2d325..8a229252937a 100644 --- a/Engine/Source/Runtime/Core/Core.Build.cs +++ b/Engine/Source/Runtime/Core/Core.Build.cs @@ -91,6 +91,9 @@ public class Core : ModuleRules { PublicFrameworks.AddRange(new string[] { "iAD" }); } + + // export Core symbols for embedded Dlls + ModuleSymbolVisibility = ModuleRules.SymbolVisibility.VisibileForDll; } else if (Target.IsInPlatformGroup(UnrealPlatformGroup.Android)) { diff --git a/Engine/Source/Runtime/Core/Private/Android/AndroidFile.cpp b/Engine/Source/Runtime/Core/Private/Android/AndroidFile.cpp index 6c9df74c8141..567ba72d2e8c 100644 --- a/Engine/Source/Runtime/Core/Private/Android/AndroidFile.cpp +++ b/Engine/Source/Runtime/Core/Private/Android/AndroidFile.cpp @@ -9,6 +9,7 @@ #if USE_ANDROID_FILE #include "Misc/App.h" #include "Misc/Paths.h" +#include "Android/AndroidJavaEnv.h" #include #include @@ -99,19 +100,12 @@ extern AAssetManager * AndroidThunkCpp_GetAssetManager(); //This function is declared in the Java-defined class, GameActivity.java: "public native void nativeSetObbInfo(String PackageName, int Version, int PatchVersion);" JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeSetObbInfo(JNIEnv* jenv, jobject thiz, jstring ProjectName, jstring PackageName, jint Version, jint PatchVersion, jstring AppType) { - const char* JavaProjectChars = jenv->GetStringUTFChars(ProjectName, 0); - GAndroidProjectName = UTF8_TO_TCHAR(JavaProjectChars); - const char* JavaPackageChars = jenv->GetStringUTFChars(PackageName, 0); - GPackageName = UTF8_TO_TCHAR(JavaPackageChars); + GAndroidProjectName = FJavaHelper::FStringFromParam(jenv, ProjectName); + GPackageName = FJavaHelper::FStringFromParam(jenv, PackageName); + GAndroidAppType = FJavaHelper::FStringFromParam(jenv, AppType); + GAndroidPackageVersion = Version; GAndroidPackagePatchVersion = PatchVersion; - const char* JavaAppTypeChars = jenv->GetStringUTFChars(AppType, 0); - GAndroidAppType = UTF8_TO_TCHAR(JavaAppTypeChars); - - //Release the strings - jenv->ReleaseStringUTFChars(ProjectName, JavaProjectChars); - jenv->ReleaseStringUTFChars(PackageName, JavaPackageChars); - jenv->ReleaseStringUTFChars(PackageName, JavaAppTypeChars); } // Constructs the base path for any files which are not in OBB/pak data @@ -2023,4 +2017,4 @@ IAndroidPlatformFile & IAndroidPlatformFile::GetPlatformPhysical() { return FAndroidPlatformFile::GetPlatformPhysical(); } -#endif \ No newline at end of file +#endif diff --git a/Engine/Source/Runtime/Core/Private/Android/AndroidJava.cpp b/Engine/Source/Runtime/Core/Private/Android/AndroidJava.cpp index 6299feadbfd2..b7bb6b09f369 100644 --- a/Engine/Source/Runtime/Core/Private/Android/AndroidJava.cpp +++ b/Engine/Source/Runtime/Core/Private/Android/AndroidJava.cpp @@ -12,26 +12,26 @@ FJavaClassObject::FJavaClassObject(FName ClassName, const char* CtorSig, ...) ANSICHAR AnsiClassName[NAME_SIZE]; ClassName.GetPlainANSIString(AnsiClassName); - Class = AndroidJavaEnv::FindJavaClass(AnsiClassName); + Class = AndroidJavaEnv::FindJavaClassGlobalRef(AnsiClassName); check(Class); jmethodID Constructor = JEnv->GetMethodID(Class, "", CtorSig); check(Constructor); va_list Params; va_start(Params, CtorSig); - jobject object = JEnv->NewObjectV(Class, Constructor, Params); + auto LocalObject = NewScopedJavaObject(JEnv, JEnv->NewObjectV(Class, Constructor, Params)); va_end(Params); VerifyException(); - check(object); + check(LocalObject); // Promote local references to global - Object = JEnv->NewGlobalRef(object); - JEnv->DeleteLocalRef(object); + Object = JEnv->NewGlobalRef(*LocalObject); } FJavaClassObject::~FJavaClassObject() { JNIEnv* JEnv = AndroidJavaEnv::GetJavaEnv(); JEnv->DeleteGlobalRef(Object); + JEnv->DeleteGlobalRef(Class); } FJavaClassMethod FJavaClassObject::GetClassMethod(const char* MethodName, const char* FuncSig) @@ -131,19 +131,14 @@ FString FJavaClassObject::CallMethod(FJavaClassMethod Method, ...) JEnv->CallObjectMethodV(Object, Method.Method, Params)); va_end(Params); VerifyException(); - const char * UTFString = JEnv->GetStringUTFChars(RetVal, nullptr); - FString Result(UTF8_TO_TCHAR(UTFString)); - JEnv->ReleaseStringUTFChars(RetVal, UTFString); + auto Result = FJavaHelper::FStringFromLocalRef(JEnv, RetVal); return Result; } -jstring FJavaClassObject::GetJString(const FString& String) +FScopedJavaObject FJavaClassObject::GetJString(const FString& String) { JNIEnv* JEnv = AndroidJavaEnv::GetJavaEnv(); - jstring local = JEnv->NewStringUTF(TCHAR_TO_UTF8(*String)); - jstring result = (jstring)JEnv->NewGlobalRef(local); - JEnv->DeleteLocalRef(local); - return result; + return FJavaHelper::ToJavaString(JEnv, String); } void FJavaClassObject::VerifyException() @@ -157,4 +152,4 @@ void FJavaClassObject::VerifyException() } } -#endif \ No newline at end of file +#endif diff --git a/Engine/Source/Runtime/Core/Private/Android/AndroidJavaEnv.cpp b/Engine/Source/Runtime/Core/Private/Android/AndroidJavaEnv.cpp index bd03a0700c28..563c948b7fad 100644 --- a/Engine/Source/Runtime/Core/Private/Android/AndroidJavaEnv.cpp +++ b/Engine/Source/Runtime/Core/Private/Android/AndroidJavaEnv.cpp @@ -69,8 +69,8 @@ void AndroidJavaEnv::InitializeJavaEnv( JavaVM* VM, jint Version, jobject Global jclass classClass = Env->FindClass("java/lang/Class"); jclass classLoaderClass = Env->FindClass("java/lang/ClassLoader"); jmethodID getClassLoaderMethod = Env->GetMethodID(classClass, "getClassLoader", "()Ljava/lang/ClassLoader;"); - jobject classLoader = Env->CallObjectMethod(MainClass, getClassLoaderMethod); - ClassLoader = Env->NewGlobalRef(classLoader); + auto classLoader = NewScopedJavaObject(Env, Env->CallObjectMethod(MainClass, getClassLoaderMethod)); + ClassLoader = Env->NewGlobalRef(*classLoader); FindClassMethod = Env->GetMethodID(classLoaderClass, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;"); } GlobalObjectRef = GlobalThis; @@ -164,7 +164,7 @@ JNIEnv* AndroidJavaEnv::GetJavaEnv( bool bRequireGlobalThis /*= true*/ ) #endif } -jclass AndroidJavaEnv::FindJavaClass( const char* name ) +jclass AndroidJavaEnv::FindJavaClass(const char* name) { JNIEnv* Env = GetJavaEnv(); if (!Env) @@ -178,6 +178,20 @@ jclass AndroidJavaEnv::FindJavaClass( const char* name ) return FoundClass; } +jclass AndroidJavaEnv::FindJavaClassGlobalRef(const char* name) +{ + JNIEnv* Env = GetJavaEnv(); + if (!Env) + { + return nullptr; + } + auto ClassNameObj = FJavaHelper::ToJavaString(Env, FString(ANSI_TO_TCHAR(name))); + auto FoundClass = NewScopedJavaObject(Env, static_cast(Env->CallObjectMethod(ClassLoader, FindClassMethod, *ClassNameObj))); + CheckJavaException(); + auto GlobalClass = (jclass)Env->NewGlobalRef(*FoundClass); + return GlobalClass; +} + void AndroidJavaEnv::DetachJavaEnv() { CurrentJavaVM->DetachCurrentThread(); @@ -199,3 +213,46 @@ bool AndroidJavaEnv::CheckJavaException() } return false; } + +FString FJavaHelper::FStringFromLocalRef(JNIEnv* Env, jstring JavaString) +{ + auto ReturnString = FStringFromParam(Env, JavaString); + + if (Env && JavaString) + { + Env->DeleteLocalRef(JavaString); + } + + return MoveTemp(ReturnString); +} + +FString FJavaHelper::FStringFromGlobalRef(JNIEnv* Env, jstring JavaString) +{ + auto ReturnString = FStringFromParam(Env, JavaString); + + if (Env && JavaString) + { + Env->DeleteGlobalRef(JavaString); + } + + return MoveTemp(ReturnString); +} + +FString FJavaHelper::FStringFromParam(JNIEnv* Env, jstring JavaString) +{ + if (!Env || !JavaString || Env->IsSameObject(JavaString, NULL)) + { + return {}; + } + + const auto chars = Env->GetStringUTFChars(JavaString, 0); + FString ReturnString(UTF8_TO_TCHAR(chars)); + Env->ReleaseStringUTFChars(JavaString, chars); + return MoveTemp(ReturnString); +} + +FScopedJavaObject FJavaHelper::ToJavaString(JNIEnv* Env, const FString& UnrealString) +{ + check(Env); + return NewScopedJavaObject(Env, Env->NewStringUTF(TCHAR_TO_UTF8(*UnrealString))); +} diff --git a/Engine/Source/Runtime/Core/Private/Android/AndroidJavaMessageBox.cpp b/Engine/Source/Runtime/Core/Private/Android/AndroidJavaMessageBox.cpp index cb43f4305490..386d5f5e619a 100644 --- a/Engine/Source/Runtime/Core/Private/Android/AndroidJavaMessageBox.cpp +++ b/Engine/Source/Runtime/Core/Private/Android/AndroidJavaMessageBox.cpp @@ -16,17 +16,17 @@ FJavaAndroidMessageBox::FJavaAndroidMessageBox() void FJavaAndroidMessageBox::SetCaption(const FString & Text) { - CallMethod(SetCaptionMethod, GetJString(Text)); + CallMethod(SetCaptionMethod, *GetJString(Text)); } void FJavaAndroidMessageBox::SetText(const FString & Text) { - CallMethod(SetTextMethod, GetJString(Text)); + CallMethod(SetTextMethod, *GetJString(Text)); } void FJavaAndroidMessageBox::AddButton(const FString & Text) { - CallMethod(AddButtonMethod, GetJString(Text)); + CallMethod(AddButtonMethod, *GetJString(Text)); } void FJavaAndroidMessageBox::Clear() diff --git a/Engine/Source/Runtime/Core/Private/Android/AndroidMisc.cpp b/Engine/Source/Runtime/Core/Private/Android/AndroidMisc.cpp index 7414cc04d930..7227484e9aae 100644 --- a/Engine/Source/Runtime/Core/Private/Android/AndroidMisc.cpp +++ b/Engine/Source/Runtime/Core/Private/Android/AndroidMisc.cpp @@ -90,9 +90,14 @@ int32 FAndroidMisc::AndroidBuildVersion = 0; // Whether or not the system handles the volume buttons (event will still be generated either way) bool FAndroidMisc::VolumeButtonsHandledBySystem = true; +// Whether an app restart is needed to free driver allocated memory after precompiling PSOs +bool FAndroidMisc::bNeedsRestartAfterPSOPrecompile = false; + // Key/Value pair variables from the optional configuration.txt TMap FAndroidMisc::ConfigRulesVariables; +EDeviceScreenOrientation FAndroidMisc::DeviceOrientation = EDeviceScreenOrientation::Unknown; + extern void AndroidThunkCpp_ForceQuit(); // From AndroidFile.cpp @@ -271,7 +276,7 @@ void InitializeJavaEventReceivers() for (auto& JavaEventReceiver : JavaEventReceivers) { - JavaEventReceiver.Clazz = AndroidJavaEnv::FindJavaClass(JavaEventReceiver.ClazzName); + JavaEventReceiver.Clazz = AndroidJavaEnv::FindJavaClassGlobalRef(JavaEventReceiver.ClazzName); if (JavaEventReceiver.Clazz == nullptr) { UE_LOG(LogAndroid, Error, TEXT("Can't find class for %s"), ANSI_TO_TCHAR(JavaEventReceiver.ClazzName)); @@ -1190,7 +1195,7 @@ int32 FAndroidMisc::GetAndroidBuildVersion() JNIEnv* JEnv = AndroidJavaEnv::GetJavaEnv(); if (nullptr != JEnv) { - jclass Class = AndroidJavaEnv::FindJavaClass("com/epicgames/ue4/GameActivity"); + jclass Class = AndroidJavaEnv::FindJavaClassGlobalRef("com/epicgames/ue4/GameActivity"); if (nullptr != Class) { jfieldID Field = JEnv->GetStaticFieldID(Class, "ANDROID_BUILD_VERSION", "I"); @@ -1198,7 +1203,7 @@ int32 FAndroidMisc::GetAndroidBuildVersion() { AndroidBuildVersion = JEnv->GetStaticIntField(Class, Field); } - JEnv->DeleteLocalRef(Class); + JEnv->DeleteGlobalRef(Class); } } } @@ -1809,16 +1814,10 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeSetConfigRulesVariable int32 Index = 0; while (Index < Count) { - jstring javaKey = (jstring)(jenv->GetObjectArrayElement(KeyValuePairs, Index++)); - jstring javaValue = (jstring)(jenv->GetObjectArrayElement(KeyValuePairs, Index++)); - - const char *nativeKey = jenv->GetStringUTFChars(javaKey, 0); - const char *nativeValue = jenv->GetStringUTFChars(javaValue, 0); - - FAndroidMisc::ConfigRulesVariables.Add(FString(nativeKey), FString(nativeValue)); - - jenv->ReleaseStringUTFChars(javaKey, nativeKey); - jenv->ReleaseStringUTFChars(javaValue, nativeValue); + auto javaKey = FJavaHelper::FStringFromLocalRef(jenv, (jstring)(jenv->GetObjectArrayElement(KeyValuePairs, Index++))); + auto javaValue = FJavaHelper::FStringFromLocalRef(jenv, (jstring)(jenv->GetObjectArrayElement(KeyValuePairs, Index++))); + + FAndroidMisc::ConfigRulesVariables.Add(javaKey, javaValue); } } diff --git a/Engine/Source/Runtime/Core/Private/Android/AndroidProcess.cpp b/Engine/Source/Runtime/Core/Private/Android/AndroidProcess.cpp index c92aa3f0e45d..40f8fce0ec5a 100644 --- a/Engine/Source/Runtime/Core/Private/Android/AndroidProcess.cpp +++ b/Engine/Source/Runtime/Core/Private/Android/AndroidProcess.cpp @@ -154,16 +154,12 @@ FString FAndroidPlatformProcess::GetGameBundleId() JNIEnv* JEnv = AndroidJavaEnv::GetJavaEnv(); if (nullptr != JEnv) { - jclass Class = AndroidJavaEnv::FindJavaClass("com/epicgames/ue4/GameActivity"); + jclass Class = AndroidJavaEnv::FindJavaClassGlobalRef("com/epicgames/ue4/GameActivity"); if (nullptr != Class) { jmethodID getAppPackageNameMethodId = JEnv->GetStaticMethodID(Class, "getAppPackageName", "()Ljava/lang/String;"); - jstring JPackageName = (jstring)JEnv->CallStaticObjectMethod(Class, getAppPackageNameMethodId, nullptr); - const char * NativePackageNameString = JEnv->GetStringUTFChars(JPackageName, 0); - FString PackageName = FString(NativePackageNameString); - JEnv->ReleaseStringUTFChars(JPackageName, NativePackageNameString); - JEnv->DeleteLocalRef(JPackageName); - JEnv->DeleteLocalRef(Class); + FString PackageName = FJavaHelper::FStringFromLocalRef(JEnv, (jstring)JEnv->CallStaticObjectMethod(Class, getAppPackageNameMethodId, nullptr)); + JEnv->DeleteGlobalRef(Class); return PackageName; } } @@ -270,4 +266,4 @@ uint64 FAndroidAffinity::GetLittleCoreMask() } return Mask; } -#endif \ No newline at end of file +#endif diff --git a/Engine/Source/Runtime/Core/Private/HAL/LowLevelMemTracker.cpp b/Engine/Source/Runtime/Core/Private/HAL/LowLevelMemTracker.cpp index c075edc3df5f..db283c8682e8 100644 --- a/Engine/Source/Runtime/Core/Private/HAL/LowLevelMemTracker.cpp +++ b/Engine/Source/Runtime/Core/Private/HAL/LowLevelMemTracker.cpp @@ -622,7 +622,7 @@ void FLowLevelMemTracker::UpdateStatsPerFrame(const TCHAR* LogName) // remove the Overhead from the default LLM as it's not something anyone needs to investigate when finding what to reduce // the platform LLM will have the info GetTracker(ELLMTracker::Default)->SetTagAmount(ELLMTag::Total, PlatformProcessMemory - Overhead, false); - GetTracker(ELLMTracker::Default)->SetTagAmount(ELLMTag::Untracked, PlatformProcessMemory - TrackedTotal, false); + GetTracker(ELLMTracker::Default)->SetTagAmount(ELLMTag::Untracked, PlatformProcessMemory - (TrackedTotal + Overhead), false); #if PLATFORM_WINDOWS GetTracker(ELLMTracker::Default)->SetTagAmount(ELLMTag::WorkingSetSize, PlatformStats.UsedPhysical, false); diff --git a/Engine/Source/Runtime/Core/Private/IOS/IOSAsyncTask.cpp b/Engine/Source/Runtime/Core/Private/IOS/IOSAsyncTask.cpp index 3a64760be609..515303077cdc 100644 --- a/Engine/Source/Runtime/Core/Private/IOS/IOSAsyncTask.cpp +++ b/Engine/Source/Runtime/Core/Private/IOS/IOSAsyncTask.cpp @@ -106,6 +106,9 @@ NSMutableArray* RunningTasks; // and remove from the list [RunningTasks removeObjectAtIndex:TaskIndex]; TaskIndex--; + + // do one at once + break; } } } diff --git a/Engine/Source/Runtime/Core/Private/IOS/IOSPlatformMisc.cpp b/Engine/Source/Runtime/Core/Private/IOS/IOSPlatformMisc.cpp index 7200077dc990..3d899a4307fd 100644 --- a/Engine/Source/Runtime/Core/Private/IOS/IOSPlatformMisc.cpp +++ b/Engine/Source/Runtime/Core/Private/IOS/IOSPlatformMisc.cpp @@ -294,26 +294,31 @@ bool FIOSPlatformMisc::IsInLowPowerMode() #if !PLATFORM_TVOS -EDeviceScreenOrientation ConvertFromUIDeviceOrientation(UIDeviceOrientation Orientation) +EDeviceScreenOrientation ConvertFromUIInterfaceOrientation(UIInterfaceOrientation Orientation) { switch(Orientation) { default: - case UIDeviceOrientationUnknown : return EDeviceScreenOrientation::Unknown; break; - case UIDeviceOrientationPortrait : return EDeviceScreenOrientation::Portrait; break; - case UIDeviceOrientationPortraitUpsideDown : return EDeviceScreenOrientation::PortraitUpsideDown; break; - case UIDeviceOrientationLandscapeLeft : return EDeviceScreenOrientation::LandscapeLeft; break; - case UIDeviceOrientationLandscapeRight : return EDeviceScreenOrientation::LandscapeRight; break; - case UIDeviceOrientationFaceUp : return EDeviceScreenOrientation::FaceUp; break; - case UIDeviceOrientationFaceDown : return EDeviceScreenOrientation::FaceDown; break; + case UIInterfaceOrientationUnknown : return EDeviceScreenOrientation::Unknown; break; + case UIInterfaceOrientationPortrait : return EDeviceScreenOrientation::Portrait; break; + case UIInterfaceOrientationPortraitUpsideDown : return EDeviceScreenOrientation::PortraitUpsideDown; break; + case UIInterfaceOrientationLandscapeLeft : return EDeviceScreenOrientation::LandscapeLeft; break; + case UIInterfaceOrientationLandscapeRight : return EDeviceScreenOrientation::LandscapeRight; break; } } #endif +UIInterfaceOrientation GInterfaceOrientation = UIInterfaceOrientationUnknown; + EDeviceScreenOrientation FIOSPlatformMisc::GetDeviceOrientation() { #if !PLATFORM_TVOS - return ConvertFromUIDeviceOrientation([[UIDevice currentDevice] orientation]); + if (GInterfaceOrientation == UIInterfaceOrientationUnknown) + { + GInterfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; + } + + return ConvertFromUIInterfaceOrientation(GInterfaceOrientation); #else return EDeviceScreenOrientation::Unknown; #endif @@ -1585,8 +1590,12 @@ bool FIOSPlatformMisc::GetStoredValue(const FString& InStoreId, const FString& I bool FIOSPlatformMisc::DeleteStoredValue(const FString& InStoreId, const FString& InSectionName, const FString& InKeyName) { - // No Implementation (currently only used by editor code so not needed on iOS) - return false; + NSUserDefaults* UserSettings = [NSUserDefaults standardUserDefaults]; + + // store it + [UserSettings removeObjectForKey:MakeStoredValueKeyName(InSectionName, InKeyName)]; + + return true; } void FIOSPlatformMisc::SetGracefulTerminationHandler() @@ -1919,3 +1928,37 @@ void ReportEnsure( const TCHAR* ErrorMessage, int NumStackFramesToIgnore ) bReentranceGuard = false; EnsureLock.Unlock(); } + + +class FIOSExec : public FSelfRegisteringExec +{ +public: + FIOSExec() + : FSelfRegisteringExec() + { + + } + + virtual bool Exec(UWorld* Inworld, const TCHAR* Cmd, FOutputDevice& Ar) override + { + if (FParse::Command(&Cmd, TEXT("IOS"))) + { + // commands to override and append commandline options for next boot (see FIOSCommandLineHelper) + if (FParse::Command(&Cmd, TEXT("OverrideCL"))) + { + return FPlatformMisc::SetStoredValue(TEXT(""), TEXT("IOSCommandLine"), TEXT("ReplacementCL"), Cmd); + } + else if (FParse::Command(&Cmd, TEXT("AppendCL"))) + { + return FPlatformMisc::SetStoredValue(TEXT(""), TEXT("IOSCommandLine"), TEXT("AppendCL"), Cmd); + } + else if (FParse::Command(&Cmd, TEXT("ClearAllCL"))) + { + return FPlatformMisc::DeleteStoredValue(TEXT(""), TEXT("IOSCommandLine"), TEXT("ReplacementCL")) && + FPlatformMisc::DeleteStoredValue(TEXT(""), TEXT("IOSCommandLine"), TEXT("AppendCL")); + } + } + + return false; + } +} GIOSExec; diff --git a/Engine/Source/Runtime/Core/Private/IOS/IOSPlatformProcess.cpp b/Engine/Source/Runtime/Core/Private/IOS/IOSPlatformProcess.cpp index 30a5b5fbe7c7..74371c1082cd 100644 --- a/Engine/Source/Runtime/Core/Private/IOS/IOSPlatformProcess.cpp +++ b/Engine/Source/Runtime/Core/Private/IOS/IOSPlatformProcess.cpp @@ -77,22 +77,7 @@ FString FIOSPlatformProcess::GetGameBundleId() void FIOSPlatformProcess::SetRealTimeMode() { - if ([IOSAppDelegate GetDelegate].OSVersion < 7 && FPlatformMisc::NumberOfCores() > 1) - { - mach_timebase_info_data_t TimeBaseInfo; - mach_timebase_info( &TimeBaseInfo ); - double MsToAbs = ((double)TimeBaseInfo.denom / (double)TimeBaseInfo.numer) * 1000000.0; - uint32 NormalProcessingTimeMs = 20; - uint32 ConstraintProcessingTimeMs = 60; - - thread_time_constraint_policy_data_t Policy; - Policy.period = 0; - Policy.computation = (uint32_t)(NormalProcessingTimeMs * MsToAbs); - Policy.constraint = (uint32_t)(ConstraintProcessingTimeMs * MsToAbs); - Policy.preemptible = true; - - thread_policy_set(pthread_mach_thread_np(pthread_self()), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t)&Policy, THREAD_TIME_CONSTRAINT_POLICY_COUNT); - } + // removed some ios 6 code that used to do something here } // Set the game thread priority to very high, slightly above the render thread @@ -123,7 +108,7 @@ void FIOSPlatformProcess::SetupRenderThread() void FIOSPlatformProcess::SetThreadAffinityMask(uint64 AffinityMask) { - if ([IOSAppDelegate GetDelegate].OSVersion >= 8 && FPlatformMisc::NumberOfCores() > 1) + if (FPlatformMisc::NumberOfCores() > 1) { thread_affinity_policy AP; AP.affinity_tag = AffinityMask; diff --git a/Engine/Source/Runtime/Core/Private/Internationalization/TextLocalizationResource.cpp b/Engine/Source/Runtime/Core/Private/Internationalization/TextLocalizationResource.cpp index 771d18cefb2e..56a60761a9ca 100644 --- a/Engine/Source/Runtime/Core/Private/Internationalization/TextLocalizationResource.cpp +++ b/Engine/Source/Runtime/Core/Private/Internationalization/TextLocalizationResource.cpp @@ -7,11 +7,11 @@ #include "Misc/Parse.h" #include "Misc/Paths.h" #include "Misc/Optional.h" +#include "Templates/UniquePtr.h" +#include "Internationalization/Internationalization.h" #include "Misc/FileHelper.h" #include "Misc/CommandLine.h" #include "Serialization/MemoryReader.h" -#include "Templates/UniquePtr.h" -#include "Internationalization/Internationalization.h" DEFINE_LOG_CATEGORY_STATIC(LogTextLocalizationResource, Log, All); diff --git a/Engine/Source/Runtime/Core/Private/Misc/AssertionMacros.cpp b/Engine/Source/Runtime/Core/Private/Misc/AssertionMacros.cpp index 043c0133c0b5..f6be0ecabfc5 100644 --- a/Engine/Source/Runtime/Core/Private/Misc/AssertionMacros.cpp +++ b/Engine/Source/Runtime/Core/Private/Misc/AssertionMacros.cpp @@ -246,6 +246,12 @@ void FDebug::LogAssertFailedMessageImplV(const ANSICHAR* Expr, const ANSICHAR* F */ FORCENOINLINE void FDebug::EnsureFailed(const ANSICHAR* Expr, const ANSICHAR* File, int32 Line, const TCHAR* Msg, int NumStackFramesToIgnore) { + // if time isn't ready yet, we better not continue + if (FPlatformTime::GetSecondsPerCycle() == 0.0) + { + return; + } + #if STATS FString EnsureFailedPerfMessage = FString::Printf(TEXT("FDebug::EnsureFailed")); SCOPE_LOG_TIME_IN_SECONDS(*EnsureFailedPerfMessage, nullptr) diff --git a/Engine/Source/Runtime/Core/Private/Misc/ConfigCacheIni.cpp b/Engine/Source/Runtime/Core/Private/Misc/ConfigCacheIni.cpp index 9d11e753cf58..5099196a4269 100644 --- a/Engine/Source/Runtime/Core/Private/Misc/ConfigCacheIni.cpp +++ b/Engine/Source/Runtime/Core/Private/Misc/ConfigCacheIni.cpp @@ -64,36 +64,130 @@ namespace FConfigValue -----------------------------------------------------------------------------*/ +struct FConfigExpansion +{ + template + FConfigExpansion(const TCHAR(&Var)[N], FString&& Val) + : Variable(Var) + , Value(Val) + , VariableLen(N - 1) + {} + + const TCHAR* Variable; + FString Value; + int VariableLen; +}; + +static FString GetApplicationSettingsDirNormalized() +{ + FString Dir = FPlatformProcess::ApplicationSettingsDir(); + FPaths::NormalizeFilename(Dir); + return Dir; +} + +static const FConfigExpansion* MatchExpansions(const TCHAR* PotentialVariable) +{ + // Allocate replacement value strings once + static const FConfigExpansion Expansions[] = + { + FConfigExpansion(TEXT("%GAME%"), FString(FApp::GetProjectName())), + FConfigExpansion(TEXT("%GAMEDIR%"), FPaths::ProjectDir()), + FConfigExpansion(TEXT("%ENGINEUSERDIR%"), FPaths::EngineUserDir()), + FConfigExpansion(TEXT("%ENGINEVERSIONAGNOSTICUSERDIR%"), FPaths::EngineVersionAgnosticUserDir()), + FConfigExpansion(TEXT("%APPSETTINGSDIR%"), GetApplicationSettingsDirNormalized()), + }; + + for (const FConfigExpansion& Expansion : Expansions) + { + if (FCString::Strncmp(Expansion.Variable, PotentialVariable, Expansion.VariableLen) == 0) + { + return &Expansion; + } + } + + return nullptr; +} + +static const FConfigExpansion* FindNextExpansion(const TCHAR* Str, const TCHAR*& OutMatch) +{ + for (const TCHAR* It = FCString::Strchr(Str, '%'); It; It = FCString::Strchr(It + 1, '%')) + { + if (const FConfigExpansion* Expansion = MatchExpansions(It)) + { + OutMatch = It; + return Expansion; + } + } + + return nullptr; +} + bool FConfigValue::ExpandValue(const FString& InCollapsedValue, FString& OutExpandedValue) { - int32 NumReplacements = 0; - OutExpandedValue = InCollapsedValue; + struct FSubstring + { + const TCHAR* Begin; + const TCHAR* End; - // Replace %GAME% with game name. - NumReplacements += OutExpandedValue.ReplaceInline(TEXT("%GAME%"), FApp::GetProjectName(), ESearchCase::CaseSensitive); + int32 Len() const { return End - Begin; } + }; - // Replace %GAMEDIR% with the game directory. - NumReplacements += OutExpandedValue.ReplaceInline(TEXT("%GAMEDIR%"), *FPaths::ProjectDir(), ESearchCase::CaseSensitive); + // Find substrings of input and expansions to concatenate to final output string + TArray> Substrings; + const TCHAR* It = *InCollapsedValue; + while (true) + { + const TCHAR* Match; + if (const FConfigExpansion* Expansion = FindNextExpansion(It, Match)) + { + Substrings.Add({ It, Match }); + Substrings.Add({ *Expansion->Value, (*Expansion->Value) + Expansion->Value.Len() }); - // Replace %ENGINEUSERDIR% with the user's engine directory. - NumReplacements += OutExpandedValue.ReplaceInline(TEXT("%ENGINEUSERDIR%"), *FPaths::EngineUserDir(), ESearchCase::CaseSensitive); + It = Match + Expansion->VariableLen; + } + else if (Substrings.Num() == 0) + { + // No expansions matched, skip concatenation and return input string + OutExpandedValue = InCollapsedValue; + return false; + } + else + { + Substrings.Add({ It, *InCollapsedValue + InCollapsedValue.Len() }); + break; + } + } - // Replace %ENGINEVERSIONAGNOSTICUSERDIR% with the user's engine agnostic directory. - NumReplacements += OutExpandedValue.ReplaceInline(TEXT("%ENGINEVERSIONAGNOSTICUSERDIR%"), *FPaths::EngineVersionAgnosticUserDir(), ESearchCase::CaseSensitive); + // Concat + int32 OutLen = 0; + for (const FSubstring& Substring : Substrings) + { + OutLen += Substring.Len(); + } - // Replace %APPSETTINGSDIR% with the application settings directory. - FString AppSettingsDir = FPlatformProcess::ApplicationSettingsDir(); - FPaths::NormalizeFilename(AppSettingsDir); - NumReplacements += OutExpandedValue.ReplaceInline(TEXT("%APPSETTINGSDIR%"), *AppSettingsDir, ESearchCase::CaseSensitive); + OutExpandedValue.Reserve(OutLen); + for (const FSubstring& Substring : Substrings) + { + OutExpandedValue.AppendChars(Substring.Begin, Substring.Len()); + } - return NumReplacements > 0; + return true; } FString FConfigValue::ExpandValue(const FString& InCollapsedValue) { - FString ExpandedValue; - ExpandValue(InCollapsedValue, ExpandedValue); - return ExpandedValue; + FString OutExpandedValue; + ExpandValue(InCollapsedValue, OutExpandedValue); + return OutExpandedValue; +} + +void FConfigValue::ExpandValueInternal() +{ + const TCHAR* Dummy; + if (FindNextExpansion(*SavedValue, Dummy)) + { + ExpandValue(SavedValue, /* out */ ExpandedValue); + } } bool FConfigValue::CollapseValue(const FString& InExpandedValue, FString& OutCollapsedValue) @@ -223,8 +317,10 @@ bool FConfigSection::operator!=( const FConfigSection& Other ) const // Pull out a property from a Struct property, StructKeyMatch should be in the form "MyProp=". This reduces // memory allocations for each attempted match -static FString ExtractPropertyValue(const FString& FullStructValue, const FString& StructKeyMatch) +static void ExtractPropertyValue(const FString& FullStructValue, const FString& StructKeyMatch, FString& Out) { + Out.Reset(); + int32 MatchLoc = FullStructValue.Find(StructKeyMatch); // we only look for matching StructKeys if the incoming Value had a key if (MatchLoc >= 0) @@ -249,13 +345,11 @@ static FString ExtractPropertyValue(const FString& FullStructValue, const FStrin } // pull out the token - return FullStructValue.Mid(MatchLoc, Travel - Start); + Out.AppendChars(*FullStructValue + MatchLoc, Travel - Start); } - - return TEXT(""); } -void FConfigSection::HandleAddCommand(FName Key, const FString& Value, bool bAppendValueIfNotArrayOfStructsKeyUsed) +void FConfigSection::HandleAddCommand(FName Key, FString&& Value, bool bAppendValueIfNotArrayOfStructsKeyUsed) { FString* StructKey = ArrayOfStructKeys.Find(Key); bool bHandledWithKey = false; @@ -265,10 +359,12 @@ void FConfigSection::HandleAddCommand(FName Key, const FString& Value, bool bApp FString StructKeyMatch = *StructKey + "="; // pull out the token that matches the StructKey (a property name) from the full struct property string - FString StructKeyValueToMatch = ExtractPropertyValue(Value, StructKeyMatch); + FString StructKeyValueToMatch; + ExtractPropertyValue(Value, StructKeyMatch, StructKeyValueToMatch); if (StructKeyValueToMatch.Len() > 0) { + FString ExistingStructValueKey; // if we have a key for this array, then we look for it in the Value for each array entry for (FConfigSection::TIterator It(*this); It; ++It) { @@ -276,7 +372,7 @@ void FConfigSection::HandleAddCommand(FName Key, const FString& Value, bool bApp if (It.Key() == Key) { // now look for the matching ArrayOfStruct Key as the incoming KeyValue - FString ExistingStructValueKey = ExtractPropertyValue(It.Value().GetValue(), StructKeyMatch); + ExtractPropertyValue(It.Value().GetValue(), StructKeyMatch, ExistingStructValueKey); if (ExistingStructValueKey == StructKeyValueToMatch) { // we matched ther key, so remove the existing line item (Value) and plop in the new one @@ -296,11 +392,11 @@ void FConfigSection::HandleAddCommand(FName Key, const FString& Value, bool bApp { if (bAppendValueIfNotArrayOfStructsKeyUsed) { - Add(Key, Value); + Add(Key, MoveTemp(Value)); } else { - AddUnique(Key, Value); + AddUnique(Key, MoveTemp(Value)); } } } @@ -472,6 +568,7 @@ void FConfigFile::CombineFromBuffer(const FString& Buffer) const TCHAR* Ptr = *Buffer; FConfigSection* CurrentSection = nullptr; FString CurrentSectionName; + FString TheLine; bool Done = false; while( !Done ) { @@ -482,9 +579,8 @@ void FConfigFile::CombineFromBuffer(const FString& Buffer) } // read the next line - FString TheLine; int32 LinesConsumed = 0; - FParse::LineExtended(&Ptr, TheLine, LinesConsumed, false); + FParse::LineExtended(&Ptr, /* reset */ TheLine, LinesConsumed, false); if (Ptr == nullptr || *Ptr == 0) { Done = true; @@ -585,7 +681,7 @@ void FConfigFile::CombineFromBuffer(const FString& Buffer) if (Cmd == '+') { // Add if not already present. - CurrentSection->HandleAddCommand( Start, ProcessedValue, false ); + CurrentSection->HandleAddCommand( Start, MoveTemp(ProcessedValue), false ); } else if( Cmd=='-' ) { @@ -595,7 +691,7 @@ void FConfigFile::CombineFromBuffer(const FString& Buffer) } else if ( Cmd=='.' ) { - CurrentSection->HandleAddCommand( Start, ProcessedValue, true ); + CurrentSection->HandleAddCommand( Start, MoveTemp(ProcessedValue), true ); } else if( Cmd=='!' ) { @@ -604,13 +700,13 @@ void FConfigFile::CombineFromBuffer(const FString& Buffer) else if (Cmd == '@') { // track a key to show uniqueness for arrays of structs - CurrentSection->ArrayOfStructKeys.Add(Start, ProcessedValue); + CurrentSection->ArrayOfStructKeys.Add(Start, MoveTemp(ProcessedValue)); } else if (Cmd == '*') { // track a key to show uniqueness for arrays of structs TMap& POCKeys = PerObjectConfigArrayOfStructKeys.FindOrAdd(CurrentSectionName); - POCKeys.Add(Start, ProcessedValue); + POCKeys.Add(Start, MoveTemp(ProcessedValue)); } else { @@ -618,11 +714,11 @@ void FConfigFile::CombineFromBuffer(const FString& Buffer) FConfigValue* ConfigValue = CurrentSection->Find( Start ); if( !ConfigValue ) { - CurrentSection->Add( Start, ProcessedValue ); + CurrentSection->Add( Start, MoveTemp(ProcessedValue) ); } else { - *ConfigValue = FConfigValue(ProcessedValue); + *ConfigValue = FConfigValue(MoveTemp(ProcessedValue)); } } @@ -922,17 +1018,18 @@ static bool LoadIniFileHierarchy(const FConfigFileHierarchy& HierarchyToLoad, FC else { // If no inis exist or only engine (Base*.ini) inis exist, don't load anything - int32 NumExistingOptionalInis = 0; - for( const auto& HierarchyIt : HierarchyToLoad ) + bool bOptionalIniFound = false; + for (const TPair& Pair : HierarchyToLoad) { - const FIniFilename& IniToLoad = HierarchyIt.Value; + const FIniFilename& IniToLoad = Pair.Value; if (IniToLoad.bRequired == false && - (!IsUsingLocalIniFile(*IniToLoad.Filename, nullptr) || DoesConfigFileExistWrapper(*IniToLoad.Filename))) + (!IsUsingLocalIniFile(*IniToLoad.Filename, nullptr) || DoesConfigFileExistWrapper(*IniToLoad.Filename))) { - NumExistingOptionalInis++; + bOptionalIniFound = true; + break; } } - if (NumExistingOptionalInis == 0) + if (!bOptionalIniFound) { // No point in generating ini return true; @@ -3363,7 +3460,12 @@ bool FConfigCacheIni::LoadExternalIniFile(FConfigFile& ConfigFile, const TCHAR* ConfigFile.Name = IniName; // don't write anything to disk in cooked builds - we will always use re-generated INI files anyway. - if (bWriteDestIni && (!FPlatformProperties::RequiresCookedData() || bAllowGeneratedIniWhenCooked) + // Note: Unfortunately bAllowGeneratedIniWhenCooked is often true even in shipping builds with cooked data + // due to default parameters. We don't dare change this now. + // + // Check GIsInitialLoad since no INI changes that should be persisted could have occurred this early. + // INI changes from code, environment variables, CLI parameters, etc should not be persisted. + if (!GIsInitialLoad && bWriteDestIni && (!FPlatformProperties::RequiresCookedData() || bAllowGeneratedIniWhenCooked) // We shouldn't save config files when in multiprocess mode, // otherwise we get file contention in XGE shader builds. && !FParse::Param(FCommandLine::Get(), TEXT("Multiprocess"))) diff --git a/Engine/Source/Runtime/Core/Private/Misc/CoreGlobals.cpp b/Engine/Source/Runtime/Core/Private/Misc/CoreGlobals.cpp index 0cb34f62914b..cfc220df1cf3 100644 --- a/Engine/Source/Runtime/Core/Private/Misc/CoreGlobals.cpp +++ b/Engine/Source/Runtime/Core/Private/Misc/CoreGlobals.cpp @@ -379,7 +379,8 @@ static void DumpBootTimingString(const TCHAR* Message) } else { - FPlatformMisc::LowLevelOutputDebugString(Message); + // Some platforms add an implicit \n if it isn't there, others don't + FPlatformMisc::LowLevelOutputDebugStringf(TEXT("%s\n"), Message); } } @@ -398,11 +399,18 @@ void DumpBootTiming() static void BootTimingPoint(const TCHAR *Message, const TCHAR *Prefix = nullptr, int32 Depth = 0, double TookTime = 0.0) { static double LastTime = 0.0; - static FString LastMessage; + static TArray MessageStack; + static FString LastGapMessage; double Now = FPlatformTime::Seconds(); FString Result; FString GapTime; + FString LastMessage; + + if (MessageStack.Num()) + { + LastMessage = MessageStack.Last(); + } if (!Prefix || FCString::Strcmp(Prefix, TEXT("}")) || LastMessage != FString(Message)) { @@ -411,12 +419,29 @@ static void BootTimingPoint(const TCHAR *Message, const TCHAR *Prefix = nullptr, GapTime = FString::Printf(TEXT(" %7.3fs **Gap**"), float(Now - LastTime)); GAllBootTiming.Add(GapTime); DumpBootTimingString(*FString::Printf(TEXT("[BT]******** %s"), *GapTime)); + LastGapMessage = LastMessage; } } LastTime = Now; - LastMessage = Message; + if (Prefix) { + if (FCString::Strcmp(Prefix, TEXT("}")) == 0) + { + if (LastMessage == Message) + { + MessageStack.Pop(); + if (LastGapMessage == Message) + { + LastGapMessage.Reset(); + } + } + } + else if (FCString::Strcmp(Prefix, TEXT("{")) == 0) + { + MessageStack.Add(Message); + } + if (TookTime != 0.0) { Result = FString::Printf(TEXT("%7.3fs took %7.3fs %s %1s %s"), float(Now - GBootTimingStart.FirstTime), float(TookTime), FCString::Spc(Depth * 2), Prefix, Message); @@ -437,7 +462,28 @@ static void BootTimingPoint(const TCHAR *Message, const TCHAR *Prefix = nullptr, Result = FString::Printf(TEXT("%7.3fs : %s"), float(Now - GBootTimingStart.FirstTime), Message); } } - GAllBootTiming.Add(Result); + bool bKeep = true; + if (Prefix && TookTime > 0.0 && GAllBootTiming.Num()) + { + // Don't suppress the first 0 time block if there was a gap right before + if (MessageStack.Num() != 0 && MessageStack.Last() == LastGapMessage) + { + LastGapMessage.Reset(); + } + else if (TookTime < 0.001) + { + // Remove a paired {} if time was too small + if (GAllBootTiming.Last().Contains(Message)) + { + GAllBootTiming.Pop(); + bKeep = false; + } + } + } + if (bKeep) + { + GAllBootTiming.Add(Result); + } DumpBootTimingString(*FString::Printf(TEXT("[BT]******** %s"), *Result)); } diff --git a/Engine/Source/Runtime/Core/Private/Modules/ModuleManager.cpp b/Engine/Source/Runtime/Core/Private/Modules/ModuleManager.cpp index 8d428d42df07..d62ed0b88e2b 100644 --- a/Engine/Source/Runtime/Core/Private/Modules/ModuleManager.cpp +++ b/Engine/Source/Runtime/Core/Private/Modules/ModuleManager.cpp @@ -441,11 +441,15 @@ IModuleInterface* FModuleManager::LoadModuleWithFailureReason(const FName InModu if (ModuleInfo->Module.IsValid()) { - // Startup the module + FScopedBootTiming BootScope("LoadModule - ", InModuleName); +#if USE_PER_MODULE_UOBJECT_BOOTSTRAP { - FScopedBootTiming BootScope("LoadModuleWithFailureReason:StartupModule - ", InModuleName); - ModuleInfo->Module->StartupModule(); + ProcessLoadedObjectsCallback.Broadcast(InModuleName, bCanProcessNewlyLoadedObjects); } +#endif + // Startup the module + ModuleInfo->Module->StartupModule(); + // The module might try to load other dependent modules in StartupModule. In this case, we want those modules shut down AFTER this one because we may still depend on the module at shutdown. ModuleInfo->LoadOrder = FModuleInfo::CurrentLoadOrder++; @@ -477,7 +481,7 @@ IModuleInterface* FModuleManager::LoadModuleWithFailureReason(const FName InModu // in the module being loaded. if (bCanProcessNewlyLoadedObjects) { - ProcessLoadedObjectsCallback.Broadcast(); + ProcessLoadedObjectsCallback.Broadcast(NAME_None, bCanProcessNewlyLoadedObjects); } // Try to dynamically load the DLL @@ -514,16 +518,11 @@ IModuleInterface* FModuleManager::LoadModuleWithFailureReason(const FName InModu // First things first. If the loaded DLL has UObjects in it, then their generated code's // static initialization will have run during the DLL loading phase, and we'll need to // go in and make sure those new UObject classes are properly registered. - { - // Sometimes modules are loaded before even the UObject systems are ready. We need to assume - // these modules aren't using UObjects. - if (bCanProcessNewlyLoadedObjects) - { - // OK, we've verified that loading the module caused new UObject classes to be - // registered, so we'll treat this module as a module with UObjects in it. - ProcessLoadedObjectsCallback.Broadcast(); - } - } + // Sometimes modules are loaded before even the UObject systems are ready. We need to assume + // these modules aren't using UObjects. + // OK, we've verified that loading the module caused new UObject classes to be + // registered, so we'll treat this module as a module with UObjects in it. + ProcessLoadedObjectsCallback.Broadcast(InModuleName, bCanProcessNewlyLoadedObjects); // Find our "InitializeModule" global function, which must exist for all module DLLs FInitializeModuleFunctionPtr InitializeModuleFunctionPtr = diff --git a/Engine/Source/Runtime/Core/Private/Unix/UnixPlatformMisc.cpp b/Engine/Source/Runtime/Core/Private/Unix/UnixPlatformMisc.cpp index 0a4f09e8951c..6ff5417e1ee2 100644 --- a/Engine/Source/Runtime/Core/Private/Unix/UnixPlatformMisc.cpp +++ b/Engine/Source/Runtime/Core/Private/Unix/UnixPlatformMisc.cpp @@ -948,3 +948,8 @@ void FUnixPlatformMisc::UngrabAllInput() UngrabAllInputCallback(); } } + +FString FUnixPlatformMisc::GetLoginId() +{ + return FString::Printf(TEXT("%s-%08x"), *GetOperatingSystemId(), static_cast(geteuid())); +} diff --git a/Engine/Source/Runtime/Core/Private/Windows/WindowsPlatformMisc.cpp b/Engine/Source/Runtime/Core/Private/Windows/WindowsPlatformMisc.cpp index 4005a2a738c1..4aa60bca6658 100644 --- a/Engine/Source/Runtime/Core/Private/Windows/WindowsPlatformMisc.cpp +++ b/Engine/Source/Runtime/Core/Private/Windows/WindowsPlatformMisc.cpp @@ -1681,6 +1681,22 @@ int32 FWindowsPlatformMisc::NumberOfWorkerThreadsToSpawn() return FMath::Max(FMath::Min(NumberOfThreads, MaxWorkerThreadsWanted), 2); } +const TCHAR* FWindowsPlatformMisc::GetPlatformFeaturesModuleName() +{ + bool bModuleExists = FModuleManager::Get().ModuleExists(TEXT("WindowsPlatformFeatures")); + // If running a dedicated server then we use the default PlatformFeatures + if (bModuleExists && !IsRunningDedicatedServer()) + { + UE_LOG(LogWindows, Log, TEXT("WindowsPlatformFeatures enabled")); + return TEXT("WindowsPlatformFeatures"); + } + else + { + UE_LOG(LogWindows, Log, TEXT("WindowsPlatformFeatures disabled or dedicated server build")); + return nullptr; + } +} + bool FWindowsPlatformMisc::OsExecute(const TCHAR* CommandType, const TCHAR* Command, const TCHAR* CommandLine) { HINSTANCE hApp = ShellExecute(NULL, diff --git a/Engine/Source/Runtime/Core/Public/Algo/FindSequence.h b/Engine/Source/Runtime/Core/Public/Algo/FindSequence.h new file mode 100644 index 000000000000..dbfed6c926a0 --- /dev/null +++ b/Engine/Source/Runtime/Core/Public/Algo/FindSequence.h @@ -0,0 +1,61 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "Algo/Impl/RangePointerType.h" + +namespace AlgoImpl +{ + template + constexpr WhereType* FindSequence(WhereType* First, WhereType* Last, WhatType* WhatFirst, WhatType* WhatLast) + { + for (; ; ++First) + { + WhereType* It = First; + for (WhatType* WhatIt = WhatFirst; ; ++It, ++WhatIt) + { + if (WhatIt == WhatLast) + { + return First; + } + if (It == Last) + { + return nullptr; + } + if (!(*It == *WhatIt)) + { + break; + } + } + } + } +} + +namespace Algo +{ + + /* + * Searches for the first occurrence of a sequence of elements in another sequence. + * + * @param Where The range to search + * @param What The sequence to search for. + * + * @return A pointer to the first occurrence of the "What" sequence in "Where" sequence, or nullptr if not found. + */ + template + FORCEINLINE auto FindSequence(const RangeWhereType& Where, const RangeWhatType& What) + -> decltype( AlgoImpl::FindSequence( GetData(Where), GetData(Where) + GetNum(Where), GetData(What), GetData(What) + GetNum(What)) ) + { + if (GetNum(What) > GetNum(Where)) + { + return nullptr; + } + else + { + return AlgoImpl::FindSequence( + GetData(Where), GetData(Where) + GetNum(Where), + GetData(What), GetData(What) + GetNum(What)); + } + } + +} diff --git a/Engine/Source/Runtime/Core/Public/Android/AndroidJava.h b/Engine/Source/Runtime/Core/Public/Android/AndroidJava.h index b2391da627f0..7e9603915463 100644 --- a/Engine/Source/Runtime/Core/Public/Android/AndroidJava.h +++ b/Engine/Source/Runtime/Core/Public/Android/AndroidJava.h @@ -5,7 +5,7 @@ #include "CoreMinimal.h" #if USE_ANDROID_JNI - +#include "Android/AndroidJavaEnv.h" #include /* @@ -38,7 +38,7 @@ public: return Object; } - static jstring GetJString(const FString& String); + static FScopedJavaObject GetJString(const FString& String); void VerifyException(); @@ -73,4 +73,4 @@ int64 FJavaClassObject::CallMethod(FJavaClassMethod Method, ...); template<> FString FJavaClassObject::CallMethod(FJavaClassMethod Method, ...); -#endif \ No newline at end of file +#endif diff --git a/Engine/Source/Runtime/Core/Public/Android/AndroidJavaEnv.h b/Engine/Source/Runtime/Core/Public/Android/AndroidJavaEnv.h index 5d4ce21342e8..23f126f7c85f 100644 --- a/Engine/Source/Runtime/Core/Public/Android/AndroidJavaEnv.h +++ b/Engine/Source/Runtime/Core/Public/Android/AndroidJavaEnv.h @@ -3,6 +3,7 @@ #pragma once #include "CoreTypes.h" +#include "Containers/UnrealString.h" #include namespace AndroidJavaEnv @@ -13,6 +14,81 @@ namespace AndroidJavaEnv CORE_API jobject GetClassLoader(); CORE_API JNIEnv* GetJavaEnv(bool bRequireGlobalThis = true); CORE_API jclass FindJavaClass(const char* name); + CORE_API jclass FindJavaClassGlobalRef(const char* name); CORE_API void DetachJavaEnv(); CORE_API bool CheckJavaException(); } + +// Helper class that automatically calls DeleteLocalRef on the passed-in Java object when goes out of scope +template +class CORE_API FScopedJavaObject +{ +public: + FScopedJavaObject(JNIEnv* InEnv, const T& InObjRef) : + Env(InEnv), + ObjRef(InObjRef) + {} + + FScopedJavaObject(FScopedJavaObject&& Other) : + Env(Other.Env), + ObjRef(Other.ObjRef) + { + Other.Env = nullptr; + Other.ObjRef = nullptr; + } + + FScopedJavaObject(const FScopedJavaObject& Other) = delete; + FScopedJavaObject& operator=(const FScopedJavaObject& Other) = delete; + + ~FScopedJavaObject() + { + if (*this) + { + Env->DeleteLocalRef(ObjRef); + } + } + + // Returns the underlying JNI pointer + T operator*() const { return ObjRef; } + + operator bool() const + { + if (!Env || !ObjRef || Env->IsSameObject(ObjRef, NULL)) + { + return false; + } + + return true; + } + +private: + JNIEnv* Env = nullptr; + T ObjRef = nullptr; +}; + +/** + Helper function that allows template deduction on the java object type, for example: + auto ScopeObject = NewScopedJavaObject(Env, JavaString); + instead of FScopedJavaObject ScopeObject(Env, JavaString); + */ +template +CORE_API FScopedJavaObject NewScopedJavaObject(JNIEnv* InEnv, const T& InObjRef) +{ + return FScopedJavaObject(InEnv, InObjRef); +} + +class CORE_API FJavaHelper +{ +public: + // Converts the java string to FString and calls DeleteLocalRef on the passed-in java string reference + static FString FStringFromLocalRef(JNIEnv* Env, jstring JavaString); + + // Converts the java string to FString and calls DeleteGlobalRef on the passed-in java string reference + static FString FStringFromGlobalRef(JNIEnv* Env, jstring JavaString); + + // Converts the java string to FString, does NOT modify the passed-in java string reference + static FString FStringFromParam(JNIEnv* Env, jstring JavaString); + + // Converts FString into a Java string wrapped in FScopedJavaObject + static FScopedJavaObject ToJavaString(JNIEnv* Env, const FString& UnrealString); +}; diff --git a/Engine/Source/Runtime/Core/Public/Android/AndroidMisc.h b/Engine/Source/Runtime/Core/Public/Android/AndroidMisc.h index c41a58d9557e..4c3ffc05091b 100644 --- a/Engine/Source/Runtime/Core/Public/Android/AndroidMisc.h +++ b/Engine/Source/Runtime/Core/Public/Android/AndroidMisc.h @@ -36,7 +36,8 @@ struct CORE_API FAndroidMisc : public FGenericPlatformMisc static void PlatformInit(); static void PlatformTearDown(); static void PlatformHandleSplashScreen(bool ShowSplashScreen); - + static EDeviceScreenOrientation GetDeviceOrientation() { return DeviceOrientation; } + FORCEINLINE static int32 GetMaxPathLength() { return ANDROID_MAX_PATH; @@ -244,6 +245,8 @@ public: static bool VolumeButtonsHandledBySystem; + static bool bNeedsRestartAfterPSOPrecompile; + enum class ECoreFrequencyProperty { CurrentFrequency, @@ -252,6 +255,11 @@ public: }; static uint32 GetCoreFrequency(int32 CoreIndex, ECoreFrequencyProperty CoreFrequencyProperty); + + static void SetDeviceOrientation(EDeviceScreenOrientation NewDeviceOrentation) { DeviceOrientation = NewDeviceOrentation; } + +private: + static EDeviceScreenOrientation DeviceOrientation; }; #if !PLATFORM_LUMIN diff --git a/Engine/Source/Runtime/Core/Public/Clang/ClangPlatformCompilerPreSetup.h b/Engine/Source/Runtime/Core/Public/Clang/ClangPlatformCompilerPreSetup.h index 3f814958560e..b42f53a104ce 100644 --- a/Engine/Source/Runtime/Core/Public/Clang/ClangPlatformCompilerPreSetup.h +++ b/Engine/Source/Runtime/Core/Public/Clang/ClangPlatformCompilerPreSetup.h @@ -40,6 +40,28 @@ _Pragma("clang diagnostic pop") #endif // DISABLE_DEPRECATION +#ifndef PRAGMA_DISABLE_OVERLOADED_VIRTUAL_WARNINGS + #define PRAGMA_DISABLE_OVERLOADED_VIRTUAL_WARNINGS \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Woverloaded-virtual\"") +#endif // PRAGMA_DISABLE_OVERLOADED_VIRTUAL_WARNINGS + +#ifndef PRAGMA_ENABLE_OVERLOADED_VIRTUAL_WARNINGS + #define PRAGMA_ENABLE_OVERLOADED_VIRTUAL_WARNINGS \ + _Pragma("clang diagnostic pop") +#endif // PRAGMA_ENABLE_OVERLOADED_VIRTUAL_WARNINGS + +#ifndef PRAGMA_DISABLE_MISSING_BRACES_WARNINGS + #define PRAGMA_DISABLE_MISSING_BRACES_WARNINGS \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wmissing-braces\"") +#endif // PRAGMA_DISABLE_MISSING_BRACES_WARNINGS + +#ifndef PRAGMA_ENABLE_MISSING_BRACES_WARNINGS + #define PRAGMA_ENABLE_MISSING_BRACES_WARNINGS \ + _Pragma("clang diagnostic pop") +#endif // PRAGMA_ENABLE_MISSING_BRACES_WARNINGS + #ifndef PRAGMA_DISABLE_SHADOW_VARIABLE_WARNINGS #define PRAGMA_DISABLE_SHADOW_VARIABLE_WARNINGS \ _Pragma("clang diagnostic push") \ diff --git a/Engine/Source/Runtime/Core/Public/Containers/Map.h b/Engine/Source/Runtime/Core/Public/Containers/Map.h index 78c06b4ff961..37545d79ee3f 100644 --- a/Engine/Source/Runtime/Core/Public/Containers/Map.h +++ b/Engine/Source/Runtime/Core/Public/Containers/Map.h @@ -418,6 +418,23 @@ private: return Add(Forward(Arg)); } + /** + * Find the value associated with a specified key, or if none exists, + * adds the value + * + * @param Key The key to search for. + * @param Value The value to associate with the key. + * @return A reference to the value associated with the specified key. + */ + template + FORCEINLINE ValueType& FindOrAddImpl(InitKeyType&& Key, InitValueType&& Value) + { + if (auto* Pair = Pairs.Find(Key)) + return Pair->Value; + + return Add(Forward(Key), Forward(Value)); + } + public: /** @@ -430,6 +447,19 @@ public: FORCEINLINE ValueType& FindOrAdd(const KeyType& Key) { return FindOrAddImpl( Key ); } FORCEINLINE ValueType& FindOrAdd( KeyType&& Key) { return FindOrAddImpl(MoveTempIfPossible(Key)); } + /** + * Find the value associated with a specified key, or if none exists, + * adds a value using the default constructor. + * + * @param Key The key to search for. + * @param Value The value to associate with the key. + * @return A reference to the value associated with the specified key. + */ + FORCEINLINE ValueType& FindOrAdd(const KeyType& Key, const ValueType& Value) { return FindOrAddImpl( Key , Value ); } + FORCEINLINE ValueType& FindOrAdd(const KeyType& Key, ValueType&& Value) { return FindOrAddImpl( Key , MoveTempIfPossible(Value) ); } + FORCEINLINE ValueType& FindOrAdd( KeyType&& Key, const ValueType& Value) { return FindOrAddImpl(MoveTempIfPossible(Key), Value ); } + FORCEINLINE ValueType& FindOrAdd( KeyType&& Key, ValueType&& Value) { return FindOrAddImpl(MoveTempIfPossible(Key), MoveTempIfPossible(Value) ); } + /** * Find the value associated with a specified key, or if none exists, * adds a value using the key as the constructor parameter. diff --git a/Engine/Source/Runtime/Core/Public/IOS/IOSCommandLineHelper.h b/Engine/Source/Runtime/Core/Public/IOS/IOSCommandLineHelper.h index 56bab750d65b..6dd688d7cf6a 100644 --- a/Engine/Source/Runtime/Core/Public/IOS/IOSCommandLineHelper.h +++ b/Engine/Source/Runtime/Core/Public/IOS/IOSCommandLineHelper.h @@ -8,7 +8,7 @@ #define IOS_MAX_PATH 1024 #define CMD_LINE_MAX 16384 -extern FString GSavedCommandLine; +extern APPLICATIONCORE_API FString GSavedCommandLine; class FIOSCommandLineHelper { @@ -53,11 +53,15 @@ class FIOSCommandLineHelper static bool TryReadCommandLineFile(const FString& CommandLineFilePath) { + bool bHasFile = false; + + // initialize the commandline + // read in the command line text file (coming from UnrealFrontend) if it exists FILE* CommandLineFile = fopen(TCHAR_TO_UTF8(*CommandLineFilePath), "r"); - if (CommandLineFile) + if(CommandLineFile) { FPlatformMisc::LowLevelOutputDebugStringf(TEXT("Checking for command line in %s... FOUND!") LINE_TERMINATOR, *CommandLineFilePath); - char CommandLine[CMD_LINE_MAX] = { 0 }; + char CommandLine[CMD_LINE_MAX] = {0}; char* DataExists = fgets(CommandLine, ARRAY_COUNT(CommandLine) - 1, CommandLineFile); if (DataExists) { @@ -70,13 +74,14 @@ class FIOSCommandLineHelper FCommandLine::Append(UTF8_TO_TCHAR(CommandLine)); } fclose(CommandLineFile); - return true; + bHasFile = true; } else { FPlatformMisc::LowLevelOutputDebugStringf(TEXT("Checking for command line in %s... NOT FOUND!") LINE_TERMINATOR, *CommandLineFilePath); - return false; } + + return bHasFile; } static void InitCommandArgs(FString AdditionalCommandArgs) @@ -96,13 +101,29 @@ class FIOSCommandLineHelper TryReadCommandLineFile(BundleCommandLineFilePath); } + FString ReplacementCL, AppendCL; + bool bHasReplacementCL = FPlatformMisc::GetStoredValue(TEXT(""), TEXT("IOSCommandLine"), TEXT("ReplacementCL"), ReplacementCL); + bool bHasAppendCL = FPlatformMisc::GetStoredValue(TEXT(""), TEXT("IOSCommandLine"), TEXT("AppendCL"), AppendCL); + + if (bHasReplacementCL) + { + FCommandLine::Set(*ReplacementCL); + } + + if (bHasAppendCL) + { + FCommandLine::Append(TEXT(" ")); + FCommandLine::Append(*AppendCL); + } + if (!AdditionalCommandArgs.IsEmpty() && !FChar::IsWhitespace(AdditionalCommandArgs[0])) { FCommandLine::Append(TEXT(" ")); + FCommandLine::Append(*AdditionalCommandArgs); } - FCommandLine::Append(*AdditionalCommandArgs); - + // now merge the GSavedCommandLine with the rest + FCommandLine::Append(TEXT(" ")); FCommandLine::Append(*GSavedCommandLine); FPlatformMisc::LowLevelOutputDebugStringf(TEXT("Combined iOS Commandline: %s") LINE_TERMINATOR, FCommandLine::Get()); diff --git a/Engine/Source/Runtime/Core/Public/IOS/IOSPlatform.h b/Engine/Source/Runtime/Core/Public/IOS/IOSPlatform.h index 4d5da16a5d90..17b6231dae2e 100644 --- a/Engine/Source/Runtime/Core/Public/IOS/IOSPlatform.h +++ b/Engine/Source/Runtime/Core/Public/IOS/IOSPlatform.h @@ -123,7 +123,7 @@ typedef FIOSPlatformTypes FPlatformTypes; #define OPERATOR_DELETE_NOTHROW_SPEC noexcept // DLL export and import definitions -#define DLLEXPORT +#define DLLEXPORT __attribute__((visibility("default"))) #define DLLIMPORT #define IOS_MAX_PATH 1024 diff --git a/Engine/Source/Runtime/Core/Public/Misc/Build.h b/Engine/Source/Runtime/Core/Public/Misc/Build.h index 5b168c1be5ef..f941ee15baa7 100644 --- a/Engine/Source/Runtime/Core/Public/Misc/Build.h +++ b/Engine/Source/Runtime/Core/Public/Misc/Build.h @@ -323,6 +323,11 @@ #define AGGRESSIVE_MEMORY_SAVING 0 #endif +// Controls if UObjects are initialized as soon as they are available or only after the module is "loaded". This only applies to monolithic builds; if there are DLLs, this is how it works anyway and this should not be turned on +#ifndef USE_PER_MODULE_UOBJECT_BOOTSTRAP + #define USE_PER_MODULE_UOBJECT_BOOTSTRAP 0 +#endif + #define USE_HITCH_DETECTION (ALLOW_HITCH_DETECTION && !WITH_EDITORONLY_DATA && !IS_PROGRAM && !UE_BUILD_DEBUG) // Controls whether shipping builds create backups of the most recent log file. diff --git a/Engine/Source/Runtime/Core/Public/Misc/ConfigCacheIni.h b/Engine/Source/Runtime/Core/Public/Misc/ConfigCacheIni.h index d0bfa7af4a87..a0e18ef8dfc0 100644 --- a/Engine/Source/Runtime/Core/Public/Misc/ConfigCacheIni.h +++ b/Engine/Source/Runtime/Core/Public/Misc/ConfigCacheIni.h @@ -39,7 +39,16 @@ public: ExpandValueInternal(); } - FConfigValue(FString InValue) + FConfigValue(const FString& InValue) + : SavedValue(InValue) +#if CONFIG_REMEMBER_ACCESS_PATTERN + , bRead(false) +#endif + { + ExpandValueInternal(); + } + + FConfigValue(FString&& InValue) : SavedValue(MoveTemp(InValue)) #if CONFIG_REMEMBER_ACCESS_PATTERN , bRead(false) @@ -48,16 +57,48 @@ public: ExpandValueInternal(); } - FConfigValue( const FConfigValue& InConfigValue ) - : SavedValue( InConfigValue.SavedValue ) - , ExpandedValue( InConfigValue.ExpandedValue ) + FConfigValue(const FConfigValue& InConfigValue) + : SavedValue(InConfigValue.SavedValue) + , ExpandedValue(InConfigValue.ExpandedValue) #if CONFIG_REMEMBER_ACCESS_PATTERN - , bRead( InConfigValue.bRead ) + , bRead(InConfigValue.bRead) #endif { // shouldn't need to expand value it's assumed that the other FConfigValue has done this already } + FConfigValue(FConfigValue&& InConfigValue) + : SavedValue(MoveTemp(InConfigValue.SavedValue)) + , ExpandedValue(MoveTemp(InConfigValue.ExpandedValue)) +#if CONFIG_REMEMBER_ACCESS_PATTERN + , bRead(InConfigValue.bRead) +#endif + { + // shouldn't need to expand value it's assumed that the other FConfigValue has done this already + } + + FConfigValue& operator=(FConfigValue&& RHS) + { + SavedValue = MoveTemp(RHS.SavedValue); + ExpandedValue = MoveTemp(RHS.ExpandedValue); +#if CONFIG_REMEMBER_ACCESS_PATTERN + bRead = RHS.bRead; +#endif + + return *this; + } + + FConfigValue& operator=(const FConfigValue& RHS) + { + SavedValue = RHS.SavedValue; + ExpandedValue = RHS.ExpandedValue; +#if CONFIG_REMEMBER_ACCESS_PATTERN + bRead = RHS.bRead; +#endif + + return *this; + } + // Returns the ini setting with any macros expanded out const FString& GetValue() const { @@ -153,13 +194,7 @@ public: private: /** Internal version of ExpandValue that expands SavedValue into ExpandedValue, or produces an empty ExpandedValue if no expansion occurred. */ - void ExpandValueInternal() - { - if (!ExpandValue(SavedValue, ExpandedValue)) - { - ExpandedValue.Empty(); - } - } + CORE_API void ExpandValueInternal(); FString SavedValue; FString ExpandedValue; @@ -186,7 +221,7 @@ public: bool operator!=( const FConfigSection& Other ) const; // process the '+' and '.' commands, takingf into account ArrayOfStruct unique keys - void CORE_API HandleAddCommand(FName Key, const FString& Value, bool bAppendValueIfNotArrayOfStructsKeyUsed); + void CORE_API HandleAddCommand(FName Key, FString&& Value, bool bAppendValueIfNotArrayOfStructsKeyUsed); template void MultiFind(const FName Key, TArray& OutValues, const bool bMaintainOrder = false) const diff --git a/Engine/Source/Runtime/Core/Public/Modules/ModuleManager.h b/Engine/Source/Runtime/Core/Public/Modules/ModuleManager.h index 9150e9cd6a46..b67d753922bd 100644 --- a/Engine/Source/Runtime/Core/Public/Modules/ModuleManager.h +++ b/Engine/Source/Runtime/Core/Public/Modules/ModuleManager.h @@ -438,7 +438,8 @@ public: * * @return The delegate. */ - FSimpleMulticastDelegate& OnProcessLoadedObjectsCallback() + DECLARE_EVENT_TwoParams(FModuleManager, ProcessLoadedObjectsEvent, FName, bool); + ProcessLoadedObjectsEvent& OnProcessLoadedObjectsCallback() { return ProcessLoadedObjectsCallback; } @@ -583,7 +584,7 @@ private: FModulesChangedEvent ModulesChangedEvent; /** Multicast delegate called to process any new loaded objects. */ - FSimpleMulticastDelegate ProcessLoadedObjectsCallback; + ProcessLoadedObjectsEvent ProcessLoadedObjectsCallback; /** When module manager is linked against an application that supports UObjects, this delegate will be primed at startup to provide information about whether a UObject package is loaded into memory. */ diff --git a/Engine/Source/Runtime/Core/Public/PixelFormat.h b/Engine/Source/Runtime/Core/Public/PixelFormat.h index 1dc7ed346373..8eb02cdea9f4 100644 --- a/Engine/Source/Runtime/Core/Public/PixelFormat.h +++ b/Engine/Source/Runtime/Core/Public/PixelFormat.h @@ -75,7 +75,7 @@ enum EPixelFormat PF_R8G8B8A8_SNORM =61, PF_R16G16B16A16_UNORM =62, PF_R16G16B16A16_SNORM =63, - PF_PLATFORM_HDR_0 =64, // Indicates platform-specific HDR output formats + PF_PLATFORM_HDR_0 =64, PF_PLATFORM_HDR_1 =65, // Reserved. PF_PLATFORM_HDR_2 =66, // Reserved. PF_NV12 =67, diff --git a/Engine/Source/Runtime/Core/Public/Unix/UnixPlatformMisc.h b/Engine/Source/Runtime/Core/Public/Unix/UnixPlatformMisc.h index 8bc089e877b5..e3890b7bc524 100644 --- a/Engine/Source/Runtime/Core/Public/Unix/UnixPlatformMisc.h +++ b/Engine/Source/Runtime/Core/Public/Unix/UnixPlatformMisc.h @@ -132,6 +132,7 @@ struct CORE_API FUnixPlatformMisc : public FGenericPlatformMisc */ static bool HasOverriddenReturnCode(uint8 * OverriddenReturnCodeToUsePtr); static FString GetOSVersion(); + static FString GetLoginId(); #if STATS || ENABLE_STATNAMEDEVENTS static void BeginNamedEventFrame(); diff --git a/Engine/Source/Runtime/Core/Public/Windows/WindowsPlatformCompilerPreSetup.h b/Engine/Source/Runtime/Core/Public/Windows/WindowsPlatformCompilerPreSetup.h index 8ba45d8a0cbe..47ad32c03c31 100644 --- a/Engine/Source/Runtime/Core/Public/Windows/WindowsPlatformCompilerPreSetup.h +++ b/Engine/Source/Runtime/Core/Public/Windows/WindowsPlatformCompilerPreSetup.h @@ -11,11 +11,15 @@ PRAGMA_DISABLE_REORDER_WARNINGS \ PRAGMA_DISABLE_SHADOW_VARIABLE_WARNINGS \ PRAGMA_DISABLE_UNDEFINED_IDENTIFIER_WARNINGS \ - PRAGMA_DISABLE_DEPRECATION_WARNINGS + PRAGMA_DISABLE_DEPRECATION_WARNINGS \ + PRAGMA_DISABLE_OVERLOADED_VIRTUAL_WARNINGS \ + PRAGMA_DISABLE_MISSING_BRACES_WARNINGS #endif // THIRD_PARTY_INCLUDES_START #ifndef THIRD_PARTY_INCLUDES_END #define THIRD_PARTY_INCLUDES_END \ + PRAGMA_DISABLE_MISSING_BRACES_WARNINGS \ + PRAGMA_DISABLE_OVERLOADED_VIRTUAL_WARNINGS \ PRAGMA_ENABLE_DEPRECATION_WARNINGS \ PRAGMA_ENABLE_UNDEFINED_IDENTIFIER_WARNINGS \ PRAGMA_ENABLE_SHADOW_VARIABLE_WARNINGS \ diff --git a/Engine/Source/Runtime/Core/Public/Windows/WindowsPlatformMisc.h b/Engine/Source/Runtime/Core/Public/Windows/WindowsPlatformMisc.h index 52ef4ab37a5a..ae76f236759d 100644 --- a/Engine/Source/Runtime/Core/Public/Windows/WindowsPlatformMisc.h +++ b/Engine/Source/Runtime/Core/Public/Windows/WindowsPlatformMisc.h @@ -80,6 +80,8 @@ struct CORE_API FWindowsPlatformMisc static int32 NumberOfCoresIncludingHyperthreads(); static int32 NumberOfWorkerThreadsToSpawn(); + static const TCHAR* GetPlatformFeaturesModuleName(); + static FString GetDefaultLanguage(); static FString GetDefaultLocale(); diff --git a/Engine/Source/Runtime/CoreUObject/Private/Internationalization/PackageLocalizationCache.cpp b/Engine/Source/Runtime/CoreUObject/Private/Internationalization/PackageLocalizationCache.cpp index 49c7a5cead8d..9ddb98c8d7e4 100644 --- a/Engine/Source/Runtime/CoreUObject/Private/Internationalization/PackageLocalizationCache.cpp +++ b/Engine/Source/Runtime/CoreUObject/Private/Internationalization/PackageLocalizationCache.cpp @@ -34,6 +34,7 @@ void FPackageLocalizationCultureCache::ConditionalUpdateCache_NoLock() return; } + SCOPED_BOOT_TIMING("FPackageLocalizationCultureCache::ConditionalUpdateCache_NoLock"); const double CacheStartTime = FPlatformTime::Seconds(); for (const FString& SourceRootPath : PendingSourceRootPathsToSearch) diff --git a/Engine/Source/Runtime/CoreUObject/Private/Misc/PackageName.cpp b/Engine/Source/Runtime/CoreUObject/Private/Misc/PackageName.cpp index b078157bbb23..3d954e28041d 100644 --- a/Engine/Source/Runtime/CoreUObject/Private/Misc/PackageName.cpp +++ b/Engine/Source/Runtime/CoreUObject/Private/Misc/PackageName.cpp @@ -1273,6 +1273,7 @@ void FPackageName::QueryRootContentPaths( TArray& OutRootContentPaths ) void FPackageName::EnsureContentPathsAreRegistered() { + SCOPED_BOOT_TIMING("FPackageName::EnsureContentPathsAreRegistered"); FLongPackagePathsSingleton::Get(); } diff --git a/Engine/Source/Runtime/CoreUObject/Private/UObject/Class.cpp b/Engine/Source/Runtime/CoreUObject/Private/UObject/Class.cpp index c22260d8c761..4bb24da33f73 100644 --- a/Engine/Source/Runtime/CoreUObject/Private/UObject/Class.cpp +++ b/Engine/Source/Runtime/CoreUObject/Private/UObject/Class.cpp @@ -3948,10 +3948,6 @@ void UClass::PurgeClass(bool bRecompilingOnLoad) } #endif -#if USE_UBER_GRAPH_PERSISTENT_FRAME - UberGraphFramePointerProperty = NULL; -#endif//USE_UBER_GRAPH_PERSISTENT_FRAME - ClassDefaultObject = NULL; Interfaces.Empty(); @@ -4032,9 +4028,6 @@ UClass::UClass(const FObjectInitializer& ObjectInitializer) , ClassCastFlags(CASTCLASS_None) , ClassWithin( UObject::StaticClass() ) , ClassGeneratedBy(nullptr) -#if USE_UBER_GRAPH_PERSISTENT_FRAME -, UberGraphFramePointerProperty(nullptr) -#endif // USE_UBER_GRAPH_PERSISTENT_FRAME , ClassDefaultObject(nullptr) { // If you add properties here, please update the other constructors and PurgeClass() @@ -4053,9 +4046,6 @@ UClass::UClass(const FObjectInitializer& ObjectInitializer, UClass* InBaseClass) , ClassCastFlags(CASTCLASS_None) , ClassWithin(UObject::StaticClass()) , ClassGeneratedBy(nullptr) -#if USE_UBER_GRAPH_PERSISTENT_FRAME -, UberGraphFramePointerProperty(nullptr) -#endif // USE_UBER_GRAPH_PERSISTENT_FRAME , ClassDefaultObject(nullptr) { // If you add properties here, please update the other constructors and PurgeClass() @@ -4369,6 +4359,7 @@ UFunction* UClass::FindFunctionByName(FName InName, EIncludeSuperFlag::Type Incl void UClass::AssembleReferenceTokenStreams() { + SCOPED_BOOT_TIMING("AssembleReferenceTokenStreams (can be optimized)"); // Iterate over all class objects and force the default objects to be created. Additionally also // assembles the token reference stream at this point. This is required for class objects that are // not taken into account for garbage collection but have instances that are. diff --git a/Engine/Source/Runtime/CoreUObject/Private/UObject/CoreNative.cpp b/Engine/Source/Runtime/CoreUObject/Private/UObject/CoreNative.cpp index a67fa4538c43..b1f87448a9d8 100644 --- a/Engine/Source/Runtime/CoreUObject/Private/UObject/CoreNative.cpp +++ b/Engine/Source/Runtime/CoreUObject/Private/UObject/CoreNative.cpp @@ -32,11 +32,8 @@ public: virtual void StartupModule() override { - { - SCOPED_BOOT_TIMING("UClassRegisterAllCompiledInClasses"); - // Register all classes that have been loaded so far. This is required for CVars to work. - UClassRegisterAllCompiledInClasses(); - } + // Register all classes that have been loaded so far. This is required for CVars to work. + UClassRegisterAllCompiledInClasses(); void InitUObject(); FCoreDelegates::OnInit.AddStatic(InitUObject); @@ -54,11 +51,8 @@ public: FRuntimeErrors::OnRuntimeIssueLogged.BindStatic(&FCoreUObjectModule::RouteRuntimeMessageToBP); #endif - { - SCOPED_BOOT_TIMING("FPackageName::EnsureContentPathsAreRegistered"); - // Make sure that additional content mount points can be registered after CoreUObject loads - FPackageName::EnsureContentPathsAreRegistered(); - } + // Make sure that additional content mount points can be registered after CoreUObject loads + FPackageName::EnsureContentPathsAreRegistered(); #if DO_BLUEPRINT_GUARD FFrame::InitPrintScriptCallstack(); diff --git a/Engine/Source/Runtime/CoreUObject/Private/UObject/Obj.cpp b/Engine/Source/Runtime/CoreUObject/Private/UObject/Obj.cpp index 4ad5f81168da..c390ea93114b 100644 --- a/Engine/Source/Runtime/CoreUObject/Private/UObject/Obj.cpp +++ b/Engine/Source/Runtime/CoreUObject/Private/UObject/Obj.cpp @@ -4233,7 +4233,9 @@ void InitUObject() FCoreDelegates::OnShutdownAfterError.AddStatic(StaticShutdownAfterError); FCoreDelegates::OnExit.AddStatic(StaticExit); +#if !USE_PER_MODULE_UOBJECT_BOOTSTRAP // otherwise this is already done FModuleManager::Get().OnProcessLoadedObjectsCallback().AddStatic(ProcessNewlyLoadedUObjects); +#endif struct Local { diff --git a/Engine/Source/Runtime/CoreUObject/Private/UObject/SavePackage.cpp b/Engine/Source/Runtime/CoreUObject/Private/UObject/SavePackage.cpp index 38c4ededa761..57132cb00396 100644 --- a/Engine/Source/Runtime/CoreUObject/Private/UObject/SavePackage.cpp +++ b/Engine/Source/Runtime/CoreUObject/Private/UObject/SavePackage.cpp @@ -5631,8 +5631,8 @@ FSavePackageResultStruct UPackage::Save(UPackage* InOuter, UObject* Base, EObjec // Set bulk data flags to what they were during initial serialization (they might have changed after that) const uint32 OldBulkDataFlags = BulkDataStorageInfo.BulkData->GetBulkDataFlags(); uint32 ModifiedBulkDataFlags = BulkDataStorageInfo.BulkDataFlags | ExtraBulkDataFlags; - bool bBulkItemIsOptional = (ModifiedBulkDataFlags & BULKDATA_OptionalPayload); - bool bBulkItemIsMapped = bAlignBulkData && (ModifiedBulkDataFlags & BULKDATA_MemoryMappedPayload); + bool bBulkItemIsOptional = (ModifiedBulkDataFlags & BULKDATA_OptionalPayload) != 0; + bool bBulkItemIsMapped = bAlignBulkData && ((ModifiedBulkDataFlags & BULKDATA_MemoryMappedPayload) != 0); if (bBulkItemIsMapped && bBulkItemIsOptional) { diff --git a/Engine/Source/Runtime/CoreUObject/Private/UObject/ScriptCore.cpp b/Engine/Source/Runtime/CoreUObject/Private/UObject/ScriptCore.cpp index b58cde0b4ca7..6f8fd4a8e464 100644 --- a/Engine/Source/Runtime/CoreUObject/Private/UObject/ScriptCore.cpp +++ b/Engine/Source/Runtime/CoreUObject/Private/UObject/ScriptCore.cpp @@ -50,22 +50,6 @@ static FAutoConsoleVariableRef CVarVerboseScriptStats( ECVF_Default ); -#if USE_UBER_GRAPH_PERSISTENT_FRAME -// Mirror definition of FPointerToUberGraphFrame, it is a UStruct and -// we cannot easily generate its reflection data here in CoreUObject. The -// builtins pattern we use for FVector, FQuat etc cannot be used because -// our only member is a raw pointer and it cannot be a UProperty. This -// creates difficulty in determining the correct size for the UStruct -struct FPointerToUberGraphFrameCoreUObject -{ - uint8* RawPointer; - -#if VALIDATE_UBER_GRAPH_PERSISTENT_FRAME - uint32 UberGraphFunctionKey; -#endif//VALIDATE_UBER_GRAPH_PERSISTENT_FRAME -}; -#endif //USE_UBER_GRAPH_PERSISTENT_FRAME - /*----------------------------------------------------------------------------- Globals. -----------------------------------------------------------------------------*/ @@ -325,33 +309,6 @@ FString UnicodeToCPPIdentifier(const FString& InName, bool bDeprecated, const TC return bDeprecated ? Ret + TEXT("_DEPRECATED") : Ret; } -#if USE_UBER_GRAPH_PERSISTENT_FRAME -/** Returns memory used to store temporary data on an instance, used by blueprints */ -static uint8* GetPersistentUberGraphFrameUnchecked(const UFunction* ForFn, UObject* Obj) -{ - const UClass* FromClass = ForFn->GetOuterUClassUnchecked(); - checkSlow(ForFn->HasAnyFunctionFlags(FUNC_UbergraphFunction)); - checkSlow(Obj->IsA(FromClass)); - checkSlow(FromClass->UberGraphFramePointerProperty); - FPointerToUberGraphFrameCoreUObject* PointerToUberGraphFrame = - FromClass->UberGraphFramePointerProperty->ContainerPtrToValuePtr( - (void*)Obj - ); - checkSlow(PointerToUberGraphFrame); - checkSlow(PointerToUberGraphFrame->RawPointer); - return PointerToUberGraphFrame->RawPointer; -} - -uint8* GetPersistentUberGraphFrame(const UFunction* ForFn, UObject* Obj) -{ - if (ForFn->HasAnyFunctionFlags(FUNC_UbergraphFunction)) - { - return GetPersistentUberGraphFrameUnchecked(ForFn, Obj); - } - return nullptr; -} -#endif //USE_UBER_GRAPH_PERSISTENT_FRAME - /*----------------------------------------------------------------------------- FFrame implementation. -----------------------------------------------------------------------------*/ @@ -745,7 +702,7 @@ void ProcessScriptFunction(UObject* Context, UFunction* Function, FFrame& Stack, uint8* FrameMemory = nullptr; FFrame NewStack(Context, Function, nullptr, &Stack, Function->Children); #if USE_UBER_GRAPH_PERSISTENT_FRAME - FrameMemory = GetPersistentUberGraphFrame(Function, Context); + FrameMemory = Function->GetOuterUClassUnchecked()->GetPersistentUberGraphFrame(Context, Function); #endif bool bUsePersistentFrame = (nullptr != FrameMemory); if (!bUsePersistentFrame) @@ -1430,7 +1387,10 @@ void UObject::ProcessEvent( UFunction* Function, void* Parms ) { uint8* Frame = NULL; #if USE_UBER_GRAPH_PERSISTENT_FRAME - Frame = GetPersistentUberGraphFrame(Function, this); + if (Function->HasAnyFunctionFlags(FUNC_UbergraphFunction)) + { + Frame = Function->GetOuterUClassUnchecked()->GetPersistentUberGraphFrame(this, Function); + } #endif const bool bUsePersistentFrame = (NULL != Frame); if (!bUsePersistentFrame) @@ -1964,7 +1924,7 @@ DEFINE_FUNCTION(UObject::execLetValueOnPersistentFrame) checkSlow(DestProperty); UFunction* UberGraphFunction = CastChecked(DestProperty->GetOwnerStruct()); checkSlow(Stack.Object->GetClass()->IsChildOf(UberGraphFunction->GetOuterUClassUnchecked())); - uint8* FrameBase = GetPersistentUberGraphFrameUnchecked(UberGraphFunction, Stack.Object); + uint8* FrameBase = UberGraphFunction->GetOuterUClassUnchecked()->GetPersistentUberGraphFrame(Stack.Object, UberGraphFunction); checkSlow(FrameBase); uint8* DestAddress = DestProperty->ContainerPtrToValuePtr(FrameBase); diff --git a/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectBase.cpp b/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectBase.cpp index b232d3cc0caf..350b788fd271 100644 --- a/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectBase.cpp +++ b/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectBase.cpp @@ -20,12 +20,15 @@ #include "UObject/GCObject.h" #include "UObject/LinkerLoad.h" #include "Misc/CommandLine.h" +#include "Interfaces/IPluginManager.h" DEFINE_LOG_CATEGORY_STATIC(LogUObjectBase, Log, All); DEFINE_STAT(STAT_UObjectsStatGroupTester); DECLARE_CYCLE_STAT(TEXT("CreateStatID"), STAT_CreateStatID, STATGROUP_StatSystem); +DEFINE_LOG_CATEGORY_STATIC(LogUObjectBootstrap, Display, Display); + /** Whether uobject system is initialized. */ namespace Internal @@ -51,7 +54,6 @@ struct FPendingRegistrantInfo }; - /** Objects to automatically register once the object system is ready. */ struct FPendingRegistrant { @@ -65,6 +67,16 @@ struct FPendingRegistrant static FPendingRegistrant* GFirstPendingRegistrant = NULL; static FPendingRegistrant* GLastPendingRegistrant = NULL; +#if USE_PER_MODULE_UOBJECT_BOOTSTRAP +static TMap>& GetPerModuleBootstrapMap() +{ + static TMap> PendingRegistrantInfo; + return PendingRegistrantInfo; +} + +#endif + + /** * Constructor used for bootstrapping * @param InClass possibly NULL, this gives the class of the new object, if known at this time @@ -211,6 +223,8 @@ void UObjectBase::DeferredRegister(UClass *UClassStaticClass,const TCHAR* Packag // Make sure that objects disregarded for GC are part of root set. check(!GUObjectArray.IsDisregardForGC(this) || GUObjectArray.IndexToObject(InternalIndex)->IsRootSet()); + + UE_LOG(LogUObjectBootstrap, Verbose, TEXT("UObjectBase::DeferredRegister %s %s"), PackageName, InName); } /** @@ -360,6 +374,83 @@ void UObjectBase::EmitBaseReferences(UClass *RootClass) RootClass->EmitObjectReference(STRUCT_OFFSET(UObjectBase, OuterPrivate), OuterPropertyName, GCRT_PersistentObject); } +#if USE_PER_MODULE_UOBJECT_BOOTSTRAP +static void UObjectReleaseModuleRegistrants(FName Module) +{ + TMap>& PerModuleMap = GetPerModuleBootstrapMap(); + + FName Package = IPluginManager::Get().PackageNameFromModuleName(Module); + + FName ScriptName = *(FString(TEXT("/Script/")) + Package.ToString()); + + TArray* Array = PerModuleMap.Find(ScriptName); + if (Array) + { + SCOPED_BOOT_TIMING("UObjectReleaseModuleRegistrants"); + for (FPendingRegistrant* PendingRegistration : *Array) + { + if (GLastPendingRegistrant) + { + GLastPendingRegistrant->NextAutoRegister = PendingRegistration; + } + else + { + check(!GFirstPendingRegistrant); + GFirstPendingRegistrant = PendingRegistration; + } + GLastPendingRegistrant = PendingRegistration; + } + UE_LOG(LogUObjectBootstrap, Verbose, TEXT("UObjectReleaseModuleRegistrants %d items in %s"), Array->Num(), *ScriptName.ToString()); + PerModuleMap.Remove(ScriptName); + } + else + { + UE_LOG(LogUObjectBootstrap, Verbose, TEXT("UObjectReleaseModuleRegistrants no items in %s"), *ScriptName.ToString()); + } +} + +void UObjectReleaseAllModuleRegistrants() +{ + SCOPED_BOOT_TIMING("UObjectReleaseAllModuleRegistrants"); + TMap>& PerModuleMap = GetPerModuleBootstrapMap(); + for (auto& Pair : PerModuleMap) + { + for (FPendingRegistrant* PendingRegistration : Pair.Value) + { + if (GLastPendingRegistrant) + { + GLastPendingRegistrant->NextAutoRegister = PendingRegistration; + } + else + { + check(!GFirstPendingRegistrant); + GFirstPendingRegistrant = PendingRegistration; + } + GLastPendingRegistrant = PendingRegistration; + } + UE_LOG(LogUObjectBootstrap, Verbose, TEXT("UObjectReleaseAllModuleRegistrants %d items in %s"), Pair.Value.Num(), *Pair.Key.ToString()); + } + PerModuleMap.Empty(); + ProcessNewlyLoadedUObjects(); +} + +static void DumpPendingUObjectModules(const TArray& Args) +{ + TMap>& PerModuleMap = GetPerModuleBootstrapMap(); + for (auto& Pair : PerModuleMap) + { + UE_LOG(LogUObjectBootstrap, Display, TEXT("Not yet loaded: %d items in %s"), Pair.Value.Num(), *Pair.Key.ToString()); + } +} + +static FAutoConsoleCommand DumpPendingUObjectModulesCmd( + TEXT("DumpPendingUObjectModules"), + TEXT("When doing per-module UObject bootstrapping, show the modules that are not yet loaded."), + FConsoleCommandWithArgsDelegate::CreateStatic(&DumpPendingUObjectModules) +); + +#endif + /** Enqueue the registration for this object. */ void UObjectBase::Register(const TCHAR* PackageName,const TCHAR* InName) { @@ -367,16 +458,28 @@ void UObjectBase::Register(const TCHAR* PackageName,const TCHAR* InName) FPendingRegistrant* PendingRegistration = new FPendingRegistrant(this); PendingRegistrants.Add(this, FPendingRegistrantInfo(InName, PackageName)); - if(GLastPendingRegistrant) + +#if USE_PER_MODULE_UOBJECT_BOOTSTRAP + if (FName(PackageName) != FName("/Script/CoreUObject")) { - GLastPendingRegistrant->NextAutoRegister = PendingRegistration; + TMap>& PerModuleMap = GetPerModuleBootstrapMap(); + + PerModuleMap.FindOrAdd(FName(PackageName)).Add(PendingRegistration); } else +#endif { - check(!GFirstPendingRegistrant); - GFirstPendingRegistrant = PendingRegistration; + if (GLastPendingRegistrant) + { + GLastPendingRegistrant->NextAutoRegister = PendingRegistration; + } + else + { + check(!GFirstPendingRegistrant); + GFirstPendingRegistrant = PendingRegistration; + } + GLastPendingRegistrant = PendingRegistration; } - GLastPendingRegistrant = PendingRegistration; } @@ -405,6 +508,8 @@ static void DequeuePendingAutoRegistrants(TArray& OutPending */ static void UObjectProcessRegistrants() { + SCOPED_BOOT_TIMING("UObjectProcessRegistrants"); + check(UObjectInitialized()); // Make list of all objects to be registered. TArray PendingRegistrants; @@ -414,7 +519,7 @@ static void UObjectProcessRegistrants() { const FPendingRegistrant& PendingRegistrant = PendingRegistrants[RegistrantIndex]; - UObjectForceRegistration(PendingRegistrant.Object); + UObjectForceRegistration(PendingRegistrant.Object, false); check(PendingRegistrant.Object->GetClass()); // should have been set by DeferredRegister @@ -423,7 +528,7 @@ static void UObjectProcessRegistrants() } } -void UObjectForceRegistration(UObjectBase* Object) +void UObjectForceRegistration(UObjectBase* Object, bool bCheckForModuleRelease) { TMap& PendingRegistrants = FPendingRegistrantInfo::GetMap(); @@ -431,6 +536,12 @@ void UObjectForceRegistration(UObjectBase* Object) if (Info) { const TCHAR* PackageName = Info->PackageName; +#if USE_PER_MODULE_UOBJECT_BOOTSTRAP + if (bCheckForModuleRelease) + { + UObjectReleaseModuleRegistrants(FName(PackageName)); + } +#endif const TCHAR* Name = Info->Name; PendingRegistrants.Remove(Object); // delete this first so that it doesn't try to do it twice Object->DeferredRegister(UClass::StaticClass(),PackageName,Name); @@ -700,6 +811,7 @@ void UClassRegisterAllCompiledInClasses() #if WITH_HOT_RELOAD TArray AddedClasses; #endif + SCOPED_BOOT_TIMING("UClassRegisterAllCompiledInClasses"); TArray& DeferredClassRegistration = GetDeferredClassRegistration(); for (const FFieldCompiledInInfo* Class : DeferredClassRegistration) @@ -762,6 +874,7 @@ static void UObjectLoadAllCompiledInDefaultProperties() const bool bHaveRegistrants = DeferredCompiledInRegistration.Num() != 0; if( bHaveRegistrants ) { + SCOPED_BOOT_TIMING("UObjectLoadAllCompiledInDefaultProperties"); TArray NewClasses; TArray NewClassesInCoreUObject; TArray NewClassesInEngine; @@ -769,6 +882,7 @@ static void UObjectLoadAllCompiledInDefaultProperties() for (UClass* (*Registrant)() : PendingRegistrants) { UClass* Class = Registrant(); + UE_LOG(LogUObjectBootstrap, Verbose, TEXT("UObjectLoadAllCompiledInDefaultProperties After Registrant %s %s"), *Class->GetOutermost()->GetName(), *Class->GetName()); if (Class->GetOutermost()->GetFName() == GLongCoreUObjectPackageName) { NewClassesInCoreUObject.Add(Class); @@ -782,19 +896,33 @@ static void UObjectLoadAllCompiledInDefaultProperties() NewClasses.Add(Class); } } - for (UClass* Class : NewClassesInCoreUObject) // we do these first because we assume these never trigger loads { - Class->GetDefaultObject(); + SCOPED_BOOT_TIMING("CoreUObject Classes"); + for (UClass* Class : NewClassesInCoreUObject) // we do these first because we assume these never trigger loads + { + UE_LOG(LogUObjectBootstrap, Verbose, TEXT("GetDefaultObject Begin %s %s"), *Class->GetOutermost()->GetName(), *Class->GetName()); + Class->GetDefaultObject(); + UE_LOG(LogUObjectBootstrap, Verbose, TEXT("GetDefaultObject End %s %s"), *Class->GetOutermost()->GetName(), *Class->GetName()); + } } - for (UClass* Class : NewClassesInEngine) // we do these second because we want to bring the engine up before the game { - Class->GetDefaultObject(); + SCOPED_BOOT_TIMING("Engine Classes"); + for (UClass* Class : NewClassesInEngine) // we do these second because we want to bring the engine up before the game + { + UE_LOG(LogUObjectBootstrap, Verbose, TEXT("GetDefaultObject Begin %s %s"), *Class->GetOutermost()->GetName(), *Class->GetName()); + Class->GetDefaultObject(); + UE_LOG(LogUObjectBootstrap, Verbose, TEXT("GetDefaultObject End %s %s"), *Class->GetOutermost()->GetName(), *Class->GetName()); + } } - for (UClass* Class : NewClasses) { - Class->GetDefaultObject(); + SCOPED_BOOT_TIMING("Other Classes"); + for (UClass* Class : NewClasses) + { + UE_LOG(LogUObjectBootstrap, Verbose, TEXT("GetDefaultObject Begin %s %s"), *Class->GetOutermost()->GetName(), *Class->GetName()); + Class->GetDefaultObject(); + UE_LOG(LogUObjectBootstrap, Verbose, TEXT("GetDefaultObject End %s %s"), *Class->GetOutermost()->GetName(), *Class->GetName()); + } } - FFeedbackContext& ErrorsFC = UClass::GetDefaultPropertiesFeedbackContext(); if (ErrorsFC.GetNumErrors() || ErrorsFC.GetNumWarnings()) { @@ -819,20 +947,24 @@ static void UObjectLoadAllCompiledInDefaultProperties() */ static void UObjectLoadAllCompiledInStructs() { + SCOPED_BOOT_TIMING("UObjectLoadAllCompiledInStructs"); - // Load Enums first TArray PendingEnumRegistrants = MoveTemp(GetDeferredCompiledInEnumRegistration()); - for (const FPendingEnumRegistrant& EnumRegistrant : PendingEnumRegistrants) - { - // Make sure the package exists in case it does not contain any UObjects - CreatePackage(nullptr, EnumRegistrant.PackageName); - } - TArray PendingStructRegistrants = MoveTemp(GetDeferredCompiledInStructRegistration()); - for (const FPendingStructRegistrant& StructRegistrant : PendingStructRegistrants) + { - // Make sure the package exists in case it does not contain any UObjects or UEnums - CreatePackage(nullptr, StructRegistrant.PackageName); + SCOPED_BOOT_TIMING("UObjectLoadAllCompiledInStructs - CreatePackages (could be optimized!)"); + // Load Enums first + for (const FPendingEnumRegistrant& EnumRegistrant : PendingEnumRegistrants) + { + // Make sure the package exists in case it does not contain any UObjects + CreatePackage(nullptr, EnumRegistrant.PackageName); + } + for (const FPendingStructRegistrant& StructRegistrant : PendingStructRegistrants) + { + // Make sure the package exists in case it does not contain any UObjects or UEnums + CreatePackage(nullptr, StructRegistrant.PackageName); + } } // Load Structs @@ -848,8 +980,19 @@ static void UObjectLoadAllCompiledInStructs() } } -void ProcessNewlyLoadedUObjects() +void ProcessNewlyLoadedUObjects(FName Package, bool bCanProcessNewlyLoadedObjects) { + SCOPED_BOOT_TIMING("ProcessNewlyLoadedUObjects"); +#if USE_PER_MODULE_UOBJECT_BOOTSTRAP + if (Package != NAME_None) + { + UObjectReleaseModuleRegistrants(Package); + } +#endif + if (!bCanProcessNewlyLoadedObjects) + { + return; + } LLM_SCOPE(ELLMTag::UObject); DECLARE_SCOPE_CYCLE_COUNTER(TEXT("ProcessNewlyLoadedUObjects"), STAT_ProcessNewlyLoadedUObjects, STATGROUP_ObjectVerbose); @@ -860,7 +1003,7 @@ void ProcessNewlyLoadedUObjects() const TArray& DeferredCompiledInEnumRegistration = GetDeferredCompiledInEnumRegistration(); bool bNewUObjects = false; - while( GFirstPendingRegistrant || DeferredCompiledInRegistration.Num() || DeferredCompiledInStructRegistration.Num() || DeferredCompiledInEnumRegistration.Num() ) + while (GFirstPendingRegistrant || DeferredCompiledInRegistration.Num() || DeferredCompiledInStructRegistration.Num() || DeferredCompiledInEnumRegistration.Num()) { bNewUObjects = true; UObjectProcessRegistrants(); @@ -915,6 +1058,8 @@ static FAutoConsoleVariableRef CMaxObjectsInGame( */ void UObjectBaseInit() { + SCOPED_BOOT_TIMING("UObjectBaseInit"); + // Zero initialize and later on get value from .ini so it is overridable per game/ platform... int32 MaxObjectsNotConsideredByGC = 0; int32 SizeOfPermanentObjectPool = 0; diff --git a/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectGlobals.cpp b/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectGlobals.cpp index 565ebcf769d8..13dbf28c1f9e 100644 --- a/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectGlobals.cpp +++ b/Engine/Source/Runtime/CoreUObject/Private/UObject/UObjectGlobals.cpp @@ -4339,6 +4339,8 @@ namespace UE4CodeGen_Private #if WITH_METADATA AddMetaData(NewFunction, Params.MetaDataArray, Params.NumMetaData); #endif + NewFunction->RPCId = Params.RPCId; + NewFunction->RPCResponseId = Params.RPCResponseId; ConstructUProperties(NewFunction, Params.PropertyArray, Params.NumProperties); @@ -4414,7 +4416,20 @@ namespace UE4CodeGen_Private return; } - UPackage* NewPackage = CastChecked(StaticFindObjectFast(UPackage::StaticClass(), nullptr, FName(UTF8_TO_TCHAR(Params.NameUTF8)), false, false)); + UObject* FoundPackage = StaticFindObjectFast(UPackage::StaticClass(), nullptr, FName(UTF8_TO_TCHAR(Params.NameUTF8)), false, false); + +#if USE_PER_MODULE_UOBJECT_BOOTSTRAP + if (!FoundPackage) + { + UE_LOG(LogUObjectGlobals, Log, TEXT("Creating package on the fly %s"), UTF8_TO_TCHAR(Params.NameUTF8)); + ProcessNewlyLoadedUObjects(FName(UTF8_TO_TCHAR(Params.NameUTF8)), false); + FoundPackage = CreatePackage(nullptr, UTF8_TO_TCHAR(Params.NameUTF8)); + } +#endif + + checkf(FoundPackage, TEXT("Code not found for generated code (package %s)."), UTF8_TO_TCHAR(Params.NameUTF8)); + + UPackage* NewPackage = CastChecked(FoundPackage); OutPackage = NewPackage; #if WITH_METADATA diff --git a/Engine/Source/Runtime/CoreUObject/Public/Serialization/DuplicatedDataReader.h b/Engine/Source/Runtime/CoreUObject/Public/Serialization/DuplicatedDataReader.h index a00d6f96e146..335e79c946e4 100644 --- a/Engine/Source/Runtime/CoreUObject/Public/Serialization/DuplicatedDataReader.h +++ b/Engine/Source/Runtime/CoreUObject/Public/Serialization/DuplicatedDataReader.h @@ -7,6 +7,8 @@ #include "UObject/UObjectAnnotation.h" #include "Serialization/DuplicatedObject.h" #include "Serialization/LargeMemoryData.h" +#include "Templates/RefCounting.h" +#include "UObject/UObjectThreadContext.h" /*---------------------------------------------------------------------------- FDuplicateDataReader. @@ -23,6 +25,9 @@ private: const FLargeMemoryData& ObjectData; int64 Offset; + /** Context for duplication */ + TRefCountPtr DuplicateContext; + //~ Begin FArchive Interface. virtual FArchive& operator<<(FName& N); @@ -67,6 +72,16 @@ public: return ObjectData.GetSize(); } + virtual void SetSerializeContext(FUObjectSerializeContext* InLoadContext) override + { + DuplicateContext = InLoadContext; + } + + virtual FUObjectSerializeContext* GetSerializeContext() override + { + return DuplicateContext; + } + /** * Constructor * diff --git a/Engine/Source/Runtime/CoreUObject/Public/Serialization/DuplicatedDataWriter.h b/Engine/Source/Runtime/CoreUObject/Public/Serialization/DuplicatedDataWriter.h index 2418addff708..e0a06d865f88 100644 --- a/Engine/Source/Runtime/CoreUObject/Public/Serialization/DuplicatedDataWriter.h +++ b/Engine/Source/Runtime/CoreUObject/Public/Serialization/DuplicatedDataWriter.h @@ -7,6 +7,8 @@ #include "UObject/UObjectAnnotation.h" #include "Serialization/DuplicatedObject.h" #include "Serialization/LargeMemoryData.h" +#include "Templates/RefCounting.h" +#include "UObject/UObjectThreadContext.h" struct FObjectInstancingGraph; @@ -34,6 +36,9 @@ private: */ struct FObjectInstancingGraph* InstanceGraph; + /** Context for duplication */ + TRefCountPtr DuplicateContext; + //~ Begin FArchive Interface. virtual FArchive& operator<<(FName& N); @@ -80,6 +85,16 @@ public: return ObjectData.GetSize(); } + virtual void SetSerializeContext(FUObjectSerializeContext* InLoadContext) override + { + DuplicateContext = InLoadContext; + } + + virtual FUObjectSerializeContext* GetSerializeContext() override + { + return DuplicateContext; + } + TArray UnserializedObjects; /** diff --git a/Engine/Source/Runtime/CoreUObject/Public/Templates/Casts.h b/Engine/Source/Runtime/CoreUObject/Public/Templates/Casts.h index 97148c10c474..9590068a33d2 100644 --- a/Engine/Source/Runtime/CoreUObject/Public/Templates/Casts.h +++ b/Engine/Source/Runtime/CoreUObject/Public/Templates/Casts.h @@ -344,6 +344,15 @@ DECLARE_CAST_BY_FLAG(UBlueprint) \ DECLARE_CAST_BY_FLAG(UDelegateFunction) \ DECLARE_CAST_BY_FLAG(UStaticMeshComponent) \ DECLARE_CAST_BY_FLAG(UEnumProperty) \ +DECLARE_CAST_BY_FLAG(UNumericProperty) \ +DECLARE_CAST_BY_FLAG(UInt8Property) \ +DECLARE_CAST_BY_FLAG(UInt16Property) \ +DECLARE_CAST_BY_FLAG(UInt64Property) \ +DECLARE_CAST_BY_FLAG(UUInt16Property) \ +DECLARE_CAST_BY_FLAG(UUInt32Property) \ +DECLARE_CAST_BY_FLAG(UUInt64Property) \ +DECLARE_CAST_BY_FLAG(UMapProperty) \ +DECLARE_CAST_BY_FLAG(USetProperty) \ FINISH_DECLARING_CAST_FLAGS // This is here to hopefully remind people to include the "\" in all declarations above, especially when copy/pasting the final line. // Now actually declare the flags diff --git a/Engine/Source/Runtime/CoreUObject/Public/UObject/Class.h b/Engine/Source/Runtime/CoreUObject/Public/UObject/Class.h index 37f555fcf290..b462d434430e 100644 --- a/Engine/Source/Runtime/CoreUObject/Public/UObject/Class.h +++ b/Engine/Source/Runtime/CoreUObject/Public/UObject/Class.h @@ -2203,16 +2203,6 @@ public: /** This is the blueprint that caused the generation of this class, or null if it is a native compiled-in class */ UObject* ClassGeneratedBy; -#if USE_UBER_GRAPH_PERSISTENT_FRAME - /** - * Property that points to the ubergraph frame, this is a blueprint specific structure that has been hoisted - * to UClass so that the interpreter (ScriptCore.cpp) can access it efficiently. The uber graph frame is a struct - * owned by a UObject but allocated separately that has a layout that corresponds to a specific UFunction (the - * UberGraphFunction) in a blueprint. - */ - UStructProperty* UberGraphFramePointerProperty; -#endif //USE_UBER_GRAPH_PERSISTENT_FRAME - #if WITH_EDITOR /** * Conditionally recompiles the class after loading, in case any dependencies were also newly loaded @@ -2506,6 +2496,12 @@ public: */ FName GetDefaultObjectName(); + /** Returns memory used to store temporary data on an instance, used by blueprints */ + virtual uint8* GetPersistentUberGraphFrame(UObject* Obj, UFunction* FuncToCheck) const + { + return nullptr; + } + /** Creates memory to store temporary data */ virtual void CreatePersistentUberGraphFrame(UObject* Obj, bool bCreateOnlyIfEmpty = false, bool bSkipSuperClass = false, UClass* OldClass = nullptr) const { diff --git a/Engine/Source/Runtime/CoreUObject/Public/UObject/Script.h b/Engine/Source/Runtime/CoreUObject/Public/UObject/Script.h index 3750cc6d3c65..afcccc7f884d 100644 --- a/Engine/Source/Runtime/CoreUObject/Public/UObject/Script.h +++ b/Engine/Source/Runtime/CoreUObject/Public/UObject/Script.h @@ -552,13 +552,3 @@ COREUOBJECT_API FString ToValidCPPIdentifierChars(TCHAR Char); */ COREUOBJECT_API FString UnicodeToCPPIdentifier(const FString& InName, bool bDeprecated, const TCHAR* Prefix); -/** - @param ForFn Function to search for a corresponding uber graph frame - @param Obj owning the uber graph frame, Obj must be an instance based on ForFn->GetOuterUClass() - @return A pointer to the start of the objects persistent uber graph - frame if ForFn is an ubergraph function, else nullptr. The uber graph - frame is a struct that has a matching layout to a blueprint's UberGraphFunction's - parameters. The Uber Graph frame is an optimization because it avoids a large - allocation and corresponding initialization when calling the UberGraphFunction -*/ -COREUOBJECT_API uint8* GetPersistentUberGraphFrame(const UFunction* ForFn, UObject* Obj); \ No newline at end of file diff --git a/Engine/Source/Runtime/CoreUObject/Public/UObject/UObjectBase.h b/Engine/Source/Runtime/CoreUObject/Public/UObject/UObjectBase.h index 50a1132b51aa..0b96538fad3c 100644 --- a/Engine/Source/Runtime/CoreUObject/Public/UObject/UObjectBase.h +++ b/Engine/Source/Runtime/CoreUObject/Public/UObject/UObjectBase.h @@ -23,7 +23,7 @@ class COREUOBJECT_API UObjectBase friend struct Z_Construct_UClass_UObject_Statics; friend class FUObjectArray; // for access to InternalIndex without revealing it to anyone else friend class FUObjectAllocator; // for access to destructor without revealing it to anyone else - friend COREUOBJECT_API void UObjectForceRegistration(UObjectBase* Object); + friend COREUOBJECT_API void UObjectForceRegistration(UObjectBase* Object, bool bCheckForModuleRelease); friend COREUOBJECT_API void InitializePrivateStaticClass( class UClass* TClass_Super_StaticClass, class UClass* TClass_PrivateStaticClass, @@ -290,7 +290,7 @@ FORCEINLINE bool UObjectInitialized() { return Internal::GObjInitialized; } /** * Force a pending registrant to register now instead of in the natural order */ -COREUOBJECT_API void UObjectForceRegistration(UObjectBase* Object); +COREUOBJECT_API void UObjectForceRegistration(UObjectBase* Object, bool bCheckForModuleRelease = true); /** * Base class for deferred native class registration @@ -416,7 +416,7 @@ COREUOBJECT_API class UScriptStruct* FindExistingStructIfHotReloadOrDynamic(UObj COREUOBJECT_API class UEnum* FindExistingEnumIfHotReloadOrDynamic(UObject* Outer, const TCHAR* EnumName, SIZE_T Size, uint32 Crc, bool bIsDynamic); /** Must be called after a module has been loaded that contains UObject classes */ -COREUOBJECT_API void ProcessNewlyLoadedUObjects(); +COREUOBJECT_API void ProcessNewlyLoadedUObjects(FName Package = NAME_None, bool bCanProcessNewlyLoadedObjects = true); #if WITH_HOT_RELOAD /** Map of duplicated CDOs for reinstancing during hot-reload purposes. */ diff --git a/Engine/Source/Runtime/D3D12RHI/Private/D3D12Device.cpp b/Engine/Source/Runtime/D3D12RHI/Private/D3D12Device.cpp index 8d1591bdeefe..cf765e39d7a6 100644 --- a/Engine/Source/Runtime/D3D12RHI/Private/D3D12Device.cpp +++ b/Engine/Source/Runtime/D3D12RHI/Private/D3D12Device.cpp @@ -146,6 +146,7 @@ bool FD3D12Device::IsGPUIdle() typedef HRESULT(WINAPI *FDXGIGetDebugInterface1)(UINT, REFIID, void **); #endif +ID3D12CommandQueue* gD3D12CommandQueue; void FD3D12Device::SetupAfterDeviceCreation() { @@ -255,6 +256,7 @@ void FD3D12Device::SetupAfterDeviceCreation() TimestampQueryHeap.Init(); CommandListManager->Create(L"3D Queue"); + gD3D12CommandQueue = CommandListManager->GetD3DCommandQueue(); CopyCommandListManager->Create(L"Copy Queue"); AsyncCommandListManager->Create(L"Async Compute Queue", 0, AsyncComputePriority_Default); diff --git a/Engine/Source/Runtime/Engine/Classes/Animation/AnimBlueprintGeneratedClass.h b/Engine/Source/Runtime/Engine/Classes/Animation/AnimBlueprintGeneratedClass.h index 38d3ebc736a4..829831aba98a 100644 --- a/Engine/Source/Runtime/Engine/Classes/Animation/AnimBlueprintGeneratedClass.h +++ b/Engine/Source/Runtime/Engine/Classes/Animation/AnimBlueprintGeneratedClass.h @@ -350,6 +350,7 @@ public: // UClass interface virtual void PurgeClass(bool bRecompilingOnLoad) override; + virtual uint8* GetPersistentUberGraphFrame(UObject* Obj, UFunction* FuncToCheck) const override; virtual void PostLoadDefaultObject(UObject* Object) override; // End of UClass interface }; diff --git a/Engine/Source/Runtime/Engine/Classes/Animation/AnimInstance.h b/Engine/Source/Runtime/Engine/Classes/Animation/AnimInstance.h index 7581981d4e32..a005a9f2dff9 100644 --- a/Engine/Source/Runtime/Engine/Classes/Animation/AnimInstance.h +++ b/Engine/Source/Runtime/Engine/Classes/Animation/AnimInstance.h @@ -1311,6 +1311,9 @@ protected: } friend struct FAnimNode_SubInstance; + + /** Return whethere this AnimNotifyState should be triggered */ + virtual bool ShouldTriggerAnimNotifyState(const UAnimNotifyState* AnimNotifyState) const { return true; } protected: /** Proxy object, nothing should access this from an externally-callable API as it is used as a scratch area on worker threads */ diff --git a/Engine/Source/Runtime/Engine/Classes/Animation/PoseAsset.h b/Engine/Source/Runtime/Engine/Classes/Animation/PoseAsset.h index 2dd280963433..c1b740146001 100644 --- a/Engine/Source/Runtime/Engine/Classes/Animation/PoseAsset.h +++ b/Engine/Source/Runtime/Engine/Classes/Animation/PoseAsset.h @@ -16,6 +16,7 @@ class UAnimSequence; class USkeletalMeshComponent; +struct FLiveLinkCurveElement; /** * Pose data @@ -170,6 +171,10 @@ public: virtual bool HasRootMotion() const { return false; } virtual bool IsValidAdditive() const { return bAdditivePose; } + // this is utility function that just cares by names to be used by live link + // this isn't fast. Use it at your caution + ENGINE_API void GetAnimationCurveOnly(TArray& InCurveNames, TArray& InCurveValues, TArray& OutCurveNames, TArray& OutCurveValues) const; + //Begin UObject Interface virtual void PostLoad() override; virtual void Serialize(FArchive& Ar) override; diff --git a/Engine/Source/Runtime/Engine/Classes/Components/InstancedStaticMeshComponent.h b/Engine/Source/Runtime/Engine/Classes/Components/InstancedStaticMeshComponent.h index fa3ceb2cf348..6d06ba139456 100644 --- a/Engine/Source/Runtime/Engine/Classes/Components/InstancedStaticMeshComponent.h +++ b/Engine/Source/Runtime/Engine/Classes/Components/InstancedStaticMeshComponent.h @@ -300,6 +300,7 @@ public: virtual void PropagateLightingScenarioChange() override; + void GetInstancesMinMaxScale(FVector& MinScale, FVector& MaxScale) const; private: /** Sets up new instance data to sensible defaults, creates physics counterparts if possible. */ diff --git a/Engine/Source/Runtime/Engine/Classes/Components/SceneCaptureComponent.h b/Engine/Source/Runtime/Engine/Classes/Components/SceneCaptureComponent.h index babf88504686..f40847bb22cc 100644 --- a/Engine/Source/Runtime/Engine/Classes/Components/SceneCaptureComponent.h +++ b/Engine/Source/Runtime/Engine/Classes/Components/SceneCaptureComponent.h @@ -181,6 +181,9 @@ public: static void UpdateDeferredCaptures(FSceneInterface* Scene); + /** Respond to visibility changes by updating Proxy Mesh visibility to match if we are in the editor*/ + virtual void OnVisibilityChanged() override; + protected: /** Update the show flags from our show flags settings (ideally, you'd be able to set this more directly, but currently unable to make FEngineShowFlags a UStruct to use it as a UProperty...) */ void UpdateShowFlags(); diff --git a/Engine/Source/Runtime/Engine/Classes/Engine/BlueprintGeneratedClass.h b/Engine/Source/Runtime/Engine/Classes/Engine/BlueprintGeneratedClass.h index ba50f89aedec..1e018d97e892 100644 --- a/Engine/Source/Runtime/Engine/Classes/Engine/BlueprintGeneratedClass.h +++ b/Engine/Source/Runtime/Engine/Classes/Engine/BlueprintGeneratedClass.h @@ -77,18 +77,13 @@ public: } }; -////////////////////////////////////////////////////////////////////////// -// WARNING: Following struct layout definition repeated in ScriptCore.cpp as -// FPointerToUberGraphFrameCoreUObject to work around reflection generation issues: + USTRUCT() struct FPointerToUberGraphFrame { GENERATED_USTRUCT_BODY() public: - ////////////////////////////////////////////////////////////////////////// - // WARNING: This struct layout definition repeated in ScriptCore.cpp as - // FPointerToUberGraphFrameCoreUObject to work around reflection generation issues: uint8* RawPointer; #if VALIDATE_UBER_GRAPH_PERSISTENT_FRAME uint32 UberGraphFunctionKey; @@ -109,9 +104,7 @@ public: check(!RawPointer); } }; -// WARNING: Preceding struct layout definition repeated in ScriptCore.cpp as -// FPointerToUberGraphFrameCoreUObject to work around reflection generation issues! -////////////////////////////////////////////////////////////////////////// + template<> struct TStructOpsTypeTraits : public TStructOpsTypeTraitsBase2 @@ -641,6 +634,9 @@ public: UPROPERTY() class UInheritableComponentHandler* InheritableComponentHandler; + UPROPERTY() + UStructProperty* UberGraphFramePointerProperty; + UPROPERTY() UFunction* UberGraphFunction; @@ -709,6 +705,7 @@ public: virtual void SerializeDefaultObject(UObject* Object, FArchive& Ar) override; virtual void PostLoadDefaultObject(UObject* Object) override; virtual bool IsFunctionImplementedInBlueprint(FName InFunctionName) const override; + virtual uint8* GetPersistentUberGraphFrame(UObject* Obj, UFunction* FuncToCheck) const override; virtual void CreatePersistentUberGraphFrame(UObject* Obj, bool bCreateOnlyIfEmpty = false, bool bSkipSuperClass = false, UClass* OldClass = nullptr) const override; virtual void DestroyPersistentUberGraphFrame(UObject* Obj, bool bSkipSuperClass = false) const override; virtual void Link(FArchive& Ar, bool bRelinkExistingProperties) override; diff --git a/Engine/Source/Runtime/Engine/Classes/Engine/ContentEncryptionConfig.h b/Engine/Source/Runtime/Engine/Classes/Engine/ContentEncryptionConfig.h index 032ae2328e2a..7c44f758861c 100644 --- a/Engine/Source/Runtime/Engine/Classes/Engine/ContentEncryptionConfig.h +++ b/Engine/Source/Runtime/Engine/Classes/Engine/ContentEncryptionConfig.h @@ -40,6 +40,18 @@ public: return ReleasedKeys; } + void DissolveGroups(const TSet& InGroupsToDissolve) + { + for (FName GroupName : InGroupsToDissolve) + { + if (PackageGroups.Contains(GroupName)) + { + PackageGroups.FindOrAdd(NAME_None).PackageNames.Append(PackageGroups.Find(GroupName)->PackageNames); + PackageGroups.Remove(GroupName); + } + } + } + private: TGroupMap PackageGroups; diff --git a/Engine/Source/Runtime/Engine/Classes/Engine/GameViewportClient.h b/Engine/Source/Runtime/Engine/Classes/Engine/GameViewportClient.h index d49e65ef95ef..64e5fdcaaa05 100644 --- a/Engine/Source/Runtime/Engine/Classes/Engine/GameViewportClient.h +++ b/Engine/Source/Runtime/Engine/Classes/Engine/GameViewportClient.h @@ -491,7 +491,13 @@ public: { return ScreenshotCapturedDelegate; } - + + /** Accessor for delegate called when a viewport is rendered */ + static FOnViewportRendered& OnViewportRendered() + { + return ViewportRenderedDelegate; + } + /* Accessor for the delegate called when a viewport is asked to close. */ FOnCloseRequested& OnCloseRequested() { @@ -882,6 +888,9 @@ private: /** Delegate called at the end of the frame when a screenshot is captured */ static FOnScreenshotCaptured ScreenshotCapturedDelegate; + + /** Delegate called right after the viewport is rendered */ + static FOnViewportRendered ViewportRenderedDelegate; /** Delegate called when a request to close the viewport is received */ FOnCloseRequested CloseRequestedDelegate; diff --git a/Engine/Source/Runtime/Engine/Classes/Engine/GameViewportDelegates.h b/Engine/Source/Runtime/Engine/Classes/Engine/GameViewportDelegates.h index 4406daad36c0..3058947e9e5b 100644 --- a/Engine/Source/Runtime/Engine/Classes/Engine/GameViewportDelegates.h +++ b/Engine/Source/Runtime/Engine/Classes/Engine/GameViewportDelegates.h @@ -19,6 +19,14 @@ class FViewport; */ DECLARE_MULTICAST_DELEGATE_ThreeParams(FOnScreenshotCaptured, int32 /*Width*/, int32 /*Height*/, const TArray& /*Colors*/); +/** + * Delegate type used by UGameViewportClient when a viewport is rendered + * + * The first parameter is the viewport. + * @see UGameViewportClient + */ +DECLARE_MULTICAST_DELEGATE_OneParam(FOnViewportRendered, FViewport*); + /** * Delegate type used by UGameViewportClient when the top level window associated * with the viewport has been requested to close. diff --git a/Engine/Source/Runtime/Engine/Classes/Engine/SkeletalMesh.h b/Engine/Source/Runtime/Engine/Classes/Engine/SkeletalMesh.h index f22668ffb693..215b52a77ed1 100644 --- a/Engine/Source/Runtime/Engine/Classes/Engine/SkeletalMesh.h +++ b/Engine/Source/Runtime/Engine/Classes/Engine/SkeletalMesh.h @@ -565,6 +565,10 @@ public: UPROPERTY(EditAnywhere, Category = LODSettings, meta = (DisplayName = "Minimum LOD")) FPerPlatformInt MinLod; + /** when true all lods below minlod will still be cooked */ + UPROPERTY(EditAnywhere, Category = LODSettings) + FPerPlatformBool DisableBelowMinLodStripping; + #if WITH_EDITORONLY_DATA UPROPERTY(EditAnywhere, BlueprintReadWrite, AssetRegistrySearchable, BlueprintSetter = SetLODSettings, Category = LODSettings) USkeletalMeshLODSettings* LODSettings; diff --git a/Engine/Source/Runtime/Engine/Classes/Engine/SkeletalMeshLODSettings.h b/Engine/Source/Runtime/Engine/Classes/Engine/SkeletalMeshLODSettings.h index 365cda6938f4..7cf301836e59 100644 --- a/Engine/Source/Runtime/Engine/Classes/Engine/SkeletalMeshLODSettings.h +++ b/Engine/Source/Runtime/Engine/Classes/Engine/SkeletalMeshLODSettings.h @@ -119,6 +119,10 @@ protected: UPROPERTY(globalconfig, EditAnywhere, Category=LODGroups, meta = (DisplayName = "Minimum LOD")) FPerPlatformInt MinLod; + /** When true LODs below MinLod will not be stripped during cook. */ + UPROPERTY(globalconfig, EditAnywhere, Category = LODGroups) + FPerPlatformBool DisableBelowMinLodStripping; + UPROPERTY(globalconfig, EditAnywhere, Category=LODGroups) TArray LODGroups; diff --git a/Engine/Source/Runtime/Engine/Classes/Engine/UserInterfaceSettings.h b/Engine/Source/Runtime/Engine/Classes/Engine/UserInterfaceSettings.h index 27648823f829..7993750b8657 100644 --- a/Engine/Source/Runtime/Engine/Classes/Engine/UserInterfaceSettings.h +++ b/Engine/Source/Runtime/Engine/Classes/Engine/UserInterfaceSettings.h @@ -191,7 +191,8 @@ public: virtual void PostInitProperties() override; - void ForceLoadResources(); + /** Loads assets, if bForceLoadEverything is true it will load despite environment */ + void ForceLoadResources(bool bForceLoadEverything = false); /** Gets the current scale of the UI based on the size of a viewport */ float GetDPIScaleBasedOnSize(FIntPoint Size) const; diff --git a/Engine/Source/Runtime/Engine/Classes/Engine/World.h b/Engine/Source/Runtime/Engine/Classes/Engine/World.h index afaaf172d576..e4cccbd0632d 100644 --- a/Engine/Source/Runtime/Engine/Classes/Engine/World.h +++ b/Engine/Source/Runtime/Engine/Classes/Engine/World.h @@ -2475,6 +2475,8 @@ public: /** Should the FX system be created for this world. */ uint32 bCreateFXSystem:1; + TSubclassOf DefaultGameMode; + InitializationValues& InitializeScenes(const bool bInitialize) { bInitializeScenes = bInitialize; return *this; } InitializationValues& AllowAudioPlayback(const bool bAllow) { bAllowAudioPlayback = bAllow; return *this; } InitializationValues& RequiresHitProxies(const bool bRequires) { bRequiresHitProxies = bRequires; return *this; } @@ -2485,6 +2487,7 @@ public: InitializationValues& EnableTraceCollision(const bool bInEnableTraceCollision) { bEnableTraceCollision = bInEnableTraceCollision; return *this; } InitializationValues& SetTransactional(const bool bInTransactional) { bTransactional = bInTransactional; return *this; } InitializationValues& CreateFXSystem(const bool bCreate) { bCreateFXSystem = bCreate; return *this; } + InitializationValues& SetDefaultGameMode(TSubclassOf GameMode) { DefaultGameMode = GameMode; return *this; } }; /** diff --git a/Engine/Source/Runtime/Engine/Classes/Sound/SampleBuffer.h b/Engine/Source/Runtime/Engine/Classes/Sound/SampleBuffer.h index 74f588f3cbdd..24b35fa710b8 100644 --- a/Engine/Source/Runtime/Engine/Classes/Sound/SampleBuffer.h +++ b/Engine/Source/Runtime/Engine/Classes/Sound/SampleBuffer.h @@ -3,12 +3,15 @@ #pragma once #include "CoreMinimal.h" +#include "UObject/ObjectMacros.h" +#include "UObject/Object.h" #include "DSP/Dsp.h" #include "Misc/Paths.h" #include "Sound/SoundEffectBase.h" #include "Async/AsyncWork.h" #include "Templates/UnrealTypeTraits.h" #include "UObject/GCObject.h" +#include "Tickable.h" class USoundWave; class FAudioDevice; @@ -68,6 +71,17 @@ namespace Audio FMemory::Memcpy(RawPCMData.GetData(), Other.RawPCMData.GetData(), NumSamples * sizeof(SampleType)); } + FORCEINLINE TSampleBuffer(TSampleBuffer&& Other) + { + NumSamples = Other.NumSamples; + NumFrames = Other.NumFrames; + NumChannels = Other.NumChannels; + SampleRate = Other.SampleRate; + SampleDuration = Other.SampleDuration; + + RawPCMData = MoveTemp(Other.RawPCMData); + } + FORCEINLINE TSampleBuffer(AlignedFloatBuffer& InData, int32 InNumChannels, int32 InSampleRate) { *this = TSampleBuffer(InData.GetData(), InData.Num(), InNumChannels, InSampleRate); @@ -83,7 +97,7 @@ namespace Audio RawPCMData.Reset(NumSamples); RawPCMData.AddUninitialized(NumSamples); - + if (TIsSame::Value) { FMemory::Memcpy(RawPCMData.GetData(), InBufferPtr, NumSamples * sizeof(float)); @@ -156,6 +170,19 @@ namespace Audio return *this; } + // Move assignment operator: + TSampleBuffer& operator=(TSampleBuffer&& Other) + { + NumSamples = Other.NumSamples; + NumFrames = Other.NumFrames; + NumChannels = Other.NumChannels; + SampleRate = Other.SampleRate; + SampleDuration = Other.SampleDuration; + + RawPCMData = MoveTemp(Other.RawPCMData); + return *this; + } + //SampleType converting assignment operator: template TSampleBuffer& operator=(const TSampleBuffer& Other) @@ -202,6 +229,50 @@ namespace Audio return *this; } + // Append audio data to internal buffer of different sample type of this sample buffer + template + void Append(const OtherSampleType* InputBuffer, int32 InNumSamples) + { + int32 StartIndex = RawPCMData.AddUninitialized(InNumSamples); + + if (TIsSame::Value) + { + FMemory::Memcpy(&RawPCMData[StartIndex], InputBuffer, InNumSamples * sizeof(SampleType)); + } + else + { + if (TIsSame::Value && TIsSame::Value) + { + // Convert from float to int: + for (int32 SampleIndex = 0; SampleIndex < InNumSamples; SampleIndex++) + { + RawPCMData[StartIndex + SampleIndex] = (int16)(InputBuffer[SampleIndex] * 32767.0f); + } + } + else if (TIsSame::Value && TIsSame::Value) + { + // Convert from int to float: + for (int32 SampleIndex = 0; SampleIndex < InNumSamples; SampleIndex++) + { + RawPCMData[StartIndex + SampleIndex] = (float)InputBuffer[SampleIndex] / 32767.0f; + } + } + else + { + // for any other types, we don't know how to explicitly convert, so we fall back to casts: + for (int32 SampleIndex = 0; SampleIndex < InNumSamples; SampleIndex++) + { + RawPCMData[StartIndex + SampleIndex] = InputBuffer[SampleIndex]; + } + } + } + + // Update meta-data + NumSamples += InNumSamples; + NumFrames = NumSamples / NumChannels; + SampleDuration = (float)NumFrames / SampleRate; + } + ~TSampleBuffer() {}; // Gets the raw PCM data of the sound wave @@ -244,6 +315,7 @@ namespace Audio return SampleRate; } + // Gets the sample duration (in seconds) of the sound FORCEINLINE float GetSampleDuration() const { return SampleDuration; @@ -277,7 +349,7 @@ namespace Audio NumChannels = InNumChannels; NumSamples = NumFrames * NumChannels; - + // Resize our buffer and copy the result in: RawPCMData.Reset(NumSamples); RawPCMData.AddUninitialized(NumSamples); @@ -364,6 +436,7 @@ namespace Audio // Loads a USoundWave, call on game thread. void LoadSoundWave(USoundWave* InSoundWave, TFunction OnLoaded); + // Update the loading state. void Update(); @@ -381,6 +454,8 @@ namespace Audio // The lambda function to call when t he sound wave finishes loading TFunction OnLoaded; + + enum class LoadStatus : uint8 { // No request to load has been issued (default) @@ -404,6 +479,10 @@ namespace Audio // Reference to current loading sound wave TArray LoadingSoundWaves; + + // MERGE-REVIEW - should be in object or moved into loading info? + // Whether or not this object is tickable. I.e. a sound wave has been asked to load. + bool bCanBeTicked; }; // Enum used to express the current state of a FSoundWavePCMWriter's current operation. diff --git a/Engine/Source/Runtime/Engine/Classes/Sound/SoundWaveProcedural.h b/Engine/Source/Runtime/Engine/Classes/Sound/SoundWaveProcedural.h index 49a6c0160803..f3afa35f39bb 100644 --- a/Engine/Source/Runtime/Engine/Classes/Sound/SoundWaveProcedural.h +++ b/Engine/Source/Runtime/Engine/Classes/Sound/SoundWaveProcedural.h @@ -15,7 +15,11 @@ #include "Sound/SoundWave.h" #include "SoundWaveProcedural.generated.h" +#if PLATFORM_IOS +#define DEFAULT_PROCEDURAL_SOUNDWAVE_BUFFER_SIZE (8 * 1024) +#else #define DEFAULT_PROCEDURAL_SOUNDWAVE_BUFFER_SIZE 1024 +#endif DECLARE_DELEGATE_TwoParams( FOnSoundWaveProceduralUnderflow, class USoundWaveProcedural*, int32 ); diff --git a/Engine/Source/Runtime/Engine/Engine.Build.cs b/Engine/Source/Runtime/Engine/Engine.Build.cs index 6d73c053375a..6b1cef8f9b11 100644 --- a/Engine/Source/Runtime/Engine/Engine.Build.cs +++ b/Engine/Source/Runtime/Engine/Engine.Build.cs @@ -102,16 +102,16 @@ public class Engine : ModuleRules ); if((Target.Platform != UnrealTargetPlatform.TVOS && Target.Platform != UnrealTargetPlatform.HTML5)) - { - // Cross platform Audio Codecs: - AddEngineThirdPartyPrivateStaticDependencies(Target, + { + // Cross platform Audio Codecs: + AddEngineThirdPartyPrivateStaticDependencies(Target, "UEOgg", "Vorbis", "VorbisFile", "libOpus" ); } - + DynamicallyLoadedModuleNames.Add("EyeTracker"); @@ -189,7 +189,7 @@ public class Engine : ModuleRules // The AnimGraphRuntime module is not needed by Engine proper, but it is loaded in LaunchEngineLoop.cpp, // and needs to be listed in an always-included module in order to be compiled into standalone games DynamicallyLoadedModuleNames.Add("AnimGraphRuntime"); - + DynamicallyLoadedModuleNames.AddRange( new string[] { diff --git a/Engine/Source/Runtime/Engine/Private/Animation/AnimBlueprintGeneratedClass.cpp b/Engine/Source/Runtime/Engine/Private/Animation/AnimBlueprintGeneratedClass.cpp index 04cdbb906acc..a11a7443a362 100644 --- a/Engine/Source/Runtime/Engine/Private/Animation/AnimBlueprintGeneratedClass.cpp +++ b/Engine/Source/Runtime/Engine/Private/Animation/AnimBlueprintGeneratedClass.cpp @@ -334,6 +334,17 @@ void UAnimBlueprintGeneratedClass::PurgeClass(bool bRecompilingOnLoad) BakedStateMachines.Empty(); } +uint8* UAnimBlueprintGeneratedClass::GetPersistentUberGraphFrame(UObject* Obj, UFunction* FuncToCheck) const +{ + if(!IsInGameThread()) + { + // we cant use the persistent frame if we are executing in parallel (as we could potentially thunk to BP) + return nullptr; + } + + return Super::GetPersistentUberGraphFrame(Obj, FuncToCheck); +} + void UAnimBlueprintGeneratedClass::PostLoadDefaultObject(UObject* Object) { Super::PostLoadDefaultObject(Object); diff --git a/Engine/Source/Runtime/Engine/Private/Animation/AnimInstance.cpp b/Engine/Source/Runtime/Engine/Private/Animation/AnimInstance.cpp index 1fdabd91252a..3df170811a89 100644 --- a/Engine/Source/Runtime/Engine/Private/Animation/AnimInstance.cpp +++ b/Engine/Source/Runtime/Engine/Private/Animation/AnimInstance.cpp @@ -247,7 +247,10 @@ void UAnimInstance::UninitializeAnimation() for(int32 Index=0; IndexNotifyEnd(SkelMeshComp, Cast(AnimNotifyEvent.NotifyStateClass->GetOuter())); + if (ShouldTriggerAnimNotifyState(AnimNotifyEvent.NotifyStateClass)) + { + AnimNotifyEvent.NotifyStateClass->NotifyEnd(SkelMeshComp, Cast(AnimNotifyEvent.NotifyStateClass->GetOuter())); + } } } @@ -1270,13 +1273,19 @@ void UAnimInstance::TriggerAnimNotifies(float DeltaSeconds) // Send end notification to AnimNotifyState not active anymore. for(const FAnimNotifyEvent& AnimNotifyEvent : ActiveAnimNotifyState) { - AnimNotifyEvent.NotifyStateClass->NotifyEnd(SkelMeshComp, Cast(AnimNotifyEvent.NotifyStateClass->GetOuter())); + if (ShouldTriggerAnimNotifyState(AnimNotifyEvent.NotifyStateClass)) + { + AnimNotifyEvent.NotifyStateClass->NotifyEnd(SkelMeshComp, Cast(AnimNotifyEvent.NotifyStateClass->GetOuter())); + } } // Call 'NotifyBegin' event on freshly added AnimNotifyState. for (const FAnimNotifyEvent* AnimNotifyEvent : NotifyStateBeginEvent) { - AnimNotifyEvent->NotifyStateClass->NotifyBegin(SkelMeshComp, Cast(AnimNotifyEvent->NotifyStateClass->GetOuter()), AnimNotifyEvent->GetDuration()); + if (ShouldTriggerAnimNotifyState(AnimNotifyEvent->NotifyStateClass)) + { + AnimNotifyEvent->NotifyStateClass->NotifyBegin(SkelMeshComp, Cast(AnimNotifyEvent->NotifyStateClass->GetOuter()), AnimNotifyEvent->GetDuration()); + } } // Switch our arrays. @@ -1285,7 +1294,10 @@ void UAnimInstance::TriggerAnimNotifies(float DeltaSeconds) // Tick currently active AnimNotifyState for(const FAnimNotifyEvent& AnimNotifyEvent : ActiveAnimNotifyState) { - AnimNotifyEvent.NotifyStateClass->NotifyTick(SkelMeshComp, Cast(AnimNotifyEvent.NotifyStateClass->GetOuter()), DeltaSeconds); + if (ShouldTriggerAnimNotifyState(AnimNotifyEvent.NotifyStateClass)) + { + AnimNotifyEvent.NotifyStateClass->NotifyTick(SkelMeshComp, Cast(AnimNotifyEvent.NotifyStateClass->GetOuter()), DeltaSeconds); + } } } @@ -1553,7 +1565,10 @@ void UAnimInstance::TriggerMontageEndedEvent(const FQueuedMontageEndedEvent& Mon if (NotifyMontage && (NotifyMontage == MontageEndedEvent.Montage)) { - AnimNotifyEvent.NotifyStateClass->NotifyEnd(SkelMeshComp, NotifyMontage); + if (ShouldTriggerAnimNotifyState(AnimNotifyEvent.NotifyStateClass)) + { + AnimNotifyEvent.NotifyStateClass->NotifyEnd(SkelMeshComp, NotifyMontage); + } ActiveAnimNotifyState.RemoveAtSwap(Index); } } diff --git a/Engine/Source/Runtime/Engine/Private/Animation/PoseAsset.cpp b/Engine/Source/Runtime/Engine/Private/Animation/PoseAsset.cpp index 46103f61ba19..a4f6836e0089 100644 --- a/Engine/Source/Runtime/Engine/Private/Animation/PoseAsset.cpp +++ b/Engine/Source/Runtime/Engine/Private/Animation/PoseAsset.cpp @@ -404,7 +404,7 @@ void UPoseAsset::GetBaseAnimationPose(struct FCompactPose& OutPose, FBlendedCurv /* * The difference between BlendFromIdentityAndAccumulcate is scale - * This ADDS scales to the FinalAtom. We use additive identity as final atom, so can't use + * This ADDS scales to the FinalAtom. We use additive identity as final atom, so can't use */ FORCEINLINE void BlendFromIdentityAndAccumulateAdditively(FTransform& FinalAtom, FTransform& SourceAtom, float BlendWeight) { @@ -426,6 +426,102 @@ FORCEINLINE void BlendFromIdentityAndAccumulateAdditively(FTransform& FinalAtom, FinalAtom.NormalizeRotation(); } +void UPoseAsset::GetAnimationCurveOnly(TArray& InCurveNames, TArray& InCurveValues, TArray& OutCurveNames, TArray& OutCurveValues) const +{ + // if we have any pose curve + if (ensure(InCurveNames.Num() == InCurveValues.Num()) && InCurveNames.Num() > 0) + { + USkeleton* MySkeleton = GetSkeleton(); + check(MySkeleton); + + bool bNormalizeWeight = bAdditivePose == false; + TMap IndexToWeightMap; + float TotalWeight = 0.f; + // we iterate through to see if we have that corresponding pose + for (int32 CurveIndex = 0; CurveIndex < InCurveNames.Num(); ++CurveIndex) + { + FSmartName PoseSmartName; + if (MySkeleton->GetSmartNameByName(USkeleton::AnimCurveMappingName, InCurveNames[CurveIndex], PoseSmartName)) + { + int32 PoseIndex = PoseContainer.PoseNames.Find(PoseSmartName); + if (ensure(PoseIndex != INDEX_NONE)) + { + const FPoseData& PoseData = PoseContainer.Poses[PoseIndex]; + const float Value = InCurveValues[CurveIndex]; + + // we only add to the list if it's not additive Or if it's additive, we don't want to add base pose index + // and has weight + if ((!bAdditivePose || PoseIndex != BasePoseIndex) && FAnimationRuntime::HasWeight(Value)) + { + IndexToWeightMap.Add(&PoseData, Value); + TotalWeight += Value; + } + } + } + } + + const int32 TotalNumberOfValidPoses = IndexToWeightMap.Num(); + if (TotalNumberOfValidPoses > 0) + { + TArray PoseCurves; + TArray CurveWeights; + + //if full pose, we'll have to normalize by weight + if (bNormalizeWeight && TotalWeight > 1.f) + { + for (TPair& WeightPair : IndexToWeightMap) + { + WeightPair.Value /= TotalWeight; + } + } + + // collect curves + PoseCurves.AddDefaulted(TotalNumberOfValidPoses); + CurveWeights.AddUninitialized(TotalNumberOfValidPoses); + int32 PoseIndex = 0; + + TArray CurveUIDList; + CurveUIDList.AddUninitialized(PoseContainer.Curves.Num()); + for (int32 CurveIndex = 0; CurveIndex < PoseContainer.Curves.Num(); ++CurveIndex) + { + CurveUIDList[CurveIndex] = PoseContainer.Curves[CurveIndex].Name.UID; + } + + for (const TPair& ActivePosePair : IndexToWeightMap) + { + const FPoseData* Pose = ActivePosePair.Key; + const float Weight = ActivePosePair.Value; + + CurveWeights[PoseIndex] = Weight; + PoseCurves[PoseIndex].InitFrom(&CurveUIDList); + PoseContainer.GetPoseCurve(Pose, PoseCurves[PoseIndex]); + + ++PoseIndex; + } + + // blend curves + FBlendedCurve BlendedCurve; + BlendCurves(PoseCurves, CurveWeights, BlendedCurve); + + OutCurveNames.Reset(); + OutCurveValues.Reset(); + for (int32 Idx = 0; Idx < CurveUIDList.Num(); ++Idx) + { + USkeleton::AnimCurveUID UID = Idx; + if (BlendedCurve.IsEnabled(UID)) + { + FSmartName CurveName; + if (MySkeleton->GetSmartNameByUID(USkeleton::AnimCurveMappingName, UID, CurveName)) + { + OutCurveNames.Add(CurveName.DisplayName); + OutCurveValues.Add(BlendedCurve.Get(UID)); + } + } + } + } + } +} + bool UPoseAsset::GetAnimationPose(struct FCompactPose& OutPose, FBlendedCurve& OutCurve, const FAnimExtractContext& ExtractionContext) const { ANIM_MT_SCOPE_CYCLE_COUNTER(PoseAssetGetAnimationPose, !IsInGameThread()); diff --git a/Engine/Source/Runtime/Engine/Private/AssetManager.cpp b/Engine/Source/Runtime/Engine/Private/AssetManager.cpp index 8c238d5dfa01..4395da04f5d8 100644 --- a/Engine/Source/Runtime/Engine/Private/AssetManager.cpp +++ b/Engine/Source/Runtime/Engine/Private/AssetManager.cpp @@ -2499,6 +2499,7 @@ bool UAssetManager::ShouldScanPrimaryAssetType(FPrimaryAssetTypeInfo& TypeInfo) void UAssetManager::ScanPrimaryAssetTypesFromConfig() { + SCOPED_BOOT_TIMING("UAssetManager::ScanPrimaryAssetTypesFromConfig"); IAssetRegistry& AssetRegistry = GetAssetRegistry(); const UAssetManagerSettings& Settings = GetSettings(); diff --git a/Engine/Source/Runtime/Engine/Private/AudioDecompress.cpp b/Engine/Source/Runtime/Engine/Private/AudioDecompress.cpp index df6d4bda446f..a264a8055121 100644 --- a/Engine/Source/Runtime/Engine/Private/AudioDecompress.cpp +++ b/Engine/Source/Runtime/Engine/Private/AudioDecompress.cpp @@ -702,7 +702,7 @@ void FAsyncAudioDecompressWorker::DoWork() static TAutoConsoleVariable CVarShouldUseBackgroundPoolFor_FAsyncRealtimeAudioTask( TEXT("AudioThread.UseBackgroundThreadPool"), - 1, + 0, TEXT("If true, use the background thread pool for realtime audio decompression.")); bool ShouldUseBackgroundPoolFor_FAsyncRealtimeAudioTask() diff --git a/Engine/Source/Runtime/Engine/Private/AudioDevice.cpp b/Engine/Source/Runtime/Engine/Private/AudioDevice.cpp index 48ebda778f9b..a42c44a313e0 100644 --- a/Engine/Source/Runtime/Engine/Private/AudioDevice.cpp +++ b/Engine/Source/Runtime/Engine/Private/AudioDevice.cpp @@ -72,6 +72,14 @@ FAutoConsoleVariableRef CVarForceRealtimeDecompression( TEXT("0: Allow full decompression on load, 1: force realtime decompression."), ECVF_Default); +static int32 DisableAutomaticPrecacheCvar = 0; +FAutoConsoleVariableRef CVarDisableAutomaticPrecache( + TEXT("au.DisableAutomaticPrecache"), + DisableAutomaticPrecacheCvar, + TEXT("When set to 1, this disables precaching on load or startup, it will only precache synchronously when playing.\n") + TEXT("0: Use normal precaching logic, 1: disables all precaching except for synchronous calls."), + ECVF_Default); + static float DecompressionThresholdCvar = 0.0f; FAutoConsoleVariableRef CVarDecompressionThreshold( TEXT("au.DecompressionThreshold"), @@ -267,6 +275,8 @@ FAudioQualitySettings FAudioDevice::GetQualityLevelSettings() bool FAudioDevice::Init(int32 InMaxChannels) { + SCOPED_BOOT_TIMING("FAudioDevice::Init"); + LLM_SCOPE(ELLMTag::AudioMisc); if (bIsInitialized) @@ -296,11 +306,6 @@ bool FAudioDevice::Init(int32 InMaxChannels) // If this is true, skip the initial startup precache so we can do it later in the flow GConfig->GetBool(TEXT("Audio"), TEXT("DeferStartupPrecache"), bDeferStartupPrecache, GEngineIni); - // Hack: Make sure that Android defers startup sounds. -#if PLATFORM_ANDROID - bDeferStartupPrecache = true; -#endif - // Get an optional engine ini setting for platform headroom. float Headroom = 0.0f; // in dB if (GConfig->GetFloat(TEXT("Audio"), TEXT("PlatformHeadroomDB"), Headroom, GEngineIni)) @@ -457,7 +462,7 @@ float FAudioDevice::GetLowPassFilterResonance() const void FAudioDevice::PrecacheStartupSounds() { // Iterate over all already loaded sounds and precache them. This relies on Super::Init in derived classes to be called last. - if (!GIsEditor && GEngine && GEngine->UseSound() ) + if (!GIsEditor && GEngine && GEngine->UseSound() && DisableAutomaticPrecacheCvar == 0) { for (TObjectIterator It; It; ++It) { @@ -5114,6 +5119,12 @@ void FAudioDevice::Precache(USoundWave* SoundWave, bool bSynchronous, bool bTrac if (!bSynchronous && SoundWave->GetPrecacheState() == ESoundWavePrecacheState::NotStarted) { + if (!bForceFullDecompression && DisableAutomaticPrecacheCvar == 1) + { + // Don't schedule a precache for a normal async request because it is currently disabled + return; + } + if (IsInGameThread()) { // On the game thread, add this sound wave to the referenced sound wave nodes so that it doesn't get GC'd diff --git a/Engine/Source/Runtime/Engine/Private/BlueprintGeneratedClass.cpp b/Engine/Source/Runtime/Engine/Private/BlueprintGeneratedClass.cpp index 4f7716454f8f..e4dc8e90f2f3 100644 --- a/Engine/Source/Runtime/Engine/Private/BlueprintGeneratedClass.cpp +++ b/Engine/Source/Runtime/Engine/Private/BlueprintGeneratedClass.cpp @@ -1220,6 +1220,23 @@ void UBlueprintGeneratedClass::CheckAndApplyComponentTemplateOverrides(UObject* } } +uint8* UBlueprintGeneratedClass::GetPersistentUberGraphFrame(UObject* Obj, UFunction* FuncToCheck) const +{ + if (Obj && UsePersistentUberGraphFrame() && UberGraphFramePointerProperty && UberGraphFunction) + { + if (UberGraphFunction == FuncToCheck) + { + FPointerToUberGraphFrame* PointerToUberGraphFrame = UberGraphFramePointerProperty->ContainerPtrToValuePtr(Obj); + checkSlow(PointerToUberGraphFrame); + ensure(PointerToUberGraphFrame->RawPointer); + return PointerToUberGraphFrame->RawPointer; + } + } + UClass* ParentClass = GetSuperClass(); + checkSlow(ParentClass); + return ParentClass->GetPersistentUberGraphFrame(Obj, FuncToCheck); +} + void UBlueprintGeneratedClass::CreatePersistentUberGraphFrame(UObject* Obj, bool bCreateOnlyIfEmpty, bool bSkipSuperClass, UClass* OldClass) const { #if USE_UBER_GRAPH_PERSISTENT_FRAME @@ -1481,6 +1498,7 @@ void UBlueprintGeneratedClass::PurgeClass(bool bRecompilingOnLoad) { Super::PurgeClass(bRecompilingOnLoad); + UberGraphFramePointerProperty = NULL; UberGraphFunction = NULL; #if VALIDATE_UBER_GRAPH_PERSISTENT_FRAME UberGraphFunctionKey = 0; diff --git a/Engine/Source/Runtime/Engine/Private/Components/SceneCaptureComponent.cpp b/Engine/Source/Runtime/Engine/Private/Components/SceneCaptureComponent.cpp index 3882ab54c443..2b74b282a648 100644 --- a/Engine/Source/Runtime/Engine/Private/Components/SceneCaptureComponent.cpp +++ b/Engine/Source/Runtime/Engine/Private/Components/SceneCaptureComponent.cpp @@ -141,7 +141,8 @@ void USceneCaptureComponent::OnRegister() ProxyMeshComponent->SetIsVisualizationComponent(true); ProxyMeshComponent->SetStaticMesh(CaptureMesh); ProxyMeshComponent->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName); - ProxyMeshComponent->bHiddenInGame = true; + ProxyMeshComponent->bVisible = bVisible; // Match the visibility of the component + ProxyMeshComponent->bHiddenInGame = true; // Hidden in game should always be true as this is a visualization component ProxyMeshComponent->CastShadow = false; ProxyMeshComponent->CreationMethod = CreationMethod; ProxyMeshComponent->RegisterComponentWithWorld(GetWorld()); @@ -411,6 +412,18 @@ void USceneCaptureComponent::OnUnregister() Super::OnUnregister(); } +void USceneCaptureComponent::OnVisibilityChanged() +{ + // ProxyMeshComponent only exists in Editor +#if WITH_EDITORONLY_DATA + if (ProxyMeshComponent != nullptr) + { + ProxyMeshComponent->SetVisibility(bVisible); + } +#endif + Super::OnVisibilityChanged(); +} + // ----------------------------------------------- diff --git a/Engine/Source/Runtime/Engine/Private/Components/SkinnedMeshComponent.cpp b/Engine/Source/Runtime/Engine/Private/Components/SkinnedMeshComponent.cpp index 9f9fe3d8a690..1d6ce6cdafc3 100644 --- a/Engine/Source/Runtime/Engine/Private/Components/SkinnedMeshComponent.cpp +++ b/Engine/Source/Runtime/Engine/Private/Components/SkinnedMeshComponent.cpp @@ -2701,8 +2701,7 @@ bool USkinnedMeshComponent::UpdateLODStatus_Internal(int32 InMasterPoseComponent const int32 LODBias = GSkeletalMeshLODBias; #endif - int32 MinLodIndex = bOverrideMinLod ? MinLodModel : 0; - MinLodIndex = FMath::Max(MinLodIndex, SkeletalMesh->MinLod.GetValueForFeatureLevel(CachedSceneFeatureLevel)); + int32 MinLodIndex = bOverrideMinLod ? MinLodModel : SkeletalMesh->MinLod.GetValueForFeatureLevel(CachedSceneFeatureLevel); int32 MaxLODIndex = 0; if (MeshObject) diff --git a/Engine/Source/Runtime/Engine/Private/GameEngine.cpp b/Engine/Source/Runtime/Engine/Private/GameEngine.cpp index 921df8f0e9dd..cf1cc078ba8a 100644 --- a/Engine/Source/Runtime/Engine/Private/GameEngine.cpp +++ b/Engine/Source/Runtime/Engine/Private/GameEngine.cpp @@ -48,6 +48,7 @@ #include "Components/ReflectionCaptureComponent.h" #include "GameFramework/GameUserSettings.h" #include "GameDelegates.h" +#include "Misc/EmbeddedCommunication.h" #include "Engine/CoreSettings.h" #include "EngineAnalytics.h" #include "Engine/DemoNetDriver.h" @@ -738,9 +739,234 @@ UEngine::UEngine(const FObjectInitializer& ObjectInitializer) DefaultTimecodeFrameRate = FFrameRate(30, 1); } + + +//@todo kairos: Move this and maybe the above engine handling code to somewhere else. I can't put this into Core +// with Embedded because of the Json dependency that I don't want/can't? add to Core. Maybe ApplicationCore? + +#include "Misc/CoreMisc.h" +#include "Misc/ConfigCacheIni.h" +#include "Misc/Parse.h" +#include "Serialization/JsonReader.h" + + +class FEmbeddedCommunicationExec : public FSelfRegisteringExec +{ +public: + FEmbeddedCommunicationExec() + : FSelfRegisteringExec() + { + + FEmbeddedDelegates::GetNativeToEmbeddedParamsDelegateForSubsystem(TEXT("engine")).AddLambda([](const FEmbeddedCallParamsHelper& Message) + { + // execute any console commands + if (Message.Command == TEXT("console")) + { + // gather all of the output + FStringOutputDevice Output; + ULocalPlayer* LocalPlayer = GEngine->GetDebugLocalPlayer(); + + for (auto Pair : Message.Parameters) + { + if( LocalPlayer ) + { + LocalPlayer->Exec( LocalPlayer->GetWorld(), *Pair.Key, Output ); + } + // and fall back to UEngine otherwise. + else + { + GEngine->Exec( GWorld, *Pair.Key, Output ); + } + } + + // call the completion delegate with all text output + Message.OnCompleteDelegate({ { TEXT("output"), Output } }, TEXT("")); + } + else if (Message.Command == TEXT("getconfig")) + { + FString File = Message.Parameters.FindRef(TEXT("file")); + FString Section = Message.Parameters.FindRef(TEXT("section")); + FString Key = Message.Parameters.FindRef(TEXT("key")); + + FString ConfigFile = GetConfigFromName(File); + + FString Value; + if (GConfig->GetString(*Section, *Key, Value, ConfigFile)) + { + // send back the value + Message.OnCompleteDelegate({ {TEXT("value"), Value} }, TEXT("")); + } + else + { + Message.OnCompleteDelegate({ }, FString::Printf(TEXT("Config key [%s] : %s in %s was not found"), *Section, *Key, *File)); + } + } + else if (Message.Command == TEXT("setconfig")) + { + FString File = Message.Parameters.FindRef(TEXT("file")); + FString Section = Message.Parameters.FindRef(TEXT("section")); + FString Key = Message.Parameters.FindRef(TEXT("key")); + FString Value = Message.Parameters.FindRef(TEXT("value")); + bool bSkipSave = Message.Parameters.FindRef(TEXT("skipsave")) == TEXT("true"); + + FString& ConfigFile = GetConfigFromName(File); + + GConfig->SetString(*Section, *Key, *Value, ConfigFile); + if (!bSkipSave) + { + GConfig->Flush(false, ConfigFile); + } + + // send back empty reply, nothing to report + Message.OnCompleteDelegate({ }, TEXT("")); + } + else if (Message.Command == TEXT("cvar")) + { + FString Name = Message.Parameters.FindRef(TEXT("name")); + IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(*Name); + if (CVar) + { + // send back the value + Message.OnCompleteDelegate({ {TEXT("value"), CVar->GetString()} }, TEXT("")); + } + else + { + Message.OnCompleteDelegate({ }, FString::Printf(TEXT("CVar %s not found"), *Name)); + } + } + else if (Message.Command == TEXT("StartUE4Live")) + { + FName Requester = *Message.Parameters.FindRef(TEXT("requester")); + bool bTickOnly = Message.Parameters.FindRef(TEXT("tickonly")) == TEXT("true"); + + FEmbeddedCommunication::KeepAwake(Requester, !bTickOnly); + Message.OnCompleteDelegate({}, TEXT("")); + } + else if (Message.Command == TEXT("StopUE4Live")) + { + FName Requester = *Message.Parameters.FindRef(TEXT("requester")); + + FEmbeddedCommunication::AllowSleep(Requester); + Message.OnCompleteDelegate({}, TEXT("")); + } + else + { + Message.OnCompleteDelegate({}, TEXT("Unknown command")); + } + }); +// #endif + + } + + static FString& GetConfigFromName(const FString& Name) + { + if (Name == TEXT("Game")) + { + return GGameIni; + } + else if (Name == TEXT("Input")) + { + return GInputIni; + } + else if (Name == TEXT("GameUserSettings")) + { + return GGameUserSettingsIni; + } + else if (Name == TEXT("Scalability")) + { + return GScalabilityIni; + } + else if (Name == TEXT("Hardware")) + { + return GHardwareIni; + } + return GEngineIni; + } + + virtual bool Exec(UWorld* Inworld, const TCHAR* Cmd, FOutputDevice& Ar) override + { + if (FParse::Command(&Cmd, TEXT("exitembedded"))) + { + FEmbeddedCallParamsHelper Helper; + Helper.Command = TEXT("exitembedded"); + if (FEmbeddedDelegates::GetEmbeddedToNativeParamsDelegateForSubsystem(TEXT("native")).IsBound()) + { + FEmbeddedDelegates::GetEmbeddedToNativeParamsDelegateForSubsystem(TEXT("native")).Broadcast(Helper); + } + return true; + } + else if (FParse::Command(&Cmd, TEXT("DumpEmbedded"))) + { + UE_LOG(LogEngine, Display, TEXT("Embedded state: %s"), *FEmbeddedCommunication::GetDebugInfo()); + return true; + } + else if (FParse::Command(&Cmd, TEXT("webcall"))) + { + int CommandIndex = FCString::Atoi(Cmd); + FString Key = FString::Printf(TEXT("Calls[%d]"), CommandIndex); + FString Command; + if (GConfig->GetString(TEXT("WebCalls"), *Key, Command, GEngineIni)) + { + const TSharedRef< TJsonReader<> >& Reader = TJsonReaderFactory<>::Create(Command.Replace(TEXT("'"), TEXT("\""))); + TSharedPtr CommandObject; + if (FJsonSerializer::Deserialize(Reader, CommandObject)) + { + FEmbeddedCallParamsHelper Helper; + FString SubsystemString; + CommandObject->TryGetStringField(TEXT("Subsystem"), SubsystemString); + CommandObject->TryGetStringField(TEXT("Command"), Helper.Command); + + const TSharedPtr* Args = nullptr; + if (CommandObject->TryGetObjectField(TEXT("Args"), Args)) + { + for (auto It : (*Args)->Values) + { + FString ValueString; + if (!It.Value->TryGetString(ValueString)) + { + // if casual string conversion failed, then encode it as a json string + const TArray< TSharedPtr >* ValueArray = nullptr; + if (It.Value->TryGetArray(ValueArray)) + { + TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&ValueString); + FJsonSerializer::Serialize(*ValueArray, Writer); + } + else + { + const TSharedPtr* ValueObject = nullptr; + if (It.Value->TryGetObject(ValueObject)) + { + TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&ValueString); + FJsonSerializer::Serialize(ValueObject->ToSharedRef(), Writer); + } + } + } + + // now put whatever string we made into the map + Helper.Parameters.Add(It.Key, ValueString); + } + } + + Helper.OnCompleteDelegate = [](const FEmbeddedCommunicationMap& InReturnValues, FString InError) {}; + FName Subsystem(*SubsystemString); + if (FEmbeddedDelegates::GetNativeToEmbeddedParamsDelegateForSubsystem(Subsystem).IsBound()) + { + FEmbeddedDelegates::GetNativeToEmbeddedParamsDelegateForSubsystem(Subsystem).Broadcast(Helper); + } + } + } + return true; + } + return false; + } + +} GEmbeddedCommunicationExec; + + void UGameEngine::Init(IEngineLoop* InEngineLoop) { DECLARE_SCOPE_CYCLE_COUNTER(TEXT("UGameEngine Init"), STAT_GameEngineStartup, STATGROUP_LoadTime); + // Call base. UEngine::Init(InEngineLoop); @@ -1475,7 +1701,7 @@ void UGameEngine::Tick( float DeltaSeconds, bool bIdleMode ) } } - if (!bIdleMode && !IsRunningDedicatedServer() && !IsRunningCommandlet()) + if (!bIdleMode && !IsRunningDedicatedServer() && !IsRunningCommandlet() && FEmbeddedCommunication::IsAwakeForRendering()) { // Render everything. RedrawViewports(); diff --git a/Engine/Source/Runtime/Engine/Private/GameViewportClient.cpp b/Engine/Source/Runtime/Engine/Private/GameViewportClient.cpp index 451625550b09..3b710c4a49a5 100644 --- a/Engine/Source/Runtime/Engine/Private/GameViewportClient.cpp +++ b/Engine/Source/Runtime/Engine/Private/GameViewportClient.cpp @@ -72,6 +72,9 @@ bool GForceFullscreen = false; /** Delegate called at the end of the frame when a screenshot is captured */ FOnScreenshotCaptured UGameViewportClient::ScreenshotCapturedDelegate; +/** Delegate called right after the viewport is rendered */ +FOnViewportRendered UGameViewportClient::ViewportRenderedDelegate; + /** Delegate called when the game viewport is created. */ FSimpleMulticastDelegate UGameViewportClient::CreatedDelegate; diff --git a/Engine/Source/Runtime/Engine/Private/HierarchicalInstancedStaticMesh.cpp b/Engine/Source/Runtime/Engine/Private/HierarchicalInstancedStaticMesh.cpp index 4edc36c1e3ef..1817e2a5b0af 100644 --- a/Engine/Source/Runtime/Engine/Private/HierarchicalInstancedStaticMesh.cpp +++ b/Engine/Source/Runtime/Engine/Private/HierarchicalInstancedStaticMesh.cpp @@ -1135,7 +1135,7 @@ static FORCEINLINE_DEBUGGABLE bool CullNode(const FFoliageCullInstanceParams& Pa return false; } -inline void CalcLOD(int32& InOutMinLOD, int32& InOutMaxLOD, const FVector& BoundMin, const FVector& BoundMax, const FVector& ViewOriginInLocalZero, const FVector& ViewOriginInLocalOne, const float (&LODPlanesMin)[MAX_STATIC_MESH_LODS], const float (&LODPlanesMax)[MAX_STATIC_MESH_LODS], float LODDistanceScaleFactor) +inline void CalcLOD(int32& InOutMinLOD, int32& InOutMaxLOD, const FVector& BoundMin, const FVector& BoundMax, const FVector& ViewOriginInLocalZero, const FVector& ViewOriginInLocalOne, const float (&LODPlanesMin)[MAX_STATIC_MESH_LODS], const float (&LODPlanesMax)[MAX_STATIC_MESH_LODS]) { if (InOutMinLOD != InOutMaxLOD) { @@ -1146,11 +1146,11 @@ inline void CalcLOD(int32& InOutMinLOD, int32& InOutMaxLOD, const FVector& Bound const float NearDot = FMath::Min(DistCenterZero, DistCenterOne) - HalfWidth; const float FarDot = FMath::Max(DistCenterZero, DistCenterOne) + HalfWidth; - while (InOutMaxLOD > InOutMinLOD && NearDot > LODPlanesMax[InOutMinLOD] * LODDistanceScaleFactor) + while (InOutMaxLOD > InOutMinLOD && NearDot > LODPlanesMax[InOutMinLOD]) { InOutMinLOD++; } - while (InOutMaxLOD > InOutMinLOD && FarDot < LODPlanesMin[InOutMaxLOD - 1] * LODDistanceScaleFactor) + while (InOutMaxLOD > InOutMinLOD && FarDot < LODPlanesMin[InOutMaxLOD - 1]) { InOutMaxLOD--; } @@ -1183,14 +1183,9 @@ void FHierarchicalStaticMeshSceneProxy::Traverse(const FFoliageCullInstanceParam } } - float DistanceScale = 1.0f; - if (MinLOD != MaxLOD) { - FVector ScaleAverage = Node.MinInstanceScale + ((Node.MaxInstanceScale - Node.MinInstanceScale) / 2.0f); - //DistanceScale = FMath::Max(FMath::Max3(ScaleAverage.X, ScaleAverage.Y, ScaleAverage.Z), 0.001f); - - CalcLOD(MinLOD, MaxLOD, Node.BoundMin, Node.BoundMax, Params.ViewOriginInLocalZero, Params.ViewOriginInLocalOne, Params.LODPlanesMin, Params.LODPlanesMax, DistanceScale); + CalcLOD(MinLOD, MaxLOD, Node.BoundMin, Node.BoundMax, Params.ViewOriginInLocalZero, Params.ViewOriginInLocalOne, Params.LODPlanesMin, Params.LODPlanesMax); if (MinLOD >= Params.LODs) { @@ -1211,7 +1206,7 @@ void FHierarchicalStaticMeshSceneProxy::Traverse(const FFoliageCullInstanceParam bool bShouldGroup = Node.FirstChild < 0 || ((Node.LastInstance - Node.FirstInstance + 1) < Params.MinInstancesToSplit[MinLOD] - && CanGroup(Node.BoundMin, Node.BoundMax, Params.ViewOriginInLocalZero, Params.ViewOriginInLocalOne, Params.LODPlanesMax[Params.LODs - 1] * DistanceScale)); + && CanGroup(Node.BoundMin, Node.BoundMax, Params.ViewOriginInLocalZero, Params.ViewOriginInLocalOne, Params.LODPlanesMax[Params.LODs - 1])); bool bSplit = (!bFullyContained || MinLOD < MaxLOD || Index < Params.FirstOcclusionNode) && !bShouldGroup; @@ -1600,12 +1595,15 @@ void FHierarchicalStaticMeshSceneProxy::GetDynamicMeshElements(const TArrayBounds.SphereRadius; + + FVector AverageScale = (InstanceParams.Tree[0].MinInstanceScale + (InstanceParams.Tree[0].MaxInstanceScale - InstanceParams.Tree[0].MinInstanceScale) / 2.0f); + FBoxSphereBounds ScaledBounds = RenderData->Bounds.TransformBy(FTransform(FRotator::ZeroRotator, FVector::ZeroVector, AverageScale)); + float SphereRadius = ScaledBounds.SphereRadius; float FinalCull = MAX_flt; if (MinSize > 0.0) { - FinalCull = ComputeBoundsDrawDistance(MinSize, SphereRadius * FMath::Max(FMath::Min3(ClusterTree[0].MinInstanceScale.X, ClusterTree[0].MinInstanceScale.Y, ClusterTree[0].MinInstanceScale.Z), 0.001f), View->ViewMatrices.GetProjectionMatrix()) * LODScale; + FinalCull = ComputeBoundsDrawDistance(MinSize, SphereRadius, View->ViewMatrices.GetProjectionMatrix()) * LODScale; } if (UserData_AllInstances.EndCullDistance > 0.0f) { @@ -1803,13 +1801,13 @@ void FHierarchicalStaticMeshSceneProxy::GetDynamicMeshElements(const TArrayCheckMaterialUsage_Concurrent(MATUSAGE_InstancedStaticMeshes)) + { + Section.Material = UMaterial::GetDefaultMaterial(MD_Surface); + } + } + } + + const bool bInstanced = GRHISupportsInstancing; + + // Copy the parameters for LOD - all instances + UserData_AllInstances.MeshRenderData = InComponent->GetStaticMesh()->RenderData.Get(); + UserData_AllInstances.StartCullDistance = InComponent->InstanceStartCullDistance; + UserData_AllInstances.EndCullDistance = InComponent->InstanceEndCullDistance; + UserData_AllInstances.MinLOD = ClampedMinLOD; + UserData_AllInstances.bRenderSelected = true; + UserData_AllInstances.bRenderUnselected = true; + UserData_AllInstances.RenderData = bInstanced ? nullptr : &InstancedRenderData; + + FVector MinScale(0); + FVector MaxScale(0); + InComponent->GetInstancesMinMaxScale(MinScale, MaxScale); + + UserData_AllInstances.AverageInstancesScale = MinScale + (MaxScale - MinScale) / 2.0f; + + // selected only + UserData_SelectedInstances = UserData_AllInstances; + UserData_SelectedInstances.bRenderUnselected = false; + + // unselected only + UserData_DeselectedInstances = UserData_AllInstances; + UserData_DeselectedInstances.bRenderSelected = false; +} + void FInstancedStaticMeshSceneProxy::SetupInstancedMeshBatch(int32 LODIndex, int32 BatchIndex, FMeshBatch& OutMeshBatch) const { const bool bInstanced = GRHISupportsInstancing; @@ -2100,6 +2149,21 @@ static bool ComponentRequestsCPUAccess(UInstancedStaticMeshComponent* InComponen return false; } +void UInstancedStaticMeshComponent::GetInstancesMinMaxScale(FVector& MinScale, FVector& MaxScale) const +{ + MinScale = FVector(MAX_flt); + MaxScale = FVector(-MAX_flt); + + for (int32 i = 0; i < PerInstanceSMData.Num(); ++i) + { + const FInstancedStaticMeshInstanceData& InstanceData = PerInstanceSMData[i]; + FVector ScaleVector = InstanceData.Transform.GetScaleVector(); + + MinScale = MinScale.ComponentMin(ScaleVector); + MaxScale = MaxScale.ComponentMax(ScaleVector); + } +} + void UInstancedStaticMeshComponent::InitPerInstanceRenderData(bool InitializeFromCurrentData, FStaticMeshInstanceData* InSharedInstanceBufferData, bool InRequireCPUAccess) { if (PerInstanceRenderData.IsValid()) @@ -2484,7 +2548,8 @@ void FInstancedStaticMeshVertexFactoryShaderParameters::GetElementShaderBindings FirstLOD = FMath::Max(FirstLOD, DebugMin); } - float SphereRadius = InstancingUserData->MeshRenderData->Bounds.SphereRadius; + FBoxSphereBounds ScaledBounds = InstancingUserData->MeshRenderData->Bounds.TransformBy(FTransform(FRotator::ZeroRotator, FVector::ZeroVector, InstancingUserData->AverageInstancesScale)); + float SphereRadius = ScaledBounds.SphereRadius; float MinSize = View->ViewMatrices.IsPerspectiveProjection() ? CVarFoliageMinimumScreenSize.GetValueOnRenderThread() : 0.0f; float LODScale = CVarFoliageLODDistanceScale.GetValueOnRenderThread(); float LODRandom = CVarRandomLODRange.GetValueOnRenderThread(); diff --git a/Engine/Source/Runtime/Engine/Private/InstancedStaticMesh.h b/Engine/Source/Runtime/Engine/Private/InstancedStaticMesh.h index 9b85c30b85c6..ce16ac91609f 100644 --- a/Engine/Source/Runtime/Engine/Private/InstancedStaticMesh.h +++ b/Engine/Source/Runtime/Engine/Private/InstancedStaticMesh.h @@ -152,6 +152,7 @@ struct FInstancingUserData bool bRenderSelected; bool bRenderUnselected; + FVector AverageInstancesScale; }; struct FInstancedStaticMeshDataType @@ -624,48 +625,7 @@ protected: private: - void SetupProxy(UInstancedStaticMeshComponent* InComponent) - { -#if WITH_EDITOR - if( bHasSelectedInstances ) - { - // if we have selected indices, mark scene proxy as selected. - SetSelection_GameThread(true); - } -#endif - // Make sure all the materials are okay to be rendered as an instanced mesh. - for (int32 LODIndex = 0; LODIndex < LODs.Num(); LODIndex++) - { - FStaticMeshSceneProxy::FLODInfo& LODInfo = LODs[LODIndex]; - for (int32 SectionIndex = 0; SectionIndex < LODInfo.Sections.Num(); SectionIndex++) - { - FStaticMeshSceneProxy::FLODInfo::FSectionInfo& Section = LODInfo.Sections[SectionIndex]; - if (!Section.Material->CheckMaterialUsage_Concurrent(MATUSAGE_InstancedStaticMeshes)) - { - Section.Material = UMaterial::GetDefaultMaterial(MD_Surface); - } - } - } - - const bool bInstanced = GRHISupportsInstancing; - - // Copy the parameters for LOD - all instances - UserData_AllInstances.MeshRenderData = InComponent->GetStaticMesh()->RenderData.Get(); - UserData_AllInstances.StartCullDistance = InComponent->InstanceStartCullDistance; - UserData_AllInstances.EndCullDistance = InComponent->InstanceEndCullDistance; - UserData_AllInstances.MinLOD = ClampedMinLOD; - UserData_AllInstances.bRenderSelected = true; - UserData_AllInstances.bRenderUnselected = true; - UserData_AllInstances.RenderData = bInstanced ? nullptr : &InstancedRenderData; - - // selected only - UserData_SelectedInstances = UserData_AllInstances; - UserData_SelectedInstances.bRenderUnselected = false; - - // unselected only - UserData_DeselectedInstances = UserData_AllInstances; - UserData_DeselectedInstances.bRenderSelected = false; - } + void SetupProxy(UInstancedStaticMeshComponent* InComponent); }; #if WITH_EDITOR diff --git a/Engine/Source/Runtime/Engine/Private/KismetSystemLibrary.cpp b/Engine/Source/Runtime/Engine/Private/KismetSystemLibrary.cpp index ca49d84ac97c..1136ab919082 100644 --- a/Engine/Source/Runtime/Engine/Private/KismetSystemLibrary.cpp +++ b/Engine/Source/Runtime/Engine/Private/KismetSystemLibrary.cpp @@ -301,14 +301,14 @@ void UKismetSystemLibrary::SetWindowTitle(const FText& Title) void UKismetSystemLibrary::ExecuteConsoleCommand(UObject* WorldContextObject, const FString& Command, APlayerController* Player) { // First, try routing through the primary player - APlayerController* TargetPC = Player ? Player : UGameplayStatics::GetPlayerController(WorldContextObject, 0); + UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); + APlayerController* TargetPC = Player || !World ? Player : World->GetFirstPlayerController(); if (TargetPC) { TargetPC->ConsoleCommand(Command, true); } - else if (GEngine) + else { - UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); GEngine->Exec(World, *Command); } } diff --git a/Engine/Source/Runtime/Engine/Private/Materials/Material.cpp b/Engine/Source/Runtime/Engine/Private/Materials/Material.cpp index 97fbbb4a7227..e50c26b82691 100644 --- a/Engine/Source/Runtime/Engine/Private/Materials/Material.cpp +++ b/Engine/Source/Runtime/Engine/Private/Materials/Material.cpp @@ -435,7 +435,8 @@ void UMaterialInterface::InitDefaultMaterials() // the default materials is only done very early in the boot process. static bool bInitialized = false; if (!bInitialized) - { + { + SCOPED_BOOT_TIMING("UMaterialInterface::InitDefaultMaterials"); check(IsInGameThread()); if (!IsInGameThread()) { diff --git a/Engine/Source/Runtime/Engine/Private/Particles/FXSystemPrivate.h b/Engine/Source/Runtime/Engine/Private/Particles/FXSystemPrivate.h index 78886f22d206..bb67e11985a5 100644 --- a/Engine/Source/Runtime/Engine/Private/Particles/FXSystemPrivate.h +++ b/Engine/Source/Runtime/Engine/Private/Particles/FXSystemPrivate.h @@ -64,7 +64,7 @@ inline bool IsParticleCollisionModeSupported(EShaderPlatform InPlatform, EPartic case PCM_DepthBuffer: // we only need to check for simple forward if we're NOT currently attempting to cache the shader // since SF is a runtime change, we need to compile the shader regardless, because we could be switching to deferred at any time - return (IsFeatureLevelSupported(InPlatform, ERHIFeatureLevel::SM4) || (IsFeatureLevelSupported(InPlatform, ERHIFeatureLevel::ES3_1) && IsVulkanPlatform(InPlatform))) + return (IsFeatureLevelSupported(InPlatform, ERHIFeatureLevel::SM4)) && (bForCaching || !IsSimpleForwardShadingEnabled(InPlatform)); case PCM_DistanceField: return IsFeatureLevelSupported(InPlatform, ERHIFeatureLevel::SM5); diff --git a/Engine/Source/Runtime/Engine/Private/PreviewScene.cpp b/Engine/Source/Runtime/Engine/Private/PreviewScene.cpp index 214c561d8789..1fe1ef218379 100644 --- a/Engine/Source/Runtime/Engine/Private/PreviewScene.cpp +++ b/Engine/Source/Runtime/Engine/Private/PreviewScene.cpp @@ -35,28 +35,33 @@ FPreviewScene::FPreviewScene(FPreviewScene::ConstructionValues CVS) PreviewWorld->InitializeNewWorld(UWorld::InitializationValues() .AllowAudioPlayback(CVS.bAllowAudioPlayback) .CreatePhysicsScene(CVS.bCreatePhysicsScene) - .RequiresHitProxies(true) + .RequiresHitProxies(CVS.bEditor) // Only Need hit proxies in an editor scene .CreateNavigation(false) .CreateAISystem(false) .ShouldSimulatePhysics(CVS.bShouldSimulatePhysics) - .SetTransactional(CVS.bTransactional)); + .SetTransactional(CVS.bTransactional) + .SetDefaultGameMode(CVS.DefaultGameMode)); + PreviewWorld->InitializeActorsForPlay(FURL()); - DirectionalLight = NewObject(GetTransientPackage(), NAME_None, RF_Transient); - DirectionalLight->Intensity = CVS.LightBrightness; - DirectionalLight->LightColor = FColor::White; - AddComponent(DirectionalLight, FTransform(CVS.LightRotation)); + if (CVS.bDefaultLighting) + { + DirectionalLight = NewObject(GetTransientPackage(), NAME_None, RF_Transient); + DirectionalLight->Intensity = CVS.LightBrightness; + DirectionalLight->LightColor = FColor::White; + AddComponent(DirectionalLight, FTransform(CVS.LightRotation)); - SkyLight = NewObject(GetTransientPackage(), NAME_None, RF_Transient); - SkyLight->bLowerHemisphereIsBlack = false; - SkyLight->SourceType = ESkyLightSourceType::SLS_SpecifiedCubemap; - SkyLight->Intensity = CVS.SkyBrightness; - SkyLight->Mobility = EComponentMobility::Movable; - AddComponent(SkyLight, FTransform::Identity); + SkyLight = NewObject(GetTransientPackage(), NAME_None, RF_Transient); + SkyLight->bLowerHemisphereIsBlack = false; + SkyLight->SourceType = ESkyLightSourceType::SLS_SpecifiedCubemap; + SkyLight->Intensity = CVS.SkyBrightness; + SkyLight->Mobility = EComponentMobility::Movable; + AddComponent(SkyLight, FTransform::Identity); - LineBatcher = NewObject(GetTransientPackage()); - LineBatcher->bCalculateAccurateBounds = false; - AddComponent(LineBatcher, FTransform::Identity); + LineBatcher = NewObject(GetTransientPackage()); + LineBatcher->bCalculateAccurateBounds = false; + AddComponent(LineBatcher, FTransform::Identity); + } } FPreviewScene::~FPreviewScene() diff --git a/Engine/Source/Runtime/Engine/Private/RepLayout.cpp b/Engine/Source/Runtime/Engine/Private/RepLayout.cpp index 384902fcf016..2220b89c3050 100644 --- a/Engine/Source/Runtime/Engine/Private/RepLayout.cpp +++ b/Engine/Source/Runtime/Engine/Private/RepLayout.cpp @@ -3076,6 +3076,7 @@ void FRepLayout::CallRepNotifies(FReceivingRepState* RepState, UObject* Object) check(LayoutState == ERepLayoutState::Normal); FRepShadowDataBuffer ShadowData(RepState->StaticBuffer.GetData()); + FRepObjectDataBuffer ObjectData(Object); for (UProperty* RepProperty : RepState->RepNotifies) { @@ -3105,13 +3106,24 @@ void FRepLayout::CallRepNotifies(FReceivingRepState* RepState, UObject* Object) }); check(Parent); + + FRepShadowDataBuffer PropertyData = ShadowData + (*Parent); - Object->ProcessEvent(RepNotifyFunc, ShadowData + (*Parent)); + // This could be cached off as a Parent flag, to avoid touching the Commands array. + if (ERepLayoutCmdType::PropertyBool == Cmds[Parent->CmdStart].Type) + { + bool BoolPropertyValue = !!static_cast(Parent->Property)->GetPropertyValue(PropertyData); + Object->ProcessEvent(RepNotifyFunc, &BoolPropertyValue); + } + else + { + Object->ProcessEvent(RepNotifyFunc, PropertyData); + } // now store the complete value in the shadow buffer if (!EnumHasAnyFlags(Parent->Flags, ERepParentFlags::IsNetSerialize | ERepParentFlags::IsCustomDelta)) { - RepProperty->CopyCompleteValue(ShadowData + (*Parent), RepProperty->ContainerPtrToValuePtr(Object)); + RepProperty->CopyCompleteValue(ShadowData + (*Parent), ObjectData + (*Parent)); } } } diff --git a/Engine/Source/Runtime/Engine/Private/SkeletalMesh.cpp b/Engine/Source/Runtime/Engine/Private/SkeletalMesh.cpp index 56254f853e0a..4e7fca413f6f 100644 --- a/Engine/Source/Runtime/Engine/Private/SkeletalMesh.cpp +++ b/Engine/Source/Runtime/Engine/Private/SkeletalMesh.cpp @@ -296,6 +296,7 @@ USkeletalMesh::USkeletalMesh(const FObjectInitializer& ObjectInitializer) #endif MinLod.Default = 0; + DisableBelowMinLodStripping.Default = false; } USkeletalMesh::USkeletalMesh(FVTableHelper& Helper) diff --git a/Engine/Source/Runtime/Engine/Private/SkeletalMeshLODRenderData.cpp b/Engine/Source/Runtime/Engine/Private/SkeletalMeshLODRenderData.cpp index 346137089f07..4da031f6456d 100644 --- a/Engine/Source/Runtime/Engine/Private/SkeletalMeshLODRenderData.cpp +++ b/Engine/Source/Runtime/Engine/Private/SkeletalMeshLODRenderData.cpp @@ -638,15 +638,16 @@ void FSkeletalMeshLODRenderData::Serialize(FArchive& Ar, UObject* Owner, int32 I USkeletalMesh* OwnerMesh = CastChecked(Owner); int32 MinMeshLod = 0; - + bool bMeshDisablesMinLodStrip = false; #if WITH_EDITOR if(bIsCook) { MinMeshLod = OwnerMesh ? OwnerMesh->MinLod.GetValueForPlatformIdentifiers(CookTarget->GetPlatformInfo().PlatformGroupName, CookTarget->GetPlatformInfo().VanillaPlatformName) : 0; + bMeshDisablesMinLodStrip = OwnerMesh ? OwnerMesh->DisableBelowMinLodStripping.GetValueForPlatformIdentifiers(CookTarget->GetPlatformInfo().PlatformGroupName, CookTarget->GetPlatformInfo().VanillaPlatformName) : false; } #endif - const bool bWantToStripBelowMinLod = bIsCook && GStripSkeletalMeshLodsDuringCooking != 0 && MinMeshLod > Idx; + const bool bWantToStripBelowMinLod = bIsCook && GStripSkeletalMeshLodsDuringCooking != 0 && MinMeshLod > Idx && !bMeshDisablesMinLodStrip; ClassDataStripFlags |= bWantToStripTessellation ? LodAdjacencyStripFlag : 0; ClassDataStripFlags |= bWantToStripBelowMinLod ? MinLodStripFlag : 0; diff --git a/Engine/Source/Runtime/Engine/Private/SkeletalMeshLODSettings.cpp b/Engine/Source/Runtime/Engine/Private/SkeletalMeshLODSettings.cpp index aa2039c0db71..dce64399d2b1 100644 --- a/Engine/Source/Runtime/Engine/Private/SkeletalMeshLODSettings.cpp +++ b/Engine/Source/Runtime/Engine/Private/SkeletalMeshLODSettings.cpp @@ -161,6 +161,7 @@ int32 USkeletalMeshLODSettings::SetLODSettingsToMesh(USkeletalMesh* InMesh) cons if (InMesh) { InMesh->MinLod = MinLod; + InMesh->DisableBelowMinLodStripping = DisableBelowMinLodStripping; // we only fill up until we have enough LODs const int32 NumSettings = FMath::Min(LODGroups.Num(), InMesh->GetLODNum()); for (int32 Index = 0; Index < NumSettings; ++Index) @@ -180,6 +181,7 @@ int32 USkeletalMeshLODSettings::SetLODSettingsFromMesh(USkeletalMesh* InMesh) if (InMesh) { MinLod = InMesh->MinLod; + DisableBelowMinLodStripping = InMesh->DisableBelowMinLodStripping; // we only fill up until we have enough LODs const int32 NumSettings = InMesh->GetLODNum(); LODGroups.Reset(NumSettings); diff --git a/Engine/Source/Runtime/Engine/Private/SoundBase.cpp b/Engine/Source/Runtime/Engine/Private/SoundBase.cpp index 5882445f5f66..b5168b11ddd6 100644 --- a/Engine/Source/Runtime/Engine/Private/SoundBase.cpp +++ b/Engine/Source/Runtime/Engine/Private/SoundBase.cpp @@ -27,6 +27,7 @@ void USoundBase::PostInitProperties() const FSoftObjectPath DefaultSoundClassName = GetDefault()->DefaultSoundClassName; if (DefaultSoundClassName.IsValid()) { + SCOPED_BOOT_TIMING("USoundBase::LoadSoundClass"); USoundBase::DefaultSoundClassObject = LoadObject(nullptr, *DefaultSoundClassName.ToString()); } } @@ -37,6 +38,7 @@ void USoundBase::PostInitProperties() const FSoftObjectPath DefaultSoundConcurrencyName = GetDefault()->DefaultSoundConcurrencyName; if (DefaultSoundConcurrencyName.IsValid()) { + SCOPED_BOOT_TIMING("USoundBase::LoadSoundConcurrency"); USoundBase::DefaultSoundConcurrencyObject = LoadObject(nullptr, *DefaultSoundConcurrencyName.ToString()); } } diff --git a/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceState.cpp b/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceState.cpp index 9465d35fd9eb..d986ea43368f 100644 --- a/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceState.cpp +++ b/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceState.cpp @@ -19,7 +19,7 @@ int32 FRenderAssetInstanceState::AddBounds(const UPrimitiveComponent* Component) return AddBounds(Component->Bounds, PackedRelativeBox_Identity, Component, Component->LastRenderTimeOnScreen, Component->Bounds.Origin, 0, 0, FLT_MAX); } -int32 FRenderAssetInstanceState::AddBounds(const FBoxSphereBounds& Bounds, uint32 PackedRelativeBox, const UPrimitiveComponent* InComponent, float LastRenderTime, const FVector4& RangeOrigin, float MinDistance, float MinRange, float MaxRange) +int32 FRenderAssetInstanceState::AddBounds(const FBoxSphereBounds& Bounds, uint32 PackedRelativeBox, const UPrimitiveComponent* InComponent, float LastRenderTime, const FVector4& RangeOrigin, float MinDistanceSq, float MinRangeSq, float MaxRangeSq) { check(InComponent); @@ -46,7 +46,7 @@ int32 FRenderAssetInstanceState::AddBounds(const FBoxSphereBounds& Bounds, uint3 FreeBoundIndices.Push(BoundsIndex + 1); } - Bounds4[BoundsIndex / 4].Set(BoundsIndex % 4, Bounds, PackedRelativeBox, LastRenderTime, RangeOrigin, MinDistance, MinRange, MaxRange); + Bounds4[BoundsIndex / 4].Set(BoundsIndex % 4, Bounds, PackedRelativeBox, LastRenderTime, RangeOrigin, MinDistanceSq, MinRangeSq, MaxRangeSq); Bounds4Components[BoundsIndex] = InComponent; return BoundsIndex; @@ -355,7 +355,7 @@ EAddComponentResult FRenderAssetInstanceState::AddComponent(const UPrimitiveComp }); int32* ComponentLink = ComponentMap.Find(Component); - float MinDistance = 0, MinRange = 0, MaxRange = FLT_MAX; + float MinDistanceSq = 0, MinRangeSq = 0, MaxRangeSq = FLT_MAX; // Loop for each bound. for (int32 InfoIndex = 0; InfoIndex < RenderAssetInstanceInfos.Num();) @@ -368,8 +368,8 @@ EAddComponentResult FRenderAssetInstanceState::AddComponent(const UPrimitiveComp ++NumOfBoundReferences; } - GetDistanceAndRange(Component, Info.Bounds, MinDistance, MinRange, MaxRange); - const int32 BoundsIndex = AddBounds(Info.Bounds, PackedRelativeBox_Identity, Component, Component->LastRenderTimeOnScreen, Component->Bounds.Origin, MinDistance, MinRange, MaxRange); + GetDistanceAndRange(Component, Info.Bounds, MinDistanceSq, MinRangeSq, MaxRangeSq); + const int32 BoundsIndex = AddBounds(Info.Bounds, PackedRelativeBox_Identity, Component, Component->LastRenderTimeOnScreen, Component->Bounds.Origin, MinDistanceSq, MinRangeSq, MaxRangeSq); AddRenderAssetElements(Component, TArrayView(RenderAssetInstanceInfos.GetData() + InfoIndex, NumOfBoundReferences), BoundsIndex, ComponentLink); InfoIndex += NumOfBoundReferences; @@ -539,12 +539,26 @@ bool FRenderAssetInstanceState::ConditionalUpdateBounds(int32 BoundIndex) } -void FRenderAssetInstanceState::UpdateLastRenderTime(int32 BoundIndex) +void FRenderAssetInstanceState::UpdateLastRenderTimeAndMaxDrawDistance(int32 BoundIndex) { const UPrimitiveComponent* Component = ensure(Bounds4Components.IsValidIndex(BoundIndex)) ? Bounds4Components[BoundIndex] : nullptr; if (Component) { - Bounds4[BoundIndex / 4].UpdateLastRenderTime(BoundIndex % 4, Component->LastRenderTimeOnScreen); + const int32 Bounds4Idx = BoundIndex / 4; + const int32 SubIdx = BoundIndex & 3; + Bounds4[Bounds4Idx].UpdateLastRenderTime(SubIdx, Component->LastRenderTimeOnScreen); + // The min draw distances of HLODs can change dynamically (see Tick, PauseDitherTransition, + // and StartDitherTransition methods of ALODActor) + const UPrimitiveComponent* LODParent = Component->GetLODParentPrimitive(); + if (LODParent) + { + const float MaxRangeSq = FRenderAssetInstanceView::GetMaxDrawDistSqWithLODParent( + Component->Bounds.Origin, + LODParent->Bounds.Origin, + LODParent->MinDrawDistance, + LODParent->Bounds.SphereRadius); + Bounds4[Bounds4Idx].UpdateMaxDrawDistanceSquared(SubIdx, MaxRangeSq); + } } } diff --git a/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceState.h b/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceState.h index ddf82f3b7e7f..a510b1180534 100644 --- a/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceState.h +++ b/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceState.h @@ -44,7 +44,7 @@ public: void UpdateBounds(const UPrimitiveComponent* Component); bool UpdateBounds(int32 BoundIndex); bool ConditionalUpdateBounds(int32 BoundIndex); - void UpdateLastRenderTime(int32 BoundIndex); + void UpdateLastRenderTimeAndMaxDrawDistance(int32 BoundIndex); uint32 GetAllocatedSize() const; @@ -66,7 +66,7 @@ private: // Returns the next elements using the same component. void RemoveElement(int32 ElementIndex, int32& NextComponentLink, int32& BoundsIndex, const UStreamableRenderAsset*& Asset); - int32 AddBounds(const FBoxSphereBounds& Bounds, uint32 PackedRelativeBox, const UPrimitiveComponent* Component, float LastRenderTime, const FVector4& RangeOrigin, float MinDistance, float MinRange, float MaxRange); + int32 AddBounds(const FBoxSphereBounds& Bounds, uint32 PackedRelativeBox, const UPrimitiveComponent* Component, float LastRenderTime, const FVector4& RangeOrigin, float MinDistanceSq, float MinRangeSq, float MaxRangeSq); FORCEINLINE int32 AddBounds(const UPrimitiveComponent* Component); void RemoveBounds(int32 Index); diff --git a/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceTask.cpp b/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceTask.cpp index aa208d7ed20f..83f50dbe3ed5 100644 --- a/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceTask.cpp +++ b/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceTask.cpp @@ -29,7 +29,7 @@ void FRefreshVisibility::operator()(bool bAsync) { for (int32 Index = BeginIndex; Index < EndIndex; ++Index) { - State->UpdateLastRenderTime(Index); + State->UpdateLastRenderTimeAndMaxDrawDistance(Index); } } diff --git a/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceView.cpp b/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceView.cpp index 370ef137df25..71e4a35fb738 100644 --- a/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceView.cpp +++ b/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceView.cpp @@ -11,7 +11,7 @@ #include "Components/PrimitiveComponent.h" #include "ContentStreaming.h" -void FRenderAssetInstanceView::FBounds4::Set(int32 Index, const FBoxSphereBounds& Bounds, uint32 InPackedRelativeBox, float InLastRenderTime, const FVector& RangeOrigin, float InMinDistance, float InMinRange, float InMaxRange) +void FRenderAssetInstanceView::FBounds4::Set(int32 Index, const FBoxSphereBounds& Bounds, uint32 InPackedRelativeBox, float InLastRenderTime, const FVector& RangeOrigin, float InMinDistanceSq, float InMinRangeSq, float InMaxRangeSq) { check(Index >= 0 && Index < 4); @@ -26,9 +26,9 @@ void FRenderAssetInstanceView::FBounds4::Set(int32 Index, const FBoxSphereBounds ExtentZ.Component(Index) = Bounds.BoxExtent.Z; Radius.Component(Index) = Bounds.SphereRadius; PackedRelativeBox[Index] = InPackedRelativeBox; - MinDistanceSq.Component(Index) = InMinDistance * InMinDistance; - MinRangeSq.Component(Index) = InMinRange * InMinRange; - MaxRangeSq.Component(Index) = InMaxRange != FLT_MAX ? (InMaxRange * InMaxRange) : FLT_MAX; + MinDistanceSq.Component(Index) = InMinDistanceSq; + MinRangeSq.Component(Index) = InMinRangeSq; + MaxRangeSq.Component(Index) = InMaxRangeSq; LastRenderTime.Component(Index) = InLastRenderTime; } @@ -43,8 +43,8 @@ void FRenderAssetInstanceView::FBounds4::UnpackBounds(int32 Index, const UPrimit UnpackRelativeBox(Component->Bounds, PackedRelativeBox[Index], SubBounds); // Update the visibility range once we have the bounds. - float MinDistance = 0, MinRange = 0, MaxRange = FLT_MAX; - FRenderAssetInstanceView::GetDistanceAndRange(Component, SubBounds, MinDistance, MinRange, MaxRange); + float MinDistance2 = 0, MinRange2 = 0, MaxRange2 = FLT_MAX; + FRenderAssetInstanceView::GetDistanceAndRange(Component, SubBounds, MinDistance2, MinRange2, MaxRange2); OriginX.Component(Index) = SubBounds.Origin.X; OriginY.Component(Index) = SubBounds.Origin.Y; @@ -57,9 +57,9 @@ void FRenderAssetInstanceView::FBounds4::UnpackBounds(int32 Index, const UPrimit ExtentZ.Component(Index) = SubBounds.BoxExtent.Z; Radius.Component(Index) = SubBounds.SphereRadius; PackedRelativeBox[Index] = PackedRelativeBox_Identity; - MinDistanceSq.Component(Index) = MinDistance * MinDistance; - MinRangeSq.Component(Index) = MinRange * MinRange; - MaxRangeSq.Component(Index) = MaxRange != FLT_MAX ? (MaxRange * MaxRange) : FLT_MAX; + MinDistanceSq.Component(Index) = MinDistance2; + MinRangeSq.Component(Index) = MinRange2; + MaxRangeSq.Component(Index) = MaxRange2; } } @@ -223,11 +223,17 @@ TRefCountPtr FRenderAssetInstanceView::CreateViewWithU return NewView; } -void FRenderAssetInstanceView::GetDistanceAndRange(const UPrimitiveComponent* Component, const FBoxSphereBounds& RenderAssetInstanceBounds, float& MinDistance, float& MinRange, float& MaxRange) +float FRenderAssetInstanceView::GetMaxDrawDistSqWithLODParent(const FVector& Origin, const FVector& ParentOrigin, float ParentMinDrawDist, float ParentBoundingSphereRadius) +{ + const float Result = ParentMinDrawDist + ParentBoundingSphereRadius + (Origin - ParentOrigin).Size(); + return Result * Result; +} + +void FRenderAssetInstanceView::GetDistanceAndRange(const UPrimitiveComponent* Component, const FBoxSphereBounds& RenderAssetInstanceBounds, float& MinDistanceSq, float& MinRangeSq, float& MaxRangeSq) { check(Component && Component->IsRegistered()); - // In the engine, the MinDistance is computed from the component bound center to the viewpoint. + // In the engine, the MinDistance is computed from the component bound center to the viewpoint (except for HLODs). // The streaming computes the distance as the distance from viewpoint to the edge of the texture bound box. // The implementation also handles MinDistance by bounding the distance to it so that if the viewpoint gets closer the screen size will stop increasing at some point. // The fact that the primitive will disappear is not so relevant as this will be handled by the visibility logic, normally streaming one less mip than requested. @@ -235,10 +241,12 @@ void FRenderAssetInstanceView::GetDistanceAndRange(const UPrimitiveComponent* Co const UPrimitiveComponent* LODParent = Component->GetLODParentPrimitive(); - MinDistance = FMath::Max(0, Component->MinDrawDistance - (RenderAssetInstanceBounds.Origin - Component->Bounds.Origin).Size() - RenderAssetInstanceBounds.SphereRadius); - MinRange = FMath::Max(0, Component->MinDrawDistance); + MinDistanceSq = FMath::Max(0, Component->MinDrawDistance - (RenderAssetInstanceBounds.Origin - Component->Bounds.Origin).Size() - RenderAssetInstanceBounds.SphereRadius); + MinDistanceSq *= MinDistanceSq; + MinRangeSq = FMath::Max(0, Component->MinDrawDistance); + MinRangeSq *= MinRangeSq; // Max distance when HLOD becomes visible. - MaxRange = LODParent ? (LODParent->MinDrawDistance + (Component->Bounds.Origin - LODParent->Bounds.Origin).Size()) : FLT_MAX; + MaxRangeSq = LODParent ? GetMaxDrawDistSqWithLODParent(Component->Bounds.Origin, LODParent->Bounds.Origin, LODParent->MinDrawDistance, LODParent->Bounds.SphereRadius) : FLT_MAX; } void FRenderAssetInstanceView::SwapData(FRenderAssetInstanceView* Lfs, FRenderAssetInstanceView* Rhs) diff --git a/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceView.h b/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceView.h index dce7cd93e5e9..8a569479c7e8 100644 --- a/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceView.h +++ b/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceView.h @@ -69,10 +69,11 @@ public: FVector4 LastRenderTime; //(FApp::GetCurrentTime() - Component->LastRenderTime); - void Set(int32 Index, const FBoxSphereBounds& Bounds, uint32 InPackedRelativeBox, float LastRenderTime, const FVector& RangeOrigin, float MinDistance, float MinRange, float MaxRange); + void Set(int32 Index, const FBoxSphereBounds& Bounds, uint32 InPackedRelativeBox, float LastRenderTime, const FVector& RangeOrigin, float MinDistanceSq, float MinRangeSq, float MaxRangeSq); void UnpackBounds(int32 Index, const UPrimitiveComponent* Component); void FullUpdate(int32 Index, const FBoxSphereBounds& Bounds, float LastRenderTime); FORCEINLINE void UpdateLastRenderTime(int32 Index, float LastRenderTime); + FORCEINLINE void UpdateMaxDrawDistanceSquared(int32 Index, float InMaxRangeSq); // Clears entry between 0 and 4 FORCEINLINE void Clear(int32 Index); @@ -198,7 +199,9 @@ public: float GetMaxTexelFactor() const { return MaxTexelFactor; } - static void GetDistanceAndRange(const UPrimitiveComponent* Component, const FBoxSphereBounds& RenderAssetInstanceBounds, float& MinDistance, float& MinRange, float& MaxRange); + static float GetMaxDrawDistSqWithLODParent(const FVector& Origin, const FVector& ParentOrigin, float ParentMinDrawDist, float ParentBoundingSphereRadius); + + static void GetDistanceAndRange(const UPrimitiveComponent* Component, const FBoxSphereBounds& RenderAssetInstanceBounds, float& MinDistanceSq, float& MinRangeSq, float& MaxRangeSq); protected: diff --git a/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceView.inl b/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceView.inl index 97de6c795d58..d3f69c01f279 100644 --- a/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceView.inl +++ b/Engine/Source/Runtime/Engine/Private/Streaming/TextureInstanceView.inl @@ -62,6 +62,12 @@ void FRenderAssetInstanceView::FBounds4::UpdateLastRenderTime(int32 Index, float LastRenderTime.Component(Index) = InLastRenderTime; } +void FRenderAssetInstanceView::FBounds4::UpdateMaxDrawDistanceSquared(int32 Index, float InMaxRangeSq) +{ + check(Index >= 0 && Index < 4); + MaxRangeSq.Component(Index) = InMaxRangeSq; +} + FRenderAssetInstanceView::FElement::FElement() : Component(nullptr) , RenderAsset(nullptr) diff --git a/Engine/Source/Runtime/Engine/Private/Streaming/TextureStreamingHelpers.cpp b/Engine/Source/Runtime/Engine/Private/Streaming/TextureStreamingHelpers.cpp index aad3ca747010..adf679aefdb1 100644 --- a/Engine/Source/Runtime/Engine/Private/Streaming/TextureStreamingHelpers.cpp +++ b/Engine/Source/Runtime/Engine/Private/Streaming/TextureStreamingHelpers.cpp @@ -97,7 +97,7 @@ TAutoConsoleVariable CVarStreamingUseFixedPoolSize( TEXT("r.Streaming.UseFixedPoolSize"), 0, TEXT("If non-zero, do not allow the pool size to change at run time."), - ECVF_ReadOnly); + ECVF_Scalability); TAutoConsoleVariable CVarStreamingPoolSize( TEXT("r.Streaming.PoolSize"), diff --git a/Engine/Source/Runtime/Engine/Private/UnrealClient.cpp b/Engine/Source/Runtime/Engine/Private/UnrealClient.cpp index 836cbf27def2..cd6f405ca66a 100644 --- a/Engine/Source/Runtime/Engine/Private/UnrealClient.cpp +++ b/Engine/Source/Runtime/Engine/Private/UnrealClient.cpp @@ -1539,6 +1539,9 @@ void FViewport::Draw( bool bShouldPresent /*= true */) ViewportClient->Draw(this, &Canvas); } Canvas.Flush_GameThread(); + + UGameViewportClient::OnViewportRendered().Broadcast(this); + ViewportClient->ProcessScreenShots(this); // Slate doesn't present immediately. Tag the viewport as requiring vsync so that it happens. diff --git a/Engine/Source/Runtime/Engine/Private/UnrealEngine.cpp b/Engine/Source/Runtime/Engine/Private/UnrealEngine.cpp index e755bcae01fc..dbb7dbe7fabb 100644 --- a/Engine/Source/Runtime/Engine/Private/UnrealEngine.cpp +++ b/Engine/Source/Runtime/Engine/Private/UnrealEngine.cpp @@ -2303,6 +2303,7 @@ UEngineCustomTimeStep* InitializeCustomTimeStep(UEngine* InEngine, FSoftClassPat */ void UEngine::InitializeObjectReferences() { + SCOPED_BOOT_TIMING("UEngine::InitializeObjectReferences"); DECLARE_SCOPE_CYCLE_COUNTER(TEXT("UEngine::InitializeObjectReferences"), STAT_InitializeObjectReferences, STATGROUP_LoadTime); // This initializes the tag data if it hasn't been already, we need to do this before loading any game data @@ -3323,6 +3324,7 @@ struct FSortedSkeletalMesh int32 ResKBIncMobile; int32 LodCount; int32 MobileMinLOD; + int32 MeshDisablesMinLODStripping; int32 VertexCountLod0; int32 VertexCountLod1; int32 VertexCountLod2; @@ -3332,7 +3334,7 @@ struct FSortedSkeletalMesh FString Name; /** Constructor, initializing every member variable with passed in values. */ - FSortedSkeletalMesh(int32 InNumKB, int32 InMaxKB, int32 InResKBExc, int32 InResKBInc, int32 InResKBIncMobile, int32 InLodCount, int32 InMobileMinLOD, int32 InVertexCountLod0, + FSortedSkeletalMesh(int32 InNumKB, int32 InMaxKB, int32 InResKBExc, int32 InResKBInc, int32 InResKBIncMobile, int32 InLodCount, int32 InMobileMinLOD, int32 InMeshDisablesMinLODStripping, int32 InVertexCountLod0, int32 InVertexCountLod1, int32 InVertexCountLod2, int32 InVertexCountTotal, int32 InVertexCountTotalMobile, int32 InVertexCountCollision, FString InName) : NumKB(InNumKB) , MaxKB(InMaxKB) @@ -3341,6 +3343,7 @@ struct FSortedSkeletalMesh , ResKBIncMobile(InResKBIncMobile) , LodCount(InLodCount) , MobileMinLOD(InMobileMinLOD) + , MeshDisablesMinLODStripping(InMeshDisablesMinLODStripping) , VertexCountLod0(InVertexCountLod0) , VertexCountLod1(InVertexCountLod1) , VertexCountLod2(InVertexCountLod2) @@ -5211,12 +5214,18 @@ bool UEngine::HandleListSkeletalMeshesCommand(const TCHAR* Cmd, FOutputDevice& A int32 LodCount = 0; int32 MobileMinLOD = -1; - + int32 MeshDisablesMinLODStripping = 0; #if WITH_EDITORONLY_DATA if (Mesh->MinLod.PerPlatform.Find(("Mobile")) != nullptr) { MobileMinLOD = *Mesh->MinLod.PerPlatform.Find(("Mobile")); } + + MeshDisablesMinLODStripping = Mesh->DisableBelowMinLodStripping.Default ? 1 : 0; + if (Mesh->DisableBelowMinLodStripping.PerPlatform.Find(("Mobile")) != nullptr) + { + MeshDisablesMinLODStripping = *Mesh->DisableBelowMinLodStripping.PerPlatform.Find(("Mobile")) ? 1 : 0; + } #endif int32 VertexCountLod0 = 0; @@ -5237,7 +5246,7 @@ bool UEngine::HandleListSkeletalMeshesCommand(const TCHAR* Cmd, FOutputDevice& A for(int32 i = 0; i < LodCount; i++) { VertexCountTotal += LodRenderData[i].GetNumVertices(); - VertexCountTotalMobile += i >= MobileMinLOD ? LodRenderData[i].GetNumVertices() : 0; + VertexCountTotalMobile += i >= MobileMinLOD || MeshDisablesMinLODStripping == 1 ? LodRenderData[i].GetNumVertices() : 0; } } @@ -5263,6 +5272,7 @@ bool UEngine::HandleListSkeletalMeshesCommand(const TCHAR* Cmd, FOutputDevice& A ResKBIncMobile, LodCount, MobileMinLOD, + MeshDisablesMinLODStripping, VertexCountLod0, VertexCountLod1, VertexCountLod2, @@ -5286,11 +5296,11 @@ bool UEngine::HandleListSkeletalMeshesCommand(const TCHAR* Cmd, FOutputDevice& A if (bCSV) { - Ar.Logf(TEXT(",NumKB, MaxKB, ResKBExc, ResKBInc, ResKBIncMobile, LOD Count, MobileMinLOD, Verts LOD0, Verts LOD1, Verts LOD2, Verts Total, Verts Total Mobile, Verts Collision, Name")); + Ar.Logf(TEXT(",NumKB, MaxKB, ResKBExc, ResKBInc, ResKBIncMobile, LOD Count, MobileMinLOD, DisableMinLODStripping, Verts LOD0, Verts LOD1, Verts LOD2, Verts Total, Verts Total Mobile, Verts Collision, Name")); } else { - Ar.Logf(TEXT(" NumKB MaxKB ResKBExc ResKBInc ResKBIncMobile NumLODs MobileMinLOD VertsLOD0 VertsLOD1 VertsLOD2 VertsTotal VertsTotalMobile VertsColl Name")); + Ar.Logf(TEXT(" NumKB MaxKB ResKBExc ResKBInc ResKBIncMobile NumLODs MobileMinLOD DisableMinLODStripping VertsLOD0 VertsLOD1 VertsLOD2 VertsTotal VertsTotalMobile VertsColl Name")); } for (int32 MeshIndex = 0; MeshIndex LoadedClasses; for ( auto& Entry : SoftwareCursors ) { @@ -197,6 +199,10 @@ void UUserInterfaceSettings::ForceLoadResources() UObject* Cursor = LoadedClasses[i]; if (Cursor) { +#if !WITH_EDITOR + // Add to root in case this was loaded after disregard for GC closes + Cursor->AddToRoot(); +#endif CursorClasses.Add(Cursor); } else diff --git a/Engine/Source/Runtime/Engine/Private/VideoRecordingSystem.cpp b/Engine/Source/Runtime/Engine/Private/VideoRecordingSystem.cpp index 472a2aa17437..afd0fd2c78c1 100644 --- a/Engine/Source/Runtime/Engine/Private/VideoRecordingSystem.cpp +++ b/Engine/Source/Runtime/Engine/Private/VideoRecordingSystem.cpp @@ -1,9 +1,3 @@ // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. #include "VideoRecordingSystem.h" - -DEFINE_STAT(STAT_VideoRecordingSystem_EnableRecording); -DEFINE_STAT(STAT_VideoRecordingSystem_NewRecording); -DEFINE_STAT(STAT_VideoRecordingSystem_StartRecording); -DEFINE_STAT(STAT_VideoRecordingSystem_PauseRecording); -DEFINE_STAT(STAT_VideoRecordingSystem_FinalizeRecording); \ No newline at end of file diff --git a/Engine/Source/Runtime/Engine/Private/World.cpp b/Engine/Source/Runtime/Engine/Private/World.cpp index bec23edec65c..ef5f9c526719 100644 --- a/Engine/Source/Runtime/Engine/Private/World.cpp +++ b/Engine/Source/Runtime/Engine/Private/World.cpp @@ -1487,7 +1487,14 @@ void UWorld::InitializeNewWorld(const InitializationValues IVS) SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; // Set constant name for WorldSettings to make a network replication work between new worlds on host and client SpawnInfo.Name = GEngine->WorldSettingsClass->GetFName(); - AWorldSettings* WorldSettings = SpawnActor( GEngine->WorldSettingsClass, SpawnInfo ); + AWorldSettings* WorldSettings = SpawnActor(GEngine->WorldSettingsClass, SpawnInfo ); + + // Allow the world creator to override the default game mode in case they do not plan to load a level. + if (IVS.DefaultGameMode) + { + WorldSettings->DefaultGameMode = IVS.DefaultGameMode; + } + PersistentLevel->SetWorldSettings(WorldSettings); check(GetWorldSettings()); #if WITH_EDITOR @@ -3752,6 +3759,7 @@ bool UWorld::SetGameMode(const FURL& InURL) void UWorld::InitializeActorsForPlay(const FURL& InURL, bool bResetTime) { check(bIsWorldInitialized); + SCOPED_BOOT_TIMING("UWorld::InitializeActorsForPlay"); double StartTime = FPlatformTime::Seconds(); // Don't reset time for seamless world transitions. diff --git a/Engine/Source/Runtime/Engine/Private/WorldSettings.cpp b/Engine/Source/Runtime/Engine/Private/WorldSettings.cpp index d3da4ca20783..6a7ec4cf5ff9 100644 --- a/Engine/Source/Runtime/Engine/Private/WorldSettings.cpp +++ b/Engine/Source/Runtime/Engine/Private/WorldSettings.cpp @@ -491,6 +491,12 @@ void AWorldSettings::CheckForErrors() Super::CheckForErrors(); UWorld* World = GetWorld(); + // World is nullptr if save is done from a derived AWorldSettings blueprint + if (World == nullptr) + { + return; + } + if ( World->GetWorldSettings() != this ) { FMessageLog("MapCheck").Warning() diff --git a/Engine/Source/Runtime/Engine/Public/EngineStats.h b/Engine/Source/Runtime/Engine/Public/EngineStats.h index 012129248223..b1b4b91beec7 100644 --- a/Engine/Source/Runtime/Engine/Public/EngineStats.h +++ b/Engine/Source/Runtime/Engine/Public/EngineStats.h @@ -114,6 +114,8 @@ DECLARE_CYCLE_STAT_EXTERN(TEXT("Sync queries"),STAT_Navigation_QueriesTimeSync,S DECLARE_CYCLE_STAT_EXTERN(TEXT("Sync meta nav area preparation"),STAT_Navigation_MetaAreaTranslation,STATGROUP_Navigation, ); DECLARE_CYCLE_STAT_EXTERN(TEXT("Async nav areas sorting"),STAT_Navigation_TileNavAreaSorting,STATGROUP_Navigation, ); DECLARE_DWORD_COUNTER_STAT_EXTERN(TEXT("Num update nav octree"),STAT_Navigation_UpdateNavOctree,STATGROUP_Navigation, ); +DECLARE_CYCLE_STAT_EXTERN(TEXT("Registering Nav Octree Element"), STAT_Navigation_RegisterNavOctreeElement, STATGROUP_Navigation, ); +DECLARE_CYCLE_STAT_EXTERN(TEXT("Unregistering Nav Octree Element"), STAT_Navigation_UnregisterNavOctreeElement, STATGROUP_Navigation, ) DECLARE_CYCLE_STAT_EXTERN(TEXT("Adding actors to navoctree"),STAT_Navigation_AddingActorsToNavOctree,STATGROUP_Navigation, ); DECLARE_CYCLE_STAT_EXTERN(TEXT("Adjusting nav links"),STAT_Navigation_AdjustingNavLinks,STATGROUP_Navigation, ); DECLARE_CYCLE_STAT_EXTERN(TEXT("Recast: sync add generated tiles"), STAT_Navigation_RecastAddGeneratedTiles,STATGROUP_Navigation, ); diff --git a/Engine/Source/Runtime/Engine/Public/PreviewScene.h b/Engine/Source/Runtime/Engine/Public/PreviewScene.h index 138a057cfb8c..f31cbcbb32d4 100644 --- a/Engine/Source/Runtime/Engine/Public/PreviewScene.h +++ b/Engine/Source/Runtime/Engine/Public/PreviewScene.h @@ -24,6 +24,7 @@ public: : LightRotation(-40.f,-67.5f,0.f) , SkyBrightness(1.0f) , LightBrightness(PI) + , bDefaultLighting(true) , bAllowAudioPlayback(false) , bForceMipsResident(true) , bCreatePhysicsScene(true) @@ -36,22 +37,29 @@ public: FRotator LightRotation; float SkyBrightness; float LightBrightness; + uint32 bDefaultLighting : 1; uint32 bAllowAudioPlayback:1; uint32 bForceMipsResident:1; uint32 bCreatePhysicsScene:1; uint32 bShouldSimulatePhysics:1; uint32 bTransactional:1; uint32 bEditor:1; - + + TSubclassOf DefaultGameMode; + + ConstructionValues& SetCreateDefaultLighting(const bool bDefault) { bDefaultLighting = bDefault; return *this; } ConstructionValues& SetLightRotation(const FRotator& Rotation) { LightRotation = Rotation; return *this; } ConstructionValues& SetSkyBrightness(const float Brightness) { SkyBrightness = Brightness; return *this; } ConstructionValues& SetLightBrightness(const float Brightness) { LightBrightness = Brightness; return *this; } + ConstructionValues& AllowAudioPlayback(const bool bAllow) { bAllowAudioPlayback = bAllow; return *this; } ConstructionValues& SetForceMipsResident(const bool bForce) { bForceMipsResident = bForce; return *this; } ConstructionValues& SetCreatePhysicsScene(const bool bCreate) { bCreatePhysicsScene = bCreate; return *this; } ConstructionValues& ShouldSimulatePhysics(const bool bInShouldSimulatePhysics) { bShouldSimulatePhysics = bInShouldSimulatePhysics; return *this; } ConstructionValues& SetTransactional(const bool bInTransactional) { bTransactional = bInTransactional; return *this; } ConstructionValues& SetEditor(const bool bInEditor) { bEditor = bInEditor; return *this; } + + ConstructionValues& SetDefaultGameMode(TSubclassOf GameMode) { DefaultGameMode = GameMode; return *this; } }; // for physical correct light computations we multiply diffuse and specular lights by PI (see LABEL_RealEnergy) diff --git a/Engine/Source/Runtime/Engine/Public/VideoRecordingSystem.h b/Engine/Source/Runtime/Engine/Public/VideoRecordingSystem.h index 83e88a2af47a..50b6281b5304 100644 --- a/Engine/Source/Runtime/Engine/Public/VideoRecordingSystem.h +++ b/Engine/Source/Runtime/Engine/Public/VideoRecordingSystem.h @@ -15,6 +15,13 @@ DECLARE_CYCLE_STAT_EXTERN(TEXT("StartRecording"), STAT_VideoRecordingSystem_Star DECLARE_CYCLE_STAT_EXTERN(TEXT("PauseRecording"), STAT_VideoRecordingSystem_PauseRecording, STATGROUP_VideoRecordingSystem, ); DECLARE_CYCLE_STAT_EXTERN(TEXT("FinalizeRecording"), STAT_VideoRecordingSystem_FinalizeRecording, STATGROUP_VideoRecordingSystem, ); +#define DEFINE_VIDEOSYSTEMRECORDING_STATS \ + DEFINE_STAT(STAT_VideoRecordingSystem_EnableRecording); \ + DEFINE_STAT(STAT_VideoRecordingSystem_NewRecording); \ + DEFINE_STAT(STAT_VideoRecordingSystem_StartRecording); \ + DEFINE_STAT(STAT_VideoRecordingSystem_PauseRecording); \ + DEFINE_STAT(STAT_VideoRecordingSystem_FinalizeRecording); + class Error; /** Represents the state of the video recorder */ diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/GameplayMediaEncoder.Build.cs b/Engine/Source/Runtime/GameplayMediaEncoder/GameplayMediaEncoder.Build.cs new file mode 100644 index 000000000000..cda10230afd8 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/GameplayMediaEncoder.Build.cs @@ -0,0 +1,45 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +using System.IO; +using UnrealBuildTool; + +[SupportedPlatforms(UnrealTargetPlatform.Win32, UnrealTargetPlatform.Win64)] +public class GameplayMediaEncoder : ModuleRules +{ + public GameplayMediaEncoder(ReadOnlyTargetRules Target) : base(Target) + { + // NOTE: General rule is not to access the private folder of another module, + // but to use the ISubmixBufferListener interface, we need to include some private headers + PrivateIncludePaths.Add(System.IO.Path.Combine(Directory.GetCurrentDirectory(), "./Runtime/AudioMixer/Private")); + + PrivateDependencyModuleNames.AddRange(new string[] + { + "Core", + "Engine", + "CoreUObject", + "ApplicationCore", + "RenderCore", + "RHI", + "SlateCore", + "Slate", + "HTTP", + "Json", + //"IBMRTMPIngest" + }); + + if (Target.Platform == UnrealTargetPlatform.Win32 || Target.Platform == UnrealTargetPlatform.Win64) + { + PrivateDependencyModuleNames.AddRange(new string[] + { + "D3D11RHI" + }); + + PublicDelayLoadDLLs.Add("mfplat.dll"); + PublicDelayLoadDLLs.Add("mfuuid.dll"); + PublicDelayLoadDLLs.Add("Mfreadwrite.dll"); + + PublicAdditionalLibraries.Add("d3d11.lib"); + } + } +} + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/BaseVideoEncoder.cpp b/Engine/Source/Runtime/GameplayMediaEncoder/Private/BaseVideoEncoder.cpp new file mode 100644 index 000000000000..cc6df005e792 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/BaseVideoEncoder.cpp @@ -0,0 +1,55 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "BaseVideoEncoder.h" + +GAMEPLAYMEDIAENCODER_START + +FBaseVideoEncoder::FBaseVideoEncoder(const FOutputSampleCallback& OutputCallback) + : OutputCallback(OutputCallback) +{ +} + +bool FBaseVideoEncoder::GetOutputType(TRefCountPtr& OutType) +{ + OutType = OutputType; + return true; +} + +bool FBaseVideoEncoder::Initialize(const FVideoEncoderConfig& InConfig) +{ + UE_LOG(GameplayMediaEncoder, Log, TEXT("VideoEncoder config: %dx%d, %d FPS, %.2f Mbps"), InConfig.Width, InConfig.Height, InConfig.Framerate, InConfig.Bitrate / 1000000.0f); + + CHECK_HR(MFCreateMediaType(OutputType.GetInitReference())); + CHECK_HR(OutputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)); + CHECK_HR(OutputType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264)); + CHECK_HR(OutputType->SetUINT32(MF_MT_AVG_BITRATE, InConfig.Bitrate)); + CHECK_HR(MFSetAttributeRatio(OutputType, MF_MT_FRAME_RATE, InConfig.Framerate, 1)); + CHECK_HR(MFSetAttributeSize(OutputType, MF_MT_FRAME_SIZE, InConfig.Width, InConfig.Height)); + CHECK_HR(MFSetAttributeRatio(OutputType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1)); + CHECK_HR(OutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive)); + Config = InConfig; + return true; +} + +bool FBaseVideoEncoder::SetBitrate(uint32 Bitrate) +{ + check(IsInRenderingThread()); // encoders apply these changes immediately and not thread-safely + + CHECK_HR(OutputType->SetUINT32(MF_MT_AVG_BITRATE, Bitrate)); + Config.Bitrate = Bitrate; + + return true; +} + +bool FBaseVideoEncoder::SetFramerate(uint32 Framerate) +{ + check(IsInRenderingThread()); // encoders apply these changes immediately and not thread-safely + + CHECK_HR(MFSetAttributeRatio(OutputType, MF_MT_FRAME_RATE, Framerate, 1)); + Config.Framerate = Framerate; + + return true; +} + +GAMEPLAYMEDIAENCODER_END + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/BaseVideoEncoder.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/BaseVideoEncoder.h new file mode 100644 index 000000000000..8f231b8f59d3 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/BaseVideoEncoder.h @@ -0,0 +1,56 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "GameplayMediaEncoderSample.h" +#include "GameplayMediaEncoderCommon.h" + +struct FVideoEncoderConfig +{ + uint32 Width; + uint32 Height; + uint32 Framerate; + uint32 Bitrate; + + FVideoEncoderConfig() + : Width(0) + , Height(0) + , Framerate(0) + , Bitrate(0) + {} +}; + +class FBaseVideoEncoder +{ +public: + using FOutputSampleCallback = TFunction; + + explicit FBaseVideoEncoder(const FOutputSampleCallback& OutputCallback); + virtual ~FBaseVideoEncoder() {} + + const FVideoEncoderConfig& GetConfig() const + { return Config; } + + virtual bool Initialize(const FVideoEncoderConfig& Config); + bool GetOutputType(TRefCountPtr& OutType); + virtual bool Process(const FTexture2DRHIRef& Texture, FTimespan Timestamp, FTimespan Duration) = 0; + + // is called from same thread as `Process()` + // dynamically changes bitrate in runtime to adjust to available bandwidth + virtual bool SetBitrate(uint32 Bitrate) = 0; // has impl despite being "pure" + + // is called from same thread as `Process()` + // dynamically changes framerate in runtime to adjust to available bandwidth + virtual bool SetFramerate(uint32 Framerate) = 0; // has impl despite being "pure" + + virtual bool Start() = 0; + virtual void Stop() = 0; +protected: + FOutputSampleCallback OutputCallback; + FVideoEncoderConfig Config; + TRefCountPtr OutputType; + uint64 InputCount = 0; + uint64 OutputCount = 0; +}; + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoder.cpp b/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoder.cpp new file mode 100644 index 000000000000..8971fd4f2241 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoder.cpp @@ -0,0 +1,494 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "GameplayMediaEncoder.h" +#include "Engine/GameEngine.h" +#include "HAL/IConsoleManager.h" +#include "Framework/Application/SlateApplication.h" +#include "Modules/ModuleManager.h" +#include "RendererInterface.h" +#include "ScreenRendering.h" +#include "ShaderCore.h" +#include "PipelineStateCache.h" +#include "ProfilingDebugging/CsvProfiler.h" +#include "IbmLiveStreaming.h" + +#if PLATFORM_WINDOWS || PLATFORM_XBOXONE + #include "Microsoft/WmfAudioEncoder.h" +#endif + +#if PLATFORM_WINDOWS + #include "Microsoft/Windows/EncoderDevice.h" + #include "Microsoft/Windows/NvVideoEncoder.h" + #include "Microsoft/Windows/WmfVideoEncoder.h" + #include "Microsoft/Windows/AmdAmfVideoEncoder.h" +#elif PLATFORM_XBOXONE + #include "Microsoft/XboxOne/XboxOneVideoEncoder.h" +#endif + +DEFINE_LOG_CATEGORY(GameplayMediaEncoder); +CSV_DEFINE_CATEGORY(GameplayMediaEncoder, true); + +// right now we support only 48KHz audio sample rate as it's the only config UE4 seems to output +// WMF AAC encoder supports also 44100Hz so its support can be easily added +const uint32 HardcodedAudioSamplerate = 48000; +// for now we downsample to stereo. WMF AAC encoder also supports 6 (5.1) channels +// so it can be added too +const uint32 HardcodedAudioNumChannels = 2; +// currently neither IVideoRecordingSystem neither HighlightFeature APIs allow to configure +// audio stream parameters +const uint32 HardcodedAudioBitrate = 24000; + +// currently neither IVideoRecordingSystem neither HighlightFeature APIs allow to configure +// video stream parameters +#if PLATFORM_WINDOWS +const uint32 HardcodedVideoFPS = 60; +#else +const uint32 HardcodedVideoFPS = 30; +#endif +const uint32 HardcodedVideoBitrate = 5000000; +const uint32 MinVideoBitrate = 1000000; +const uint32 MaxVideoBitrate = 20000000; +const uint32 MinVideoFPS = 10; +const uint32 MaxVideoFPS = 60; + +const uint32 MaxWidth = 1920; +const uint32 MaxHeight = 1080; + +GAMEPLAYMEDIAENCODER_START + +FAutoConsoleCommand GameplayMediaEncoderInitialize( + TEXT("GameplayMediaEncoder.Initialize"), + TEXT("Constructs the audio/video encoding objects. Does not start encoding"), + FConsoleCommandDelegate::CreateStatic(&FGameplayMediaEncoder::InitializeCmd) +); + +FAutoConsoleCommand GameplayMediaEncoderStart( + TEXT("GameplayMediaEncoder.Start"), + TEXT("Starts encoding"), + FConsoleCommandDelegate::CreateStatic(&FGameplayMediaEncoder::StartCmd) +); + +FAutoConsoleCommand GameplayMediaEncoderStop( + TEXT("GameplayMediaEncoder.Stop"), + TEXT("Stops encoding"), + FConsoleCommandDelegate::CreateStatic(&FGameplayMediaEncoder::StopCmd) +); + +FAutoConsoleCommand GameplayMediaEncoderShutdown( + TEXT("GameplayMediaEncoder.Shutdown"), + TEXT("Releases all systems."), + FConsoleCommandDelegate::CreateStatic(&FGameplayMediaEncoder::ShutdownCmd) +); + +////////////////////////////////////////////////////////////////////////// +// +// FGameplayMediaEncoder +// +////////////////////////////////////////////////////////////////////////// + +FGameplayMediaEncoder* FGameplayMediaEncoder::Get() +{ + static FGameplayMediaEncoder Singleton; + return &Singleton; +} + +FGameplayMediaEncoder::FGameplayMediaEncoder() +{ +#if PLATFORM_WINDOWS + EncoderDevice = MakeShared(); +#endif +} + +FGameplayMediaEncoder::~FGameplayMediaEncoder() +{ +} + +bool FGameplayMediaEncoder::RegisterListener(IGameplayMediaEncoderListener* Listener) +{ + check(IsInGameThread()); + FScopeLock Lock(&ListenersCS); + + if (Listeners.Num() == 0) + { + UE_LOG(GameplayMediaEncoder, Log, TEXT("Registering the first listener")); + if (!Start()) + { + return false; + } + } + + Listeners.AddUnique(Listener); + return true; +} + +void FGameplayMediaEncoder::UnregisterListener(IGameplayMediaEncoderListener* Listener) +{ + check(IsInGameThread()); + FScopeLock Lock(&ListenersCS); + + Listeners.Remove(Listener); + if (Listeners.Num() == 0) + { + UE_LOG(GameplayMediaEncoder, Log, TEXT("Unregistered the last listener")); + Stop(); + } +} + +bool FGameplayMediaEncoder::GetAudioOutputType(TRefCountPtr& OutType) +{ + return AudioEncoder ? AudioEncoder->GetOutputType(OutType) : false; +} + +bool FGameplayMediaEncoder::GetVideoOutputType(TRefCountPtr& OutType) +{ + return VideoEncoder ? VideoEncoder->GetOutputType(OutType) : false; +} + +bool FGameplayMediaEncoder::Initialize() +{ + MemoryCheckpoint("Initial"); + + if (VideoEncoder) + { + UE_LOG(GameplayMediaEncoder, Log, TEXT("Already initialized")); + return true; + } + + auto OnMediaSampleReadyCallback = [this](const FGameplayMediaEncoderSample& Sample) + { + return OnMediaSampleReady(Sample); + }; + + // + // Audio + // + AudioEncoder.Reset(new FWmfAudioEncoder(OnMediaSampleReadyCallback)); + FWmfAudioEncoderConfig AudioConfig; + AudioConfig.SampleRate = HardcodedAudioSamplerate; + AudioConfig.NumChannels = HardcodedAudioNumChannels; + AudioConfig.Bitrate = HardcodedAudioBitrate; + if (!AudioEncoder->Initialize(AudioConfig)) + { + Stop(); + return false; + } + + bAudioFormatChecked = false; + MemoryCheckpoint("Audio encoder initialized"); + + // + // Video + // + FVideoEncoderConfig VideoConfig; + + FParse::Value(FCommandLine::Get(), TEXT("GameplayMediaEncoder.ResY="), VideoConfig.Height); + if (VideoConfig.Height == 0 || VideoConfig.Height == 720) + { + VideoConfig.Width = 1280; + VideoConfig.Height = 720; + } + else if (VideoConfig.Height == 1080) + { + VideoConfig.Width = 1920; + VideoConfig.Height = 1080; + } + else + { + UE_LOG(GameplayMediaEncoder, Fatal, TEXT("GameplayMediaEncoder.ResY can only have a value of 720 or 1080")); + return false; + } + + // Specifying 0 will completely disable frame skipping (therefore encoding as many frames as possible) + VideoConfig.Framerate = HardcodedAudioSamplerate; + FParse::Value(FCommandLine::Get(), TEXT("GameplayMediaEncoder.FPS="), VideoConfig.Framerate); + if (VideoConfig.Framerate == 0) + { + // Note : When disabling frame skipping, we lie to the encoder when initializing. + // We still specify a framerate, but then feed frames without skipping + VideoConfig.Framerate = HardcodedVideoFPS; + bDoFrameSkipping = false; + UE_LOG(GameplayMediaEncoder, Log, TEXT("Uncapping FPS")); + } + else + { + VideoConfig.Framerate = FMath::Clamp(VideoConfig.Framerate, (uint32)MinVideoFPS, (uint32)MaxVideoFPS); + bDoFrameSkipping = true; + UE_LOG(GameplayMediaEncoder, Log, TEXT("Capping FPS %u"), VideoConfig.Framerate); + } + + VideoConfig.Bitrate = HardcodedVideoBitrate; + FParse::Value(FCommandLine::Get(), TEXT("GameplayMediaEncoder.Bitrate="), VideoConfig.Bitrate); + VideoConfig.Bitrate = FMath::Clamp(VideoConfig.Bitrate, (uint32)MinVideoBitrate, (uint32)MaxVideoBitrate); + + UE_LOG(GameplayMediaEncoder, Log, TEXT("Using a config of {Width=%u, Height=%u, Framerate=%u, Bitrate=%u}"), VideoConfig.Width, VideoConfig.Height, VideoConfig.Framerate, VideoConfig.Bitrate); + + // + // Try to initialize the best encoder for the current platform + // +#if PLATFORM_WINDOWS + VideoEncoder.Reset(new FNvVideoEncoder(OnMediaSampleReadyCallback, EncoderDevice)); + if (!VideoEncoder->Initialize(VideoConfig)) + { + VideoEncoder.Reset(new FAmdAmfVideoEncoder(OnMediaSampleReadyCallback)); + if (!VideoEncoder->Initialize(VideoConfig)) + { + VideoEncoder.Reset(new FWmfVideoEncoder(OnMediaSampleReadyCallback)); + if (!VideoEncoder->Initialize(VideoConfig)) + { + Stop(); + return false; + } + } + } +#elif PLATFORM_XBOXONE + VideoEncoder.Reset(new FXboxOneVideoEncoder(OnMediaSampleReadyCallback)); + verify(VideoEncoder->Initialize(VideoConfig)); +#endif + + StartTime = 0; + + MemoryCheckpoint("Video encoder initialized"); + + return true; +} + +bool FGameplayMediaEncoder::Start() +{ + // Initialize if not initialized + if (!VideoEncoder) + { + if (!Initialize()) + return false; + } + + if (StartTime != 0) + { + UE_LOG(GameplayMediaEncoder, Log, TEXT("Already running")); + return true; + } + + if (!VideoEncoder) + { + UE_LOG(GameplayMediaEncoder, Log, TEXT("Not initialized yet , so also performing a Intialize()")); + if (!Initialize()) + { + return false; + } + } + + StartTime = FTimespan::FromSeconds(FPlatformTime::Seconds()); + LastAudioInputTimestamp = LastVideoInputTimestamp = GetMediaTimestamp(); + NumCapturedFrames = 0; + + // + // subscribe to engine delegates for audio output and back buffer + // + if (UGameEngine* GameEngine = Cast(GEngine)) + { + FAudioDevice* AudioDevice = GameEngine->GetMainAudioDevice(); + if (AudioDevice) + { + AudioDevice->RegisterSubmixBufferListener(this); + } + + VideoEncoder->Start(); + FSlateRenderer::FOnBackBufferReadyToPresent OnBackBufferReadyDelegate; + OnBackBufferReadyDelegate.BindRaw(this, &FGameplayMediaEncoder::OnBackBufferReady); + FSlateApplication::Get().GetRenderer()->OnBackBufferReadyToPresent() = OnBackBufferReadyDelegate; + } + + return true; +} + +void FGameplayMediaEncoder::Stop() +{ + check(IsInGameThread()); + + if (StartTime == 0) + { + UE_LOG(GameplayMediaEncoder, Log, TEXT("Not running")); + return; + } + + if (UGameEngine* GameEngine = Cast(GEngine)) + { + FAudioDevice* AudioDevice = GameEngine->GetMainAudioDevice(); + if (AudioDevice) + { + AudioDevice->UnregisterSubmixBufferListener(this); + } + + if (FSlateApplication::IsInitialized()) + { + FSlateApplication::Get().GetRenderer()->OnBackBufferReadyToPresent().Unbind(); + } + } + + VideoEncoder->Stop(); + StartTime = 0; +} + +void FGameplayMediaEncoder::Shutdown() +{ + if (StartTime != 0) + { + UE_LOG(GameplayMediaEncoder, Log, TEXT("Currently running, so also performing a Stop()")); + Stop(); + } + + { + FScopeLock Lock(&AudioProcessingCS); + AudioEncoder.Reset(); + } + { + FScopeLock Lock(&VideoProcessingCS); + VideoEncoder.Reset(); + } +} + +bool FGameplayMediaEncoder::OnMediaSampleReady(const FGameplayMediaEncoderSample& Sample) +{ + FScopeLock ProcessMediaSamplesLock(&ProcessMediaSamplesCS); + if (bProcessMediaSamples) + { + FScopeLock Lock(&ListenersCS); + + for (auto&& Listener : Listeners) + { + Listener->OnMediaSample(Sample); + } + } + + return true; +} + +FTimespan FGameplayMediaEncoder::GetMediaTimestamp() const +{ + return FTimespan::FromSeconds(FPlatformTime::Seconds()) - StartTime; +} + +void FGameplayMediaEncoder::OnNewSubmixBuffer(const USoundSubmix* OwningSubmix, float* AudioData, int32 NumSamples, int32 NumChannels, const int32 SampleRate, double AudioClock) +{ + CSV_SCOPED_TIMING_STAT(GameplayMediaEncoder, OnNewSubmixBuffer); + if (SampleRate != HardcodedAudioSamplerate) + { + // Only report the problem once + if (!bAudioFormatChecked) + { + bAudioFormatChecked = true; + UE_LOG(GameplayMediaEncoder, Error, TEXT("Audio SampleRate needs to be %d HZ, current value is %d. VideoRecordingSystem won't record audio"), HardcodedAudioSamplerate, SampleRate); + } + return; + } + + ProcessAudioFrame(AudioData, NumSamples, NumChannels, SampleRate); +} + +void FGameplayMediaEncoder::OnBackBufferReady(const FTexture2DRHIRef& BackBuffer) +{ + CSV_SCOPED_TIMING_STAT(GameplayMediaEncoder, OnBackBufferReady); + check(IsInRenderingThread()); + ProcessVideoFrame(BackBuffer); +} + +bool FGameplayMediaEncoder::ProcessAudioFrame(const float* AudioData, int32 NumSamples, int32 NumChannels, int32 SampleRate) +{ + Audio::AlignedFloatBuffer InData; + InData.Append(AudioData, NumSamples); + Audio::TSampleBuffer FloatBuffer(InData, NumChannels, SampleRate); + + // Mix to stereo if required, since PixelStreaming only accept stereo at the moment + if (FloatBuffer.GetNumChannels() != HardcodedAudioNumChannels) + { + FloatBuffer.MixBufferToChannels(HardcodedAudioNumChannels); + } + + PCM16 = FloatBuffer; + + { + FScopeLock Lock(&AudioProcessingCS); + + FTimespan Timestamp = GetMediaTimestamp(); + FTimespan Duration = Timestamp - LastAudioInputTimestamp; + LastAudioInputTimestamp = Timestamp; + AudioEncoder->Process(reinterpret_cast(PCM16.GetData()), PCM16.GetNumSamples() * sizeof(*PCM16.GetData()), Timestamp, Duration); + } + + return true; +} + +bool FGameplayMediaEncoder::ProcessVideoFrame(const FTexture2DRHIRef& BackBuffer) +{ + FScopeLock Lock(&VideoProcessingCS); + + FTimespan Now = GetMediaTimestamp(); + + if (bDoFrameSkipping) + { + uint64 NumExpectedFrames = static_cast(Now.GetTotalSeconds() * VideoEncoder->GetConfig().Framerate); + UE_LOG(GameplayMediaEncoder, VeryVerbose, TEXT("time %.3f: captured %d, expected %d"), Now.GetTotalSeconds(), NumCapturedFrames + 1, NumExpectedFrames); + if (NumCapturedFrames + 1 > NumExpectedFrames) + { + UE_LOG(GameplayMediaEncoder, Verbose, TEXT("Framerate control dropped captured frame")); + return true; + } + } + + if (!ChangeVideoConfig()) + { + return false; + } + + FTimespan Duration = Now - LastVideoInputTimestamp; + if (!VideoEncoder->Process(BackBuffer, Now, Duration)) + { + return false; + } + + LastVideoInputTimestamp = Now; + NumCapturedFrames++; + return true; +} + +void FGameplayMediaEncoder::SetVideoBitrate(uint32 Bitrate) +{ + NewVideoBitrate = Bitrate; + bChangeBitrate = true; +} + +void FGameplayMediaEncoder::SetVideoFramerate(uint32 Framerate) +{ + NewVideoFramerate = FMath::Clamp(Framerate, MinVideoFPS, MaxVideoFPS); + bChangeFramerate = true; +} + +bool FGameplayMediaEncoder::ChangeVideoConfig() +{ + if (bChangeBitrate) + { + if (!VideoEncoder->SetBitrate(NewVideoBitrate)) + { + return false; + } + bChangeBitrate = false; + } + + if (bChangeFramerate) + { + UE_LOG(GameplayMediaEncoder, Verbose, TEXT("framerate -> %d"), NewVideoFramerate.Load()); + + if (!VideoEncoder->SetFramerate(NewVideoFramerate)) + { + return false; + } + bChangeFramerate = false; + // reset framerate control + FramerateMonitoringStart = GetMediaTimestamp(); + NumCapturedFrames = 0; + } + + return true; +} + +GAMEPLAYMEDIAENCODER_END + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoderCommon.cpp b/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoderCommon.cpp new file mode 100644 index 000000000000..1e86a45be766 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoderCommon.cpp @@ -0,0 +1,82 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "GameplayMediaEncoderCommon.h" +#include "RHI.h" + +#if WMFMEDIA_SUPPORTED_PLATFORM + #pragma comment(lib, "mfplat") + #pragma comment(lib, "mfuuid") + #pragma comment(lib, "Mfreadwrite") +#endif + +GAMEPLAYMEDIAENCODER_START + +// +// Windows only code +// +#if PLATFORM_WINDOWS +ID3D11Device* GetUE4DxDevice() +{ + auto Device = static_cast(GDynamicRHI->RHIGetNativeDevice()); + checkf(Device != nullptr, TEXT("Failed to get UE4's ID3D11Device")); + return Device; +} +#endif + +// +// XboxOne only code +// +#if PLATFORM_XBOXONE +ID3D12Device* GetUE4DxDevice() +{ + auto Device = static_cast(GDynamicRHI->RHIGetNativeDevice()); + checkf(Device != nullptr, TEXT("Failed to get UE4's ID3D12Device")); + return Device; +} + +#endif + + +// #RVF : Remove these once the code is production ready +TArray gMemoryCheckpoints; +uint64 MemoryCheckpoint(const FString& Name) +{ +#if PLATFORM_WINDOWS + return 0; +#else + TITLEMEMORYSTATUS TitleStatus; + TitleStatus.dwLength = sizeof(TitleStatus); + TitleMemoryStatus(&TitleStatus); + + static uint64 PeakMemory = 0; + + FMemoryCheckpoint Check; + Check.Name = Name; + uint64_t UsedPhysical = TitleStatus.ullLegacyUsed + TitleStatus.ullTitleUsed; + static uint64_t FirstUsedPhysical = UsedPhysical; + + Check.UsedPhysicalMB = UsedPhysical / double(1024 * 1024); + Check.DeltaMB = 0; + Check.AccumulatedMB = (UsedPhysical - FirstUsedPhysical) / double(1024 * 1024); + if (gMemoryCheckpoints.Num()) + { + Check.DeltaMB = Check.UsedPhysicalMB - gMemoryCheckpoints.Last().UsedPhysicalMB; + } + gMemoryCheckpoints.Add(Check); + return UsedPhysical; +#endif +} + +void LogMemoryCheckpoints(const FString& Name) +{ + UE_LOG(GameplayMediaEncoder, Log, TEXT("Memory breakdown: %s..."), *Name); + for (const FMemoryCheckpoint& a : gMemoryCheckpoints) + { + UE_LOG(GameplayMediaEncoder, Log, TEXT("%s: UsedPhysicalMB=%4.3f, DeltaMB=%4.3f, AccumulatedMB=%4.3f"), + *a.Name, a.UsedPhysicalMB, a.DeltaMB, a.AccumulatedMB); + } +} + + +GAMEPLAYMEDIAENCODER_END + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoderCommon.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoderCommon.h new file mode 100644 index 000000000000..9dde15938617 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoderCommon.h @@ -0,0 +1,318 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Stats/Stats.h" +#include "Logging/LogMacros.h" +#include "RHIStaticStates.h" +#include "HAL/ThreadSafeBool.h" +#include "HAL/ThreadSafeCounter.h" +#include "HAL/Runnable.h" +#include "HAL/RunnableThread.h" +#include "HAL/Event.h" +#include "Misc/ScopeExit.h" +#include "ShaderCore.h" +#include "ProfilingDebugging/CsvProfiler.h" +#include "RHI.h" +#include "RHIResources.h" + +// +// Macros to control some things during development +// #RVF : Remove this when cleaning up +// +#define WRITE_TO_FILE 0 +#define LIVESTREAMING 0 + +#if UE_BUILD_SHIPPING + #define GAMEPLAYMEDIAENCODER_DEBUG 0 +#else + #define GAMEPLAYMEDIAENCODER_DEBUG 0 +#endif + +// +// Includes common to Windows and XboxOne +// +#if PLATFORM_WINDOWS || PLATFORM_XBOXONE + #include "Templates/RefCounting.h" +#endif + +// +// Windows only include +// +#if PLATFORM_WINDOWS + + #include "Windows/AllowWindowsPlatformTypes.h" + #include "Windows/PreWindowsApi.h" + #include + #include + #include + #include + #include + #include + #include + #include + #include "Windows/PostWindowsApi.h" + #include "Windows/HideWindowsPlatformTypes.h" + + #include "D3D11State.h" + #include "D3D11Resources.h" +#endif + +// +// XboxOne only includes +// +#if PLATFORM_XBOXONE + +#include "XboxOne/XboxOneAllowPlatformTypes.h" +#include "XboxOne/XboxOnePreApi.h" + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include +#include "XboxOne/XboxOnePostApi.h" +#include "XboxOne/XboxOneHidePlatformTypes.h" + +#endif + +#if GAMEPLAYMEDIAENCODER_DEBUG + #define GAMEPLAYMEDIAENCODER_START PRAGMA_DISABLE_OPTIMIZATION + #define GAMEPLAYMEDIAENCODER_END PRAGMA_ENABLE_OPTIMIZATION +#else + #define GAMEPLAYMEDIAENCODER_START + #define GAMEPLAYMEDIAENCODER_END +#endif + +#define WMFMEDIA_SUPPORTED_PLATFORM (PLATFORM_WINDOWS && (WINVER >= 0x0600 /*Vista*/) && !UE_SERVER) + +DECLARE_LOG_CATEGORY_EXTERN(GameplayMediaEncoder, Log, VeryVerbose); + +// +// Windows and XboxOne common code/macros +// +#if PLATFORM_WINDOWS || PLATFORM_XBOXONE + +inline const FString GetComErrorDescription(HRESULT Res) +{ + const uint32 BufSize = 4096; + WIDECHAR buffer[4096]; + if (::FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, + nullptr, + Res, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), + buffer, + sizeof(buffer) / sizeof(*buffer), + nullptr)) + { + return buffer; + } + else + { + return TEXT("[cannot find error description]"); + } +} + +#if PLATFORM_WINDOWS + #include "Windows/AllowWindowsPlatformTypes.h" +#elif PLATFORM_XBOXONE + #include "XboxOne/XboxOneAllowPlatformTypes.h" +#endif + +// macro to deal with COM calls inside a function that returns `false` on error +#define CHECK_HR(COM_call)\ + {\ + HRESULT Res = COM_call;\ + if (FAILED(Res))\ + {\ + UE_LOG(GameplayMediaEncoder, Error, TEXT("`" #COM_call "` failed: 0x%X - %s"), Res, *GetComErrorDescription(Res));\ + return false;\ + }\ + } + +// macro to deal with COM calls inside COM method (that returns HRESULT) +#define CHECK_HR_COM(COM_call)\ + {\ + HRESULT Res = COM_call;\ + if (FAILED(Res))\ + {\ + UE_LOG(GameplayMediaEncoder, Error, TEXT("`" #COM_call "` failed: 0x%X - %s"), Res, *GetComErrorDescription(Res));\ + return Res;\ + }\ + } + +// macro to deal with COM calls inside COM method (that simply returns) +#define CHECK_HR_VOID(COM_call)\ + {\ + HRESULT Res = COM_call;\ + if (FAILED(Res))\ + {\ + UE_LOG(GameplayMediaEncoder, Error, TEXT("`" #COM_call "` failed: 0x%X - %s"), Res, *GetComErrorDescription(Res));\ + return;\ + }\ + } + +#if PLATFORM_WINDOWS + #include "Windows/HideWindowsPlatformTypes.h" +#elif PLATFORM_XBOXONE + #include "XboxOne/XboxOneHidePlatformTypes.h" +#endif + +// following commented include causes name clash between UE4 and Windows `IMediaEventSink`, +// we just need a couple of GUIDs from there so the solution is to duplicate them below +//#include "wmcodecdsp.h" + +const GUID CLSID_AACMFTEncoder = { 0x93AF0C51, 0x2275, 0x45d2, { 0xA3, 0x5B, 0xF2, 0xBA, 0x21, 0xCA, 0xED, 0x00 } }; +const GUID CLSID_CMSH264EncoderMFT = { 0x6ca50344, 0x051a, 0x4ded, { 0x97, 0x79, 0xa4, 0x33, 0x05, 0x16, 0x5e, 0x35 } }; +const GUID CLSID_VideoProcessorMFT = { 0x88753b26, 0x5b24, 0x49bd, { 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 0xc9, 0x82 } }; + +// `MF_LOW_LATENCY` is defined in "mfapi.h" for >= WIN8 +// UE4 supports lower Windows versions at the moment and so `WINVER` is < `_WIN32_WINNT_WIN8` +// to be able to use `MF_LOW_LATENCY` with default UE4 build we define it ourselves and check actual +// Windows version in runtime +#if (WINVER < _WIN32_WINNT_WIN8) + const GUID MF_LOW_LATENCY = { 0x9c27891a, 0xed7a, 0x40e1,{ 0x88, 0xe8, 0xb2, 0x27, 0x27, 0xa0, 0x24, 0xee } }; +#endif + + +#endif + +// +// Windows only utility code/macros +// +#if PLATFORM_WINDOWS + +ID3D11Device* GetUE4DxDevice(); + +// scope-disable particular DX11 Debug Layer errors +class FScopeDisabledDxDebugErrors final +{ +private: + +public: + FScopeDisabledDxDebugErrors(TArray&& ErrorsToDisable) + { + TRefCountPtr Debug; + HRESULT HRes = GetUE4DxDevice()->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast(Debug.GetInitReference())); + + if (HRes == E_NOINTERFACE) + { + // Debug Layer is not enabled, so no need to disable its errors + return; + } + + if (!SUCCEEDED(HRes) || + !SUCCEEDED(HRes = InfoQueue->QueryInterface(__uuidof(ID3D11InfoQueue), reinterpret_cast(Debug.GetInitReference())))) + { + UE_LOG(GameplayMediaEncoder, VeryVerbose, TEXT("Failed to get ID3D11InfoQueue: 0x%X - %s"), HRes, *GetComErrorDescription(HRes)); + return; + } + + D3D11_INFO_QUEUE_FILTER filter = {}; + filter.DenyList.NumIDs = ErrorsToDisable.Num(); + filter.DenyList.pIDList = ErrorsToDisable.GetData(); + bSucceeded = SUCCEEDED(InfoQueue->PushStorageFilter(&filter)); + } + + ~FScopeDisabledDxDebugErrors() + { + if (bSucceeded) + { + InfoQueue->PopStorageFilter(); + } + } + +private: + TRefCountPtr InfoQueue; + bool bSucceeded = false; +}; + + +#endif + +// +// XboxOne only utility code/macros +// +#if PLATFORM_XBOXONE + +ID3D12Device* GetUE4DxDevice(); + +#endif + +class FThread final : public FRunnable +{ +public: + using FCallback = TFunction; + + explicit FThread(TCHAR const* ThreadName, const FCallback& Callback) : + Callback(Callback) + { + Thread.Reset(FRunnableThread::Create(this, ThreadName, TPri_BelowNormal)); + } + + void Join() + { + Thread->WaitForCompletion(); + } + + virtual uint32 Run() override + { + Callback(); + return 0; + } + +private: + FCallback Callback; + TUniquePtr Thread; + +private: + FThread(const FThread&) = delete; + FThread& operator=(const FThread&) = delete; +}; + + +template +inline void ExecuteRHICommand(F&& Functor) +{ + FRHICommandList& RHICmdList = FRHICommandListExecutor::GetImmediateCommandList(); + if (RHICmdList.Bypass()) + { + Functor(); + } + else + { + struct FLocalRHICommand final : public FRHICommand + { + F Functor; + + FLocalRHICommand(F InFunctor) + : Functor(MoveTemp(InFunctor)) + {} + + void Execute(FRHICommandListBase& CmdList) + { + Functor(); + } + }; + + new (RHICmdList.AllocCommand()) FLocalRHICommand(Functor); + } +} + +// #RVF : Remove this once the code is production ready. +struct FMemoryCheckpoint +{ + FString Name; + float UsedPhysicalMB; + float DeltaMB; + float AccumulatedMB; +}; +extern TArray gMemoryCheckpoints; +uint64 MemoryCheckpoint(const FString& Name); +void LogMemoryCheckpoints(const FString& Name); + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoderModule.cpp b/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoderModule.cpp new file mode 100644 index 000000000000..55560de0c90c --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoderModule.cpp @@ -0,0 +1,21 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "CoreMinimal.h" +#include "Modules/ModuleInterface.h" +#include "Modules/ModuleManager.h" +#include "GameplayMediaEncoderCommon.h" + +GAMEPLAYMEDIAENCODER_START + +class FGameplayMediaEncoderModule : public IModuleInterface +{ +public: + FGameplayMediaEncoderModule() + { + } + +}; + +IMPLEMENT_MODULE(FGameplayMediaEncoderModule, GameplayMediaEncoder); + +GAMEPLAYMEDIAENCODER_END diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoderSample.cpp b/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoderSample.cpp new file mode 100644 index 000000000000..fcb52e209eb1 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/GameplayMediaEncoderSample.cpp @@ -0,0 +1,107 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "GameplayMediaEncoderSample.h" +#include "GameplayMediaEncoderCommon.h" +#include "Misc/AssertionMacros.h" + +GAMEPLAYMEDIAENCODER_START + +namespace +{ + TRefCountPtr CloneMediaBuffer(const TRefCountPtr& Src) + { + uint8* SrcByteBuffer = nullptr; + DWORD SrcMaxLen = 0; + DWORD SrcCurrLen = 0; + verify(SUCCEEDED(Src->Lock(&SrcByteBuffer, &SrcMaxLen, &SrcCurrLen))); + + TRefCountPtr Dest; + verify(SUCCEEDED(MFCreateMemoryBuffer(SrcCurrLen, Dest.GetInitReference()))); + + uint8* DestByteBuffer = nullptr; + verify(SUCCEEDED(Dest->Lock(&DestByteBuffer, nullptr, nullptr))); + FMemory::Memcpy(DestByteBuffer, SrcByteBuffer, SrcCurrLen); + verify(SUCCEEDED(Dest->Unlock())); + verify(SUCCEEDED(Src->Unlock())); + + verify(SUCCEEDED(Dest->SetCurrentLength(SrcCurrLen))); + return Dest; + } +} + +bool FGameplayMediaEncoderSample::CreateSample() +{ + Sample = nullptr; + CHECK_HR(MFCreateSample(Sample.GetInitReference())); + return true; +} + +FTimespan FGameplayMediaEncoderSample::GetTime() const +{ + int64 Time; + HRESULT hr = Sample->GetSampleTime(&Time); + verifyf(SUCCEEDED(hr), TEXT("%s"), *GetComErrorDescription(hr)); + return Time; +} + +void FGameplayMediaEncoderSample::SetTime(FTimespan Time) +{ + verify(SUCCEEDED(Sample->SetSampleTime(Time.GetTicks()))); +} + +FTimespan FGameplayMediaEncoderSample::GetDuration() const +{ + int64 Duration; + HRESULT hr = Sample->GetSampleDuration(&Duration); + verifyf(SUCCEEDED(hr), TEXT("%s"), *GetComErrorDescription(hr)); + return Duration; +} + +void FGameplayMediaEncoderSample::SetDuration(FTimespan Duration) +{ + verify(SUCCEEDED(Sample->SetSampleDuration(Duration.GetTicks()))); +} + +bool FGameplayMediaEncoderSample::IsVideoKeyFrame() const +{ + return MediaType == EMediaType::Video && MFGetAttributeUINT32(Sample, MFSampleExtension_CleanPoint, 0) != 0; +} + +FGameplayMediaEncoderSample FGameplayMediaEncoderSample::Clone() const +{ + FGameplayMediaEncoderSample Res{ MediaType }; + if (!Sample) + { + return Res; + } + + verify(Res.CreateSample()); + + DWORD Flags = 0; + verify(SUCCEEDED(Sample->GetSampleFlags(&Flags))); + verify(SUCCEEDED(Res.GetSample()->SetSampleFlags(Flags))); + + Res.SetTime(GetTime()); + Res.SetDuration(GetDuration()); + + if (IsVideoKeyFrame()) + { + verify(SUCCEEDED(Res.GetSample()->SetUINT32(MFSampleExtension_CleanPoint, 1))); + } + + DWORD BufferCount = 0; + verify(SUCCEEDED(Sample->GetBufferCount(&BufferCount))); + + for (DWORD i = 0; i != BufferCount; ++i) + { + TRefCountPtr SrcBuf; + verify(SUCCEEDED(Sample->GetBufferByIndex(i, SrcBuf.GetInitReference()))); + + TRefCountPtr DestBuf = CloneMediaBuffer(SrcBuf); + verify(SUCCEEDED(Res.GetSample()->AddBuffer(DestBuf))); + } + + return Res; +} + +GAMEPLAYMEDIAENCODER_END diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/IbmLiveStreaming.cpp b/Engine/Source/Runtime/GameplayMediaEncoder/Private/IbmLiveStreaming.cpp new file mode 100644 index 000000000000..6c1ce106c9db --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/IbmLiveStreaming.cpp @@ -0,0 +1,1024 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "IbmLiveStreaming.h" + +#include "HttpModule.h" +#include "Interfaces/IHttpResponse.h" +#include "Serialization/JsonReader.h" +#include "Dom/JsonObject.h" +#include "Serialization/JsonSerializer.h" +#include "Misc/ScopeLock.h" +#include "VideoRecordingSystem.h" +#include "Algo/FindSequence.h" + +#if defined(WITH_IBMRTMPINGEST) && LIVESTREAMING + +DEFINE_LOG_CATEGORY(IbmLiveStreaming); + +GAMEPLAYMEDIAENCODER_START + +extern "C" +{ + // rtmp_c_static.lib needs us to define this symbol + char* build_number = "1"; +} + +// From IBM's sample +typedef enum _AACPacketType { + AACSequenceHeader, + AACRaw +} AACPacketType; + +FAutoConsoleCommand LiveStreamingStart( + TEXT("LiveStreaming.Start"), + TEXT("Starts live streaming gameplay to IBM Cloud Video"), + FConsoleCommandDelegate::CreateStatic(&FIbmLiveStreaming::StartCmd) +); + +FAutoConsoleCommand LiveStreamingStop( + TEXT("LiveStreaming.Stop"), + TEXT("Stops live streaming"), + FConsoleCommandDelegate::CreateStatic(&FIbmLiveStreaming::StopCmd) +); + +static TAutoConsoleVariable CVarLiveStreamingClientId( + TEXT("LiveStreaming.ClientId"), + TEXT("76898b5ebb31c697023fccb47a3e7a7eb6aacb83"), + TEXT("IBMCloudVideo ClientId to use for live streaming")); + +static TAutoConsoleVariable CVarLiveStreamingClientSecret( + TEXT("LiveStreaming.ClientSecret"), + TEXT("11b3d99c37f85943224d710f037f2c5e8c8fe673"), + TEXT("IBMCloudVideo ClientSecret to use for live streaming")); + +static TAutoConsoleVariable CVarLiveStreamingChannel( + TEXT("LiveStreaming.Channel"), + TEXT("23619107"), + TEXT("IBMCloudVideo Channel to use for live streaming")); + +static TAutoConsoleVariable CVarLiveStreamingMaxBitrate( + TEXT("LiveStreaming.MaxBitrate"), + 30, + TEXT("LiveStreaming: max allowed bitrate, in Mbps")); + +static TAutoConsoleVariable CVarLiveStreamingSpaceToEmptyQueue( + TEXT("LiveStreaming.SpaceToEmptyQueue"), + 0.8, + TEXT("LiveStreaming: factor to set bitrate a bit lower than available b/w to let IBMRTMP lib to empty the queue")); + +static TAutoConsoleVariable CVarLiveStreamingNonCongestedBitrateIncrease( + TEXT("LiveStreaming.NonCongestedBitrateIncrease"), + 1.2, + TEXT("LiveStreaming: rate of growth of non-congested bitrate")); + +static TAutoConsoleVariable CVarLiveStreamingBitrateThresholdToSwitchFPS( + TEXT("LiveStreaming.BitrateThresholdToSwitchFPS"), + 15, + TEXT("LiveStreaming: bitrate threshold to switch to lower FPS, in Mbps")); + +static TAutoConsoleVariable CVarLiveStreamingDownscaledFPS( + TEXT("LiveStreaming.DownscaledFPS"), + 30, + TEXT("LiveStreaming: framerate to switch if poor uplink is detected")); + +static TAutoConsoleVariable CVarLiveStreamingBitrateProximityTolerance( + TEXT("LiveStreaming.BitrateProximityTolerance"), + 1.2, + TEXT("LiveStreaming: How close should the bitrate be to the reported bandwidth, to be recognized as fulfilling the available bandwidth")); + +// +// FIbmLiveStreaming::FFormData +// + +FIbmLiveStreaming::FFormData::FFormData() +{ + // To understand the need of the Boundary string, see https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html + BoundaryLabel = FString(TEXT("e543322540af456f9a3773049ca02529-")) + FString::FromInt(FMath::Rand()); + BoundaryBegin = FString(TEXT("--")) + BoundaryLabel + FString(TEXT("\r\n")); + BoundaryEnd = FString(TEXT("\r\n--")) + BoundaryLabel + FString(TEXT("--\r\n")); +} + +void FIbmLiveStreaming::FFormData::AddField(const FString& Name, const FString& Value) +{ + Data += FString(TEXT("\r\n")) + + BoundaryBegin + + FString(TEXT("Content-Disposition: form-data; name=\"")) + + Name + + FString(TEXT("\"\r\n\r\n")) + + Value; +} + +// Convert FString to UTF8 and put it in a TArray +TArray FIbmLiveStreaming::FFormData::FStringToUint8(const FString& InString) +{ + TArray OutBytes; + + // Handle empty strings + if (InString.Len() > 0) + { + FTCHARToUTF8 Converted(*InString); // Convert to UTF8 + OutBytes.Append(reinterpret_cast(Converted.Get()), Converted.Length()); + } + + return OutBytes; +} + +TSharedRef FIbmLiveStreaming::FFormData::CreateHttpPostRequestImpl(const FString& URL) +{ + TSharedRef HttpRequest = FHttpModule::Get().CreateRequest(); + + TArray CombinedContent; + CombinedContent.Append(FStringToUint8(Data)); + //CombinedContent.Append(MultiPartContent); + CombinedContent.Append(FStringToUint8(BoundaryEnd)); + + HttpRequest->SetHeader(TEXT("Content-Type"), FString(TEXT("multipart/form-data; boundary=")) + BoundaryLabel); + HttpRequest->SetURL(URL); + HttpRequest->SetVerb(TEXT("POST")); + HttpRequest->SetContent(CombinedContent); + + return HttpRequest; +} + +// +// FIbmLiveStreaming +// + +FIbmLiveStreaming* FIbmLiveStreaming::Singleton = nullptr; + +FIbmLiveStreaming::FIbmLiveStreaming() +{ + // + // Create the RTMCData instance. + // Ideally, we should be using rtmp_c_getinstance to query if the internal RTMPCData instance was set, + // so thus initialize it or destroy it accordingly, but at the time of writing, rtmp_c_getinstance + // logs an error if the internal instance is not set, so we avoid using rtmp_c_getinstance to keep + // the logs clean. + UE_LOG(IbmLiveStreaming, Log, TEXT("Creating rtmpc object")); + RTMPCData* rtmp_c = rtmp_c_alloc(502, 1, 1, "Windows", "Windows device", TCHAR_TO_ANSI(*FGuid::NewGuid().ToString()), "en"); + check(rtmp_c); + rtmp_c->appFlavor = AppFlavorUstream; + rtmp_c_start(rtmp_c); +} + +FIbmLiveStreaming::~FIbmLiveStreaming() +{ + Stop(); + + RTMPCData* rtmp_c = rtmp_c_getinstance(); + check(rtmp_c); + UE_LOG(IbmLiveStreaming, Verbose, TEXT("Stopping rtmp_c instance")); + rtmp_c_stop(rtmp_c); + UE_LOG(IbmLiveStreaming, Verbose, TEXT("Freeing rtmp_c instance")); + rtmp_c_free(rtmp_c); +} + +FIbmLiveStreaming* FIbmLiveStreaming::Get() +{ + if (!Singleton) + { + Singleton = new FIbmLiveStreaming(); + } + + return Singleton; +} + +void FIbmLiveStreaming::CustomLogMsg(const char* Msg) +{ + FString FinalMsg(Msg); + // IBM RTMP Ingest appends a \n to the end of the string. We need to remove it so we don't have empty lines in our logs + FinalMsg.TrimEndInline(); + UE_LOG(IbmLiveStreaming, Verbose, TEXT("IBMRTMPIngest: %s"), *FinalMsg); +} + +bool FIbmLiveStreaming::CheckState(const wchar_t* FuncName, EState ExpectedState) +{ + if (State == ExpectedState) + { + return true; + } + else + { + UE_LOG(IbmLiveStreaming, Error, TEXT("%s: Wrong state (%d instead of %d)"), FuncName, static_cast(State.Load()), static_cast(ExpectedState)); + return false; + } +} + +bool FIbmLiveStreaming::CheckState(const wchar_t* FuncName, EState ExpectedStateMin, EState ExpectedStateMax) +{ + if (State >= ExpectedStateMin && State<=ExpectedStateMax) + { + return true; + } + else + { + UE_LOG(IbmLiveStreaming, Error, TEXT("%s: Wrong state (%d instead of [%d..%d])"), FuncName, static_cast(State.Load()), static_cast(ExpectedStateMin), static_cast(ExpectedStateMax)); + return false; + } +} + +bool FIbmLiveStreaming::Start() +{ + if (!CheckState(__FUNCTIONW__, EState::None)) + { + return false; + } + + FGameplayMediaEncoder* MediaEncoder = FGameplayMediaEncoder::Get(); + // First thing we need to do is call RegisterListener, which initializes FGameplayMediaEncoder if this is the first listener + MediaEncoder->RegisterListener(this); + + // Get SampleRate and NumChannels + uint32 AudioSampleRate, AudioNumChannels, AudioBitrate; + TRefCountPtr AudioOutputType; + verify(MediaEncoder->GetAudioOutputType(AudioOutputType)); + CHECK_HR(AudioOutputType->GetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, &AudioSampleRate)); + CHECK_HR(AudioOutputType->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &AudioNumChannels)); + CHECK_HR(AudioOutputType->GetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &AudioBitrate)); + + if (CVarLiveStreamingClientId.GetValueOnAnyThread().IsEmpty() || + CVarLiveStreamingClientSecret.GetValueOnAnyThread().IsEmpty() || + CVarLiveStreamingChannel.GetValueOnAnyThread().IsEmpty()) + { + UE_LOG(IbmLiveStreaming, Error, TEXT("ClientId/ClientSecret/Channel not specified.")); + return false; + } + + return Start( + CVarLiveStreamingClientId.GetValueOnAnyThread(), + CVarLiveStreamingClientSecret.GetValueOnAnyThread(), + CVarLiveStreamingChannel.GetValueOnAnyThread(), + AudioSampleRate, AudioNumChannels, AudioBitrate); +} + +bool FIbmLiveStreaming::Start(const FString& ClientId, const FString& ClientSecret, const FString& Channel, uint32 AudioSampleRate, uint32 AudioNumChannels, uint32 AudioBitrate) +{ + + MemoryCheckpoint("IbmLiveStreaming: Before start"); + + check(IsInGameThread()); + + if (!CheckState(__FUNCTIONW__, EState::None)) + { + return false; + } + + // NOTE: Repeated calls to RegisterListener(this) are ignored + FGameplayMediaEncoder::Get()->RegisterListener(this); + + if (!((AudioSampleRate == 44100 || AudioSampleRate == 48000) && (AudioNumChannels == 2))) + { + UE_LOG(IbmLiveStreaming, Error, TEXT("Unsupported audio settings")); + return false; + } + + custom_c_log_msg = &FIbmLiveStreaming::CustomLogMsg; + + AudioPacketsSent = 0; + VideoPacketsSent = 0; + + Config.ClientId = ClientId; + Config.ClientSecret = ClientSecret; + Config.Channel = Channel; + Config.AudioSampleRate = AudioSampleRate; + Config.AudioNumChannels = AudioNumChannels; + Config.AudioBitrate = AudioBitrate; + + UE_LOG(IbmLiveStreaming, Log, + TEXT("Initializing with ClientId=%s, ClientSecret=%s, Channel=%s, AudioSampleRate=%d, AudioNumChannels=%d"), + *ClientId, *ClientSecret, *Channel, AudioSampleRate, AudioNumChannels); + + FFormData FormData; + FormData.AddField(TEXT("grant_type"), TEXT("client_credentials")); + FormData.AddField(TEXT("client_id"), Config.ClientId); + FormData.AddField(TEXT("client_secret"), Config.ClientSecret); + FormData.AddField(TEXT("scope"), TEXT("broadcaster")); + TSharedRef HttpRequest = FormData.CreateHttpPostRequest("https://www.ustream.tv/oauth2/token", this, &FIbmLiveStreaming::OnProcessRequestComplete); + + if (!HttpRequest->ProcessRequest()) + { + UE_LOG(IbmLiveStreaming, Error, TEXT("Failed to initialize request to get access token")); + return false; + } + + State = EState::GettingAccessToken; + + MemoryCheckpoint("IbmLiveStreaming: After start"); + + return true; +} + +bool FIbmLiveStreaming::GetJsonField(const TSharedPtr& JsonObject, const FString& FieldName, FString& DestStr) +{ + if (JsonObject->TryGetStringField(FieldName, DestStr)) + { + return true; + } + else + { + UE_LOG(IbmLiveStreaming, Error, TEXT("Json field '%s' not found or not a string"), *FieldName); + return false; + } +} + +bool FIbmLiveStreaming::GetJsonField(const TSharedPtr& JsonObject, const FString& FieldName, const TSharedPtr*& DestObj) +{ + if (JsonObject->TryGetObjectField(FieldName, DestObj)) + { + return true; + } + else + { + UE_LOG(IbmLiveStreaming, Error, TEXT("Json field '%s' not found or not an object"), *FieldName); + return false; + } +} + +void FIbmLiveStreaming::OnProcessRequestComplete(FHttpRequestPtr SourceHttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded) +{ + FString Content = HttpResponse->GetContentAsString(); + EHttpResponseCodes::Type ResponseCode = (EHttpResponseCodes::Type) HttpResponse->GetResponseCode(); + UE_LOG(IbmLiveStreaming, Verbose, TEXT("Ingest reply: Code %d, Content= %s"), (int)ResponseCode, *Content); + if (!EHttpResponseCodes::IsOk(ResponseCode)) + { + UE_LOG(IbmLiveStreaming, Error, TEXT("Http Request failed.")); + State = EState::None; + return; + } + + TSharedRef> JsonReader = TJsonReaderFactory::Create(Content); + TSharedPtr JsonObject = MakeShareable(new FJsonObject()); + if (!(FJsonSerializer::Deserialize(JsonReader, JsonObject) && JsonObject.IsValid())) + { + UE_LOG(IbmLiveStreaming, Error, TEXT("Failed to deserialize http request reply as json.")); + State = EState::None; + return; + } + + if (State == EState::GettingAccessToken) + { + FString AccessToken, TokenType; + if (!GetJsonField(JsonObject, TEXT("access_token"), AccessToken) || + !GetJsonField(JsonObject, TEXT("token_type"), TokenType)) + { + State = EState::None; + return; + } + UE_LOG(IbmLiveStreaming, Verbose, TEXT("Token: %s, Type:%s"), *AccessToken, *TokenType); + + // + // Fire up the next stage's http request + // + TSharedRef HttpRequest = FHttpModule::Get().CreateRequest(); + HttpRequest->OnProcessRequestComplete().BindRaw(this, &FIbmLiveStreaming::OnProcessRequestComplete); + HttpRequest->SetURL(FString::Printf(TEXT("https://api.ustream.tv/channels/%s/ingest.json"), *Config.Channel)); + HttpRequest->SetVerb(TEXT("GET")); + HttpRequest->SetHeader(TEXT("Authorization"), TokenType + " " + AccessToken); + if (!HttpRequest->ProcessRequest()) + { + UE_LOG(IbmLiveStreaming, Error, TEXT("Failed to initialize IBMRTMP Ingest")); + State = EState::None; + return; + } + + State = EState::GettingIngestSettings; + } + else if (State == EState::GettingIngestSettings) + { + const TSharedPtr* IngestObject; + FString RtmpUrl; + if (!GetJsonField(JsonObject, TEXT("ingest"), IngestObject) || + !GetJsonField(*IngestObject, TEXT("rtmp_url"), RtmpUrl) || + !GetJsonField(*IngestObject, TEXT("streaming_key"), Ingest.StreamingKey)) + { + State = EState::None; + return; + } + UE_LOG(IbmLiveStreaming, Verbose, TEXT("rtmp_url: %s, streaming_key: %s"), *RtmpUrl, *Ingest.StreamingKey); + + TArray Tokens; + RtmpUrl.ParseIntoArray(Tokens, TEXT("/")); + if (Tokens.Num() != 4) + { + UE_LOG(IbmLiveStreaming, Error, TEXT("Failed to initialize IBMRTMP Ingest. 'rtmp_url' field doesn't have the expected format.")); + State = EState::None; + return; + } + + Ingest.RtmpUrl.Host = Tokens[1]; + Ingest.RtmpUrl.Application = Tokens[2]; + Ingest.RtmpUrl.Channel = Tokens[3]; + Ingest.RtmpUrl.ApplicationName = Ingest.RtmpUrl.Application + TEXT("/") + Ingest.RtmpUrl.Channel; + Ingest.RtmpUrl.StreamNamePrefix = FString::FromInt(FMath::Rand() % 9000 + 1000); + Ingest.RtmpUrl.StreamName = TEXT("broadcaster/live") + Ingest.RtmpUrl.StreamNamePrefix; + Connect(); + } +} + +TAutoConsoleVariable CVarLiveStreamingBwMeasureWithEmptyQueue( + TEXT("LiveStreaming.bwMeasureWithEmptyQueue"), + 1000, + TEXT("LiveStreaming: interval of reporting measured bandwdith when send queue is empty, in msecs")); + +TAutoConsoleVariable CVarLiveStreamingBwMeasureWithNotEmptyQueue( + TEXT("LiveStreaming.bwMeasureWithNotEmptyQueue"), + 300, + TEXT("LiveStreaming: interval of reporting measured bandwdith when send queue is not empty, in msecs")); + +void FIbmLiveStreaming::Connect() +{ + if (!CheckState(__FUNCTIONW__, EState::GettingIngestSettings)) + { + return ; + } + + State = EState::Connecting; + + Ctx.Client = rtmpclient_alloc(); + check(Ctx.Client); + Ctx.Client->server = strcpy_alloc(TCHAR_TO_ANSI(*Ingest.RtmpUrl.Host)); + + // + // Connect module + // + Ctx.ConnectModule = rtmpmodule_connect_create(Ctx.Client, TCHAR_TO_ANSI(*Ingest.RtmpUrl.ApplicationName)); + check(Ctx.ConnectModule); + Ctx.ConnectModule->rpin = strcpy_alloc(rtmp_c_getinstance()->rpin); + Ctx.ConnectModule->streamingKey = strcpy_alloc(TCHAR_TO_ANSI(*Ingest.StreamingKey)); + Ctx.ConnectModule->clientType = strcpy_alloc("broadcaster"); + Ctx.ConnectModule->hlsCompatible = 1; + Ctx.ConnectModule->streamNamePrefix = strcpy_alloc(TCHAR_TO_ANSI(*Ingest.RtmpUrl.StreamNamePrefix)); + Ctx.ConnectModule->onConnectionSuccess = FIbmLiveStreaming::OnConnectionSuccess; + Ctx.ConnectModule->onConnectionError = FIbmLiveStreaming::OnConnectionError; + Ctx.ConnectModule->deviceType = RTMPDeviceTypeMobile; + Ctx.ConnectModule->customData = this; + // Ctx.ConnectModule->hasPermanentContentUrl = 0; + + // + // Broadcaster module + // + Ctx.BroadcasterModule = rtmpmodule_broadcaster_create(Ctx.Client, TCHAR_TO_ANSI(*Ingest.RtmpUrl.StreamName)); + check(Ctx.BroadcasterModule); + Ctx.BroadcasterModule->onStreamPublished = FIbmLiveStreaming::OnStreamPublished; + Ctx.BroadcasterModule->onStreamError = FIbmLiveStreaming::OnStreamError; + Ctx.BroadcasterModule->onStreamDeleted = FIbmLiveStreaming::OnStreamDeleted; + Ctx.BroadcasterModule->onStopPublish = FIbmLiveStreaming::OnStopPublish; + Ctx.BroadcasterModule->autoPublish = 0; + Ctx.BroadcasterModule->customData = this; + + Ctx.BroadcasterModule->bwMeasureMinInterval = CVarLiveStreamingBwMeasureWithEmptyQueue.GetValueOnAnyThread(); + Ctx.BroadcasterModule->bwMeasureMaxInterval = CVarLiveStreamingBwMeasureWithNotEmptyQueue.GetValueOnAnyThread(); + Ctx.BroadcasterModule->onStreamBandwidthChanged = FIbmLiveStreaming::OnStreamBandwidthChanged; + + rtmpclient_start(Ctx.Client); +} + +void FIbmLiveStreaming::Stop() +{ + + if (State == EState::Stopping) + { + return; + } + + check(IsInGameThread()); + UE_LOG(IbmLiveStreaming, Log, TEXT("Stopping")); + + if (!CheckState(__FUNCTIONW__, EState::GettingAccessToken, EState::Connected)) + { + return; + } + + State = EState::Stopping; + FGameplayMediaEncoder::Get()->UnregisterListener(this); + + { + FScopeLock Lock(&CtxMutex); + if (Ctx.BroadcasterModule) + { + rtmpmodule_broadcaster_stop_publish(Ctx.BroadcasterModule); + } + } + +} + +void FIbmLiveStreaming::FinishStopOnGameThread() +{ + check(IsInGameThread()); + + UE_LOG(IbmLiveStreaming, Log, TEXT("Finalizing stop on game thread")); + + FGameplayMediaEncoder::Get()->UnregisterListener(this); + + FScopeLock Lock(&CtxMutex); + if (Ctx.Client) + { + rtmpclient_free(Ctx.Client); + Ctx.Client = nullptr; + } + Ctx.BroadcasterModule = nullptr; + Ctx.ConnectModule = nullptr; + + State = EState::None; +} + +// +// Utility helper functions +// +namespace +{ + static constexpr uint8 NAL[4] = { 0, 0, 0, 1 }; + + const TArrayView MakeArrayViewFromRange(const uint8* Begin, const uint8* End) + { + return TArrayView(const_cast(Begin), static_cast(End - Begin)); + }; + + // + // Helper functions to make it easier to write to RawData objects + // + void RawDataPush(RawData* Pkt, uint8 Val) + { + check(Pkt->offset < Pkt->length); + Pkt->data[Pkt->offset++] = Val; + } + + void RawDataPush(RawData* Pkt, const uint8* Begin, const uint8* End) + { + int Len = static_cast(End - Begin); + check((Pkt->offset + Len) <= Pkt->length); + FMemory::Memcpy(Pkt->data + Pkt->offset, Begin, Len); + Pkt->offset += Len; + } + +} + +RawData* FIbmLiveStreaming::GetAvccHeader(const TArrayView& DataView, const uint8** OutPpsEnd) +{ + // Begin/End To make it easier to use + const uint8* DataBegin = DataView.GetData(); + const uint8* DataEnd = DataView.GetData() + DataView.Num(); + + // encoded frame should begin with NALU start code + check(FMemory::Memcmp(DataBegin, NAL, sizeof(NAL)) == 0); + + const uint8* SpsEnd = Algo::FindSequence(MakeArrayViewFromRange(DataBegin + sizeof(NAL), DataEnd), NAL); + check(SpsEnd); + TArrayView SPS = MakeArrayViewFromRange(DataBegin + sizeof(NAL), SpsEnd); + + if (SPS[0] == 0x09) + { + // now it's not an SPS but AUD and so we need to skip it. happens with AMD AMF encoder + const uint8* SpsBegin = SpsEnd + sizeof(NAL); + SpsEnd = Algo::FindSequence(MakeArrayViewFromRange(SpsBegin, DataEnd), NAL); + check(SpsEnd); + SPS = MakeArrayViewFromRange(SpsBegin, SpsEnd); + check(SPS[0] == 0x67); // SPS first byte: [forbidden_zero_bit:1 = 0, nal_ref_idc:2 = 3, nal_unit_type:5 = 7] + } + + const uint8* PpsBegin = SpsEnd + sizeof(NAL); + const uint8* PpsEnd = Algo::FindSequence(MakeArrayViewFromRange(PpsBegin, DataEnd), NAL); + // encoded frame can contain just SPS/PPS + if (PpsEnd == nullptr) + { + PpsEnd = DataEnd; + } + const TArrayView PPS = MakeArrayViewFromRange(PpsBegin, PpsEnd); + + // To avoid reallocating, calculate the required final size (This is checked for correctness at the end) + int32 FinalSize = 16 + SPS.Num() + PPS.Num(); + RawData* Pkt = rawdata_alloc(FinalSize); + + static constexpr uint8 Hdr[5] = { 0x17, 0, 0, 0, 0 }; + RawDataPush(Pkt, Hdr, Hdr + sizeof(Hdr)); + + // http://neurocline.github.io/dev/2016/07/28/video-and-containers.html + // http://aviadr1.blogspot.com/2010/05/h264-extradata-partially-explained-for.html + RawDataPush(Pkt, 0x01); // AVCC version + RawDataPush(Pkt, SPS[1]); // profile + RawDataPush(Pkt, SPS[2]); // compatibility + RawDataPush(Pkt, SPS[3]); // level + RawDataPush(Pkt, 0xFC | 3); // reserved (6 bits), NALU length size - 1 (2 bits) + RawDataPush(Pkt, 0xE0 | 1); // reserved (3 bits), num of SPSs (5 bits) + + const uint8* SPS_size = Bytes(static_cast(SPS.Num())); // 2 bytes for length of SPS + RawDataPush(Pkt, SPS_size[1]); + RawDataPush(Pkt, SPS_size[0]); + + RawDataPush(Pkt, SPS.GetData(), SPS.GetData() + SPS.Num()); + + RawDataPush(Pkt, 1); // num of PPSs + const uint8* PPS_size = Bytes(static_cast(PPS.Num())); // 2 bytes for length of PPS + RawDataPush(Pkt, PPS_size[1]); + RawDataPush(Pkt, PPS_size[0]); + RawDataPush(Pkt, PPS.GetData(), PPS.GetData() + PPS.Num()); // PPS data + + // Check if we calculated the required size exactly + check(Pkt->offset == Pkt->length); + + *OutPpsEnd = PpsEnd; + Pkt->offset = 0; + return Pkt; +} + +RawData* FIbmLiveStreaming::GetVideoPacket(const TArrayView& DataView, bool bVideoKeyframe, const uint8* DataBegin) +{ + check(FMemory::Memcmp(DataBegin, NAL, sizeof(NAL)) == 0); + + // To make it easier to use + const uint8* DataEnd = DataView.GetData() + DataView.Num(); + + // To avoid reallocating, calculate the required final size (This is checked for correctness at the end) + int FinalSize = 5 + 4 + (DataEnd - (DataBegin + sizeof(NAL))); + RawData * Pkt = rawdata_alloc(FinalSize); + + RawDataPush(Pkt, bVideoKeyframe ? 0x17 : 0x27); + RawDataPush(Pkt, 0x1); + RawDataPush(Pkt, 0x0); + RawDataPush(Pkt, 0x0); + RawDataPush(Pkt, 0x0); + + int32 DataSizeValue = static_cast(DataEnd - DataBegin - sizeof(NAL));; + verify(DataSizeValue > 0); + const uint8* DataSize = Bytes(DataSizeValue); + RawDataPush(Pkt, DataSize[3]); + RawDataPush(Pkt, DataSize[2]); + RawDataPush(Pkt, DataSize[1]); + RawDataPush(Pkt, DataSize[0]); + RawDataPush(Pkt, DataBegin + sizeof(NAL), DataEnd); + + // Check if we calculated the required size exactly + check(Pkt->offset == Pkt->length); + + Pkt->offset = 0; + return Pkt; +} + +void FIbmLiveStreaming::QueueFrame(RTMPContentType FrameType, RawData* Pkt, uint32 TimestampMs) +{ + FScopeLock Lock(&CtxMutex); + rtmpmodule_broadcaster_queue_frame(Ctx.BroadcasterModule, FrameType, Pkt, TimestampMs); +} + +DECLARE_CYCLE_STAT(TEXT("IBMRTMP_Inject"), STAT_FIbmLiveStreaming_Inject, STATGROUP_VideoRecordingSystem); +DECLARE_CYCLE_STAT(TEXT("IBMRTMP_InjectVideo"), STAT_FIbmLiveStreaming_InjectVideo, STATGROUP_VideoRecordingSystem); +DECLARE_CYCLE_STAT(TEXT("IBMRTMP_InjectAudio"), STAT_FIbmLiveStreaming_InjectAudio, STATGROUP_VideoRecordingSystem); +void FIbmLiveStreaming::InjectVideo(uint32 TimestampMs, const TArrayView& DataView, bool bIsKeyFrame) +{ + SCOPE_CYCLE_COUNTER(STAT_FIbmLiveStreaming_InjectVideo); + + UE_LOG(IbmLiveStreaming, Verbose, TEXT("Injecting Video. TimestampMs=%u, Size=%u, bIsKeyFrame=%s"), TimestampMs, DataView.Num(), bIsKeyFrame ? TEXT("true"):TEXT("false")); + + // + // From IBM's sample... + // + //video packet: + //#1 config: 0x17,0,0,0,0,avcc | ts: 0 + //..n data: key 0x17 | inter: 0x27, 0x01, 0, 0, 0, data size without nal, video data after nal + // sample_add_frame(ctx, data, data_lenght, timestamp, RTMPVideoDataPacketType); + if (VideoPacketsSent == 0) + { + check(bIsKeyFrame); // the first packet always should be key-frame + + const uint8* PpsEnd; + RawData* Pkt = GetAvccHeader(DataView, &PpsEnd); + QueueFrame(RTMPVideoDataPacketType, Pkt, 0); + + if (PpsEnd != DataView.GetData() + DataView.Num()) // do we have any other NALUs in this frame? + { + Pkt = GetVideoPacket(DataView, bIsKeyFrame, PpsEnd); + QueueFrame(RTMPVideoDataPacketType, Pkt, TimestampMs); + } + } + else + { + RawData* Pkt = GetVideoPacket(DataView, bIsKeyFrame, DataView.GetData()); + QueueFrame(RTMPVideoDataPacketType, Pkt, TimestampMs); + } + + ++VideoPacketsSent; + + // Every N seconds, we log the average framerate + { + double Now = FPlatformTime::Seconds(); + double Elapsed = Now - FpsCalculationStartTime; + if (Elapsed >= 4.0f) + { + UE_LOG(IbmLiveStreaming, Verbose, TEXT("LiveStreaming Framerate = %3.2f"), + (VideoPacketsSent - FpsCalculationStartVideoPackets) / Elapsed); + FpsCalculationStartVideoPackets = VideoPacketsSent; + FpsCalculationStartTime = Now; + } + } + +} + +void FIbmLiveStreaming::InjectAudio(uint32 TimestampMs, const TArrayView& DataView) +{ + SCOPE_CYCLE_COUNTER(STAT_FIbmLiveStreaming_InjectAudio); + + UE_LOG(IbmLiveStreaming, Verbose, TEXT("Injecting Audio. TimestampMs=%u, Size=%u"), TimestampMs, DataView.Num()); + + // + // From IBM's sample + // + //audio packet: + //#1 config: aac config (parser: aac_parse_extradata) 1byte (FLVCodecAAC|FLVAudioSampleRate(select rate)|FLVAudioSize(mostly 16b)|FLVAudioChannels(mostly stereo)), AACSequenceHeader, aac_lc_write_extradata() output | ts: 0 + //..n data: 1byte aac config, AACRaw, audio data + // sample_add_frame(ctx, data, data_lenght, timestamp, RTMPAudioDataPacketType); + + // NOTE: FLVAudioSampleRate only goes up to 44kHz (FLVAudioSampleRate44kHz), but audio works fine at 48hkz too + // because aac_lc_write_extradata allows specifying the correct sample rate + constexpr unsigned char ConfigByte = FLVCodecAAC | FLVAudioSampleRate44kHz | FLVAudio16bit | FLVAudioStereo; + if (!AudioPacketsSent == 0) + { + RawData* Pkt= rawdata_alloc(2); + Pkt->data[0] = ConfigByte; + Pkt->data[1] = AACSequenceHeader; + Pkt->offset = 2; + aac_lc_write_extradata(Pkt, Config.AudioSampleRate, Config.AudioNumChannels); // This adds another 2 bytes of configuration data + Pkt->offset = 0; + QueueFrame(RTMPAudioDataPacketType, Pkt, 0); + } + + RawData* Pkt= rawdata_alloc(2 + DataView.Num()); + Pkt->data[0] = ConfigByte; + Pkt->data[1] = AACRaw; + FMemory::Memcpy(Pkt->data + 2, DataView.GetData(), DataView.Num()); + QueueFrame(RTMPAudioDataPacketType, Pkt, TimestampMs); + + ++AudioPacketsSent; +} + +void FIbmLiveStreaming::OnMediaSample(const FGameplayMediaEncoderSample& Sample) +{ + SCOPE_CYCLE_COUNTER(STAT_FIbmLiveStreaming_Inject); + FScopeLock Lock(&CtxMutex); + + if (State != EState::Connected) + { + return; + } + + if (VideoPacketsSent == 0 && AudioPacketsSent == 0) + { + // We only start injecting when we receive a keyframe + if (!Sample.IsVideoKeyFrame()) + { + return; + } + + LiveStreamStartTimespan = Sample.GetTime(); + FpsCalculationStartTime = LiveStreamStartTimespan.GetTotalSeconds(); + } + + uint32 TimestampMs = static_cast((Sample.GetTime() - LiveStreamStartTimespan).GetTotalMilliseconds()); + + TRefCountPtr MediaBuffer = nullptr; + verify(SUCCEEDED(const_cast(Sample.GetSample())->GetBufferByIndex(0, MediaBuffer.GetInitReference()))); + BYTE* SrcData = nullptr; + DWORD MaxLength = 0; + DWORD CurrentLength = 0; + verify(SUCCEEDED(MediaBuffer->Lock(&SrcData, &MaxLength, &CurrentLength))); + // Append the payload to Data (in case it has any custom data there already) + TArrayView DataView(SrcData, CurrentLength); + + if (Sample.GetType() == EMediaType::Video) + { + InjectVideo(TimestampMs, DataView, Sample.IsVideoKeyFrame()); + } + else if (Sample.GetType() == EMediaType::Audio) + { + InjectAudio(TimestampMs, DataView); + } + + verify(SUCCEEDED(MediaBuffer->Unlock())); + + // #RVF : remove this once the code is production ready + static bool FirstPacket = true; + if (FirstPacket) + { + FirstPacket = false; + MemoryCheckpoint("IbmLiveStreaming: After sending first packet"); + LogMemoryCheckpoints("After live streaming the first packet"); + } +} + +void FIbmLiveStreaming::StopFromSocketThread() +{ + { + FScopeLock Lock(&CtxMutex); + rtmpclient_stop(Ctx.Client); + } + + // Execute the Finalize event on the GameThread + FGraphEventRef FinalizeEvent = FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( + FSimpleDelegateGraphTask::FDelegate::CreateRaw(this, &FIbmLiveStreaming::FinishStopOnGameThread), + TStatId(), nullptr, ENamedThreads::GameThread); +} + +void FIbmLiveStreaming::OnConnectionErrorImpl(RTMPModuleConnect* Module, RTMPEvent Evt, void* RejectInfoObj) +{ + UE_LOG(IbmLiveStreaming, Error, TEXT("%s: Connect failed. Reason: %d"), __FUNCTIONW__, Module->rejectReason); + StopFromSocketThread(); +} + +void FIbmLiveStreaming::OnConnectionSuccessImpl(RTMPModuleConnect* Module) +{ + UE_LOG(IbmLiveStreaming, Log, TEXT("%s"), __FUNCTIONW__); + check(State == EState::Connecting); + + { + FScopeLock Lock(&CtxMutex); + rtmpmodule_broadcaster_start(Ctx.BroadcasterModule); + } + + // Changing the state AFTER making the required IBM calls + State = EState::Connected; +} + +void FIbmLiveStreaming::OnStreamPublishedImpl(RTMPModuleBroadcaster* Module) +{ + UE_LOG(IbmLiveStreaming, Log, TEXT("%s"), __FUNCTIONW__); + check(State == EState::Connected); + + { + FScopeLock Lock(&CtxMutex); + rtmpmodule_broadcaster_start_publish(Ctx.BroadcasterModule); + } + +} + +void FIbmLiveStreaming::OnStreamDeletedImpl(RTMPModuleBroadcaster* Module) +{ + UE_LOG(IbmLiveStreaming, Log, TEXT("%s"), __FUNCTIONW__); + StopFromSocketThread(); +} + +void FIbmLiveStreaming::OnStreamErrorImpl(RTMPModuleBroadcaster* Module) +{ + UE_LOG(IbmLiveStreaming, Log, TEXT("%s"), __FUNCTIONW__); + StopFromSocketThread(); +} + +void FIbmLiveStreaming::OnStopPublishImpl(RTMPModuleBroadcaster* Module) +{ + UE_LOG(IbmLiveStreaming, Log, TEXT("%s"), __FUNCTIONW__); + + { + FScopeLock Lock(&CtxMutex); + rtmpmodule_broadcaster_stop(Ctx.BroadcasterModule); + } +} + +void FIbmLiveStreaming::OnStreamBandwidthChangedImpl(RTMPModuleBroadcaster* Module, uint32 Bandwidth, bool bQueueWasEmpty) +{ + UE_LOG(IbmLiveStreaming, Verbose, TEXT("%s"), __FUNCTIONW__); + check(State == EState::Connected); + + // if debugger is stopped on a breakpoint and then resumed, measured b/w will be very small. just ignore it + if (Bandwidth <= Config.AudioBitrate) + { + UE_LOG(IbmLiveStreaming, Warning, TEXT("low traffic detected (%.3f Mbps), have debugger been stopped on breakpoint?"), Bandwidth / 10000000.0); + return; + } + + uint32 VideoBandwidth = Bandwidth - Config.AudioBitrate; + + // + // Get current video framerate and framerate + // + TRefCountPtr VideoOutputType; + uint32 CurrentBitrate, CurrentFramerate, CurrentFramerateDenominator; + verify(FGameplayMediaEncoder::Get()->GetVideoOutputType(VideoOutputType)); + verify(SUCCEEDED(MFGetAttributeRatio(VideoOutputType, MF_MT_FRAME_RATE, &CurrentFramerate, &CurrentFramerateDenominator))); + verify(SUCCEEDED(VideoOutputType->GetUINT32(MF_MT_AVG_BITRATE, &CurrentBitrate))); + + // NOTE: + // Reported bandwidth doesn't always mean available bandwidth, e.g. when we don't push enough data. + // In general, `VideoBandwidth` value is either: + // * encoder's output bitrate if available bandwidth is more than required for encoder with current settings + // * currently available bandwidth if encoder's output bitrate is higher than that + + // NOTE: + // Bitrate depends on framerate as it's in bits per second(!): e.g. to calculate how much bits per encoded + // frame is allowed encoder divides configured bitrate by framerate. + + // bitrate control + + const double BitrateProximityTolerance = CVarLiveStreamingBitrateProximityTolerance.GetValueOnAnyThread(); + + uint32 NewVideoBitrate = 0; + uint32 NewVideoFramerate = 0; + + // - if queue is not empty we restrict bitrate to reported bandwidth; + // - if queue is empty and reported bandwidth is close to current bitrate (encoder output is restricted + // but potentially greater bandwidth is available) we increase bitrate by a constant factor. + // we don't increase bitrate if encoder wasn't fulfilling available bandwidth + if (!bQueueWasEmpty) + { + NewVideoBitrate = static_cast(VideoBandwidth * CVarLiveStreamingSpaceToEmptyQueue.GetValueOnAnyThread()); + } + else if (CurrentBitrate < VideoBandwidth * BitrateProximityTolerance) + { + // `VideoBandwidth` is often just a fluctuations of current encoder bitrate, so if it's too close to currently + // configured bitrate let's be optimistic and try to stress network a little bit more, + // mainly to increase bitrate recovery speed + NewVideoBitrate = FMath::Max(static_cast(CurrentBitrate * CVarLiveStreamingNonCongestedBitrateIncrease.GetValueOnAnyThread()), VideoBandwidth); + } + + // framerate control + // by default we stream 60FPS or as much as the game manages + // if available b/w is lower than configurable threshold (e.g. 15Mbps) we downscale to e.g. 30FPS + // (configurable) and restore back to 60FPS if b/w improves + + const uint32 BitrateThresholdToSwitchFPS = static_cast(CVarLiveStreamingBitrateThresholdToSwitchFPS.GetValueOnAnyThread() * 1000 * 1000); + // two values to avoid switching back and forth on bitrate fluctuations + const uint32 BitrateThresholdDown = static_cast(BitrateThresholdToSwitchFPS * BitrateProximityTolerance); // switch down to 30FPS if bitrate is lower than that + const uint32 BitrateThresholdUp = static_cast(BitrateThresholdToSwitchFPS / BitrateProximityTolerance); // switch up to 60FPS if bitrate is higher than that + + const uint32 DownscaledFPS = static_cast(CVarLiveStreamingDownscaledFPS.GetValueOnAnyThread()); + + if (NewVideoBitrate != 0) + { + if (CurrentFramerate > DownscaledFPS && NewVideoBitrate < BitrateThresholdDown && + NewVideoBitrate < CurrentBitrate) // don't downscale if bitrate is growing + { + NewVideoFramerate = DownscaledFPS; + } + else if (CurrentFramerate < HardcodedVideoFPS && NewVideoBitrate > BitrateThresholdUp) + { + NewVideoFramerate = HardcodedVideoFPS; + } + } + + // a special case: + // if we are on downscaled framerate and encoder doesn't produce enough data to probe higher b/w + // (happens when currently set bitrate is more than enough for encoder on downscaled FPS and it's lower + // than threshold to switch to higher framerate), we won't switch to higher framerate even on unlimited b/w. + // so whenever we detect that encoder doesn't push hard enough on downscaled framerate try to switch to + // higher framerate and let the logic above kick in if the assumption is wrong + //if (!bChangeBitrate && !bChangeFramerate && bQueueWasEmpty && + if (NewVideoBitrate == 0 && NewVideoFramerate == 0 && bQueueWasEmpty && + CurrentFramerate < HardcodedVideoFPS && + CurrentBitrate > VideoBandwidth * BitrateProximityTolerance) + { + NewVideoFramerate = HardcodedVideoFPS; + UE_LOG(IbmLiveStreaming, Verbose, TEXT("framerate control special case: switching to %dFPS"), NewVideoFramerate); + } + + if (NewVideoBitrate) + { + FGameplayMediaEncoder::Get()->SetVideoBitrate(NewVideoBitrate); + } + + if (NewVideoFramerate) + { + FGameplayMediaEncoder::Get()->SetVideoFramerate(NewVideoFramerate); + } + + UE_LOG(IbmLiveStreaming, Verbose, + TEXT("reported b/w %.3f Mbps, video b/w %.3f, queue empty %d, configured bitrate %.3f, new bitrate %.3f, configured %dFPS, new %dFPS"), + Bandwidth / 1000000.0, VideoBandwidth / 1000000.0, bQueueWasEmpty, CurrentBitrate / 1000000.0, + NewVideoBitrate ? NewVideoBitrate / 1000000.0 : -1.0, + CurrentFramerate, NewVideoFramerate ? NewVideoFramerate : -1); +} + +void FIbmLiveStreaming::OnConnectionError(RTMPModuleConnect* Module, RTMPEvent Evt, void* RejectInfoObj) +{ + reinterpret_cast(Module->customData)->OnConnectionErrorImpl(Module, Evt, RejectInfoObj); +} +void FIbmLiveStreaming::OnConnectionSuccess(RTMPModuleConnect* Module) +{ + reinterpret_cast(Module->customData)->OnConnectionSuccessImpl(Module); +} + +void FIbmLiveStreaming::OnStreamPublished(RTMPModuleBroadcaster* Module) +{ + reinterpret_cast(Module->customData)->OnStreamPublishedImpl(Module); +} + +void FIbmLiveStreaming::OnStreamDeleted(RTMPModuleBroadcaster* Module) +{ + reinterpret_cast(Module->customData)->OnStreamDeletedImpl(Module); +} + +void FIbmLiveStreaming::OnStreamError(RTMPModuleBroadcaster* Module) +{ + reinterpret_cast(Module->customData)->OnStreamErrorImpl(Module); +} + +void FIbmLiveStreaming::OnStopPublish(RTMPModuleBroadcaster* Module) +{ + reinterpret_cast(Module->customData)->OnStopPublishImpl(Module); +} + +void FIbmLiveStreaming::OnStreamBandwidthChanged(RTMPModuleBroadcaster* Module, unsigned long Bandwidth, int32 QueueWasEmpty) +{ + reinterpret_cast(Module->customData)->OnStreamBandwidthChangedImpl(Module, Bandwidth, QueueWasEmpty != 0 ); +} + +GAMEPLAYMEDIAENCODER_END + +#endif // WITH_IBMRTMPINGEST + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/IbmLiveStreaming.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/IbmLiveStreaming.h new file mode 100644 index 000000000000..9aa1d9b4f2d9 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/IbmLiveStreaming.h @@ -0,0 +1,212 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "GameplayMediaEncoder.h" +#include "Interfaces/IHttpRequest.h" +#include "GameplayMediaEncoderCommon.h" + +#if defined(WITH_IBMRTMPINGEST) && LIVESTREAMING + +// IBM RTMP Ingest +THIRD_PARTY_INCLUDES_START + extern "C" { + #include "rtmp_c/core/init.h" + #include "rtmp_c/net/rtmp/rtmpclient.h" + #include "rtmp_c/net/rtmp/modules/rtmpmodule_connect.h" + #include "rtmp_c/net/rtmp/modules/rtmpmodule_broadcaster.h" + #include "rtmp_c/core/rawdata.h" + #include "rtmp_c/core/platform/threadfunc.h" + #include "rtmp_c/codec/codecs.h" + } +THIRD_PARTY_INCLUDES_END + +class FJsonObject; + +DECLARE_LOG_CATEGORY_EXTERN(IbmLiveStreaming, Log, All); + +class FIbmLiveStreaming final : private IGameplayMediaEncoderListener +{ +public: + using FBandwidthProbeCallback = TFunction; + + FIbmLiveStreaming(); + ~FIbmLiveStreaming(); + + static FIbmLiveStreaming* Get(); + + /** + * Starts streaming, using best guess settings + */ + bool Start(); + /** + * Starts streaming, using explicit settings + */ + bool Start(const FString& ClientId, const FString& ClientSecret, const FString& Channel, uint32 AudioSampleRate, uint32 AudioNumChannels, uint32 AudioBitrate); + /** + * Stops streaming + */ + void Stop(); + + static void StartCmd() + { + // We call Get(), so it creates the singleton + Get()->Start(); + } + + static void StopCmd() + { + if (Singleton) + { + Singleton->Stop(); + } + } + +private: + enum class EState + { + None, + GettingAccessToken, // See https://developers.video.ibm.com/channel-api/getting-started.html#token-endpoint_8 + GettingIngestSettings, // See https://developers.video.ibm.com/channel-api/channel.html#ingest-settings_77 + Connecting, + Connected, + Stopping + }; + + struct FRtmpUrl + { + FString Host; + FString Application; + FString Channel; + FString ApplicationName; + FString StreamName; + FString StreamNamePrefix; + }; + + struct FIngest + { + FString StreamingKey; + FRtmpUrl RtmpUrl; + }; + + struct FFormData + { + public: + FFormData(); + void AddField(const FString& Name, const FString& Value); + + // Call this in the end, to generate the HttpRequest + template + TSharedRef CreateHttpPostRequest(const FString& URL, T1&& TargetObj, T2&& TargetObjHandler) + { + auto HttpRequest = CreateHttpPostRequestImpl(URL); + HttpRequest->OnProcessRequestComplete().BindRaw(std::forward(TargetObj), std::forward(TargetObjHandler)); + return HttpRequest; + } + + private: + static TArray FStringToUint8(const FString& InString); + + FString BoundaryLabel; + FString BoundaryBegin; + FString BoundaryEnd; + FString Data; + + TSharedRef CreateHttpPostRequestImpl(const FString& URL); + }; + + // IGameplayMediaEncoderListener interface + void OnMediaSample(const FGameplayMediaEncoderSample& Sample) override; + + /** + * Callback from HTTP library when a request has completed + * @param HttpRequest The request object + * @param HttpResponse The response from the server + * @param bSucceeded Whether a response was successfully received + */ + void OnProcessRequestComplete(FHttpRequestPtr SourceHttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded); + + static bool GetJsonField(const TSharedPtr& JsonObject, const FString& FieldName, FString& DestStr); + static bool GetJsonField(const TSharedPtr& JsonObject, const FString& FieldName, const TSharedPtr*& DestObj); + + void Connect(); + + // Called to finalize a previous call to `Stop()`. This is called once + // the IBM library tells us the stream stopped and was deleted + void FinishStopOnGameThread(); + void StopFromSocketThread(); + + // + // Callbacks for IBM RTMP C Ingest + // + static void OnConnectionError(RTMPModuleConnect* Module, RTMPEvent Evt, void* RejectInfoObj); + static void OnConnectionSuccess(RTMPModuleConnect* Module); + static void OnStreamPublished(RTMPModuleBroadcaster* Module); + static void OnStreamDeleted(RTMPModuleBroadcaster* Module); + static void OnStreamError(RTMPModuleBroadcaster* Module); + static void OnStopPublish(RTMPModuleBroadcaster* Module); + static void OnStreamBandwidthChanged(RTMPModuleBroadcaster* Module, unsigned long Bandwidth, int32 QueueWasEmpty); + void OnConnectionErrorImpl(RTMPModuleConnect* Module, RTMPEvent Evt, void* RejectInfoObj); + void OnConnectionSuccessImpl(RTMPModuleConnect* Module); + void OnStreamPublishedImpl(RTMPModuleBroadcaster* Module); + void OnStreamDeletedImpl(RTMPModuleBroadcaster* Module); + void OnStreamErrorImpl(RTMPModuleBroadcaster* Module); + void OnStopPublishImpl(RTMPModuleBroadcaster* Module); + void OnStreamBandwidthChangedImpl(RTMPModuleBroadcaster* Module, uint32 Bandwidth, bool bQueueWasEmpty); + + static RawData* GetAvccHeader(const TArrayView& DataView, const uint8** OutPpsEnd); + static RawData* GetVideoPacket(const TArrayView& Data, bool bVideoKeyframe, const uint8* DataBegin); + + void InjectVideo(uint32 TimestampMs, const TArrayView& DataView, bool bIsKeyFrame); + void InjectAudio(uint32 TimestampMs, const TArrayView& DataView); + + template + static const uint8* Bytes(T& t) + { + return reinterpret_cast(&t); + } + + // Custom log function for the IBM librayr + static void CustomLogMsg(const char* Msg); + + // Utility functions to log an error if we are in the wrong state + bool CheckState(const wchar_t* FuncName, EState ExpectedState); + bool CheckState(const wchar_t* FuncName, EState ExpectedStateMin, EState ExpectedStateMax); + + static FIbmLiveStreaming* Singleton; + + // Initialization parameters + struct + { + FString ClientId; + FString ClientSecret; + FString Channel; + uint32 AudioSampleRate; + uint32 AudioNumChannels; + uint32 AudioBitrate; + } Config; + + FIngest Ingest; + + TAtomic State = EState::None; + TAtomic AudioPacketsSent = 0; + TAtomic VideoPacketsSent = 0; + FTimespan LiveStreamStartTimespan; + uint32 FpsCalculationStartVideoPackets = 0; + double FpsCalculationStartTime = 0; + + struct + { + RTMPClient* Client = nullptr; + RTMPModuleBroadcaster* BroadcasterModule = nullptr; + RTMPModuleConnect* ConnectModule = nullptr; + } Ctx; + FCriticalSection CtxMutex; + + // Helper function that locks Ctx and make the IBM call + void QueueFrame(RTMPContentType FrameType, RawData* Pkt, uint32 TimestampMs); +}; + +#endif // WITH_IBMRTMPINGEST + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/AdvancedMediaFrameworkSDK.tps b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/AdvancedMediaFrameworkSDK.tps new file mode 100644 index 000000000000..d4b4df5597c3 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/AdvancedMediaFrameworkSDK.tps @@ -0,0 +1,13 @@ + + + Advanced Media Framework (AMF) SDK + /Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf + Used to hardware encode PC highlights. + https://github.com/GPUOpen-LibrariesAndSDKs/AMF/blob/master/LICENSE.txt + + Licensees + Git + P4 + + /Engine/Source/ThirdParty/Licenses/AdvancedMediaFrameworkSDK_License.txt + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/Ambisonic2SRenderer.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/Ambisonic2SRenderer.h new file mode 100644 index 000000000000..63ac79770626 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/Ambisonic2SRenderer.h @@ -0,0 +1,79 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// interface declaration; Ambisonic to Stereo Renderer +//------------------------------------------------------------------------------------------------- + +#ifndef AMF_Ambisonic2SRenderer_h +#define AMF_Ambisonic2SRenderer_h +#pragma once + +#include "public/include/components/Component.h" + +#define AMFAmbisonic2SRendererHW L"AMFAmbisonic2SRenderer" + +enum AMF_AMBISONIC2SRENDERER_MODE_ENUM +{ + AMF_AMBISONIC2SRENDERER_MODE_SIMPLE = 0, + AMF_AMBISONIC2SRENDERER_MODE_HRTF_AMD0 = 1, + AMF_AMBISONIC2SRENDERER_MODE_HRTF_MIT1 = 2, +}; + + +// static properties +#define AMF_AMBISONIC2SRENDERER_IN_AUDIO_SAMPLE_RATE L"InSampleRate" // amf_int64 (default = 0) +#define AMF_AMBISONIC2SRENDERER_IN_AUDIO_CHANNELS L"InChannels" // amf_int64 (only = 4) +#define AMF_AMBISONIC2SRENDERER_IN_AUDIO_SAMPLE_FORMAT L"InSampleFormat" // amf_int64(AMF_AUDIO_FORMAT) (default = AMFAF_FLTP) + +#define AMF_AMBISONIC2SRENDERER_OUT_AUDIO_CHANNELS L"OutChannels" // amf_int64 (only = 2 - stereo) +#define AMF_AMBISONIC2SRENDERER_OUT_AUDIO_SAMPLE_FORMAT L"OutSampleFormat" // amf_int64(AMF_AUDIO_FORMAT) (only = AMFAF_FLTP) +#define AMF_AMBISONIC2SRENDERER_OUT_AUDIO_CHANNEL_LAYOUT L"OutChannelLayout" // amf_int64 (only = 3 - defalut stereo L R) + +#define AMF_AMBISONIC2SRENDERER_MODE L"StereoMode" //TODO: AMF_AMBISONIC2SRENDERER_MODE_ENUM(default=AMF_AMBISONIC2SRENDERER_MODE_HRTF) + + +// dynamic properties +#define AMF_AMBISONIC2SRENDERER_W L"w" //amf_int64 (default=0) +#define AMF_AMBISONIC2SRENDERER_X L"x" //amf_int64 (default=1) +#define AMF_AMBISONIC2SRENDERER_Y L"y" //amf_int64 (default=2) +#define AMF_AMBISONIC2SRENDERER_Z L"z" //amf_int64 (default=3) + +#define AMF_AMBISONIC2SRENDERER_THETA L"Theta" //double (default=0.0) +#define AMF_AMBISONIC2SRENDERER_PHI L"Phi" //double (default=0.0) +#define AMF_AMBISONIC2SRENDERER_RHO L"Rho" //double (default=0.0) + +extern "C" +{ + AMF_RESULT AMF_CDECL_CALL AMFCreateComponentAmbisonic(amf::AMFContext* pContext, void* reserved, amf::AMFComponent** ppComponent); +} +#endif //#ifndef AMF_Ambisonic2SRenderer_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/AudioCapture.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/AudioCapture.h new file mode 100644 index 000000000000..abaa4efbb136 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/AudioCapture.h @@ -0,0 +1,84 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// Audio session interface declaration +//------------------------------------------------------------------------------------------------- +#ifndef AMF_AudioCapture_h +#define AMF_AudioCapture_h + +#pragma once + +#include "public/include/components/Component.h" + +// Set to capture from either a microphone or desktop +#define AUDIOCAPTURE_SOURCE L"AudioCaptureSource" // amf_bool true for microphone, false for desktop; + +// In the case of capturing a microphone, the AUDIOCAPTURE_DEVICE_ACTIVE property +// can be set to -1 so that the active input devices are looked up. If the initialization +// is successful then the AUDIOCAPTURE_DEVICE_NAME and AUDIOCAPTURE_DEVICE_COUNT +// properties will be set. +#define AUDIOCAPTURE_DEVICE_ACTIVE L"AudioCaptureDeviceActive" // amf_int64 +#define AUDIOCAPTURE_DEVICE_COUNT L"AudioCaptureDeviceCount" // amf_int64 +#define AUDIOCAPTURE_DEVICE_NAME L"AudioCaptureDeviceName" // String + +// Codec used for audio capture +#define AUDIOCAPTURE_CODEC L"AudioCaptureCodec" // amf_int64, AV_CODEC_ID_PCM_F32LE +// Sample rate used for audio capture +#define AUDIOCAPTURE_SAMPLERATE L"AudioCaptureSampleRate" // amf_int64, 44100,def +// Sample count used for audio capture +#define AUDIOCAPTURE_SAMPLES L"AudioCaptureSampleCount" // amf_int64, 1024 +// Bitrate used for audio capture +#define AUDIOCAPTURE_BITRATE L"AudioCaptureBitRate" // amf_int64, 1024 +// Channel count used for audio capture +#define AUDIOCAPTURE_CHANNELS L"AudioCaptureChannelCount" // amf_int64, 2 +// Format used for audio capture +#define AUDIOCAPTURE_FORMAT L"AudioCaptureFormat" // amf_int64, AMFAF_U8 +// Block alignment +#define AUDIOCAPTURE_BLOCKALIGN L"AudioCaptureBlockAlign" // amf_int64, AMFAF_U8 +// Audio frame size +#define AUDIOCAPTURE_FRAMESIZE L"AudioCaptureFrameSize" // amf_int64, AMFAF_U8 +// Audio low latency state +#define AUDIOCAPTURE_LOWLATENCY L"AudioCaptureLowLatency" // amf_int64; + +// Optional interface that provides current time +#define AUDIOCAPTURE_CURRENT_TIME_INTERFACE L"CurrentTimeInterface" // interface to current time object + +extern "C" +{ + // Component that allows the recording of inputs such as microphones or the audio that is being + // rendered. The direction that is captured is controlled by the AUDIOCAPTURE_CAPTURE property + // + AMF_RESULT AMF_CDECL_CALL AMFCreateComponentAudioCapture(amf::AMFContext* pContext, amf::AMFComponent** ppComponent); +} + +#endif // #ifndef AMF_AudioCapture_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/Component.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/Component.h new file mode 100644 index 000000000000..7f13cc442e98 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/Component.h @@ -0,0 +1,440 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/** + *************************************************************************************************** + * @file Component.h + * @brief AMFComponent interface declaration + *************************************************************************************************** + */ +#ifndef AMF_Component_h +#define AMF_Component_h +#pragma once + +#include "../core/Data.h" +#include "../core/PropertyStorageEx.h" +#include "../core/Surface.h" +#include "../core/Context.h" +#include "ComponentCaps.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif + //---------------------------------------------------------------------------------------------- + // AMFDataAllocatorCB interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFDataAllocatorCB : public AMFInterface + { + public: + AMF_DECLARE_IID(0x4bf46198, 0x8b7b, 0x49d0, 0xaa, 0x72, 0x48, 0xd4, 0x7, 0xce, 0x24, 0xc5 ) + + virtual AMF_RESULT AMF_STD_CALL AllocBuffer(AMF_MEMORY_TYPE type, amf_size size, AMFBuffer** ppBuffer) = 0; + virtual AMF_RESULT AMF_STD_CALL AllocSurface(AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, + amf_int32 width, amf_int32 height, amf_int32 hPitch, amf_int32 vPitch, AMFSurface** ppSurface) = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFDataAllocatorCBPtr; +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFDataAllocatorCB, 0x4bf46198, 0x8b7b, 0x49d0, 0xaa, 0x72, 0x48, 0xd4, 0x7, 0xce, 0x24, 0xc5 ) + typedef struct AMFDataAllocatorCB AMFDataAllocatorCB; + + typedef struct AMFDataAllocatorCBVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFDataAllocatorCB* pThis); + amf_long (AMF_STD_CALL *Release)(AMFDataAllocatorCB* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFDataAllocatorCB* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + // AMFDataAllocatorCB interface + AMF_RESULT (AMF_STD_CALL *AllocBuffer)(AMFDataAllocatorCB* pThis, AMF_MEMORY_TYPE type, amf_size size, AMFBuffer** ppBuffer); + AMF_RESULT (AMF_STD_CALL *AllocSurface)(AMFDataAllocatorCB* pThis, AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, + amf_int32 width, amf_int32 height, amf_int32 hPitch, amf_int32 vPitch, AMFSurface** ppSurface); + } AMFDataAllocatorCBVtbl; + + struct AMFDataAllocatorCB + { + const AMFDataAllocatorCBVtbl *pVtbl; + }; + +#endif // #if defined(__cplusplus) + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFComponentOptimizationCallback + { + public: + virtual AMF_RESULT AMF_STD_CALL OnComponentOptimizationProgress(amf_uint percent) = 0; + }; +#else // #if defined(__cplusplus) + typedef struct AMFComponentOptimizationCallback AMFComponentOptimizationCallback; + typedef struct AMFComponentOptimizationCallbackVtbl + { + // AMFDataAllocatorCB interface + AMF_RESULT (AMF_STD_CALL *OnComponentOptimizationProgress)(AMFComponentOptimizationCallback* pThis, amf_uint percent); + } AMFComponentOptimizationCallbackVtbl; + + struct AMFComponentOptimizationCallback + { + const AMFComponentOptimizationCallbackVtbl *pVtbl; + }; + +#endif //#if defined(__cplusplus) + //---------------------------------------------------------------------------------------------- + // AMFComponent interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFComponent : public AMFPropertyStorageEx + { + public: + AMF_DECLARE_IID(0x8b51e5e4, 0x455d, 0x4034, 0xa7, 0x46, 0xde, 0x1b, 0xed, 0xc3, 0xc4, 0x6) + + virtual AMF_RESULT AMF_STD_CALL Init(AMF_SURFACE_FORMAT format,amf_int32 width,amf_int32 height) = 0; + virtual AMF_RESULT AMF_STD_CALL ReInit(amf_int32 width,amf_int32 height) = 0; + virtual AMF_RESULT AMF_STD_CALL Terminate() = 0; + virtual AMF_RESULT AMF_STD_CALL Drain() = 0; + virtual AMF_RESULT AMF_STD_CALL Flush() = 0; + + virtual AMF_RESULT AMF_STD_CALL SubmitInput(AMFData* pData) = 0; + virtual AMF_RESULT AMF_STD_CALL QueryOutput(AMFData** ppData) = 0; + virtual AMFContext* AMF_STD_CALL GetContext() = 0; + virtual AMF_RESULT AMF_STD_CALL SetOutputDataAllocatorCB(AMFDataAllocatorCB* callback) = 0; + + virtual AMF_RESULT AMF_STD_CALL GetCaps(AMFCaps** ppCaps) = 0; + virtual AMF_RESULT AMF_STD_CALL Optimize(AMFComponentOptimizationCallback* pCallback) = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFComponentPtr; +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFComponent, 0x8b51e5e4, 0x455d, 0x4034, 0xa7, 0x46, 0xde, 0x1b, 0xed, 0xc3, 0xc4, 0x6) + typedef struct AMFComponent AMFComponent; + + typedef struct AMFComponentVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFComponent* pThis); + amf_long (AMF_STD_CALL *Release)(AMFComponent* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFComponent* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFPropertyStorage interface + AMF_RESULT (AMF_STD_CALL *SetProperty)(AMFComponent* pThis, const wchar_t* name, AMFVariantStruct value); + AMF_RESULT (AMF_STD_CALL *GetProperty)(AMFComponent* pThis, const wchar_t* name, AMFVariantStruct* pValue); + amf_bool (AMF_STD_CALL *HasProperty)(AMFComponent* pThis, const wchar_t* name); + amf_size (AMF_STD_CALL *GetPropertyCount)(AMFComponent* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyAt)(AMFComponent* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue); + AMF_RESULT (AMF_STD_CALL *Clear)(AMFComponent* pThis); + AMF_RESULT (AMF_STD_CALL *AddTo)(AMFComponent* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep); + AMF_RESULT (AMF_STD_CALL *CopyTo)(AMFComponent* pThis, AMFPropertyStorage* pDest, amf_bool deep); + void (AMF_STD_CALL *AddObserver)(AMFComponent* pThis, AMFPropertyStorageObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver)(AMFComponent* pThis, AMFPropertyStorageObserver* pObserver); + + // AMFPropertyStorageEx interface + + amf_size (AMF_STD_CALL *GetPropertiesInfoCount)(AMFComponent* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyInfoAt)(AMFComponent* pThis, amf_size index, const AMFPropertyInfo** ppInfo); + AMF_RESULT (AMF_STD_CALL *GetPropertyInfo)(AMFComponent* pThis, const wchar_t* name, const AMFPropertyInfo** ppInfo); + AMF_RESULT (AMF_STD_CALL *ValidateProperty)(AMFComponent* pThis, const wchar_t* name, AMFVariantStruct value, AMFVariantStruct* pOutValidated); + + // AMFComponent interface + + AMF_RESULT (AMF_STD_CALL *Init)(AMFComponent* pThis, AMF_SURFACE_FORMAT format,amf_int32 width,amf_int32 height); + AMF_RESULT (AMF_STD_CALL *ReInit)(AMFComponent* pThis, amf_int32 width,amf_int32 height); + AMF_RESULT (AMF_STD_CALL *Terminate)(AMFComponent* pThis); + AMF_RESULT (AMF_STD_CALL *Drain)(AMFComponent* pThis); + AMF_RESULT (AMF_STD_CALL *Flush)(AMFComponent* pThis); + + AMF_RESULT (AMF_STD_CALL *SubmitInput)(AMFComponent* pThis, AMFData* pData); + AMF_RESULT (AMF_STD_CALL *QueryOutput)(AMFComponent* pThis, AMFData** ppData); + AMFContext* (AMF_STD_CALL *GetContext)(AMFComponent* pThis); + AMF_RESULT (AMF_STD_CALL *SetOutputDataAllocatorCB)(AMFComponent* pThis, AMFDataAllocatorCB* callback); + + AMF_RESULT (AMF_STD_CALL *GetCaps)(AMFComponent* pThis, AMFCaps** ppCaps); + AMF_RESULT (AMF_STD_CALL *Optimize)(AMFComponent* pThis, AMFComponentOptimizationCallback* pCallback); + } AMFComponentVtbl; + + struct AMFComponent + { + const AMFComponentVtbl *pVtbl; + }; + +#endif // #if defined(__cplusplus) + //---------------------------------------------------------------------------------------------- + // AMFInput interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFInput : public AMFPropertyStorageEx + { + public: + AMF_DECLARE_IID(0x1181eee7, 0x95f2, 0x434a, 0x9b, 0x96, 0xea, 0x55, 0xa, 0xa7, 0x84, 0x89) + + virtual AMF_RESULT AMF_STD_CALL SubmitInput(AMFData* pData) = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFInputPtr; +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFInput, 0x1181eee7, 0x95f2, 0x434a, 0x9b, 0x96, 0xea, 0x55, 0xa, 0xa7, 0x84, 0x89) + typedef struct AMFInput AMFInput; + + typedef struct AMFInputVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFInput* pThis); + amf_long (AMF_STD_CALL *Release)(AMFInput* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFInput* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFPropertyStorage interface + AMF_RESULT (AMF_STD_CALL *SetProperty)(AMFInput* pThis, const wchar_t* name, AMFVariantStruct value); + AMF_RESULT (AMF_STD_CALL *GetProperty)(AMFInput* pThis, const wchar_t* name, AMFVariantStruct* pValue); + amf_bool (AMF_STD_CALL *HasProperty)(AMFInput* pThis, const wchar_t* name); + amf_size (AMF_STD_CALL *GetPropertyCount)(AMFInput* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyAt)(AMFInput* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue); + AMF_RESULT (AMF_STD_CALL *Clear)(AMFInput* pThis); + AMF_RESULT (AMF_STD_CALL *AddTo)(AMFInput* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep); + AMF_RESULT (AMF_STD_CALL *CopyTo)(AMFInput* pThis, AMFPropertyStorage* pDest, amf_bool deep); + void (AMF_STD_CALL *AddObserver)(AMFInput* pThis, AMFPropertyStorageObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver)(AMFInput* pThis, AMFPropertyStorageObserver* pObserver); + + // AMFPropertyStorageEx interface + + amf_size (AMF_STD_CALL *GetPropertiesInfoCount)(AMFInput* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyInfoAt)(AMFInput* pThis, amf_size index, const AMFPropertyInfo** ppInfo); + AMF_RESULT (AMF_STD_CALL *GetPropertyInfo)(AMFInput* pThis, const wchar_t* name, const AMFPropertyInfo** ppInfo); + AMF_RESULT (AMF_STD_CALL *ValidateProperty)(AMFInput* pThis, const wchar_t* name, AMFVariantStruct value, AMFVariantStruct* pOutValidated); + + // AMFInput interface + AMF_RESULT (AMF_STD_CALL *SubmitInput)(AMFInput* pThis, AMFData* pData); + + } AMFInputVtbl; + + struct AMFInput + { + const AMFInputVtbl *pVtbl; + }; +#endif // #if defined(__cplusplus) + + //---------------------------------------------------------------------------------------------- + // AMFOutput interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFOutput : public AMFPropertyStorageEx + { + public: + AMF_DECLARE_IID(0x86a8a037, 0x912c, 0x4698, 0xb0, 0x46, 0x7, 0x5a, 0x1f, 0xac, 0x6b, 0x97); + + virtual AMF_RESULT AMF_STD_CALL QueryOutput(AMFData** ppData) = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFOutputPtr; +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFOutput, 0x86a8a037, 0x912c, 0x4698, 0xb0, 0x46, 0x7, 0x5a, 0x1f, 0xac, 0x6b, 0x97); + typedef struct AMFOutput AMFOutput; + + typedef struct AMFOutputVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFOutput* pThis); + amf_long (AMF_STD_CALL *Release)(AMFOutput* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFOutput* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFPropertyStorage interface + AMF_RESULT (AMF_STD_CALL *SetProperty)(AMFOutput* pThis, const wchar_t* name, AMFVariantStruct value); + AMF_RESULT (AMF_STD_CALL *GetProperty)(AMFOutput* pThis, const wchar_t* name, AMFVariantStruct* pValue); + amf_bool (AMF_STD_CALL *HasProperty)(AMFOutput* pThis, const wchar_t* name); + amf_size (AMF_STD_CALL *GetPropertyCount)(AMFOutput* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyAt)(AMFOutput* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue); + AMF_RESULT (AMF_STD_CALL *Clear)(AMFOutput* pThis); + AMF_RESULT (AMF_STD_CALL *AddTo)(AMFOutput* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep); + AMF_RESULT (AMF_STD_CALL *CopyTo)(AMFOutput* pThis, AMFPropertyStorage* pDest, amf_bool deep); + void (AMF_STD_CALL *AddObserver)(AMFOutput* pThis, AMFPropertyStorageObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver)(AMFOutput* pThis, AMFPropertyStorageObserver* pObserver); + + // AMFPropertyStorageEx interface + + amf_size (AMF_STD_CALL *GetPropertiesInfoCount)(AMFOutput* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyInfoAt)(AMFOutput* pThis, amf_size index, const AMFPropertyInfo** ppInfo); + AMF_RESULT (AMF_STD_CALL *GetPropertyInfo)(AMFOutput* pThis, const wchar_t* name, const AMFPropertyInfo** ppInfo); + AMF_RESULT (AMF_STD_CALL *ValidateProperty)(AMFOutput* pThis, const wchar_t* name, AMFVariantStruct value, AMFVariantStruct* pOutValidated); + + // AMFOutput interface + AMF_RESULT (AMF_STD_CALL *QueryOutput)(AMFOutput* pThis, AMFData** ppData); + + } AMFOutputVtbl; + + struct AMFOutput + { + const AMFOutputVtbl *pVtbl; + }; + +#endif // #if defined(__cplusplus) + //---------------------------------------------------------------------------------------------- + // AMFComponent interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFComponentEx : public AMFComponent + { + public: + AMF_DECLARE_IID(0xfda792af, 0x8712, 0x44df, 0x8e, 0xa0, 0xdf, 0xfa, 0xad, 0x2c, 0x80, 0x93) + + virtual amf_int32 AMF_STD_CALL GetInputCount() = 0; + virtual amf_int32 AMF_STD_CALL GetOutputCount() = 0; + + virtual AMF_RESULT AMF_STD_CALL GetInput(amf_int32 index, AMFInput** ppInput) = 0; + virtual AMF_RESULT AMF_STD_CALL GetOutput(amf_int32 index, AMFOutput** ppOutput) = 0; + + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFComponentExPtr; +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFComponentEx, 0xfda792af, 0x8712, 0x44df, 0x8e, 0xa0, 0xdf, 0xfa, 0xad, 0x2c, 0x80, 0x93) + typedef struct AMFComponentEx AMFComponentEx; + + typedef struct AMFComponentExVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFComponentEx* pThis); + amf_long (AMF_STD_CALL *Release)(AMFComponentEx* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFComponentEx* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFPropertyStorage interface + AMF_RESULT (AMF_STD_CALL *SetProperty)(AMFComponentEx* pThis, const wchar_t* name, AMFVariantStruct value); + AMF_RESULT (AMF_STD_CALL *GetProperty)(AMFComponentEx* pThis, const wchar_t* name, AMFVariantStruct* pValue); + amf_bool (AMF_STD_CALL *HasProperty)(AMFComponentEx* pThis, const wchar_t* name); + amf_size (AMF_STD_CALL *GetPropertyCount)(AMFComponentEx* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyAt)(AMFComponentEx* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue); + AMF_RESULT (AMF_STD_CALL *Clear)(AMFComponentEx* pThis); + AMF_RESULT (AMF_STD_CALL *AddTo)(AMFComponentEx* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep); + AMF_RESULT (AMF_STD_CALL *CopyTo)(AMFComponentEx* pThis, AMFPropertyStorage* pDest, amf_bool deep); + void (AMF_STD_CALL *AddObserver)(AMFComponentEx* pThis, AMFPropertyStorageObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver)(AMFComponentEx* pThis, AMFPropertyStorageObserver* pObserver); + + // AMFPropertyStorageEx interface + + amf_size (AMF_STD_CALL *GetPropertiesInfoCount)(AMFComponentEx* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyInfoAt)(AMFComponentEx* pThis, amf_size index, const AMFPropertyInfo** ppInfo); + AMF_RESULT (AMF_STD_CALL *GetPropertyInfo)(AMFComponentEx* pThis, const wchar_t* name, const AMFPropertyInfo** ppInfo); + AMF_RESULT (AMF_STD_CALL *ValidateProperty)(AMFComponentEx* pThis, const wchar_t* name, AMFVariantStruct value, AMFVariantStruct* pOutValidated); + + // AMFComponent interface + + AMF_RESULT (AMF_STD_CALL *Init)(AMFComponentEx* pThis, AMF_SURFACE_FORMAT format,amf_int32 width,amf_int32 height); + AMF_RESULT (AMF_STD_CALL *ReInit)(AMFComponentEx* pThis, amf_int32 width,amf_int32 height); + AMF_RESULT (AMF_STD_CALL *Terminate)(AMFComponentEx* pThis); + AMF_RESULT (AMF_STD_CALL *Drain)(AMFComponentEx* pThis); + AMF_RESULT (AMF_STD_CALL *Flush)(AMFComponentEx* pThis); + + AMF_RESULT (AMF_STD_CALL *SubmitInput)(AMFComponentEx* pThis, AMFData* pData); + AMF_RESULT (AMF_STD_CALL *QueryOutput)(AMFComponentEx* pThis, AMFData** ppData); + AMFContext* (AMF_STD_CALL *GetContext)(AMFComponentEx* pThis); + AMF_RESULT (AMF_STD_CALL *SetOutputDataAllocatorCB)(AMFComponentEx* pThis, AMFDataAllocatorCB* callback); + + AMF_RESULT (AMF_STD_CALL *GetCaps)(AMFComponentEx* pThis, AMFCaps** ppCaps); + AMF_RESULT (AMF_STD_CALL *Optimize)(AMFComponentEx* pThis, AMFComponentOptimizationCallback* pCallback); + + // AMFComponentEx interface + + amf_int32 (AMF_STD_CALL *GetInputCount)(AMFComponentEx* pThis); + amf_int32 (AMF_STD_CALL *GetOutputCount)(AMFComponentEx* pThis); + + AMF_RESULT (AMF_STD_CALL *GetInput)(AMFComponentEx* pThis, amf_int32 index, AMFInput** ppInput); + AMF_RESULT (AMF_STD_CALL *GetOutput)(AMFComponentEx* pThis, amf_int32 index, AMFOutput** ppOutput); + + + } AMFComponentExVtbl; + + struct AMFComponentEx + { + const AMFComponentExVtbl *pVtbl; + }; +#endif // #if defined(__cplusplus) + + +#if defined(__cplusplus) +} // namespace +#endif + +typedef enum AMF_STREAM_TYPE_ENUM +{ + AMF_STREAM_UNKNOWN = 0, + AMF_STREAM_VIDEO = 1, + AMF_STREAM_AUDIO = 2, + AMF_STREAM_DATA = 3, +} AMF_STREAM_TYPE_ENUM; + +typedef enum AMF_STREAM_CODEC_ID_ENUM // matched codecs from VideoDecoxcderUVD.h +{ + AMF_STREAM_CODEC_ID_UNKNOWN = 0, + AMF_STREAM_CODEC_ID_MPEG2 = 1, // AMFVideoDecoderUVD_MPEG2 + AMF_STREAM_CODEC_ID_MPEG4 = 2, // AMFVideoDecoderUVD_MPEG4 + AMF_STREAM_CODEC_ID_WMV3 = 3, // AMFVideoDecoderUVD_WMV3 + AMF_STREAM_CODEC_ID_VC1 = 4, // AMFVideoDecoderUVD_VC1 + AMF_STREAM_CODEC_ID_H264_AVC = 5, // AMFVideoDecoderUVD_H264_AVC + AMF_STREAM_CODEC_ID_H264_MVC = 6, // AMFVideoDecoderUVD_H264_MVC + AMF_STREAM_CODEC_ID_H264_SVC = 7, // AMFVideoDecoderUVD_H264_SVC + AMF_STREAM_CODEC_ID_MJPEG = 8, // AMFVideoDecoderUVD_MJPEG + AMF_STREAM_CODEC_ID_H265_HEVC = 9, // AMFVideoDecoderHW_H265_HEVC + AMF_STREAM_CODEC_ID_H265_MAIN10 = 10, // AMFVideoDecoderHW_H265_MAIN10 +} AMF_STREAM_CODEC_ID_ENUM; + +// common stream properties +#define AMF_STREAM_TYPE L"StreamType" // amf_int64( AMF_STREAM_TYPE_ENUM ) +#define AMF_STREAM_ENABLED L"Enabled" // bool( default = false ) +#define AMF_STREAM_CODEC_ID L"CodecID" // amf_int64(Video: AMF_STREAM_CODEC_ID_ENUM, Audio: AVCodecID) (default = 0 - uncompressed) +#define AMF_STREAM_BIT_RATE L"BitRate" // amf_int64 (default = codec->bit_rate) +#define AMF_STREAM_EXTRA_DATA L"ExtraData" // interface to AMFBuffer - as is from FFMPEG + +// video stream properties +#define AMF_STREAM_VIDEO_MEMORY_TYPE L"VideoMemoryType" // amf_int64(AMF_MEMORY_TYPE); default = AMF_MEMORY_DX11 +#define AMF_STREAM_VIDEO_FORMAT L"VideoFormat" // amf_int64(AMF_SURFACE_FORMAT); default = AMF_SURFACE_NV12 (used if AMF_STREAM_CODEC_ID == 0) +#define AMF_STREAM_VIDEO_FRAME_RATE L"VideoFrameRate" // AMFRate; default = (30,1) - video frame rate +#define AMF_STREAM_VIDEO_FRAME_SIZE L"VideoFrameSize" // AMFSize; default = (1920,1080) - video frame rate +#define AMF_STREAM_VIDEO_SURFACE_POOL L"VideoSurfacePool" // amf_int64; default = 5, number of allocated output surfaces +//TODO support interlaced frames + +// audio stream properties +#define AMF_STREAM_AUDIO_FORMAT L"AudioFormat" // amf_int64(AMF_AUDIO_FORMAT); default = AMFAF_S16 +#define AMF_STREAM_AUDIO_SAMPLE_RATE L"AudioSampleRate" // amf_int64; default = 48000 +#define AMF_STREAM_AUDIO_CHANNELS L"AudioChannels" // amf_int64; default = 2 +#define AMF_STREAM_AUDIO_CHANNEL_LAYOUT L"AudioChannelLayout" // amf_int64 (default = codec->channel_layout) +#define AMF_STREAM_AUDIO_BLOCK_ALIGN L"AudioBlockAlign" // amf_int64 (default = codec->block_align) +#define AMF_STREAM_AUDIO_FRAME_SIZE L"AudioFrameSize" // amf_int64 (default = codec->frame_size) + + +#endif //#ifndef AMF_Component_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/ComponentCaps.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/ComponentCaps.h new file mode 100644 index 000000000000..48197670dac9 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/ComponentCaps.h @@ -0,0 +1,172 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_ComponentCaps_h +#define AMF_ComponentCaps_h + +#pragma once + +#include "../core/Interface.h" +#include "../core/PropertyStorage.h" +#include "../core/Surface.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif + typedef enum AMF_ACCELERATION_TYPE + { + AMF_ACCEL_NOT_SUPPORTED = -1, + AMF_ACCEL_HARDWARE, + AMF_ACCEL_GPU, + AMF_ACCEL_SOFTWARE + } AMF_ACCELERATION_TYPE; + //---------------------------------------------------------------------------------------------- + // AMFIOCaps interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFIOCaps : public AMFInterface + { + public: + // Get supported resolution ranges in pixels/lines: + virtual void AMF_STD_CALL GetWidthRange(amf_int32* minWidth, amf_int32* maxWidth) const = 0; + virtual void AMF_STD_CALL GetHeightRange(amf_int32* minHeight, amf_int32* maxHeight) const = 0; + + // Get memory alignment in lines: Vertical aligmnent should be multiples of this number + virtual amf_int32 AMF_STD_CALL GetVertAlign() const = 0; + + // Enumerate supported surface pixel formats + virtual amf_int32 AMF_STD_CALL GetNumOfFormats() const = 0; + virtual AMF_RESULT AMF_STD_CALL GetFormatAt(amf_int32 index, AMF_SURFACE_FORMAT* format, amf_bool* native) const = 0; + + // Enumerate supported memory types + virtual amf_int32 AMF_STD_CALL GetNumOfMemoryTypes() const = 0; + virtual AMF_RESULT AMF_STD_CALL GetMemoryTypeAt(amf_int32 index, AMF_MEMORY_TYPE* memType, amf_bool* native) const = 0; + + virtual amf_bool AMF_STD_CALL IsInterlacedSupported() const = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFIOCapsPtr; +#else // #if defined(__cplusplus) + typedef struct AMFIOCaps AMFIOCaps; + + typedef struct AMFIOCapsVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFIOCaps* pThis); + amf_long (AMF_STD_CALL *Release)(AMFIOCaps* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFIOCaps* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFIOCaps interface + // Get supported resolution ranges in pixels/lines: + void (AMF_STD_CALL *GetWidthRange)(AMFIOCaps* pThis, amf_int32* minWidth, amf_int32* maxWidth); + void (AMF_STD_CALL *GetHeightRange)(AMFIOCaps* pThis, amf_int32* minHeight, amf_int32* maxHeight); + + // Get memory alignment in lines: Vertical aligmnent should be multiples of this number + amf_int32 (AMF_STD_CALL *GetVertAlign)(AMFIOCaps* pThis); + + // Enumerate supported surface pixel formats + amf_int32 (AMF_STD_CALL *GetNumOfFormats)(AMFIOCaps* pThis); + AMF_RESULT (AMF_STD_CALL *GetFormatAt)(AMFIOCaps* pThis, amf_int32 index, AMF_SURFACE_FORMAT* format, amf_bool* native); + + // Enumerate supported memory types + amf_int32 (AMF_STD_CALL *GetNumOfMemoryTypes)(AMFIOCaps* pThis); + AMF_RESULT (AMF_STD_CALL *GetMemoryTypeAt)(AMFIOCaps* pThis, amf_int32 index, AMF_MEMORY_TYPE* memType, amf_bool* native); + + amf_bool (AMF_STD_CALL *IsInterlacedSupported)(AMFIOCaps* pThis); + } AMFIOCapsVtbl; + + struct AMFIOCaps + { + const AMFIOCapsVtbl *pVtbl; + }; + +#endif // #if defined(__cplusplus) + + //---------------------------------------------------------------------------------------------- + // AMFCaps interface - base interface for every h/w module supported by Capability Manager + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFCaps : public AMFPropertyStorage + { + public: + virtual AMF_ACCELERATION_TYPE AMF_STD_CALL GetAccelerationType() const = 0; + virtual AMF_RESULT AMF_STD_CALL GetInputCaps(AMFIOCaps** input) = 0; + virtual AMF_RESULT AMF_STD_CALL GetOutputCaps(AMFIOCaps** output) = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFCapsPtr; +#else // #if defined(__cplusplus) + typedef struct AMFCaps AMFCaps; + + typedef struct AMFCapsVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFCaps* pThis); + amf_long (AMF_STD_CALL *Release)(AMFCaps* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFCaps* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFPropertyStorage interface + AMF_RESULT (AMF_STD_CALL *SetProperty)(AMFCaps* pThis, const wchar_t* name, AMFVariantStruct value); + AMF_RESULT (AMF_STD_CALL *GetProperty)(AMFCaps* pThis, const wchar_t* name, AMFVariantStruct* pValue); + amf_bool (AMF_STD_CALL *HasProperty)(AMFCaps* pThis, const wchar_t* name); + amf_size (AMF_STD_CALL *GetPropertyCount)(AMFCaps* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyAt)(AMFCaps* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue); + AMF_RESULT (AMF_STD_CALL *Clear)(AMFCaps* pThis); + AMF_RESULT (AMF_STD_CALL *AddTo)(AMFCaps* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep); + AMF_RESULT (AMF_STD_CALL *CopyTo)(AMFCaps* pThis, AMFPropertyStorage* pDest, amf_bool deep); + void (AMF_STD_CALL *AddObserver)(AMFCaps* pThis, AMFPropertyStorageObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver)(AMFCaps* pThis, AMFPropertyStorageObserver* pObserver); + + // AMFCaps interface + + AMF_ACCELERATION_TYPE (AMF_STD_CALL *GetAccelerationType)(AMFCaps* pThis); + AMF_RESULT (AMF_STD_CALL *GetInputCaps)(AMFCaps* pThis, AMFIOCaps** input); + AMF_RESULT (AMF_STD_CALL *GetOutputCaps)(AMFCaps* pThis, AMFIOCaps** output); + } AMFCapsVtbl; + + struct AMFCaps + { + const AMFCapsVtbl *pVtbl; + }; +#endif // #if defined(__cplusplus) + + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) +} +#endif + +#endif //#ifndef AMF_ComponentCaps_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/DisplayCapture.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/DisplayCapture.h new file mode 100644 index 000000000000..eb729e8ab83b --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/DisplayCapture.h @@ -0,0 +1,67 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// Desktop duplication interface declaration +//------------------------------------------------------------------------------------------------- + +#ifndef AMF_DisplayCapture_h +#define AMF_DisplayCapture_h +#pragma once + +#include "Component.h" + +#define AMFDisplayCapture L"AMFDisplayCapture" + +// Static properties +// +// Index of the display monitor +// - Monitor index is determined by using EnumAdapters() in DX11. +#define AMF_DISPLAYCAPTURE_MONITOR_INDEX L"InMonitorIndex" // amf_int64 (default = 0) +// Capture frame rate +#define AMF_DISPLAYCAPTURE_FRAMERATE L"InFrameRate" // amf_int64 (default = 60) +// Optional interface object for getting current time. +#define AMF_DISPLAYCAPTURE_CURRENT_TIME_INTERFACE L"CurrentTimeInterface" +// Capture format +#define AMF_DISPLAYCAPTURE_FORMAT L"CurrentFormat" + +extern "C" +{ + // Component that allows the desktop to be captured: + // - DX11 only and the device must be created with IDXGIFactory1 or later support + // - The monitor display must not be rotated. See DDAPISource.cpp + // - Component will fail to initialize on Windows 7 as the Desktop Duplication API + // is not supported + // + AMF_RESULT AMF_CDECL_CALL AMFCreateComponentDisplayCapture(amf::AMFContext* pContext, amf::AMFComponent** ppComponent); +} +#endif // #ifndef AMF_DisplayCapture_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGAudioConverter.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGAudioConverter.h new file mode 100644 index 000000000000..5ce79cab608f --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGAudioConverter.h @@ -0,0 +1,62 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// AMFFAudioConverterFFMPEG interface declaration +//------------------------------------------------------------------------------------------------- + +#ifndef AMF_AudioConverterFFMPEG_h +#define AMF_AudioConverterFFMPEG_h + +#pragma once + + +#define FFMPEG_AUDIO_CONVERTER L"AudioConverterFFMPEG" + + +#define AUDIO_CONVERTER_IN_AUDIO_BIT_RATE L"In_BitRate" // amf_int64 (default = 128000) +#define AUDIO_CONVERTER_IN_AUDIO_SAMPLE_RATE L"In_SampleRate" // amf_int64 (default = 0) +#define AUDIO_CONVERTER_IN_AUDIO_CHANNELS L"In_Channels" // amf_int64 (default = 2) +#define AUDIO_CONVERTER_IN_AUDIO_SAMPLE_FORMAT L"In_SampleFormat" // amf_int64 (default = AMFAF_UNKNOWN) (AMF_AUDIO_FORMAT) +#define AUDIO_CONVERTER_IN_AUDIO_CHANNEL_LAYOUT L"In_ChannelLayout" // amf_int64 (default = 0) +#define AUDIO_CONVERTER_IN_AUDIO_BLOCK_ALIGN L"In_BlockAlign" // amf_int64 (default = 0) + +#define AUDIO_CONVERTER_OUT_AUDIO_BIT_RATE L"Out_BitRate" // amf_int64 (default = 128000) +#define AUDIO_CONVERTER_OUT_AUDIO_SAMPLE_RATE L"Out_SampleRate" // amf_int64 (default = 0) +#define AUDIO_CONVERTER_OUT_AUDIO_CHANNELS L"Out_Channels" // amf_int64 (default = 2) +#define AUDIO_CONVERTER_OUT_AUDIO_SAMPLE_FORMAT L"Out_SampleFormat" // amf_int64 (default = AMFAF_UNKNOWN) (AMF_AUDIO_FORMAT) +#define AUDIO_CONVERTER_OUT_AUDIO_CHANNEL_LAYOUT L"Out_ChannelLayout" // amf_int64 (default = 0) +#define AUDIO_CONVERTER_OUT_AUDIO_BLOCK_ALIGN L"Out_BlockAlign" // amf_int64 (default = 0) + + + +#endif //#ifndef AMF_AudioConverterFFMPEG_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGAudioDecoder.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGAudioDecoder.h new file mode 100644 index 000000000000..e0c324c6b9c9 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGAudioDecoder.h @@ -0,0 +1,68 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// AudioDecoderFFMPEG interface declaration +//------------------------------------------------------------------------------------------------- +#ifndef AMF_AudioDecoderFFMPEG_h +#define AMF_AudioDecoderFFMPEG_h + +#pragma once + + +#define FFMPEG_AUDIO_DECODER L"AudioDecoderFFMPEG" + + +#define AUDIO_DECODER_ENABLE_DEBUGGING L"EnableDebug" // bool (default = false) - trace some debug information if set to true +#define AUDIO_DECODER_ENABLE_DECODING L"EnableDecoding" // bool (default = true) - if false, component will not decode anything + +#define AUDIO_DECODER_IN_AUDIO_CODEC_ID L"In_CodecID" // amf_int64 (default = AV_CODEC_ID_NONE) - FFMPEG codec ID +#define AUDIO_DECODER_IN_AUDIO_BIT_RATE L"In_BitRate" // amf_int64 (default = 128000) +#define AUDIO_DECODER_IN_AUDIO_EXTRA_DATA L"In_ExtraData" // interface to AMFBuffer +#define AUDIO_DECODER_IN_AUDIO_SAMPLE_RATE L"In_SampleRate" // amf_int64 (default = 0) +#define AUDIO_DECODER_IN_AUDIO_CHANNELS L"In_Channels" // amf_int64 (default = 2) +#define AUDIO_DECODER_IN_AUDIO_SAMPLE_FORMAT L"In_SampleFormat" // amf_int64 (default = AMFAF_UNKNOWN) (AMF_AUDIO_FORMAT) +#define AUDIO_DECODER_IN_AUDIO_CHANNEL_LAYOUT L"In_ChannelLayout" // amf_int64 (default = 0) +#define AUDIO_DECODER_IN_AUDIO_BLOCK_ALIGN L"In_BlockAlign" // amf_int64 (default = 0) +#define AUDIO_DECODER_IN_AUDIO_FRAME_SIZE L"In_FrameSize" // amf_int64 (default = 0) +#define AUDIO_DECODER_IN_AUDIO_SEEK_POSITION L"In_SeekPosition" // amf_int64 (default = 0) + +#define AUDIO_DECODER_OUT_AUDIO_BIT_RATE L"Out_BitRate" // amf_int64 (default = 128000) +#define AUDIO_DECODER_OUT_AUDIO_SAMPLE_RATE L"Out_SampleRate" // amf_int64 (default = 0) +#define AUDIO_DECODER_OUT_AUDIO_CHANNELS L"Out_Channels" // amf_int64 (default = 2) +#define AUDIO_DECODER_OUT_AUDIO_SAMPLE_FORMAT L"Out_SampleFormat" // amf_int64 (default = AMFAF_UNKNOWN) (AMF_AUDIO_FORMAT) +#define AUDIO_DECODER_OUT_AUDIO_CHANNEL_LAYOUT L"Out_ChannelLayout" // amf_int64 (default = 0) +#define AUDIO_DECODER_OUT_AUDIO_BLOCK_ALIGN L"Out_BlockAlign" // amf_int64 (default = 0) + + + +#endif //#ifndef AMF_AudioDecoderFFMPEG_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGAudioEncoder.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGAudioEncoder.h new file mode 100644 index 000000000000..872080b19319 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGAudioEncoder.h @@ -0,0 +1,66 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// AudioEncoderFFMPEG interface declaration +//------------------------------------------------------------------------------------------------- +#ifndef AMF_AudioEncoderFFMPEG_h +#define AMF_AudioEncoderFFMPEG_h + +#pragma once + + +#define FFMPEG_AUDIO_ENCODER L"AudioEncoderFFMPEG" + + +#define AUDIO_ENCODER_ENABLE_DEBUGGING L"EnableDebug" // bool (default = false) - trace some debug information if set to true +#define AUDIO_ENCODER_ENABLE_ENCODING L"EnableEncoding" // bool (default = true) - if false, component will not encode anything +#define AUDIO_ENCODER_AUDIO_CODEC_ID L"CodecID" // amf_int64 (default = AV_CODEC_ID_NONE) - FFMPEG codec ID + +#define AUDIO_ENCODER_IN_AUDIO_SAMPLE_RATE L"In_SampleRate" // amf_int64 (default = 44100) +#define AUDIO_ENCODER_IN_AUDIO_CHANNELS L"In_Channels" // amf_int64 (default = 2) +#define AUDIO_ENCODER_IN_AUDIO_SAMPLE_FORMAT L"In_SampleFormat" // amf_int64 (default = AMFAF_S16) (AMF_AUDIO_FORMAT) +#define AUDIO_ENCODER_IN_AUDIO_CHANNEL_LAYOUT L"In_ChannelLayout" // amf_int64 (default = 3) +#define AUDIO_ENCODER_IN_AUDIO_BLOCK_ALIGN L"In_BlockAlign" // amf_int64 (default = 0) + +#define AUDIO_ENCODER_OUT_AUDIO_BIT_RATE L"Out_BitRate" // amf_int64 (default = 128000) +#define AUDIO_ENCODER_OUT_AUDIO_EXTRA_DATA L"Out_ExtraData" // interface to AMFBuffer +#define AUDIO_ENCODER_OUT_AUDIO_SAMPLE_RATE L"Out_SampleRate" // amf_int64 (default = 44100) +#define AUDIO_ENCODER_OUT_AUDIO_CHANNELS L"Out_Channels" // amf_int64 (default = 2) +#define AUDIO_ENCODER_OUT_AUDIO_SAMPLE_FORMAT L"Out_SampleFormat" // amf_int64 (default = AMFAF_S16) (AMF_AUDIO_FORMAT) +#define AUDIO_ENCODER_OUT_AUDIO_CHANNEL_LAYOUT L"Out_ChannelLayout" // amf_int64 (default = 0) +#define AUDIO_ENCODER_OUT_AUDIO_BLOCK_ALIGN L"Out_BlockAlign" // amf_int64 (default = 0) +#define AUDIO_ENCODER_OUT_AUDIO_FRAME_SIZE L"Out_FrameSize" // amf_int64 (default = 0) + + + +#endif //#ifndef AMF_AudioEncoderFFMPEG_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGComponents.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGComponents.h new file mode 100644 index 000000000000..a3fbaff2b01d --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGComponents.h @@ -0,0 +1,54 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// FFMPEG components definitions +//------------------------------------------------------------------------------------------------- + +#ifndef AMF_ComponentsFFMPEG_h +#define AMF_ComponentsFFMPEG_h + +#pragma once + + +#if defined(_WIN32) + #if defined(_M_AMD64) + #define FFMPEG_DLL_NAME L"amf-component-ffmpeg64.dll" + #else + #define FFMPEG_DLL_NAME L"amf-component-ffmpeg32.dll" + #endif +#elif defined(__linux) + #define FFMPEG_DLL_NAME L"amf-component-ffmpeg.so" +#endif + + +#endif //#ifndef AMF_ComponentsFFMPEG_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGFileDemuxer.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGFileDemuxer.h new file mode 100644 index 000000000000..4b921297a79c --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGFileDemuxer.h @@ -0,0 +1,65 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// DemuxerFFMPEG interface declaration +//------------------------------------------------------------------------------------------------- +#ifndef AMF_FileDemuxerFFMPEG_h +#define AMF_FileDemuxerFFMPEG_h + +#pragma once + +#define FFMPEG_DEMUXER L"DemuxerFFMPEG" + + +// component properties +#define FFMPEG_DEMUXER_PATH L"Path" // string - the file to open +#define FFMPEG_DEMUXER_URL L"Url" // string - the stream url to open +#define FFMPEG_DEMUXER_START_FRAME L"StartFrame" // amf_int64 (default = 0) +#define FFMPEG_DEMUXER_FRAME_COUNT L"FramesNumber" // amf_int64 (default = 0) +#define FFMPEG_DEMUXER_DURATION L"Duration" // amf_int64 (default = 0) +#define FFMPEG_DEMUXER_CHECK_MVC L"CheckMVC" // bool (default = true) +//#define FFMPEG_DEMUXER_SYNC_AV L"SyncAV" // bool (default = false) +#define FFMPEG_DEMUXER_INDIVIDUAL_STREAM_MODE L"StreamMode" // bool (default = true) +#define FFMPEG_DEMUXER_LISTEN L"Listen" // bool (default = false) + +// for common, video and audio properties see Component.h + + +// video stream properties +#define FFMPEG_DEMUXER_VIDEO_PIXEL_ASPECT_RATIO L"PixelAspectRatio" // double (default = calculated) + + +// buffer properties +#define FFMPEG_DEMUXER_BUFFER_TYPE L"BufferType" // amf_int64 ( AMF_STREAM_TYPE_ENUM ) +#define FFMPEG_DEMUXER_BUFFER_STREAM_INDEX L"BufferStreamIndexType" // amf_int64 ( stream index ) +#endif //#ifndef AMF_FileDemuxerFFMPEG_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGFileMuxer.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGFileMuxer.h new file mode 100644 index 000000000000..35e9d3b66643 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/FFMPEGFileMuxer.h @@ -0,0 +1,52 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// MuxerFFMPEG interface declaration +//------------------------------------------------------------------------------------------------- +#ifndef AMF_FileMuxerFFMPEG_h +#define AMF_FileMuxerFFMPEG_h + +#pragma once + +#define FFMPEG_MUXER L"MuxerFFMPEG" + + +// component properties +#define FFMPEG_MUXER_PATH L"Path" // string - the file to open +#define FFMPEG_MUXER_URL L"Url" // string - the stream url to open +#define FFMPEG_MUXER_LISTEN L"Listen" // bool (default = false) +#define FFMPEG_MUXER_ENABLE_VIDEO L"EnableVideo" // bool (default = true) +#define FFMPEG_MUXER_ENABLE_AUDIO L"EnableAudio" // bool (default = false) + + +#endif //#ifndef AMF_FileMuxerFFMPEG_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/MediaSource.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/MediaSource.h new file mode 100644 index 000000000000..1afdb6745ef6 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/MediaSource.h @@ -0,0 +1,79 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_MediaSource_h +#define AMF_MediaSource_h + +#pragma once + +#include "public/include/core/Interface.h" + +namespace amf +{ + enum AMF_SEEK_TYPE + { + AMF_SEEK_PREV = 0, // nearest packet before pts + AMF_SEEK_NEXT = 1, // nearest packet after pts + AMF_SEEK_PREV_KEYFRAME = 2, // nearest keyframe packet before pts + AMF_SEEK_NEXT_KEYFRAME = 3, // nearest keyframe packet after pts + }; + + //---------------------------------------------------------------------------------------------- + // media source interface. + //---------------------------------------------------------------------------------------------- + class AMFMediaSource : public AMFInterface + { + public: + AMF_DECLARE_IID(0xb367695a, 0xdbd0, 0x4430, 0x95, 0x3b, 0xbc, 0x7d, 0xbd, 0x2a, 0xa7, 0x66) + + // interface + virtual AMF_RESULT AMF_STD_CALL Seek(amf_pts pos, AMF_SEEK_TYPE seekType, amf_int32 whichStream) = 0; + virtual amf_pts AMF_STD_CALL GetPosition() = 0; + virtual amf_pts AMF_STD_CALL GetDuration() = 0; + + virtual void AMF_STD_CALL SetMinPosition(amf_pts pts) = 0; + virtual amf_pts AMF_STD_CALL GetMinPosition() = 0; + virtual void AMF_STD_CALL SetMaxPosition(amf_pts pts) = 0; + virtual amf_pts AMF_STD_CALL GetMaxPosition() = 0; + + virtual amf_uint64 AMF_STD_CALL GetFrameFromPts(amf_pts pts) = 0; + virtual amf_pts AMF_STD_CALL GetPtsFromFrame(amf_uint64 frame) = 0; + + virtual bool AMF_STD_CALL SupportFramesAccess() = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFMediaSourcePtr; +} //namespace amf + +#endif //#ifndef AMF_MediaSource_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoCapture.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoCapture.h new file mode 100644 index 000000000000..db0f6c0b23fc --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoCapture.h @@ -0,0 +1,52 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// ZCamLive interface declaration +//------------------------------------------------------------------------------------------------- +#ifndef AMF_VideoCapture_h +#define AMF_VideoCapture_h + +#pragma once + +#define VIDEOCAP_DEVICE_COUNT L"VideoCapDeviceCount" // amf_int64, (default=2), number of video capture devices +#define VIDEOCAP_DEVICE_NAME L"VideoCapDeviceName" // WString, (default=""), name of the video capture device +#define VIDEOCAP_DEVICE_ACTIVE L"VideoCapDeviceActive" // WString, (default=""), name of the selected video capture device + +#define VIDEOCAP_CODEC L"CodecID" // WString (default = "AMFVideoDecoderUVD_H264_AVC"), UVD codec ID +#define VIDEOCAP_FRAMESIZE L"FrameSize" // AMFSize, (default=AMFConstructSize(1920, 1080)), frame size in pixels + +extern "C" +{ + AMF_RESULT AMF_CDECL_CALL AMFCreateComponentVideoCapture(amf::AMFContext* pContext, amf::AMFComponentEx** ppComponent); +} +#endif // AMF_VideoCapture_h \ No newline at end of file diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoConverter.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoConverter.h new file mode 100644 index 000000000000..d41f2234d8eb --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoConverter.h @@ -0,0 +1,88 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// AMFFVideoConverter interface declaration +//------------------------------------------------------------------------------------------------- +#ifndef AMF_VideoConverter_h +#define AMF_VideoConverter_h +#pragma once + +#include "Component.h" + +#define AMFVideoConverter L"AMFVideoConverter" + +enum AMF_VIDEO_CONVERTER_SCALE_ENUM +{ + AMF_VIDEO_CONVERTER_SCALE_INVALID = -1, + AMF_VIDEO_CONVERTER_SCALE_BILINEAR = 0, + AMF_VIDEO_CONVERTER_SCALE_BICUBIC = 1 +}; + +enum AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM +{ + AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN = -1, + AMF_VIDEO_CONVERTER_COLOR_PROFILE_601 = 0, + AMF_VIDEO_CONVERTER_COLOR_PROFILE_709 = 1, + AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020 = 2, + AMF_VIDEO_CONVERTER_COLOR_PROFILE_JPEG = 3, // full range + AMF_VIDEO_CONVERTER_COLOR_PROFILE_COUNT +}; + + +#define AMF_VIDEO_CONVERTER_OUTPUT_FORMAT L"OutputFormat" // Values : AMF_SURFACE_NV12 or AMF_SURFACE_BGRA or AMF_SURFACE_YUV420P +#define AMF_VIDEO_CONVERTER_MEMORY_TYPE L"MemoryType" // Values : AMF_MEMORY_DX11 or AMF_MEMORY_DX9 or AMF_MEMORY_UNKNOWN (get from input type) +#define AMF_VIDEO_CONVERTER_COMPUTE_DEVICE L"ComputeDevice" // Values : AMF_MEMORY_COMPUTE_FOR_DX9 enumeration + +#define AMF_VIDEO_CONVERTER_OUTPUT_SIZE L"OutputSize" // AMFSize (default=0,0) width in pixels. default means no scaling +#define AMF_VIDEO_CONVERTER_OUTPUT_RECT L"OutputRect" // AMFRect (default=0, 0, 0, 0) rectangle in pixels. default means no rect + +#define AMF_VIDEO_CONVERTER_KEEP_ASPECT_RATIO L"KeepAspectRatio" // bool (default=false) Keep aspect ratio if scaling. +#define AMF_VIDEO_CONVERTER_FILL L"Fill" // bool (default=false) fill area out of ROI. +#define AMF_VIDEO_CONVERTER_FILL_COLOR L"FillColor" // AMFColor + + +#define AMF_VIDEO_CONVERTER_SCALE L"ScaleType" // amf_int64(AMF_VIDEO_CONVERTER_SCALE_ENUM); default = AMF_VIDEO_CONVERTER_SCALE_BILINEAR + +#define AMF_VIDEO_CONVERTER_FORCE_OUTPUT_SURFACE_SIZE L"ForceOutputSurfaceSize" // bool (default=false) Force output size from output surface + + +#define AMF_VIDEO_CONVERTER_COLOR_PROFILE L"ColorProfile" // amf_int64(AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM); default = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN - mean AUTO + +#define AMF_VIDEO_CONVERTER_LINEAR_RGB L"LinearRGB" // bool (default=false) Convert to/from linear RGB instead of sRGB using AMF_VIDEO_DECODER_COLOR_TRANSFER_CHARACTERISTIC or by default AMF_VIDEO_CONVERTER_TRANSFER_CHARACTERISTIC +#define AMF_VIDEO_CONVERTER_TRANSFER_CHARACTERISTIC L"ColorTransferChar" // amf_int64(AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM); default = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED, ISO/IEC 23001-8_2013 7.2 See VideoDecoderUVD.h for enum +#define AMF_VIDEO_CONVERTER_DISPLAY_HDR_METADATA L"DisplayHDRMetadata" // AMFBuffer containing AMFHDRMetadata; default NULL +#define AMF_VIDEO_CONVERTER_USE_DECODER_HDR_METADATA L"UseDecoderHDRMetadata" // bool (default=true) uses decoder metadata AMF_VIDEO_DECODER_HDR_METADATA in color conversion + + + +#endif //#ifndef AMF_VideoConverter_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoDecoderUVD.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoDecoderUVD.h new file mode 100644 index 000000000000..bf96a1fda8a0 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoDecoderUVD.h @@ -0,0 +1,147 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// VideoDecoderUVD interface declaration +//------------------------------------------------------------------------------------------------- +#ifndef AMF_VideoDecoderUVD_h +#define AMF_VideoDecoderUVD_h +#pragma once + +#include "Component.h" + +#define AMFVideoDecoderUVD_MPEG2 L"AMFVideoDecoderUVD_MPEG2" +#define AMFVideoDecoderUVD_MPEG4 L"AMFVideoDecoderUVD_MPEG4" +#define AMFVideoDecoderUVD_WMV3 L"AMFVideoDecoderUVD_WMV3" +#define AMFVideoDecoderUVD_VC1 L"AMFVideoDecoderUVD_VC1" +#define AMFVideoDecoderUVD_H264_AVC L"AMFVideoDecoderUVD_H264_AVC" +#define AMFVideoDecoderUVD_H264_MVC L"AMFVideoDecoderUVD_H264_MVC" +#define AMFVideoDecoderUVD_H264_SVC L"AMFVideoDecoderUVD_H264_SVC" +#define AMFVideoDecoderUVD_MJPEG L"AMFVideoDecoderUVD_MJPEG" +#define AMFVideoDecoderHW_H265_HEVC L"AMFVideoDecoderHW_H265_HEVC" +#define AMFVideoDecoderHW_H265_MAIN10 L"AMFVideoDecoderHW_H265_MAIN10" + +enum AMF_VIDEO_DECODER_MODE_ENUM +{ + AMF_VIDEO_DECODER_MODE_REGULAR = 0, // DPB delay is based on number of reference frames + 1 (from SPS) + AMF_VIDEO_DECODER_MODE_COMPLIANT, // DPB delay is based on profile - up to 16 + AMF_VIDEO_DECODER_MODE_LOW_LATENCY, // DPB delay is 0. Expect stream with no reordering in P-Frames or B-Frames. B-frames can be present as long as they do not introduce any frame re-ordering +}; +enum AMF_TIMESTAMP_MODE_ENUM +{ + AMF_TS_PRESENTATION = 0, // default. decoder will preserve timestamps from input to output + AMF_TS_SORT, // decoder will resort PTS list + AMF_TS_DECODE // timestamps reflect decode order - decoder will reuse them +}; + +#define AMF_VIDEO_DECODER_SURFACE_COPY L"SurfaceCopy" // amf_bool; default = false; return output surfaces as a copy +#define AMF_VIDEO_DECODER_EXTRADATA L"ExtraData" // AMFInterface* -> AMFBuffer* - AVCC - size length + SPS/PPS; or as Annex B. Optional if stream is Annex B +#define AMF_VIDEO_DECODER_FRAME_RATE L"FrameRate" // amf_double; default = 0.0, optional property to restore duration in the output if needed +#define AMF_TIMESTAMP_MODE L"TimestampMode" // amf_int64(AMF_TIMESTAMP_MODE_ENUM) - default AMF_TS_PRESENTATION - how input timestamps are treated +#define AMF_VIDEO_DECODER_FULL_RANGE_COLOR L"FullRangeColor" // bool; default = false; inidicates that YUV input is (0,255) + +// dynamic/adaptive resolution change +#define AMF_VIDEO_DECODER_ADAPTIVE_RESOLUTION_CHANGE L"AdaptiveResolutionChange" // amf_bool; default = false; reuse allocated surfaces if new resolution is smaller +#define AMF_VIDEO_DECODER_ALLOC_SIZE L"AllocSize" // AMFSize; default (1920,1088); size of allocated surface if AdaptiveResolutionChange is true +#define AMF_VIDEO_DECODER_CURRENT_SIZE L"CurrentSize" // AMFSize; default = (0,0); current size of the video + +// reference frame management +#define AMF_VIDEO_DECODER_REORDER_MODE L"ReorderMode" // amf_int64(AMF_VIDEO_DECODER_MODE_ENUM); default = AMF_VIDEO_DECODER_MODE_REGULAR; defines number of surfaces in DPB list. +#define AMF_VIDEO_DECODER_SURFACE_POOL_SIZE L"SurfacePoolSize" // amf_int64; number of surfaces in the decode pool = DPB list size + number of surfaces for presentation +#define AMF_VIDEO_DECODER_DPB_SIZE L"DPBSize" // amf_int64; minimum number of surfaces for reordering + +#define AMF_VIDEO_DECODER_DEFAULT_SURFACES_FOR_TRANSIT 5 // if AMF_VIDEO_DECODER_SURFACE_POOL_SIZE is 0 , AMF_VIDEO_DECODER_SURFACE_POOL_SIZE=AMF_VIDEO_DECODER_DEFAULT_SURFACES_FOR_TRANSIT+AMF_VIDEO_DECODER_DPB_SIZE + +// Decoder capabilities - exposed in AMFCaps interface +#define AMF_VIDEO_DECODER_CAP_NUM_OF_STREAMS L"NumOfStreams" // amf_int64; maximum number of decode streams supported + + +// metadata information: can be set on output surface +enum AMF_COLOR_PRIMARIES_ENUM // as in color_primaries AVC and HEVC +{ + AMF_COLOR_PRIMARIES_UNDEFINED = 0, + AMF_COLOR_PRIMARIES_BT709 = 1, + AMF_COLOR_PRIMARIES_UNSPECIFIED = 2, + AMF_COLOR_PRIMARIES_RESERVED = 3, + AMF_COLOR_PRIMARIES_BT470M = 4, + AMF_COLOR_PRIMARIES_BT470BG = 5, + AMF_COLOR_PRIMARIES_SMPTE170M = 6, + AMF_COLOR_PRIMARIES_SMPTE240M = 7, + AMF_COLOR_PRIMARIES_FILM = 8, + AMF_COLOR_PRIMARIES_BT2020 = 9, + AMF_COLOR_PRIMARIES_SMPTE428 = 10, + AMF_COLOR_PRIMARIES_SMPTE431 = 11, + AMF_COLOR_PRIMARIES_SMPTE432 = 12, + AMF_COLOR_PRIMARIES_JEDEC_P22 = 22, +}; +enum AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM // as in transfer_characteristic AVC and HEVC +{ + AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED = 0, + AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709 = 1, + AMF_COLOR_TRANSFER_CHARACTERISTIC_UNSPECIFIED = 2, + AMF_COLOR_TRANSFER_CHARACTERISTIC_RESERVED = 3, + AMF_COLOR_TRANSFER_CHARACTERISTIC_GAMMA22 = 4, + AMF_COLOR_TRANSFER_CHARACTERISTIC_GAMMA28 = 5, + AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE170M = 6, + AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE240M = 7, + AMF_COLOR_TRANSFER_CHARACTERISTIC_LINEAR = 8, + AMF_COLOR_TRANSFER_CHARACTERISTIC_LOG = 9, + AMF_COLOR_TRANSFER_CHARACTERISTIC_LOG_SQRT = 10, + AMF_COLOR_TRANSFER_CHARACTERISTIC_IEC61966_2_4 = 11, + AMF_COLOR_TRANSFER_CHARACTERISTIC_BT1361_ECG = 12, + AMF_COLOR_TRANSFER_CHARACTERISTIC_IEC61966_2_1 = 13, + AMF_COLOR_TRANSFER_CHARACTERISTIC_BT2020_10 = 14, //BT709 curve + AMF_COLOR_TRANSFER_CHARACTERISTIC_BT2020_12 = 15, + AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084 = 16, //PQ curve + AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE428 = 17, + AMF_COLOR_TRANSFER_CHARACTERISTIC_ARIB_STD_B67 = 18, +}; + +typedef struct AMFHDRMetadata +{ + amf_uint16 redPrimary[2]; // normalized to 50000 + amf_uint16 greenPrimary[2]; // normalized to 50000 + amf_uint16 bluePrimary[2]; // normalized to 50000 + amf_uint16 whitePoint[2]; // normalized to 50000 + amf_uint32 maxMasteringLuminance; // normalized to 10000 + amf_uint32 minMasteringLuminance; // normalized to 10000 + amf_uint16 maxContentLightLevel; // nit value + amf_uint16 maxFrameAverageLightLevel; // nit value +} AMFHDRMetadata; + + +// In addition to component AMF_VIDEO_DECODER_FULL_RANGE_COLOR will be also set on surface +#define AMF_VIDEO_DECODER_COLOR_TRANSFER_CHARACTERISTIC L"ColorTransferChar" // amf_int64(AMF_COLOR_TRANSFER_CHARACTERISTIC_ENUM); default = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED, ISO/IEC 23001-8_2013 7.2 +#define AMF_VIDEO_DECODER_COLOR_PRIMARIES L"ColorPrimaries" // amf_int64(AMF_COLOR_PRIMARIES_ENUM); default = AMF_COLOR_PRIMARIES_UNDEFINED, ISO/IEC 23001-8_2013 7.1 +#define AMF_VIDEO_DECODER_HDR_METADATA L"HdrMetadata" // AMFBuffer containing AMFHDRMetadata; default NULL + +#endif //#ifndef AMF_VideoDecoderUVD_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoEncoderHEVC.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoEncoderHEVC.h new file mode 100644 index 000000000000..1059558baf93 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoEncoderHEVC.h @@ -0,0 +1,190 @@ +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// VideoEncoderHW_HEVC interface declaration +//------------------------------------------------------------------------------------------------- + +#ifndef AMF_VideoEncoderHEVC_h +#define AMF_VideoEncoderHEVC_h +#pragma once + +#include "Component.h" + +#define AMFVideoEncoder_HEVC L"AMFVideoEncoderHW_HEVC" + +enum AMF_VIDEO_ENCODER_HEVC_USAGE_ENUM +{ + AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING = 0, + AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY, + AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY, + AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM +}; + +enum AMF_VIDEO_ENCODER_HEVC_PROFILE_ENUM +{ + AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN = 1 +}; + +enum AMF_VIDEO_ENCODER_HEVC_TIER_ENUM +{ + AMF_VIDEO_ENCODER_HEVC_TIER_MAIN = 0, + AMF_VIDEO_ENCODER_HEVC_TIER_HIGH = 1 +}; + +enum AMF_VIDEO_ENCODER_LEVEL_ENUM +{ + AMF_LEVEL_1 = 30, + AMF_LEVEL_2 = 60, + AMF_LEVEL_2_1 = 63, + AMF_LEVEL_3 = 90, + AMF_LEVEL_3_1 = 93, + AMF_LEVEL_4 = 120, + AMF_LEVEL_4_1 = 123, + AMF_LEVEL_5 = 150, + AMF_LEVEL_5_1 = 153, + AMF_LEVEL_5_2 = 156, + AMF_LEVEL_6 = 180, + AMF_LEVEL_6_1 = 183, + AMF_LEVEL_6_2 = 186 +}; + +enum AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_ENUM +{ + AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_UNKNOWN = -1, + AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP = 0, + AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR, + AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR, + AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR +}; + +enum AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_ENUM +{ + AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_NONE = 0, + AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_SKIP, + AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_IDR, + AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_I, + AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_P +}; + +enum AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_ENUM +{ + AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_IDR, + AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_I, + AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_P +}; + +enum AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_ENUM +{ + AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY = 0, + AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED = 5, + AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED = 10 +}; + +enum AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_ENUM +{ + AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_NONE = 0, + AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_GOP_ALIGNED, + AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_IDR_ALIGNED +}; + + + +// Static properties - can be set before Init() +#define AMF_VIDEO_ENCODER_HEVC_FRAMESIZE L"HevcFrameSize" // AMFSize; default = 0,0; Frame size + +#define AMF_VIDEO_ENCODER_HEVC_USAGE L"HevcUsage" // amf_int64(AMF_VIDEO_ENCODER_HEVC_USAGE_ENUM); default = N/A; Encoder usage type. fully configures parameter set. +#define AMF_VIDEO_ENCODER_HEVC_PROFILE L"HevcProfile" // amf_int64(AMF_VIDEO_ENCODER_HEVC_PROFILE_ENUM) ; default = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN; +#define AMF_VIDEO_ENCODER_HEVC_TIER L"HevcTier" // amf_int64(AMF_VIDEO_ENCODER_HEVC_TIER_ENUM) ; default = AMF_VIDEO_ENCODER_HEVC_TIER_MAIN; +#define AMF_VIDEO_ENCODER_HEVC_PROFILE_LEVEL L"HevcProfileLevel" // amf_int64 (AMF_VIDEO_ENCODER_LEVEL_ENUM, default depends on HW capabilities); +#define AMF_VIDEO_ENCODER_HEVC_MAX_LTR_FRAMES L"HevcMaxOfLTRFrames" // amf_int64; default = 0; Max number of LTR frames +#define AMF_VIDEO_ENCODER_HEVC_MAX_NUM_REFRAMES L"HevcMaxNumRefFrames" // amf_int64; default = 1; Maximum number of reference frames +#define AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET L"HevcQualityPreset" // amf_int64(AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_ENUM); default = depends on USAGE; Quality Preset +#define AMF_VIDEO_ENCODER_HEVC_EXTRADATA L"HevcExtraData" // AMFInterface* - > AMFBuffer*; SPS/PPS buffer - read-only +#define AMF_VIDEO_ENCODER_HEVC_ASPECT_RATIO L"HevcAspectRatio" // AMFRatio; default = 1, 1 + +// Picture control properties +#define AMF_VIDEO_ENCODER_HEVC_NUM_GOPS_PER_IDR L"HevcGOPSPerIDR" // amf_int64; default = 1; The frequency to insert IDR as start of a GOP. 0 means no IDR will be inserted. +#define AMF_VIDEO_ENCODER_HEVC_GOP_SIZE L"HevcGOPSize" // amf_int64; default = 60; GOP Size, in frames +#define AMF_VIDEO_ENCODER_HEVC_DE_BLOCKING_FILTER_DISABLE L"HevcDeBlockingFilter" // bool; default = depends on USAGE; De-blocking Filter +#define AMF_VIDEO_ENCODER_HEVC_SLICES_PER_FRAME L"HevcSlicesPerFrame" // amf_int64; default = 1; Number of slices Per Frame +#define AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE L"HevcHeaderInsertionMode" // amf_int64(AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_ENUM); default = NONE + +// Rate control properties +#define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD L"HevcRateControlMethod" // amf_int64(AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_MODE_ENUM); default = depends on USAGE; Rate Control Method +#define AMF_VIDEO_ENCODER_HEVC_FRAMERATE L"HevcFrameRate" // AMFRate; default = depends on usage; Frame Rate +#define AMF_VIDEO_ENCODER_HEVC_VBV_BUFFER_SIZE L"HevcVBVBufferSize" // amf_int64; default = depends on USAGE; VBV Buffer Size in bits +#define AMF_VIDEO_ENCODER_HEVC_INITIAL_VBV_BUFFER_FULLNESS L"HevcInitialVBVBufferFullness" // amf_int64; default = 64; Initial VBV Buffer Fullness 0=0% 64=100% +#define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_PREANALYSIS_ENABLE L"HevcRateControlPreAnalysisEnable" // bool; default = depends on USAGE; enable Pre-analysis assisted rate control +#define AMF_VIDEO_ENCODER_HEVC_ENABLE_VBAQ L"HevcEnableVBAQ" // // bool; default = depends on USAGE; Enable auto VBAQ + +// Motion estimation +#define AMF_VIDEO_ENCODER_HEVC_MOTION_HALF_PIXEL L"HevcHalfPixel" // bool; default= true; Half Pixel +#define AMF_VIDEO_ENCODER_HEVC_MOTION_QUARTERPIXEL L"HevcQuarterPixel" // bool; default= true; Quarter Pixel + +// Dynamic properties - can be set at any time + +// Rate control properties +#define AMF_VIDEO_ENCODER_HEVC_ENFORCE_HRD L"HevcEnforceHRD" // bool; default = depends on USAGE; Enforce HRD +#define AMF_VIDEO_ENCODER_HEVC_FILLER_DATA_ENABLE L"HevcFillerDataEnable" // bool; default = depends on USAGE; Enforce HRD +#define AMF_VIDEO_ENCODER_HEVC_TARGET_BITRATE L"HevcTargetBitrate" // amf_int64; default = depends on USAGE; Target bit rate in bits +#define AMF_VIDEO_ENCODER_HEVC_PEAK_BITRATE L"HevcPeakBitrate" // amf_int64; default = depends on USAGE; Peak bit rate in bits + +#define AMF_VIDEO_ENCODER_HEVC_MAX_AU_SIZE L"HevcMaxAUSize" // amf_int64; default = 60; Max AU Size in bits + +#define AMF_VIDEO_ENCODER_HEVC_MIN_QP_I L"HevcMinQP_I" // amf_int64; default = depends on USAGE; Min QP; range = +#define AMF_VIDEO_ENCODER_HEVC_MAX_QP_I L"HevcMaxQP_I" // amf_int64; default = depends on USAGE; Max QP; range = +#define AMF_VIDEO_ENCODER_HEVC_MIN_QP_P L"HevcMinQP_P" // amf_int64; default = depends on USAGE; Min QP; range = +#define AMF_VIDEO_ENCODER_HEVC_MAX_QP_P L"HevcMaxQP_P" // amf_int64; default = depends on USAGE; Max QP; range = + +#define AMF_VIDEO_ENCODER_HEVC_QP_I L"HevcQP_I" // amf_int64; default = 26; P-frame QP; range = 0-51 +#define AMF_VIDEO_ENCODER_HEVC_QP_P L"HevcQP_P" // amf_int64; default = 26; P-frame QP; range = 0-51 + +#define AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_SKIP_FRAME_ENABLE L"HevcRateControlSkipFrameEnable" // bool; default = depends on USAGE; Rate Control Based Frame Skip + + + +// Per-submittion properties - can be set on input surface interface +#define AMF_VIDEO_ENCODER_HEVC_END_OF_SEQUENCE L"HevcEndOfSequence" // bool; default = false; generate end of sequence +#define AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE L"HevcForcePictureType" // amf_int64(AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_ENUM); default = AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_NONE; generate particular picture type +#define AMF_VIDEO_ENCODER_HEVC_INSERT_AUD L"HevcInsertAUD" // bool; default = false; insert AUD +#define AMF_VIDEO_ENCODER_HEVC_INSERT_HEADER L"HevcInsertHeader" // bool; default = false; insert header(SPS, PPS, VPS) + +#define AMF_VIDEO_ENCODER_HEVC_MARK_CURRENT_WITH_LTR_INDEX L"HevcMarkCurrentWithLTRIndex" // amf_int64; default = N/A; Mark current frame with LTR index +#define AMF_VIDEO_ENCODER_HEVC_FORCE_LTR_REFERENCE_BITFIELD L"HevcForceLTRReferenceBitfield"// amf_int64; default = 0; force LTR bit-field + +// Properties set by encoder on output buffer interface +#define AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE L"HevcOutputDataType" // amf_int64(AMF_VIDEO_ENCODER_HEVC_OUTPUT_DATA_TYPE_ENUM); default = N/A +#define AMF_VIDEO_ENCODER_HEVC_OUTPUT_MARKED_LTR_INDEX L"HevcMarkedLTRIndex" // amf_int64; default = -1; Marked LTR index +#define AMF_VIDEO_ENCODER_HEVC_OUTPUT_REFERENCED_LTR_INDEX_BITFIELD L"HevcReferencedLTRIndexBitfield"// amf_int64; default = 0; referenced LTR bit-field + +// HEVC Encoder capabilities - exposed in AMFCaps interface +#define AMF_VIDEO_ENCODER_HEVC_CAP_MAX_BITRATE L"HevcMaxBitrate" // amf_int64; Maximum bit rate in bits +#define AMF_VIDEO_ENCODER_HEVC_CAP_NUM_OF_STREAMS L"HevcNumOfStreams" // amf_int64; maximum number of encode streams supported +#define AMF_VIDEO_ENCODER_HEVC_CAP_MAX_PROFILE L"HevcMaxProfile" // amf_int64(AMF_VIDEO_ENCODER_HEVC_PROFILE_ENUM) +#define AMF_VIDEO_ENCODER_HEVC_CAP_MAX_TIER L"HevcMaxTier" // amf_int64(AMF_VIDEO_ENCODER_HEVC_TIER_ENUM) maximum profile tier +#define AMF_VIDEO_ENCODER_HEVC_CAP_MAX_LEVEL L"HevcMaxLevel" // amf_int64 maximum profile level +#define AMF_VIDEO_ENCODER_HEVC_CAP_MIN_REFERENCE_FRAMES L"HevcMinReferenceFrames" // amf_int64 minimum number of reference frames +#define AMF_VIDEO_ENCODER_HEVC_CAP_MAX_REFERENCE_FRAMES L"HevcMaxReferenceFrames" // amf_int64 maximum number of reference frames + + +#endif //#ifndef AMF_VideoEncoderHEVC_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoEncoderVCE.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoEncoderVCE.h new file mode 100644 index 000000000000..fb3c46ff7dd0 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoEncoderVCE.h @@ -0,0 +1,226 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// AMFVideoEncoderHW_AVC interface declaration +//------------------------------------------------------------------------------------------------- + +#ifndef AMF_VideoEncoderVCE_h +#define AMF_VideoEncoderVCE_h +#pragma once + +#include "Component.h" + +#define AMFVideoEncoderVCE_AVC L"AMFVideoEncoderVCE_AVC" +#define AMFVideoEncoderVCE_SVC L"AMFVideoEncoderVCE_SVC" + +enum AMF_VIDEO_ENCODER_USAGE_ENUM +{ + AMF_VIDEO_ENCODER_USAGE_TRANSCONDING = 0, + AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY, + AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY, + AMF_VIDEO_ENCODER_USAGE_WEBCAM +}; + +enum AMF_VIDEO_ENCODER_PROFILE_ENUM +{ + AMF_VIDEO_ENCODER_PROFILE_UNKNOWN = 0, + AMF_VIDEO_ENCODER_PROFILE_BASELINE = 66, + AMF_VIDEO_ENCODER_PROFILE_MAIN = 77, + AMF_VIDEO_ENCODER_PROFILE_HIGH = 100, + AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE = 256, + AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH = 257 +}; + +enum AMF_VIDEO_ENCODER_SCANTYPE_ENUM +{ + AMF_VIDEO_ENCODER_SCANTYPE_PROGRESSIVE = 0, + AMF_VIDEO_ENCODER_SCANTYPE_INTERLACED +}; + +enum AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_ENUM +{ + AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN = -1, + AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP = 0, + AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR, + AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR, + AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR +}; + +enum AMF_VIDEO_ENCODER_QUALITY_PRESET_ENUM +{ + AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED = 0, + AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED, + AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY +}; + +enum AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_ENUM +{ + AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_NONE = 0, + AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_FRAME, + AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_TOP_FIELD, + AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_BOTTOM_FIELD +}; + +enum AMF_VIDEO_ENCODER_PICTURE_TYPE_ENUM +{ + AMF_VIDEO_ENCODER_PICTURE_TYPE_NONE = 0, + AMF_VIDEO_ENCODER_PICTURE_TYPE_SKIP, + AMF_VIDEO_ENCODER_PICTURE_TYPE_IDR, + AMF_VIDEO_ENCODER_PICTURE_TYPE_I, + AMF_VIDEO_ENCODER_PICTURE_TYPE_P, + AMF_VIDEO_ENCODER_PICTURE_TYPE_B +}; + +enum AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_ENUM +{ + AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_IDR, + AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_I, + AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_P, + AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_B +}; + +enum AMF_VIDEO_ENCODER_PREENCODE_MODE_ENUM +{ + AMF_VIDEO_ENCODER_PREENCODE_DISABLED = 0, + AMF_VIDEO_ENCODER_PREENCODE_ENABLED = 1, +}; + +enum AMF_VIDEO_ENCODER_CODING_ENUM +{ + AMF_VIDEO_ENCODER_UNDEFINED = 0, // BASELINE = CALV; MAIN, HIGH = CABAC + AMF_VIDEO_ENCODER_CABAC, + AMF_VIDEO_ENCODER_CALV, + +}; + + +// Static properties - can be set before Init() + +#define AMF_VIDEO_ENCODER_FRAMESIZE L"FrameSize" // AMFSize; default = 0,0; Frame size +#define AMF_VIDEO_ENCODER_FRAMERATE L"FrameRate" // AMFRate; default = depends on usage; Frame Rate + +#define AMF_VIDEO_ENCODER_EXTRADATA L"ExtraData" // AMFInterface* - > AMFBuffer*; SPS/PPS buffer in Annex B format - read-only +#define AMF_VIDEO_ENCODER_USAGE L"Usage" // amf_int64(AMF_VIDEO_ENCODER_USAGE_ENUM); default = N/A; Encoder usage type. fully configures parameter set. +#define AMF_VIDEO_ENCODER_PROFILE L"Profile" // amf_int64(AMF_VIDEO_ENCODER_PROFILE_ENUM) ; default = AMF_VIDEO_ENCODER_PROFILE_MAIN; H264 profile +#define AMF_VIDEO_ENCODER_PROFILE_LEVEL L"ProfileLevel" // amf_int64; default = 42; H264 profile level +#define AMF_VIDEO_ENCODER_MAX_LTR_FRAMES L"MaxOfLTRFrames" // amf_int64; default = 0; Max number of LTR frames +#define AMF_VIDEO_ENCODER_SCANTYPE L"ScanType" // amf_int64(AMF_VIDEO_ENCODER_SCANTYPE_ENUM); default = AMF_VIDEO_ENCODER_SCANTYPE_PROGRESSIVE; indicates input stream type +#define AMF_VIDEO_ENCODER_MAX_NUM_REFRAMES L"MaxNumRefFrames" // amf_int64; Maximum number of reference frames +#define AMF_VIDEO_ENCODER_ASPECT_RATIO L"AspectRatio" // AMFRatio; default = 1, 1 +#define AMF_VIDEO_ENCODER_FULL_RANGE_COLOR L"FullRangeColor" // bool; default = false; inidicates that YUV input is (0,255) +#define AMF_VIDEO_ENCODER_RATE_CONTROL_PREANALYSIS_ENABLE L"RateControlPreanalysisEnable" // amf_int64(AMF_VIDEO_ENCODER_PREENCODE_MODE_ENUM); default = AMF_VIDEO_ENCODER_PREENCODE_DISABLED; controls Pre-analysis assisted rate control + + // Quality preset property +#define AMF_VIDEO_ENCODER_QUALITY_PRESET L"QualityPreset" // amf_int64(AMF_VIDEO_ENCODER_QUALITY_PRESET_ENUM); default = depends on USAGE; Quality Preset + + +// Dynamic properties - can be set at any time + + // Rate control properties +#define AMF_VIDEO_ENCODER_B_PIC_DELTA_QP L"BPicturesDeltaQP" // amf_int64; default = depends on USAGE; B-picture Delta +#define AMF_VIDEO_ENCODER_REF_B_PIC_DELTA_QP L"ReferenceBPicturesDeltaQP"// amf_int64; default = depends on USAGE; Reference B-picture Delta + +#define AMF_VIDEO_ENCODER_ENFORCE_HRD L"EnforceHRD" // bool; default = depends on USAGE; Enforce HRD +#define AMF_VIDEO_ENCODER_FILLER_DATA_ENABLE L"FillerDataEnable" // bool; default = false; Filler Data Enable +#define AMF_VIDEO_ENCODER_ENABLE_VBAQ L"EnableVBAQ" // bool; default = depends on USAGE; Enable VBAQ + + +#define AMF_VIDEO_ENCODER_VBV_BUFFER_SIZE L"VBVBufferSize" // amf_int64; default = depends on USAGE; VBV Buffer Size in bits +#define AMF_VIDEO_ENCODER_INITIAL_VBV_BUFFER_FULLNESS L"InitialVBVBufferFullness" // amf_int64; default = 64; Initial VBV Buffer Fullness 0=0% 64=100% + +#define AMF_VIDEO_ENCODER_MAX_AU_SIZE L"MaxAUSize" // amf_int64; default = 0; Max AU Size in bits + +#define AMF_VIDEO_ENCODER_MIN_QP L"MinQP" // amf_int64; default = depends on USAGE; Min QP; range = 0-51 +#define AMF_VIDEO_ENCODER_MAX_QP L"MaxQP" // amf_int64; default = depends on USAGE; Max QP; range = 0-51 +#define AMF_VIDEO_ENCODER_QP_I L"QPI" // amf_int64; default = 22; I-frame QP; range = 0-51 +#define AMF_VIDEO_ENCODER_QP_P L"QPP" // amf_int64; default = 22; P-frame QP; range = 0-51 +#define AMF_VIDEO_ENCODER_QP_B L"QPB" // amf_int64; default = 22; B-frame QP; range = 0-51 +#define AMF_VIDEO_ENCODER_TARGET_BITRATE L"TargetBitrate" // amf_int64; default = depends on USAGE; Target bit rate in bits +#define AMF_VIDEO_ENCODER_PEAK_BITRATE L"PeakBitrate" // amf_int64; default = depends on USAGE; Peak bit rate in bits +#define AMF_VIDEO_ENCODER_RATE_CONTROL_SKIP_FRAME_ENABLE L"RateControlSkipFrameEnable" // bool; default = depends on USAGE; Rate Control Based Frame Skip +#define AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD L"RateControlMethod" // amf_int64(AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_ENUM); default = depends on USAGE; Rate Control Method + + // Picture control properties +#define AMF_VIDEO_ENCODER_HEADER_INSERTION_SPACING L"HeaderInsertionSpacing" // amf_int64; default = depends on USAGE; Header Insertion Spacing; range 0-1000 +#define AMF_VIDEO_ENCODER_B_PIC_PATTERN L"BPicturesPattern" // amf_int64; default = 3; B-picture Pattern (number of B-Frames) +#define AMF_VIDEO_ENCODER_DE_BLOCKING_FILTER L"DeBlockingFilter" // bool; default = depends on USAGE; De-blocking Filter +#define AMF_VIDEO_ENCODER_B_REFERENCE_ENABLE L"BReferenceEnable" // bool; default = true; Enable Refrence to B-frames +#define AMF_VIDEO_ENCODER_IDR_PERIOD L"IDRPeriod" // amf_int64; default = depends on USAGE; IDR Period in frames +#define AMF_VIDEO_ENCODER_INTRA_REFRESH_NUM_MBS_PER_SLOT L"IntraRefreshMBsNumberPerSlot" // amf_int64; default = depends on USAGE; Intra Refresh MBs Number Per Slot in Macroblocks +#define AMF_VIDEO_ENCODER_SLICES_PER_FRAME L"SlicesPerFrame" // amf_int64; default = 1; Number of slices Per Frame +#define AMF_VIDEO_ENCODER_CABAC_ENABLE L"CABACEnable" // amf_int64(AMF_VIDEO_ENCODER_CODING_ENUM) default = AMF_VIDEO_ENCODER_UNDEFINED + + // Motion estimation +#define AMF_VIDEO_ENCODER_MOTION_HALF_PIXEL L"HalfPixel" // bool; default= true; Half Pixel +#define AMF_VIDEO_ENCODER_MOTION_QUARTERPIXEL L"QuarterPixel" // bool; default= true; Quarter Pixel + + // SVC +#define AMF_VIDEO_ENCODER_NUM_TEMPORAL_ENHANCMENT_LAYERS L"NumOfTemporalEnhancmentLayers" // amf_int64; default = 0; range = 0, min(2, caps->GetMaxNumOfTemporalLayers()) number of temporal enhancment Layers (SVC) + +// Per-submittion properties - can be set on input surface interface +#define AMF_VIDEO_ENCODER_END_OF_SEQUENCE L"EndOfSequence" // bool; default = false; generate end of sequence +#define AMF_VIDEO_ENCODER_END_OF_STREAM L"EndOfStream" // bool; default = false; generate end of stream +#define AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE L"ForcePictureType" // amf_int64(AMF_VIDEO_ENCODER_PICTURE_TYPE_ENUM); default = AMF_VIDEO_ENCODER_PICTURE_TYPE_NONE; generate particular picture type +#define AMF_VIDEO_ENCODER_INSERT_AUD L"InsertAUD" // bool; default = false; insert AUD +#define AMF_VIDEO_ENCODER_INSERT_SPS L"InsertSPS" // bool; default = false; insert SPS +#define AMF_VIDEO_ENCODER_INSERT_PPS L"InsertPPS" // bool; default = false; insert PPS +#define AMF_VIDEO_ENCODER_PICTURE_STRUCTURE L"PictureStructure" // amf_int64(AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_ENUM); default = AMF_VIDEO_ENCODER_PICTURE_STRUCTURE_FRAME; indicate picture type +#define AMF_VIDEO_ENCODER_MARK_CURRENT_WITH_LTR_INDEX L"MarkCurrentWithLTRIndex" // //amf_int64; default = N/A; Mark current frame with LTR index +#define AMF_VIDEO_ENCODER_FORCE_LTR_REFERENCE_BITFIELD L"ForceLTRReferenceBitfield"// amf_int64; default = 0; force LTR bit-field + +// properties set by encoder on output buffer interface +#define AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE L"OutputDataType" // amf_int64(AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_ENUM); default = N/A +#define AMF_VIDEO_ENCODER_OUTPUT_MARKED_LTR_INDEX L"MarkedLTRIndex" //amf_int64; default = -1; Marked LTR index +#define AMF_VIDEO_ENCODER_OUTPUT_REFERENCED_LTR_INDEX_BITFIELD L"ReferencedLTRIndexBitfield" // amf_int64; default = 0; referenced LTR bit-field + + +#define AMF_VIDEO_ENCODER_HDCP_COUNTER L"HDCPCounter" // const void* + +// Properties for multi-instance cloud gaming +#define AMF_VIDEO_ENCODER_MAX_INSTANCES L"EncoderMaxInstances" // amf_uint32; default = 1; max number of encoder instances +#define AMF_VIDEO_ENCODER_MULTI_INSTANCE_MODE L"MultiInstanceMode" // bool; default = false; +#define AMF_VIDEO_ENCODER_CURRENT_QUEUE L"MultiInstanceCurrentQueue"// amf_uin32; default = 0; + +// VCE Encoder capabilities - exposed in AMFCaps interface +#define AMF_VIDEO_ENCODER_CAP_MAX_BITRATE L"MaxBitrate" // amf_int64; Maximum bit rate in bits +#define AMF_VIDEO_ENCODER_CAP_NUM_OF_STREAMS L"NumOfStreams" // amf_int64; maximum number of encode streams supported +#define AMF_VIDEO_ENCODER_CAP_MAX_PROFILE L"MaxProfile" // AMF_VIDEO_ENCODER_PROFILE_ENUM +#define AMF_VIDEO_ENCODER_CAP_MAX_LEVEL L"MaxLevel" // amf_int64 maximum profile level +#define AMF_VIDEO_ENCODER_CAP_BFRAMES L"BFrames" // bool is B-Frames supported +#define AMF_VIDEO_ENCODER_CAP_MIN_REFERENCE_FRAMES L"MinReferenceFrames" // amf_int64 minimum number of reference frames +#define AMF_VIDEO_ENCODER_CAP_MAX_REFERENCE_FRAMES L"MaxReferenceFrames" // amf_int64 maximum number of reference frames +#define AMF_VIDEO_ENCODER_CAP_MAX_TEMPORAL_LAYERS L"MaxTemporalLayers" // amf_int64 maximum number of temporal layers +#define AMF_VIDEO_ENCODER_CAP_FIXED_SLICE_MODE L"FixedSliceMode" // bool is fixed slice mode supported +#define AMF_VIDEO_ENCODER_CAP_NUM_OF_HW_INSTANCES L"NumOfHwInstances" // amf_int64 number of HW encoder instances + +#endif //#ifndef AMF_VideoEncoderVCE_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoStitch.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoStitch.h new file mode 100644 index 000000000000..0ae2af5275e7 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/VideoStitch.h @@ -0,0 +1,124 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// +// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/** + *************************************************************************************************** + * @file VideoStitch.h + * @brief AMFVideoStitch interface declaration + *************************************************************************************************** + */ +#ifndef AMF_VideoStitch_h +#define AMF_VideoStitch_h +#pragma once + +#include "public/include/components/Component.h" + +#define AMFVideoStitch L"AMFVideoStitch" //Component name + +// static properties +#define AMF_VIDEO_STITCH_OUTPUT_FORMAT L"OutputFormat" // Values, AMF_SURFACE_BGRA or AMF_SURFACE_RGBA +#define AMF_VIDEO_STITCH_MEMORY_TYPE L"MemoryType" // Values, only AMF_MEMORY_DX11 is supported for now. +#define AMF_VIDEO_STITCH_OUTPUT_SIZE L"OutputSize" // AMFSize, (width, height) in pixels. default= (0,0), will be the same size as input. +#define AMF_VIDEO_STITCH_INPUTCOUNT L"InputCount" // amf_uint64, number of camera inputs. + +// individual camera direction and location +#define AMF_VIDEO_CAMERA_ANGLE_PITCH L"CameraPitch" // double, in radians, default = 0, camera pitch orientation +#define AMF_VIDEO_CAMERA_ANGLE_YAW L"CameraYaw" // double, in radians, default = 0, camera yaw orientation +#define AMF_VIDEO_CAMERA_ANGLE_ROLL L"CameraRoll" // double, in radians, default = 0, camera roll orientation + +#define AMF_VIDEO_CAMERA_OFFSET_X L"CameraOffsetX" // double, in pixels, default = 0, X offset of camera center of the lens from the center of the rig. +#define AMF_VIDEO_CAMERA_OFFSET_Y L"CameraOffsetY" // double, in pixels, default = 0, Y offset of camera center of the lens from the center of the rig. +#define AMF_VIDEO_CAMERA_OFFSET_Z L"CameraOffsetZ" // double, in pixels, default = 0, Z offset of camera center of the lens from the center of the rig. +#define AMF_VIDEO_CAMERA_HFOV L"CameraHFOV" // double, in radians, default = PI, - horizontal field of view +#define AMF_VIDEO_CAMERA_SCALE L"CameraScale" // double, default = 1, scale coeff + +// lens correction parameters +#define AMF_VIDEO_STITCH_LENS_CORR_K1 L"LensK1" // double, default = 0. +#define AMF_VIDEO_STITCH_LENS_CORR_K2 L"LensK2" // double, default = 0. +#define AMF_VIDEO_STITCH_LENS_CORR_K3 L"LensK3" // double, default = 0. +#define AMF_VIDEO_STITCH_LENS_CORR_OFFX L"LensOffX" // double, default = 0. +#define AMF_VIDEO_STITCH_LENS_CORR_OFFY L"LensOffY" // double, default = 0. +#define AMF_VIDEO_STITCH_CROP L"Crop" //AMFRect, in pixels default = (0,0,0,0). + +#define AMF_VIDEO_STITCH_LENS_MODE L"LensMode" // Values, AMF_VIDEO_STITCH_LENS_CORR_MODE_ENUM, (default = AMF_VIDEO_STITCH_LENS_CORR_MODE_RADIAL) + +#define AMF_VIDEO_STITCH_OUTPUT_MODE L"OutputMode" // AMF_VIDEO_STITCH_OUTPUT_MODE_ENUM (default=AMF_VIDEO_STITCH_OUTPUT_MODE_PREVIEW) +#define AMF_VIDEO_STITCH_COMBINED_SOURCE L"CombinedSource" // bool, (default=false) video sources are combined in one stream + +#define AMF_VIDEO_STITCH_COMPUTE_DEVICE L"ComputeDevice" // amf_int64(AMF_MEMORY_TYPE) Values, AMF_MEMORY_DX11, AMF_MEMORY_COMPUTE_FOR_DX11, AMF_MEMORY_OPENCL + +//for debug +#define AMF_VIDEO_STITCH_WIRE_RENDER L"Wire" // bool (default=false) reder wireframe + +//view angle +#define AMF_VIDEO_STITCH_VIEW_ROTATE_X L"AngleX" // double, in radians, default = 0 - delta from current position / automatilcally reset to 0 inside SetProperty() call +#define AMF_VIDEO_STITCH_VIEW_ROTATE_Y L"AngleY" // double, in radians, default = 0 - delta from current position / automatilcally reset to 0 inside SetProperty() call +#define AMF_VIDEO_STITCH_VIEW_ROTATE_Z L"AngleZ" // double, in radians, default = 0 - delta from current position / automatilcally reset to 0 inside SetProperty() call + +#define AMF_VIDEO_STITCH_COLOR_BALANCE L"ColorBalance" // bool (default=true) enables color balance + +//lens mode +enum AMF_VIDEO_STITCH_LENS_ENUM +{ + AMF_VIDEO_STITCH_LENS_RECTILINEAR = 0, //rect linear lens + AMF_VIDEO_STITCH_LENS_FISHEYE_FULLFRAME = 1, //fisheye full frame + AMF_VIDEO_STITCH_LENS_FISHEYE_CIRCULAR = 2, //fisheye, circular +}; + +//Output Mode +enum AMF_VIDEO_STITCH_OUTPUT_MODE_ENUM +{ + AMF_VIDEO_STITCH_OUTPUT_MODE_PREVIEW = 0, //preview mode + AMF_VIDEO_STITCH_OUTPUT_MODE_EQUIRECTANGULAR = 1, //equirectangular mode + AMF_VIDEO_STITCH_OUTPUT_MODE_CUBEMAP = 2, //cubemap mode + AMF_VIDEO_STITCH_OUTPUT_MODE_LAST = AMF_VIDEO_STITCH_OUTPUT_MODE_CUBEMAP, +}; + +//audio mode +enum AMF_VIDEO_STITCH_AUDIO_MODE_ENUM +{ + AMF_VIDEO_STITCH_AUDIO_MODE_NONE = 0, //no audio + AMF_VIDEO_STITCH_AUDIO_MODE_VIDEO = 1, //using audio from video stream + AMF_VIDEO_STITCH_AUDIO_MODE_FILE = 2, //using audio from file + AMF_VIDEO_STITCH_AUDIO_MODE_CAPTURE = 3, //using audio from capture device + AMF_VIDEO_STITCH_AUDIO_MODE_INVALID = -1, //invalid +}; + + +#if defined(_M_AMD64) + #define STITCH_DLL_NAME L"amf-stitch-64.dll" +#else + #define STITCH_DLL_NAME L"amf-stitch-32.dll" +#endif + +#endif //#ifndef AMF_VideoStitch_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/ZCamLiveStream.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/ZCamLiveStream.h new file mode 100644 index 000000000000..7f4a6bbee8a2 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/components/ZCamLiveStream.h @@ -0,0 +1,83 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +//------------------------------------------------------------------------------------------------- +// ZCamLive interface declaration +//------------------------------------------------------------------------------------------------- +#ifndef AMF_ZCamLiveStream_h +#define AMF_ZCamLiveStream_h + +#pragma once +#define ZCAMLIVE_STREAMCOUNT L"StreamCount" // amf_int64 (default = 4), number of streams +#define ZCAMLIVE_VIDEO_FRAMESIZE L"FrameSize" // AMFSize (default = AMFConstructSize(2704, 1520)), frame size +#define ZCAMLIVE_VIDEO_FRAMERATE L"FrameRate" // AMFRate (default = 30.0), video frame rate +#define ZCAMLIVE_VIDEO_BIT_RATE L"BitRate" // amf_int64 (default = 3000000), video bitrate +#define ZCAMLIVE_STREAM_ACTIVE_CAMERA L"ActiveCamera" // amf_int64 (default = -1, all the cameras), the index of the camera to capture +#define ZCAMLIVE_STREAM_FRAMECOUNT L"FrameCount" // amf_int64 (default = 0), number of frames captured +#define ZCAMLIVE_CODEC_ID L"CodecID" // WString (default = "AMFVideoDecoderUVD_H264_AVC"), UVD codec ID +#define ZCAMLIVE_VIDEO_MODE L"VideoMode" // Enum (default = 0, 2K7P30), ZCam mode +#define ZCAMLIVE_AUDIO_MODE L"AudioMode" // Enum (default = 0, Silent) - Audio mode +#define ZCAMLIVE_LOWLATENCY L"LowLatency" // amf_int64 (default = 1, LowLatency), low latency flag +#define ZCAMLIVE_IP_0 L"ZCamIP_00" // WString, IP address of the #1 stream, default "10.98.32.1" +#define ZCAMLIVE_IP_1 L"ZCamIP_01" // WString, IP address of the #2 stream, default "10.98.32.2" +#define ZCAMLIVE_IP_2 L"ZCamIP_02" // WString, IP address of the #3 stream, default "10.98.32.3" +#define ZCAMLIVE_IP_3 L"ZCamIP_03" // WString, IP address of the #4 stream, default "10.98.32.4" + +//Camera live capture Mode +enum CAMLIVE_MODE_ENUM +{ + CAMLIVE_MODE_ZCAM_1080P24 = 0, //1920x1080, 24FPS + CAMLIVE_MODE_ZCAM_1080P30, //1920x1080, 30FPS + CAMLIVE_MODE_ZCAM_1080P60, //1920x1080, 60FPS + CAMLIVE_MODE_ZCAM_2K7P24, //2704x1520, 24FPS + CAMLIVE_MODE_ZCAM_2K7P30, //2704x1520, 24FPS + CAMLIVE_MODE_ZCAM_2K7P60, //2704x1520, 24FPS + CAMLIVE_MODE_ZCAM_2544P24, //3392x2544, 24FPS + CAMLIVE_MODE_ZCAM_2544P30, //3392x2544, 24FPS + CAMLIVE_MODE_ZCAM_2544P60, //3392x2544, 24FPS + CAMLIVE_MODE_THETAS, //Ricoh TheataS + CAMLIVE_MODE_THETAV, //Ricoh TheataV + CAMLIVE_MODE_INVALID = -1, +}; + +enum CAM_AUDIO_MODE_ENUM +{ + CAM_AUDIO_MODE_NONE = 0, //None + CAM_AUDIO_MODE_SILENT, //Silent audio + CAM_AUDIO_MODE_CAMERA //Capture from camera, not supported yet +}; + +extern "C" +{ + AMF_RESULT AMF_CDECL_CALL AMFCreateComponentZCamLiveStream(amf::AMFContext* pContext, amf::AMFComponentEx** ppComponent); +} +#endif // AMF_ZCamLiveStream_h \ No newline at end of file diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/AudioBuffer.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/AudioBuffer.h new file mode 100644 index 000000000000..2d0f6f0ecc25 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/AudioBuffer.h @@ -0,0 +1,184 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_AudioBuffer_h +#define AMF_AudioBuffer_h +#pragma once + +#include "Data.h" +#if defined(_MSC_VER) + #pragma warning( push ) + #pragma warning(disable : 4263) + #pragma warning(disable : 4264) +#endif +#if defined(__cplusplus) +namespace amf +{ +#endif + typedef enum AMF_AUDIO_FORMAT + { + AMFAF_UNKNOWN =-1, + AMFAF_U8 = 0, // amf_uint8 + AMFAF_S16 = 1, // amf_int16 + AMFAF_S32 = 2, // amf_int32 + AMFAF_FLT = 3, // amf_float + AMFAF_DBL = 4, // amf_double + + AMFAF_U8P = 5, // amf_uint8 + AMFAF_S16P = 6, // amf_int16 + AMFAF_S32P = 7, // amf_int32 + AMFAF_FLTP = 8, // amf_float + AMFAF_DBLP = 9, // amf_double + AMFAF_FIRST = AMFAF_U8, + AMFAF_LAST = AMFAF_DBLP, + } AMF_AUDIO_FORMAT; + + //---------------------------------------------------------------------------------------------- + // AMFAudioBufferObserver interface - callback + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMFAudioBuffer; + class AMF_NO_VTABLE AMFAudioBufferObserver + { + public: + virtual void AMF_STD_CALL OnBufferDataRelease(AMFAudioBuffer* pBuffer) = 0; + }; +#else // #if defined(__cplusplus) + typedef struct AMFAudioBuffer AMFAudioBuffer; + typedef struct AMFAudioBufferObserver AMFAudioBufferObserver; + typedef struct AMFAudioBufferObserverVtbl + { + void (AMF_STD_CALL *OnBufferDataRelease)(AMFAudioBufferObserver* pThis, AMFAudioBuffer* pBuffer); + } AMFAudioBufferObserverVtbl; + + struct AMFAudioBufferObserver + { + const AMFAudioBufferObserverVtbl *pVtbl; + }; + +#endif // #if defined(__cplusplus) + //---------------------------------------------------------------------------------------------- + // AudioBuffer interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFAudioBuffer : public AMFData + { + public: + AMF_DECLARE_IID(0x2212ff8, 0x6107, 0x430b, 0xb6, 0x3c, 0xc7, 0xe5, 0x40, 0xe5, 0xf8, 0xeb) + + virtual amf_int32 AMF_STD_CALL GetSampleCount() = 0; + virtual amf_int32 AMF_STD_CALL GetSampleRate() = 0; + virtual amf_int32 AMF_STD_CALL GetChannelCount() = 0; + virtual AMF_AUDIO_FORMAT AMF_STD_CALL GetSampleFormat() = 0; + virtual amf_int32 AMF_STD_CALL GetSampleSize() = 0; + virtual amf_uint32 AMF_STD_CALL GetChannelLayout() = 0; + virtual void* AMF_STD_CALL GetNative() = 0; + virtual amf_size AMF_STD_CALL GetSize() = 0; + + // Observer management + virtual void AMF_STD_CALL AddObserver(AMFAudioBufferObserver* pObserver) = 0; + virtual void AMF_STD_CALL RemoveObserver(AMFAudioBufferObserver* pObserver) = 0; + + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFAudioBufferPtr; + //---------------------------------------------------------------------------------------------- +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFAudioBuffer, 0x2212ff8, 0x6107, 0x430b, 0xb6, 0x3c, 0xc7, 0xe5, 0x40, 0xe5, 0xf8, 0xeb) + + typedef struct AMFAudioBufferVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFAudioBuffer* pThis); + amf_long (AMF_STD_CALL *Release)(AMFAudioBuffer* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFAudioBuffer* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFPropertyStorage interface + AMF_RESULT (AMF_STD_CALL *SetProperty)(AMFAudioBuffer* pThis, const wchar_t* name, AMFVariantStruct value); + AMF_RESULT (AMF_STD_CALL *GetProperty)(AMFAudioBuffer* pThis, const wchar_t* name, AMFVariantStruct* pValue); + amf_bool (AMF_STD_CALL *HasProperty)(AMFAudioBuffer* pThis, const wchar_t* name); + amf_size (AMF_STD_CALL *GetPropertyCount)(AMFAudioBuffer* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyAt)(AMFAudioBuffer* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue); + AMF_RESULT (AMF_STD_CALL *Clear)(AMFAudioBuffer* pThis); + AMF_RESULT (AMF_STD_CALL *AddTo)(AMFAudioBuffer* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep); + AMF_RESULT (AMF_STD_CALL *CopyTo)(AMFAudioBuffer* pThis, AMFPropertyStorage* pDest, amf_bool deep); + void (AMF_STD_CALL *AddObserver)(AMFAudioBuffer* pThis, AMFPropertyStorageObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver)(AMFAudioBuffer* pThis, AMFPropertyStorageObserver* pObserver); + + // AMFData interface + + AMF_MEMORY_TYPE (AMF_STD_CALL *GetMemoryType)(AMFAudioBuffer* pThis); + + AMF_RESULT (AMF_STD_CALL *Duplicate)(AMFAudioBuffer* pThis, AMF_MEMORY_TYPE type, AMFData** ppData); + AMF_RESULT (AMF_STD_CALL *Convert)(AMFAudioBuffer* pThis, AMF_MEMORY_TYPE type); // optimal interop if possilble. Copy through host memory if needed + AMF_RESULT (AMF_STD_CALL *Interop)(AMFAudioBuffer* pThis, AMF_MEMORY_TYPE type); // only optimal interop if possilble. No copy through host memory for GPU objects + + AMF_DATA_TYPE (AMF_STD_CALL *GetDataType)(AMFAudioBuffer* pThis); + + amf_bool (AMF_STD_CALL *IsReusable)(AMFAudioBuffer* pThis); + + void (AMF_STD_CALL *SetPts)(AMFAudioBuffer* pThis, amf_pts pts); + amf_pts (AMF_STD_CALL *GetPts)(AMFAudioBuffer* pThis); + void (AMF_STD_CALL *SetDuration)(AMFAudioBuffer* pThis, amf_pts duration); + amf_pts (AMF_STD_CALL *GetDuration)(AMFAudioBuffer* pThis); + + // AMFAudioBuffer interface + + amf_int32 (AMF_STD_CALL *GetSampleCount)(AMFAudioBuffer* pThis); + amf_int32 (AMF_STD_CALL *GetSampleRate)(AMFAudioBuffer* pThis); + amf_int32 (AMF_STD_CALL *GetChannelCount)(AMFAudioBuffer* pThis); + AMF_AUDIO_FORMAT (AMF_STD_CALL *GetSampleFormat)(AMFAudioBuffer* pThis); + amf_int32 (AMF_STD_CALL *GetSampleSize)(AMFAudioBuffer* pThis); + amf_uint32 (AMF_STD_CALL *GetChannelLayout)(AMFAudioBuffer* pThis); + void* (AMF_STD_CALL *GetNative)(AMFAudioBuffer* pThis); + amf_size (AMF_STD_CALL *GetSize)(AMFAudioBuffer* pThis); + + // Observer management + void (AMF_STD_CALL *AddObserver_AudioBuffer)(AMFAudioBuffer* pThis, AMFAudioBufferObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver_AudioBuffer)(AMFAudioBuffer* pThis, AMFAudioBufferObserver* pObserver); + + } AMFAudioBufferVtbl; + + struct AMFAudioBuffer + { + const AMFAudioBufferVtbl *pVtbl; + }; +#endif // #if defined(__cplusplus) +#if defined(__cplusplus) +} // namespace +#endif +#if defined(_MSC_VER) + #pragma warning( pop ) +#endif +#endif //#ifndef AMF_AudioBuffer_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Buffer.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Buffer.h new file mode 100644 index 000000000000..fd893ea1b366 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Buffer.h @@ -0,0 +1,179 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_Buffer_h +#define AMF_Buffer_h +#pragma once + +#include "Data.h" + +#if defined(_MSC_VER) + #pragma warning( push ) + #pragma warning(disable : 4263) + #pragma warning(disable : 4264) +#endif +#if defined(__cplusplus) +namespace amf +{ +#endif + + //---------------------------------------------------------------------------------------------- + // AMF_BUFFER_USAGE translates to D3D11_BIND_FLAG or VkBufferUsageFlagBits + // bit mask + //---------------------------------------------------------------------------------------------- + typedef enum AMF_BUFFER_USAGE_BITS + { // D3D11 Vulkan + AMF_BUFFER_USAGE_DEFAULT = 0x80000000, // D3D11_USAGE_STAGING, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT + AMF_BUFFER_USAGE_NONE = 0x00000000, // 0 , 0 + AMF_BUFFER_USAGE_CONSTANT = 0x00000001, // D3D11_BIND_CONSTANT_BUFFER, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT + AMF_BUFFER_USAGE_SHADER_RESOURCE = 0x00000002, // D3D11_BIND_SHADER_RESOURCE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT + AMF_BUFFER_USAGE_UNORDERED_ACCESS = 0x00000004, // D3D11_BIND_UNORDERED_ACCESS, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT + AMF_BUFFER_USAGE_TRANSFER_SRC = 0x00000008, // VK_BUFFER_USAGE_TRANSFER_SRC_BIT + AMF_BUFFER_USAGE_TRANSFER_DST = 0x00000010, // VK_BUFFER_USAGE_TRANSFER_DST_BIT + } AMF_BUFFER_USAGE_BITS; + typedef amf_flags AMF_BUFFER_USAGE; + //---------------------------------------------------------------------------------------------- + + + //---------------------------------------------------------------------------------------------- + // AMFBufferObserver interface - callback + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMFBuffer; + class AMF_NO_VTABLE AMFBufferObserver + { + public: + virtual void AMF_STD_CALL OnBufferDataRelease(AMFBuffer* pBuffer) = 0; + }; +#else // #if defined(__cplusplus) + typedef struct AMFBuffer AMFBuffer; + typedef struct AMFBufferObserver AMFBufferObserver; + + typedef struct AMFBufferObserverVtbl + { + void (AMF_STD_CALL *OnBufferDataRelease)(AMFBufferObserver* pThis, AMFBuffer* pBuffer); + } AMFBufferObserverVtbl; + + struct AMFBufferObserver + { + const AMFBufferObserverVtbl *pVtbl; + }; + +#endif // #if defined(__cplusplus) + + //---------------------------------------------------------------------------------------------- + // AMFBuffer interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFBuffer : public AMFData + { + public: + AMF_DECLARE_IID(0xb04b7248, 0xb6f0, 0x4321, 0xb6, 0x91, 0xba, 0xa4, 0x74, 0xf, 0x9f, 0xcb) + + virtual AMF_RESULT AMF_STD_CALL SetSize(amf_size newSize) = 0; + virtual amf_size AMF_STD_CALL GetSize() = 0; + virtual void* AMF_STD_CALL GetNative() = 0; + + // Observer management + virtual void AMF_STD_CALL AddObserver(AMFBufferObserver* pObserver) = 0; + virtual void AMF_STD_CALL RemoveObserver(AMFBufferObserver* pObserver) = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFBufferPtr; + //---------------------------------------------------------------------------------------------- + +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFBuffer, 0xb04b7248, 0xb6f0, 0x4321, 0xb6, 0x91, 0xba, 0xa4, 0x74, 0xf, 0x9f, 0xcb) + + typedef struct AMFBufferVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFBuffer* pThis); + amf_long (AMF_STD_CALL *Release)(AMFBuffer* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFBuffer* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFPropertyStorage interface + AMF_RESULT (AMF_STD_CALL *SetProperty)(AMFBuffer* pThis, const wchar_t* name, AMFVariantStruct value); + AMF_RESULT (AMF_STD_CALL *GetProperty)(AMFBuffer* pThis, const wchar_t* name, AMFVariantStruct* pValue); + amf_bool (AMF_STD_CALL *HasProperty)(AMFBuffer* pThis, const wchar_t* name); + amf_size (AMF_STD_CALL *GetPropertyCount)(AMFBuffer* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyAt)(AMFBuffer* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue); + AMF_RESULT (AMF_STD_CALL *Clear)(AMFBuffer* pThis); + AMF_RESULT (AMF_STD_CALL *AddTo)(AMFBuffer* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep); + AMF_RESULT (AMF_STD_CALL *CopyTo)(AMFBuffer* pThis, AMFPropertyStorage* pDest, amf_bool deep); + void (AMF_STD_CALL *AddObserver)(AMFBuffer* pThis, AMFPropertyStorageObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver)(AMFBuffer* pThis, AMFPropertyStorageObserver* pObserver); + + // AMFData interface + + AMF_MEMORY_TYPE (AMF_STD_CALL *GetMemoryType)(AMFBuffer* pThis); + + AMF_RESULT (AMF_STD_CALL *Duplicate)(AMFBuffer* pThis, AMF_MEMORY_TYPE type, AMFData** ppData); + AMF_RESULT (AMF_STD_CALL *Convert)(AMFBuffer* pThis, AMF_MEMORY_TYPE type); // optimal interop if possilble. Copy through host memory if needed + AMF_RESULT (AMF_STD_CALL *Interop)(AMFBuffer* pThis, AMF_MEMORY_TYPE type); // only optimal interop if possilble. No copy through host memory for GPU objects + + AMF_DATA_TYPE (AMF_STD_CALL *GetDataType)(AMFBuffer* pThis); + + amf_bool (AMF_STD_CALL *IsReusable)(AMFBuffer* pThis); + + void (AMF_STD_CALL *SetPts)(AMFBuffer* pThis, amf_pts pts); + amf_pts (AMF_STD_CALL *GetPts)(AMFBuffer* pThis); + void (AMF_STD_CALL *SetDuration)(AMFBuffer* pThis, amf_pts duration); + amf_pts (AMF_STD_CALL *GetDuration)(AMFBuffer* pThis); + + // AMFBuffer interface + + AMF_RESULT (AMF_STD_CALL *SetSize)(AMFBuffer* pThis, amf_size newSize); + amf_size (AMF_STD_CALL *GetSize)(AMFBuffer* pThis); + void* (AMF_STD_CALL *GetNative)(AMFBuffer* pThis); + + // Observer management + void (AMF_STD_CALL *AddObserver_Buffer)(AMFBuffer* pThis, AMFBufferObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver_Buffer)(AMFBuffer* pThis, AMFBufferObserver* pObserver); + + } AMFBufferVtbl; + + struct AMFBuffer + { + const AMFBufferVtbl *pVtbl; + }; + +#endif // #if defined(__cplusplus) +#if defined(__cplusplus) +} // namespace +#endif +#if defined(_MSC_VER) + #pragma warning( pop ) +#endif +#endif //#ifndef AMF_Buffer_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Compute.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Compute.h new file mode 100644 index 000000000000..daac4078dde3 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Compute.h @@ -0,0 +1,302 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/** + *************************************************************************************************** + * @file Compute.h + * @brief AMFCompute interface declaration + *************************************************************************************************** + */ +#ifndef AMF_Compute_h +#define AMF_Compute_h +#pragma once + +#include "Buffer.h" +#include "Surface.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif + typedef amf_uint64 AMF_KERNEL_ID; + + //---------------------------------------------------------------------------------------------- + // enumerations for plane conversion + //---------------------------------------------------------------------------------------------- + typedef enum AMF_CHANNEL_ORDER + { + AMF_CHANNEL_ORDER_INVALID = 0, + AMF_CHANNEL_ORDER_R = 1, + AMF_CHANNEL_ORDER_RG = 2, + AMF_CHANNEL_ORDER_BGRA = 3, + AMF_CHANNEL_ORDER_RGBA = 4, + AMF_CHANNEL_ORDER_ARGB = 5, + AMF_CHANNEL_ORDER_YUY2 = 6, + } AMF_CHANNEL_ORDER; + //---------------------------------------------------------------------------------------------- + typedef enum AMF_CHANNEL_TYPE + { + AMF_CHANNEL_INVALID = 0, + AMF_CHANNEL_UNSIGNED_INT8 = 1, + AMF_CHANNEL_UNSIGNED_INT32 = 2, + AMF_CHANNEL_UNORM_INT8 = 3, + AMF_CHANNEL_UNORM_INT16 = 4, + AMF_CHANNEL_SNORM_INT16 = 5, + AMF_CHANNEL_FLOAT = 6, + AMF_CHANNEL_FLOAT16 = 7, + AMF_CHANNEL_UNSIGNED_INT16 = 8, +} AMF_CHANNEL_TYPE; + //---------------------------------------------------------------------------------------------- +#define AMF_STRUCTURED_BUFFER_FORMAT L"StructuredBufferFormat" // amf_int64(AMF_CHANNEL_TYPE), default - AMF_CHANNEL_UNSIGNED_INT32; to be set on AMFBuffer objects +#if defined(_WIN32) + AMF_WEAK GUID AMFStructuredBufferFormatGUID = { 0x90c5d674, 0xe90, 0x4181, 0xbd, 0xef, 0x26, 0x13, 0xc1, 0xdf, 0xa3, 0xbd }; // UINT(DXGI_FORMAT), default - DXGI_FORMAT_R32_UINT; to be set on ID3D11Buffer or ID3D11Texture2D objects when used natively +#endif + //---------------------------------------------------------------------------------------------- + // enumeration argument type + //---------------------------------------------------------------------------------------------- + typedef enum AMF_ARGUMENT_ACCESS_TYPE + { + AMF_ARGUMENT_ACCESS_READ = 0, + AMF_ARGUMENT_ACCESS_WRITE = 1, + AMF_ARGUMENT_ACCESS_READWRITE = 2, + AMF_ARGUMENT_ACCESS_READWRITE_MASK = 0xFFFF, + //Sampler parameters + AMF_ARGUMENT_SAMPLER_LINEAR = 0x10000000, + AMF_ARGUMENT_SAMPLER_NORM_COORD = 0x20000000, + AMF_ARGUMENT_SAMPLER_POINT = 0x40000000, + AMF_ARGUMENT_SAMPLER_MASK = 0xFFFF0000, + } AMF_ARGUMENT_ACCESS_TYPE; + //---------------------------------------------------------------------------------------------- + // AMFComputeKernel interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFComputeKernel : public AMFInterface + { + public: + AMF_DECLARE_IID(0x94815701, 0x6c84, 0x4ba6, 0xa9, 0xfe, 0xe9, 0xad, 0x40, 0xf8, 0x8, 0x8) + + virtual void* AMF_STD_CALL GetNative() = 0; + virtual const wchar_t* AMF_STD_CALL GetIDName() = 0; + + virtual AMF_RESULT AMF_STD_CALL SetArgPlaneNative(amf_size index, void* pPlane, AMF_ARGUMENT_ACCESS_TYPE eAccess) = 0; + virtual AMF_RESULT AMF_STD_CALL SetArgBufferNative(amf_size index, void* pBuffer, AMF_ARGUMENT_ACCESS_TYPE eAccess) = 0; + + virtual AMF_RESULT AMF_STD_CALL SetArgPlane(amf_size index, AMFPlane* pPlane, AMF_ARGUMENT_ACCESS_TYPE eAccess) = 0; + virtual AMF_RESULT AMF_STD_CALL SetArgBuffer(amf_size index, AMFBuffer* pBuffer, AMF_ARGUMENT_ACCESS_TYPE eAccess) = 0; + + virtual AMF_RESULT AMF_STD_CALL SetArgInt32(amf_size index, amf_int32 data) = 0; + virtual AMF_RESULT AMF_STD_CALL SetArgInt64(amf_size index, amf_int64 data) = 0; + virtual AMF_RESULT AMF_STD_CALL SetArgFloat(amf_size index, amf_float data) = 0; + virtual AMF_RESULT AMF_STD_CALL SetArgBlob(amf_size index, amf_size dataSize, const void* pData) = 0; + + virtual AMF_RESULT AMF_STD_CALL GetCompileWorkgroupSize(amf_size workgroupSize[3]) = 0; + + virtual AMF_RESULT AMF_STD_CALL Enqueue(amf_size dimension, amf_size globalOffset[3], amf_size globalSize[3], amf_size localSize[3]) = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFComputeKernelPtr; +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFComputeKernel, 0x94815701, 0x6c84, 0x4ba6, 0xa9, 0xfe, 0xe9, 0xad, 0x40, 0xf8, 0x8, 0x8) + typedef struct AMFComputeKernel AMFComputeKernel; + + typedef struct AMFComputeKernelVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFComputeKernel* pThis); + amf_long (AMF_STD_CALL *Release)(AMFComputeKernel* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFComputeKernel* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFComputeKernel interface + + } AMFComputeKernelVtbl; + + struct AMFComputeKernel + { + const AMFComputeKernelVtbl *pVtbl; + }; + +#endif //#if defined(__cplusplus) + + //---------------------------------------------------------------------------------------------- + // AMFComputeSyncPoint interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFComputeSyncPoint : public AMFInterface + { + public: + AMF_DECLARE_IID(0x66f33fe6, 0xaae, 0x4e65, 0xba, 0x3, 0xea, 0x8b, 0xa3, 0x60, 0x11, 0x2) + + virtual amf_bool AMF_STD_CALL IsCompleted() = 0; + virtual void AMF_STD_CALL Wait() = 0; + }; + typedef AMFInterfacePtr_T AMFComputeSyncPointPtr; +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFComputeSyncPoint, 0x66f33fe6, 0xaae, 0x4e65, 0xba, 0x3, 0xea, 0x8b, 0xa3, 0x60, 0x11, 0x2) + typedef struct AMFComputeSyncPoint AMFComputeSyncPoint; + + typedef struct AMFComputeSyncPointVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFComputeSyncPoint* pThis); + amf_long (AMF_STD_CALL *Release)(AMFComputeSyncPoint* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFComputeSyncPoint* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFComputeSyncPoint interface + amf_bool (AMF_STD_CALL *IsCompleted)(AMFComputeSyncPoint* pThis); + void (AMF_STD_CALL *Wait)(AMFComputeSyncPoint* pThis); + + } AMFComputeSyncPointVtbl; + + struct AMFComputeSyncPoint + { + const AMFComputeSyncPointVtbl *pVtbl; + }; + +#endif // #if defined(__cplusplus) + + //---------------------------------------------------------------------------------------------- + // AMFCompute interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFCompute : public AMFInterface + { + public: + AMF_DECLARE_IID(0x3846233a, 0x3f43, 0x443f, 0x8a, 0x45, 0x75, 0x22, 0x11, 0xa9, 0xfb, 0xd5) + + virtual AMF_MEMORY_TYPE AMF_STD_CALL GetMemoryType() = 0; + + virtual void* AMF_STD_CALL GetNativeContext() = 0; + virtual void* AMF_STD_CALL GetNativeDeviceID() = 0; + virtual void* AMF_STD_CALL GetNativeCommandQueue() = 0; + + virtual AMF_RESULT AMF_STD_CALL GetKernel(AMF_KERNEL_ID kernelID, AMFComputeKernel** kernel) = 0; + + virtual AMF_RESULT AMF_STD_CALL PutSyncPoint(AMFComputeSyncPoint** ppSyncPoint) = 0; + virtual AMF_RESULT AMF_STD_CALL FinishQueue() = 0; + virtual AMF_RESULT AMF_STD_CALL FlushQueue() = 0; + + virtual AMF_RESULT AMF_STD_CALL FillPlane(AMFPlane *pPlane, const amf_size origin[3], const amf_size region[3], const void* pColor) = 0; + virtual AMF_RESULT AMF_STD_CALL FillBuffer(AMFBuffer* pBuffer, amf_size dstOffset, amf_size dstSize, const void* pSourcePattern, amf_size patternSize) = 0; + virtual AMF_RESULT AMF_STD_CALL ConvertPlaneToBuffer(AMFPlane *pSrcPlane, AMFBuffer** ppDstBuffer) = 0; + + virtual AMF_RESULT AMF_STD_CALL CopyBuffer(AMFBuffer* pSrcBuffer, amf_size srcOffset, amf_size size, AMFBuffer* pDstBuffer, amf_size dstOffset) = 0; + virtual AMF_RESULT AMF_STD_CALL CopyPlane(AMFPlane *pSrcPlane, const amf_size srcOrigin[3], const amf_size region[3], AMFPlane *pDstPlane, const amf_size dstOrigin[3]) = 0; + + virtual AMF_RESULT AMF_STD_CALL CopyBufferToHost(AMFBuffer* pSrcBuffer, amf_size srcOffset, amf_size size, void* pDest, amf_bool blocking) = 0; + virtual AMF_RESULT AMF_STD_CALL CopyBufferFromHost(const void* pSource, amf_size size, AMFBuffer* pDstBuffer, amf_size dstOffsetInBytes, amf_bool blocking) = 0; + + virtual AMF_RESULT AMF_STD_CALL CopyPlaneToHost(AMFPlane *pSrcPlane, const amf_size origin[3], const amf_size region[3], void* pDest, amf_size dstPitch, amf_bool blocking) = 0; + virtual AMF_RESULT AMF_STD_CALL CopyPlaneFromHost(void* pSource, const amf_size origin[3], const amf_size region[3], amf_size srcPitch, AMFPlane *pDstPlane, amf_bool blocking) = 0; + + virtual AMF_RESULT AMF_STD_CALL ConvertPlaneToPlane(AMFPlane* pSrcPlane, AMFPlane** ppDstPlane, AMF_CHANNEL_ORDER order, AMF_CHANNEL_TYPE type) = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFComputePtr; +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFCompute, 0x3846233a, 0x3f43, 0x443f, 0x8a, 0x45, 0x75, 0x22, 0x11, 0xa9, 0xfb, 0xd5) + typedef struct AMFCompute AMFCompute; + + typedef struct AMFComputeVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFCompute* pThis); + amf_long (AMF_STD_CALL *Release)(AMFCompute* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFCompute* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFCompute interface + AMF_MEMORY_TYPE (AMF_STD_CALL *GetMemoryType)(AMFCompute* pThis); + void* (AMF_STD_CALL *GetNativeContext)(AMFCompute* pThis); + void* (AMF_STD_CALL *GetNativeDeviceID)(AMFCompute* pThis); + void* (AMF_STD_CALL *GetNativeCommandQueue)(AMFCompute* pThis); + AMF_RESULT (AMF_STD_CALL *GetKernel)(AMFCompute* pThis, AMF_KERNEL_ID kernelID, AMFComputeKernel** kernel); + AMF_RESULT (AMF_STD_CALL *PutSyncPoint)(AMFCompute* pThis, AMFComputeSyncPoint** ppSyncPoint); + AMF_RESULT (AMF_STD_CALL *FinishQueue)(AMFCompute* pThis); + AMF_RESULT (AMF_STD_CALL *FlushQueue)(AMFCompute* pThis); + AMF_RESULT (AMF_STD_CALL *FillPlane)(AMFCompute* pThis, AMFPlane *pPlane, const amf_size origin[3], const amf_size region[3], const void* pColor); + AMF_RESULT (AMF_STD_CALL *FillBuffer)(AMFCompute* pThis, AMFBuffer* pBuffer, amf_size dstOffset, amf_size dstSize, const void* pSourcePattern, amf_size patternSize); + AMF_RESULT (AMF_STD_CALL *ConvertPlaneToBuffer)(AMFCompute* pThis, AMFPlane *pSrcPlane, AMFBuffer** ppDstBuffer); + AMF_RESULT (AMF_STD_CALL *CopyBuffer)(AMFCompute* pThis, AMFBuffer* pSrcBuffer, amf_size srcOffset, amf_size size, AMFBuffer* pDstBuffer, amf_size dstOffset); + AMF_RESULT (AMF_STD_CALL *CopyPlane)(AMFCompute* pThis, AMFPlane *pSrcPlane, const amf_size srcOrigin[3], const amf_size region[3], AMFPlane *pDstPlane, const amf_size dstOrigin[3]); + AMF_RESULT (AMF_STD_CALL *CopyBufferToHost)(AMFCompute* pThis, AMFBuffer* pSrcBuffer, amf_size srcOffset, amf_size size, void* pDest, amf_bool blocking); + AMF_RESULT (AMF_STD_CALL *CopyBufferFromHost)(AMFCompute* pThis, const void* pSource, amf_size size, AMFBuffer* pDstBuffer, amf_size dstOffsetInBytes, amf_bool blocking); + AMF_RESULT (AMF_STD_CALL *CopyPlaneToHost)(AMFCompute* pThis, AMFPlane *pSrcPlane, const amf_size origin[3], const amf_size region[3], void* pDest, amf_size dstPitch, amf_bool blocking); + AMF_RESULT (AMF_STD_CALL *CopyPlaneFromHost)(AMFCompute* pThis, void* pSource, const amf_size origin[3], const amf_size region[3], amf_size srcPitch, AMFPlane *pDstPlane, amf_bool blocking); + AMF_RESULT (AMF_STD_CALL *ConvertPlaneToPlane)(AMFCompute* pThis, AMFPlane* pSrcPlane, AMFPlane** ppDstPlane, AMF_CHANNEL_ORDER order, AMF_CHANNEL_TYPE type); + } AMFComputeVtbl; + + struct AMFCompute + { + const AMFComputeVtbl *pVtbl; + }; + +#endif // #if defined(__cplusplus) + + //---------------------------------------------------------------------------------------------- + // AMFPrograms interface - singleton + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFPrograms + { + public: + virtual AMF_RESULT AMF_STD_CALL RegisterKernelSourceFile(AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, const wchar_t* filepath, const char* options) = 0; + virtual AMF_RESULT AMF_STD_CALL RegisterKernelSource(AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options) = 0; + virtual AMF_RESULT AMF_STD_CALL RegisterKernelBinary(AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options) = 0; + virtual AMF_RESULT AMF_STD_CALL RegisterKernelSource1(AMF_MEMORY_TYPE eMemoryType, AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options) = 0; + virtual AMF_RESULT AMF_STD_CALL RegisterKernelBinary1(AMF_MEMORY_TYPE eMemoryType, AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options) = 0; + }; +#else // #if defined(__cplusplus) + typedef struct AMFPrograms AMFPrograms; + typedef struct AMFProgramsVtbl + { + AMF_RESULT (AMF_STD_CALL *RegisterKernelSourceFile)(AMFPrograms* pThis, AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, const wchar_t* filepath, const char* options); + AMF_RESULT (AMF_STD_CALL *RegisterKernelSource)(AMFPrograms* pThis, AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options); + AMF_RESULT (AMF_STD_CALL *RegisterKernelBinary)(AMFPrograms* pThis, AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options); + AMF_RESULT (AMF_STD_CALL *RegisterKernelSource1)(AMFPrograms* pThis, AMF_MEMORY_TYPE eMemoryType, AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options); + AMF_RESULT (AMF_STD_CALL *RegisterKernelBinary1)(AMFPrograms* pThis, AMF_MEMORY_TYPE eMemoryType, AMF_KERNEL_ID* pKernelID, const wchar_t* kernelid_name, const char* kernelName, amf_size dataSize, const amf_uint8* data, const char* options); + } AMFProgramsVtbl; + + struct AMFPrograms + { + const AMFProgramsVtbl *pVtbl; + }; +#endif // #if defined(__cplusplus) + + +#if defined(__cplusplus) +} // namespace amf +#endif + +#endif // AMF_Compute_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/ComputeFactory.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/ComputeFactory.h new file mode 100644 index 000000000000..d126f270a8d2 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/ComputeFactory.h @@ -0,0 +1,147 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_ComputeFactory_h +#define AMF_ComputeFactory_h +#pragma once + +#include "Compute.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif +// compute device audio capabilities accessed via GetProperties() from AMFComputeDevice +#define AMF_DEVICE_NAME L"DeviceName" // char*, string, device name +#define AMF_DRIVER_VERSION_NAME L"DriverVersion" // char*, string, driver version +#define AMF_AUDIO_CONVOLUTION_MAX_STREAMS L"ConvolutionMaxStreams" // amf_int64, maximum number of audio streams supported in realtime +#define AMF_AUDIO_CONVOLUTION_LENGTH L"ConvolutionLength" // amf_int64, length of convolution in samples +#define AMF_AUDIO_CONVOLUTION_BUFFER_SIZE L"ConvolutionBufferSize" // amf_int64, buffer size in samples +#define AMF_AUDIO_CONVOLUTION_SAMPLE_RATE L"ConvolutionSampleRate" // amf_int64, sample rate + +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFComputeDevice : public AMFPropertyStorage + { + public: + AMF_DECLARE_IID(0xb79d7cf6, 0x2c5c, 0x4deb, 0xb8, 0x96, 0xa2, 0x9e, 0xbe, 0xa6, 0xe3, 0x97); + + virtual void* AMF_STD_CALL GetNativePlatform() = 0; + virtual void* AMF_STD_CALL GetNativeDeviceID() = 0; + virtual void* AMF_STD_CALL GetNativeContext() = 0; + + virtual AMF_RESULT AMF_STD_CALL CreateCompute(void *reserved, AMFCompute **ppCompute) = 0; + virtual AMF_RESULT AMF_STD_CALL CreateComputeEx(void* pCommandQueue, AMFCompute **ppCompute) = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFComputeDevicePtr; +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFComputeDevice, 0xb79d7cf6, 0x2c5c, 0x4deb, 0xb8, 0x96, 0xa2, 0x9e, 0xbe, 0xa6, 0xe3, 0x97); + typedef struct AMFComputeDevice AMFComputeDevice; + + typedef struct AMFComputeDeviceVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFComputeDevice* pThis); + amf_long (AMF_STD_CALL *Release)(AMFComputeDevice* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFComputeDevice* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFPropertyStorage interface + AMF_RESULT (AMF_STD_CALL *SetProperty)(AMFComputeDevice* pThis, const wchar_t* name, AMFVariantStruct value); + AMF_RESULT (AMF_STD_CALL *GetProperty)(AMFComputeDevice* pThis, const wchar_t* name, AMFVariantStruct* pValue); + amf_bool (AMF_STD_CALL *HasProperty)(AMFComputeDevice* pThis, const wchar_t* name); + amf_size (AMF_STD_CALL *GetPropertyCount)(AMFComputeDevice* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyAt)(AMFComputeDevice* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue); + AMF_RESULT (AMF_STD_CALL *Clear)(AMFComputeDevice* pThis); + AMF_RESULT (AMF_STD_CALL *AddTo)(AMFComputeDevice* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep); + AMF_RESULT (AMF_STD_CALL *CopyTo)(AMFComputeDevice* pThis, AMFPropertyStorage* pDest, amf_bool deep); + void (AMF_STD_CALL *AddObserver)(AMFComputeDevice* pThis, AMFPropertyStorageObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver)(AMFComputeDevice* pThis, AMFPropertyStorageObserver* pObserver); + + // AMFComputeDevice interface + void* (AMF_STD_CALL *GetNativePlatform)(AMFComputeDevice* pThis); + void* (AMF_STD_CALL *GetNativeDeviceID)(AMFComputeDevice* pThis); + void* (AMF_STD_CALL *GetNativeContext)(AMFComputeDevice* pThis); + + AMF_RESULT (AMF_STD_CALL *CreateCompute)(AMFComputeDevice* pThis, void *reserved, AMFCompute **ppCompute); + AMF_RESULT (AMF_STD_CALL *CreateComputeEx)(AMFComputeDevice* pThis, void* pCommandQueue, AMFCompute **ppCompute); + + } AMFComputeDeviceVtbl; + + struct AMFComputeDevice + { + const AMFComputeDeviceVtbl *pVtbl; + }; +#endif // #if defined(__cplusplus) + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFComputeFactory : public AMFInterface + { + public: + AMF_DECLARE_IID(0xe3c24bd7, 0x2d83, 0x416c, 0x8c, 0x4e, 0xfd, 0x13, 0xca, 0x86, 0xf4, 0xd0); + + virtual amf_int32 AMF_STD_CALL GetDeviceCount() = 0; + virtual AMF_RESULT AMF_STD_CALL GetDeviceAt(amf_int32 index, AMFComputeDevice **ppDevice) = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFComputeFactoryPtr; +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFComputeFactory, 0xe3c24bd7, 0x2d83, 0x416c, 0x8c, 0x4e, 0xfd, 0x13, 0xca, 0x86, 0xf4, 0xd0); + typedef struct AMFComputeFactory AMFComputeFactory; + + typedef struct AMFComputeFactoryVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFComputeFactory* pThis); + amf_long (AMF_STD_CALL *Release)(AMFComputeFactory* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFComputeFactory* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFComputeFactory interface + amf_int32 (AMF_STD_CALL *GetDeviceCount)(AMFComputeFactory* pThis); + AMF_RESULT (AMF_STD_CALL *GetDeviceAt)(AMFComputeFactory* pThis, amf_int32 index, AMFComputeDevice **ppDevice); + } AMFComputeFactoryVtbl; + + struct AMFComputeFactory + { + const AMFComputeFactoryVtbl *pVtbl; + }; +#endif // #if defined(__cplusplus) + + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) +}; // namespace amf +#endif + +#endif // AMF_ComputeFactory_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Context.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Context.h new file mode 100644 index 000000000000..f38a7123ea04 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Context.h @@ -0,0 +1,619 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_Context_h +#define AMF_Context_h +#pragma once + +#include "Buffer.h" +#include "AudioBuffer.h" +#include "Surface.h" +#include "Compute.h" +#include "ComputeFactory.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif + //---------------------------------------------------------------------------------------------- + // AMFContext interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFContext : public AMFPropertyStorage + { + public: + AMF_DECLARE_IID(0xa76a13f0, 0xd80e, 0x4fcc, 0xb5, 0x8, 0x65, 0xd0, 0xb5, 0x2e, 0xd9, 0xee) + + // Cleanup + virtual AMF_RESULT AMF_STD_CALL Terminate() = 0; + + // DX9 + virtual AMF_RESULT AMF_STD_CALL InitDX9(void* pDX9Device) = 0; + virtual void* AMF_STD_CALL GetDX9Device(AMF_DX_VERSION dxVersionRequired = AMF_DX9) = 0; + virtual AMF_RESULT AMF_STD_CALL LockDX9() = 0; + virtual AMF_RESULT AMF_STD_CALL UnlockDX9() = 0; + class AMFDX9Locker; + + // DX11 + virtual AMF_RESULT AMF_STD_CALL InitDX11(void* pDX11Device, AMF_DX_VERSION dxVersionRequired = AMF_DX11_0) = 0; + virtual void* AMF_STD_CALL GetDX11Device(AMF_DX_VERSION dxVersionRequired = AMF_DX11_0) = 0; + virtual AMF_RESULT AMF_STD_CALL LockDX11() = 0; + virtual AMF_RESULT AMF_STD_CALL UnlockDX11() = 0; + class AMFDX11Locker; + + // OpenCL + virtual AMF_RESULT AMF_STD_CALL InitOpenCL(void* pCommandQueue = NULL) = 0; + virtual void* AMF_STD_CALL GetOpenCLContext() = 0; + virtual void* AMF_STD_CALL GetOpenCLCommandQueue() = 0; + virtual void* AMF_STD_CALL GetOpenCLDeviceID() = 0; + virtual AMF_RESULT AMF_STD_CALL GetOpenCLComputeFactory(AMFComputeFactory **ppFactory) = 0; // advanced compute - multiple queries + virtual AMF_RESULT AMF_STD_CALL InitOpenCLEx(AMFComputeDevice *pDevice) = 0; + virtual AMF_RESULT AMF_STD_CALL LockOpenCL() = 0; + virtual AMF_RESULT AMF_STD_CALL UnlockOpenCL() = 0; + class AMFOpenCLLocker; + + // OpenGL + virtual AMF_RESULT AMF_STD_CALL InitOpenGL(amf_handle hOpenGLContext, amf_handle hWindow, amf_handle hDC) = 0; + virtual amf_handle AMF_STD_CALL GetOpenGLContext() = 0; + virtual amf_handle AMF_STD_CALL GetOpenGLDrawable() = 0; + virtual AMF_RESULT AMF_STD_CALL LockOpenGL() = 0; + virtual AMF_RESULT AMF_STD_CALL UnlockOpenGL() = 0; + class AMFOpenGLLocker; + + // XV - Linux + virtual AMF_RESULT AMF_STD_CALL InitXV(void* pXVDevice) = 0; + virtual void* AMF_STD_CALL GetXVDevice() = 0; + virtual AMF_RESULT AMF_STD_CALL LockXV() = 0; + virtual AMF_RESULT AMF_STD_CALL UnlockXV() = 0; + class AMFXVLocker; + + // Gralloc - Android + virtual AMF_RESULT AMF_STD_CALL InitGralloc(void* pGrallocDevice) = 0; + virtual void* AMF_STD_CALL GetGrallocDevice() = 0; + virtual AMF_RESULT AMF_STD_CALL LockGralloc() = 0; + virtual AMF_RESULT AMF_STD_CALL UnlockGralloc() = 0; + class AMFGrallocLocker; + + // Allocation + virtual AMF_RESULT AMF_STD_CALL AllocBuffer(AMF_MEMORY_TYPE type, amf_size size, AMFBuffer** ppBuffer) = 0; + virtual AMF_RESULT AMF_STD_CALL AllocSurface(AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, AMFSurface** ppSurface) = 0; + virtual AMF_RESULT AMF_STD_CALL AllocAudioBuffer(AMF_MEMORY_TYPE type, AMF_AUDIO_FORMAT format, amf_int32 samples, amf_int32 sampleRate, amf_int32 channels, + AMFAudioBuffer** ppAudioBuffer) = 0; + + // Wrap existing objects + virtual AMF_RESULT AMF_STD_CALL CreateBufferFromHostNative(void* pHostBuffer, amf_size size, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver) = 0; + virtual AMF_RESULT AMF_STD_CALL CreateSurfaceFromHostNative(AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, amf_int32 hPitch, amf_int32 vPitch, void* pData, + AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0; + virtual AMF_RESULT AMF_STD_CALL CreateSurfaceFromDX9Native(void* pDX9Surface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0; + virtual AMF_RESULT AMF_STD_CALL CreateSurfaceFromDX11Native(void* pDX11Surface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0; + virtual AMF_RESULT AMF_STD_CALL CreateSurfaceFromOpenGLNative(AMF_SURFACE_FORMAT format, amf_handle hGLTextureID, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0; + virtual AMF_RESULT AMF_STD_CALL CreateSurfaceFromGrallocNative(amf_handle hGrallocSurface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0; + virtual AMF_RESULT AMF_STD_CALL CreateSurfaceFromOpenCLNative(AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, void** pClPlanes, + AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0; + virtual AMF_RESULT AMF_STD_CALL CreateBufferFromOpenCLNative(void* pCLBuffer, amf_size size, AMFBuffer** ppBuffer) = 0; + + // Access to AMFCompute interface - AMF_MEMORY_OPENCL, AMF_MEMORY_COMPUTE_FOR_DX9, AMF_MEMORY_COMPUTE_FOR_DX11 are currently supported + virtual AMF_RESULT AMF_STD_CALL GetCompute(AMF_MEMORY_TYPE eMemType, AMFCompute** ppCompute) = 0; + }; + + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFContextPtr; + + //---------------------------------------------------------------------------------------------- + // AMFContext1 interface + //---------------------------------------------------------------------------------------------- + + class AMF_NO_VTABLE AMFContext1 : public AMFContext + { + public: + AMF_DECLARE_IID(0xd9e9f868, 0x6220, 0x44c6, 0xa2, 0x2f, 0x7c, 0xd6, 0xda, 0xc6, 0x86, 0x46) + + virtual AMF_RESULT AMF_STD_CALL CreateBufferFromDX11Native(void* pHostBuffer, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver) = 0; + + virtual AMF_RESULT AMF_STD_CALL AllocBufferEx(AMF_MEMORY_TYPE type, amf_size size, AMF_BUFFER_USAGE usage, AMF_MEMORY_CPU_ACCESS access, AMFBuffer** ppBuffer) = 0; + virtual AMF_RESULT AMF_STD_CALL AllocSurfaceEx(AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, AMF_SURFACE_USAGE usage, AMF_MEMORY_CPU_ACCESS access, AMFSurface** ppSurface) = 0; + + // Vulkan - Windows, Linux + virtual AMF_RESULT AMF_STD_CALL InitVulkan(void* pVulkanDevice) = 0; + virtual void* AMF_STD_CALL GetVulkanDevice() = 0; + virtual AMF_RESULT AMF_STD_CALL LockVulkan() = 0; + virtual AMF_RESULT AMF_STD_CALL UnlockVulkan() = 0; + + virtual AMF_RESULT AMF_STD_CALL CreateSurfaceFromVulkanNative(void* pVulkanImage, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver) = 0; + virtual AMF_RESULT AMF_STD_CALL CreateBufferFromVulkanNative(void* pVulkanBuffer, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver) = 0; + virtual AMF_RESULT AMF_STD_CALL GetVulkanDeviceExtensions(amf_size *pCount, const char **ppExtensions) = 0; + + + class AMFVulkanLocker; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFContext1Ptr; + +#else + typedef struct AMFContext AMFContext; + AMF_DECLARE_IID(AMFContext, 0xa76a13f0, 0xd80e, 0x4fcc, 0xb5, 0x8, 0x65, 0xd0, 0xb5, 0x2e, 0xd9, 0xee) + + typedef struct AMFContextVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFContext* pThis); + amf_long (AMF_STD_CALL *Release)(AMFContext* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFContext* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFInterface AMFPropertyStorage + + AMF_RESULT (AMF_STD_CALL *SetProperty)(AMFContext* pThis, const wchar_t* name, AMFVariantStruct value); + AMF_RESULT (AMF_STD_CALL *GetProperty)(AMFContext* pThis, const wchar_t* name, AMFVariantStruct* pValue); + amf_bool (AMF_STD_CALL *HasProperty)(AMFContext* pThis, const wchar_t* name); + amf_size (AMF_STD_CALL *GetPropertyCount)(AMFContext* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyAt)(AMFContext* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue); + AMF_RESULT (AMF_STD_CALL *Clear)(AMFContext* pThis); + AMF_RESULT (AMF_STD_CALL *AddTo)(AMFContext* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep); + AMF_RESULT (AMF_STD_CALL *CopyTo)(AMFContext* pThis, AMFPropertyStorage* pDest, amf_bool deep); + void (AMF_STD_CALL *AddObserver)(AMFContext* pThis, AMFPropertyStorageObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver)(AMFContext* pThis, AMFPropertyStorageObserver* pObserver); + + // AMFContext interface + + // Cleanup + AMF_RESULT (AMF_STD_CALL *Terminate)(AMFContext* pThis); + + // DX9 + AMF_RESULT (AMF_STD_CALL *InitDX9)(AMFContext* pThis, void* pDX9Device); + void* (AMF_STD_CALL *GetDX9Device)(AMFContext* pThis, AMF_DX_VERSION dxVersionRequired); + AMF_RESULT (AMF_STD_CALL *LockDX9)(AMFContext* pThis); + AMF_RESULT (AMF_STD_CALL *UnlockDX9)(AMFContext* pThis); + // DX11 + AMF_RESULT (AMF_STD_CALL *InitDX11)(AMFContext* pThis, void* pDX11Device, AMF_DX_VERSION dxVersionRequired); + void* (AMF_STD_CALL *GetDX11Device)(AMFContext* pThis, AMF_DX_VERSION dxVersionRequired); + AMF_RESULT (AMF_STD_CALL *LockDX11)(AMFContext* pThis); + AMF_RESULT (AMF_STD_CALL *UnlockDX11)(AMFContext* pThis); + + // OpenCL + AMF_RESULT (AMF_STD_CALL *InitOpenCL)(AMFContext* pThis, void* pCommandQueue); + void* (AMF_STD_CALL *GetOpenCLContext)(AMFContext* pThis); + void* (AMF_STD_CALL *GetOpenCLCommandQueue)(AMFContext* pThis); + void* (AMF_STD_CALL *GetOpenCLDeviceID)(AMFContext* pThis); + AMF_RESULT (AMF_STD_CALL *GetOpenCLComputeFactory)(AMFContext* pThis, AMFComputeFactory **ppFactory); // advanced compute - multiple queries + AMF_RESULT (AMF_STD_CALL *InitOpenCLEx)(AMFContext* pThis, AMFComputeDevice *pDevice); + AMF_RESULT (AMF_STD_CALL *LockOpenCL)(AMFContext* pThis); + AMF_RESULT (AMF_STD_CALL *UnlockOpenCL)(AMFContext* pThis); + + // OpenGL + AMF_RESULT (AMF_STD_CALL *InitOpenGL)(AMFContext* pThis, amf_handle hOpenGLContext, amf_handle hWindow, amf_handle hDC); + amf_handle (AMF_STD_CALL *GetOpenGLContext)(AMFContext* pThis); + amf_handle (AMF_STD_CALL *GetOpenGLDrawable)(AMFContext* pThis); + AMF_RESULT (AMF_STD_CALL *LockOpenGL)(AMFContext* pThis); + AMF_RESULT (AMF_STD_CALL *UnlockOpenGL)(AMFContext* pThis); + // XV - Linux + AMF_RESULT (AMF_STD_CALL *InitXV)(AMFContext* pThis, void* pXVDevice); + void* (AMF_STD_CALL *GetXVDevice)(AMFContext* pThis); + AMF_RESULT (AMF_STD_CALL *LockXV)(AMFContext* pThis); + AMF_RESULT (AMF_STD_CALL *UnlockXV)(AMFContext* pThis); + + // Gralloc - Android + AMF_RESULT (AMF_STD_CALL *InitGralloc)(AMFContext* pThis, void* pGrallocDevice); + void* (AMF_STD_CALL *GetGrallocDevice)(AMFContext* pThis); + AMF_RESULT (AMF_STD_CALL *LockGralloc)(AMFContext* pThis); + AMF_RESULT (AMF_STD_CALL *UnlockGralloc)(AMFContext* pThis); + // Allocation + AMF_RESULT (AMF_STD_CALL *AllocBuffer)(AMFContext* pThis, AMF_MEMORY_TYPE type, amf_size size, AMFBuffer** ppBuffer); + AMF_RESULT (AMF_STD_CALL *AllocSurface)(AMFContext* pThis, AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, AMFSurface** ppSurface); + AMF_RESULT (AMF_STD_CALL *AllocAudioBuffer)(AMFContext* pThis, AMF_MEMORY_TYPE type, AMF_AUDIO_FORMAT format, amf_int32 samples, amf_int32 sampleRate, amf_int32 channels, + AMFAudioBuffer** ppAudioBuffer); + + // Wrap existing objects + AMF_RESULT (AMF_STD_CALL *CreateBufferFromHostNative)(AMFContext* pThis, void* pHostBuffer, amf_size size, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateSurfaceFromHostNative)(AMFContext* pThis, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, amf_int32 hPitch, amf_int32 vPitch, void* pData, + AMFSurface** ppSurface, AMFSurfaceObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateSurfaceFromDX9Native)(AMFContext* pThis, void* pDX9Surface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateSurfaceFromDX11Native)(AMFContext* pThis, void* pDX11Surface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateSurfaceFromOpenGLNative)(AMFContext* pThis, AMF_SURFACE_FORMAT format, amf_handle hGLTextureID, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateSurfaceFromGrallocNative)(AMFContext* pThis, amf_handle hGrallocSurface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateSurfaceFromOpenCLNative)(AMFContext* pThis, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, void** pClPlanes, + AMFSurface** ppSurface, AMFSurfaceObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateBufferFromOpenCLNative)(AMFContext* pThis, void* pCLBuffer, amf_size size, AMFBuffer** ppBuffer); + + // Access to AMFCompute interface - AMF_MEMORY_OPENCL, AMF_MEMORY_COMPUTE_FOR_DX9, AMF_MEMORY_COMPUTE_FOR_DX11 are currently supported + AMF_RESULT (AMF_STD_CALL *GetCompute)(AMFContext* pThis, AMF_MEMORY_TYPE eMemType, AMFCompute** ppCompute); + + } AMFContextVtbl; + + struct AMFContext + { + const AMFContextVtbl *pVtbl; + }; + + + typedef struct AMFContext1 AMFContext1; + AMF_DECLARE_IID(AMFContext1, 0xd9e9f868, 0x6220, 0x44c6, 0xa2, 0x2f, 0x7c, 0xd6, 0xda, 0xc6, 0x86, 0x46) + + typedef struct AMFContext1Vtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFContext1* pThis); + amf_long (AMF_STD_CALL *Release)(AMFContext1* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFContext1* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFInterface AMFPropertyStorage + + AMF_RESULT (AMF_STD_CALL *SetProperty)(AMFContext1* pThis, const wchar_t* name, AMFVariantStruct value); + AMF_RESULT (AMF_STD_CALL *GetProperty)(AMFContext1* pThis, const wchar_t* name, AMFVariantStruct* pValue); + amf_bool (AMF_STD_CALL *HasProperty)(AMFContext1* pThis, const wchar_t* name); + amf_size (AMF_STD_CALL *GetPropertyCount)(AMFContext1* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyAt)(AMFContext1* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue); + AMF_RESULT (AMF_STD_CALL *Clear)(AMFContext1* pThis); + AMF_RESULT (AMF_STD_CALL *AddTo)(AMFContext1* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep); + AMF_RESULT (AMF_STD_CALL *CopyTo)(AMFContext1* pThis, AMFPropertyStorage* pDest, amf_bool deep); + void (AMF_STD_CALL *AddObserver)(AMFContext1* pThis, AMFPropertyStorageObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver)(AMFContext1* pThis, AMFPropertyStorageObserver* pObserver); + + // AMFContext interface + + // Cleanup + AMF_RESULT (AMF_STD_CALL *Terminate)(AMFContext1* pThis); + + // DX9 + AMF_RESULT (AMF_STD_CALL *InitDX9)(AMFContext1* pThis, void* pDX9Device); + void* (AMF_STD_CALL *GetDX9Device)(AMFContext1* pThis, AMF_DX_VERSION dxVersionRequired); + AMF_RESULT (AMF_STD_CALL *LockDX9)(AMFContext1* pThis); + AMF_RESULT (AMF_STD_CALL *UnlockDX9)(AMFContext1* pThis); + // DX11 + AMF_RESULT (AMF_STD_CALL *InitDX11)(AMFContext1* pThis, void* pDX11Device, AMF_DX_VERSION dxVersionRequired); + void* (AMF_STD_CALL *GetDX11Device)(AMFContext1* pThis, AMF_DX_VERSION dxVersionRequired); + AMF_RESULT (AMF_STD_CALL *LockDX11)(AMFContext1* pThis); + AMF_RESULT (AMF_STD_CALL *UnlockDX11)(AMFContext1* pThis); + + // OpenCL + AMF_RESULT (AMF_STD_CALL *InitOpenCL)(AMFContext1* pThis, void* pCommandQueue); + void* (AMF_STD_CALL *GetOpenCLContext)(AMFContext1* pThis); + void* (AMF_STD_CALL *GetOpenCLCommandQueue)(AMFContext1* pThis); + void* (AMF_STD_CALL *GetOpenCLDeviceID)(AMFContext1* pThis); + AMF_RESULT (AMF_STD_CALL *GetOpenCLComputeFactory)(AMFContext1* pThis, AMFComputeFactory **ppFactory); // advanced compute - multiple queries + AMF_RESULT (AMF_STD_CALL *InitOpenCLEx)(AMFContext1* pThis, AMFComputeDevice *pDevice); + AMF_RESULT (AMF_STD_CALL *LockOpenCL)(AMFContext1* pThis); + AMF_RESULT (AMF_STD_CALL *UnlockOpenCL)(AMFContext1* pThis); + + // OpenGL + AMF_RESULT (AMF_STD_CALL *InitOpenGL)(AMFContext1* pThis, amf_handle hOpenGLContext, amf_handle hWindow, amf_handle hDC); + amf_handle (AMF_STD_CALL *GetOpenGLContext)(AMFContext1* pThis); + amf_handle (AMF_STD_CALL *GetOpenGLDrawable)(AMFContext1* pThis); + AMF_RESULT (AMF_STD_CALL *LockOpenGL)(AMFContext1* pThis); + AMF_RESULT (AMF_STD_CALL *UnlockOpenGL)(AMFContext1* pThis); + // XV - Linux + AMF_RESULT (AMF_STD_CALL *InitXV)(AMFContext1* pThis, void* pXVDevice); + void* (AMF_STD_CALL *GetXVDevice)(AMFContext1* pThis); + AMF_RESULT (AMF_STD_CALL *LockXV)(AMFContext1* pThis); + AMF_RESULT (AMF_STD_CALL *UnlockXV)(AMFContext1* pThis); + + // Gralloc - Android + AMF_RESULT (AMF_STD_CALL *InitGralloc)(AMFContext1* pThis, void* pGrallocDevice); + void* (AMF_STD_CALL *GetGrallocDevice)(AMFContext1* pThis); + AMF_RESULT (AMF_STD_CALL *LockGralloc)(AMFContext1* pThis); + AMF_RESULT (AMF_STD_CALL *UnlockGralloc)(AMFContext1* pThis); + // Allocation + AMF_RESULT (AMF_STD_CALL *AllocBuffer)(AMFContext1* pThis, AMF_MEMORY_TYPE type, amf_size size, AMFBuffer** ppBuffer); + AMF_RESULT (AMF_STD_CALL *AllocSurface)(AMFContext1* pThis, AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, AMFSurface** ppSurface); + AMF_RESULT (AMF_STD_CALL *AllocAudioBuffer)(AMFContext1* pThis, AMF_MEMORY_TYPE type, AMF_AUDIO_FORMAT format, amf_int32 samples, amf_int32 sampleRate, amf_int32 channels, + AMFAudioBuffer** ppAudioBuffer); + + // Wrap existing objects + AMF_RESULT (AMF_STD_CALL *CreateBufferFromHostNative)(AMFContext1* pThis, void* pHostBuffer, amf_size size, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateSurfaceFromHostNative)(AMFContext1* pThis, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, amf_int32 hPitch, amf_int32 vPitch, void* pData, + AMFSurface** ppSurface, AMFSurfaceObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateSurfaceFromDX9Native)(AMFContext1* pThis, void* pDX9Surface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateSurfaceFromDX11Native)(AMFContext1* pThis, void* pDX11Surface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateSurfaceFromOpenGLNative)(AMFContext1* pThis, AMF_SURFACE_FORMAT format, amf_handle hGLTextureID, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateSurfaceFromGrallocNative)(AMFContext1* pThis, amf_handle hGrallocSurface, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateSurfaceFromOpenCLNative)(AMFContext1* pThis, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, void** pClPlanes, + AMFSurface** ppSurface, AMFSurfaceObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateBufferFromOpenCLNative)(AMFContext1* pThis, void* pCLBuffer, amf_size size, AMFBuffer** ppBuffer); + + // Access to AMFCompute interface - AMF_MEMORY_OPENCL, AMF_MEMORY_COMPUTE_FOR_DX9, AMF_MEMORY_COMPUTE_FOR_DX11 are currently supported + AMF_RESULT (AMF_STD_CALL *GetCompute)(AMFContext1* pThis, AMF_MEMORY_TYPE eMemType, AMFCompute** ppCompute); + + // AMFContext1 interface + + AMF_RESULT (AMF_STD_CALL *CreateBufferFromDX11Native)(AMFContext1* pThis, void* pHostBuffer, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *AllocBufferEx)(AMFContext1* pThis, AMF_MEMORY_TYPE type, amf_size size, AMF_BUFFER_USAGE usage, AMF_MEMORY_CPU_ACCESS access, AMFBuffer** ppBuffer); + AMF_RESULT (AMF_STD_CALL *AllocSurfaceEx)(AMFContext1* pThis, AMF_MEMORY_TYPE type, AMF_SURFACE_FORMAT format, amf_int32 width, amf_int32 height, AMF_SURFACE_USAGE usage, AMF_MEMORY_CPU_ACCESS access, AMFSurface** ppSurface); + + // Vulkan - Windows, Linux + AMF_RESULT (AMF_STD_CALL *InitVulkan)(AMFContext1* pThis, void* pVulkanDevice); + void* (AMF_STD_CALL *GetVulkanDevice)(AMFContext1* pThis); + AMF_RESULT (AMF_STD_CALL *LockVulkan)(AMFContext1* pThis); + AMF_RESULT (AMF_STD_CALL *UnlockVulkan)(AMFContext1* pThis); + + AMF_RESULT (AMF_STD_CALL *CreateSurfaceFromVulkanNative)(AMFContext1* pThis, void* pVulkanImage, AMFSurface** ppSurface, AMFSurfaceObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *CreateBufferFromVulkanNative)(AMFContext1* pThis, void* pVulkanBuffer, AMFBuffer** ppBuffer, AMFBufferObserver* pObserver); + AMF_RESULT (AMF_STD_CALL *GetVulkanDeviceExtensions)(AMFContext1* pThis, amf_size *pCount, const char **ppExtensions); + + } AMFContext1Vtbl; + + struct AMFContext1 + { + const AMFContext1Vtbl *pVtbl; + }; + + +#endif + +#if defined(__cplusplus) + //---------------------------------------------------------------------------------------------- + // Lockers + //---------------------------------------------------------------------------------------------- + class AMFContext::AMFDX9Locker + { + public: + AMFDX9Locker() : m_Context(NULL) + {} + AMFDX9Locker(AMFContext* resources) : m_Context(NULL) + { + Lock(resources); + } + ~AMFDX9Locker() + { + if(m_Context != NULL) + { + m_Context->UnlockDX9(); + } + } + void Lock(AMFContext* resources) + { + if(m_Context != NULL) + { + m_Context->UnlockDX9(); + } + m_Context = resources; + if(m_Context != NULL) + { + m_Context->LockDX9(); + } + } + protected: + AMFContext* m_Context; + + private: + AMFDX9Locker(const AMFDX9Locker&); + AMFDX9Locker& operator=(const AMFDX9Locker&); + }; + //---------------------------------------------------------------------------------------------- + class AMFContext::AMFDX11Locker + { + public: + AMFDX11Locker() : m_Context(NULL) + {} + AMFDX11Locker(AMFContext* resources) : m_Context(NULL) + { + Lock(resources); + } + ~AMFDX11Locker() + { + if(m_Context != NULL) + { + m_Context->UnlockDX11(); + } + } + void Lock(AMFContext* resources) + { + if(m_Context != NULL) + { + m_Context->UnlockDX11(); + } + m_Context = resources; + if(m_Context != NULL) + { + m_Context->LockDX11(); + } + } + protected: + AMFContext* m_Context; + + private: + AMFDX11Locker(const AMFDX11Locker&); + AMFDX11Locker& operator=(const AMFDX11Locker&); + }; + //---------------------------------------------------------------------------------------------- + class AMFContext::AMFOpenCLLocker + { + public: + AMFOpenCLLocker() : m_Context(NULL) + {} + AMFOpenCLLocker(AMFContext* resources) : m_Context(NULL) + { + Lock(resources); + } + ~AMFOpenCLLocker() + { + if(m_Context != NULL) + { + m_Context->UnlockOpenCL(); + } + } + void Lock(AMFContext* resources) + { + if(m_Context != NULL) + { + m_Context->UnlockOpenCL(); + } + m_Context = resources; + if(m_Context != NULL) + { + m_Context->LockOpenCL(); + } + } + protected: + AMFContext* m_Context; + private: + AMFOpenCLLocker(const AMFOpenCLLocker&); + AMFOpenCLLocker& operator=(const AMFOpenCLLocker&); + }; + //---------------------------------------------------------------------------------------------- + class AMFContext::AMFOpenGLLocker + { + public: + AMFOpenGLLocker(AMFContext* pContext) : m_pContext(pContext), + m_GLLocked(false) + { + if(m_pContext != NULL) + { + if(m_pContext->LockOpenGL() == AMF_OK) + { + m_GLLocked = true; + } + } + } + ~AMFOpenGLLocker() + { + if(m_GLLocked) + { + m_pContext->UnlockOpenGL(); + } + } + private: + AMFContext* m_pContext; + amf_bool m_GLLocked; ///< AMFOpenGLLocker can be called when OpenGL is not initialized yet + ///< in this case don't call UnlockOpenGL + AMFOpenGLLocker(const AMFOpenGLLocker&); + AMFOpenGLLocker& operator=(const AMFOpenGLLocker&); + }; + //---------------------------------------------------------------------------------------------- + class AMFContext::AMFXVLocker + { + public: + AMFXVLocker() : m_pContext(NULL) + {} + AMFXVLocker(AMFContext* pContext) : m_pContext(NULL) + { + Lock(pContext); + } + ~AMFXVLocker() + { + if(m_pContext != NULL) + { + m_pContext->UnlockXV(); + } + } + void Lock(AMFContext* pContext) + { + if((pContext != NULL) && (pContext->GetXVDevice() != NULL)) + { + m_pContext = pContext; + m_pContext->LockXV(); + } + } + protected: + AMFContext* m_pContext; + private: + AMFXVLocker(const AMFXVLocker&); + AMFXVLocker& operator=(const AMFXVLocker&); + }; + //---------------------------------------------------------------------------------------------- + class AMFContext::AMFGrallocLocker + { + public: + AMFGrallocLocker() : m_pContext(NULL) + {} + AMFGrallocLocker(AMFContext* pContext) : m_pContext(NULL) + { + Lock(pContext); + } + ~AMFGrallocLocker() + { + if(m_pContext != NULL) + { + m_pContext->UnlockGralloc(); + } + } + void Lock(AMFContext* pContext) + { + if((pContext != NULL) && (pContext->GetGrallocDevice() != NULL)) + { + m_pContext = pContext; + m_pContext->LockGralloc(); + } + } + protected: + AMFContext* m_pContext; + private: + AMFGrallocLocker(const AMFGrallocLocker&); + AMFGrallocLocker& operator=(const AMFGrallocLocker&); + }; + //---------------------------------------------------------------------------------------------- + class AMFContext1::AMFVulkanLocker + { + public: + AMFVulkanLocker() : m_pContext(NULL) + {} + AMFVulkanLocker(AMFContext1* pContext) : m_pContext(NULL) + { + Lock(pContext); + } + ~AMFVulkanLocker() + { + if(m_pContext != NULL) + { + m_pContext->UnlockVulkan(); + } + } + void Lock(AMFContext1* pContext) + { + if((pContext != NULL) && (pContext->GetVulkanDevice() != NULL)) + { + m_pContext = pContext; + m_pContext->LockVulkan(); + } + } + protected: + AMFContext1* m_pContext; + private: + AMFVulkanLocker(const AMFVulkanLocker&); + AMFVulkanLocker& operator=(const AMFVulkanLocker&); + }; + //---------------------------------------------------------------------------------------------- + //---------------------------------------------------------------------------------------------- + //---------------------------------------------------------------------------------------------- +#endif +#if defined(__cplusplus) +} +#endif +enum AMF_CONTEXT_DEVICETYPE_ENUM +{ + AMF_CONTEXT_DEVICE_TYPE_GPU = 0, + AMF_CONTEXT_DEVICE_TYPE_CPU +}; +#define AMF_CONTEXT_DEVICE_TYPE L"AMF_Context_DeviceType" //Value type: amf_int64; Values : AMF_CONTEXT_DEVICE_TYPE_GPU for GPU (default) , AMF_CONTEXT_DEVICE_TYPE_CPU for CPU. +#endif //#ifndef AMF_Context_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Data.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Data.h new file mode 100644 index 000000000000..bc24de6fd78e --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Data.h @@ -0,0 +1,175 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_Data_h +#define AMF_Data_h +#pragma once + +#include "PropertyStorage.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif + //---------------------------------------------------------------------------------------------- + typedef enum AMF_DATA_TYPE + { + AMF_DATA_BUFFER = 0, + AMF_DATA_SURFACE = 1, + AMF_DATA_AUDIO_BUFFER = 2, + AMF_DATA_USER = 1000, + // all extensions will be AMF_DATA_USER+i + } AMF_DATA_TYPE; + //---------------------------------------------------------------------------------------------- + typedef enum AMF_MEMORY_TYPE + { + AMF_MEMORY_UNKNOWN = 0, + AMF_MEMORY_HOST = 1, + AMF_MEMORY_DX9 = 2, + AMF_MEMORY_DX11 = 3, + AMF_MEMORY_OPENCL = 4, + AMF_MEMORY_OPENGL = 5, + AMF_MEMORY_XV = 6, + AMF_MEMORY_GRALLOC = 7, + AMF_MEMORY_COMPUTE_FOR_DX9 = 8, // deprecated, the same as AMF_MEMORY_OPENCL + AMF_MEMORY_COMPUTE_FOR_DX11 = 9, // deprecated, the same as AMF_MEMORY_OPENCL + AMF_MEMORY_VULKAN = 10, + } AMF_MEMORY_TYPE; + + //---------------------------------------------------------------------------------------------- + typedef enum AMF_DX_VERSION + { + AMF_DX9 = 90, + AMF_DX9_EX = 91, + AMF_DX11_0 = 110, + AMF_DX11_1 = 111 + } AMF_DX_VERSION; + + //---------------------------------------------------------------------------------------------- + // AMF_MEMORY_CPU_ACCESS translates to D3D11_CPU_ACCESS_FLAG or VkImageUsageFlags + // bit mask + //---------------------------------------------------------------------------------------------- + typedef enum AMF_MEMORY_CPU_ACCESS_BITS + { // D3D11 Vulkan + AMF_MEMORY_CPU_DEFAULT = 0x80000000, // 0 , VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT + AMF_MEMORY_CPU_NONE = 0x00000000, // 0 , 0 + AMF_MEMORY_CPU_READ = 0x00000001, // D3D11_CPU_ACCESS_READ, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT + AMF_MEMORY_CPU_WRITE = 0x00000002, // D3D11_CPU_ACCESS_WRITE, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT + AMF_MEMORY_CPU_LOCAL = 0x00000004, // , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT + AMF_MEMORY_CPU_PINNED = 0x00000008, // , VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR + } AMF_MEMORY_CPU_ACCESS_BITS; + typedef amf_flags AMF_MEMORY_CPU_ACCESS; + //---------------------------------------------------------------------------------------------- + // AMFData interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFData : public AMFPropertyStorage + { + public: + AMF_DECLARE_IID(0xa1159bf6, 0x9104, 0x4107, 0x8e, 0xaa, 0xc5, 0x3d, 0x5d, 0xba, 0xc5, 0x11) + + virtual AMF_MEMORY_TYPE AMF_STD_CALL GetMemoryType() = 0; + + virtual AMF_RESULT AMF_STD_CALL Duplicate(AMF_MEMORY_TYPE type, AMFData** ppData) = 0; + virtual AMF_RESULT AMF_STD_CALL Convert(AMF_MEMORY_TYPE type) = 0; // optimal interop if possilble. Copy through host memory if needed + virtual AMF_RESULT AMF_STD_CALL Interop(AMF_MEMORY_TYPE type) = 0; // only optimal interop if possilble. No copy through host memory for GPU objects + + virtual AMF_DATA_TYPE AMF_STD_CALL GetDataType() = 0; + + virtual amf_bool AMF_STD_CALL IsReusable() = 0; + + virtual void AMF_STD_CALL SetPts(amf_pts pts) = 0; + virtual amf_pts AMF_STD_CALL GetPts() = 0; + virtual void AMF_STD_CALL SetDuration(amf_pts duration) = 0; + virtual amf_pts AMF_STD_CALL GetDuration() = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFDataPtr; + //---------------------------------------------------------------------------------------------- + +#else // #if defined(__cplusplus) + typedef struct AMFData AMFData; + AMF_DECLARE_IID(AMFData, 0xa1159bf6, 0x9104, 0x4107, 0x8e, 0xaa, 0xc5, 0x3d, 0x5d, 0xba, 0xc5, 0x11) + + typedef struct AMFDataVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFData* pThis); + amf_long (AMF_STD_CALL *Release)(AMFData* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFData* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFPropertyStorage interface + AMF_RESULT (AMF_STD_CALL *SetProperty)(AMFData* pThis, const wchar_t* name, AMFVariantStruct value); + AMF_RESULT (AMF_STD_CALL *GetProperty)(AMFData* pThis, const wchar_t* name, AMFVariantStruct* pValue); + amf_bool (AMF_STD_CALL *HasProperty)(AMFData* pThis, const wchar_t* name); + amf_size (AMF_STD_CALL *GetPropertyCount)(AMFData* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyAt)(AMFData* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue); + AMF_RESULT (AMF_STD_CALL *Clear)(AMFData* pThis); + AMF_RESULT (AMF_STD_CALL *AddTo)(AMFData* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep); + AMF_RESULT (AMF_STD_CALL *CopyTo)(AMFData* pThis, AMFPropertyStorage* pDest, amf_bool deep); + void (AMF_STD_CALL *AddObserver)(AMFData* pThis, AMFPropertyStorageObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver)(AMFData* pThis, AMFPropertyStorageObserver* pObserver); + + // AMFData interface + + AMF_MEMORY_TYPE (AMF_STD_CALL *GetMemoryType)(AMFData* pThis); + + AMF_RESULT (AMF_STD_CALL *Duplicate)(AMFData* pThis, AMF_MEMORY_TYPE type, AMFData** ppData); + AMF_RESULT (AMF_STD_CALL *Convert)(AMFData* pThis, AMF_MEMORY_TYPE type); // optimal interop if possilble. Copy through host memory if needed + AMF_RESULT (AMF_STD_CALL *Interop)(AMFData* pThis, AMF_MEMORY_TYPE type); // only optimal interop if possilble. No copy through host memory for GPU objects + + AMF_DATA_TYPE (AMF_STD_CALL *GetDataType)(AMFData* pThis); + + amf_bool (AMF_STD_CALL *IsReusable)(AMFData* pThis); + + void (AMF_STD_CALL *SetPts)(AMFData* pThis, amf_pts pts); + amf_pts (AMF_STD_CALL *GetPts)(AMFData* pThis); + void (AMF_STD_CALL *SetDuration)(AMFData* pThis, amf_pts duration); + amf_pts (AMF_STD_CALL *GetDuration)(AMFData* pThis); + + } AMFDataVtbl; + + struct AMFData + { + const AMFDataVtbl *pVtbl; + }; + + +#endif // #if defined(__cplusplus) + +#if defined(__cplusplus) +} // namespace +#endif + +#endif //#ifndef AMF_Data_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Debug.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Debug.h new file mode 100644 index 000000000000..40610b01ce3a --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Debug.h @@ -0,0 +1,78 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_Debug_h +#define AMF_Debug_h +#pragma once + +#include "Platform.h" +#include "Result.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif + //---------------------------------------------------------------------------------------------- + // AMFDebug interface - singleton + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFDebug + { + public: + virtual void AMF_STD_CALL EnablePerformanceMonitor(amf_bool enable) = 0; + virtual amf_bool AMF_STD_CALL PerformanceMonitorEnabled() = 0; + virtual void AMF_STD_CALL AssertsEnable(amf_bool enable) = 0; + virtual amf_bool AMF_STD_CALL AssertsEnabled() = 0; + }; +#else // #if defined(__cplusplus) + typedef struct AMFDebug AMFDebug; + typedef struct AMFDebugVtbl + { + // AMFDebug interface + void (AMF_STD_CALL *EnablePerformanceMonitor)(AMFDebug* pThis, amf_bool enable); + amf_bool (AMF_STD_CALL *PerformanceMonitorEnabled)(AMFDebug* pThis); + void (AMF_STD_CALL *AssertsEnable)(AMFDebug* pThis, amf_bool enable); + amf_bool (AMF_STD_CALL *AssertsEnabled)(AMFDebug* pThis); + } AMFDebugVtbl; + + struct AMFDebug + { + const AMFDebugVtbl *pVtbl; + }; + +#endif // #if defined(__cplusplus) + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) +} +#endif + +#endif // AMF_Debug_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Dump.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Dump.h new file mode 100644 index 000000000000..b8c27446a2a5 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Dump.h @@ -0,0 +1,112 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_Dump_h +#define AMF_Dump_h +#pragma once + +#include "Platform.h" +#include "Result.h" +#include "Interface.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFDump : public AMFInterface + { + public: + AMF_DECLARE_IID(0x75366ad4, 0x504c, 0x430b, 0xbb, 0xe2, 0xad, 0x21, 0x82, 0x8, 0xf, 0x72); + + + virtual const wchar_t* AMF_STD_CALL GetDumpBasePath() const = 0; // Get application dump base path + virtual AMF_RESULT AMF_STD_CALL SetDumpBasePath(const wchar_t* path) = 0; // Set application dump base path + + // Enable/disable input and/or output stream dumps + virtual bool AMF_STD_CALL IsInputDumpEnabled() const = 0; + virtual AMF_RESULT AMF_STD_CALL EnableInputDump(bool enabled) = 0; + virtual const wchar_t* AMF_STD_CALL GetInputDumpFullName() const = 0; // Get full name of dump file + + // Enable/disable input and/or output stream dumps + virtual bool AMF_STD_CALL IsOutputDumpEnabled() const = 0; + virtual AMF_RESULT AMF_STD_CALL EnableOutputDump(bool enabled) = 0; + virtual const wchar_t* AMF_STD_CALL GetOutputDumpFullName() const = 0; // Get full name of dump file + + // When enabled, each new application session will create a subfolder with a time stamp in the base path tree (disabled by default) + virtual bool AMF_STD_CALL IsPerSessionDumpEnabled() const = 0; + virtual void AMF_STD_CALL EnablePerSessionDump(bool enabled) = 0; + }; + typedef AMFInterfacePtr_T AMFDumpPtr; +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFDump, 0x75366ad4, 0x504c, 0x430b, 0xbb, 0xe2, 0xad, 0x21, 0x82, 0x8, 0xf, 0x72); + typedef struct AMFDump AMFDump; + + typedef struct AMFDumpVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFDump* pThis); + amf_long (AMF_STD_CALL *Release)(AMFDump* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFDump* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFDump interface + const wchar_t* (AMF_STD_CALL *GetDumpBasePath)(AMFDump* pThis) const; // Get application dump base path + AMF_RESULT (AMF_STD_CALL *SetDumpBasePath)(AMFDump* pThis, const wchar_t* path); // Set application dump base path + + // Enable/disable input and/or output stream dumps + bool (AMF_STD_CALL *IsInputDumpEnabled)(AMFDump* pThis) const; + AMF_RESULT (AMF_STD_CALL *EnableInputDump)(AMFDump* pThis, bool enabled); + const wchar_t* (AMF_STD_CALL *GetInputDumpFullName)(AMFDump* pThis) const; // Get full name of dump file + + // Enable/disable input and/or output stream dumps + bool (AMF_STD_CALL *IsOutputDumpEnabled)(AMFDump* pThis) const; + AMF_RESULT (AMF_STD_CALL *EnableOutputDump)(AMFDump* pThis, bool enabled); + const wchar_t* (AMF_STD_CALL *GetOutputDumpFullName)(AMFDump* pThis) const; // Get full name of dump file + + // When enabled, each new application session will create a subfolder with a time stamp in the base path tree (disabled by default) + bool (AMF_STD_CALL *IsPerSessionDumpEnabled)(AMFDump* pThis) const; + void (AMF_STD_CALL *EnablePerSessionDump)(AMFDump* pThis, bool enabled); + + } AMFDumpVtbl; + + struct AMFDump + { + const AMFDumpVtbl *pVtbl; + }; + + +#endif // #if defined(__cplusplus) +#if defined(__cplusplus) +} // namespace +#endif + +#endif //AMF_Dump_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Factory.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Factory.h new file mode 100644 index 000000000000..695f1c582005 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Factory.h @@ -0,0 +1,127 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_Factory_h +#define AMF_Factory_h +#pragma once + +#include "Platform.h" +#include "Version.h" +#include "Result.h" +#include "Context.h" +#include "Debug.h" +#include "Trace.h" +#include "Compute.h" + +#include "../components/Component.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif + //---------------------------------------------------------------------------------------------- + // AMFFactory interface - singleton + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFFactory + { + public: + virtual AMF_RESULT AMF_STD_CALL CreateContext(AMFContext** ppContext) = 0; + virtual AMF_RESULT AMF_STD_CALL CreateComponent(AMFContext* pContext, const wchar_t* id, AMFComponent** ppComponent) = 0; + virtual AMF_RESULT AMF_STD_CALL SetCacheFolder(const wchar_t* path) = 0; + virtual const wchar_t* AMF_STD_CALL GetCacheFolder() = 0; + virtual AMF_RESULT AMF_STD_CALL GetDebug(AMFDebug** ppDebug) = 0; + virtual AMF_RESULT AMF_STD_CALL GetTrace(AMFTrace** ppTrace) = 0; + virtual AMF_RESULT AMF_STD_CALL GetPrograms(AMFPrograms** ppPrograms) = 0; + }; +#else + typedef struct AMFFactory AMFFactory; + + typedef struct AMFFactoryVtbl + { + AMF_RESULT (AMF_STD_CALL *CreateContext)(AMFFactory* pThis, AMFContext** ppContext); + AMF_RESULT (AMF_STD_CALL *CreateComponent)(AMFFactory* pThis, AMFContext* pContext, const wchar_t* id, AMFComponent** ppComponent); + AMF_RESULT (AMF_STD_CALL *SetCacheFolder)(AMFFactory* pThis, const wchar_t* path); + const wchar_t* (AMF_STD_CALL *GetCacheFolder)(AMFFactory* pThis); + AMF_RESULT (AMF_STD_CALL *GetDebug)(AMFFactory* pThis, AMFDebug** ppDebug); + AMF_RESULT (AMF_STD_CALL *GetTrace)(AMFFactory* pThis, AMFTrace** ppTrace); + AMF_RESULT (AMF_STD_CALL *GetPrograms)(AMFFactory* pThis, AMFPrograms** ppPrograms); + } AMFFactoryVtbl; + + struct AMFFactory + { + const AMFFactoryVtbl *pVtbl; + }; + +#endif +#if defined(__cplusplus) +} +#endif + +//---------------------------------------------------------------------------------------------- +// DLL entry points +//---------------------------------------------------------------------------------------------- + +#define AMF_INIT_FUNCTION_NAME "AMFInit" +#define AMF_QUERY_VERSION_FUNCTION_NAME "AMFQueryVersion" + +#if defined(__cplusplus) +extern "C" +{ + typedef AMF_RESULT (AMF_CDECL_CALL *AMFInit_Fn)(amf_uint64 version, amf::AMFFactory **ppFactory); + typedef AMF_RESULT (AMF_CDECL_CALL *AMFQueryVersion_Fn)(amf_uint64 *pVersion); +} +#else + typedef AMF_RESULT (AMF_CDECL_CALL *AMFInit_Fn)(amf_uint64 version, AMFFactory **ppFactory); + typedef AMF_RESULT (AMF_CDECL_CALL *AMFQueryVersion_Fn)(amf_uint64 *pVersion); +#endif + +#if defined(_WIN32) + #if defined(_M_AMD64) + #define AMF_DLL_NAME L"amfrt64.dll" + #define AMF_DLL_NAMEA "amfrt64.dll" + #else + #define AMF_DLL_NAME L"amfrt32.dll" + #define AMF_DLL_NAMEA "amfrt32.dll" + #endif +#elif defined(__linux__) + #if defined(__x86_64__) + #define AMF_DLL_NAME L"libamfrt64.so.1" + #define AMF_DLL_NAMEA "libamfrt64.so.1" + #else + #define AMF_DLL_NAME L"libamfrt32.so.1" + #define AMF_DLL_NAMEA "libamfrt32.so.1" + #endif +#endif +//---------------------------------------------------------------------------------------------- + +#endif // AMF_Factory_h \ No newline at end of file diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Interface.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Interface.h new file mode 100644 index 000000000000..9ac7e41165f9 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Interface.h @@ -0,0 +1,258 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_Interface_h +#define AMF_Interface_h +#pragma once + +#include "Result.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif +#if defined(__cplusplus) + #define AMF_DECLARE_IID(_data1, _data2, _data3, _data41, _data42, _data43, _data44, _data45, _data46, _data47, _data48) \ + static AMF_INLINE const amf::AMFGuid IID() \ + { \ + amf::AMFGuid uid = {_data1, _data2, _data3, _data41, _data42, _data43, _data44, _data45, _data46, _data47, _data48}; \ + return uid; \ + } +#else +#define AMF_DECLARE_IID(name, _data1, _data2, _data3, _data41, _data42, _data43, _data44, _data45, _data46, _data47, _data48) \ + AMF_INLINE static const AMFGuid IID_##name(void) \ + { \ + AMFGuid uid = {_data1, _data2, _data3, _data41, _data42, _data43, _data44, _data45, _data46, _data47, _data48}; \ + return uid; \ + } +#endif + + //------------------------------------------------------------------------ + // AMFInterface interface - base class for all AMF interfaces + //------------------------------------------------------------------------ +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFInterface + { + public: + AMF_DECLARE_IID(0x9d872f34, 0x90dc, 0x4b93, 0xb6, 0xb2, 0x6c, 0xa3, 0x7c, 0x85, 0x25, 0xdb) + + virtual amf_long AMF_STD_CALL Acquire() = 0; + virtual amf_long AMF_STD_CALL Release() = 0; + virtual AMF_RESULT AMF_STD_CALL QueryInterface(const AMFGuid& interfaceID, void** ppInterface) = 0; + }; +#else + AMF_DECLARE_IID(AMFInterface, 0x9d872f34, 0x90dc, 0x4b93, 0xb6, 0xb2, 0x6c, 0xa3, 0x7c, 0x85, 0x25, 0xdb) + typedef struct AMFInterface AMFInterface; + + typedef struct AMFInterfaceVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFInterface* pThis); + amf_long (AMF_STD_CALL *Release)(AMFInterface* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFInterface* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + } AMFInterfaceVtbl; + + struct AMFInterface + { + const AMFInterfaceVtbl *pVtbl; + }; +#endif + //------------------------------------------------------------------------ + // template for AMF smart pointer + //------------------------------------------------------------------------ +#if defined(__cplusplus) + template + class AMFInterfacePtr_T + { + private: + _Interf* m_pInterf; + + void InternalAcquire() + { + if(m_pInterf != NULL) + { + m_pInterf->Acquire(); + } + } + void InternalRelease() + { + if(m_pInterf != NULL) + { + m_pInterf->Release(); + } + } + public: + AMFInterfacePtr_T() : m_pInterf(NULL) + {} + + AMFInterfacePtr_T(const AMFInterfacePtr_T<_Interf>& p) : m_pInterf(p.m_pInterf) + { + InternalAcquire(); + } + + AMFInterfacePtr_T(_Interf* pInterface) : m_pInterf(pInterface) + { + InternalAcquire(); + } + + template + explicit AMFInterfacePtr_T(const AMFInterfacePtr_T<_OtherInterf>& cp) : m_pInterf(NULL) + { + void* pInterf = NULL; + if((cp == NULL) || (cp->QueryInterface(_Interf::IID(), &pInterf) != AMF_OK)) + { + pInterf = NULL; + } + m_pInterf = static_cast<_Interf*>(pInterf); + } + + template + explicit AMFInterfacePtr_T(_OtherInterf* cp) : m_pInterf(NULL) + { + void* pInterf = NULL; + if((cp == NULL) || (cp->QueryInterface(_Interf::IID(), &pInterf) != AMF_OK)) + { + pInterf = NULL; + } + m_pInterf = static_cast<_Interf*>(pInterf); + } + + ~AMFInterfacePtr_T() + { + InternalRelease(); + } + + AMFInterfacePtr_T& operator=(_Interf* pInterface) + { + if(m_pInterf != pInterface) + { + _Interf* pOldInterface = m_pInterf; + m_pInterf = pInterface; + InternalAcquire(); + if(pOldInterface != NULL) + { + pOldInterface->Release(); + } + } + return *this; + } + + AMFInterfacePtr_T& operator=(const AMFInterfacePtr_T<_Interf>& cp) + { + return operator=(cp.m_pInterf); + } + + void Attach(_Interf* pInterface) + { + InternalRelease(); + m_pInterf = pInterface; + } + + _Interf* Detach() + { + _Interf* const pOld = m_pInterf; + m_pInterf = NULL; + return pOld; + } + void Release() + { + InternalRelease(); + m_pInterf = NULL; + } + + operator _Interf*() const + { + return m_pInterf; + } + + _Interf& operator*() const + { + return *m_pInterf; + } + + // Returns the address of the interface pointer contained in this + // class. This is required for initializing from C-style factory function to + // avoid getting an incorrect ref count at the beginning. + + _Interf** operator&() + { + InternalRelease(); + m_pInterf = 0; + return &m_pInterf; + } + + _Interf* operator->() const + { + return m_pInterf; + } + + bool operator==(const AMFInterfacePtr_T<_Interf>& p) + { + return (m_pInterf == p.m_pInterf); + } + + bool operator==(_Interf* p) + { + return (m_pInterf == p); + } + + bool operator!=(const AMFInterfacePtr_T<_Interf>& p) + { + return !(operator==(p)); + } + bool operator!=(_Interf* p) + { + return !(operator==(p)); + } + + _Interf* GetPtr() + { + return m_pInterf; + } + + const _Interf* GetPtr() const + { + return m_pInterf; + } + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFInterfacePtr; + //---------------------------------------------------------------------------------------------- +#endif + +#if defined(__cplusplus) +} +#endif + +#endif //#ifndef AMF_Interface_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Plane.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Plane.h new file mode 100644 index 000000000000..6d3e9f946e9c --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Plane.h @@ -0,0 +1,112 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_Plane_h +#define AMF_Plane_h +#pragma once + +#include "Interface.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif + //--------------------------------------------------------------------------------------------- + typedef enum AMF_PLANE_TYPE + { + AMF_PLANE_UNKNOWN = 0, + AMF_PLANE_PACKED = 1, // for all packed formats: BGRA, YUY2, etc + AMF_PLANE_Y = 2, + AMF_PLANE_UV = 3, + AMF_PLANE_U = 4, + AMF_PLANE_V = 5, + } AMF_PLANE_TYPE; + //--------------------------------------------------------------------------------------------- + // AMFPlane interface + //--------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFPlane : public AMFInterface + { + public: + AMF_DECLARE_IID(0xbede1aa6, 0xd8fa, 0x4625, 0x94, 0x65, 0x6c, 0x82, 0xc4, 0x37, 0x71, 0x2e) + + virtual AMF_PLANE_TYPE AMF_STD_CALL GetType() = 0; + virtual void* AMF_STD_CALL GetNative() = 0; + virtual amf_int32 AMF_STD_CALL GetPixelSizeInBytes() = 0; + virtual amf_int32 AMF_STD_CALL GetOffsetX() = 0; + virtual amf_int32 AMF_STD_CALL GetOffsetY() = 0; + virtual amf_int32 AMF_STD_CALL GetWidth() = 0; + virtual amf_int32 AMF_STD_CALL GetHeight() = 0; + virtual amf_int32 AMF_STD_CALL GetHPitch() = 0; + virtual amf_int32 AMF_STD_CALL GetVPitch() = 0; + virtual bool AMF_STD_CALL IsTiled() = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFPlanePtr; + //---------------------------------------------------------------------------------------------- +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFPlane, 0xbede1aa6, 0xd8fa, 0x4625, 0x94, 0x65, 0x6c, 0x82, 0xc4, 0x37, 0x71, 0x2e) + typedef struct AMFPlane AMFPlane; + typedef struct AMFPlaneVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFPlane* pThis); + amf_long (AMF_STD_CALL *Release)(AMFPlane* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFPlane* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFPlane interface + AMF_PLANE_TYPE (AMF_STD_CALL *GetType)(AMFPlane* pThis); + void* (AMF_STD_CALL *GetNative)(AMFPlane* pThis); + amf_int32 (AMF_STD_CALL *GetPixelSizeInBytes)(AMFPlane* pThis); + amf_int32 (AMF_STD_CALL *GetOffsetX)(AMFPlane* pThis); + amf_int32 (AMF_STD_CALL *GetOffsetY)(AMFPlane* pThis); + amf_int32 (AMF_STD_CALL *GetWidth)(AMFPlane* pThis); + amf_int32 (AMF_STD_CALL *GetHeight)(AMFPlane* pThis); + amf_int32 (AMF_STD_CALL *GetHPitch)(AMFPlane* pThis); + amf_int32 (AMF_STD_CALL *GetVPitch)(AMFPlane* pThis); + amf_bool (AMF_STD_CALL *IsTiled)(AMFPlane* pThis); + + } AMFPlaneVtbl; + + struct AMFPlane + { + const AMFPlaneVtbl *pVtbl; + }; +#endif // #if defined(__cplusplus) + +#if defined(__cplusplus) +} // namespace amf +#endif + +#endif //#ifndef AMF_Plane_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Platform.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Platform.h new file mode 100644 index 000000000000..61cee576da6d --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Platform.h @@ -0,0 +1,447 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_Platform_h +#define AMF_Platform_h +#pragma once + +//---------------------------------------------------------------------------------------------- +// export declaration +//---------------------------------------------------------------------------------------------- +#if defined(_WIN32) + #if defined(AMF_CORE_STATIC) + #define AMF_CORE_LINK + #else + #if defined(AMF_CORE_EXPORTS) + #define AMF_CORE_LINK __declspec(dllexport) + #else + #define AMF_CORE_LINK __declspec(dllimport) + #endif + #endif +#elif defined(__linux) + #if defined(AMF_CORE_EXPORTS) + #define AMF_CORE_LINK __attribute__((visibility("default"))) + #else + #define AMF_CORE_LINK + #endif +#else + #define AMF_CORE_LINK +#endif // #ifdef _WIN32 + +#define AMF_MACRO_STRING2(x) #x +#define AMF_MACRO_STRING(x) AMF_MACRO_STRING2(x) + +#define AMF_TODO(_todo) (__FILE__ "(" AMF_MACRO_STRING(__LINE__) "): TODO: "_todo) + + + #if defined(__GNUC__) || defined(__clang__) + #define AMF_ALIGN(n) __attribute__((aligned(n))) + #elif defined(_MSC_VER) || defined(__INTEL_COMPILER) + #define AMF_ALIGN(n) __declspec(align(n)) + #else + #define AMF_ALIGN(n) +// #error Need to define AMF_ALIGN + #endif + +#include +#include +#include + +#if defined(_WIN32) + + +#ifndef NOMINMAX +#define NOMINMAX +#endif + #define AMF_STD_CALL __stdcall + #define AMF_CDECL_CALL __cdecl + #define AMF_FAST_CALL __fastcall +#if defined(__GNUC__) || defined(__clang__) + #define AMF_INLINE inline + #define AMF_FORCEINLINE inline +#else + #define AMF_INLINE __inline + #define AMF_FORCEINLINE __forceinline +#endif + #define AMF_NO_VTABLE __declspec(novtable) + + #define AMFPRId64 "I64d" + #define LPRId64 L"I64d" + + #define AMFPRIud64 "Iu64d" + #define LPRIud64 L"Iu64d" + + #define AMFPRIx64 "I64x" + #define LPRIx64 L"I64x" + +#else // !WIN32 - Linux and Mac + + #define AMF_STD_CALL + #define AMF_CDECL_CALL + #define AMF_FAST_CALL +#if defined(__GNUC__) || defined(__clang__) + #define AMF_INLINE inline + #define AMF_FORCEINLINE inline +#else + #define AMF_INLINE __inline__ + #define AMF_FORCEINLINE __inline__ +#endif + #define AMF_NO_VTABLE + + #if !defined(AMFPRId64) + #define AMFPRId64 "lld" + #define LPRId64 L"lld" + + #define AMFPRIud64 "ulld" + #define LPRIud64 L"ulld" + + #define AMFPRIx64 "llx" + #define LPRIx64 L"llx" + #endif + +#endif // WIN32 + + +#if defined(_MSC_VER) +#define AMF_WEAK __declspec( selectany ) +#elif defined (__GNUC__) || defined (__GCC__) || defined(__clang__)//GCC or CLANG +#define AMF_WEAK __attribute__((weak)) +#endif + +#define amf_countof(x) (sizeof(x) / sizeof(x[0])) + +//------------------------------------------------------------------------------------------------- +// basic data types +//------------------------------------------------------------------------------------------------- +typedef int64_t amf_int64; +typedef int32_t amf_int32; +typedef int16_t amf_int16; +typedef int8_t amf_int8; + +typedef uint64_t amf_uint64; +typedef uint32_t amf_uint32; +typedef uint16_t amf_uint16; +typedef uint8_t amf_uint8; +typedef size_t amf_size; + +typedef void* amf_handle; +typedef double amf_double; +typedef float amf_float; + +typedef void amf_void; + +#if defined(__cplusplus) +typedef bool amf_bool; +#else +typedef amf_uint8 amf_bool; +#define true 1 +#define false 0 +#endif + +typedef long amf_long; +typedef int amf_int; +typedef unsigned long amf_ulong; +typedef unsigned int amf_uint; + +typedef amf_int64 amf_pts; // in 100 nanosecs + +typedef amf_uint32 amf_flags; + +#define AMF_SECOND 10000000L // 1 second in 100 nanoseconds + +#define AMF_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define AMF_MAX(a, b) ((a) > (b) ? (a) : (b)) + +#if defined(_WIN32) + #define PATH_SEPARATOR_WSTR L"\\" + #define PATH_SEPARATOR_WCHAR L'\\' +#elif defined(__linux) // Linux + #define PATH_SEPARATOR_WSTR L"/" + #define PATH_SEPARATOR_WCHAR L'/' +#endif + +typedef struct AMFRect +{ + amf_int32 left; + amf_int32 top; + amf_int32 right; + amf_int32 bottom; +#if defined(__cplusplus) + bool operator==(const AMFRect& other) const + { + return left == other.left && top == other.top && right == other.right && bottom == other.bottom; + } + AMF_INLINE bool operator!=(const AMFRect& other) const { return !operator==(other); } + amf_int32 Width() const { return right - left; } + amf_int32 Height() const { return bottom - top; } +#endif +} AMFRect; + +static AMF_INLINE struct AMFRect AMFConstructRect(amf_int32 left, amf_int32 top, amf_int32 right, amf_int32 bottom) +{ + struct AMFRect object = {left, top, right, bottom}; + return object; +} + +typedef struct AMFSize +{ + amf_int32 width; + amf_int32 height; +#if defined(__cplusplus) + bool operator==(const AMFSize& other) const + { + return width == other.width && height == other.height; + } + AMF_INLINE bool operator!=(const AMFSize& other) const { return !operator==(other); } +#endif +} AMFSize; + +static AMF_INLINE struct AMFSize AMFConstructSize(amf_int32 width, amf_int32 height) +{ + struct AMFSize object = {width, height}; + return object; +} + +typedef struct AMFPoint +{ + amf_int32 x; + amf_int32 y; +#if defined(__cplusplus) + bool operator==(const AMFPoint& other) const + { + return x == other.x && y == other.y; + } + AMF_INLINE bool operator!=(const AMFPoint& other) const { return !operator==(other); } +#endif +} AMFPoint; + +static AMF_INLINE struct AMFPoint AMFConstructPoint(amf_int32 x, amf_int32 y) +{ + struct AMFPoint object = {x, y}; + return object; +} + +typedef struct AMFRate +{ + amf_uint32 num; + amf_uint32 den; +#if defined(__cplusplus) + bool operator==(const AMFRate& other) const + { + return num == other.num && den == other.den; + } + AMF_INLINE bool operator!=(const AMFRate& other) const { return !operator==(other); } +#endif +} AMFRate; + +static AMF_INLINE struct AMFRate AMFConstructRate(amf_uint32 num, amf_uint32 den) +{ + struct AMFRate object = {num, den}; + return object; +} + +typedef struct AMFRatio +{ + amf_uint32 num; + amf_uint32 den; +#if defined(__cplusplus) + bool operator==(const AMFRatio& other) const + { + return num == other.num && den == other.den; + } + AMF_INLINE bool operator!=(const AMFRatio& other) const { return !operator==(other); } +#endif +} AMFRatio; + +static AMF_INLINE struct AMFRatio AMFConstructRatio(amf_uint32 num, amf_uint32 den) +{ + struct AMFRatio object = {num, den}; + return object; +} + +#pragma pack(push, 1) +#if defined(_MSC_VER) + #pragma warning( push ) +#endif +#if defined(WIN32) +#if defined(_MSC_VER) + #pragma warning(disable : 4200) + #pragma warning(disable : 4201) +#endif +#endif +typedef struct AMFColor +{ + union + { + struct + { + amf_uint8 r; + amf_uint8 g; + amf_uint8 b; + amf_uint8 a; + }; + amf_uint32 rgba; + }; +#if defined(__cplusplus) + bool operator==(const AMFColor& other) const + { + return r == other.r && g == other.g && b == other.b && a == other.a; + } + AMF_INLINE bool operator!=(const AMFColor& other) const { return !operator==(other); } +#endif +} AMFColor; +#if defined(_MSC_VER) + #pragma warning( pop ) +#endif +#pragma pack(pop) + + +static AMF_INLINE struct AMFColor AMFConstructColor(amf_uint8 r, amf_uint8 g, amf_uint8 b, amf_uint8 a) +{ + struct AMFColor object; + object.r = r; + object.g = g; + object.b = b; + object.a = a; + return object; +} + +#if defined(_WIN32) + #include + + #if defined(__cplusplus) + extern "C" + { + #endif + // allocator + static AMF_INLINE void* AMF_CDECL_CALL amf_variant_alloc(amf_size count) + { + return CoTaskMemAlloc(count); + } + static AMF_INLINE void AMF_CDECL_CALL amf_variant_free(void* ptr) + { + CoTaskMemFree(ptr); + } + #if defined(__cplusplus) + } + #endif + +#else // defined(_WIN32) + #include + #if defined(__cplusplus) + extern "C" + { + #endif + // allocator + static AMF_INLINE void* AMF_CDECL_CALL amf_variant_alloc(amf_size count) + { + return malloc(count); + } + static AMF_INLINE void AMF_CDECL_CALL amf_variant_free(void* ptr) + { + free(ptr); + } + #if defined(__cplusplus) + } + #endif +#endif // defined(_WIN32) + + +#if defined(__cplusplus) +namespace amf +{ +#endif + typedef struct AMFGuid + { + amf_uint32 data1; + amf_uint16 data2; + amf_uint16 data3; + amf_uint8 data41; + amf_uint8 data42; + amf_uint8 data43; + amf_uint8 data44; + amf_uint8 data45; + amf_uint8 data46; + amf_uint8 data47; + amf_uint8 data48; +#if defined(__cplusplus) + AMFGuid(amf_uint32 _data1, amf_uint16 _data2, amf_uint16 _data3, + amf_uint8 _data41, amf_uint8 _data42, amf_uint8 _data43, amf_uint8 _data44, + amf_uint8 _data45, amf_uint8 _data46, amf_uint8 _data47, amf_uint8 _data48) + : data1 (_data1), + data2 (_data2), + data3 (_data3), + data41(_data41), + data42(_data42), + data43(_data43), + data44(_data44), + data45(_data45), + data46(_data46), + data47(_data47), + data48(_data48) + {} + + bool operator==(const AMFGuid& other) const + { + return + data1 == other.data1 && + data2 == other.data2 && + data3 == other.data3 && + data41 == other.data41 && + data42 == other.data42 && + data43 == other.data43 && + data44 == other.data44 && + data45 == other.data45 && + data46 == other.data46 && + data47 == other.data47 && + data48 == other.data48; + } + AMF_INLINE bool operator!=(const AMFGuid& other) const { return !operator==(other); } +#endif + } AMFGuid; + +#if defined(__cplusplus) + static AMF_INLINE bool AMFCompareGUIDs(const AMFGuid& guid1, const AMFGuid& guid2) + { + return guid1 == guid2; + } +#else + static AMF_INLINE amf_bool AMFCompareGUIDs(const struct AMFGuid guid1, const struct AMFGuid guid2) + { + return memcmp(&guid1, &guid2, sizeof(guid1)) == 0; + } +#endif +#if defined(__cplusplus) +} +#endif + +#endif //#ifndef AMF_Platform_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/PropertyStorage.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/PropertyStorage.h new file mode 100644 index 000000000000..9fb87bec0273 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/PropertyStorage.h @@ -0,0 +1,275 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_PropertyStorage_h +#define AMF_PropertyStorage_h +#pragma once + +#include "Variant.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif + //---------------------------------------------------------------------------------------------- + // AMFPropertyStorageObserver interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + + class AMF_NO_VTABLE AMFPropertyStorageObserver + { + public: + virtual void AMF_STD_CALL OnPropertyChanged(const wchar_t* name) = 0; + }; +#else //#if defined(__cplusplus) + typedef struct AMFPropertyStorageObserver AMFPropertyStorageObserver; + typedef struct AMFPropertyStorageObserverVtbl + { + void (AMF_STD_CALL *OnPropertyChanged)(AMFPropertyStorageObserver *pThis, const wchar_t* name); + } AMFPropertyStorageObserverVtbl; + + struct AMFPropertyStorageObserver + { + const AMFPropertyStorageObserverVtbl *pVtbl; + }; + +#endif // #if defined(__cplusplus) +#if defined(__cplusplus) + //---------------------------------------------------------------------------------------------- + // AMFPropertyStorage interface + //---------------------------------------------------------------------------------------------- + class AMF_NO_VTABLE AMFPropertyStorage : public AMFInterface + { + public: + AMF_DECLARE_IID(0xc7cec05b, 0xcfb9, 0x48af, 0xac, 0xe3, 0xf6, 0x8d, 0xf8, 0x39, 0x5f, 0xe3) + + virtual AMF_RESULT AMF_STD_CALL SetProperty(const wchar_t* name, AMFVariantStruct value) = 0; + virtual AMF_RESULT AMF_STD_CALL GetProperty(const wchar_t* name, AMFVariantStruct* pValue) const = 0; + + virtual amf_bool AMF_STD_CALL HasProperty(const wchar_t* name) const = 0; + virtual amf_size AMF_STD_CALL GetPropertyCount() const = 0; + virtual AMF_RESULT AMF_STD_CALL GetPropertyAt(amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue) const = 0; + + virtual AMF_RESULT AMF_STD_CALL Clear() = 0; + virtual AMF_RESULT AMF_STD_CALL AddTo(AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep) const= 0; + virtual AMF_RESULT AMF_STD_CALL CopyTo(AMFPropertyStorage* pDest, amf_bool deep) const = 0; + + virtual void AMF_STD_CALL AddObserver(AMFPropertyStorageObserver* pObserver) = 0; + virtual void AMF_STD_CALL RemoveObserver(AMFPropertyStorageObserver* pObserver) = 0; + + template + AMF_RESULT AMF_STD_CALL SetProperty(const wchar_t* name, const _T& value); + template + AMF_RESULT AMF_STD_CALL GetProperty(const wchar_t* name, _T* pValue) const; + template + AMF_RESULT AMF_STD_CALL GetPropertyString(const wchar_t* name, _T* pValue) const; + template + AMF_RESULT AMF_STD_CALL GetPropertyWString(const wchar_t* name, _T* pValue) const; + + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFPropertyStoragePtr; + //---------------------------------------------------------------------------------------------- + +#else // #if defined(__cplusplus) + typedef struct AMFPropertyStorage AMFPropertyStorage; + AMF_DECLARE_IID(AMFPropertyStorage, 0xc7cec05b, 0xcfb9, 0x48af, 0xac, 0xe3, 0xf6, 0x8d, 0xf8, 0x39, 0x5f, 0xe3) + + typedef struct AMFPropertyStorageVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFPropertyStorage* pThis); + amf_long (AMF_STD_CALL *Release)(AMFPropertyStorage* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFPropertyStorage* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFPropertyStorage interface + AMF_RESULT (AMF_STD_CALL *SetProperty)(AMFPropertyStorage* pThis, const wchar_t* name, AMFVariantStruct value); + AMF_RESULT (AMF_STD_CALL *GetProperty)(AMFPropertyStorage* pThis, const wchar_t* name, AMFVariantStruct* pValue); + amf_bool (AMF_STD_CALL *HasProperty)(AMFPropertyStorage* pThis, const wchar_t* name); + amf_size (AMF_STD_CALL *GetPropertyCount)(AMFPropertyStorage* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyAt)(AMFPropertyStorage* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue); + AMF_RESULT (AMF_STD_CALL *Clear)(AMFPropertyStorage* pThis); + AMF_RESULT (AMF_STD_CALL *AddTo)(AMFPropertyStorage* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep); + AMF_RESULT (AMF_STD_CALL *CopyTo)(AMFPropertyStorage* pThis, AMFPropertyStorage* pDest, amf_bool deep); + void (AMF_STD_CALL *AddObserver)(AMFPropertyStorage* pThis, AMFPropertyStorageObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver)(AMFPropertyStorage* pThis, AMFPropertyStorageObserver* pObserver); + + } AMFPropertyStorageVtbl; + + struct AMFPropertyStorage + { + const AMFPropertyStorageVtbl *pVtbl; + }; + + #define AMF_ASSIGN_PROPERTY_DATA(res, varType, pThis, name, val ) \ + { \ + AMFVariantStruct var = {0}; \ + AMFVariantAssign##varType(&var, val); \ + res = pThis->pVtbl->SetProperty(pThis, name, var ); \ + } + + #define AMF_QUERY_INTERFACE(res, from, InterfaceTypeTo, to) \ + { \ + AMFGuid guid_##InterfaceTypeTo = IID_##InterfaceTypeTo(); \ + res = from->pVtbl->QueryInterface(from, &guid_##InterfaceTypeTo, (void**)&to); \ + } + + #define AMF_ASSIGN_PROPERTY_INTERFACE(res, pThis, name, val) \ + { \ + AMFInterface *amf_interface; \ + AMFVariantStruct var; \ + res = AMFVariantInit(&var); \ + if (res == AMF_OK) \ + { \ + AMF_QUERY_INTERFACE(res, val, AMFInterface, amf_interface)\ + if (res == AMF_OK) \ + { \ + res = AMFVariantAssignInterface(&var, amf_interface); \ + amf_interface->pVtbl->Release(amf_interface); \ + if (res == AMF_OK) \ + { \ + res = pThis->pVtbl->SetProperty(pThis, name, var); \ + } \ + } \ + AMFVariantClear(&var); \ + } \ + } + + #define AMF_GET_PROPERTY_INTERFACE(res, pThis, name, TargetType, val) \ + { \ + AMFVariantStruct var; \ + res = AMFVariantInit(&var); \ + if (res != AMF_OK) \ + { \ + res = pThis->pVtbl->GetProperty(pThis, name, &var); \ + if (res == AMF_OK) \ + { \ + if (var.type == AMF_VARIANT_INTERFACE && AMFVariantInterface(&var)) \ + { \ + AMF_QUERY_INTERFACE(res, AMFVariantInterface(&var), TargetType, val); \ + } \ + else \ + { \ + res = AMF_INVALID_DATA_TYPE; \ + } \ + } \ + } \ + AMFVariantClear(&var); \ + } + + #define AMF_ASSIGN_PROPERTY_TYPE(res, varType, dataType , pThis, name, val ) AMF_ASSIGN_PROPERTY_DATA(res, varType, pThis, name, (dataType)val) + + #define AMF_ASSIGN_PROPERTY_INT64(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_TYPE(res, Int64, amf_int64, pThis, name, val) + #define AMF_ASSIGN_PROPERTY_DOUBLE(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_TYPE(res, Double, amf_double, pThis, name, val) + #define AMF_ASSIGN_PROPERTY_BOOL(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_TYPE(res, Bool, amf_bool, pThis, name, val) + #define AMF_ASSIGN_PROPERTY_RECT(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_DATA(res, Rect, pThis, name, &val) + #define AMF_ASSIGN_PROPERTY_SIZE(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_DATA(res, Size, pThis, name, &val) + #define AMF_ASSIGN_PROPERTY_POINT(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_DATA(res, Point, pThis, name, &val) + #define AMF_ASSIGN_PROPERTY_RATE(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_DATA(res, Rate, pThis, name, &val) + #define AMF_ASSIGN_PROPERTY_RATIO(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_DATA(res, Ratio, pThis, name, &val) + #define AMF_ASSIGN_PROPERTY_COLOR(res, pThis, name, val ) AMF_ASSIGN_PROPERTY_DATA(res, Color, pThis, name, &val) + +#endif // #if defined(__cplusplus) + + +#if defined(__cplusplus) + //---------------------------------------------------------------------------------------------- + // template methods implementations + //---------------------------------------------------------------------------------------------- + template inline + AMF_RESULT AMF_STD_CALL AMFPropertyStorage::SetProperty(const wchar_t* name, const _T& value) + { + AMF_RESULT err = SetProperty(name, static_cast(AMFVariant(value))); + return err; + } + //---------------------------------------------------------------------------------------------- + template inline + AMF_RESULT AMF_STD_CALL AMFPropertyStorage::GetProperty(const wchar_t* name, _T* pValue) const + { + AMFVariant var; + AMF_RESULT err = GetProperty(name, static_cast(&var)); + if(err == AMF_OK) + { + *pValue = static_cast<_T>(var); + } + return err; + } + //---------------------------------------------------------------------------------------------- + template inline + AMF_RESULT AMF_STD_CALL AMFPropertyStorage::GetPropertyString(const wchar_t* name, _T* pValue) const + { + AMFVariant var; + AMF_RESULT err = GetProperty(name, static_cast(&var)); + if(err == AMF_OK) + { + *pValue = var.ToString().c_str(); + } + return err; + } + //---------------------------------------------------------------------------------------------- + template inline + AMF_RESULT AMF_STD_CALL AMFPropertyStorage::GetPropertyWString(const wchar_t* name, _T* pValue) const + { + AMFVariant var; + AMF_RESULT err = GetProperty(name, static_cast(&var)); + if(err == AMF_OK) + { + *pValue = var.ToWString().c_str(); + } + return err; + } + //---------------------------------------------------------------------------------------------- + template<> inline + AMF_RESULT AMF_STD_CALL AMFPropertyStorage::GetProperty(const wchar_t* name, + AMFInterface** ppValue) const + { + AMFVariant var; + AMF_RESULT err = GetProperty(name, static_cast(&var)); + if(err == AMF_OK) + { + *ppValue = static_cast(var); + } + if(*ppValue) + { + (*ppValue)->Acquire(); + } + return err; + } +#endif // #if defined(__cplusplus) + +#if defined(__cplusplus) +} //namespace amf +#endif + +#endif // #ifndef AMF_PropertyStorage_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/PropertyStorageEx.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/PropertyStorageEx.h new file mode 100644 index 000000000000..1e6a04ec0944 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/PropertyStorageEx.h @@ -0,0 +1,197 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_PropertyStorageEx_h +#define AMF_PropertyStorageEx_h +#pragma once + +#include "PropertyStorage.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif + //---------------------------------------------------------------------------------------------- + typedef enum AMF_PROPERTY_CONTENT_ENUM + { + AMF_PROPERTY_CONTENT_DEFAULT = 0, + AMF_PROPERTY_CONTENT_XML, // m_eType is AMF_VARIANT_STRING + + AMF_PROPERTY_CONTENT_FILE_OPEN_PATH, // m_eType AMF_VARIANT_WSTRING + AMF_PROPERTY_CONTENT_FILE_SAVE_PATH // m_eType AMF_VARIANT_WSTRING + } AMF_PROPERTY_CONTENT_ENUM; + //---------------------------------------------------------------------------------------------- + typedef enum AMF_PROPERTY_ACCESS_TYPE + { + AMF_PROPERTY_ACCESS_PRIVATE = 0, + AMF_PROPERTY_ACCESS_READ = 0x1, + AMF_PROPERTY_ACCESS_WRITE = 0x2, + AMF_PROPERTY_ACCESS_READ_WRITE = (AMF_PROPERTY_ACCESS_READ | AMF_PROPERTY_ACCESS_WRITE), + AMF_PROPERTY_ACCESS_WRITE_RUNTIME = 0x4, + AMF_PROPERTY_ACCESS_FULL = 0xFF, + } AMF_PROPERTY_ACCESS_TYPE; + //---------------------------------------------------------------------------------------------- + typedef struct AMFEnumDescriptionEntry + { + amf_int value; + const wchar_t* name; + } AMFEnumDescriptionEntry; + //---------------------------------------------------------------------------------------------- + typedef amf_uint32 AMF_PROPERTY_CONTENT_TYPE; + + typedef struct AMFPropertyInfo + { + const wchar_t* name; + const wchar_t* desc; + AMF_VARIANT_TYPE type; + AMF_PROPERTY_CONTENT_TYPE contentType; + + AMFVariantStruct defaultValue; + AMFVariantStruct minValue; + AMFVariantStruct maxValue; + AMF_PROPERTY_ACCESS_TYPE accessType; + const AMFEnumDescriptionEntry* pEnumDescription; + +#if defined(__cplusplus) + AMFPropertyInfo() : + name(NULL), + desc(NULL), + type(), + contentType(), + defaultValue(), + minValue(), + maxValue(), + accessType(AMF_PROPERTY_ACCESS_FULL), + pEnumDescription(NULL) + {} + AMFPropertyInfo(const AMFPropertyInfo& propery) : name(propery.name), + desc(propery.desc), + type(propery.type), + contentType(propery.contentType), + defaultValue(propery.defaultValue), + minValue(propery.minValue), + maxValue(propery.maxValue), + accessType(propery.accessType), + pEnumDescription(propery.pEnumDescription) + {} + virtual ~AMFPropertyInfo(){} + + amf_bool AMF_STD_CALL AllowedRead() const + { + return (accessType & AMF_PROPERTY_ACCESS_READ) != 0; + } + amf_bool AMF_STD_CALL AllowedWrite() const + { + return (accessType & AMF_PROPERTY_ACCESS_WRITE) != 0; + } + amf_bool AMF_STD_CALL AllowedChangeInRuntime() const + { + return (accessType & AMF_PROPERTY_ACCESS_WRITE_RUNTIME) != 0; + } + + AMFPropertyInfo& operator=(const AMFPropertyInfo& propery) + { + desc = propery.desc; + type = propery.type; + contentType = propery.contentType; + defaultValue = propery.defaultValue; + minValue = propery.minValue; + maxValue = propery.maxValue; + accessType = propery.accessType; + pEnumDescription = propery.pEnumDescription; + + return *this; + } +#endif // #if defined(__cplusplus) + } AMFPropertyInfo; + //---------------------------------------------------------------------------------------------- + // AMFPropertyStorageEx interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFPropertyStorageEx : public AMFPropertyStorage + { + public: + AMF_DECLARE_IID(0x16b8958d, 0xe943, 0x4a33, 0xa3, 0x5a, 0x88, 0x5a, 0xd8, 0x28, 0xf2, 0x67) + + virtual amf_size AMF_STD_CALL GetPropertiesInfoCount() const = 0; + virtual AMF_RESULT AMF_STD_CALL GetPropertyInfo(amf_size index, const AMFPropertyInfo** ppInfo) const = 0; + virtual AMF_RESULT AMF_STD_CALL GetPropertyInfo(const wchar_t* name, const AMFPropertyInfo** ppInfo) const = 0; + virtual AMF_RESULT AMF_STD_CALL ValidateProperty(const wchar_t* name, AMFVariantStruct value, AMFVariantStruct* pOutValidated) const = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFPropertyStorageExPtr; +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFPropertyStorageEx, 0x16b8958d, 0xe943, 0x4a33, 0xa3, 0x5a, 0x88, 0x5a, 0xd8, 0x28, 0xf2, 0x67) + typedef struct AMFPropertyStorageEx AMFPropertyStorageEx; + + typedef struct AMFPropertyStorageExVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFPropertyStorageEx* pThis); + amf_long (AMF_STD_CALL *Release)(AMFPropertyStorageEx* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFPropertyStorageEx* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFPropertyStorage interface + AMF_RESULT (AMF_STD_CALL *SetProperty)(AMFPropertyStorageEx* pThis, const wchar_t* name, AMFVariantStruct value); + AMF_RESULT (AMF_STD_CALL *GetProperty)(AMFPropertyStorageEx* pThis, const wchar_t* name, AMFVariantStruct* pValue); + amf_bool (AMF_STD_CALL *HasProperty)(AMFPropertyStorageEx* pThis, const wchar_t* name); + amf_size (AMF_STD_CALL *GetPropertyCount)(AMFPropertyStorageEx* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyAt)(AMFPropertyStorageEx* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue); + AMF_RESULT (AMF_STD_CALL *Clear)(AMFPropertyStorageEx* pThis); + AMF_RESULT (AMF_STD_CALL *AddTo)(AMFPropertyStorageEx* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep); + AMF_RESULT (AMF_STD_CALL *CopyTo)(AMFPropertyStorageEx* pThis, AMFPropertyStorage* pDest, amf_bool deep); + void (AMF_STD_CALL *AddObserver)(AMFPropertyStorageEx* pThis, AMFPropertyStorageObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver)(AMFPropertyStorageEx* pThis, AMFPropertyStorageObserver* pObserver); + + // AMFPropertyStorageEx interface + + amf_size (AMF_STD_CALL *GetPropertiesInfoCount)(AMFPropertyStorageEx* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyInfoAt)(AMFPropertyStorageEx* pThis, amf_size index, const AMFPropertyInfo** ppInfo); + AMF_RESULT (AMF_STD_CALL *GetPropertyInfo)(AMFPropertyStorageEx* pThis, const wchar_t* name, const AMFPropertyInfo** ppInfo); + AMF_RESULT (AMF_STD_CALL *ValidateProperty)(AMFPropertyStorageEx* pThis, const wchar_t* name, AMFVariantStruct value, AMFVariantStruct* pOutValidated); + + } AMFPropertyStorageExVtbl; + + struct AMFPropertyStorageEx + { + const AMFPropertyStorageExVtbl *pVtbl; + }; +#endif // #if defined(__cplusplus) + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) +} //namespace amf +#endif + + +#endif //#ifndef AMF_PropertyStorageEx_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Result.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Result.h new file mode 100644 index 000000000000..87118d5e7363 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Result.h @@ -0,0 +1,127 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_Result_h +#define AMF_Result_h +#pragma once + +#include "Platform.h" + +//---------------------------------------------------------------------------------------------- +// result codes +//---------------------------------------------------------------------------------------------- + +typedef enum AMF_RESULT +{ + AMF_OK = 0, + AMF_FAIL , + +// common errors + AMF_UNEXPECTED , + + AMF_ACCESS_DENIED , + AMF_INVALID_ARG , + AMF_OUT_OF_RANGE , + + AMF_OUT_OF_MEMORY , + AMF_INVALID_POINTER , + + AMF_NO_INTERFACE , + AMF_NOT_IMPLEMENTED , + AMF_NOT_SUPPORTED , + AMF_NOT_FOUND , + + AMF_ALREADY_INITIALIZED , + AMF_NOT_INITIALIZED , + + AMF_INVALID_FORMAT ,// invalid data format + + AMF_WRONG_STATE , + AMF_FILE_NOT_OPEN ,// cannot open file + +// device common codes + AMF_NO_DEVICE , + +// device directx + AMF_DIRECTX_FAILED , +// device opencl + AMF_OPENCL_FAILED , +// device opengl + AMF_GLX_FAILED ,//failed to use GLX +// device XV + AMF_XV_FAILED , //failed to use Xv extension +// device alsa + AMF_ALSA_FAILED ,//failed to use ALSA + +// component common codes + + //result codes + AMF_EOF , + AMF_REPEAT , + AMF_INPUT_FULL ,//returned by AMFComponent::SubmitInput if input queue is full + AMF_RESOLUTION_CHANGED ,//resolution changed client needs to Drain/Terminate/Init + AMF_RESOLUTION_UPDATED ,//resolution changed in adaptive mode. New ROI will be set on output on newly decoded frames + + //error codes + AMF_INVALID_DATA_TYPE ,//invalid data type + AMF_INVALID_RESOLUTION ,//invalid resolution (width or height) + AMF_CODEC_NOT_SUPPORTED ,//codec not supported + AMF_SURFACE_FORMAT_NOT_SUPPORTED ,//surface format not supported + AMF_SURFACE_MUST_BE_SHARED ,//surface should be shared (DX11: (MiscFlags & D3D11_RESOURCE_MISC_SHARED) == 0, DX9: No shared handle found) + +// component video decoder + AMF_DECODER_NOT_PRESENT ,//failed to create the decoder + AMF_DECODER_SURFACE_ALLOCATION_FAILED ,//failed to create the surface for decoding + AMF_DECODER_NO_FREE_SURFACES , + +// component video encoder + AMF_ENCODER_NOT_PRESENT ,//failed to create the encoder + +// component video processor + +// component video conveter + +// component dem + AMF_DEM_ERROR , + AMF_DEM_PROPERTY_READONLY , + AMF_DEM_REMOTE_DISPLAY_CREATE_FAILED , + AMF_DEM_START_ENCODING_FAILED , + AMF_DEM_QUERY_OUTPUT_FAILED , + +// component TAN + AMF_TAN_CLIPPING_WAS_REQUIRED , // Resulting data was truncated to meet output type's value limits. + AMF_TAN_UNSUPPORTED_VERSION , // Not supported version requested, solely for TANCreateContext(). + + AMF_NEED_MORE_INPUT ,//returned by AMFComponent::SubmitInput did not produce buffer +} AMF_RESULT; + +#endif //#ifndef AMF_Result_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Surface.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Surface.h new file mode 100644 index 000000000000..f0fe94739273 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Surface.h @@ -0,0 +1,254 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_Surface_h +#define AMF_Surface_h +#pragma once + +#include "Data.h" +#include "Plane.h" + +#if defined(_MSC_VER) + #pragma warning( push ) + #pragma warning(disable : 4263) + #pragma warning(disable : 4264) +#endif +#if defined(__cplusplus) +namespace amf +{ +#endif + //---------------------------------------------------------------------------------------------- + typedef enum AMF_SURFACE_FORMAT + { + AMF_SURFACE_UNKNOWN = 0, + AMF_SURFACE_NV12, ///< 1 - planar Y width x height + packed UV width/2 x height/2 - 8 bit per component + AMF_SURFACE_YV12, ///< 2 - planar Y width x height + V width/2 x height/2 + U width/2 x height/2 - 8 bit per component + AMF_SURFACE_BGRA, ///< 3 - packed - 8 bit per component + AMF_SURFACE_ARGB, ///< 4 - packed - 8 bit per component + AMF_SURFACE_RGBA, ///< 5 - packed - 8 bit per component + AMF_SURFACE_GRAY8, ///< 6 - single component - 8 bit + AMF_SURFACE_YUV420P, ///< 7 - planar Y width x height + U width/2 x height/2 + V width/2 x height/2 - 8 bit per component + AMF_SURFACE_U8V8, ///< 8 - double component - 8 bit per component + AMF_SURFACE_YUY2, ///< 9 - YUY2: Byte 0=8-bit Y'0; Byte 1=8-bit Cb; Byte 2=8-bit Y'1; Byte 3=8-bit Cr + AMF_SURFACE_P010, ///< 10- planar Y width x height + packed UV width/2 x height/2 - 10 bit per component (16 allocated, upper 10 bits are used) + AMF_SURFACE_RGBA_F16, ///< 11 - packed - 16 bit per component float + AMF_SURFACE_UYVY, ///< 12 - the similar to YUY2 but Y and UV swapped: Byte 0=8-bit Cb; Byte 1=8-bit Y'0; Byte 2=8-bit Cr Byte 3=8-bit Y'1; (used the same DX/CL/Vulkan storage as YUY2) + + AMF_SURFACE_FIRST = AMF_SURFACE_NV12, + AMF_SURFACE_LAST = AMF_SURFACE_RGBA_F16 + } AMF_SURFACE_FORMAT; + //---------------------------------------------------------------------------------------------- + // AMF_SURFACE_USAGE translates to D3D11_BIND_FLAG or VkImageUsageFlags + // bit mask + //---------------------------------------------------------------------------------------------- + typedef enum AMF_SURFACE_USAGE_BITS + { // D3D11 Vulkan + AMF_SURFACE_USAGE_DEFAULT = 0x80000000, // will apply default VK_IMAGE_USAGE_TRANSFER_SRC_BIT| VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT + AMF_SURFACE_USAGE_NONE = 0x00000000, // 0, , 0 + AMF_SURFACE_USAGE_SHADER_RESOURCE = 0x00000001, // D3D11_BIND_SHADER_RESOURCE, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT + AMF_SURFACE_USAGE_RENDER_TARGET = 0x00000002, // D3D11_BIND_RENDER_TARGET, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT + AMF_SURFACE_USAGE_UNORDERED_ACCESS = 0x00000004, // D3D11_BIND_UNORDERED_ACCESS, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT + AMF_SURFACE_USAGE_TRANSFER_SRC = 0x00000008, // VK_IMAGE_USAGE_TRANSFER_SRC_BIT + AMF_SURFACE_USAGE_TRANSFER_DST = 0x00000010, // VK_IMAGE_USAGE_TRANSFER_DST_BIT + } AMF_SURFACE_USAGE_BITS; + typedef amf_flags AMF_SURFACE_USAGE; + //---------------------------------------------------------------------------------------------- + +#if defined(_WIN32) + AMF_WEAK GUID AMFFormatGUID = { 0x8cd592d0, 0x8063, 0x4af8, 0xa7, 0xd0, 0x32, 0x5b, 0xc5, 0xf7, 0x48, 0xab}; // UINT(AMF_SURFACE_FORMAT), default - AMF_SURFACE_UNKNOWN; to be set on ID3D11Texture2D objects when used natively (i.e. force UYVY on DXGI_FORMAT_YUY2 texture) +#endif + + //---------------------------------------------------------------------------------------------- + // frame type + //---------------------------------------------------------------------------------------------- + typedef enum AMF_FRAME_TYPE + { + // flags + AMF_FRAME_STEREO_FLAG = 0x10000000, + AMF_FRAME_LEFT_FLAG = AMF_FRAME_STEREO_FLAG | 0x20000000, + AMF_FRAME_RIGHT_FLAG = AMF_FRAME_STEREO_FLAG | 0x40000000, + AMF_FRAME_BOTH_FLAG = AMF_FRAME_LEFT_FLAG | AMF_FRAME_RIGHT_FLAG, + AMF_FRAME_INTERLEAVED_FLAG = 0x01000000, + AMF_FRAME_FIELD_FLAG = 0x02000000, + AMF_FRAME_EVEN_FLAG = 0x04000000, + AMF_FRAME_ODD_FLAG = 0x08000000, + + // values + AMF_FRAME_UNKNOWN =-1, + AMF_FRAME_PROGRESSIVE = 0, + + AMF_FRAME_INTERLEAVED_EVEN_FIRST = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_EVEN_FLAG, + AMF_FRAME_INTERLEAVED_ODD_FIRST = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_ODD_FLAG, + AMF_FRAME_FIELD_SINGLE_EVEN = AMF_FRAME_FIELD_FLAG | AMF_FRAME_EVEN_FLAG, + AMF_FRAME_FIELD_SINGLE_ODD = AMF_FRAME_FIELD_FLAG | AMF_FRAME_ODD_FLAG, + + AMF_FRAME_STEREO_LEFT = AMF_FRAME_LEFT_FLAG, + AMF_FRAME_STEREO_RIGHT = AMF_FRAME_RIGHT_FLAG, + AMF_FRAME_STEREO_BOTH = AMF_FRAME_BOTH_FLAG, + + AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_LEFT = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_EVEN_FLAG | AMF_FRAME_LEFT_FLAG, + AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_RIGHT = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_EVEN_FLAG | AMF_FRAME_RIGHT_FLAG, + AMF_FRAME_INTERLEAVED_EVEN_FIRST_STEREO_BOTH = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_EVEN_FLAG | AMF_FRAME_BOTH_FLAG, + + AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_LEFT = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_ODD_FLAG | AMF_FRAME_LEFT_FLAG, + AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_RIGHT = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_ODD_FLAG | AMF_FRAME_RIGHT_FLAG, + AMF_FRAME_INTERLEAVED_ODD_FIRST_STEREO_BOTH = AMF_FRAME_INTERLEAVED_FLAG | AMF_FRAME_ODD_FLAG | AMF_FRAME_BOTH_FLAG, + } AMF_FRAME_TYPE; + + //---------------------------------------------------------------------------------------------- + // AMFSurfaceObserver interface - callback; is called before internal release resources. + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMFSurface; + class AMF_NO_VTABLE AMFSurfaceObserver + { + public: + virtual void AMF_STD_CALL OnSurfaceDataRelease(AMFSurface* pSurface) = 0; + }; +#else // #if defined(__cplusplus) + typedef struct AMFSurface AMFSurface; + typedef struct AMFSurfaceObserver AMFSurfaceObserver; + + typedef struct AMFSurfaceObserverVtbl + { + void (AMF_STD_CALL *OnSurfaceDataRelease)(AMFSurfaceObserver* pThis, AMFSurface* pSurface); + } AMFSurfaceObserverVtbl; + + struct AMFSurfaceObserver + { + const AMFSurfaceObserverVtbl *pVtbl; + }; +#endif // #if defined(__cplusplus) + + //---------------------------------------------------------------------------------------------- + // AMFSurface interface + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFSurface : public AMFData + { + public: + AMF_DECLARE_IID(0x3075dbe3, 0x8718, 0x4cfa, 0x86, 0xfb, 0x21, 0x14, 0xc0, 0xa5, 0xa4, 0x51) + + virtual AMF_SURFACE_FORMAT AMF_STD_CALL GetFormat() = 0; + + // do not store planes outside. should be used together with Surface + virtual amf_size AMF_STD_CALL GetPlanesCount() = 0; + virtual AMFPlane* AMF_STD_CALL GetPlaneAt(amf_size index) = 0; + virtual AMFPlane* AMF_STD_CALL GetPlane(AMF_PLANE_TYPE type) = 0; + + virtual AMF_FRAME_TYPE AMF_STD_CALL GetFrameType() = 0; + virtual void AMF_STD_CALL SetFrameType(AMF_FRAME_TYPE type) = 0; + + virtual AMF_RESULT AMF_STD_CALL SetCrop(amf_int32 x,amf_int32 y, amf_int32 width, amf_int32 height) = 0; + virtual AMF_RESULT AMF_STD_CALL CopySurfaceRegion(AMFSurface* pDest, amf_int32 dstX, amf_int32 dstY, amf_int32 srcX, amf_int32 srcY, amf_int32 width, amf_int32 height) = 0; + + // Observer management + virtual void AMF_STD_CALL AddObserver(AMFSurfaceObserver* pObserver) = 0; + virtual void AMF_STD_CALL RemoveObserver(AMFSurfaceObserver* pObserver) = 0; + }; + //---------------------------------------------------------------------------------------------- + // smart pointer + //---------------------------------------------------------------------------------------------- + typedef AMFInterfacePtr_T AMFSurfacePtr; + //---------------------------------------------------------------------------------------------- +#else // #if defined(__cplusplus) + AMF_DECLARE_IID(AMFSurface, 0x3075dbe3, 0x8718, 0x4cfa, 0x86, 0xfb, 0x21, 0x14, 0xc0, 0xa5, 0xa4, 0x51) + typedef struct AMFSurfaceVtbl + { + // AMFInterface interface + amf_long (AMF_STD_CALL *Acquire)(AMFSurface* pThis); + amf_long (AMF_STD_CALL *Release)(AMFSurface* pThis); + enum AMF_RESULT (AMF_STD_CALL *QueryInterface)(AMFSurface* pThis, const struct AMFGuid *interfaceID, void** ppInterface); + + // AMFPropertyStorage interface + AMF_RESULT (AMF_STD_CALL *SetProperty)(AMFSurface* pThis, const wchar_t* name, AMFVariantStruct value); + AMF_RESULT (AMF_STD_CALL *GetProperty)(AMFSurface* pThis, const wchar_t* name, AMFVariantStruct* pValue); + amf_bool (AMF_STD_CALL *HasProperty)(AMFSurface* pThis, const wchar_t* name); + amf_size (AMF_STD_CALL *GetPropertyCount)(AMFSurface* pThis); + AMF_RESULT (AMF_STD_CALL *GetPropertyAt)(AMFSurface* pThis, amf_size index, wchar_t* name, amf_size nameSize, AMFVariantStruct* pValue); + AMF_RESULT (AMF_STD_CALL *Clear)(AMFSurface* pThis); + AMF_RESULT (AMF_STD_CALL *AddTo)(AMFSurface* pThis, AMFPropertyStorage* pDest, amf_bool overwrite, amf_bool deep); + AMF_RESULT (AMF_STD_CALL *CopyTo)(AMFSurface* pThis, AMFPropertyStorage* pDest, amf_bool deep); + void (AMF_STD_CALL *AddObserver)(AMFSurface* pThis, AMFPropertyStorageObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver)(AMFSurface* pThis, AMFPropertyStorageObserver* pObserver); + + // AMFData interface + + AMF_MEMORY_TYPE (AMF_STD_CALL *GetMemoryType)(AMFSurface* pThis); + + AMF_RESULT (AMF_STD_CALL *Duplicate)(AMFSurface* pThis, AMF_MEMORY_TYPE type, AMFData** ppData); + AMF_RESULT (AMF_STD_CALL *Convert)(AMFSurface* pThis, AMF_MEMORY_TYPE type); // optimal interop if possilble. Copy through host memory if needed + AMF_RESULT (AMF_STD_CALL *Interop)(AMFSurface* pThis, AMF_MEMORY_TYPE type); // only optimal interop if possilble. No copy through host memory for GPU objects + + AMF_DATA_TYPE (AMF_STD_CALL *GetDataType)(AMFSurface* pThis); + + amf_bool (AMF_STD_CALL *IsReusable)(AMFSurface* pThis); + + void (AMF_STD_CALL *SetPts)(AMFSurface* pThis, amf_pts pts); + amf_pts (AMF_STD_CALL *GetPts)(AMFSurface* pThis); + void (AMF_STD_CALL *SetDuration)(AMFSurface* pThis, amf_pts duration); + amf_pts (AMF_STD_CALL *GetDuration)(AMFSurface* pThis); + + // AMFSurface interface + + AMF_SURFACE_FORMAT (AMF_STD_CALL *GetFormat)(AMFSurface* pThis); + + // do not store planes outside. should be used together with Surface + amf_size (AMF_STD_CALL *GetPlanesCount)(AMFSurface* pThis); + AMFPlane* (AMF_STD_CALL *GetPlaneAt)(AMFSurface* pThis, amf_size index); + AMFPlane* (AMF_STD_CALL *GetPlane)(AMFSurface* pThis, AMF_PLANE_TYPE type); + + AMF_FRAME_TYPE (AMF_STD_CALL *GetFrameType)(AMFSurface* pThis); + void (AMF_STD_CALL *SetFrameType)(AMFSurface* pThis, AMF_FRAME_TYPE type); + + AMF_RESULT (AMF_STD_CALL *SetCrop)(AMFSurface* pThis, amf_int32 x,amf_int32 y, amf_int32 width, amf_int32 height); + AMF_RESULT (AMF_STD_CALL *CopySurfaceRegion)(AMFSurface* pThis, AMFSurface* pDest, amf_int32 dstX, amf_int32 dstY, amf_int32 srcX, amf_int32 srcY, amf_int32 width, amf_int32 height); + + + // Observer management + void (AMF_STD_CALL *AddObserver_Surface)(AMFSurface* pThis, AMFSurfaceObserver* pObserver); + void (AMF_STD_CALL *RemoveObserver_Surface)(AMFSurface* pThis, AMFSurfaceObserver* pObserver); + + } AMFSurfaceVtbl; + + struct AMFSurface + { + const AMFSurfaceVtbl *pVtbl; + }; +#endif // #if defined(__cplusplus) +#if defined(__cplusplus) +} +#endif +#if defined(_MSC_VER) + #pragma warning( pop ) +#endif +#endif //#ifndef AMF_Surface_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Trace.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Trace.h new file mode 100644 index 000000000000..f9a37514ddf9 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Trace.h @@ -0,0 +1,183 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_Trace_h +#define AMF_Trace_h +#pragma once + +#include "Platform.h" +#include "Result.h" +#include "Surface.h" +#include "AudioBuffer.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif + //---------------------------------------------------------------------------------------------- + // trace levels + //---------------------------------------------------------------------------------------------- + #define AMF_TRACE_ERROR 0 + #define AMF_TRACE_WARNING 1 + #define AMF_TRACE_INFO 2 // default in sdk + #define AMF_TRACE_DEBUG 3 + #define AMF_TRACE_TRACE 4 + + #define AMF_TRACE_TEST 5 + #define AMF_TRACE_NOLOG 100 + + //---------------------------------------------------------------------------------------------- + // available trace writers + //---------------------------------------------------------------------------------------------- + #define AMF_TRACE_WRITER_CONSOLE L"Console" + #define AMF_TRACE_WRITER_DEBUG_OUTPUT L"DebugOutput" + #define AMF_TRACE_WRITER_FILE L"File" + + //---------------------------------------------------------------------------------------------- + // AMFTraceWriter interface - callback + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFTraceWriter + { + public: + virtual void AMF_CDECL_CALL Write(const wchar_t* scope, const wchar_t* message) = 0; + virtual void AMF_CDECL_CALL Flush() = 0; + }; +#else // #if defined(__cplusplus) + typedef struct AMFTraceWriter AMFTraceWriter; + + typedef struct AMFTraceWriterVtbl + { + // AMFTraceWriter interface + void (AMF_CDECL_CALL *Write)(AMFTraceWriter* pThis, const wchar_t* scope, const wchar_t* message); + void (AMF_CDECL_CALL *Flush)(AMFTraceWriter* pThis); + } AMFTraceWriterVtbl; + + struct AMFTraceWriter + { + const AMFTraceWriterVtbl *pVtbl; + }; + +#endif // #if defined(__cplusplus) + + //---------------------------------------------------------------------------------------------- + // AMFTrace interface - singleton + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + class AMF_NO_VTABLE AMFTrace + { + public: + virtual void AMF_STD_CALL TraceW(const wchar_t* src_path, amf_int32 line, amf_int32 level, const wchar_t* scope,amf_int32 countArgs, const wchar_t* format, ...) = 0; + virtual void AMF_STD_CALL Trace(const wchar_t* src_path, amf_int32 line, amf_int32 level, const wchar_t* scope, const wchar_t* message, va_list* pArglist) = 0; + + virtual amf_int32 AMF_STD_CALL SetGlobalLevel(amf_int32 level) = 0; + virtual amf_int32 AMF_STD_CALL GetGlobalLevel() = 0; + + virtual amf_bool AMF_STD_CALL EnableWriter(const wchar_t* writerID, bool enable) = 0; + virtual amf_bool AMF_STD_CALL WriterEnabled(const wchar_t* writerID) = 0; + virtual AMF_RESULT AMF_STD_CALL TraceEnableAsync(amf_bool enable) = 0; + virtual AMF_RESULT AMF_STD_CALL TraceFlush() = 0; + virtual AMF_RESULT AMF_STD_CALL SetPath(const wchar_t* path) = 0; + virtual AMF_RESULT AMF_STD_CALL GetPath(wchar_t* path, amf_size* pSize) = 0; + virtual amf_int32 AMF_STD_CALL SetWriterLevel(const wchar_t* writerID, amf_int32 level) = 0; + virtual amf_int32 AMF_STD_CALL GetWriterLevel(const wchar_t* writerID) = 0; + virtual amf_int32 AMF_STD_CALL SetWriterLevelForScope(const wchar_t* writerID, const wchar_t* scope, amf_int32 level) = 0; + virtual amf_int32 AMF_STD_CALL GetWriterLevelForScope(const wchar_t* writerID, const wchar_t* scope) = 0; + + virtual amf_int32 AMF_STD_CALL GetIndentation() = 0; + virtual void AMF_STD_CALL Indent(amf_int32 addIndent) = 0; + + virtual void AMF_STD_CALL RegisterWriter(const wchar_t* writerID, AMFTraceWriter* pWriter, amf_bool enable) = 0; + virtual void AMF_STD_CALL UnregisterWriter(const wchar_t* writerID) = 0; + + virtual const wchar_t* AMF_STD_CALL GetResultText(AMF_RESULT res) = 0; + virtual const wchar_t* AMF_STD_CALL SurfaceGetFormatName(const AMF_SURFACE_FORMAT eSurfaceFormat) = 0; + virtual AMF_SURFACE_FORMAT AMF_STD_CALL SurfaceGetFormatByName(const wchar_t* name) = 0; + + virtual const wchar_t* const AMF_STD_CALL GetMemoryTypeName(const AMF_MEMORY_TYPE memoryType) = 0; + virtual AMF_MEMORY_TYPE AMF_STD_CALL GetMemoryTypeByName(const wchar_t* name) = 0; + + virtual const wchar_t* const AMF_STD_CALL GetSampleFormatName(const AMF_AUDIO_FORMAT eFormat) = 0; + virtual AMF_AUDIO_FORMAT AMF_STD_CALL GetSampleFormatByName(const wchar_t* name) = 0; + }; +#else // #if defined(__cplusplus) + typedef struct AMFTrace AMFTrace; + + typedef struct AMFTraceVtbl + { + // AMFTrace interface + void (AMF_STD_CALL *TraceW)(AMFTrace* pThis, const wchar_t* src_path, amf_int32 line, amf_int32 level, const wchar_t* scope,amf_int32 countArgs, const wchar_t* format, ...); + void (AMF_STD_CALL *Trace)(AMFTrace* pThis, const wchar_t* src_path, amf_int32 line, amf_int32 level, const wchar_t* scope, const wchar_t* message, va_list* pArglist); + + amf_int32 (AMF_STD_CALL *SetGlobalLevel)(AMFTrace* pThis, amf_int32 level); + amf_int32 (AMF_STD_CALL *GetGlobalLevel)(AMFTrace* pThis); + + amf_bool (AMF_STD_CALL *EnableWriter)(AMFTrace* pThis, const wchar_t* writerID, amf_bool enable); + amf_bool (AMF_STD_CALL *WriterEnabled)(AMFTrace* pThis, const wchar_t* writerID); + AMF_RESULT (AMF_STD_CALL *TraceEnableAsync)(AMFTrace* pThis, amf_bool enable); + AMF_RESULT (AMF_STD_CALL *TraceFlush)(AMFTrace* pThis); + AMF_RESULT (AMF_STD_CALL *SetPath)(AMFTrace* pThis, const wchar_t* path); + AMF_RESULT (AMF_STD_CALL *GetPath)(AMFTrace* pThis, wchar_t* path, amf_size* pSize); + amf_int32 (AMF_STD_CALL *SetWriterLevel)(AMFTrace* pThis, const wchar_t* writerID, amf_int32 level); + amf_int32 (AMF_STD_CALL *GetWriterLevel)(AMFTrace* pThis, const wchar_t* writerID); + amf_int32 (AMF_STD_CALL *SetWriterLevelForScope)(AMFTrace* pThis, const wchar_t* writerID, const wchar_t* scope, amf_int32 level); + amf_int32 (AMF_STD_CALL *GetWriterLevelForScope)(AMFTrace* pThis, const wchar_t* writerID, const wchar_t* scope); + + amf_int32 (AMF_STD_CALL *GetIndentation)(AMFTrace* pThis); + void (AMF_STD_CALL *Indent)(AMFTrace* pThis, amf_int32 addIndent); + + void (AMF_STD_CALL *RegisterWriter)(AMFTrace* pThis, const wchar_t* writerID, AMFTraceWriter* pWriter, amf_bool enable); + void (AMF_STD_CALL *UnregisterWriter)(AMFTrace* pThis, const wchar_t* writerID); + + const wchar_t* (AMF_STD_CALL *GetResultText)(AMFTrace* pThis, AMF_RESULT res); + const wchar_t* (AMF_STD_CALL *SurfaceGetFormatName)(AMFTrace* pThis, const AMF_SURFACE_FORMAT eSurfaceFormat); + AMF_SURFACE_FORMAT (AMF_STD_CALL *SurfaceGetFormatByName)(AMFTrace* pThis, const wchar_t* name); + + const wchar_t* const (AMF_STD_CALL *GetMemoryTypeName)(AMFTrace* pThis, const AMF_MEMORY_TYPE memoryType); + AMF_MEMORY_TYPE (AMF_STD_CALL *GetMemoryTypeByName)(AMFTrace* pThis, const wchar_t* name); + + const wchar_t* const (AMF_STD_CALL *GetSampleFormatName)(AMFTrace* pThis, const AMF_AUDIO_FORMAT eFormat); + AMF_AUDIO_FORMAT (AMF_STD_CALL *GetSampleFormatByName)(AMFTrace* pThis, const wchar_t* name); + } AMFTraceVtbl; + + struct AMFTrace + { + const AMFTraceVtbl *pVtbl; + }; + +#endif +#if defined(__cplusplus) +} +#endif + + +#endif // AMF_Trace_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Variant.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Variant.h new file mode 100644 index 000000000000..ebd472a13476 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Variant.h @@ -0,0 +1,1707 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef AMF_Variant_h +#define AMF_Variant_h +#pragma once +#if defined(_MSC_VER) + #pragma warning(disable: 4996) +#endif + +#include "Interface.h" +#include +#include +#include + +#if defined(__cplusplus) +namespace amf +{ +#endif + //---------------------------------------------------------------------------------------------- + // variant types + //---------------------------------------------------------------------------------------------- + typedef enum AMF_VARIANT_TYPE + { + AMF_VARIANT_EMPTY = 0, + + AMF_VARIANT_BOOL = 1, + AMF_VARIANT_INT64 = 2, + AMF_VARIANT_DOUBLE = 3, + + AMF_VARIANT_RECT = 4, + AMF_VARIANT_SIZE = 5, + AMF_VARIANT_POINT = 6, + AMF_VARIANT_RATE = 7, + AMF_VARIANT_RATIO = 8, + AMF_VARIANT_COLOR = 9, + + AMF_VARIANT_STRING = 10, // value is char* + AMF_VARIANT_WSTRING = 11, // value is wchar_t* + AMF_VARIANT_INTERFACE = 12, // value is AMFInterface* + } AMF_VARIANT_TYPE; + //---------------------------------------------------------------------------------------------- + // variant struct + //---------------------------------------------------------------------------------------------- + typedef struct AMFVariantStruct + { + AMF_VARIANT_TYPE type; + union + { + amf_bool boolValue; + amf_int64 int64Value; + amf_double doubleValue; + char* stringValue; + wchar_t* wstringValue; + AMFInterface* pInterface; + struct AMFRect rectValue; + struct AMFSize sizeValue; + struct AMFPoint pointValue; + struct AMFRate rateValue; + struct AMFRatio ratioValue; + struct AMFColor colorValue; + }; + } AMFVariantStruct; + //---------------------------------------------------------------------------------------------- + // variant accessors + //---------------------------------------------------------------------------------------------- + + static AMF_INLINE AMF_VARIANT_TYPE AMF_STD_CALL AMFVariantGetType(const AMFVariantStruct* _variant) { return (_variant)->type; } +#if defined(__cplusplus) + static AMF_INLINE AMF_VARIANT_TYPE& AMF_STD_CALL AMFVariantGetType(AMFVariantStruct* _variant) { return (_variant)->type; } +#endif + static AMF_INLINE amf_bool AMF_STD_CALL AMFVariantGetBool(const AMFVariantStruct* _variant) { return (_variant)->boolValue; } + static AMF_INLINE amf_int64 AMF_STD_CALL AMFVariantGetInt64(const AMFVariantStruct* _variant) { return (_variant)->int64Value; } + static AMF_INLINE amf_double AMF_STD_CALL AMFVariantGetDouble(const AMFVariantStruct* _variant) { return (_variant)->doubleValue; } + static AMF_INLINE const char* AMF_STD_CALL AMFVariantGetString(const AMFVariantStruct* _variant) { return (_variant)->stringValue; } + static AMF_INLINE const wchar_t* AMF_STD_CALL AMFVariantGetWString(const AMFVariantStruct* _variant) { return (_variant)->wstringValue; } +#if defined(__cplusplus) + static AMF_INLINE const AMFInterface* AMF_STD_CALL AMFVariantGetInterface(const AMFVariantStruct* _variant) { return (_variant)->pInterface; } +#endif + static AMF_INLINE AMFInterface* AMF_STD_CALL AMFVariantGetInterface(AMFVariantStruct* _variant) { return (_variant)->pInterface; } + +#if defined(__cplusplus) + static AMF_INLINE const AMFRect & AMF_STD_CALL AMFVariantGetRect (const AMFVariantStruct* _variant) { return (_variant)->rectValue; } + static AMF_INLINE const AMFSize & AMF_STD_CALL AMFVariantGetSize (const AMFVariantStruct* _variant) { return (_variant)->sizeValue; } + static AMF_INLINE const AMFPoint& AMF_STD_CALL AMFVariantGetPoint(const AMFVariantStruct* _variant) { return (_variant)->pointValue; } + static AMF_INLINE const AMFRate & AMF_STD_CALL AMFVariantGetRate (const AMFVariantStruct* _variant) { return (_variant)->rateValue; } + static AMF_INLINE const AMFRatio& AMF_STD_CALL AMFVariantGetRatio(const AMFVariantStruct* _variant) { return (_variant)->ratioValue; } + static AMF_INLINE const AMFColor& AMF_STD_CALL AMFVariantGetColor(const AMFVariantStruct* _variant) { return (_variant)->colorValue; } +#else // #if defined(__cplusplus) + static AMF_INLINE const AMFRect AMF_STD_CALL AMFVariantGetRect (const AMFVariantStruct* _variant) { return (_variant)->rectValue; } + static AMF_INLINE const AMFSize AMF_STD_CALL AMFVariantGetSize (const AMFVariantStruct* _variant) { return (_variant)->sizeValue; } + static AMF_INLINE const AMFPoint AMF_STD_CALL AMFVariantGetPoint(const AMFVariantStruct* _variant) { return (_variant)->pointValue; } + static AMF_INLINE const AMFRate AMF_STD_CALL AMFVariantGetRate (const AMFVariantStruct* _variant) { return (_variant)->rateValue; } + static AMF_INLINE const AMFRatio AMF_STD_CALL AMFVariantGetRatio(const AMFVariantStruct* _variant) { return (_variant)->ratioValue; } + static AMF_INLINE const AMFColor AMF_STD_CALL AMFVariantGetColor(const AMFVariantStruct* _variant) { return (_variant)->colorValue; } +#endif // #if defined(__cplusplus) + + + #define AMFVariantEmpty(_variant) 0 + #define AMFVariantBool(_variant) (_variant)->boolValue + #define AMFVariantInt64(_variant) (_variant)->int64Value + #define AMFVariantDouble(_variant) (_variant)->doubleValue + + #define AMFVariantRect(_variant) (_variant)->rectValue + #define AMFVariantSize(_variant) (_variant)->sizeValue + #define AMFVariantPoint(_variant) (_variant)->pointValue + #define AMFVariantRate(_variant) (_variant)->rateValue + #define AMFVariantRatio(_variant) (_variant)->ratioValue + #define AMFVariantColor(_variant) (_variant)->colorValue + + #define AMFVariantString(_variant) (_variant)->stringValue + #define AMFVariantWString(_variant) (_variant)->wstringValue + #define AMFVariantInterface(_variant) (_variant)->pInterface + //---------------------------------------------------------------------------------------------- + // variant hleper functions + //---------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantInit(AMFVariantStruct* pVariant); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantClear(AMFVariantStruct* pVariant); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantCompare(const AMFVariantStruct* pFirst, const AMFVariantStruct* pSecond, amf_bool* equal); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantCopy(AMFVariantStruct* pDest, const AMFVariantStruct* pSrc); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignBool(AMFVariantStruct* pDest, amf_bool value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignInt64(AMFVariantStruct* pDest, amf_int64 value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignDouble(AMFVariantStruct* pDest, amf_double value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignString(AMFVariantStruct* pDest, const char* value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignWString(AMFVariantStruct* pDest, const wchar_t* value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignInterface(AMFVariantStruct* pDest, AMFInterface* value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRect(AMFVariantStruct* pDest, const AMFRect* value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignSize(AMFVariantStruct* pDest, const AMFSize* value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignPoint(AMFVariantStruct* pDest, const AMFPoint* value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRate(AMFVariantStruct* pDest, const AMFRate* value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRatio(AMFVariantStruct* pDest, const AMFRatio* value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignColor(AMFVariantStruct* pDest, const AMFColor* value); + +#if defined(__cplusplus) + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRect(AMFVariantStruct* pDest, const AMFRect& value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignSize(AMFVariantStruct* pDest, const AMFSize& value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignPoint(AMFVariantStruct* pDest, const AMFPoint& value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRate(AMFVariantStruct* pDest, const AMFRate& value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRatio(AMFVariantStruct* pDest, const AMFRatio& value); + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignColor(AMFVariantStruct* pDest, const AMFColor& value); + + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantChangeType(AMFVariantStruct* pDest, const AMFVariantStruct* pSrc, AMF_VARIANT_TYPE newType); +#endif + static AMF_INLINE char* AMF_CDECL_CALL AMFVariantDuplicateString(const char* from); + static AMF_INLINE void AMF_CDECL_CALL AMFVariantFreeString(char* from); + static AMF_INLINE wchar_t* AMF_CDECL_CALL AMFVariantDuplicateWString(const wchar_t* from); + static AMF_INLINE void AMF_CDECL_CALL AMFVariantFreeWString(wchar_t* from); + +#if defined(__cplusplus) + //---------------------------------------------------------------------------------------------- + // AMF_INLINE Variant helper class + //---------------------------------------------------------------------------------------------- + class AMFVariant : public AMFVariantStruct + { + public: + class String; + class WString; + + public: + AMFVariant() { AMFVariantInit(this); } + explicit AMFVariant(const AMFVariantStruct& other) { AMFVariantInit(this); AMFVariantCopy(this, const_cast(&other)); } + + explicit AMFVariant(const AMFVariantStruct* pOther); + template + explicit AMFVariant(const AMFInterfacePtr_T& pValue); + + AMFVariant(const AMFVariant& other) { AMFVariantInit(this); AMFVariantCopy(this, const_cast(static_cast(&other))); } + + explicit AMF_INLINE AMFVariant(amf_bool value) { AMFVariantInit(this); AMFVariantAssignBool(this, value); } + explicit AMF_INLINE AMFVariant(amf_int64 value) { AMFVariantInit(this); AMFVariantAssignInt64(this, value); } + explicit AMF_INLINE AMFVariant(amf_uint64 value) { AMFVariantInit(this); AMFVariantAssignInt64(this, (amf_int64)value); } + explicit AMF_INLINE AMFVariant(amf_int32 value) { AMFVariantInit(this); AMFVariantAssignInt64(this, value); } + explicit AMF_INLINE AMFVariant(amf_uint32 value) { AMFVariantInit(this); AMFVariantAssignInt64(this, value); } + explicit AMF_INLINE AMFVariant(amf_double value) { AMFVariantInit(this); AMFVariantAssignDouble(this, value); } + explicit AMF_INLINE AMFVariant(const AMFRect & value) { AMFVariantInit(this); AMFVariantAssignRect(this, &value); } + explicit AMF_INLINE AMFVariant(const AMFSize & value) { AMFVariantInit(this); AMFVariantAssignSize(this, &value); } + explicit AMF_INLINE AMFVariant(const AMFPoint& value) { AMFVariantInit(this); AMFVariantAssignPoint(this, &value); } + explicit AMF_INLINE AMFVariant(const AMFRate & value) { AMFVariantInit(this); AMFVariantAssignRate(this, &value); } + explicit AMF_INLINE AMFVariant(const AMFRatio& value) { AMFVariantInit(this); AMFVariantAssignRatio(this, &value); } + explicit AMF_INLINE AMFVariant(const AMFColor& value) { AMFVariantInit(this); AMFVariantAssignColor(this, &value); } + explicit AMF_INLINE AMFVariant(const char* value) { AMFVariantInit(this); AMFVariantAssignString(this, value); } + explicit AMF_INLINE AMFVariant(const wchar_t* value) { AMFVariantInit(this); AMFVariantAssignWString(this, value); } + explicit AMF_INLINE AMFVariant(AMFInterface* pValue) { AMFVariantInit(this); AMFVariantAssignInterface(this, pValue); } + + ~AMFVariant() { AMFVariantClear(this); } + + AMFVariant& operator=(const AMFVariantStruct& other); + AMFVariant& operator=(const AMFVariantStruct* pOther); + AMFVariant& operator=(const AMFVariant& other); + + AMFVariant& operator=(amf_bool value) { AMFVariantAssignBool(this, value); return *this;} + AMFVariant& operator=(amf_int64 value) { AMFVariantAssignInt64(this, value); return *this;} + AMFVariant& operator=(amf_uint64 value) { AMFVariantAssignInt64(this, (amf_int64)value); return *this;} + AMFVariant& operator=(amf_int32 value) { AMFVariantAssignInt64(this, value); return *this;} + AMFVariant& operator=(amf_uint32 value) { AMFVariantAssignInt64(this, value); return *this;} + AMFVariant& operator=(amf_double value) { AMFVariantAssignDouble(this, value); return *this;} + AMFVariant& operator=(const AMFRect & value) { AMFVariantAssignRect(this, &value); return *this;} + AMFVariant& operator=(const AMFSize & value) { AMFVariantAssignSize(this, &value); return *this;} + AMFVariant& operator=(const AMFPoint& value) { AMFVariantAssignPoint(this, &value); return *this;} + AMFVariant& operator=(const AMFRate & value) { AMFVariantAssignRate(this, &value); return *this;} + AMFVariant& operator=(const AMFRatio& value) { AMFVariantAssignRatio(this, &value); return *this;} + AMFVariant& operator=(const AMFColor& value) { AMFVariantAssignColor(this, &value); return *this;} + AMFVariant& operator=(const char* value) { AMFVariantAssignString(this, value); return *this;} + AMFVariant& operator=(const wchar_t* value) { AMFVariantAssignWString(this, value); return *this;} + AMFVariant& operator=(AMFInterface* value) { AMFVariantAssignInterface(this, value); return *this;} + + template AMFVariant& operator=(const AMFInterfacePtr_T& value); + + operator amf_bool() const { return ToBool(); } + operator amf_int64() const { return ToInt64(); } + operator amf_uint64() const { return ToUInt64(); } + operator amf_int32() const { return ToInt32(); } + operator amf_uint32() const { return ToUInt32(); } + operator amf_double() const { return ToDouble(); } + operator amf_float() const { return ToFloat(); } + operator AMFRect () const { return ToRect (); } + operator AMFSize () const { return ToSize (); } + operator AMFPoint() const { return ToPoint(); } + operator AMFRate () const { return ToRate (); } + operator AMFRatio() const { return ToRatio(); } + operator AMFColor() const { return ToColor(); } + operator AMFInterface*() const { return ToInterface(); } + + AMF_INLINE amf_bool ToBool() const { return Empty() ? false : GetValue(AMFVariantGetBool); } + AMF_INLINE amf_int64 ToInt64() const { return Empty() ? 0 : GetValue(AMFVariantGetInt64); } + AMF_INLINE amf_uint64 ToUInt64() const { return Empty() ? 0 : GetValue(AMFVariantGetInt64); } + AMF_INLINE amf_int32 ToInt32() const { return Empty() ? 0 : GetValue(AMFVariantGetInt64); } + AMF_INLINE amf_uint32 ToUInt32() const { return Empty() ? 0 : GetValue(AMFVariantGetInt64); } + AMF_INLINE amf_double ToDouble() const { return Empty() ? 0 : GetValue(AMFVariantGetDouble); } + AMF_INLINE amf_float ToFloat() const { return Empty() ? 0 : GetValue(AMFVariantGetDouble); } + AMF_INLINE AMFRect ToRect () const { return Empty() ? AMFRect() : GetValue(AMFVariantGetRect); } + AMF_INLINE AMFSize ToSize () const { return Empty() ? AMFSize() : GetValue(AMFVariantGetSize); } + AMF_INLINE AMFPoint ToPoint() const { return Empty() ? AMFPoint() : GetValue(AMFVariantGetPoint); } + AMF_INLINE AMFRate ToRate () const { return Empty() ? AMFRate() : GetValue(AMFVariantGetRate); } + AMF_INLINE AMFRatio ToRatio() const { return Empty() ? AMFRatio() : GetValue(AMFVariantGetRatio); } + AMF_INLINE AMFColor ToColor() const { return Empty() ? AMFColor() : GetValue(AMFVariantGetColor); } + AMF_INLINE AMFInterface* ToInterface() const { return AMFVariantGetType(this) == AMF_VARIANT_INTERFACE ? this->pInterface : NULL; } + AMF_INLINE String ToString() const; + AMF_INLINE WString ToWString() const; + + bool operator==(const AMFVariantStruct& other) const; + bool operator==(const AMFVariantStruct* pOther) const; + + bool operator!=(const AMFVariantStruct& other) const; + bool operator!=(const AMFVariantStruct* pOther) const; + + void Clear() { AMFVariantClear(this); } + + void Attach(AMFVariantStruct& variant); + AMFVariantStruct Detach(); + + AMFVariantStruct& GetVariant(); + + void ChangeType(AMF_VARIANT_TYPE type, const AMFVariant* pSrc = NULL); + + bool Empty() const; + private: + template + ReturnType GetValue(Getter getter) const; + }; + //---------------------------------------------------------------------------------------------- + // helper String class + //---------------------------------------------------------------------------------------------- + class AMFVariant::String + { + friend class AMFVariant; + private: + void Free() + { + if (m_Str != NULL) + { + AMFVariantFreeString(m_Str); + m_Str = NULL; + } + } + public: + String() :m_Str(NULL){} + String(const char* str) : m_Str(NULL) + { + m_Str = AMFVariantDuplicateString(str); + } + String(const String& p_other) : m_Str(NULL) + { + operator=(p_other); + } + +#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (_MSC_VER >= 1600) + String(String&& p_other) : m_Str(NULL) + { + operator=(p_other); + } +#endif + ~String() + { + Free(); + } + + char& operator[](size_t index) + { + if (index >= size()) + { + resize(index); + } + return m_Str[index]; + } + + String& operator=(const String& p_other) + { + Free(); + m_Str = AMFVariantDuplicateString(p_other.m_Str); + return *this; + } +#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (_MSC_VER >= 1600) + String& operator=(String&& p_other) + { + Free(); + m_Str = p_other.m_Str; + p_other.m_Str = NULL; // Transfer the ownership + return *this; + } +#endif + bool operator==(const String& p_other) const + { + if (m_Str == NULL && p_other.m_Str == NULL) + { + return true; + } + else if ((m_Str == NULL && p_other.m_Str != NULL) || (m_Str != NULL && p_other.m_Str == NULL)) + { + return false; + } + return strcmp(c_str(), p_other.c_str()) == 0; + } + const char* c_str() const { return m_Str; } + size_t size() const + { + if(m_Str == NULL) + { + return 0; + } + return (size_t)strlen(m_Str); + } + + AMF_INLINE size_t length() const { return size(); } + + void resize(size_t sizeAlloc) + { + if(sizeAlloc == 0) + { + Free(); + return; + } + char* str = (char*)amf_variant_alloc(sizeof(char)*(sizeAlloc + 1)); + if(m_Str != NULL) + { + size_t copySize = sizeAlloc; + if(copySize > size()) + { + copySize = size(); + } + memcpy(str, m_Str, copySize * sizeof(char)); + Free(); + str[sizeAlloc] = 0; + } + m_Str = str; + } + private: + char* m_Str; + }; + //---------------------------------------------------------------------------------------------- + // helper WString class + //---------------------------------------------------------------------------------------------- + class AMFVariant::WString + { + friend class AMFVariant; + private: + void Free() + { + if (m_Str != NULL) + { + AMFVariantFreeWString(m_Str); + m_Str = NULL; + } + } + public: + WString() :m_Str(NULL){} + WString(const wchar_t* str) : m_Str(NULL) + { + m_Str = AMFVariantDuplicateWString(str); + } + WString(const WString& p_other) : m_Str(NULL) + { + operator=(p_other); + } +#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (_MSC_VER >= 1600) + WString(WString&& p_other) : m_Str(NULL) + { + operator=(p_other); + } +#endif + ~WString() + { + Free(); + } + + WString& operator=(const WString& p_other) + { + Free(); + m_Str = AMFVariantDuplicateWString(p_other.m_Str); + return *this; + } +#if (__cplusplus == 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X) || (_MSC_VER >= 1600) + WString& operator=(WString&& p_other) + { + Free(); + m_Str = p_other.m_Str; + p_other.m_Str = NULL; // Transfer the ownership + return *this; + } +#endif + wchar_t& operator[](size_t index) + { + if (index >= size()) + { + resize(index); + } + return m_Str[index]; + } + + bool operator==(const WString& p_other) const + { + if (m_Str == NULL && p_other.m_Str == NULL) + { + return true; + } + else if ((m_Str == NULL && p_other.m_Str != NULL) || (m_Str != NULL && p_other.m_Str == NULL)) + { + return false; + } + return wcscmp(c_str(), p_other.c_str()) == 0; + } + + const wchar_t* c_str() const { return m_Str; } + size_t size() const + { + if(m_Str == NULL) + { + return 0; + } + return (size_t)wcslen(m_Str); + } + + AMF_INLINE size_t length() const { return size(); } + + void resize(size_t sizeAlloc) + { + if(sizeAlloc == 0) + { + Free(); + return; + } + wchar_t* str = (wchar_t*)amf_variant_alloc(sizeof(wchar_t)*(sizeAlloc + 1)); + if(m_Str != NULL) + { + size_t copySize = sizeAlloc; + if(copySize > size()) + { + copySize = size(); + } + memcpy(str, m_Str, copySize * sizeof(wchar_t)); + Free(); + str[sizeAlloc] = 0; + } + m_Str = str; + } + private: + wchar_t* m_Str; + }; + //------------------------------------------------------------------------------------------------- + AMFVariant::String AMFVariant::ToString() const + { + String temp = GetValue(AMFVariantGetString); + return String(temp.c_str()); + } + //------------------------------------------------------------------------------------------------- + AMFVariant::WString AMFVariant::ToWString() const + { + WString temp = GetValue(AMFVariantGetWString); + return WString(temp.c_str()); + } +#endif // defined(__cplusplus) + //---------------------------------------------------------------------------------------------- + // AMF_INLINE implementation of helper functions + //---------------------------------------------------------------------------------------------- + #define AMF_VARIANT_RETURN_IF_INVALID_POINTER(p) \ + { \ + if(p == NULL) \ + { \ + return AMF_INVALID_POINTER; \ + } \ + } + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantInit(AMFVariantStruct* pVariant) + { + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pVariant); + pVariant->type = AMF_VARIANT_EMPTY; + return AMF_OK; + } + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantClear(AMFVariantStruct* pVariant) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pVariant); + + switch(AMFVariantGetType(pVariant)) + { + case AMF_VARIANT_STRING: + amf_variant_free(AMFVariantString(pVariant)); + pVariant->type = AMF_VARIANT_EMPTY; + break; + + case AMF_VARIANT_WSTRING: + amf_variant_free(AMFVariantWString(pVariant)); + pVariant->type = AMF_VARIANT_EMPTY; + break; + + case AMF_VARIANT_INTERFACE: + if(AMFVariantInterface(pVariant) != NULL) + { +#if defined(__cplusplus) + AMFVariantInterface(pVariant)->Release(); +#else + AMFVariantInterface(pVariant)->pVtbl->Release(AMFVariantInterface(pVariant)); +#endif + AMFVariantInterface(pVariant) = NULL; + } + pVariant->type = AMF_VARIANT_EMPTY; + break; + + default: + pVariant->type = AMF_VARIANT_EMPTY; + break; + } + return errRet; + } + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantCompare(const AMFVariantStruct* pFirst, const AMFVariantStruct* pSecond, amf_bool* bEqual) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pFirst); + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pSecond); + + if(pFirst == pSecond) + { + *bEqual = true; + } + else if(AMFVariantGetType(pFirst) != AMFVariantGetType(pSecond)) + { + *bEqual = false; + } + else + { + switch(AMFVariantGetType(pFirst)) + { + case AMF_VARIANT_EMPTY: + *bEqual = true; + break; + case AMF_VARIANT_BOOL: + *bEqual = AMFVariantGetBool(pFirst) == AMFVariantBool(pSecond); + break; + case AMF_VARIANT_INT64: + *bEqual = AMFVariantGetInt64(pFirst) == AMFVariantInt64(pSecond); + break; + case AMF_VARIANT_DOUBLE: + *bEqual = AMFVariantGetDouble(pFirst) == AMFVariantDouble(pSecond); + break; + case AMF_VARIANT_RECT: +#if defined(__cplusplus) + *bEqual = AMFVariantGetRect(pFirst) == AMFVariantGetRect(pSecond); +#else + *bEqual = memcmp(&pFirst->rectValue, &pSecond->rectValue, sizeof(AMFRect)) == 0; +#endif + break; + case AMF_VARIANT_SIZE: +#if defined(__cplusplus) + *bEqual = AMFVariantGetSize(pFirst) == AMFVariantGetSize(pSecond); +#else + *bEqual = memcmp(&pFirst->sizeValue, &pSecond->sizeValue, sizeof(AMFSize)) == 0; +#endif + break; + case AMF_VARIANT_POINT: +#if defined(__cplusplus) + *bEqual = AMFVariantGetPoint(pFirst) == AMFVariantGetPoint(pSecond); +#else + *bEqual = memcmp(&pFirst->pointValue, &pSecond->pointValue, sizeof(AMFPoint)) == 0; +#endif + break; + case AMF_VARIANT_RATE: +#if defined(__cplusplus) + *bEqual = AMFVariantGetRate(pFirst) == AMFVariantGetRate(pSecond); +#else + *bEqual = memcmp(&pFirst->rateValue, &pSecond->rateValue, sizeof(AMFRate)) == 0; +#endif + break; + case AMF_VARIANT_RATIO: +#if defined(__cplusplus) + *bEqual = AMFVariantGetRatio(pFirst) == AMFVariantGetRatio(pSecond); +#else + *bEqual = memcmp(&pFirst->ratioValue, &pSecond->ratioValue, sizeof(AMFRatio)) == 0; +#endif + break; + case AMF_VARIANT_COLOR: +#if defined(__cplusplus) + *bEqual = AMFVariantGetColor(pFirst) == AMFVariantGetColor(pSecond); +#else + *bEqual = memcmp(&pFirst->colorValue, &pSecond->colorValue, sizeof(AMFColor)) == 0; +#endif + break; + case AMF_VARIANT_STRING: + *bEqual = strcmp(AMFVariantString(pFirst), AMFVariantString(pSecond)) == 0; + break; + case AMF_VARIANT_WSTRING: + *bEqual = wcscmp(AMFVariantWString(pFirst), AMFVariantWString(pSecond)) == 0; + break; + case AMF_VARIANT_INTERFACE: + *bEqual = AMFVariantInterface(pFirst) == AMFVariantInterface(pSecond); + break; + default: + errRet = AMF_INVALID_ARG; + break; + } + } + return errRet; + } + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantCopy(AMFVariantStruct* pDest, const AMFVariantStruct* pSrc) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest); + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pSrc); + if(pDest != pSrc) + { + switch(AMFVariantGetType(pSrc)) + { + case AMF_VARIANT_EMPTY: + errRet = AMFVariantClear(pDest); + break; + case AMF_VARIANT_BOOL: + errRet = AMFVariantAssignBool(pDest, AMFVariantBool(pSrc)); + break; + case AMF_VARIANT_INT64: + errRet = AMFVariantAssignInt64(pDest, AMFVariantInt64(pSrc)); + break; + case AMF_VARIANT_DOUBLE: + errRet = AMFVariantAssignDouble(pDest, AMFVariantDouble(pSrc)); + break; + case AMF_VARIANT_RECT: + errRet = AMFVariantAssignRect(pDest, &pSrc->rectValue); + break; + case AMF_VARIANT_SIZE: + errRet = AMFVariantAssignSize(pDest, &pSrc->sizeValue); + break; + case AMF_VARIANT_POINT: + errRet = AMFVariantAssignPoint(pDest, &pSrc->pointValue); + break; + case AMF_VARIANT_RATE: + errRet = AMFVariantAssignRate(pDest, &pSrc->rateValue); + break; + case AMF_VARIANT_RATIO: + errRet = AMFVariantAssignRatio(pDest, &pSrc->ratioValue); + break; + case AMF_VARIANT_COLOR: + errRet = AMFVariantAssignColor(pDest, &pSrc->colorValue); + break; + case AMF_VARIANT_STRING: + errRet = AMFVariantAssignString(pDest, AMFVariantString(pSrc)); + break; + case AMF_VARIANT_WSTRING: + errRet = AMFVariantAssignWString(pDest, AMFVariantWString(pSrc)); + break; + case AMF_VARIANT_INTERFACE: + errRet = AMFVariantAssignInterface(pDest, AMFVariantInterface(pSrc)); + break; + default: + errRet = AMF_INVALID_ARG; + break; + } + } + return errRet; + } + #define AMFVariantTypeEmpty AMF_VARIANT_EMPTY + + #define AMFVariantTypeBool AMF_VARIANT_BOOL + #define AMFVariantTypeInt64 AMF_VARIANT_INT64 + #define AMFVariantTypeDouble AMF_VARIANT_DOUBLE + + #define AMFVariantTypeRect AMF_VARIANT_RECT + #define AMFVariantTypeSize AMF_VARIANT_SIZE + #define AMFVariantTypePoint AMF_VARIANT_POINT + #define AMFVariantTypeRate AMF_VARIANT_RATE + #define AMFVariantTypeRatio AMF_VARIANT_RATIO + #define AMFVariantTypeColor AMF_VARIANT_COLOR + + #define AMFVariantTypeString AMF_VARIANT_STRING + #define AMFVariantTypeWString AMF_VARIANT_WSTRING + #define AMFVariantTypeInterface AMF_VARIANT_INTERFACE + +#if defined(__cplusplus) + + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignString(AMFVariantStruct* pDest, const AMFVariant::String& value) + { + return AMFVariantAssignString(pDest, value.c_str()); + } + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignWString(AMFVariantStruct* pDest, const AMFVariant::WString& value) + { + return AMFVariantAssignWString(pDest, value.c_str()); + } + + static AMF_INLINE amf_bool AMFConvertEmptyToBool(void*, AMF_RESULT& res) { res = AMF_OK; return false; } + static AMF_INLINE amf_int64 AMFConvertEmptyToInt64(void*, AMF_RESULT& res) {res = AMF_OK; return 0; } + static AMF_INLINE amf_double AMFConvertEmptyToDouble(void*, AMF_RESULT& res) {res = AMF_OK; return 0; } + + + static AMF_INLINE AMFVariant::String AMFConvertEmptyToString(void*, AMF_RESULT& res) {res = AMF_OK; return ""; } + static AMF_INLINE AMFVariant::WString AMFConvertEmptyToWString(void*, AMF_RESULT& res) {res = AMF_OK; return L""; } + static AMF_INLINE amf_int64 AMFConvertBoolToInt64(bool value, AMF_RESULT& res){res = AMF_OK; return value ? 1 : 0;} + static AMF_INLINE amf_double AMFConvertBoolToDouble(bool value, AMF_RESULT& res){res = AMF_OK; return value ? 1 : 0;} + static AMF_INLINE AMFVariant::String AMFConvertBoolToString(bool value, AMF_RESULT& res){res = AMF_OK; return value ? "true" : "false";} + static AMF_INLINE AMFVariant::WString AMFConvertBoolToWString(bool value, AMF_RESULT& res){res = AMF_OK; return value ? L"true" : L"false";} + static AMF_INLINE bool AMFConvertInt64ToBool(amf_int64 value, AMF_RESULT& res){res = AMF_OK;return value != 0;} + static AMF_INLINE amf_double AMFConvertInt64ToDouble(amf_int64 value, AMF_RESULT& res){res = AMF_OK;return (amf_double)value;} + static AMF_INLINE AMFVariant::String AMFConvertInt64ToString(amf_int64 value, AMF_RESULT& res) + { + res = AMF_OK; + char buff[0xFF]; + sprintf(buff, "%" AMFPRId64, (long long)value); + return buff; + } + static AMF_INLINE AMFVariant::WString AMFConvertInt64ToWString(amf_int64 value, AMF_RESULT& res) + { + res = AMF_OK; + wchar_t buff[0xFF]; + swprintf(buff, 0xFF, L"%" LPRId64, (long long)value); + return buff; + } + + static AMF_INLINE bool AMFConvertDoubleToBool(amf_double value, AMF_RESULT& res){res = AMF_OK;return value != 0;} + static AMF_INLINE amf_int64 AMFConvertDoubleToInt64(amf_double value, AMF_RESULT& res){res = AMF_OK;return amf_int64(value);} + static AMF_INLINE AMFVariant::String AMFConvertDoubleToString(amf_double value, AMF_RESULT& res) + { + res = AMF_OK; + char buff[0xFF]; + sprintf(buff, "%lf", value); + return buff; + } + static AMF_INLINE AMFVariant::WString AMFConvertDoubleToWString(amf_double value, AMF_RESULT& res) + { + res = AMF_OK; + wchar_t buff[0xFF]; + swprintf(buff, 0xFF, L"%lf", value); + return buff; + } + + static AMF_INLINE bool AMFConvertStringToBool(const AMFVariant::String& value, AMF_RESULT& res) + { + res = AMF_OK; + AMFVariant::String tmp = value; + if(( tmp == "true") || ( tmp == "True") || ( tmp == "TRUE") || ( tmp == "1") ) + { + return true; + } + else + { + if(( tmp == "false") || ( tmp == "False") || ( tmp == "FALSE") || ( tmp == "0") ) + { + return false; + } + } + res = AMF_INVALID_ARG; + return false; + } + + static AMF_INLINE amf_int64 AMFConvertStringToInt64(const AMFVariant::String& value, AMF_RESULT& res) + { + res = AMF_OK; + long long tmp = 0; + int readElements = 0; + + if(value.size() > 2 && ( value.c_str()[0] == '0') && ( value.c_str()[1] == 'x') ) + { + readElements = sscanf(value.c_str(), "0x%" AMFPRIx64, &tmp); + } + else if(value.size() > 0) + { + readElements = sscanf(value.c_str(), "%" AMFPRId64, &tmp); + } + if(readElements) + { + return tmp; + } + res = AMF_INVALID_ARG; + return 0; + } + + static AMF_INLINE amf_double AMFConvertStringToDouble(const AMFVariant::String& value, AMF_RESULT& res) + { + res = AMF_OK; + amf_double tmp = 0; + int readElements = 0; + if(value.size() > 0) + { + readElements = sscanf(value.c_str(), "%lf", &tmp); + } + if(readElements) + { + return tmp; + } + res = AMF_INVALID_ARG; + return 0; + } + + static AMF_INLINE AMFVariant::WString AMFConvertStringToWString(const AMFVariant::String& value, AMF_RESULT& res) + { + res = AMF_OK; +// return amf_from_utf8_to_unicode(value); + AMFVariant::WString result; + if(0 == value.size()) + { + return result; + } + const char* pUtf8Buff = value.c_str(); + +#if defined(_WIN32) + _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); + int UnicodeBuffSize = ::MultiByteToWideChar(CP_UTF8, 0, pUtf8Buff, -1, NULL, 0); + if(0 == UnicodeBuffSize) + { + return result; + } + UnicodeBuffSize += 8; // get some extra space + result.resize(UnicodeBuffSize); + UnicodeBuffSize = ::MultiByteToWideChar(CP_UTF8, 0, pUtf8Buff, -1, (LPWSTR)result.c_str(), UnicodeBuffSize); + UnicodeBuffSize--; + +#elif defined(__ANDROID__) + // on android mbstowcs cannot be used to define length + char* old_locale = setlocale(LC_CTYPE, "en_US.UTF8"); + + mbstate_t mbs; + mbrlen(NULL, 0, &mbs); + int len = value.size(); + const char* pt = pUtf8Buff; + int UnicodeBuffSize = 0; + while(len > 0) + { + size_t length = mbrlen (pt, len, &mbs); //MM TODO Android always return 1 + if((length == 0) || (length > len)) + { + break; + } + UnicodeBuffSize++; + len -= length; + pt += length; + } + UnicodeBuffSize += 8; // get some extra space + result.resize(UnicodeBuffSize); + + mbrlen (NULL, 0, &mbs); + len = value.size(); + pt = pUtf8Buff; + UnicodeBuffSize = 0; + while(len > 0) + { + size_t length = mbrlen (pt, len, &mbs); + if((length == 0) || (length > len)) + { + break; + } + mbrtowc(&((wchar_t*)(result.c_str()))[UnicodeBuffSize], pt, length, &mbs); //MM TODO Android always return 1 char + UnicodeBuffSize++; + len -= length; + pt += length; + } + setlocale(LC_CTYPE, old_locale); + + #else + char* old_locale = setlocale(LC_CTYPE, "en_US.UTF8"); + int UnicodeBuffSize = mbstowcs(NULL, pUtf8Buff, 0); + if(0 == UnicodeBuffSize) + { + return result; + } + UnicodeBuffSize += 8; // get some extra space + result.resize(UnicodeBuffSize); + UnicodeBuffSize = mbstowcs((wchar_t*)result.c_str(), pUtf8Buff, UnicodeBuffSize + 1); + setlocale(LC_CTYPE, old_locale); +#endif + result.resize(UnicodeBuffSize); + return result; + } + static AMF_INLINE AMFVariant::String AMFConvertWStringToString(const AMFVariant::WString& value, AMF_RESULT& res) + { + res = AMF_OK; +// return amf_from_unicode_to_utf8(value); + AMFVariant::String result; + if(0 == value.size()) + { + return result; + } + + const wchar_t* pwBuff = value.c_str(); + +#if defined(_WIN32) + _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); + int Utf8BuffSize = ::WideCharToMultiByte(CP_UTF8, 0, pwBuff, -1, NULL, 0, NULL, NULL); + if(0 == Utf8BuffSize) + { + return result; + } + Utf8BuffSize += 8; // get some extra space + result.resize(Utf8BuffSize); + Utf8BuffSize = ::WideCharToMultiByte(CP_UTF8, 0, pwBuff, -1, (LPSTR)result.c_str(), Utf8BuffSize, NULL, NULL); + Utf8BuffSize--; +#elif defined(__ANDROID__) + char* old_locale = setlocale(LC_CTYPE, "en_US.UTF8"); + int Utf8BuffSize = value.length(); + if(0 == Utf8BuffSize) + { + return result; + } + Utf8BuffSize += 8; // get some extra space + result.resize(Utf8BuffSize); + + mbstate_t mbs; + mbrlen(NULL, 0, &mbs); + + Utf8BuffSize = 0; + for( int i = 0; i < value.length(); i++) + { + //MM TODO Android - not implemented + //int written = wcrtomb(&result[Utf8BuffSize], pwBuff[i], &mbs); + ((char*)(result.c_str()))[Utf8BuffSize] = (char)(pwBuff[i]); + int written = 1; + // temp replacement + Utf8BuffSize += written; + } + setlocale(LC_CTYPE, old_locale); + +#else + char* old_locale = setlocale(LC_CTYPE, "en_US.UTF8"); + int Utf8BuffSize = wcstombs(NULL, pwBuff, 0); + if(0 == Utf8BuffSize) + { + return result; + } + Utf8BuffSize += 8; // get some extra space + result.resize(Utf8BuffSize); + Utf8BuffSize = wcstombs((char*)result.c_str(), pwBuff, Utf8BuffSize + 1); + + setlocale(LC_CTYPE, old_locale); +#endif + result.resize(Utf8BuffSize); + return result; + } + + + static AMF_INLINE bool AMFConvertWStringToBool(const AMFVariant::WString& value, AMF_RESULT& res) + { + return AMFConvertStringToBool(AMFConvertWStringToString(value, res), res); + } + static AMF_INLINE amf_int64 AMFConvertWStringToInt64(const AMFVariant::WString& value, AMF_RESULT& res) + { + return AMFConvertStringToInt64(AMFConvertWStringToString(value, res), res); + } + static AMF_INLINE amf_double AMFConvertWStringToDouble(const AMFVariant::WString& value, AMF_RESULT& res) + { + return AMFConvertStringToDouble(AMFConvertWStringToString(value, res), res); + } + + static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertRectToString(const AMFRect& value, AMF_RESULT& res) + { + res = AMF_OK; + char buff[0xFF]; + sprintf(buff, "%d,%d,%d,%d", value.left, value.top, value.right, value.bottom); + return buff; + } + static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertSizeToString(const AMFSize& value, AMF_RESULT& res) + { + res = AMF_OK; + char buff[0xFF]; + sprintf(buff, "%d,%d", value.width, value.height); + return buff; + } + static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertPointToString(const AMFPoint& value, AMF_RESULT& res) + { + res = AMF_OK; + char buff[0xFF]; + sprintf(buff, "%d,%d", value.x, value.y); + return buff; + } + static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertRateToString(const AMFRate& value, AMF_RESULT& res) + { + res = AMF_OK; + char buff[0xFF]; + sprintf(buff, "%d,%d", value.num, value.den); + return buff; + } + static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertRatioToString(const AMFRatio& value, AMF_RESULT& res) + { + res = AMF_OK; + char buff[0xFF]; + sprintf(buff, "%d,%d", value.num, value.den); + return buff; + } + static AMF_INLINE AMFVariant::String AMF_STD_CALL AMFConvertColorToString(const AMFColor& value, AMF_RESULT& res) + { + res = AMF_OK; + char buff[0xFF]; + sprintf(buff, "%d,%d,%d,%d", value.r, value.g, value.b, value.a); + return buff; + } + + static AMF_INLINE AMFRect AMF_STD_CALL AMFConvertStringToRect(const AMFVariant::String& value, AMF_RESULT& res) + { + res = AMF_OK; + AMFRect tmp = {}; + int readElements = 0; + if(value.size() > 0) + { + readElements = sscanf(value.c_str(), "%d,%d,%d,%d", &tmp.left, &tmp.top, &tmp.right, &tmp.bottom); + } + if(readElements) + { + return tmp; + } + res = AMF_INVALID_ARG; + return tmp; + } + + static AMF_INLINE AMFSize AMF_STD_CALL AMFConvertStringToSize(const AMFVariant::String& value, AMF_RESULT& res) + { + res = AMF_OK; + AMFSize tmp = {}; + int readElements = 0; + if(value.size() > 0) + { + readElements = sscanf(value.c_str(), "%d,%d", &tmp.width, &tmp.height); + } + if(readElements) + { + return tmp; + } + res = AMF_INVALID_ARG; + return tmp; + } + static AMF_INLINE AMFPoint AMF_STD_CALL AMFConvertStringToPoint(const AMFVariant::String& value, AMF_RESULT& res) + { + res = AMF_OK; + AMFPoint tmp = {}; + int readElements = 0; + if(value.size() > 0) + { + readElements = sscanf(value.c_str(), "%d,%d", &tmp.x, &tmp.y); + } + if(readElements) + { + return tmp; + } + res = AMF_INVALID_ARG; + return tmp; + } + static AMF_INLINE AMFRate AMF_STD_CALL AMFConvertStringToRate(const AMFVariant::String& value, AMF_RESULT& res) + { + res = AMF_OK; + AMFRate tmp = {}; + int readElements = 0; + if(value.size() > 0) + { + readElements = sscanf(value.c_str(), "%d,%d", &tmp.num, &tmp.den); + } + if(readElements) + { + return tmp; + } + res = AMF_INVALID_ARG; + return tmp; + } + static AMF_INLINE AMFRatio AMF_STD_CALL AMFConvertStringToRatio(const AMFVariant::String& value, AMF_RESULT& res) + { + res = AMF_OK; + AMFRatio tmp = {}; + int readElements = 0; + if(value.size() > 0) + { + readElements = sscanf(value.c_str(), "%d,%d", &tmp.num, &tmp.den); + } + if(readElements) + { + return tmp; + } + res = AMF_INVALID_ARG; + return tmp; + } + static AMF_INLINE AMFColor AMF_STD_CALL AMFConvertStringToColor(const AMFVariant::String& value, AMF_RESULT& res) + { + res = AMF_OK; + int readElements = 0; + amf_uint32 r = 0; + amf_uint32 g = 0; + amf_uint32 b = 0; + amf_uint32 a = 0; + if(value.size() > 0) + { + readElements = sscanf(value.c_str(), "%u,%u,%u,%u", &r, &g, &b, &a); + } + if(readElements) + { + return AMFConstructColor((amf_uint8)r, (amf_uint8)g, (amf_uint8)b, (amf_uint8)a); + } + res = AMF_INVALID_ARG; + return AMFConstructColor(0, 0, 0, 255); + } +/////////////////////// + static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertRectToWString(const AMFRect& value, AMF_RESULT& res) + { + return AMFConvertStringToWString(AMFConvertRectToString(value, res), res); + } + static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertSizeToWString(const AMFSize& value, AMF_RESULT& res) + { + return AMFConvertStringToWString(AMFConvertSizeToString(value, res), res); + } + static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertPointToWString(const AMFPoint& value, AMF_RESULT& res) + { + return AMFConvertStringToWString(AMFConvertPointToString(value, res), res); + } + static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertRateToWString(const AMFRate& value, AMF_RESULT& res) + { + return AMFConvertStringToWString(AMFConvertRateToString(value, res), res); + } + static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertRatioToWString(const AMFRatio& value, AMF_RESULT& res) + { + return AMFConvertStringToWString(AMFConvertRatioToString(value, res), res); + } + static AMF_INLINE AMFVariant::WString AMF_STD_CALL AMFConvertColorToWString(const AMFColor& value, AMF_RESULT& res) + { + return AMFConvertStringToWString(AMFConvertColorToString(value, res), res); + } + + static AMF_INLINE AMFRect AMF_STD_CALL AMFConvertWStringToRect(const AMFVariant::WString& value, AMF_RESULT& res) + { + return AMFConvertStringToRect(AMFConvertWStringToString(value, res), res); + } + + static AMF_INLINE AMFSize AMF_STD_CALL AMFConvertWStringToSize(const AMFVariant::WString& value, AMF_RESULT& res) + { + return AMFConvertStringToSize(AMFConvertWStringToString(value, res), res); + } + static AMF_INLINE AMFPoint AMF_STD_CALL AMFConvertWStringToPoint(const AMFVariant::WString& value, AMF_RESULT& res) + { + return AMFConvertStringToPoint(AMFConvertWStringToString(value, res), res); + } + static AMF_INLINE AMFRate AMF_STD_CALL AMFConvertWStringToRate(const AMFVariant::WString& value, AMF_RESULT& res) + { + return AMFConvertStringToRate(AMFConvertWStringToString(value, res), res); + } + static AMF_INLINE AMFRatio AMF_STD_CALL AMFConvertWStringToRatio(const AMFVariant::WString& value, AMF_RESULT& res) + { + return AMFConvertStringToRatio(AMFConvertWStringToString(value, res), res); + } + static AMF_INLINE AMFColor AMF_STD_CALL AMFConvertWStringToColor(const AMFVariant::WString& value, AMF_RESULT& res) + { + return AMFConvertStringToColor(AMFConvertWStringToString(value, res), res); + } + + //------------------------------------------------------------------------------------------------- + #define AMFConvertTool(srcType, dstType)\ + if(AMFVariantGetType(pSrc) == AMFVariantType##srcType && newType == AMFVariantType##dstType)\ + {\ + AMF_RESULT res = AMF_OK;\ + AMFVariantAssign##dstType(pDest, AMFConvert##srcType##To##dstType(AMFVariant##srcType(pSrc), res));\ + return res;\ + }\ + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantChangeType(AMFVariantStruct* pDest, const AMFVariantStruct* pSrc, AMF_VARIANT_TYPE newType) + { + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest); + + if(pSrc == 0) + { + pSrc = pDest; + } + + if(AMFVariantGetType(pSrc) == newType) + { + if(pDest == pSrc) + { + return AMF_OK; + } + return AMFVariantCopy(pDest, pSrc); + } + AMFVariantClear(pDest); + + AMFConvertTool(Empty, Bool); + AMFConvertTool(Empty, Int64); + AMFConvertTool(Empty, Double); + AMFConvertTool(Empty, String); + AMFConvertTool(Empty, WString); + + AMFConvertTool(Bool, Int64); + AMFConvertTool(Bool, Double); + AMFConvertTool(Bool, String); + AMFConvertTool(Bool, WString); + + AMFConvertTool(Int64, Bool); + AMFConvertTool(Int64, Double); + AMFConvertTool(Int64, String); + AMFConvertTool(Int64, WString); + + AMFConvertTool(Double, Bool); + AMFConvertTool(Double, Int64); + AMFConvertTool(Double, String); + AMFConvertTool(Double, String); + + AMFConvertTool(String, Bool); + AMFConvertTool(String, Int64); + AMFConvertTool(String, Double); + AMFConvertTool(String, WString); + + AMFConvertTool(WString, Bool); + AMFConvertTool(WString, Int64); + AMFConvertTool(WString, Double); + AMFConvertTool(WString, String); + + AMFConvertTool(String, Rect); + AMFConvertTool(String, Size); + AMFConvertTool(String, Point); + AMFConvertTool(String, Rate); + AMFConvertTool(String, Ratio); + AMFConvertTool(String, Color); + + AMFConvertTool(Rect , String); + AMFConvertTool(Size , String); + AMFConvertTool(Point, String); + AMFConvertTool(Rate , String); + AMFConvertTool(Ratio, String); + AMFConvertTool(Color, String); + + AMFConvertTool(WString, Rect); + AMFConvertTool(WString, Size); + AMFConvertTool(WString, Point); + AMFConvertTool(WString, Rate); + AMFConvertTool(WString, Ratio); + AMFConvertTool(WString, Color); + + AMFConvertTool(Rect , WString); + AMFConvertTool(Size , WString); + AMFConvertTool(Point, WString); + AMFConvertTool(Rate , WString); + AMFConvertTool(Ratio, WString); + AMFConvertTool(Color, WString); + + return AMF_INVALID_ARG; + } +#endif // #if defined(__cplusplus) + + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignBool(AMFVariantStruct* pDest, amf_bool value) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest); + + errRet = AMFVariantClear(pDest); + if(errRet == AMF_OK) + { + pDest->type = AMF_VARIANT_BOOL; + AMFVariantBool(pDest) = value; + } + return errRet; + } + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignInt64(AMFVariantStruct* pDest, amf_int64 value) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest); + + errRet = AMFVariantClear(pDest); + if(errRet == AMF_OK) + { + pDest->type = AMF_VARIANT_INT64; + AMFVariantInt64(pDest) = value; + } + return errRet; + } + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignDouble(AMFVariantStruct* pDest, amf_double value) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest); + + errRet = AMFVariantClear(pDest); + if(errRet == AMF_OK) + { + pDest->type = AMF_VARIANT_DOUBLE; + AMFVariantDouble(pDest) = value; + } + return errRet; + } + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignString(AMFVariantStruct* pDest, const char* pValue) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest); + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pValue); + + errRet = AMFVariantClear(pDest); + if(errRet == AMF_OK) + { + size_t size = (strlen(pValue) + 1); + pDest->type = AMF_VARIANT_STRING; + AMFVariantString(pDest) = (char*)amf_variant_alloc(size * sizeof(char)); + if(AMFVariantString(pDest)) + { + strncpy(AMFVariantString(pDest), pValue, size); + } + else + { + errRet = AMF_OUT_OF_MEMORY; + } + } + return errRet; + } + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignWString(AMFVariantStruct* pDest, const wchar_t* pValue) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest); + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pValue); + + errRet = AMFVariantClear(pDest); + if(errRet == AMF_OK) + { + size_t size = (wcslen(pValue) + 1); + pDest->type = AMF_VARIANT_WSTRING; + AMFVariantWString(pDest) = (wchar_t*)amf_variant_alloc(size * sizeof(wchar_t)); + if(AMFVariantWString(pDest)) + { + wcsncpy(AMFVariantWString(pDest), pValue, size); + } + else + { + errRet = AMF_OUT_OF_MEMORY; + } + } + return errRet; + } + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignInterface(AMFVariantStruct* pDest, AMFInterface* pValue) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest); + //AMF_VARIANT_RETURN_IF_INVALID_POINTER(pValue);//can be NULL + + errRet = AMFVariantClear(pDest); + if(errRet == AMF_OK) + { + pDest->type = AMF_VARIANT_INTERFACE; + AMFVariantInterface(pDest) = pValue; + if(AMFVariantInterface(pDest)) + { +#if defined(__cplusplus) + AMFVariantInterface(pDest)->Acquire(); +#else + AMFVariantInterface(pDest)->pVtbl->Acquire(AMFVariantInterface(pDest)); +#endif + + } + } + return errRet; + } + //------------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRect(AMFVariantStruct* pDest, const AMFRect& value) + { + return AMFVariantAssignRect(pDest, &value); + } +#endif + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRect (AMFVariantStruct* pDest, const AMFRect* value) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest); + + errRet = AMFVariantClear(pDest); + if(errRet == AMF_OK) + { + pDest->type = AMF_VARIANT_RECT; + AMFVariantRect(pDest) = *value; + } + return errRet; + } + //------------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignSize (AMFVariantStruct* pDest, const AMFSize& value) + { + return AMFVariantAssignSize (pDest, &value); + } +#endif + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignSize (AMFVariantStruct* pDest, const AMFSize* value) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest); + + errRet = AMFVariantClear(pDest); + if(errRet == AMF_OK) + { + pDest->type = AMF_VARIANT_SIZE; + AMFVariantSize(pDest) = *value; + } + return errRet; + } + //------------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignPoint(AMFVariantStruct* pDest, const AMFPoint& value) + { + return AMFVariantAssignPoint(pDest, &value); + } +#endif + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignPoint(AMFVariantStruct* pDest, const AMFPoint* value) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest); + + errRet = AMFVariantClear(pDest); + if(errRet == AMF_OK) + { + pDest->type = AMF_VARIANT_POINT; + AMFVariantPoint(pDest) = *value; + } + return errRet; + } + //------------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRate (AMFVariantStruct* pDest, const AMFRate& value) + { + return AMFVariantAssignRate (pDest, &value); + } +#endif + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRate (AMFVariantStruct* pDest, const AMFRate* value) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest); + + errRet = AMFVariantClear(pDest); + if(errRet == AMF_OK) + { + pDest->type = AMF_VARIANT_RATE; + AMFVariantRate(pDest) = *value; + } + return errRet; + } + //------------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRatio(AMFVariantStruct* pDest, const AMFRatio& value) + { + return AMFVariantAssignRatio(pDest, &value); + } +#endif + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignRatio(AMFVariantStruct* pDest, const AMFRatio* value) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest); + + errRet = AMFVariantClear(pDest); + if(errRet == AMF_OK) + { + pDest->type = AMF_VARIANT_RATIO; + AMFVariantRatio(pDest) = *value; + } + return errRet; + } + //------------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignColor(AMFVariantStruct* pDest, const AMFColor& value) + { + return AMFVariantAssignColor(pDest, &value); + } +#endif + //------------------------------------------------------------------------------------------------- + static AMF_INLINE AMF_RESULT AMF_CDECL_CALL AMFVariantAssignColor(AMFVariantStruct* pDest, const AMFColor* value) + { + AMF_RESULT errRet = AMF_OK; + AMF_VARIANT_RETURN_IF_INVALID_POINTER(pDest); + + errRet = AMFVariantClear(pDest); + if(errRet == AMF_OK) + { + pDest->type = AMF_VARIANT_COLOR; + AMFVariantColor(pDest) = *value; + } + return errRet; + } + //------------------------------------------------------------------------------------------------- + static AMF_INLINE char* AMF_CDECL_CALL AMFVariantDuplicateString(const char* from) + { + char* ret = 0; + if(from) + { + ret = (char*)amf_variant_alloc(sizeof(char)*(strlen(from) + 1)); + if(ret) + { + strcpy(ret, from); + } + } + return ret; + } + //------------------------------------------------------------------------------------------------- + static AMF_INLINE void AMF_CDECL_CALL AMFVariantFreeString(char* from) + { + amf_variant_free(from); + } + //------------------------------------------------------------------------------------------------- + static AMF_INLINE wchar_t* AMF_CDECL_CALL AMFVariantDuplicateWString(const wchar_t* from) + { + wchar_t* ret = 0; + if(from) + { + ret = (wchar_t*)amf_variant_alloc(sizeof(wchar_t)*(wcslen(from) + 1)); + if(ret) + { + wcscpy(ret, from); + } + } + return ret; + } + //------------------------------------------------------------------------------------------------- + static AMF_INLINE void AMF_CDECL_CALL AMFVariantFreeWString(wchar_t* from) + { + amf_variant_free(from); + } + //---------------------------------------------------------------------------------------------- + // AMF_INLINE implementation of AMFVariant class + //---------------------------------------------------------------------------------------------- +#if defined(__cplusplus) + AMF_INLINE AMFVariant::AMFVariant(const AMFVariantStruct* pOther) + { + AMFVariantInit(this); + if(pOther != NULL) + { + AMFVariantCopy(this, const_cast(pOther)); + } + } + //------------------------------------------------------------------------------------------------- + template + AMFVariant::AMFVariant(const AMFInterfacePtr_T& pValue) + { + AMFVariantInit(this); + AMFVariantAssignInterface(this, pValue); + } + //------------------------------------------------------------------------------------------------- + template + ReturnType AMFVariant::GetValue(Getter getter) const + { + ReturnType str = ReturnType(); + if(AMFVariantGetType(this) == variantType) + { + str = static_cast(getter(this)); + } + else + { + AMFVariant varDest; + varDest.ChangeType(variantType, this); + if(varDest.type != AMF_VARIANT_EMPTY) + { + str = static_cast(getter(&varDest)); + } + } + return str; + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE AMFVariant& AMFVariant::operator=(const AMFVariantStruct& other) + { + AMFVariantCopy(this, const_cast(&other)); + return *this; + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE AMFVariant& AMFVariant::operator=(const AMFVariantStruct* pOther) + { + if(pOther != NULL) + { + AMFVariantCopy(this, const_cast(pOther)); + } + return *this; + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE AMFVariant& AMFVariant::operator=(const AMFVariant& other) + { + AMFVariantCopy(this, + const_cast(static_cast(&other))); + return *this; + } + //------------------------------------------------------------------------------------------------- + template + AMFVariant& AMFVariant::operator=(const AMFInterfacePtr_T& value) + { + AMFVariantAssignInterface(this, value); + return *this; + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE bool AMFVariant::operator==(const AMFVariantStruct& other) const + { + return *this == &other; + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE bool AMFVariant::operator==(const AMFVariantStruct* pOther) const + { + //TODO: double check + amf_bool ret = false; + if(pOther == NULL) + { + ret = false; + } + else + { + AMFVariantCompare(this, pOther, &ret); + } + return ret; + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE bool AMFVariant::operator!=(const AMFVariantStruct& other) const + { + return !(*this == &other); + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE bool AMFVariant::operator!=(const AMFVariantStruct* pOther) const + { + return !(*this == pOther); + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE void AMFVariant::Attach(AMFVariantStruct& variant) + { + Clear(); + memcpy(this, &variant, sizeof(variant)); + AMFVariantGetType(&variant) = AMF_VARIANT_EMPTY; + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE AMFVariantStruct AMFVariant::Detach() + { + AMFVariantStruct varResult = *this; + AMFVariantGetType(this) = AMF_VARIANT_EMPTY; + return varResult; + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE AMFVariantStruct& AMFVariant::GetVariant() + { + return *static_cast(this); + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE void AMFVariant::ChangeType(AMF_VARIANT_TYPE newType, const AMFVariant* pSrc) + { + AMFVariantChangeType(this, pSrc, newType); + } + //------------------------------------------------------------------------------------------------- + AMF_INLINE bool AMFVariant::Empty() const + { + return type == AMF_VARIANT_EMPTY; + } + //------------------------------------------------------------------------------------------------- +#endif // #if defined(__cplusplus) + +#if defined(__cplusplus) +} //namespace amf +#endif + +#endif //#ifndef AMF_Variant_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Version.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Version.h new file mode 100644 index 000000000000..9177566ebe56 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/Version.h @@ -0,0 +1,59 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/** +*************************************************************************************************** +* @file Version.h +* @brief Version declaration +*************************************************************************************************** +*/ +#ifndef AMF_Version_h +#define AMF_Version_h +#pragma once + +#include "Platform.h" + +#define AMF_MAKE_FULL_VERSION(VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE, VERSION_BUILD_NUM) ( ((amf_uint64)(VERSION_MAJOR) << 48ull) | ((amf_uint64)(VERSION_MINOR) << 32ull) | ((amf_uint64)(VERSION_RELEASE) << 16ull) | (amf_uint64)(VERSION_BUILD_NUM)) + +#define AMF_GET_MAJOR_VERSION(x) ((x >> 48ull) & 0xFFFF) +#define AMF_GET_MINOR_VERSION(x) ((x >> 32ull) & 0xFFFF) +#define AMF_GET_SUBMINOR_VERSION(x) ((x >> 16ull) & 0xFFFF) +#define AMF_GET_BUILD_VERSION(x) ((x >> 0ull) & 0xFFFF) + +#define AMF_VERSION_MAJOR 1 +#define AMF_VERSION_MINOR 4 +#define AMF_VERSION_RELEASE 9 +#define AMF_VERSION_BUILD_NUM 0 + +#define AMF_FULL_VERSION AMF_MAKE_FULL_VERSION(AMF_VERSION_MAJOR, AMF_VERSION_MINOR, AMF_VERSION_RELEASE, AMF_VERSION_BUILD_NUM) + +#endif //#ifndef AMF_Version_h diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/VulkanAMF.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/VulkanAMF.h new file mode 100644 index 000000000000..3b053e60661c --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmf/core/VulkanAMF.h @@ -0,0 +1,113 @@ +// +// Notice Regarding Standards. AMD does not provide a license or sublicense to +// any Intellectual Property Rights relating to any standards, including but not +// limited to any audio and/or video codec technologies such as MPEG-2, MPEG-4; +// AVC/H.264; HEVC/H.265; AAC decode/FFMPEG; AAC encode/FFMPEG; VC-1; and MP3 +// (collectively, the "Media Technologies"). For clarity, you will pay any +// royalties due for such third party technologies, which may include the Media +// Technologies that are owed as a result of AMD providing the Software to you. +// +// MIT license +// +// Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#ifndef __VulkanAMF_h__ +#define __VulkanAMF_h__ +#pragma once +#include "Platform.h" +#ifdef _WIN32 + #define VK_USE_PLATFORM_WIN32_KHR +#elif defined(__linux) + #define VK_USE_PLATFORM_XLIB_KHR +#endif + +#include "vulkan/vulkan.h" + +#if defined(__cplusplus) +namespace amf +{ +#endif + typedef struct AMFVulkanDevice + { + amf_size cbSizeof; // sizeof(AMFVulkanDevice) + void* pNext; // reserved for extensions + VkInstance hInstance; + VkPhysicalDevice hPhysicalDevice; + VkDevice hDevice; + } AMFVulkanDevice; + + typedef struct AMFVulkanSync + { + amf_size cbSizeof; // sizeof(AMFVulkanSemaphore) + void* pNext; // reserved for extensions + VkSemaphore hSemaphore; + bool bSubmitted; // if true - wait for hSemaphore. re-submit hSemaphore if not synced by other ways and set to true + VkFence hFence; // To sync on CPU; can be nullptr. Submitted in vkQueueSubmit. If waited for hFence, null it, do not delete or reset. + } AMFVulkanSync; + + typedef struct AMFVulkanBuffer + { + amf_size cbSizeof; // sizeof(AMFVulkanBuffer) + void* pNext; // reserved for extensions + VkBuffer hBuffer; + VkDeviceMemory hMemory; + amf_int64 iSize; + amf_int64 iAllocatedSize; // for reuse + amf_uint32 eAccessFlags; // VkAccessFlagBits + amf_uint32 eUsage; // AMF_BUFFER_USAGE + amf_uint32 eAccess; // AMF_MEMORY_CPU_ACCESS + AMFVulkanSync Sync; + } AMFVulkanBuffer; + + typedef struct AMFVulkanSurface + { + amf_size cbSizeof; // sizeof(AMFVulkanSurface) + void* pNext; // reserved for extensions + // surface properties + VkImage hImage; + VkDeviceMemory hMemory; + amf_int64 iSize; // memory size + amf_uint32 eFormat; // VkFormat + amf_int32 iWidth; + amf_int32 iHeight; + amf_uint32 eCurrentLayout; // VkImageLayout + amf_uint32 eUsage; // AMF_SURFACE_USAGE + amf_uint32 eAccess; // AMF_MEMORY_CPU_ACCESS + AMFVulkanSync Sync; // To sync on GPU + } AMFVulkanSurface; + + typedef struct AMFVulkanView + { + amf_size cbSizeof; // sizeof(AMFVulkanSurface) + void* pNext; // reserved for extensions + // surface properties + AMFVulkanSurface *pSurface; + VkImageView hView; + amf_int32 iPlaneWidth; + amf_int32 iPlaneHeight; + amf_int32 iPlaneWidthPitch; + amf_int32 iPlaneHeightPitch; + } AMFVulkanView; +#if defined(__cplusplus) +} // namespace amf +#endif +#endif // __VulkanAMF_h__ \ No newline at end of file diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmfPrivate.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmfPrivate.h new file mode 100644 index 000000000000..321abf19587b --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmfPrivate.h @@ -0,0 +1,79 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "GameplayMediaEncoderCommon.h" + +// AMF includes Windows headers which triggers redefinition warnings +// include UE4 Windows definition before that +#include "Windows/WindowsHWrapper.h" + +THIRD_PARTY_INCLUDES_START + #include "AmdAmf/core/Result.h" + #include "AmdAmf/core/Factory.h" + #include "AmdAmf/components/VideoEncoderVCE.h" + #include "AmdAmf/core/Compute.h" + #include "AmdAmf/core/Plane.h" +THIRD_PARTY_INCLUDES_END + +DECLARE_LOG_CATEGORY_EXTERN(AmdAmf, Log, VeryVerbose); + +#define CHECK_AMF_RET(AMF_call)\ +{\ + AMF_RESULT Res = AMF_call;\ + if (Res != AMF_OK)\ + {\ + UE_LOG(AmdAmf, Error, TEXT("`" #AMF_call "` failed with error code: %d"), Res);\ + /*check(false);*/\ + return false;\ + }\ +} + +// enumerates all available properties of AMFPropertyStorage interface and logs their name, +// current and default values and other info +inline bool LogAmfPropertyStorage(amf::AMFPropertyStorageEx* PropertyStorage) +{ + SIZE_T NumProps = PropertyStorage->GetPropertiesInfoCount(); + for (int i = 0; i != NumProps; ++i) + { + const amf::AMFPropertyInfo* Info; + CHECK_AMF_RET(PropertyStorage->GetPropertyInfo(i, &Info)); + + if (Info->accessType != amf::AMF_PROPERTY_ACCESS_PRIVATE) + { + amf::AMFVariant Value; + CHECK_AMF_RET(PropertyStorage->GetProperty(Info->name, &Value)); + + FString EnumDesc; + if (Info->pEnumDescription) + { + int j = 0; + for (; /*j != Value.ToInt32()*/; ++j) + { + if (Info->pEnumDescription[j].value == Value.ToInt32()) + { + break; + } + } + EnumDesc = TEXT(" ") + FString(Info->pEnumDescription[j].name); + } + + UE_LOG(AmdAmf, Log, TEXT("Prop %s (%s): value: %s%s, default value: %s (%s - %s), access: %d"), + Info->name, + Info->desc, + Value.ToWString().c_str(), + *EnumDesc, + amf::AMFVariant{ Info->defaultValue }.ToWString().c_str(), + amf::AMFVariant{ Info->minValue }.ToWString().c_str(), + amf::AMFVariant{ Info->maxValue }.ToWString().c_str(), + static_cast(Info->accessType)); + } + else + { + UE_LOG(AmdAmf, VeryVerbose, TEXT("Prop: %s (%s) - PRIVATE"), Info->name, Info->desc); + } + } + + return true; +} + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmfVideoEncoder.cpp b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmfVideoEncoder.cpp new file mode 100644 index 000000000000..7bf53cc1d795 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmfVideoEncoder.cpp @@ -0,0 +1,412 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "AmdAmfVideoEncoder.h" + +#if PLATFORM_WINDOWS + +#include "GameplayMediaEncoderSample.h" + +#include "ScreenRendering.h" +#include "ShaderCore.h" +#include "RendererInterface.h" +#include "RHIStaticStates.h" +#include "PipelineStateCache.h" +#include "Modules/ModuleManager.h" +#include "CommonRenderResources.h" + +GAMEPLAYMEDIAENCODER_START + +DEFINE_LOG_CATEGORY(AmdAmf); + +FAmdAmfVideoEncoder::FAmdAmfVideoEncoder(const FOutputSampleCallback& OutputCallback) : + FBaseVideoEncoder(OutputCallback) +{} + +FAmdAmfVideoEncoder::~FAmdAmfVideoEncoder() +{ + // BufferedFrames keep references to AMFData, we need to release them before destroying AMF + for (FFrame& Frame : BufferedFrames) + { + Frame.EncodedData = nullptr; + } + + // Cleanup in this order + if (AmfEncoder) + { + AmfEncoder->Terminate(); + AmfEncoder = nullptr; + } + if (AmfContext) + { + AmfContext->Terminate(); + AmfContext = nullptr; + } + AmfFactory = nullptr; + if (DllHandle) + { + FPlatformProcess::FreeDllHandle(DllHandle); + DllHandle = nullptr; + } +} + +bool FAmdAmfVideoEncoder::Initialize(const FVideoEncoderConfig& InConfig) +{ + if (bInitialized) + { + UE_LOG(AmdAmf, Error, TEXT("Encoder already initialized. Re-initialization is not supported. Instead recreate the instance.")); + return false; + } + + UE_LOG(AmdAmf, Log, TEXT("VideoEncoder config: %dx%d, %d FPS, %.2f Mbps"), InConfig.Width, InConfig.Height, InConfig.Framerate, InConfig.Bitrate / 1000000.0f); + + if (!FBaseVideoEncoder::Initialize(InConfig)) + { + return false; + } + + DllHandle = FPlatformProcess::GetDllHandle(AMF_DLL_NAME); + if (DllHandle == nullptr) + { + return false; + } + + AMFInit_Fn AmfInitFn = (AMFInit_Fn)FPlatformProcess::GetDllExport((HMODULE)DllHandle, TEXT(AMF_INIT_FUNCTION_NAME)); + if (AmfInitFn == nullptr) + { + return false; + } + CHECK_AMF_RET(AmfInitFn(AMF_FULL_VERSION, &AmfFactory)); + + AMFQueryVersion_Fn AmfVersionFun = (AMFQueryVersion_Fn)FPlatformProcess::GetDllExport((HMODULE)DllHandle, TEXT(AMF_QUERY_VERSION_FUNCTION_NAME)); + if (AmfVersionFun == nullptr) + { + return false; + } + uint64 AmfVersion = 0; + AmfVersionFun(&AmfVersion); + + CHECK_AMF_RET(AmfFactory->CreateContext(&AmfContext)); + CHECK_AMF_RET(AmfContext->InitDX11(GetUE4DxDevice())); + + CHECK_AMF_RET(AmfFactory->CreateComponent(AmfContext, AMFVideoEncoderVCE_AVC, &AmfEncoder)); + CHECK_AMF_RET(AmfEncoder->SetProperty(AMF_VIDEO_ENCODER_USAGE, /*AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY*/AMF_VIDEO_ENCODER_USAGE_TRANSCONDING)); + CHECK_AMF_RET(AmfEncoder->SetProperty(AMF_VIDEO_ENCODER_PROFILE, AMF_VIDEO_ENCODER_PROFILE_MAIN)); + //CHECK_AMF_RET(AmfEncoder->SetProperty(AMF_VIDEO_ENCODER_B_PIC_PATTERN, 0)); + CHECK_AMF_RET(AmfEncoder->SetProperty(AMF_VIDEO_ENCODER_QUALITY_PRESET, AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY)); + CHECK_AMF_RET(AmfEncoder->SetProperty(AMF_VIDEO_ENCODER_TARGET_BITRATE, InConfig.Bitrate)); + CHECK_AMF_RET(AmfEncoder->SetProperty(AMF_VIDEO_ENCODER_FRAMESIZE, ::AMFConstructSize(InConfig.Width, InConfig.Height))); + CHECK_AMF_RET(AmfEncoder->SetProperty(AMF_VIDEO_ENCODER_FRAMERATE, ::AMFConstructRate(InConfig.Framerate, 1))); + + // generate key-frames every second, useful for seeking in resulting .mp4 and keeping recording ring buffer + // of second-precise duration + uint64 IdrPeriod = InConfig.Framerate; + CHECK_AMF_RET(AmfEncoder->SetProperty(AMF_VIDEO_ENCODER_IDR_PERIOD, IdrPeriod)); + // insert SPS/PPS before every key-frame. .mp4 file video stream must start from SPS/PPS. Their size is + // negligible so having them before every key-frame is not an issue but they presence simplifies + // implementation significantly. Otherwise we would extract SPS/PPS from the first key-frame and store + // them manually at the beginning of resulting .mp4 file + CHECK_AMF_RET(AmfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEADER_INSERTION_SPACING, IdrPeriod)); + + CHECK_AMF_RET(AmfEncoder->Init(amf::AMF_SURFACE_RGBA, InConfig.Width, InConfig.Height)); + + //LogAmfPropertyStorage(AmfEncoder); + + for (uint32 i = 0; i < NumBufferedFrames; ++i) + { + FFrame& Frame = BufferedFrames[i]; + ResetResolvedBackBuffer(Frame); + } + + UE_LOG(AmdAmf, Log, TEXT("AMF H.264 encoder initialised, v.0x%X"), AmfVersion); + + bInitialized = true; + + return true; +} + +bool FAmdAmfVideoEncoder::Start() +{ + return true; +} + +void FAmdAmfVideoEncoder::Stop() +{ +} + +bool FAmdAmfVideoEncoder::SetBitrate(uint32 Bitrate) +{ + // update `Config` and `OutputType` + if (!FBaseVideoEncoder::SetBitrate(Bitrate)) + { + return false; + } + + // reconfigure AMF + CHECK_AMF_RET(AmfEncoder->SetProperty(AMF_VIDEO_ENCODER_TARGET_BITRATE, Bitrate)); + + return true; +} + +bool FAmdAmfVideoEncoder::SetFramerate(uint32 Framerate) +{ + // update `Config` and `OutputType` + if (!FBaseVideoEncoder::SetFramerate(Framerate)) + { + return false; + } + + // reconfigure AMF + CHECK_AMF_RET(AmfEncoder->SetProperty(AMF_VIDEO_ENCODER_FRAMERATE, ::AMFConstructRate(Framerate, 1))); + + return true; +} + +DECLARE_CYCLE_STAT(TEXT("Process"), STAT_FAmdAmfVideoEncoder_Process, STATGROUP_AmdAmfVideoEncoder); + +bool FAmdAmfVideoEncoder::Process(const FTexture2DRHIRef& Texture, FTimespan Timestamp, FTimespan Duration) +{ + SCOPE_CYCLE_COUNTER(STAT_FAmdAmfVideoEncoder_Process); + + check(IsInRenderingThread()); + + // first process output to free reused instances of input frames + return ProcessOutput() && ProcessInput(Texture, Timestamp, Duration); +} + +DECLARE_CYCLE_STAT(TEXT("ProcessInput"), STAT_FAmdAmfVideoEncoder_ProcessInput, STATGROUP_AmdAmfVideoEncoder); + +bool FAmdAmfVideoEncoder::ProcessInput(const FTexture2DRHIRef& Texture, FTimespan Timestamp, FTimespan Duration) +// prepare frame and submit to encoder +{ + SCOPE_CYCLE_COUNTER(STAT_FAmdAmfVideoEncoder_ProcessInput); + + UE_LOG(AmdAmf, VeryVerbose, TEXT("frame #%d input"), InputFrameCount); + + uint32 BufferIndex = InputFrameCount % NumBufferedFrames; + FFrame& Frame = BufferedFrames[BufferIndex]; + + if (Frame.bEncoding) + { + UE_LOG(AmdAmf, Verbose, TEXT("Dropped frame because encoder is lagging")); + return true; + } + + Frame.bEncoding = true; + + ResolveBackBuffer(Texture, Frame.ResolvedBackBuffer); + + Frame.FrameIdx = InputFrameCount; + Frame.Timestamp = Timestamp; + Frame.Duration = Duration; + + // ResolveBackBuffer can be asynchronous (executed by RHI Command List, so we need to do the same + // for submitting frame to encoder + ExecuteRHICommand([this, &Frame]() { SubmitFrameToEncoder(Frame); }); + + ++InputFrameCount; + + return true; +} + +DECLARE_CYCLE_STAT(TEXT("SubmitFrameToEncoder"), STAT_FAmdAmfVideoEncoder_SubmitFrameToEncoder, STATGROUP_AmdAmfVideoEncoder); +DECLARE_CYCLE_STAT(TEXT("AmfEncoder->SubmitInput"), STAT_FAmdAmfVideoEncoder_AmfEncoder_SubmitInput, STATGROUP_AmdAmfVideoEncoder); + +bool FAmdAmfVideoEncoder::SubmitFrameToEncoder(FFrame& Frame) +{ + SCOPE_CYCLE_COUNTER(STAT_FAmdAmfVideoEncoder_SubmitFrameToEncoder); + + amf::AMFSurfacePtr AmfSurfaceIn; + ID3D11Texture2D* ResolvedBackBufferDX11 = static_cast(GetD3D11TextureFromRHITexture(Frame.ResolvedBackBuffer)->GetResource()); + + CHECK_AMF_RET(AmfContext->CreateSurfaceFromDX11Native(ResolvedBackBufferDX11, &AmfSurfaceIn, nullptr)); + + { + // if `-d3ddebug` is enabled `SubmitInput` crashes with DX11 error, see output window + // we believe it's an internal AMF shader problem so we disable those errors explicitly, otherwise + // DX Debug Layer can't be used at all + FScopeDisabledDxDebugErrors Errors({ + D3D11_MESSAGE_ID_DEVICE_UNORDEREDACCESSVIEW_RETURN_TYPE_MISMATCH, + D3D11_MESSAGE_ID_DEVICE_CSSETUNORDEREDACCESSVIEWS_TOOMANYVIEWS, + }); + + { + SCOPE_CYCLE_COUNTER(STAT_FAmdAmfVideoEncoder_AmfEncoder_SubmitInput); + CHECK_AMF_RET(AmfEncoder->SubmitInput(AmfSurfaceIn)); + } + } + + return true; +} + +DECLARE_CYCLE_STAT(TEXT("QueryEncoderOutput"), STAT_FAmdAmfVideoEncoder_QueryEncoderOutput, STATGROUP_AmdAmfVideoEncoder); + +DECLARE_CYCLE_STAT(TEXT("AmfEncoder->QueryOutput"), STAT_FAmdAmfVideoEncoder_AmfEncoder_QueryOutput, STATGROUP_AmdAmfVideoEncoder); + +bool FAmdAmfVideoEncoder::ProcessOutput() +// check if output is ready and handle it +{ + SCOPE_CYCLE_COUNTER(STAT_FAmdAmfVideoEncoder_QueryEncoderOutput); + + check(IsInRenderingThread()); + + // more than one output frame can be ready + while (BufferedFrames[OutputFrameCount % NumBufferedFrames].bEncoding) + { + amf::AMFDataPtr EncodedData; + AMF_RESULT Ret; + { + SCOPE_CYCLE_COUNTER(STAT_FAmdAmfVideoEncoder_AmfEncoder_QueryOutput); + Ret = AmfEncoder->QueryOutput(&EncodedData); + } + if (Ret == AMF_OK && EncodedData != nullptr) + { + UE_LOG(AmdAmf, VeryVerbose, TEXT("frame #%d encoded"), OutputFrameCount); + + FFrame& Frame = BufferedFrames[OutputFrameCount % NumBufferedFrames]; + check(Frame.bEncoding); + checkf(OutputFrameCount == Frame.FrameIdx, TEXT("%d - %d"), OutputFrameCount, Frame.FrameIdx); + Frame.EncodedData = EncodedData; + + if (!HandleEncodedFrame(Frame)) + { + return false; + } + + ++OutputFrameCount; + } + else if (Ret == AMF_REPEAT) + { + break; // not ready yet + } + else + { + UE_LOG(AmdAmf, Error, TEXT("Failed to query AMF H.264 Encoder output: %d, %p"), Ret, EncodedData.GetPtr()); + return false; + } + } + + return true; +} + +DECLARE_CYCLE_STAT(TEXT("ProcessEncodedFrame"), STAT_FAmdAmfVideoEncoder_ProcessEncodedFrame, STATGROUP_AmdAmfVideoEncoder); + +bool FAmdAmfVideoEncoder::HandleEncodedFrame(FFrame& Frame) +{ + SCOPE_CYCLE_COUNTER(STAT_FAmdAmfVideoEncoder_ProcessEncodedFrame); + + checkf(Frame.bEncoding && Frame.EncodedData != nullptr, TEXT("Internal error: %d, %p"), static_cast(Frame.bEncoding), Frame.EncodedData.GetPtr()); + if (!Frame.bEncoding || Frame.EncodedData == nullptr) + { + return false; + } + + // Query for buffer interface + amf::AMFBufferPtr EncodedBuffer(Frame.EncodedData); + void* EncodedBufferPtr = EncodedBuffer->GetNative(); + size_t EncodedBufferSize = EncodedBuffer->GetSize(); + + // Retrieve encoded frame from AMFBuffer and copy to IMFMediaBuffer + TRefCountPtr MediaBuffer; + CHECK_HR(MFCreateMemoryBuffer(EncodedBufferSize, MediaBuffer.GetInitReference())); + CHECK_HR(MediaBuffer->SetCurrentLength(EncodedBufferSize)); + BYTE* MediaBufferData = nullptr; + DWORD MediaBufferLength = 0; + MediaBuffer->Lock(&MediaBufferData, nullptr, &MediaBufferLength); + FMemory::Memcpy(MediaBufferData, EncodedBufferPtr, EncodedBufferSize); + MediaBuffer->Unlock(); + + FGameplayMediaEncoderSample OutputSample{ EMediaType::Video }; + if (!OutputSample.CreateSample()) + { + return false; + } + CHECK_HR(OutputSample.GetSample()->AddBuffer(MediaBuffer)); + OutputSample.SetTime(Frame.Timestamp); + OutputSample.SetDuration(Frame.Duration); + + // mark as a key-frame (if it is) + uint64 OutputFrameType; + CHECK_AMF_RET(EncodedBuffer->GetProperty(AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE, &OutputFrameType)); + CHECK_HR(OutputSample.GetSample()->SetUINT32(MFSampleExtension_CleanPoint, OutputFrameType == AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE_IDR ? 1 : 0)); + + UE_LOG(AmdAmf, Verbose, TEXT("encoded frame #%d: time %.3f, duration %.3f, size %d, type %d"), Frame.FrameIdx, OutputSample.GetTime().GetTotalSeconds(), OutputSample.GetDuration().GetTotalSeconds(), EncodedBufferSize, OutputFrameType); + + // only now when we're done dealing with encoded data we can "release" this frame + // to be reused for encoding input + Frame.EncodedData = nullptr; + Frame.bEncoding = false; + + OutputCallback(OutputSample); + return true; +} + +void FAmdAmfVideoEncoder::ResetResolvedBackBuffer(FFrame& Frame) +{ + Frame.ResolvedBackBuffer.SafeRelease(); + + // Make sure format used here is compatible with AMF_SURFACE_FORMAT specified in encoder Init() function. + FRHIResourceCreateInfo CreateInfo; + Frame.ResolvedBackBuffer = RHICreateTexture2D(Config.Width, Config.Height, EPixelFormat::PF_R8G8B8A8, 1, 1, TexCreate_RenderTargetable, CreateInfo); +} + +DECLARE_CYCLE_STAT(TEXT("ResolveBackBuffer"), STAT_FAmdAmfVideoEncoder_ResolveBackBuffer, STATGROUP_AmdAmfVideoEncoder); + +void FAmdAmfVideoEncoder::ResolveBackBuffer(const FTexture2DRHIRef& BackBuffer, const FTexture2DRHIRef& ResolvedBackBuffer) +{ + SCOPE_CYCLE_COUNTER(STAT_FAmdAmfVideoEncoder_ResolveBackBuffer); + + IRendererModule* RendererModule = &FModuleManager::GetModuleChecked("Renderer"); + FRHICommandListImmediate& RHICmdList = FRHICommandListExecutor::GetImmediateCommandList(); + + if (BackBuffer->GetFormat() == ResolvedBackBuffer->GetFormat() && + BackBuffer->GetSizeXY() == ResolvedBackBuffer->GetSizeXY()) + { + RHICmdList.CopyToResolveTarget(BackBuffer, ResolvedBackBuffer, FResolveParams()); + } + else // Texture format mismatch, use a shader to do the copy. + { + SetRenderTarget(RHICmdList, ResolvedBackBuffer, FTextureRHIRef()); + RHICmdList.SetViewport(0, 0, 0.0f, ResolvedBackBuffer->GetSizeX(), ResolvedBackBuffer->GetSizeY(), 1.0f); + + FGraphicsPipelineStateInitializer GraphicsPSOInit; + RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit); + GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI(); + GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI(); + GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState::GetRHI(); + + TShaderMap* ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel); + TShaderMapRef VertexShader(ShaderMap); + TShaderMapRef PixelShader(ShaderMap); + + GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GFilterVertexDeclaration.VertexDeclarationRHI; + GraphicsPSOInit.BoundShaderState.VertexShaderRHI = GETSAFERHISHADER_VERTEX(*VertexShader); + GraphicsPSOInit.BoundShaderState.PixelShaderRHI = GETSAFERHISHADER_PIXEL(*PixelShader); + GraphicsPSOInit.PrimitiveType = PT_TriangleList; + + SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit); + + if (ResolvedBackBuffer->GetSizeX() != BackBuffer->GetSizeX() || ResolvedBackBuffer->GetSizeY() != BackBuffer->GetSizeY()) + PixelShader->SetParameters(RHICmdList, TStaticSamplerState::GetRHI(), BackBuffer); + else + PixelShader->SetParameters(RHICmdList, TStaticSamplerState::GetRHI(), BackBuffer); + + RendererModule->DrawRectangle( + RHICmdList, + 0, 0, // Dest X, Y + ResolvedBackBuffer->GetSizeX(), // Dest Width + ResolvedBackBuffer->GetSizeY(), // Dest Height + 0, 0, // Source U, V + 1, 1, // Source USize, VSize + ResolvedBackBuffer->GetSizeXY(), // Target buffer size + FIntPoint(1, 1), // Source texture size + *VertexShader, + EDRF_Default); + + SetRenderTarget(RHICmdList, FTextureRHIRef(), FTextureRHIRef()); + } +} + +GAMEPLAYMEDIAENCODER_END + +#endif + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmfVideoEncoder.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmfVideoEncoder.h new file mode 100644 index 000000000000..7792b350cb42 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/AmdAmfVideoEncoder.h @@ -0,0 +1,56 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "GameplayMediaEncoderCommon.h" + +#include "AmdAmfPrivate.h" +#include "BaseVideoEncoder.h" + +DECLARE_STATS_GROUP(TEXT("AmdAmfVideoEncoder"), STATGROUP_AmdAmfVideoEncoder, STATCAT_Advanced); + +// H.264 Encoder based on AMF SDK for AMD GPUs +class FAmdAmfVideoEncoder: public FBaseVideoEncoder +{ +public: + explicit FAmdAmfVideoEncoder(const FOutputSampleCallback& OutputCallback); + ~FAmdAmfVideoEncoder() override; + + bool Initialize(const FVideoEncoderConfig& Config) override; + bool Start() override; + void Stop() override; + bool Process(const FTexture2DRHIRef& Texture, FTimespan Timestamp, FTimespan Duration) override; + + bool SetBitrate(uint32 Bitrate) override; + bool SetFramerate(uint32 Framerate) override; + +private: + struct FFrame + { + FTexture2DRHIRef ResolvedBackBuffer; + amf::AMFDataPtr EncodedData; + uint64 FrameIdx = 0; + FThreadSafeBool bEncoding = false; + FTimespan Timestamp; + FTimespan Duration; + }; + + bool ProcessInput(const FTexture2DRHIRef& Texture, FTimespan Timestamp, FTimespan Duration); + bool SubmitFrameToEncoder(FFrame& Frame); + bool ProcessOutput(); + bool HandleEncodedFrame(FFrame& Frame); + void ResetResolvedBackBuffer(FFrame& Frame); + void ResolveBackBuffer(const FTexture2DRHIRef& BackBuffer, const FTexture2DRHIRef& ResolvedBackBuffer); + + bool bInitialized = false; + amf_handle DllHandle = nullptr; + amf::AMFFactory* AmfFactory = nullptr; + amf::AMFContextPtr AmfContext; + amf::AMFComponentPtr AmfEncoder; + uint64 InputFrameCount = 0; + uint64 OutputFrameCount = 0; + static const uint32 NumBufferedFrames = 3; + FFrame BufferedFrames[NumBufferedFrames]; +}; + + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/D3D11VideoProcessor.cpp b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/D3D11VideoProcessor.cpp new file mode 100644 index 000000000000..68f7a8dfac0d --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/D3D11VideoProcessor.cpp @@ -0,0 +1,62 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "D3D11VideoProcessor.h" + +GAMEPLAYMEDIAENCODER_START + +CSV_DECLARE_CATEGORY_EXTERN(GameplayMediaEncoder); + +bool FD3D11VideoProcessor::Initialize(uint32 Width, uint32 Height) +{ + CSV_SCOPED_TIMING_STAT(GameplayMediaEncoder, D3D11VideoProcessor_Initialize); + + ID3D11Device* DX11Device = static_cast(GDynamicRHI->RHIGetNativeDevice()); + check(DX11Device); + ID3D11DeviceContext* DX11DeviceContext = nullptr; + DX11Device->GetImmediateContext(&DX11DeviceContext); + check(DX11DeviceContext); + + CHECK_HR(DX11Device->QueryInterface(__uuidof(ID3D11VideoDevice), (void**)&VideoDevice)); + CHECK_HR(DX11DeviceContext->QueryInterface(__uuidof(ID3D11VideoContext), (void**)&VideoContext)); + + D3D11_VIDEO_PROCESSOR_CONTENT_DESC ContentDesc = + { + D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE, + { 1, 1 }, Width, Height, + { 1, 1 }, Width, Height, + D3D11_VIDEO_USAGE_PLAYBACK_NORMAL + }; + CHECK_HR(VideoDevice->CreateVideoProcessorEnumerator(&ContentDesc, VideoProcessorEnumerator.GetInitReference())); + CHECK_HR(VideoDevice->CreateVideoProcessor(VideoProcessorEnumerator, 0, VideoProcessor.GetInitReference())); + + return true; +} + +bool FD3D11VideoProcessor::ConvertTexture(const FTexture2DRHIRef& InTexture, const FTexture2DRHIRef& OutTexture) +{ + CSV_SCOPED_TIMING_STAT(GameplayMediaEncoder, D3D11VideoProcessor_ConvertTexture); + + // TODO: clean up dead entries of InputViews and OutputViews which happen after resolutions change + ID3D11Texture2D* InTextureDX11 = (ID3D11Texture2D*)(GetD3D11TextureFromRHITexture(InTexture)->GetResource()); + TRefCountPtr& InputView = InputViews.FindOrAdd(InTextureDX11); + if (!InputView) + { + D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC InputViewDesc = { 0, D3D11_VPIV_DIMENSION_TEXTURE2D, { 0, 0 } }; + CHECK_HR(VideoDevice->CreateVideoProcessorInputView(InTextureDX11, VideoProcessorEnumerator, &InputViewDesc, InputView.GetInitReference())); + } + + ID3D11Texture2D* OutTextureDX11 = (ID3D11Texture2D*)(GetD3D11TextureFromRHITexture(OutTexture)->GetResource()); + TRefCountPtr& OutputView = OutputViews.FindOrAdd(OutTextureDX11); + if (!OutputView) + { + D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC OutputViewDesc = { D3D11_VPOV_DIMENSION_TEXTURE2D }; + CHECK_HR(VideoDevice->CreateVideoProcessorOutputView(OutTextureDX11, VideoProcessorEnumerator, &OutputViewDesc, OutputView.GetInitReference())); + } + + D3D11_VIDEO_PROCESSOR_STREAM Stream = { true, 0, 0, 0, 0, nullptr, InputView, nullptr }; + CHECK_HR(VideoContext->VideoProcessorBlt(VideoProcessor, OutputView, 0, 1, &Stream)); + return true; +} + +GAMEPLAYMEDIAENCODER_END + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/D3D11VideoProcessor.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/D3D11VideoProcessor.h new file mode 100644 index 000000000000..800e4ea159fc --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/D3D11VideoProcessor.h @@ -0,0 +1,21 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "GameplayMediaEncoderCommon.h" + +class FD3D11VideoProcessor +{ +public: + bool Initialize(uint32 Width, uint32 Height); + bool ConvertTexture(const FTexture2DRHIRef& InTexture, const FTexture2DRHIRef& OutTexture); + +private: + TRefCountPtr VideoDevice; + TRefCountPtr VideoContext; + TRefCountPtr VideoProcessor; + TRefCountPtr VideoProcessorEnumerator; + TMap> InputViews; + TMap> OutputViews; +}; + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/EncoderDevice.cpp b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/EncoderDevice.cpp new file mode 100644 index 000000000000..7adfd5f44efd --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/EncoderDevice.cpp @@ -0,0 +1,46 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "EncoderDevice.h" + +#if PLATFORM_WINDOWS + +FEncoderDevice::FEncoderDevice() +{ + if (GDynamicRHI) + { + ID3D11Device* D3D11Device = GetUE4DxDevice(); + + IDXGIDevice* DXGIDevice = nullptr; + CHECK_HR_VOID(D3D11Device->QueryInterface(__uuidof(IDXGIDevice), (LPVOID*)&DXGIDevice)); + + IDXGIAdapter* Adapter; + CHECK_HR_VOID(DXGIDevice->GetAdapter(&Adapter)); + + D3D_DRIVER_TYPE DriverType = D3D_DRIVER_TYPE_UNKNOWN; + uint32 DeviceFlags = D3D11Device->GetCreationFlags(); + D3D_FEATURE_LEVEL FeatureLevel = D3D11Device->GetFeatureLevel(); + D3D_FEATURE_LEVEL ActualFeatureLevel; + + CHECK_HR_VOID(D3D11CreateDevice( + Adapter, + DriverType, + NULL, + DeviceFlags, + &FeatureLevel, + 1, + D3D11_SDK_VERSION, + Device.GetInitReference(), + &ActualFeatureLevel, + DeviceContext.GetInitReference() + )); + + DXGIDevice->Release(); + } + else + { + UE_LOG(GameplayMediaEncoder, Error, TEXT("Attempting to create Encoder Device without existing RHI")); + } +} + +#endif + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/EncoderDevice.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/EncoderDevice.h new file mode 100644 index 000000000000..01cd0a0e79fe --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/EncoderDevice.h @@ -0,0 +1,16 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "GameplayMediaEncoderCommon.h" + +class FEncoderDevice +{ +public: + FEncoderDevice(); + + TRefCountPtr Device; + TRefCountPtr DeviceContext; +}; + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/NvEncoder/NVIDIAVideoCodecSDK.tps b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/NvEncoder/NVIDIAVideoCodecSDK.tps new file mode 100644 index 000000000000..47a9a22b22dd --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/NvEncoder/NVIDIAVideoCodecSDK.tps @@ -0,0 +1,11 @@ + + + NVIDIA VIDEO CODEC SDK v8.0 + Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/NvEncoder + Performs encoding/decoding of a video stream into various formats. Used for prototyping UE4 pixel streaming plugin for Enterprise team. SDK will primarily function as the video encoder for UE4 pixel streaming server instances deployed primarily to the cloud as well as locally. + http://developer2.download.nvidia.com/designworks/DesignWorks_SDKs_Samples_Tools_License_distrib_use_rights_2017_06_13.pdf + + P4 + + None + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/NvEncoder/nvEncodeAPI.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/NvEncoder/nvEncodeAPI.h new file mode 100644 index 000000000000..8825f266d32a --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/NvEncoder/nvEncodeAPI.h @@ -0,0 +1,3415 @@ +/* + * This copyright notice applies to this header file only: + * + * Copyright (c) 2010-2018 NVIDIA Corporation + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the software, and to permit persons to whom the + * software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file nvEncodeAPI.h + * NVIDIA GPUs - beginning with the Kepler generation - contain a hardware-based encoder + * (referred to as NVENC) which provides fully-accelerated hardware-based video encoding. + * NvEncodeAPI provides the interface for NVIDIA video encoder (NVENC). + * \date 2011-2018 + * This file contains the interface constants, structure definitions and function prototypes. + */ + +#ifndef _NV_ENCODEAPI_H_ +#define _NV_ENCODEAPI_H_ + +#include + +#ifdef _WIN32 +#include +#endif + +#ifdef _MSC_VER +#ifndef _STDINT +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +#endif +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup ENCODER_STRUCTURE NvEncodeAPI Data structures + * @{ + */ + +#ifdef _WIN32 +#define NVENCAPI __stdcall +typedef RECT NVENC_RECT; +#else +#define NVENCAPI +// ========================================================================================= +#ifndef GUID +/*! + * \struct GUID + * Abstracts the GUID structure for non-windows platforms. + */ +// ========================================================================================= +typedef struct +{ + uint32_t Data1; /**< [in]: Specifies the first 8 hexadecimal digits of the GUID. */ + uint16_t Data2; /**< [in]: Specifies the first group of 4 hexadecimal digits. */ + uint16_t Data3; /**< [in]: Specifies the second group of 4 hexadecimal digits. */ + uint8_t Data4[8]; /**< [in]: Array of 8 bytes. The first 2 bytes contain the third group of 4 hexadecimal digits. + The remaining 6 bytes contain the final 12 hexadecimal digits. */ +} GUID; +#endif // GUID + +/** + * \struct _NVENC_RECT + * Defines a Rectangle. Used in ::NV_ENC_PREPROCESS_FRAME. + */ +typedef struct _NVENC_RECT +{ + uint32_t left; /**< [in]: X coordinate of the upper left corner of rectangular area to be specified. */ + uint32_t top; /**< [in]: Y coordinate of the upper left corner of the rectangular area to be specified. */ + uint32_t right; /**< [in]: X coordinate of the bottom right corner of the rectangular area to be specified. */ + uint32_t bottom; /**< [in]: Y coordinate of the bottom right corner of the rectangular area to be specified. */ +} NVENC_RECT; + +#endif // _WIN32 + +/** @} */ /* End of GUID and NVENC_RECT structure grouping*/ + +typedef void* NV_ENC_INPUT_PTR; /**< NVENCODE API input buffer */ +typedef void* NV_ENC_OUTPUT_PTR; /**< NVENCODE API output buffer*/ +typedef void* NV_ENC_REGISTERED_PTR; /**< A Resource that has been registered with NVENCODE API*/ + +#define NVENCAPI_MAJOR_VERSION 8 +#define NVENCAPI_MINOR_VERSION 1 + +#define NVENCAPI_VERSION (NVENCAPI_MAJOR_VERSION | (NVENCAPI_MINOR_VERSION << 24)) + +/** + * Macro to generate per-structure version for use with API. + */ +#define NVENCAPI_STRUCT_VERSION(ver) ((uint32_t)NVENCAPI_VERSION | ((ver)<<16) | (0x7 << 28)) + + +#define NVENC_INFINITE_GOPLENGTH 0xffffffff + +#define NV_MAX_SEQ_HDR_LEN (512) + +// ========================================================================================= +// Encode Codec GUIDS supported by the NvEncodeAPI interface. +// ========================================================================================= + +// {6BC82762-4E63-4ca4-AA85-1E50F321F6BF} +static const GUID NV_ENC_CODEC_H264_GUID = +{ 0x6bc82762, 0x4e63, 0x4ca4, { 0xaa, 0x85, 0x1e, 0x50, 0xf3, 0x21, 0xf6, 0xbf } }; + +// {790CDC88-4522-4d7b-9425-BDA9975F7603} +static const GUID NV_ENC_CODEC_HEVC_GUID = +{ 0x790cdc88, 0x4522, 0x4d7b, { 0x94, 0x25, 0xbd, 0xa9, 0x97, 0x5f, 0x76, 0x3 } }; + + + +// ========================================================================================= +// * Encode Profile GUIDS supported by the NvEncodeAPI interface. +// ========================================================================================= + +// {BFD6F8E7-233C-4341-8B3E-4818523803F4} +static const GUID NV_ENC_CODEC_PROFILE_AUTOSELECT_GUID = +{ 0xbfd6f8e7, 0x233c, 0x4341, { 0x8b, 0x3e, 0x48, 0x18, 0x52, 0x38, 0x3, 0xf4 } }; + +// {0727BCAA-78C4-4c83-8C2F-EF3DFF267C6A} +static const GUID NV_ENC_H264_PROFILE_BASELINE_GUID = +{ 0x727bcaa, 0x78c4, 0x4c83, { 0x8c, 0x2f, 0xef, 0x3d, 0xff, 0x26, 0x7c, 0x6a } }; + +// {60B5C1D4-67FE-4790-94D5-C4726D7B6E6D} +static const GUID NV_ENC_H264_PROFILE_MAIN_GUID = +{ 0x60b5c1d4, 0x67fe, 0x4790, { 0x94, 0xd5, 0xc4, 0x72, 0x6d, 0x7b, 0x6e, 0x6d } }; + +// {E7CBC309-4F7A-4b89-AF2A-D537C92BE310} +static const GUID NV_ENC_H264_PROFILE_HIGH_GUID = +{ 0xe7cbc309, 0x4f7a, 0x4b89, { 0xaf, 0x2a, 0xd5, 0x37, 0xc9, 0x2b, 0xe3, 0x10 } }; + +// {7AC663CB-A598-4960-B844-339B261A7D52} +static const GUID NV_ENC_H264_PROFILE_HIGH_444_GUID = +{ 0x7ac663cb, 0xa598, 0x4960, { 0xb8, 0x44, 0x33, 0x9b, 0x26, 0x1a, 0x7d, 0x52 } }; + +// {40847BF5-33F7-4601-9084-E8FE3C1DB8B7} +static const GUID NV_ENC_H264_PROFILE_STEREO_GUID = +{ 0x40847bf5, 0x33f7, 0x4601, { 0x90, 0x84, 0xe8, 0xfe, 0x3c, 0x1d, 0xb8, 0xb7 } }; + +// {CE788D20-AAA9-4318-92BB-AC7E858C8D36} +static const GUID NV_ENC_H264_PROFILE_SVC_TEMPORAL_SCALABILTY = +{ 0xce788d20, 0xaaa9, 0x4318, { 0x92, 0xbb, 0xac, 0x7e, 0x85, 0x8c, 0x8d, 0x36 } }; + +// {B405AFAC-F32B-417B-89C4-9ABEED3E5978} +static const GUID NV_ENC_H264_PROFILE_PROGRESSIVE_HIGH_GUID = +{ 0xb405afac, 0xf32b, 0x417b, { 0x89, 0xc4, 0x9a, 0xbe, 0xed, 0x3e, 0x59, 0x78 } }; + +// {AEC1BD87-E85B-48f2-84C3-98BCA6285072} +static const GUID NV_ENC_H264_PROFILE_CONSTRAINED_HIGH_GUID = +{ 0xaec1bd87, 0xe85b, 0x48f2, { 0x84, 0xc3, 0x98, 0xbc, 0xa6, 0x28, 0x50, 0x72 } }; + +// {B514C39A-B55B-40fa-878F-F1253B4DFDEC} +static const GUID NV_ENC_HEVC_PROFILE_MAIN_GUID = +{ 0xb514c39a, 0xb55b, 0x40fa, { 0x87, 0x8f, 0xf1, 0x25, 0x3b, 0x4d, 0xfd, 0xec } }; + +// {fa4d2b6c-3a5b-411a-8018-0a3f5e3c9be5} +static const GUID NV_ENC_HEVC_PROFILE_MAIN10_GUID = +{ 0xfa4d2b6c, 0x3a5b, 0x411a, { 0x80, 0x18, 0x0a, 0x3f, 0x5e, 0x3c, 0x9b, 0xe5 } }; + +// For HEVC Main 444 8 bit and HEVC Main 444 10 bit profiles only +// {51ec32b5-1b4c-453c-9cbd-b616bd621341} +static const GUID NV_ENC_HEVC_PROFILE_FREXT_GUID = +{ 0x51ec32b5, 0x1b4c, 0x453c, { 0x9c, 0xbd, 0xb6, 0x16, 0xbd, 0x62, 0x13, 0x41 } }; + +// ========================================================================================= +// * Preset GUIDS supported by the NvEncodeAPI interface. +// ========================================================================================= +// {B2DFB705-4EBD-4C49-9B5F-24A777D3E587} +static const GUID NV_ENC_PRESET_DEFAULT_GUID = +{ 0xb2dfb705, 0x4ebd, 0x4c49, { 0x9b, 0x5f, 0x24, 0xa7, 0x77, 0xd3, 0xe5, 0x87 } }; + +// {60E4C59F-E846-4484-A56D-CD45BE9FDDF6} +static const GUID NV_ENC_PRESET_HP_GUID = +{ 0x60e4c59f, 0xe846, 0x4484, { 0xa5, 0x6d, 0xcd, 0x45, 0xbe, 0x9f, 0xdd, 0xf6 } }; + +// {34DBA71D-A77B-4B8F-9C3E-B6D5DA24C012} +static const GUID NV_ENC_PRESET_HQ_GUID = +{ 0x34dba71d, 0xa77b, 0x4b8f, { 0x9c, 0x3e, 0xb6, 0xd5, 0xda, 0x24, 0xc0, 0x12 } }; + +// {82E3E450-BDBB-4e40-989C-82A90DF9EF32} +static const GUID NV_ENC_PRESET_BD_GUID = +{ 0x82e3e450, 0xbdbb, 0x4e40, { 0x98, 0x9c, 0x82, 0xa9, 0xd, 0xf9, 0xef, 0x32 } }; + +// {49DF21C5-6DFA-4feb-9787-6ACC9EFFB726} +static const GUID NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID = +{ 0x49df21c5, 0x6dfa, 0x4feb, { 0x97, 0x87, 0x6a, 0xcc, 0x9e, 0xff, 0xb7, 0x26 } }; + +// {C5F733B9-EA97-4cf9-BEC2-BF78A74FD105} +static const GUID NV_ENC_PRESET_LOW_LATENCY_HQ_GUID = +{ 0xc5f733b9, 0xea97, 0x4cf9, { 0xbe, 0xc2, 0xbf, 0x78, 0xa7, 0x4f, 0xd1, 0x5 } }; + +// {67082A44-4BAD-48FA-98EA-93056D150A58} +static const GUID NV_ENC_PRESET_LOW_LATENCY_HP_GUID = +{ 0x67082a44, 0x4bad, 0x48fa, { 0x98, 0xea, 0x93, 0x5, 0x6d, 0x15, 0xa, 0x58 } }; + +// {D5BFB716-C604-44e7-9BB8-DEA5510FC3AC} +static const GUID NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID = +{ 0xd5bfb716, 0xc604, 0x44e7, { 0x9b, 0xb8, 0xde, 0xa5, 0x51, 0xf, 0xc3, 0xac } }; + +// {149998E7-2364-411d-82EF-179888093409} +static const GUID NV_ENC_PRESET_LOSSLESS_HP_GUID = +{ 0x149998e7, 0x2364, 0x411d, { 0x82, 0xef, 0x17, 0x98, 0x88, 0x9, 0x34, 0x9 } }; + +/** + * \addtogroup ENCODER_STRUCTURE NvEncodeAPI Data structures + * @{ + */ + +/** + * Input frame encode modes + */ +typedef enum _NV_ENC_PARAMS_FRAME_FIELD_MODE +{ + NV_ENC_PARAMS_FRAME_FIELD_MODE_FRAME = 0x01, /**< Frame mode */ + NV_ENC_PARAMS_FRAME_FIELD_MODE_FIELD = 0x02, /**< Field mode */ + NV_ENC_PARAMS_FRAME_FIELD_MODE_MBAFF = 0x03 /**< MB adaptive frame/field */ +} NV_ENC_PARAMS_FRAME_FIELD_MODE; + +/** + * Rate Control Modes + */ +typedef enum _NV_ENC_PARAMS_RC_MODE +{ + NV_ENC_PARAMS_RC_CONSTQP = 0x0, /**< Constant QP mode */ + NV_ENC_PARAMS_RC_VBR = 0x1, /**< Variable bitrate mode */ + NV_ENC_PARAMS_RC_CBR = 0x2, /**< Constant bitrate mode */ + NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ = 0x8, /**< low-delay CBR, high quality */ + NV_ENC_PARAMS_RC_CBR_HQ = 0x10, /**< CBR, high quality (slower) */ + NV_ENC_PARAMS_RC_VBR_HQ = 0x20 /**< VBR, high quality (slower) */ +} NV_ENC_PARAMS_RC_MODE; + +/** + * Emphasis Levels + */ +typedef enum _NV_ENC_EMPHASIS_MAP_LEVEL +{ + NV_ENC_EMPHASIS_MAP_LEVEL_0 = 0x0, /**< Emphasis Map Level 0, for zero Delta QP value */ + NV_ENC_EMPHASIS_MAP_LEVEL_1 = 0x1, /**< Emphasis Map Level 1, for very low Delta QP value */ + NV_ENC_EMPHASIS_MAP_LEVEL_2 = 0x2, /**< Emphasis Map Level 2, for low Delta QP value */ + NV_ENC_EMPHASIS_MAP_LEVEL_3 = 0x3, /**< Emphasis Map Level 3, for medium Delta QP value */ + NV_ENC_EMPHASIS_MAP_LEVEL_4 = 0x4, /**< Emphasis Map Level 4, for high Delta QP value */ + NV_ENC_EMPHASIS_MAP_LEVEL_5 = 0x5 /**< Emphasis Map Level 5, for very high Delta QP value */ +} NV_ENC_EMPHASIS_MAP_LEVEL; + +/** + * QP MAP MODE + */ +typedef enum _NV_ENC_QP_MAP_MODE +{ + NV_ENC_QP_MAP_DISABLED = 0x0, /**< Value in NV_ENC_PIC_PARAMS::qpDeltaMap have no effect. */ + NV_ENC_QP_MAP_EMPHASIS = 0x1, /**< Value in NV_ENC_PIC_PARAMS::qpDeltaMap will be treated as Empasis level. Currently this is only supported for H264 */ + NV_ENC_QP_MAP_DELTA = 0x2, /**< Value in NV_ENC_PIC_PARAMS::qpDeltaMap will be treated as QP delta map. */ + NV_ENC_QP_MAP = 0x3, /**< Currently This is not supported. Value in NV_ENC_PIC_PARAMS::qpDeltaMap will be treated as QP value. */ +} NV_ENC_QP_MAP_MODE; + +#define NV_ENC_PARAMS_RC_VBR_MINQP (NV_ENC_PARAMS_RC_MODE)0x4 /**< Deprecated */ +#define NV_ENC_PARAMS_RC_2_PASS_QUALITY NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ /**< Deprecated */ +#define NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP NV_ENC_PARAMS_RC_CBR_HQ /**< Deprecated */ +#define NV_ENC_PARAMS_RC_2_PASS_VBR NV_ENC_PARAMS_RC_VBR_HQ /**< Deprecated */ +#define NV_ENC_PARAMS_RC_CBR2 NV_ENC_PARAMS_RC_CBR /**< Deprecated */ + +/** + * Input picture structure + */ +typedef enum _NV_ENC_PIC_STRUCT +{ + NV_ENC_PIC_STRUCT_FRAME = 0x01, /**< Progressive frame */ + NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM = 0x02, /**< Field encoding top field first */ + NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP = 0x03 /**< Field encoding bottom field first */ +} NV_ENC_PIC_STRUCT; + +/** + * Input picture type + */ +typedef enum _NV_ENC_PIC_TYPE +{ + NV_ENC_PIC_TYPE_P = 0x0, /**< Forward predicted */ + NV_ENC_PIC_TYPE_B = 0x01, /**< Bi-directionally predicted picture */ + NV_ENC_PIC_TYPE_I = 0x02, /**< Intra predicted picture */ + NV_ENC_PIC_TYPE_IDR = 0x03, /**< IDR picture */ + NV_ENC_PIC_TYPE_BI = 0x04, /**< Bi-directionally predicted with only Intra MBs */ + NV_ENC_PIC_TYPE_SKIPPED = 0x05, /**< Picture is skipped */ + NV_ENC_PIC_TYPE_INTRA_REFRESH = 0x06, /**< First picture in intra refresh cycle */ + NV_ENC_PIC_TYPE_UNKNOWN = 0xFF /**< Picture type unknown */ +} NV_ENC_PIC_TYPE; + +/** + * Motion vector precisions + */ +typedef enum _NV_ENC_MV_PRECISION +{ + NV_ENC_MV_PRECISION_DEFAULT = 0x0, /** (if lookahead is enabled, input frames must remain available to the encoder until encode completion) */ + uint32_t disableIadapt :1; /**< [in]: Set this to 1 to disable adaptive I-frame insertion at scene cuts (only has an effect when lookahead is enabled) */ + uint32_t disableBadapt :1; /**< [in]: Set this to 1 to disable adaptive B-frame decision (only has an effect when lookahead is enabled) */ + uint32_t enableTemporalAQ :1; /**< [in]: Set this to 1 to enable temporal AQ for H.264 */ + uint32_t zeroReorderDelay :1; /**< [in]: Set this to 1 to indicate zero latency operation (no reordering delay, num_reorder_frames=0) */ + uint32_t enableNonRefP :1; /**< [in]: Set this to 1 to enable automatic insertion of non-reference P-frames (no effect if enablePTD=0) */ + uint32_t strictGOPTarget :1; /**< [in]: Set this to 1 to minimize GOP-to-GOP rate fluctuations */ + uint32_t aqStrength :4; /**< [in]: When AQ (Spatial) is enabled (i.e. NV_ENC_RC_PARAMS::enableAQ is set), this field is used to specify AQ strength. AQ strength scale is from 1 (low) - 15 (aggressive). If not set, strength is autoselected by driver. */ + uint32_t reservedBitFields :16; /**< [in]: Reserved bitfields and must be set to 0 */ + NV_ENC_QP minQP; /**< [in]: Specifies the minimum QP used for rate control. Client must set NV_ENC_CONFIG::enableMinQP to 1. */ + NV_ENC_QP maxQP; /**< [in]: Specifies the maximum QP used for rate control. Client must set NV_ENC_CONFIG::enableMaxQP to 1. */ + NV_ENC_QP initialRCQP; /**< [in]: Specifies the initial QP used for rate control. Client must set NV_ENC_CONFIG::enableInitialRCQP to 1. */ + uint32_t temporallayerIdxMask; /**< [in]: Specifies the temporal layers (as a bitmask) whose QPs have changed. Valid max bitmask is [2^NV_ENC_CAPS_NUM_MAX_TEMPORAL_LAYERS - 1] */ + uint8_t temporalLayerQP[8]; /**< [in]: Specifies the temporal layer QPs used for rate control. Temporal layer index is used as as the array index */ + uint8_t targetQuality; /**< [in]: Target CQ (Constant Quality) level for VBR mode (range 0-51 with 0-automatic) */ + uint8_t targetQualityLSB; /**< [in]: Fractional part of target quality (as 8.8 fixed point format) */ + uint16_t lookaheadDepth; /**< [in]: Maximum depth of lookahead with range 0-32 (only used if enableLookahead=1) */ + uint32_t reserved1; + NV_ENC_QP_MAP_MODE qpMapMode; /**< [in]: This flag is used to interpret values in array pecified by NV_ENC_PIC_PARAMS::qpDeltaMap. + Set this to NV_ENC_QP_MAP_EMPHASIS to treat values specified by NV_ENC_PIC_PARAMS::qpDeltaMap as Emphasis level Map. + Emphasis Level can be assigned any value specified in enum NV_ENC_EMPHASIS_MAP_LEVEL. + Emphasis Level Map is used to specify regions to be encoded at varying levels of quality. + The hardware encoder adjusts the quantization within the image as per the provided emphasis map, + by adjusting the quantization parameter (QP) assigned to each macroblock. This adjustment is commonly called “Delta QP”. + The adjustment depends on the absolute QP decided by the rate control algorithm, and is applied after the rate control has decided each macroblock’s QP. + Since the Delta QP overrides rate control, enabling emphasis level map may violate bitrate and VBV buffersize constraints. + Emphasis level map is useful in situations when client has a priori knowledge of the image complexity (e.g. via use of NVFBC's Classification feature) and encoding those high-complexity areas at higher quality (lower QP) is important, even at the possible cost of violating bitrate/VBV buffersize constraints + This feature is not supported when AQ( Spatial/Temporal) is enabled. + This feature is only supported for H264 codec currently. + + Set this to NV_ENC_QP_MAP_DELTA to treat values specified by NV_ENC_PIC_PARAMS::qpDeltaMap as QPDelta. This specify QP modifier to be applied on top of the QP chosen by rate control + + Set this to NV_ENC_QP_MAP_DISABLED to ignore NV_ENC_PIC_PARAMS::qpDeltaMap values. In this case, qpDeltaMap should be set to NULL. + + Other values are reserved for future use.*/ + uint32_t reserved[7]; + } NV_ENC_RC_PARAMS; + +/** macro for constructing the version field of ::_NV_ENC_RC_PARAMS */ +#define NV_ENC_RC_PARAMS_VER NVENCAPI_STRUCT_VERSION(1) + + + +/** + * \struct _NV_ENC_CONFIG_H264_VUI_PARAMETERS + * H264 Video Usability Info parameters + */ +typedef struct _NV_ENC_CONFIG_H264_VUI_PARAMETERS +{ + uint32_t overscanInfoPresentFlag; /**< [in]: if set to 1 , it specifies that the overscanInfo is present */ + uint32_t overscanInfo; /**< [in]: Specifies the overscan info(as defined in Annex E of the ITU-T Specification). */ + uint32_t videoSignalTypePresentFlag; /**< [in]: If set to 1, it specifies that the videoFormat, videoFullRangeFlag and colourDescriptionPresentFlag are present. */ + uint32_t videoFormat; /**< [in]: Specifies the source video format(as defined in Annex E of the ITU-T Specification).*/ + uint32_t videoFullRangeFlag; /**< [in]: Specifies the output range of the luma and chroma samples(as defined in Annex E of the ITU-T Specification). */ + uint32_t colourDescriptionPresentFlag; /**< [in]: If set to 1, it specifies that the colourPrimaries, transferCharacteristics and colourMatrix are present. */ + uint32_t colourPrimaries; /**< [in]: Specifies color primaries for converting to RGB(as defined in Annex E of the ITU-T Specification) */ + uint32_t transferCharacteristics; /**< [in]: Specifies the opto-electronic transfer characteristics to use (as defined in Annex E of the ITU-T Specification) */ + uint32_t colourMatrix; /**< [in]: Specifies the matrix coefficients used in deriving the luma and chroma from the RGB primaries (as defined in Annex E of the ITU-T Specification). */ + uint32_t chromaSampleLocationFlag; /**< [in]: if set to 1 , it specifies that the chromaSampleLocationTop and chromaSampleLocationBot are present.*/ + uint32_t chromaSampleLocationTop; /**< [in]: Specifies the chroma sample location for top field(as defined in Annex E of the ITU-T Specification) */ + uint32_t chromaSampleLocationBot; /**< [in]: Specifies the chroma sample location for bottom field(as defined in Annex E of the ITU-T Specification) */ + uint32_t bitstreamRestrictionFlag; /**< [in]: if set to 1, it specifies the bitstream restriction parameters are present in the bitstream.*/ + uint32_t reserved[15]; +}NV_ENC_CONFIG_H264_VUI_PARAMETERS; + +typedef NV_ENC_CONFIG_H264_VUI_PARAMETERS NV_ENC_CONFIG_HEVC_VUI_PARAMETERS; + +/** + * \struct _NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE + * External motion vector hint counts per block type. + * H264 supports multiple hint while HEVC supports one hint for each valid candidate. + */ +typedef struct _NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE +{ + uint32_t numCandsPerBlk16x16 : 4; /**< [in]: Supported for H264,HEVC.It Specifies the number of candidates per 16x16 block. */ + uint32_t numCandsPerBlk16x8 : 4; /**< [in]: Supported for H264 only.Specifies the number of candidates per 16x8 block. */ + uint32_t numCandsPerBlk8x16 : 4; /**< [in]: Supported for H264 only.Specifies the number of candidates per 8x16 block. */ + uint32_t numCandsPerBlk8x8 : 4; /**< [in]: Supported for H264,HEVC.Specifies the number of candidates per 8x8 block. */ + uint32_t reserved : 16; /**< [in]: Reserved for padding. */ + uint32_t reserved1[3]; /**< [in]: Reserved for future use. */ +} NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE; + + +/** + * \struct _NVENC_EXTERNAL_ME_HINT + * External Motion Vector hint structure. + */ +typedef struct _NVENC_EXTERNAL_ME_HINT +{ + int32_t mvx : 12; /**< [in]: Specifies the x component of integer pixel MV (relative to current MB) S12.0. */ + int32_t mvy : 10; /**< [in]: Specifies the y component of integer pixel MV (relative to current MB) S10.0 .*/ + int32_t refidx : 5; /**< [in]: Specifies the reference index (31=invalid). Current we support only 1 reference frame per direction for external hints, so \p refidx must be 0. */ + int32_t dir : 1; /**< [in]: Specifies the direction of motion estimation . 0=L0 1=L1.*/ + int32_t partType : 2; /**< [in]: Specifies the block partition type.0=16x16 1=16x8 2=8x16 3=8x8 (blocks in partition must be consecutive).*/ + int32_t lastofPart : 1; /**< [in]: Set to 1 for the last MV of (sub) partition */ + int32_t lastOfMB : 1; /**< [in]: Set to 1 for the last MV of macroblock. */ +} NVENC_EXTERNAL_ME_HINT; + + +/** + * \struct _NV_ENC_CONFIG_H264 + * H264 encoder configuration parameters + */ +typedef struct _NV_ENC_CONFIG_H264 +{ + uint32_t enableTemporalSVC :1; /**< [in]: Set to 1 to enable SVC temporal*/ + uint32_t enableStereoMVC :1; /**< [in]: Set to 1 to enable stereo MVC*/ + uint32_t hierarchicalPFrames :1; /**< [in]: Set to 1 to enable hierarchical PFrames */ + uint32_t hierarchicalBFrames :1; /**< [in]: Set to 1 to enable hierarchical BFrames */ + uint32_t outputBufferingPeriodSEI :1; /**< [in]: Set to 1 to write SEI buffering period syntax in the bitstream */ + uint32_t outputPictureTimingSEI :1; /**< [in]: Set to 1 to write SEI picture timing syntax in the bitstream. When set for following rateControlMode : NV_ENC_PARAMS_RC_CBR, NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ, + NV_ENC_PARAMS_RC_CBR_HQ, filler data is inserted if needed to achieve hrd bitrate */ + uint32_t outputAUD :1; /**< [in]: Set to 1 to write access unit delimiter syntax in bitstream */ + uint32_t disableSPSPPS :1; /**< [in]: Set to 1 to disable writing of Sequence and Picture parameter info in bitstream */ + uint32_t outputFramePackingSEI :1; /**< [in]: Set to 1 to enable writing of frame packing arrangement SEI messages to bitstream */ + uint32_t outputRecoveryPointSEI :1; /**< [in]: Set to 1 to enable writing of recovery point SEI message */ + uint32_t enableIntraRefresh :1; /**< [in]: Set to 1 to enable gradual decoder refresh or intra refresh. If the GOP structure uses B frames this will be ignored */ + uint32_t enableConstrainedEncoding :1; /**< [in]: Set this to 1 to enable constrainedFrame encoding where each slice in the constarined picture is independent of other slices + Check support for constrained encoding using ::NV_ENC_CAPS_SUPPORT_CONSTRAINED_ENCODING caps. */ + uint32_t repeatSPSPPS :1; /**< [in]: Set to 1 to enable writing of Sequence and Picture parameter for every IDR frame */ + uint32_t enableVFR :1; /**< [in]: Set to 1 to enable variable frame rate. */ + uint32_t enableLTR :1; /**< [in]: Set to 1 to enable LTR (Long Term Reference) frame support. LTR can be used in two modes: "LTR Trust" mode and "LTR Per Picture" mode. + LTR Trust mode: In this mode, ltrNumFrames pictures after IDR are automatically marked as LTR. This mode is enabled by setting ltrTrustMode = 1. + Use of LTR Trust mode is strongly discouraged as this mode may be deprecated in future. + LTR Per Picture mode: In this mode, client can control whether the current picture should be marked as LTR. Enable this mode by setting + ltrTrustMode = 0 and ltrMarkFrame = 1 for the picture to be marked as LTR. This is the preferred mode + for using LTR. + Note that LTRs are not supported if encoding session is configured with B-frames */ + uint32_t qpPrimeYZeroTransformBypassFlag :1; /**< [in]: To enable lossless encode set this to 1, set QP to 0 and RC_mode to NV_ENC_PARAMS_RC_CONSTQP and profile to HIGH_444_PREDICTIVE_PROFILE. + Check support for lossless encoding using ::NV_ENC_CAPS_SUPPORT_LOSSLESS_ENCODE caps. */ + uint32_t useConstrainedIntraPred :1; /**< [in]: Set 1 to enable constrained intra prediction. */ + uint32_t reservedBitFields :15; /**< [in]: Reserved bitfields and must be set to 0 */ + uint32_t level; /**< [in]: Specifies the encoding level. Client is recommended to set this to NV_ENC_LEVEL_AUTOSELECT in order to enable the NvEncodeAPI interface to select the correct level. */ + uint32_t idrPeriod; /**< [in]: Specifies the IDR interval. If not set, this is made equal to gopLength in NV_ENC_CONFIG.Low latency application client can set IDR interval to NVENC_INFINITE_GOPLENGTH so that IDR frames are not inserted automatically. */ + uint32_t separateColourPlaneFlag; /**< [in]: Set to 1 to enable 4:4:4 separate colour planes */ + uint32_t disableDeblockingFilterIDC; /**< [in]: Specifies the deblocking filter mode. Permissible value range: [0,2] */ + uint32_t numTemporalLayers; /**< [in]: Specifies max temporal layers to be used for hierarchical coding. Valid value range is [1,::NV_ENC_CAPS_NUM_MAX_TEMPORAL_LAYERS] */ + uint32_t spsId; /**< [in]: Specifies the SPS id of the sequence header */ + uint32_t ppsId; /**< [in]: Specifies the PPS id of the picture header */ + NV_ENC_H264_ADAPTIVE_TRANSFORM_MODE adaptiveTransformMode; /**< [in]: Specifies the AdaptiveTransform Mode. Check support for AdaptiveTransform mode using ::NV_ENC_CAPS_SUPPORT_ADAPTIVE_TRANSFORM caps. */ + NV_ENC_H264_FMO_MODE fmoMode; /**< [in]: Specified the FMO Mode. Check support for FMO using ::NV_ENC_CAPS_SUPPORT_FMO caps. */ + NV_ENC_H264_BDIRECT_MODE bdirectMode; /**< [in]: Specifies the BDirect mode. Check support for BDirect mode using ::NV_ENC_CAPS_SUPPORT_BDIRECT_MODE caps.*/ + NV_ENC_H264_ENTROPY_CODING_MODE entropyCodingMode; /**< [in]: Specifies the entropy coding mode. Check support for CABAC mode using ::NV_ENC_CAPS_SUPPORT_CABAC caps. */ + NV_ENC_STEREO_PACKING_MODE stereoMode; /**< [in]: Specifies the stereo frame packing mode which is to be signalled in frame packing arrangement SEI */ + uint32_t intraRefreshPeriod; /**< [in]: Specifies the interval between successive intra refresh if enableIntrarefresh is set. Requires enableIntraRefresh to be set. + Will be disabled if NV_ENC_CONFIG::gopLength is not set to NVENC_INFINITE_GOPLENGTH. */ + uint32_t intraRefreshCnt; /**< [in]: Specifies the length of intra refresh in number of frames for periodic intra refresh. This value should be smaller than intraRefreshPeriod */ + uint32_t maxNumRefFrames; /**< [in]: Specifies the DPB size used for encoding. Setting it to 0 will let driver use the default dpb size. + The low latency application which wants to invalidate reference frame as an error resilience tool + is recommended to use a large DPB size so that the encoder can keep old reference frames which can be used if recent + frames are invalidated. */ + uint32_t sliceMode; /**< [in]: This parameter in conjunction with sliceModeData specifies the way in which the picture is divided into slices + sliceMode = 0 MB based slices, sliceMode = 1 Byte based slices, sliceMode = 2 MB row based slices, sliceMode = 3 numSlices in Picture. + When forceIntraRefreshWithFrameCnt is set it will have priority over sliceMode setting + When sliceMode == 0 and sliceModeData == 0 whole picture will be coded with one slice */ + uint32_t sliceModeData; /**< [in]: Specifies the parameter needed for sliceMode. For: + sliceMode = 0, sliceModeData specifies # of MBs in each slice (except last slice) + sliceMode = 1, sliceModeData specifies maximum # of bytes in each slice (except last slice) + sliceMode = 2, sliceModeData specifies # of MB rows in each slice (except last slice) + sliceMode = 3, sliceModeData specifies number of slices in the picture. Driver will divide picture into slices optimally */ + NV_ENC_CONFIG_H264_VUI_PARAMETERS h264VUIParameters; /**< [in]: Specifies the H264 video usability info pamameters */ + uint32_t ltrNumFrames; /**< [in]: Specifies the number of LTR frames. This parameter has different meaning in two LTR modes. + In "LTR Trust" mode (ltrTrustMode = 1), encoder will mark the first ltrNumFrames base layer reference frames within each IDR interval as LTR. + In "LTR Per Picture" mode (ltrTrustMode = 0 and ltrMarkFrame = 1), ltrNumFrames specifies maximum number of LTR frames in DPB. */ + uint32_t ltrTrustMode; /**< [in]: Specifies the LTR operating mode. See comments near NV_ENC_CONFIG_H264::enableLTR for description of the two modes. + Set to 1 to use "LTR Trust" mode of LTR operation. Clients are discouraged to use "LTR Trust" mode as this mode may + be deprecated in future releases. + Set to 0 when using "LTR Per Picture" mode of LTR operation. */ + uint32_t chromaFormatIDC; /**< [in]: Specifies the chroma format. Should be set to 1 for yuv420 input, 3 for yuv444 input. + Check support for YUV444 encoding using ::NV_ENC_CAPS_SUPPORT_YUV444_ENCODE caps.*/ + uint32_t maxTemporalLayers; /**< [in]: Specifies the max temporal layer used for hierarchical coding. */ + NV_ENC_BFRAME_REF_MODE useBFramesAsRef; /**< [in]: Specifies the B-Frame as reference mode. Check support for useBFramesAsRef mode using ::NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE caps.*/ + uint32_t reserved1[269]; /**< [in]: Reserved and must be set to 0 */ + void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_CONFIG_H264; + +/** + * \struct _NV_ENC_CONFIG_HEVC + * HEVC encoder configuration parameters to be set during initialization. + */ +typedef struct _NV_ENC_CONFIG_HEVC +{ + uint32_t level; /**< [in]: Specifies the level of the encoded bitstream.*/ + uint32_t tier; /**< [in]: Specifies the level tier of the encoded bitstream.*/ + NV_ENC_HEVC_CUSIZE minCUSize; /**< [in]: Specifies the minimum size of luma coding unit.*/ + NV_ENC_HEVC_CUSIZE maxCUSize; /**< [in]: Specifies the maximum size of luma coding unit. Currently NVENC SDK only supports maxCUSize equal to NV_ENC_HEVC_CUSIZE_32x32.*/ + uint32_t useConstrainedIntraPred :1; /**< [in]: Set 1 to enable constrained intra prediction. */ + uint32_t disableDeblockAcrossSliceBoundary :1; /**< [in]: Set 1 to disable in loop filtering across slice boundary.*/ + uint32_t outputBufferingPeriodSEI :1; /**< [in]: Set 1 to write SEI buffering period syntax in the bitstream */ + uint32_t outputPictureTimingSEI :1; /**< [in]: Set 1 to write SEI picture timing syntax in the bitstream */ + uint32_t outputAUD :1; /**< [in]: Set 1 to write Access Unit Delimiter syntax. */ + uint32_t enableLTR :1; /**< [in]: Set to 1 to enable LTR (Long Term Reference) frame support. LTR can be used in two modes: "LTR Trust" mode and "LTR Per Picture" mode. + LTR Trust mode: In this mode, ltrNumFrames pictures after IDR are automatically marked as LTR. This mode is enabled by setting ltrTrustMode = 1. + Use of LTR Trust mode is strongly discouraged as this mode may be deprecated in future releases. + LTR Per Picture mode: In this mode, client can control whether the current picture should be marked as LTR. Enable this mode by setting + ltrTrustMode = 0 and ltrMarkFrame = 1 for the picture to be marked as LTR. This is the preferred mode + for using LTR. + Note that LTRs are not supported if encoding session is configured with B-frames */ + uint32_t disableSPSPPS :1; /**< [in]: Set 1 to disable VPS,SPS and PPS signalling in the bitstream. */ + uint32_t repeatSPSPPS :1; /**< [in]: Set 1 to output VPS,SPS and PPS for every IDR frame.*/ + uint32_t enableIntraRefresh :1; /**< [in]: Set 1 to enable gradual decoder refresh or intra refresh. If the GOP structure uses B frames this will be ignored */ + uint32_t chromaFormatIDC :2; /**< [in]: Specifies the chroma format. Should be set to 1 for yuv420 input, 3 for yuv444 input.*/ + uint32_t pixelBitDepthMinus8 :3; /**< [in]: Specifies pixel bit depth minus 8. Should be set to 0 for 8 bit input, 2 for 10 bit input.*/ + uint32_t reserved :18; /**< [in]: Reserved bitfields.*/ + uint32_t idrPeriod; /**< [in]: Specifies the IDR interval. If not set, this is made equal to gopLength in NV_ENC_CONFIG.Low latency application client can set IDR interval to NVENC_INFINITE_GOPLENGTH so that IDR frames are not inserted automatically. */ + uint32_t intraRefreshPeriod; /**< [in]: Specifies the interval between successive intra refresh if enableIntrarefresh is set. Requires enableIntraRefresh to be set. + Will be disabled if NV_ENC_CONFIG::gopLength is not set to NVENC_INFINITE_GOPLENGTH. */ + uint32_t intraRefreshCnt; /**< [in]: Specifies the length of intra refresh in number of frames for periodic intra refresh. This value should be smaller than intraRefreshPeriod */ + uint32_t maxNumRefFramesInDPB; /**< [in]: Specifies the maximum number of references frames in the DPB.*/ + uint32_t ltrNumFrames; /**< [in]: This parameter has different meaning in two LTR modes. + In "LTR Trust" mode (ltrTrustMode = 1), encoder will mark the first ltrNumFrames base layer reference frames within each IDR interval as LTR. + In "LTR Per Picture" mode (ltrTrustMode = 0 and ltrMarkFrame = 1), ltrNumFrames specifies maximum number of LTR frames in DPB. */ + uint32_t vpsId; /**< [in]: Specifies the VPS id of the video parameter set */ + uint32_t spsId; /**< [in]: Specifies the SPS id of the sequence header */ + uint32_t ppsId; /**< [in]: Specifies the PPS id of the picture header */ + uint32_t sliceMode; /**< [in]: This parameter in conjunction with sliceModeData specifies the way in which the picture is divided into slices + sliceMode = 0 CTU based slices, sliceMode = 1 Byte based slices, sliceMode = 2 CTU row based slices, sliceMode = 3, numSlices in Picture + When sliceMode == 0 and sliceModeData == 0 whole picture will be coded with one slice */ + uint32_t sliceModeData; /**< [in]: Specifies the parameter needed for sliceMode. For: + sliceMode = 0, sliceModeData specifies # of CTUs in each slice (except last slice) + sliceMode = 1, sliceModeData specifies maximum # of bytes in each slice (except last slice) + sliceMode = 2, sliceModeData specifies # of CTU rows in each slice (except last slice) + sliceMode = 3, sliceModeData specifies number of slices in the picture. Driver will divide picture into slices optimally */ + uint32_t maxTemporalLayersMinus1; /**< [in]: Specifies the max temporal layer used for hierarchical coding. */ + NV_ENC_CONFIG_HEVC_VUI_PARAMETERS hevcVUIParameters; /**< [in]: Specifies the HEVC video usability info pamameters */ + uint32_t ltrTrustMode; /**< [in]: Specifies the LTR operating mode. See comments near NV_ENC_CONFIG_HEVC::enableLTR for description of the two modes. + Set to 1 to use "LTR Trust" mode of LTR operation. Clients are discouraged to use "LTR Trust" mode as this mode may + be deprecated in future releases. + Set to 0 when using "LTR Per Picture" mode of LTR operation. */ + uint32_t reserved1[217]; /**< [in]: Reserved and must be set to 0.*/ + void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_CONFIG_HEVC; + +/** + * \struct _NV_ENC_CONFIG_H264_MEONLY + * H264 encoder configuration parameters for ME only Mode + * + */ +typedef struct _NV_ENC_CONFIG_H264_MEONLY +{ + uint32_t disablePartition16x16 :1; /**< [in]: Disable MotionEstimation on 16x16 blocks*/ + uint32_t disablePartition8x16 :1; /**< [in]: Disable MotionEstimation on 8x16 blocks*/ + uint32_t disablePartition16x8 :1; /**< [in]: Disable MotionEstimation on 16x8 blocks*/ + uint32_t disablePartition8x8 :1; /**< [in]: Disable MotionEstimation on 8x8 blocks*/ + uint32_t disableIntraSearch :1; /**< [in]: Disable Intra search during MotionEstimation*/ + uint32_t bStereoEnable :1; /**< [in]: Enable Stereo Mode for Motion Estimation where each view is independently executed*/ + uint32_t reserved :26; /**< [in]: Reserved and must be set to 0 */ + uint32_t reserved1 [255]; /**< [in]: Reserved and must be set to 0 */ + void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_CONFIG_H264_MEONLY; + + +/** + * \struct _NV_ENC_CONFIG_HEVC_MEONLY + * HEVC encoder configuration parameters for ME only Mode + * + */ +typedef struct _NV_ENC_CONFIG_HEVC_MEONLY +{ + uint32_t reserved [256]; /**< [in]: Reserved and must be set to 0 */ + void* reserved1[64]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_CONFIG_HEVC_MEONLY; + +/** + * \struct _NV_ENC_CODEC_CONFIG + * Codec-specific encoder configuration parameters to be set during initialization. + */ +typedef union _NV_ENC_CODEC_CONFIG +{ + NV_ENC_CONFIG_H264 h264Config; /**< [in]: Specifies the H.264-specific encoder configuration. */ + NV_ENC_CONFIG_HEVC hevcConfig; /**< [in]: Specifies the HEVC-specific encoder configuration. */ + NV_ENC_CONFIG_H264_MEONLY h264MeOnlyConfig; /**< [in]: Specifies the H.264-specific ME only encoder configuration. */ + NV_ENC_CONFIG_HEVC_MEONLY hevcMeOnlyConfig; /**< [in]: Specifies the HEVC-specific ME only encoder configuration. */ + uint32_t reserved[320]; /**< [in]: Reserved and must be set to 0 */ +} NV_ENC_CODEC_CONFIG; + + +/** + * \struct _NV_ENC_CONFIG + * Encoder configuration parameters to be set during initialization. + */ +typedef struct _NV_ENC_CONFIG +{ + uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_CONFIG_VER. */ + GUID profileGUID; /**< [in]: Specifies the codec profile guid. If client specifies \p NV_ENC_CODEC_PROFILE_AUTOSELECT_GUID the NvEncodeAPI interface will select the appropriate codec profile. */ + uint32_t gopLength; /**< [in]: Specifies the number of pictures in one GOP. Low latency application client can set goplength to NVENC_INFINITE_GOPLENGTH so that keyframes are not inserted automatically. */ + int32_t frameIntervalP; /**< [in]: Specifies the GOP pattern as follows: \p frameIntervalP = 0: I, 1: IPP, 2: IBP, 3: IBBP If goplength is set to NVENC_INFINITE_GOPLENGTH \p frameIntervalP should be set to 1. */ + uint32_t monoChromeEncoding; /**< [in]: Set this to 1 to enable monochrome encoding for this session. */ + NV_ENC_PARAMS_FRAME_FIELD_MODE frameFieldMode; /**< [in]: Specifies the frame/field mode. + Check support for field encoding using ::NV_ENC_CAPS_SUPPORT_FIELD_ENCODING caps. + Using a frameFieldMode other than NV_ENC_PARAMS_FRAME_FIELD_MODE_FRAME for RGB input is not supported. */ + NV_ENC_MV_PRECISION mvPrecision; /**< [in]: Specifies the desired motion vector prediction precision. */ + NV_ENC_RC_PARAMS rcParams; /**< [in]: Specifies the rate control parameters for the current encoding session. */ + NV_ENC_CODEC_CONFIG encodeCodecConfig; /**< [in]: Specifies the codec specific config parameters through this union. */ + uint32_t reserved [278]; /**< [in]: Reserved and must be set to 0 */ + void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_CONFIG; + +/** macro for constructing the version field of ::_NV_ENC_CONFIG */ +#define NV_ENC_CONFIG_VER (NVENCAPI_STRUCT_VERSION(7) | ( 1<<31 )) + + +/** + * \struct _NV_ENC_INITIALIZE_PARAMS + * Encode Session Initialization parameters. + */ +typedef struct _NV_ENC_INITIALIZE_PARAMS +{ + uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_INITIALIZE_PARAMS_VER. */ + GUID encodeGUID; /**< [in]: Specifies the Encode GUID for which the encoder is being created. ::NvEncInitializeEncoder() API will fail if this is not set, or set to unsupported value. */ + GUID presetGUID; /**< [in]: Specifies the preset for encoding. If the preset GUID is set then , the preset configuration will be applied before any other parameter. */ + uint32_t encodeWidth; /**< [in]: Specifies the encode width. If not set ::NvEncInitializeEncoder() API will fail. */ + uint32_t encodeHeight; /**< [in]: Specifies the encode height. If not set ::NvEncInitializeEncoder() API will fail. */ + uint32_t darWidth; /**< [in]: Specifies the display aspect ratio Width. */ + uint32_t darHeight; /**< [in]: Specifies the display aspect ratio height. */ + uint32_t frameRateNum; /**< [in]: Specifies the numerator for frame rate used for encoding in frames per second ( Frame rate = frameRateNum / frameRateDen ). */ + uint32_t frameRateDen; /**< [in]: Specifies the denominator for frame rate used for encoding in frames per second ( Frame rate = frameRateNum / frameRateDen ). */ + uint32_t enableEncodeAsync; /**< [in]: Set this to 1 to enable asynchronous mode and is expected to use events to get picture completion notification. */ + uint32_t enablePTD; /**< [in]: Set this to 1 to enable the Picture Type Decision is be taken by the NvEncodeAPI interface. */ + uint32_t reportSliceOffsets :1; /**< [in]: Set this to 1 to enable reporting slice offsets in ::_NV_ENC_LOCK_BITSTREAM. NV_ENC_INITIALIZE_PARAMS::enableEncodeAsync must be set to 0 to use this feature. Client must set this to 0 if NV_ENC_CONFIG_H264::sliceMode is 1 on Kepler GPUs */ + uint32_t enableSubFrameWrite :1; /**< [in]: Set this to 1 to write out available bitstream to memory at subframe intervals */ + uint32_t enableExternalMEHints :1; /**< [in]: Set to 1 to enable external ME hints for the current frame. For NV_ENC_INITIALIZE_PARAMS::enablePTD=1 with B frames, programming L1 hints is optional for B frames since Client doesn't know internal GOP structure. + NV_ENC_PIC_PARAMS::meHintRefPicDist should preferably be set with enablePTD=1. */ + uint32_t enableMEOnlyMode :1; /**< [in]: Set to 1 to enable ME Only Mode .*/ + uint32_t enableWeightedPrediction :1; /**< [in]: Set this to 1 to enable weighted prediction. Not supported if encode session is configured for B-Frames( 'frameIntervalP' in NV_ENC_CONFIG is greater than 1).*/ + uint32_t reservedBitFields :27; /**< [in]: Reserved bitfields and must be set to 0 */ + uint32_t privDataSize; /**< [in]: Reserved private data buffer size and must be set to 0 */ + void* privData; /**< [in]: Reserved private data buffer and must be set to NULL */ + NV_ENC_CONFIG* encodeConfig; /**< [in]: Specifies the advanced codec specific structure. If client has sent a valid codec config structure, it will override parameters set by the NV_ENC_INITIALIZE_PARAMS::presetGUID parameter. If set to NULL the NvEncodeAPI interface will use the NV_ENC_INITIALIZE_PARAMS::presetGUID to set the codec specific parameters. + Client can also optionally query the NvEncodeAPI interface to get codec specific parameters for a presetGUID using ::NvEncGetEncodePresetConfig() API. It can then modify (if required) some of the codec config parameters and send down a custom config structure as part of ::_NV_ENC_INITIALIZE_PARAMS. + Even in this case client is recommended to pass the same preset guid it has used in ::NvEncGetEncodePresetConfig() API to query the config structure; as NV_ENC_INITIALIZE_PARAMS::presetGUID. This will not override the custom config structure but will be used to determine other Encoder HW specific parameters not exposed in the API. */ + uint32_t maxEncodeWidth; /**< [in]: Maximum encode width to be used for current Encode session. + Client should allocate output buffers according to this dimension for dynamic resolution change. If set to 0, Encoder will not allow dynamic resolution change. */ + uint32_t maxEncodeHeight; /**< [in]: Maximum encode height to be allowed for current Encode session. + Client should allocate output buffers according to this dimension for dynamic resolution change. If set to 0, Encode will not allow dynamic resolution change. */ + NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE maxMEHintCountsPerBlock[2]; /**< [in]: If Client wants to pass external motion vectors in NV_ENC_PIC_PARAMS::meExternalHints buffer it must specify the maximum number of hint candidates per block per direction for the encode session. + The NV_ENC_INITIALIZE_PARAMS::maxMEHintCountsPerBlock[0] is for L0 predictors and NV_ENC_INITIALIZE_PARAMS::maxMEHintCountsPerBlock[1] is for L1 predictors. + This client must also set NV_ENC_INITIALIZE_PARAMS::enableExternalMEHints to 1. */ + uint32_t reserved [289]; /**< [in]: Reserved and must be set to 0 */ + void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_INITIALIZE_PARAMS; + +/** macro for constructing the version field of ::_NV_ENC_INITIALIZE_PARAMS */ +#define NV_ENC_INITIALIZE_PARAMS_VER (NVENCAPI_STRUCT_VERSION(5) | ( 1<<31 )) + + +/** + * \struct _NV_ENC_RECONFIGURE_PARAMS + * Encode Session Reconfigured parameters. + */ +typedef struct _NV_ENC_RECONFIGURE_PARAMS +{ + uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_RECONFIGURE_PARAMS_VER. */ + NV_ENC_INITIALIZE_PARAMS reInitEncodeParams; /**< [in]: Encoder session re-initialization parameters. + If reInitEncodeParams.encodeConfig is NULL and + reInitEncodeParams.presetGUID is the same as the preset + GUID specified on the call to NvEncInitializeEncoder(), + EncodeAPI will continue to use the existing encode + configuration. + If reInitEncodeParams.encodeConfig is NULL and + reInitEncodeParams.presetGUID is different from the preset + GUID specified on the call to NvEncInitializeEncoder(), + EncodeAPI will try to use the default configuration for + the preset specified by reInitEncodeParams.presetGUID. + In this case, reconfiguration may fail if the new + configuration is incompatible with the existing + configuration (e.g. the new configuration results in + a change in the GOP structure). */ + uint32_t resetEncoder :1; /**< [in]: This resets the rate control states and other internal encoder states. This should be used only with an IDR frame. + If NV_ENC_INITIALIZE_PARAMS::enablePTD is set to 1, encoder will force the frame type to IDR */ + uint32_t forceIDR :1; /**< [in]: Encode the current picture as an IDR picture. This flag is only valid when Picture type decision is taken by the Encoder + [_NV_ENC_INITIALIZE_PARAMS::enablePTD == 1]. */ + uint32_t reserved :30; + +}NV_ENC_RECONFIGURE_PARAMS; + +/** macro for constructing the version field of ::_NV_ENC_RECONFIGURE_PARAMS */ +#define NV_ENC_RECONFIGURE_PARAMS_VER (NVENCAPI_STRUCT_VERSION(1) | ( 1<<31 )) + +/** + * \struct _NV_ENC_PRESET_CONFIG + * Encoder preset config + */ +typedef struct _NV_ENC_PRESET_CONFIG +{ + uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_PRESET_CONFIG_VER. */ + NV_ENC_CONFIG presetCfg; /**< [out]: preset config returned by the Nvidia Video Encoder interface. */ + uint32_t reserved1[255]; /**< [in]: Reserved and must be set to 0 */ + void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */ +}NV_ENC_PRESET_CONFIG; + +/** macro for constructing the version field of ::_NV_ENC_PRESET_CONFIG */ +#define NV_ENC_PRESET_CONFIG_VER (NVENCAPI_STRUCT_VERSION(4) | ( 1<<31 )) + + +/** + * \struct _NV_ENC_SEI_PAYLOAD + * User SEI message + */ +typedef struct _NV_ENC_SEI_PAYLOAD +{ + uint32_t payloadSize; /**< [in] SEI payload size in bytes. SEI payload must be byte aligned, as described in Annex D */ + uint32_t payloadType; /**< [in] SEI payload types and syntax can be found in Annex D of the H.264 Specification. */ + uint8_t *payload; /**< [in] pointer to user data */ +} NV_ENC_SEI_PAYLOAD; + +#define NV_ENC_H264_SEI_PAYLOAD NV_ENC_SEI_PAYLOAD + +/** + * \struct _NV_ENC_PIC_PARAMS_H264 + * H264 specific enc pic params. sent on a per frame basis. + */ +typedef struct _NV_ENC_PIC_PARAMS_H264 +{ + uint32_t displayPOCSyntax; /**< [in]: Specifies the display POC syntax This is required to be set if client is handling the picture type decision. */ + uint32_t reserved3; /**< [in]: Reserved and must be set to 0 */ + uint32_t refPicFlag; /**< [in]: Set to 1 for a reference picture. This is ignored if NV_ENC_INITIALIZE_PARAMS::enablePTD is set to 1. */ + uint32_t colourPlaneId; /**< [in]: Specifies the colour plane ID associated with the current input. */ + uint32_t forceIntraRefreshWithFrameCnt; /**< [in]: Forces an intra refresh with duration equal to intraRefreshFrameCnt. + When outputRecoveryPointSEI is set this is value is used for recovery_frame_cnt in recovery point SEI message + forceIntraRefreshWithFrameCnt cannot be used if B frames are used in the GOP structure specified */ + uint32_t constrainedFrame :1; /**< [in]: Set to 1 if client wants to encode this frame with each slice completely independent of other slices in the frame. + NV_ENC_INITIALIZE_PARAMS::enableConstrainedEncoding should be set to 1 */ + uint32_t sliceModeDataUpdate :1; /**< [in]: Set to 1 if client wants to change the sliceModeData field to specify new sliceSize Parameter + When forceIntraRefreshWithFrameCnt is set it will have priority over sliceMode setting */ + uint32_t ltrMarkFrame :1; /**< [in]: Set to 1 if client wants to mark this frame as LTR */ + uint32_t ltrUseFrames :1; /**< [in]: Set to 1 if client allows encoding this frame using the LTR frames specified in ltrFrameBitmap */ + uint32_t reservedBitFields :28; /**< [in]: Reserved bit fields and must be set to 0 */ + uint8_t* sliceTypeData; /**< [in]: Deprecated. */ + uint32_t sliceTypeArrayCnt; /**< [in]: Deprecated. */ + uint32_t seiPayloadArrayCnt; /**< [in]: Specifies the number of elements allocated in seiPayloadArray array. */ + NV_ENC_SEI_PAYLOAD* seiPayloadArray; /**< [in]: Array of SEI payloads which will be inserted for this frame. */ + uint32_t sliceMode; /**< [in]: This parameter in conjunction with sliceModeData specifies the way in which the picture is divided into slices + sliceMode = 0 MB based slices, sliceMode = 1 Byte based slices, sliceMode = 2 MB row based slices, sliceMode = 3, numSlices in Picture + When forceIntraRefreshWithFrameCnt is set it will have priority over sliceMode setting + When sliceMode == 0 and sliceModeData == 0 whole picture will be coded with one slice */ + uint32_t sliceModeData; /**< [in]: Specifies the parameter needed for sliceMode. For: + sliceMode = 0, sliceModeData specifies # of MBs in each slice (except last slice) + sliceMode = 1, sliceModeData specifies maximum # of bytes in each slice (except last slice) + sliceMode = 2, sliceModeData specifies # of MB rows in each slice (except last slice) + sliceMode = 3, sliceModeData specifies number of slices in the picture. Driver will divide picture into slices optimally */ + uint32_t ltrMarkFrameIdx; /**< [in]: Specifies the long term referenceframe index to use for marking this frame as LTR.*/ + uint32_t ltrUseFrameBitmap; /**< [in]: Specifies the the associated bitmap of LTR frame indices to use when encoding this frame. */ + uint32_t ltrUsageMode; /**< [in]: Not supported. Reserved for future use and must be set to 0. */ + uint32_t reserved [243]; /**< [in]: Reserved and must be set to 0. */ + void* reserved2[62]; /**< [in]: Reserved and must be set to NULL. */ +} NV_ENC_PIC_PARAMS_H264; + +/** + * \struct _NV_ENC_PIC_PARAMS_HEVC + * HEVC specific enc pic params. sent on a per frame basis. + */ +typedef struct _NV_ENC_PIC_PARAMS_HEVC +{ + uint32_t displayPOCSyntax; /**< [in]: Specifies the display POC syntax This is required to be set if client is handling the picture type decision. */ + uint32_t refPicFlag; /**< [in]: Set to 1 for a reference picture. This is ignored if NV_ENC_INITIALIZE_PARAMS::enablePTD is set to 1. */ + uint32_t temporalId; /**< [in]: Specifies the temporal id of the picture */ + uint32_t forceIntraRefreshWithFrameCnt; /**< [in]: Forces an intra refresh with duration equal to intraRefreshFrameCnt. + When outputRecoveryPointSEI is set this is value is used for recovery_frame_cnt in recovery point SEI message + forceIntraRefreshWithFrameCnt cannot be used if B frames are used in the GOP structure specified */ + uint32_t constrainedFrame :1; /**< [in]: Set to 1 if client wants to encode this frame with each slice completely independent of other slices in the frame. + NV_ENC_INITIALIZE_PARAMS::enableConstrainedEncoding should be set to 1 */ + uint32_t sliceModeDataUpdate :1; /**< [in]: Set to 1 if client wants to change the sliceModeData field to specify new sliceSize Parameter + When forceIntraRefreshWithFrameCnt is set it will have priority over sliceMode setting */ + uint32_t ltrMarkFrame :1; /**< [in]: Set to 1 if client wants to mark this frame as LTR */ + uint32_t ltrUseFrames :1; /**< [in]: Set to 1 if client allows encoding this frame using the LTR frames specified in ltrFrameBitmap */ + uint32_t reservedBitFields :28; /**< [in]: Reserved bit fields and must be set to 0 */ + uint8_t* sliceTypeData; /**< [in]: Array which specifies the slice type used to force intra slice for a particular slice. Currently supported only for NV_ENC_CONFIG_H264::sliceMode == 3. + Client should allocate array of size sliceModeData where sliceModeData is specified in field of ::_NV_ENC_CONFIG_H264 + Array element with index n corresponds to nth slice. To force a particular slice to intra client should set corresponding array element to NV_ENC_SLICE_TYPE_I + all other array elements should be set to NV_ENC_SLICE_TYPE_DEFAULT */ + uint32_t sliceTypeArrayCnt; /**< [in]: Client should set this to the number of elements allocated in sliceTypeData array. If sliceTypeData is NULL then this should be set to 0 */ + uint32_t sliceMode; /**< [in]: This parameter in conjunction with sliceModeData specifies the way in which the picture is divided into slices + sliceMode = 0 CTU based slices, sliceMode = 1 Byte based slices, sliceMode = 2 CTU row based slices, sliceMode = 3, numSlices in Picture + When forceIntraRefreshWithFrameCnt is set it will have priority over sliceMode setting + When sliceMode == 0 and sliceModeData == 0 whole picture will be coded with one slice */ + uint32_t sliceModeData; /**< [in]: Specifies the parameter needed for sliceMode. For: + sliceMode = 0, sliceModeData specifies # of CTUs in each slice (except last slice) + sliceMode = 1, sliceModeData specifies maximum # of bytes in each slice (except last slice) + sliceMode = 2, sliceModeData specifies # of CTU rows in each slice (except last slice) + sliceMode = 3, sliceModeData specifies number of slices in the picture. Driver will divide picture into slices optimally */ + uint32_t ltrMarkFrameIdx; /**< [in]: Specifies the long term reference frame index to use for marking this frame as LTR.*/ + uint32_t ltrUseFrameBitmap; /**< [in]: Specifies the associated bitmap of LTR frame indices to use when encoding this frame. */ + uint32_t ltrUsageMode; /**< [in]: Not supported. Reserved for future use and must be set to 0. */ + uint32_t seiPayloadArrayCnt; /**< [in]: Specifies the number of elements allocated in seiPayloadArray array. */ + uint32_t reserved; /**< [in]: Reserved and must be set to 0. */ + NV_ENC_SEI_PAYLOAD* seiPayloadArray; /**< [in]: Array of SEI payloads which will be inserted for this frame. */ + uint32_t reserved2 [244]; /**< [in]: Reserved and must be set to 0. */ + void* reserved3[61]; /**< [in]: Reserved and must be set to NULL. */ +} NV_ENC_PIC_PARAMS_HEVC; + +/** + * Codec specific per-picture encoding parameters. + */ +typedef union _NV_ENC_CODEC_PIC_PARAMS +{ + NV_ENC_PIC_PARAMS_H264 h264PicParams; /**< [in]: H264 encode picture params. */ + NV_ENC_PIC_PARAMS_HEVC hevcPicParams; /**< [in]: HEVC encode picture params. */ + uint32_t reserved[256]; /**< [in]: Reserved and must be set to 0. */ +} NV_ENC_CODEC_PIC_PARAMS; + +/** + * \struct _NV_ENC_PIC_PARAMS + * Encoding parameters that need to be sent on a per frame basis. + */ +typedef struct _NV_ENC_PIC_PARAMS +{ + uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_PIC_PARAMS_VER. */ + uint32_t inputWidth; /**< [in]: Specifies the input buffer width */ + uint32_t inputHeight; /**< [in]: Specifies the input buffer height */ + uint32_t inputPitch; /**< [in]: Specifies the input buffer pitch. If pitch value is not known, set this to inputWidth. */ + uint32_t encodePicFlags; /**< [in]: Specifies bit-wise OR`ed encode pic flags. See ::NV_ENC_PIC_FLAGS enum. */ + uint32_t frameIdx; /**< [in]: Specifies the frame index associated with the input frame [optional]. */ + uint64_t inputTimeStamp; /**< [in]: Specifies presentation timestamp associated with the input picture. */ + uint64_t inputDuration; /**< [in]: Specifies duration of the input picture */ + NV_ENC_INPUT_PTR inputBuffer; /**< [in]: Specifies the input buffer pointer. Client must use a pointer obtained from ::NvEncCreateInputBuffer() or ::NvEncMapInputResource() APIs.*/ + NV_ENC_OUTPUT_PTR outputBitstream; /**< [in]: Specifies the pointer to output buffer. Client should use a pointer obtained from ::NvEncCreateBitstreamBuffer() API. */ + void* completionEvent; /**< [in]: Specifies an event to be signalled on completion of encoding of this Frame [only if operating in Asynchronous mode]. Each output buffer should be associated with a distinct event pointer. */ + NV_ENC_BUFFER_FORMAT bufferFmt; /**< [in]: Specifies the input buffer format. */ + NV_ENC_PIC_STRUCT pictureStruct; /**< [in]: Specifies structure of the input picture. */ + NV_ENC_PIC_TYPE pictureType; /**< [in]: Specifies input picture type. Client required to be set explicitly by the client if the client has not set NV_ENC_INITALIZE_PARAMS::enablePTD to 1 while calling NvInitializeEncoder. */ + NV_ENC_CODEC_PIC_PARAMS codecPicParams; /**< [in]: Specifies the codec specific per-picture encoding parameters. */ + NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE meHintCountsPerBlock[2]; /**< [in]: Specifies the number of hint candidates per block per direction for the current frame. meHintCountsPerBlock[0] is for L0 predictors and meHintCountsPerBlock[1] is for L1 predictors. + The candidate count in NV_ENC_PIC_PARAMS::meHintCountsPerBlock[lx] must never exceed NV_ENC_INITIALIZE_PARAMS::maxMEHintCountsPerBlock[lx] provided during encoder intialization. */ + NVENC_EXTERNAL_ME_HINT *meExternalHints; /**< [in]: Specifies the pointer to ME external hints for the current frame. The size of ME hint buffer should be equal to number of macroblocks * the total number of candidates per macroblock. + The total number of candidates per MB per direction = 1*meHintCountsPerBlock[Lx].numCandsPerBlk16x16 + 2*meHintCountsPerBlock[Lx].numCandsPerBlk16x8 + 2*meHintCountsPerBlock[Lx].numCandsPerBlk8x8 + + 4*meHintCountsPerBlock[Lx].numCandsPerBlk8x8. For frames using bidirectional ME , the total number of candidates for single macroblock is sum of total number of candidates per MB for each direction (L0 and L1) */ + uint32_t reserved1[6]; /**< [in]: Reserved and must be set to 0 */ + void* reserved2[2]; /**< [in]: Reserved and must be set to NULL */ + int8_t *qpDeltaMap; /**< [in]: Specifies the pointer to signed byte array containing value per MB in raster scan order for the current picture, which will be Interperated depending on NV_ENC_RC_PARAMS::qpMapMode. + If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_DELTA , This specify QP modifier to be applied on top of the QP chosen by rate control. + If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_EMPHASIS, it specifies emphasis level map per MB. This level value along with QP chosen by rate control is used to compute the QP modifier, + which in turn is applied on top of QP chosen by rate control. + If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_DISABLED value in qpDeltaMap will be ignored.*/ + uint32_t qpDeltaMapSize; /**< [in]: Specifies the size in bytes of qpDeltaMap surface allocated by client and pointed to by NV_ENC_PIC_PARAMS::qpDeltaMap. Surface (array) should be picWidthInMbs * picHeightInMbs */ + uint32_t reservedBitFields; /**< [in]: Reserved bitfields and must be set to 0 */ + uint16_t meHintRefPicDist[2]; /**< [in]: Specifies temporal distance for reference picture (NVENC_EXTERNAL_ME_HINT::refidx = 0) used during external ME with NV_ENC_INITALIZE_PARAMS::enablePTD = 1 . meHintRefPicDist[0] is for L0 hints and meHintRefPicDist[1] is for L1 hints. + If not set, will internally infer distance of 1. Ignored for NV_ENC_INITALIZE_PARAMS::enablePTD = 0 */ + uint32_t reserved3[286]; /**< [in]: Reserved and must be set to 0 */ + void* reserved4[60]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_PIC_PARAMS; + +/** Macro for constructing the version field of ::_NV_ENC_PIC_PARAMS */ +#define NV_ENC_PIC_PARAMS_VER (NVENCAPI_STRUCT_VERSION(4) | ( 1<<31 )) + + +/** + * \struct _NV_ENC_MEONLY_PARAMS + * MEOnly parameters that need to be sent on a per motion estimation basis. + * NV_ENC_MEONLY_PARAMS::meExternalHints is supported for H264 only. + */ +typedef struct _NV_ENC_MEONLY_PARAMS +{ + uint32_t version; /**< [in]: Struct version. Must be set to NV_ENC_MEONLY_PARAMS_VER.*/ + uint32_t inputWidth; /**< [in]: Specifies the input buffer width */ + uint32_t inputHeight; /**< [in]: Specifies the input buffer height */ + NV_ENC_INPUT_PTR inputBuffer; /**< [in]: Specifies the input buffer pointer. Client must use a pointer obtained from NvEncCreateInputBuffer() or NvEncMapInputResource() APIs. */ + NV_ENC_INPUT_PTR referenceFrame; /**< [in]: Specifies the reference frame pointer */ + NV_ENC_OUTPUT_PTR mvBuffer; /**< [in]: Specifies the pointer to motion vector data buffer allocated by NvEncCreateMVBuffer. Client must lock mvBuffer using ::NvEncLockBitstream() API to get the motion vector data. */ + NV_ENC_BUFFER_FORMAT bufferFmt; /**< [in]: Specifies the input buffer format. */ + void* completionEvent; /**< [in]: Specifies an event to be signalled on completion of motion estimation + of this Frame [only if operating in Asynchronous mode]. + Each output buffer should be associated with a distinct event pointer. */ + uint32_t viewID; /**< [in]: Specifies left,right viewID if NV_ENC_CONFIG_H264_MEONLY::bStereoEnable is set. + viewID can be 0,1 if bStereoEnable is set, 0 otherwise. */ + NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE + meHintCountsPerBlock[2]; /**< [in]: Specifies the number of hint candidates per block for the current frame. meHintCountsPerBlock[0] is for L0 predictors. + The candidate count in NV_ENC_PIC_PARAMS::meHintCountsPerBlock[lx] must never exceed NV_ENC_INITIALIZE_PARAMS::maxMEHintCountsPerBlock[lx] provided during encoder intialization. */ + NVENC_EXTERNAL_ME_HINT *meExternalHints; /**< [in]: Specifies the pointer to ME external hints for the current frame. The size of ME hint buffer should be equal to number of macroblocks * the total number of candidates per macroblock. + The total number of candidates per MB per direction = 1*meHintCountsPerBlock[Lx].numCandsPerBlk16x16 + 2*meHintCountsPerBlock[Lx].numCandsPerBlk16x8 + 2*meHintCountsPerBlock[Lx].numCandsPerBlk8x8 + + 4*meHintCountsPerBlock[Lx].numCandsPerBlk8x8. For frames using bidirectional ME , the total number of candidates for single macroblock is sum of total number of candidates per MB for each direction (L0 and L1) */ + uint32_t reserved1[243]; /**< [in]: Reserved and must be set to 0 */ + void* reserved2[59]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_MEONLY_PARAMS; + +/** NV_ENC_MEONLY_PARAMS struct version*/ +#define NV_ENC_MEONLY_PARAMS_VER NVENCAPI_STRUCT_VERSION(3) + + +/** + * \struct _NV_ENC_LOCK_BITSTREAM + * Bitstream buffer lock parameters. + */ +typedef struct _NV_ENC_LOCK_BITSTREAM +{ + uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_LOCK_BITSTREAM_VER. */ + uint32_t doNotWait :1; /**< [in]: If this flag is set, the NvEncodeAPI interface will return buffer pointer even if operation is not completed. If not set, the call will block until operation completes. */ + uint32_t ltrFrame :1; /**< [out]: Flag indicating this frame is marked as LTR frame */ + uint32_t reservedBitFields :30; /**< [in]: Reserved bit fields and must be set to 0 */ + void* outputBitstream; /**< [in]: Pointer to the bitstream buffer being locked. */ + uint32_t* sliceOffsets; /**< [in,out]: Array which receives the slice offsets. This is not supported if NV_ENC_CONFIG_H264::sliceMode is 1 on Kepler GPUs. Array size must be equal to size of frame in MBs. */ + uint32_t frameIdx; /**< [out]: Frame no. for which the bitstream is being retrieved. */ + uint32_t hwEncodeStatus; /**< [out]: The NvEncodeAPI interface status for the locked picture. */ + uint32_t numSlices; /**< [out]: Number of slices in the encoded picture. Will be reported only if NV_ENC_INITIALIZE_PARAMS::reportSliceOffsets set to 1. */ + uint32_t bitstreamSizeInBytes; /**< [out]: Actual number of bytes generated and copied to the memory pointed by bitstreamBufferPtr. */ + uint64_t outputTimeStamp; /**< [out]: Presentation timestamp associated with the encoded output. */ + uint64_t outputDuration; /**< [out]: Presentation duration associates with the encoded output. */ + void* bitstreamBufferPtr; /**< [out]: Pointer to the generated output bitstream. + For MEOnly mode _NV_ENC_LOCK_BITSTREAM::bitstreamBufferPtr should be typecast to + NV_ENC_H264_MV_DATA/NV_ENC_HEVC_MV_DATA pointer respectively for H264/HEVC */ + NV_ENC_PIC_TYPE pictureType; /**< [out]: Picture type of the encoded picture. */ + NV_ENC_PIC_STRUCT pictureStruct; /**< [out]: Structure of the generated output picture. */ + uint32_t frameAvgQP; /**< [out]: Average QP of the frame. */ + uint32_t frameSatd; /**< [out]: Total SATD cost for whole frame. */ + uint32_t ltrFrameIdx; /**< [out]: Frame index associated with this LTR frame. */ + uint32_t ltrFrameBitmap; /**< [out]: Bitmap of LTR frames indices which were used for encoding this frame. Value of 0 if no LTR frames were used. */ + uint32_t reserved [236]; /**< [in]: Reserved and must be set to 0 */ + void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_LOCK_BITSTREAM; + +/** Macro for constructing the version field of ::_NV_ENC_LOCK_BITSTREAM */ +#define NV_ENC_LOCK_BITSTREAM_VER NVENCAPI_STRUCT_VERSION(1) + + +/** + * \struct _NV_ENC_LOCK_INPUT_BUFFER + * Uncompressed Input Buffer lock parameters. + */ +typedef struct _NV_ENC_LOCK_INPUT_BUFFER +{ + uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_LOCK_INPUT_BUFFER_VER. */ + uint32_t doNotWait :1; /**< [in]: Set to 1 to make ::NvEncLockInputBuffer() a unblocking call. If the encoding is not completed, driver will return ::NV_ENC_ERR_ENCODER_BUSY error code. */ + uint32_t reservedBitFields :31; /**< [in]: Reserved bitfields and must be set to 0 */ + NV_ENC_INPUT_PTR inputBuffer; /**< [in]: Pointer to the input buffer to be locked, client should pass the pointer obtained from ::NvEncCreateInputBuffer() or ::NvEncMapInputResource API. */ + void* bufferDataPtr; /**< [out]: Pointed to the locked input buffer data. Client can only access input buffer using the \p bufferDataPtr. */ + uint32_t pitch; /**< [out]: Pitch of the locked input buffer. */ + uint32_t reserved1[251]; /**< [in]: Reserved and must be set to 0 */ + void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_LOCK_INPUT_BUFFER; + +/** Macro for constructing the version field of ::_NV_ENC_LOCK_INPUT_BUFFER */ +#define NV_ENC_LOCK_INPUT_BUFFER_VER NVENCAPI_STRUCT_VERSION(1) + + +/** + * \struct _NV_ENC_MAP_INPUT_RESOURCE + * Map an input resource to a Nvidia Encoder Input Buffer + */ +typedef struct _NV_ENC_MAP_INPUT_RESOURCE +{ + uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_MAP_INPUT_RESOURCE_VER. */ + uint32_t subResourceIndex; /**< [in]: Deprecated. Do not use. */ + void* inputResource; /**< [in]: Deprecated. Do not use. */ + NV_ENC_REGISTERED_PTR registeredResource; /**< [in]: The Registered resource handle obtained by calling NvEncRegisterInputResource. */ + NV_ENC_INPUT_PTR mappedResource; /**< [out]: Mapped pointer corresponding to the registeredResource. This pointer must be used in NV_ENC_PIC_PARAMS::inputBuffer parameter in ::NvEncEncodePicture() API. */ + NV_ENC_BUFFER_FORMAT mappedBufferFmt; /**< [out]: Buffer format of the outputResource. This buffer format must be used in NV_ENC_PIC_PARAMS::bufferFmt if client using the above mapped resource pointer. */ + uint32_t reserved1[251]; /**< [in]: Reserved and must be set to 0. */ + void* reserved2[63]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_MAP_INPUT_RESOURCE; + +/** Macro for constructing the version field of ::_NV_ENC_MAP_INPUT_RESOURCE */ +#define NV_ENC_MAP_INPUT_RESOURCE_VER NVENCAPI_STRUCT_VERSION(4) + +/** + * \struct _NV_ENC_INPUT_RESOURCE_OPENGL_TEX + * NV_ENC_REGISTER_RESOURCE::resourceToRegister must be a pointer to a variable of this type, + * when NV_ENC_REGISTER_RESOURCE::resourceType is NV_ENC_INPUT_RESOURCE_TYPE_OPENGL_TEX + */ +typedef struct _NV_ENC_INPUT_RESOURCE_OPENGL_TEX +{ + uint32_t texture; /**< [in]: The name of the texture to be used. */ + uint32_t target; /**< [in]: Accepted values are GL_TEXTURE_RECTANGLE and GL_TEXTURE_2D. */ +} NV_ENC_INPUT_RESOURCE_OPENGL_TEX; + +/** + * \struct _NV_ENC_REGISTER_RESOURCE + * Register a resource for future use with the Nvidia Video Encoder Interface. + */ +typedef struct _NV_ENC_REGISTER_RESOURCE +{ + uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_REGISTER_RESOURCE_VER. */ + NV_ENC_INPUT_RESOURCE_TYPE resourceType; /**< [in]: Specifies the type of resource to be registered. + Supported values are + ::NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX, + ::NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR, + ::NV_ENC_INPUT_RESOURCE_TYPE_OPENGL_TEX */ + uint32_t width; /**< [in]: Input buffer Width. */ + uint32_t height; /**< [in]: Input buffer Height. */ + uint32_t pitch; /**< [in]: Input buffer Pitch. */ + uint32_t subResourceIndex; /**< [in]: Subresource Index of the DirectX resource to be registered. Should be set to 0 for other interfaces. */ + void* resourceToRegister; /**< [in]: Handle to the resource that is being registered. */ + NV_ENC_REGISTERED_PTR registeredResource; /**< [out]: Registered resource handle. This should be used in future interactions with the Nvidia Video Encoder Interface. */ + NV_ENC_BUFFER_FORMAT bufferFormat; /**< [in]: Buffer format of resource to be registered. */ + uint32_t reserved1[248]; /**< [in]: Reserved and must be set to 0. */ + void* reserved2[62]; /**< [in]: Reserved and must be set to NULL. */ +} NV_ENC_REGISTER_RESOURCE; + +/** Macro for constructing the version field of ::_NV_ENC_REGISTER_RESOURCE */ +#define NV_ENC_REGISTER_RESOURCE_VER NVENCAPI_STRUCT_VERSION(3) + +/** + * \struct _NV_ENC_STAT + * Encode Stats structure. + */ +typedef struct _NV_ENC_STAT +{ + uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_STAT_VER. */ + uint32_t reserved; /**< [in]: Reserved and must be set to 0 */ + NV_ENC_OUTPUT_PTR outputBitStream; /**< [out]: Specifies the pointer to output bitstream. */ + uint32_t bitStreamSize; /**< [out]: Size of generated bitstream in bytes. */ + uint32_t picType; /**< [out]: Picture type of encoded picture. See ::NV_ENC_PIC_TYPE. */ + uint32_t lastValidByteOffset; /**< [out]: Offset of last valid bytes of completed bitstream */ + uint32_t sliceOffsets[16]; /**< [out]: Offsets of each slice */ + uint32_t picIdx; /**< [out]: Picture number */ + uint32_t reserved1[233]; /**< [in]: Reserved and must be set to 0 */ + void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_STAT; + +/** Macro for constructing the version field of ::_NV_ENC_STAT */ +#define NV_ENC_STAT_VER NVENCAPI_STRUCT_VERSION(1) + + +/** + * \struct _NV_ENC_SEQUENCE_PARAM_PAYLOAD + * Sequence and picture paramaters payload. + */ +typedef struct _NV_ENC_SEQUENCE_PARAM_PAYLOAD +{ + uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_INITIALIZE_PARAMS_VER. */ + uint32_t inBufferSize; /**< [in]: Specifies the size of the spsppsBuffer provied by the client */ + uint32_t spsId; /**< [in]: Specifies the SPS id to be used in sequence header. Default value is 0. */ + uint32_t ppsId; /**< [in]: Specifies the PPS id to be used in picture header. Default value is 0. */ + void* spsppsBuffer; /**< [in]: Specifies bitstream header pointer of size NV_ENC_SEQUENCE_PARAM_PAYLOAD::inBufferSize. It is the client's responsibility to manage this memory. */ + uint32_t* outSPSPPSPayloadSize; /**< [out]: Size of the sequence and picture header in bytes written by the NvEncodeAPI interface to the SPSPPSBuffer. */ + uint32_t reserved [250]; /**< [in]: Reserved and must be set to 0 */ + void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_SEQUENCE_PARAM_PAYLOAD; + +/** Macro for constructing the version field of ::_NV_ENC_SEQUENCE_PARAM_PAYLOAD */ +#define NV_ENC_SEQUENCE_PARAM_PAYLOAD_VER NVENCAPI_STRUCT_VERSION(1) + + +/** + * Event registration/unregistration parameters. + */ +typedef struct _NV_ENC_EVENT_PARAMS +{ + uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_EVENT_PARAMS_VER. */ + uint32_t reserved; /**< [in]: Reserved and must be set to 0 */ + void* completionEvent; /**< [in]: Handle to event to be registered/unregistered with the NvEncodeAPI interface. */ + uint32_t reserved1[253]; /**< [in]: Reserved and must be set to 0 */ + void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_EVENT_PARAMS; + +/** Macro for constructing the version field of ::_NV_ENC_EVENT_PARAMS */ +#define NV_ENC_EVENT_PARAMS_VER NVENCAPI_STRUCT_VERSION(1) + +/** + * Encoder Session Creation parameters + */ +typedef struct _NV_ENC_OPEN_ENCODE_SESSIONEX_PARAMS +{ + uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER. */ + NV_ENC_DEVICE_TYPE deviceType; /**< [in]: Specified the device Type */ + void* device; /**< [in]: Pointer to client device. */ + void* reserved; /**< [in]: Reserved and must be set to 0. */ + uint32_t apiVersion; /**< [in]: API version. Should be set to NVENCAPI_VERSION. */ + uint32_t reserved1[253]; /**< [in]: Reserved and must be set to 0 */ + void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS; +/** Macro for constructing the version field of ::_NV_ENC_OPEN_ENCODE_SESSIONEX_PARAMS */ +#define NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER NVENCAPI_STRUCT_VERSION(1) + +/** @} */ /* END ENCODER_STRUCTURE */ + + +/** + * \addtogroup ENCODE_FUNC NvEncodeAPI Functions + * @{ + */ + +// NvEncOpenEncodeSession +/** + * \brief Opens an encoding session. + * + * Deprecated. + * + * \return + * ::NV_ENC_ERR_INVALID_CALL\n + * + */ +NVENCSTATUS NVENCAPI NvEncOpenEncodeSession (void* device, uint32_t deviceType, void** encoder); + +// NvEncGetEncodeGuidCount +/** + * \brief Retrieves the number of supported encode GUIDs. + * + * The function returns the number of codec guids supported by the NvEncodeAPI + * interface. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [out] encodeGUIDCount + * Number of supported encode GUIDs. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncGetEncodeGUIDCount (void* encoder, uint32_t* encodeGUIDCount); + + +// NvEncGetEncodeGUIDs +/** + * \brief Retrieves an array of supported encoder codec GUIDs. + * + * The function returns an array of codec guids supported by the NvEncodeAPI interface. + * The client must allocate an array where the NvEncodeAPI interface can + * fill the supported guids and pass the pointer in \p *GUIDs parameter. + * The size of the array can be determined by using ::NvEncGetEncodeGUIDCount() API. + * The Nvidia Encoding interface returns the number of codec guids it has actually + * filled in the guid array in the \p GUIDCount parameter. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] guidArraySize + * Number of GUIDs to retrieved. Should be set to the number retrieved using + * ::NvEncGetEncodeGUIDCount. + * \param [out] GUIDs + * Array of supported Encode GUIDs. + * \param [out] GUIDCount + * Number of supported Encode GUIDs. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncGetEncodeGUIDs (void* encoder, GUID* GUIDs, uint32_t guidArraySize, uint32_t* GUIDCount); + + +// NvEncGetEncodeProfileGuidCount +/** + * \brief Retrieves the number of supported profile GUIDs. + * + * The function returns the number of profile GUIDs supported for a given codec. + * The client must first enumerate the codec guids supported by the NvEncodeAPI + * interface. After determining the codec guid, it can query the NvEncodeAPI + * interface to determine the number of profile guids supported for a particular + * codec guid. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] encodeGUID + * The codec guid for which the profile guids are being enumerated. + * \param [out] encodeProfileGUIDCount + * Number of encode profiles supported for the given encodeGUID. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncGetEncodeProfileGUIDCount (void* encoder, GUID encodeGUID, uint32_t* encodeProfileGUIDCount); + + +// NvEncGetEncodeProfileGUIDs +/** + * \brief Retrieves an array of supported encode profile GUIDs. + * + * The function returns an array of supported profile guids for a particular + * codec guid. The client must allocate an array where the NvEncodeAPI interface + * can populate the profile guids. The client can determine the array size using + * ::NvEncGetEncodeProfileGUIDCount() API. The client must also validiate that the + * NvEncodeAPI interface supports the GUID the client wants to pass as \p encodeGUID + * parameter. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] encodeGUID + * The encode guid whose profile guids are being enumerated. + * \param [in] guidArraySize + * Number of GUIDs to be retrieved. Should be set to the number retrieved using + * ::NvEncGetEncodeProfileGUIDCount. + * \param [out] profileGUIDs + * Array of supported Encode Profile GUIDs + * \param [out] GUIDCount + * Number of valid encode profile GUIDs in \p profileGUIDs array. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncGetEncodeProfileGUIDs (void* encoder, GUID encodeGUID, GUID* profileGUIDs, uint32_t guidArraySize, uint32_t* GUIDCount); + +// NvEncGetInputFormatCount +/** + * \brief Retrieve the number of supported Input formats. + * + * The function returns the number of supported input formats. The client must + * query the NvEncodeAPI interface to determine the supported input formats + * before creating the input surfaces. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] encodeGUID + * Encode GUID, corresponding to which the number of supported input formats + * is to be retrieved. + * \param [out] inputFmtCount + * Number of input formats supported for specified Encode GUID. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_GENERIC \n + */ +NVENCSTATUS NVENCAPI NvEncGetInputFormatCount (void* encoder, GUID encodeGUID, uint32_t* inputFmtCount); + + +// NvEncGetInputFormats +/** + * \brief Retrieves an array of supported Input formats + * + * Returns an array of supported input formats The client must use the input + * format to create input surface using ::NvEncCreateInputBuffer() API. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] encodeGUID + * Encode GUID, corresponding to which the number of supported input formats + * is to be retrieved. + *\param [in] inputFmtArraySize + * Size input format count array passed in \p inputFmts. + *\param [out] inputFmts + * Array of input formats supported for this Encode GUID. + *\param [out] inputFmtCount + * The number of valid input format types returned by the NvEncodeAPI + * interface in \p inputFmts array. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncGetInputFormats (void* encoder, GUID encodeGUID, NV_ENC_BUFFER_FORMAT* inputFmts, uint32_t inputFmtArraySize, uint32_t* inputFmtCount); + + +// NvEncGetEncodeCaps +/** + * \brief Retrieves the capability value for a specified encoder attribute. + * + * The function returns the capability value for a given encoder attribute. The + * client must validate the encodeGUID using ::NvEncGetEncodeGUIDs() API before + * calling this function. The encoder attribute being queried are enumerated in + * ::NV_ENC_CAPS_PARAM enum. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] encodeGUID + * Encode GUID, corresponding to which the capability attribute is to be retrieved. + * \param [in] capsParam + * Used to specify attribute being queried. Refer ::NV_ENC_CAPS_PARAM for more + * details. + * \param [out] capsVal + * The value corresponding to the capability attribute being queried. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_GENERIC \n + */ +NVENCSTATUS NVENCAPI NvEncGetEncodeCaps (void* encoder, GUID encodeGUID, NV_ENC_CAPS_PARAM* capsParam, int* capsVal); + + +// NvEncGetEncodePresetCount +/** + * \brief Retrieves the number of supported preset GUIDs. + * + * The function returns the number of preset GUIDs available for a given codec. + * The client must validate the codec guid using ::NvEncGetEncodeGUIDs() API + * before calling this function. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] encodeGUID + * Encode GUID, corresponding to which the number of supported presets is to + * be retrieved. + * \param [out] encodePresetGUIDCount + * Receives the number of supported preset GUIDs. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncGetEncodePresetCount (void* encoder, GUID encodeGUID, uint32_t* encodePresetGUIDCount); + + +// NvEncGetEncodePresetGUIDs +/** + * \brief Receives an array of supported encoder preset GUIDs. + * + * The function returns an array of encode preset guids available for a given codec. + * The client can directly use one of the preset guids based upon the use case + * or target device. The preset guid chosen can be directly used in + * NV_ENC_INITIALIZE_PARAMS::presetGUID parameter to ::NvEncEncodePicture() API. + * Alternately client can also use the preset guid to retrieve the encoding config + * parameters being used by NvEncodeAPI interface for that given preset, using + * ::NvEncGetEncodePresetConfig() API. It can then modify preset config parameters + * as per its use case and send it to NvEncodeAPI interface as part of + * NV_ENC_INITIALIZE_PARAMS::encodeConfig parameter for NvEncInitializeEncoder() + * API. + * + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] encodeGUID + * Encode GUID, corresponding to which the list of supported presets is to be + * retrieved. + * \param [in] guidArraySize + * Size of array of preset guids passed in \p preset GUIDs + * \param [out] presetGUIDs + * Array of supported Encode preset GUIDs from the NvEncodeAPI interface + * to client. + * \param [out] encodePresetGUIDCount + * Receives the number of preset GUIDs returned by the NvEncodeAPI + * interface. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncGetEncodePresetGUIDs (void* encoder, GUID encodeGUID, GUID* presetGUIDs, uint32_t guidArraySize, uint32_t* encodePresetGUIDCount); + + +// NvEncGetEncodePresetConfig +/** + * \brief Returns a preset config structure supported for given preset GUID. + * + * The function returns a preset config structure for a given preset guid. Before + * using this function the client must enumerate the preset guids available for + * a given codec. The preset config structure can be modified by the client depending + * upon its use case and can be then used to initialize the encoder using + * ::NvEncInitializeEncoder() API. The client can use this function only if it + * wants to modify the NvEncodeAPI preset configuration, otherwise it can + * directly use the preset guid. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] encodeGUID + * Encode GUID, corresponding to which the list of supported presets is to be + * retrieved. + * \param [in] presetGUID + * Preset GUID, corresponding to which the Encoding configurations is to be + * retrieved. + * \param [out] presetConfig + * The requested Preset Encoder Attribute set. Refer ::_NV_ENC_CONFIG for +* more details. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncGetEncodePresetConfig (void* encoder, GUID encodeGUID, GUID presetGUID, NV_ENC_PRESET_CONFIG* presetConfig); + +// NvEncInitializeEncoder +/** + * \brief Initialize the encoder. + * + * This API must be used to initialize the encoder. The initialization parameter + * is passed using \p *createEncodeParams The client must send the following + * fields of the _NV_ENC_INITIALIZE_PARAMS structure with a valid value. + * - NV_ENC_INITIALIZE_PARAMS::encodeGUID + * - NV_ENC_INITIALIZE_PARAMS::encodeWidth + * - NV_ENC_INITIALIZE_PARAMS::encodeHeight + * + * The client can pass a preset guid directly to the NvEncodeAPI interface using + * NV_ENC_INITIALIZE_PARAMS::presetGUID field. If the client doesn't pass + * NV_ENC_INITIALIZE_PARAMS::encodeConfig structure, the codec specific parameters + * will be selected based on the preset guid. The preset guid must have been + * validated by the client using ::NvEncGetEncodePresetGUIDs() API. + * If the client passes a custom ::_NV_ENC_CONFIG structure through + * NV_ENC_INITIALIZE_PARAMS::encodeConfig , it will override the codec specific parameters + * based on the preset guid. It is recommended that even if the client passes a custom config, + * it should also send a preset guid. In this case, the preset guid passed by the client + * will not override any of the custom config parameters programmed by the client, + * it is only used as a hint by the NvEncodeAPI interface to determine certain encoder parameters + * which are not exposed to the client. + * + * There are two modes of operation for the encoder namely: + * - Asynchronous mode + * - Synchronous mode + * + * The client can select asynchronous or synchronous mode by setting the \p + * enableEncodeAsync field in ::_NV_ENC_INITIALIZE_PARAMS to 1 or 0 respectively. + *\par Asynchronous mode of operation: + * The Asynchronous mode can be enabled by setting NV_ENC_INITIALIZE_PARAMS::enableEncodeAsync to 1. + * The client operating in asynchronous mode must allocate completion event object + * for each output buffer and pass the completion event object in the + * ::NvEncEncodePicture() API. The client can create another thread and wait on + * the event object to be signalled by NvEncodeAPI interface on completion of the + * encoding process for the output frame. This should unblock the main thread from + * submitting work to the encoder. When the event is signalled the client can call + * NvEncodeAPI interfaces to copy the bitstream data using ::NvEncLockBitstream() + * API. This is the preferred mode of operation. + * + * NOTE: Asynchronous mode is not supported on Linux. + * + *\par Synchronous mode of operation: + * The client can select synchronous mode by setting NV_ENC_INITIALIZE_PARAMS::enableEncodeAsync to 0. + * The client working in synchronous mode can work in a single threaded or multi + * threaded mode. The client need not allocate any event objects. The client can + * only lock the bitstream data after NvEncodeAPI interface has returned + * ::NV_ENC_SUCCESS from encode picture. The NvEncodeAPI interface can return + * ::NV_ENC_ERR_NEED_MORE_INPUT error code from ::NvEncEncodePicture() API. The + * client must not lock the output buffer in such case but should send the next + * frame for encoding. The client must keep on calling ::NvEncEncodePicture() API + * until it returns ::NV_ENC_SUCCESS. \n + * The client must always lock the bitstream data in order in which it has submitted. + * This is true for both asynchronous and synchronous mode. + * + *\par Picture type decision: + * If the client is taking the picture type decision and it must disable the picture + * type decision module in NvEncodeAPI by setting NV_ENC_INITIALIZE_PARAMS::enablePTD + * to 0. In this case the client is required to send the picture in encoding + * order to NvEncodeAPI by doing the re-ordering for B frames. \n + * If the client doesn't want to take the picture type decision it can enable + * picture type decision module in the NvEncodeAPI interface by setting + * NV_ENC_INITIALIZE_PARAMS::enablePTD to 1 and send the input pictures in display + * order. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] createEncodeParams + * Refer ::_NV_ENC_INITIALIZE_PARAMS for details. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncInitializeEncoder (void* encoder, NV_ENC_INITIALIZE_PARAMS* createEncodeParams); + + +// NvEncCreateInputBuffer +/** + * \brief Allocates Input buffer. + * + * This function is used to allocate an input buffer. The client must enumerate + * the input buffer format before allocating the input buffer resources. The + * NV_ENC_INPUT_PTR returned by the NvEncodeAPI interface in the + * NV_ENC_CREATE_INPUT_BUFFER::inputBuffer field can be directly used in + * ::NvEncEncodePicture() API. The number of input buffers to be allocated by the + * client must be at least 4 more than the number of B frames being used for encoding. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in,out] createInputBufferParams + * Pointer to the ::NV_ENC_CREATE_INPUT_BUFFER structure. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncCreateInputBuffer (void* encoder, NV_ENC_CREATE_INPUT_BUFFER* createInputBufferParams); + + +// NvEncDestroyInputBuffer +/** + * \brief Release an input buffers. + * + * This function is used to free an input buffer. If the client has allocated + * any input buffer using ::NvEncCreateInputBuffer() API, it must free those + * input buffers by calling this function. The client must release the input + * buffers before destroying the encoder using ::NvEncDestroyEncoder() API. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] inputBuffer + * Pointer to the input buffer to be released. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncDestroyInputBuffer (void* encoder, NV_ENC_INPUT_PTR inputBuffer); + + +// NvEncCreateBitstreamBuffer +/** + * \brief Allocates an output bitstream buffer + * + * This function is used to allocate an output bitstream buffer and returns a + * NV_ENC_OUTPUT_PTR to bitstream buffer to the client in the + * NV_ENC_CREATE_BITSTREAM_BUFFER::bitstreamBuffer field. + * The client can only call this function after the encoder session has been + * initialized using ::NvEncInitializeEncoder() API. The minimum number of output + * buffers allocated by the client must be at least 4 more than the number of B + * B frames being used for encoding. The client can only access the output + * bitsteam data by locking the \p bitstreamBuffer using the ::NvEncLockBitstream() + * function. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in,out] createBitstreamBufferParams + * Pointer ::NV_ENC_CREATE_BITSTREAM_BUFFER for details. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncCreateBitstreamBuffer (void* encoder, NV_ENC_CREATE_BITSTREAM_BUFFER* createBitstreamBufferParams); + + +// NvEncDestroyBitstreamBuffer +/** + * \brief Release a bitstream buffer. + * + * This function is used to release the output bitstream buffer allocated using + * the ::NvEncCreateBitstreamBuffer() function. The client must release the output + * bitstreamBuffer using this function before destroying the encoder session. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] bitstreamBuffer + * Pointer to the bitstream buffer being released. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncDestroyBitstreamBuffer (void* encoder, NV_ENC_OUTPUT_PTR bitstreamBuffer); + +// NvEncEncodePicture +/** + * \brief Submit an input picture for encoding. + * + * This function is used to submit an input picture buffer for encoding. The + * encoding parameters are passed using \p *encodePicParams which is a pointer + * to the ::_NV_ENC_PIC_PARAMS structure. + * + * If the client has set NV_ENC_INITIALIZE_PARAMS::enablePTD to 0, then it must + * send a valid value for the following fields. + * - NV_ENC_PIC_PARAMS::pictureType + * - NV_ENC_PIC_PARAMS_H264::displayPOCSyntax (H264 only) + * - NV_ENC_PIC_PARAMS_H264::frameNumSyntax(H264 only) + * - NV_ENC_PIC_PARAMS_H264::refPicFlag(H264 only) + * + * + *\par Asynchronous Encoding + * If the client has enabled asynchronous mode of encoding by setting + * NV_ENC_INITIALIZE_PARAMS::enableEncodeAsync to 1 in the ::NvEncInitializeEncoder() + * API ,then the client must send a valid NV_ENC_PIC_PARAMS::completionEvent. + * Incase of asynchronous mode of operation, client can queue the ::NvEncEncodePicture() + * API commands from the main thread and then queue output buffers to be processed + * to a secondary worker thread. Before the locking the output buffers in the + * secondary thread , the client must wait on NV_ENC_PIC_PARAMS::completionEvent + * it has queued in ::NvEncEncodePicture() API call. The client must always process + * completion event and the output buffer in the same order in which they have been + * submitted for encoding. The NvEncodeAPI interface is responsible for any + * re-ordering required for B frames and will always ensure that encoded bitstream + * data is written in the same order in which output buffer is submitted. + *\code + The below example shows how asynchronous encoding in case of 1 B frames + ------------------------------------------------------------------------ + Suppose the client allocated 4 input buffers(I1,I2..), 4 output buffers(O1,O2..) + and 4 completion events(E1, E2, ...). The NvEncodeAPI interface will need to + keep a copy of the input buffers for re-ordering and it allocates following + internal buffers (NvI1, NvI2...). These internal buffers are managed by NvEncodeAPI + and the client is not responsible for the allocating or freeing the memory of + the internal buffers. + + a) The client main thread will queue the following encode frame calls. + Note the picture type is unknown to the client, the decision is being taken by + NvEncodeAPI interface. The client should pass ::_NV_ENC_PIC_PARAMS parameter + consisting of allocated input buffer, output buffer and output events in successive + ::NvEncEncodePicture() API calls along with other required encode picture params. + For example: + 1st EncodePicture parameters - (I1, O1, E1) + 2nd EncodePicture parameters - (I2, O2, E2) + 3rd EncodePicture parameters - (I3, O3, E3) + + b) NvEncodeAPI SW will receive the following encode Commands from the client. + The left side shows input from client in the form (Input buffer, Output Buffer, + Output Event). The right hand side shows a possible picture type decision take by + the NvEncodeAPI interface. + (I1, O1, E1) ---P1 Frame + (I2, O2, E2) ---B2 Frame + (I3, O3, E3) ---P3 Frame + + c) NvEncodeAPI interface will make a copy of the input buffers to its internal + buffersfor re-ordering. These copies are done as part of nvEncEncodePicture + function call from the client and NvEncodeAPI interface is responsible for + synchronization of copy operation with the actual encoding operation. + I1 --> NvI1 + I2 --> NvI2 + I3 --> NvI3 + + d) After returning from ::NvEncEncodePicture() call , the client must queue the output + bitstream processing work to the secondary thread. The output bitstream processing + for asynchronous mode consist of first waiting on completion event(E1, E2..) + and then locking the output bitstream buffer(O1, O2..) for reading the encoded + data. The work queued to the secondary thread by the client is in the following order + (I1, O1, E1) + (I2, O2, E2) + (I3, O3, E3) + Note they are in the same order in which client calls ::NvEncEncodePicture() API + in \p step a). + + e) NvEncodeAPI interface will do the re-ordering such that Encoder HW will receive + the following encode commands: + (NvI1, O1, E1) ---P1 Frame + (NvI3, O2, E2) ---P3 Frame + (NvI2, O3, E3) ---B2 frame + + f) After the encoding operations are completed, the events will be signalled + by NvEncodeAPI interface in the following order : + (O1, E1) ---P1 Frame ,output bitstream copied to O1 and event E1 signalled. + (O2, E2) ---P3 Frame ,output bitstream copied to O2 and event E2 signalled. + (O3, E3) ---B2 Frame ,output bitstream copied to O3 and event E3 signalled. + + g) The client must lock the bitstream data using ::NvEncLockBitstream() API in + the order O1,O2,O3 to read the encoded data, after waiting for the events + to be signalled in the same order i.e E1, E2 and E3.The output processing is + done in the secondary thread in the following order: + Waits on E1, copies encoded bitstream from O1 + Waits on E2, copies encoded bitstream from O2 + Waits on E3, copies encoded bitstream from O3 + + -Note the client will receive the events signalling and output buffer in the + same order in which they have submitted for encoding. + -Note the LockBitstream will have picture type field which will notify the + output picture type to the clients. + -Note the input, output buffer and the output completion event are free to be + reused once NvEncodeAPI interfaced has signalled the event and the client has + copied the data from the output buffer. + + * \endcode + * + *\par Synchronous Encoding + * The client can enable synchronous mode of encoding by setting + * NV_ENC_INITIALIZE_PARAMS::enableEncodeAsync to 0 in ::NvEncInitializeEncoder() API. + * The NvEncodeAPI interface may return ::NV_ENC_ERR_NEED_MORE_INPUT error code for + * some ::NvEncEncodePicture() API calls when NV_ENC_INITIALIZE_PARAMS::enablePTD + * is set to 1, but the client must not treat it as a fatal error. The NvEncodeAPI + * interface might not be able to submit an input picture buffer for encoding + * immediately due to re-ordering for B frames. The NvEncodeAPI interface cannot + * submit the input picture which is decided to be encoded as B frame as it waits + * for backward reference from temporally subsequent frames. This input picture + * is buffered internally and waits for more input picture to arrive. The client + * must not call ::NvEncLockBitstream() API on the output buffers whose + * ::NvEncEncodePicture() API returns ::NV_ENC_ERR_NEED_MORE_INPUT. The client must + * wait for the NvEncodeAPI interface to return ::NV_ENC_SUCCESS before locking the + * output bitstreams to read the encoded bitstream data. The following example + * explains the scenario with synchronous encoding with 2 B frames. + *\code + The below example shows how synchronous encoding works in case of 1 B frames + ----------------------------------------------------------------------------- + Suppose the client allocated 4 input buffers(I1,I2..), 4 output buffers(O1,O2..) + and 4 completion events(E1, E2, ...). The NvEncodeAPI interface will need to + keep a copy of the input buffers for re-ordering and it allocates following + internal buffers (NvI1, NvI2...). These internal buffers are managed by NvEncodeAPI + and the client is not responsible for the allocating or freeing the memory of + the internal buffers. + + The client calls ::NvEncEncodePicture() API with input buffer I1 and output buffer O1. + The NvEncodeAPI decides to encode I1 as P frame and submits it to encoder + HW and returns ::NV_ENC_SUCCESS. + The client can now read the encoded data by locking the output O1 by calling + NvEncLockBitstream API. + + The client calls ::NvEncEncodePicture() API with input buffer I2 and output buffer O2. + The NvEncodeAPI decides to encode I2 as B frame and buffers I2 by copying it + to internal buffer and returns ::NV_ENC_ERR_NEED_MORE_INPUT. + The error is not fatal and it notifies client that it cannot read the encoded + data by locking the output O2 by calling ::NvEncLockBitstream() API without submitting + more work to the NvEncodeAPI interface. + + The client calls ::NvEncEncodePicture() with input buffer I3 and output buffer O3. + The NvEncodeAPI decides to encode I3 as P frame and it first submits I3 for + encoding which will be used as backward reference frame for I2. + The NvEncodeAPI then submits I2 for encoding and returns ::NV_ENC_SUCESS. Both + the submission are part of the same ::NvEncEncodePicture() function call. + The client can now read the encoded data for both the frames by locking the output + O2 followed by O3 ,by calling ::NvEncLockBitstream() API. + + The client must always lock the output in the same order in which it has submitted + to receive the encoded bitstream in correct encoding order. + + * \endcode + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in,out] encodePicParams + * Pointer to the ::_NV_ENC_PIC_PARAMS structure. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_ENCODER_BUSY \n + * ::NV_ENC_ERR_NEED_MORE_INPUT \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncEncodePicture (void* encoder, NV_ENC_PIC_PARAMS* encodePicParams); + + +// NvEncLockBitstream +/** + * \brief Lock output bitstream buffer + * + * This function is used to lock the bitstream buffer to read the encoded data. + * The client can only access the encoded data by calling this function. + * The pointer to client accessible encoded data is returned in the + * NV_ENC_LOCK_BITSTREAM::bitstreamBufferPtr field. The size of the encoded data + * in the output buffer is returned in the NV_ENC_LOCK_BITSTREAM::bitstreamSizeInBytes + * The NvEncodeAPI interface also returns the output picture type and picture structure + * of the encoded frame in NV_ENC_LOCK_BITSTREAM::pictureType and + * NV_ENC_LOCK_BITSTREAM::pictureStruct fields respectively. If the client has + * set NV_ENC_LOCK_BITSTREAM::doNotWait to 1, the function might return + * ::NV_ENC_ERR_LOCK_BUSY if client is operating in synchronous mode. This is not + * a fatal failure if NV_ENC_LOCK_BITSTREAM::doNotWait is set to 1. In the above case the client can + * retry the function after few milliseconds. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in,out] lockBitstreamBufferParams + * Pointer to the ::_NV_ENC_LOCK_BITSTREAM structure. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_LOCK_BUSY \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncLockBitstream (void* encoder, NV_ENC_LOCK_BITSTREAM* lockBitstreamBufferParams); + + +// NvEncUnlockBitstream +/** + * \brief Unlock the output bitstream buffer + * + * This function is used to unlock the output bitstream buffer after the client + * has read the encoded data from output buffer. The client must call this function + * to unlock the output buffer which it has previously locked using ::NvEncLockBitstream() + * function. Using a locked bitstream buffer in ::NvEncEncodePicture() API will cause + * the function to fail. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in,out] bitstreamBuffer + * bitstream buffer pointer being unlocked + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncUnlockBitstream (void* encoder, NV_ENC_OUTPUT_PTR bitstreamBuffer); + + +// NvLockInputBuffer +/** + * \brief Locks an input buffer + * + * This function is used to lock the input buffer to load the uncompressed YUV + * pixel data into input buffer memory. The client must pass the NV_ENC_INPUT_PTR + * it had previously allocated using ::NvEncCreateInputBuffer()in the + * NV_ENC_LOCK_INPUT_BUFFER::inputBuffer field. + * The NvEncodeAPI interface returns pointer to client accessible input buffer + * memory in NV_ENC_LOCK_INPUT_BUFFER::bufferDataPtr field. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in,out] lockInputBufferParams + * Pointer to the ::_NV_ENC_LOCK_INPUT_BUFFER structure + * + * \return + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_LOCK_BUSY \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncLockInputBuffer (void* encoder, NV_ENC_LOCK_INPUT_BUFFER* lockInputBufferParams); + + +// NvUnlockInputBuffer +/** + * \brief Unlocks the input buffer + * + * This function is used to unlock the input buffer memory previously locked for + * uploading YUV pixel data. The input buffer must be unlocked before being used + * again for encoding, otherwise NvEncodeAPI will fail the ::NvEncEncodePicture() + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] inputBuffer + * Pointer to the input buffer that is being unlocked. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_GENERIC \n + * + * + */ +NVENCSTATUS NVENCAPI NvEncUnlockInputBuffer (void* encoder, NV_ENC_INPUT_PTR inputBuffer); + + +// NvEncGetEncodeStats +/** + * \brief Get encoding statistics. + * + * This function is used to retrieve the encoding statistics. + * This API is not supported when encode device type is CUDA. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in,out] encodeStats + * Pointer to the ::_NV_ENC_STAT structure. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncGetEncodeStats (void* encoder, NV_ENC_STAT* encodeStats); + + +// NvEncGetSequenceParams +/** + * \brief Get encoded sequence and picture header. + * + * This function can be used to retrieve the sequence and picture header out of + * band. The client must call this function only after the encoder has been + * initialized using ::NvEncInitializeEncoder() function. The client must + * allocate the memory where the NvEncodeAPI interface can copy the bitstream + * header and pass the pointer to the memory in NV_ENC_SEQUENCE_PARAM_PAYLOAD::spsppsBuffer. + * The size of buffer is passed in the field NV_ENC_SEQUENCE_PARAM_PAYLOAD::inBufferSize. + * The NvEncodeAPI interface will copy the bitstream header payload and returns + * the actual size of the bitstream header in the field + * NV_ENC_SEQUENCE_PARAM_PAYLOAD::outSPSPPSPayloadSize. + * The client must call ::NvEncGetSequenceParams() function from the same thread which is + * being used to call ::NvEncEncodePicture() function. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in,out] sequenceParamPayload + * Pointer to the ::_NV_ENC_SEQUENCE_PARAM_PAYLOAD structure. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncGetSequenceParams (void* encoder, NV_ENC_SEQUENCE_PARAM_PAYLOAD* sequenceParamPayload); + + +// NvEncRegisterAsyncEvent +/** + * \brief Register event for notification to encoding completion. + * + * This function is used to register the completion event with NvEncodeAPI + * interface. The event is required when the client has configured the encoder to + * work in asynchronous mode. In this mode the client needs to send a completion + * event with every output buffer. The NvEncodeAPI interface will signal the + * completion of the encoding process using this event. Only after the event is + * signalled the client can get the encoded data using ::NvEncLockBitstream() function. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] eventParams + * Pointer to the ::_NV_ENC_EVENT_PARAMS structure. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncRegisterAsyncEvent (void* encoder, NV_ENC_EVENT_PARAMS* eventParams); + + +// NvEncUnregisterAsyncEvent +/** + * \brief Unregister completion event. + * + * This function is used to unregister completion event which has been previously + * registered using ::NvEncRegisterAsyncEvent() function. The client must unregister + * all events before destroying the encoder using ::NvEncDestroyEncoder() function. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] eventParams + * Pointer to the ::_NV_ENC_EVENT_PARAMS structure. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncUnregisterAsyncEvent (void* encoder, NV_ENC_EVENT_PARAMS* eventParams); + + +// NvEncMapInputResource +/** + * \brief Map an externally created input resource pointer for encoding. + * + * Maps an externally allocated input resource [using and returns a NV_ENC_INPUT_PTR + * which can be used for encoding in the ::NvEncEncodePicture() function. The + * mapped resource is returned in the field NV_ENC_MAP_INPUT_RESOURCE::outputResourcePtr. + * The NvEncodeAPI interface also returns the buffer format of the mapped resource + * in the field NV_ENC_MAP_INPUT_RESOURCE::outbufferFmt. + * This function provides synchronization guarantee that any graphics or compute + * work submitted on the input buffer is completed before the buffer is used for encoding. + * The client should not access any input buffer while they are mapped by the encoder. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in,out] mapInputResParams + * Pointer to the ::_NV_ENC_MAP_INPUT_RESOURCE structure. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_RESOURCE_NOT_REGISTERED \n + * ::NV_ENC_ERR_MAP_FAILED \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncMapInputResource (void* encoder, NV_ENC_MAP_INPUT_RESOURCE* mapInputResParams); + + +// NvEncUnmapInputResource +/** + * \brief UnMaps a NV_ENC_INPUT_PTR which was mapped for encoding + * + * + * UnMaps an input buffer which was previously mapped using ::NvEncMapInputResource() + * API. The mapping created using ::NvEncMapInputResource() should be invalidated + * using this API before the external resource is destroyed by the client. The client + * must unmap the buffer after ::NvEncLockBitstream() API returns succuessfully for encode + * work submitted using the mapped input buffer. + * + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] mappedInputBuffer + * Pointer to the NV_ENC_INPUT_PTR + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_RESOURCE_NOT_REGISTERED \n + * ::NV_ENC_ERR_RESOURCE_NOT_MAPPED \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncUnmapInputResource (void* encoder, NV_ENC_INPUT_PTR mappedInputBuffer); + +// NvEncDestroyEncoder +/** + * \brief Destroy Encoding Session + * + * Destroys the encoder session previously created using ::NvEncOpenEncodeSession() + * function. The client must flush the encoder before freeing any resources. In order + * to flush the encoder the client must pass a NULL encode picture packet and either + * wait for the ::NvEncEncodePicture() function to return in synchronous mode or wait + * for the flush event to be signaled by the encoder in asynchronous mode. + * The client must free all the input and output resources created using the + * NvEncodeAPI interface before destroying the encoder. If the client is operating + * in asynchronous mode, it must also unregister the completion events previously + * registered. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncDestroyEncoder (void* encoder); + +// NvEncInvalidateRefFrames +/** + * \brief Invalidate reference frames + * + * Invalidates reference frame based on the time stamp provided by the client. + * The encoder marks any reference frames or any frames which have been reconstructed + * using the corrupt frame as invalid for motion estimation and uses older reference + * frames for motion estimation. The encoded forces the current frame to be encoded + * as an intra frame if no reference frames are left after invalidation process. + * This is useful for low latency application for error resiliency. The client + * is recommended to set NV_ENC_CONFIG_H264::maxNumRefFrames to a large value so + * that encoder can keep a backup of older reference frames in the DPB and can use them + * for motion estimation when the newer reference frames have been invalidated. + * This API can be called multiple times. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] invalidRefFrameTimeStamp + * Timestamp of the invalid reference frames which needs to be invalidated. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncInvalidateRefFrames(void* encoder, uint64_t invalidRefFrameTimeStamp); + +// NvEncOpenEncodeSessionEx +/** + * \brief Opens an encoding session. + * + * Opens an encoding session and returns a pointer to the encoder interface in + * the \p **encoder parameter. The client should start encoding process by calling + * this API first. + * The client must pass a pointer to IDirect3DDevice9 device or CUDA context in the \p *device parameter. + * For the OpenGL interface, \p device must be NULL. An OpenGL context must be current when + * calling all NvEncodeAPI functions. + * If the creation of encoder session fails, the client must call ::NvEncDestroyEncoder API + * before exiting. + * + * \param [in] openSessionExParams + * Pointer to a ::NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS structure. + * \param [out] encoder + * Encode Session pointer to the NvEncodeAPI interface. + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_NO_ENCODE_DEVICE \n + * ::NV_ENC_ERR_UNSUPPORTED_DEVICE \n + * ::NV_ENC_ERR_INVALID_DEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncOpenEncodeSessionEx (NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS *openSessionExParams, void** encoder); + +// NvEncRegisterResource +/** + * \brief Registers a resource with the Nvidia Video Encoder Interface. + * + * Registers a resource with the Nvidia Video Encoder Interface for book keeping. + * The client is expected to pass the registered resource handle as well, while calling ::NvEncMapInputResource API. + * + * \param [in] encoder + * Pointer to the NVEncodeAPI interface. + * + * \param [in] registerResParams + * Pointer to a ::_NV_ENC_REGISTER_RESOURCE structure + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_RESOURCE_REGISTER_FAILED \n + * ::NV_ENC_ERR_GENERIC \n + * ::NV_ENC_ERR_UNIMPLEMENTED \n + * + */ +NVENCSTATUS NVENCAPI NvEncRegisterResource (void* encoder, NV_ENC_REGISTER_RESOURCE* registerResParams); + +// NvEncUnregisterResource +/** + * \brief Unregisters a resource previously registered with the Nvidia Video Encoder Interface. + * + * Unregisters a resource previously registered with the Nvidia Video Encoder Interface. + * The client is expected to unregister any resource that it has registered with the + * Nvidia Video Encoder Interface before destroying the resource. + * + * \param [in] encoder + * Pointer to the NVEncodeAPI interface. + * + * \param [in] registeredResource + * The registered resource pointer that was returned in ::NvEncRegisterResource. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_RESOURCE_NOT_REGISTERED \n + * ::NV_ENC_ERR_GENERIC \n + * ::NV_ENC_ERR_UNIMPLEMENTED \n + * + */ +NVENCSTATUS NVENCAPI NvEncUnregisterResource (void* encoder, NV_ENC_REGISTERED_PTR registeredResource); + +// NvEncReconfigureEncoder +/** + * \brief Reconfigure an existing encoding session. + * + * Reconfigure an existing encoding session. + * The client should call this API to change/reconfigure the parameter passed during + * NvEncInitializeEncoder API call. + * Currently Reconfiguration of following are not supported. + * Change in GOP structure. + * Change in sync-Async mode. + * Change in MaxWidth & MaxHeight. + * Change in PTDmode. + * + * Resolution change is possible only if maxEncodeWidth & maxEncodeHeight of NV_ENC_INITIALIZE_PARAMS + * is set while creating encoder session. + * + * \param [in] encoder + * Pointer to the NVEncodeAPI interface. + * + * \param [in] reInitEncodeParams + * Pointer to a ::NV_ENC_RECONFIGURE_PARAMS structure. + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_NO_ENCODE_DEVICE \n + * ::NV_ENC_ERR_UNSUPPORTED_DEVICE \n + * ::NV_ENC_ERR_INVALID_DEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_GENERIC \n + * + */ +NVENCSTATUS NVENCAPI NvEncReconfigureEncoder (void *encoder, NV_ENC_RECONFIGURE_PARAMS* reInitEncodeParams); + + + +// NvEncCreateMVBuffer +/** + * \brief Allocates output MV buffer for ME only mode. + * + * This function is used to allocate an output MV buffer. The size of the mvBuffer is + * dependent on the frame height and width of the last ::NvEncCreateInputBuffer() call. + * The NV_ENC_OUTPUT_PTR returned by the NvEncodeAPI interface in the + * ::NV_ENC_CREATE_MV_BUFFER::mvBuffer field should be used in + * ::NvEncRunMotionEstimationOnly() API. + * Client must lock ::NV_ENC_CREATE_MV_BUFFER::mvBuffer using ::NvEncLockBitstream() API to get the motion vector data. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in,out] createMVBufferParams + * Pointer to the ::NV_ENC_CREATE_MV_BUFFER structure. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_GENERIC \n + */ +NVENCSTATUS NVENCAPI NvEncCreateMVBuffer (void* encoder, NV_ENC_CREATE_MV_BUFFER* createMVBufferParams); + + +// NvEncDestroyMVBuffer +/** + * \brief Release an output MV buffer for ME only mode. + * + * This function is used to release the output MV buffer allocated using + * the ::NvEncCreateMVBuffer() function. The client must release the output + * mvBuffer using this function before destroying the encoder session. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] mvBuffer + * Pointer to the mvBuffer being released. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_GENERIC \n + */ +NVENCSTATUS NVENCAPI NvEncDestroyMVBuffer (void* encoder, NV_ENC_OUTPUT_PTR mvBuffer); + + +// NvEncRunMotionEstimationOnly +/** + * \brief Submit an input picture and reference frame for motion estimation in ME only mode. + * + * This function is used to submit the input frame and reference frame for motion + * estimation. The ME parameters are passed using *meOnlyParams which is a pointer + * to ::_NV_ENC_MEONLY_PARAMS structure. + * Client must lock ::NV_ENC_CREATE_MV_BUFFER::mvBuffer using ::NvEncLockBitstream() API to get the motion vector data. + * to get motion vector data. + * + * \param [in] encoder + * Pointer to the NvEncodeAPI interface. + * \param [in] meOnlyParams + * Pointer to the ::_NV_ENC_MEONLY_PARAMS structure. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n + * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n + * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n + * ::NV_ENC_ERR_OUT_OF_MEMORY \n + * ::NV_ENC_ERR_INVALID_PARAM \n + * ::NV_ENC_ERR_INVALID_VERSION \n + * ::NV_ENC_ERR_NEED_MORE_INPUT \n + * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n + * ::NV_ENC_ERR_GENERIC \n + */ +NVENCSTATUS NVENCAPI NvEncRunMotionEstimationOnly (void* encoder, NV_ENC_MEONLY_PARAMS* meOnlyParams); + +// NvEncodeAPIGetMaxSupportedVersion +/** + * \brief Get the largest NvEncodeAPI version supported by the driver. + * + * This function can be used by clients to determine if the driver supports + * the NvEncodeAPI header the application was compiled with. + * + * \param [out] version + * Pointer to the requested value. The 4 least significant bits in the returned + * indicate the minor version and the rest of the bits indicate the major + * version of the largest supported version. + * + * \return + * ::NV_ENC_SUCCESS \n + * ::NV_ENC_ERR_INVALID_PTR \n + */ +NVENCSTATUS NVENCAPI NvEncodeAPIGetMaxSupportedVersion (uint32_t* version); + + +/// \cond API PFN +/* + * Defines API function pointers + */ +typedef NVENCSTATUS (NVENCAPI* PNVENCOPENENCODESESSION) (void* device, uint32_t deviceType, void** encoder); +typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODEGUIDCOUNT) (void* encoder, uint32_t* encodeGUIDCount); +typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODEGUIDS) (void* encoder, GUID* GUIDs, uint32_t guidArraySize, uint32_t* GUIDCount); +typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODEPROFILEGUIDCOUNT) (void* encoder, GUID encodeGUID, uint32_t* encodeProfileGUIDCount); +typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODEPROFILEGUIDS) (void* encoder, GUID encodeGUID, GUID* profileGUIDs, uint32_t guidArraySize, uint32_t* GUIDCount); +typedef NVENCSTATUS (NVENCAPI* PNVENCGETINPUTFORMATCOUNT) (void* encoder, GUID encodeGUID, uint32_t* inputFmtCount); +typedef NVENCSTATUS (NVENCAPI* PNVENCGETINPUTFORMATS) (void* encoder, GUID encodeGUID, NV_ENC_BUFFER_FORMAT* inputFmts, uint32_t inputFmtArraySize, uint32_t* inputFmtCount); +typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODECAPS) (void* encoder, GUID encodeGUID, NV_ENC_CAPS_PARAM* capsParam, int* capsVal); +typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODEPRESETCOUNT) (void* encoder, GUID encodeGUID, uint32_t* encodePresetGUIDCount); +typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODEPRESETGUIDS) (void* encoder, GUID encodeGUID, GUID* presetGUIDs, uint32_t guidArraySize, uint32_t* encodePresetGUIDCount); +typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODEPRESETCONFIG) (void* encoder, GUID encodeGUID, GUID presetGUID, NV_ENC_PRESET_CONFIG* presetConfig); +typedef NVENCSTATUS (NVENCAPI* PNVENCINITIALIZEENCODER) (void* encoder, NV_ENC_INITIALIZE_PARAMS* createEncodeParams); +typedef NVENCSTATUS (NVENCAPI* PNVENCCREATEINPUTBUFFER) (void* encoder, NV_ENC_CREATE_INPUT_BUFFER* createInputBufferParams); +typedef NVENCSTATUS (NVENCAPI* PNVENCDESTROYINPUTBUFFER) (void* encoder, NV_ENC_INPUT_PTR inputBuffer); +typedef NVENCSTATUS (NVENCAPI* PNVENCCREATEBITSTREAMBUFFER) (void* encoder, NV_ENC_CREATE_BITSTREAM_BUFFER* createBitstreamBufferParams); +typedef NVENCSTATUS (NVENCAPI* PNVENCDESTROYBITSTREAMBUFFER) (void* encoder, NV_ENC_OUTPUT_PTR bitstreamBuffer); +typedef NVENCSTATUS (NVENCAPI* PNVENCENCODEPICTURE) (void* encoder, NV_ENC_PIC_PARAMS* encodePicParams); +typedef NVENCSTATUS (NVENCAPI* PNVENCLOCKBITSTREAM) (void* encoder, NV_ENC_LOCK_BITSTREAM* lockBitstreamBufferParams); +typedef NVENCSTATUS (NVENCAPI* PNVENCUNLOCKBITSTREAM) (void* encoder, NV_ENC_OUTPUT_PTR bitstreamBuffer); +typedef NVENCSTATUS (NVENCAPI* PNVENCLOCKINPUTBUFFER) (void* encoder, NV_ENC_LOCK_INPUT_BUFFER* lockInputBufferParams); +typedef NVENCSTATUS (NVENCAPI* PNVENCUNLOCKINPUTBUFFER) (void* encoder, NV_ENC_INPUT_PTR inputBuffer); +typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODESTATS) (void* encoder, NV_ENC_STAT* encodeStats); +typedef NVENCSTATUS (NVENCAPI* PNVENCGETSEQUENCEPARAMS) (void* encoder, NV_ENC_SEQUENCE_PARAM_PAYLOAD* sequenceParamPayload); +typedef NVENCSTATUS (NVENCAPI* PNVENCREGISTERASYNCEVENT) (void* encoder, NV_ENC_EVENT_PARAMS* eventParams); +typedef NVENCSTATUS (NVENCAPI* PNVENCUNREGISTERASYNCEVENT) (void* encoder, NV_ENC_EVENT_PARAMS* eventParams); +typedef NVENCSTATUS (NVENCAPI* PNVENCMAPINPUTRESOURCE) (void* encoder, NV_ENC_MAP_INPUT_RESOURCE* mapInputResParams); +typedef NVENCSTATUS (NVENCAPI* PNVENCUNMAPINPUTRESOURCE) (void* encoder, NV_ENC_INPUT_PTR mappedInputBuffer); +typedef NVENCSTATUS (NVENCAPI* PNVENCDESTROYENCODER) (void* encoder); +typedef NVENCSTATUS (NVENCAPI* PNVENCINVALIDATEREFFRAMES) (void* encoder, uint64_t invalidRefFrameTimeStamp); +typedef NVENCSTATUS (NVENCAPI* PNVENCOPENENCODESESSIONEX) (NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS *openSessionExParams, void** encoder); +typedef NVENCSTATUS (NVENCAPI* PNVENCREGISTERRESOURCE) (void* encoder, NV_ENC_REGISTER_RESOURCE* registerResParams); +typedef NVENCSTATUS (NVENCAPI* PNVENCUNREGISTERRESOURCE) (void* encoder, NV_ENC_REGISTERED_PTR registeredRes); +typedef NVENCSTATUS (NVENCAPI* PNVENCRECONFIGUREENCODER) (void* encoder, NV_ENC_RECONFIGURE_PARAMS* reInitEncodeParams); + +typedef NVENCSTATUS (NVENCAPI* PNVENCCREATEMVBUFFER) (void* encoder, NV_ENC_CREATE_MV_BUFFER* createMVBufferParams); +typedef NVENCSTATUS (NVENCAPI* PNVENCDESTROYMVBUFFER) (void* encoder, NV_ENC_OUTPUT_PTR mvBuffer); +typedef NVENCSTATUS (NVENCAPI* PNVENCRUNMOTIONESTIMATIONONLY) (void* encoder, NV_ENC_MEONLY_PARAMS* meOnlyParams); + + +/// \endcond + + +/** @} */ /* END ENCODE_FUNC */ + +/** + * \ingroup ENCODER_STRUCTURE + * NV_ENCODE_API_FUNCTION_LIST + */ +typedef struct _NV_ENCODE_API_FUNCTION_LIST +{ + uint32_t version; /**< [in]: Client should pass NV_ENCODE_API_FUNCTION_LIST_VER. */ + uint32_t reserved; /**< [in]: Reserved and should be set to 0. */ + PNVENCOPENENCODESESSION nvEncOpenEncodeSession; /**< [out]: Client should access ::NvEncOpenEncodeSession() API through this pointer. */ + PNVENCGETENCODEGUIDCOUNT nvEncGetEncodeGUIDCount; /**< [out]: Client should access ::NvEncGetEncodeGUIDCount() API through this pointer. */ + PNVENCGETENCODEPRESETCOUNT nvEncGetEncodeProfileGUIDCount; /**< [out]: Client should access ::NvEncGetEncodeProfileGUIDCount() API through this pointer.*/ + PNVENCGETENCODEPRESETGUIDS nvEncGetEncodeProfileGUIDs; /**< [out]: Client should access ::NvEncGetEncodeProfileGUIDs() API through this pointer. */ + PNVENCGETENCODEGUIDS nvEncGetEncodeGUIDs; /**< [out]: Client should access ::NvEncGetEncodeGUIDs() API through this pointer. */ + PNVENCGETINPUTFORMATCOUNT nvEncGetInputFormatCount; /**< [out]: Client should access ::NvEncGetInputFormatCount() API through this pointer. */ + PNVENCGETINPUTFORMATS nvEncGetInputFormats; /**< [out]: Client should access ::NvEncGetInputFormats() API through this pointer. */ + PNVENCGETENCODECAPS nvEncGetEncodeCaps; /**< [out]: Client should access ::NvEncGetEncodeCaps() API through this pointer. */ + PNVENCGETENCODEPRESETCOUNT nvEncGetEncodePresetCount; /**< [out]: Client should access ::NvEncGetEncodePresetCount() API through this pointer. */ + PNVENCGETENCODEPRESETGUIDS nvEncGetEncodePresetGUIDs; /**< [out]: Client should access ::NvEncGetEncodePresetGUIDs() API through this pointer. */ + PNVENCGETENCODEPRESETCONFIG nvEncGetEncodePresetConfig; /**< [out]: Client should access ::NvEncGetEncodePresetConfig() API through this pointer. */ + PNVENCINITIALIZEENCODER nvEncInitializeEncoder; /**< [out]: Client should access ::NvEncInitializeEncoder() API through this pointer. */ + PNVENCCREATEINPUTBUFFER nvEncCreateInputBuffer; /**< [out]: Client should access ::NvEncCreateInputBuffer() API through this pointer. */ + PNVENCDESTROYINPUTBUFFER nvEncDestroyInputBuffer; /**< [out]: Client should access ::NvEncDestroyInputBuffer() API through this pointer. */ + PNVENCCREATEBITSTREAMBUFFER nvEncCreateBitstreamBuffer; /**< [out]: Client should access ::NvEncCreateBitstreamBuffer() API through this pointer. */ + PNVENCDESTROYBITSTREAMBUFFER nvEncDestroyBitstreamBuffer; /**< [out]: Client should access ::NvEncDestroyBitstreamBuffer() API through this pointer. */ + PNVENCENCODEPICTURE nvEncEncodePicture; /**< [out]: Client should access ::NvEncEncodePicture() API through this pointer. */ + PNVENCLOCKBITSTREAM nvEncLockBitstream; /**< [out]: Client should access ::NvEncLockBitstream() API through this pointer. */ + PNVENCUNLOCKBITSTREAM nvEncUnlockBitstream; /**< [out]: Client should access ::NvEncUnlockBitstream() API through this pointer. */ + PNVENCLOCKINPUTBUFFER nvEncLockInputBuffer; /**< [out]: Client should access ::NvEncLockInputBuffer() API through this pointer. */ + PNVENCUNLOCKINPUTBUFFER nvEncUnlockInputBuffer; /**< [out]: Client should access ::NvEncUnlockInputBuffer() API through this pointer. */ + PNVENCGETENCODESTATS nvEncGetEncodeStats; /**< [out]: Client should access ::NvEncGetEncodeStats() API through this pointer. */ + PNVENCGETSEQUENCEPARAMS nvEncGetSequenceParams; /**< [out]: Client should access ::NvEncGetSequenceParams() API through this pointer. */ + PNVENCREGISTERASYNCEVENT nvEncRegisterAsyncEvent; /**< [out]: Client should access ::NvEncRegisterAsyncEvent() API through this pointer. */ + PNVENCUNREGISTERASYNCEVENT nvEncUnregisterAsyncEvent; /**< [out]: Client should access ::NvEncUnregisterAsyncEvent() API through this pointer. */ + PNVENCMAPINPUTRESOURCE nvEncMapInputResource; /**< [out]: Client should access ::NvEncMapInputResource() API through this pointer. */ + PNVENCUNMAPINPUTRESOURCE nvEncUnmapInputResource; /**< [out]: Client should access ::NvEncUnmapInputResource() API through this pointer. */ + PNVENCDESTROYENCODER nvEncDestroyEncoder; /**< [out]: Client should access ::NvEncDestroyEncoder() API through this pointer. */ + PNVENCINVALIDATEREFFRAMES nvEncInvalidateRefFrames; /**< [out]: Client should access ::NvEncInvalidateRefFrames() API through this pointer. */ + PNVENCOPENENCODESESSIONEX nvEncOpenEncodeSessionEx; /**< [out]: Client should access ::NvEncOpenEncodeSession() API through this pointer. */ + PNVENCREGISTERRESOURCE nvEncRegisterResource; /**< [out]: Client should access ::NvEncRegisterResource() API through this pointer. */ + PNVENCUNREGISTERRESOURCE nvEncUnregisterResource; /**< [out]: Client should access ::NvEncUnregisterResource() API through this pointer. */ + PNVENCRECONFIGUREENCODER nvEncReconfigureEncoder; /**< [out]: Client should access ::NvEncReconfigureEncoder() API through this pointer. */ + void* reserved1; + PNVENCCREATEMVBUFFER nvEncCreateMVBuffer; /**< [out]: Client should access ::NvEncCreateMVBuffer API through this pointer. */ + PNVENCDESTROYMVBUFFER nvEncDestroyMVBuffer; /**< [out]: Client should access ::NvEncDestroyMVBuffer API through this pointer. */ + PNVENCRUNMOTIONESTIMATIONONLY nvEncRunMotionEstimationOnly; /**< [out]: Client should access ::NvEncRunMotionEstimationOnly API through this pointer. */ + void* reserved2[281]; /**< [in]: Reserved and must be set to NULL */ +} NV_ENCODE_API_FUNCTION_LIST; + +/** Macro for constructing the version field of ::_NV_ENCODEAPI_FUNCTION_LIST. */ +#define NV_ENCODE_API_FUNCTION_LIST_VER NVENCAPI_STRUCT_VERSION(2) + +// NvEncodeAPICreateInstance +/** + * \ingroup ENCODE_FUNC + * Entry Point to the NvEncodeAPI interface. + * + * Creates an instance of the NvEncodeAPI interface, and populates the + * pFunctionList with function pointers to the API routines implemented by the + * NvEncodeAPI interface. + * + * \param [out] functionList + * + * \return + * ::NV_ENC_SUCCESS + * ::NV_ENC_ERR_INVALID_PTR + */ +NVENCSTATUS NVENCAPI NvEncodeAPICreateInstance(NV_ENCODE_API_FUNCTION_LIST *functionList); + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/NvVideoEncoder.cpp b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/NvVideoEncoder.cpp new file mode 100644 index 000000000000..0404ecd89837 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/NvVideoEncoder.cpp @@ -0,0 +1,739 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "NvVideoEncoder.h" + +#if PLATFORM_WINDOWS + +#include "CoreMinimal.h" +#include "Misc/CoreDelegates.h" +#include "ScreenRendering.h" +#include "RendererInterface.h" +#include "PipelineStateCache.h" +#include "CommonRenderResources.h" +#include "Modules/ModuleManager.h" + +#include "SceneUtils.h" +#include "EncoderDevice.h" + +#include "VideoRecordingSystem.h" + +DEFINE_LOG_CATEGORY(NvVideoEncoder); + +const uint32 BitstreamSize = 1024 * 1024 * 2; + +#define CHECK_NV_RES(NvCall)\ +{\ + NVENCSTATUS Res = NvCall;\ + if (Res != NV_ENC_SUCCESS)\ + {\ + UE_LOG(NvVideoEncoder, Error, TEXT("`" #NvCall "` failed with error code: %d"), Res);\ + /*check(false);*/\ + return false;\ + }\ +} + +CSV_DECLARE_CATEGORY_EXTERN(GameplayMediaEncoder); + +DECLARE_CYCLE_STAT(TEXT("NvEnc_WaitForEncodeEvent"), STAT_NvEnc_WaitForEncodeEvent, STATGROUP_VideoRecordingSystem); +DECLARE_FLOAT_COUNTER_STAT(TEXT("NvEnc_CaptureToEncodeStart"), STAT_NvEnc_CaptureToEncodeStart, STATGROUP_VideoRecordingSystem); +DECLARE_FLOAT_COUNTER_STAT(TEXT("NvEnc_EncodeTime"), STAT_NvEnc_EncodeTime, STATGROUP_VideoRecordingSystem); +DECLARE_FLOAT_COUNTER_STAT(TEXT("NvEnc_EncodeToWriterTime"), STAT_NvEnc_EncodeToWriterTime, STATGROUP_VideoRecordingSystem); + +#define CLOSE_EVENT_HANDLE(EventHandle) CloseHandle(EventHandle); + +GAMEPLAYMEDIAENCODER_START + +FNvVideoEncoder::FNvVideoEncoder(const FOutputSampleCallback& OutputCallback, TSharedPtr InEncoderDevice) + : FBaseVideoEncoder(OutputCallback) + , EncoderDevice(InEncoderDevice) +{ +} + +FNvVideoEncoder::~FNvVideoEncoder() +{ + bExitEncoderThread = true; + + if (EncoderThread.IsValid()) + { + // Trigger an event to ensure we can get out of the encoder thread. + SetEvent(EncodeQueue.EncodeEvent); + + // Exit encoder runnable thread before shutting down NvEnc interface + EncoderThread->Join(); + } + ReleaseResources(); + + if (EncoderInterface) + { + NVENCSTATUS Result = NvEncodeAPI->nvEncDestroyEncoder(EncoderInterface); + if (Result != NV_ENC_SUCCESS) + { + UE_LOG(NvVideoEncoder, Error, TEXT("Failed to destroy NvEnc interface")); + } + EncoderInterface = nullptr; + } + + if (DllHandle) + { + FPlatformProcess::FreeDllHandle(DllHandle); + } +} + +bool FNvVideoEncoder::Initialize(const FVideoEncoderConfig& InConfig) +{ + if (bInitialized) + { + UE_LOG(NvVideoEncoder, Error, TEXT("Encoder already initialized. Re-initialization is not implemented.")); + return false; + } + + // Fails to register a DX11 resource in nvEncRegisterResource, need to use CUDA on Win7 + // Error: `NvEncodeAPI->nvEncRegisterResource(EncoderInterface, &RegisterResource)` failed with error code: 22 + if (!FWindowsPlatformMisc::VerifyWindowsVersion(6, 2) /*Is Win8 or higher?*/) + { + UE_LOG(NvVideoEncoder, Error, TEXT("NvEncoder for Windows 7 is not implemented")); + return false; + } + + if (!FBaseVideoEncoder::Initialize(InConfig)) + { + return false; + } + + DllHandle = FPlatformProcess::GetDllHandle(TEXT("nvEncodeAPI64.dll")); + if (DllHandle == nullptr) + { + UE_LOG(NvVideoEncoder, Error, TEXT("Failed to load NvEncode dll")); + return false; + } + + // create the encoder instance + { + // define a function pointer for creating an instance of nvEncodeAPI + typedef NVENCSTATUS(NVENCAPI *NVENCAPIPROC)(NV_ENCODE_API_FUNCTION_LIST*); + NVENCAPIPROC NvEncodeAPICreateInstanceFunc; + +# pragma warning(push) +# pragma warning(disable: 4191) // https://stackoverflow.com/a/4215425/453271 + NvEncodeAPICreateInstanceFunc = (NVENCAPIPROC)FPlatformProcess::GetDllExport((HMODULE)DllHandle, TEXT("NvEncodeAPICreateInstance")); +# pragma warning(pop) + + if (NvEncodeAPICreateInstanceFunc == nullptr) + { + UE_LOG(NvVideoEncoder, Error, TEXT("NvEncodeAPICreateInstance failed")); + return false; + } + + NvEncodeAPI.Reset(new NV_ENCODE_API_FUNCTION_LIST); + FMemory::Memzero(NvEncodeAPI.Get(), sizeof(NV_ENCODE_API_FUNCTION_LIST)); + NvEncodeAPI->version = NV_ENCODE_API_FUNCTION_LIST_VER; + CHECK_NV_RES(NvEncodeAPICreateInstanceFunc(NvEncodeAPI.Get())); + } + + // Open an encoding session + { + NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS OpenEncodeSessionExParams; + FMemory::Memzero(OpenEncodeSessionExParams); + OpenEncodeSessionExParams.version = NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER; + OpenEncodeSessionExParams.device = EncoderDevice->Device; + OpenEncodeSessionExParams.deviceType = NV_ENC_DEVICE_TYPE_DIRECTX; // Currently only DX11 is supported + OpenEncodeSessionExParams.apiVersion = NVENCAPI_VERSION; + CHECK_NV_RES(NvEncodeAPI->nvEncOpenEncodeSessionEx(&OpenEncodeSessionExParams, &EncoderInterface)); + } + + FMemory::Memzero(NvEncInitializeParams); + + // Set initialization parameters + { + NvEncInitializeParams.version = NV_ENC_INITIALIZE_PARAMS_VER; + NvEncInitializeParams.encodeWidth = Config.Width; + NvEncInitializeParams.encodeHeight = Config.Height; + NvEncInitializeParams.darWidth = Config.Width; + NvEncInitializeParams.darHeight = Config.Height; + NvEncInitializeParams.encodeGUID = NV_ENC_CODEC_H264_GUID; + NvEncInitializeParams.presetGUID = NV_ENC_PRESET_HQ_GUID; + + NvEncInitializeParams.frameRateNum = Config.Framerate; + NvEncInitializeParams.frameRateDen = 1; + + NvEncInitializeParams.enablePTD = 1; + NvEncInitializeParams.reportSliceOffsets = 0; + NvEncInitializeParams.enableSubFrameWrite = 0; + NvEncInitializeParams.encodeConfig = &NvEncConfig; + NvEncInitializeParams.maxEncodeWidth = Config.Width; + NvEncInitializeParams.maxEncodeHeight = Config.Height; + } + + // Get preset config and tweak it accordingly + { + NV_ENC_PRESET_CONFIG PresetConfig = {}; + PresetConfig.version = NV_ENC_PRESET_CONFIG_VER; + PresetConfig.presetCfg.version = NV_ENC_CONFIG_VER; + CHECK_NV_RES(NvEncodeAPI->nvEncGetEncodePresetConfig(EncoderInterface, NvEncInitializeParams.encodeGUID, NvEncInitializeParams.presetGUID, &PresetConfig)); + + FMemory::Memcpy(&NvEncConfig, &PresetConfig.presetCfg, sizeof(NV_ENC_CONFIG)); + + //NvEncConfig.profileGUID = NV_ENC_H264_PROFILE_BASELINE_GUID; + NvEncConfig.profileGUID = NV_ENC_H264_PROFILE_MAIN_GUID; + NvEncConfig.gopLength = Config.Framerate; // once a sec + NvEncConfig.encodeCodecConfig.h264Config.idrPeriod = Config.Framerate; + //NvEncConfig.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CBR; + //NvEncConfig.rcParams.rateControlMode = NV_ENC_PARAMS_RC_2_PASS_VBR; + NvEncConfig.rcParams.averageBitRate = Config.Bitrate; + + // configure "entire frame as a single slice" + NvEncConfig.encodeCodecConfig.h264Config.sliceMode = 3; + NvEncConfig.encodeCodecConfig.h264Config.sliceModeData = 1; + + // repeat SPS/PPS with each key-frame for simplicity of saving recording ring-buffer to .mp4 + // (video stream in .mp4 must start with SPS/PPS) + NvEncConfig.encodeCodecConfig.h264Config.repeatSPSPPS = 1; + + // high level is chosen because we aim at high bitrate + NvEncConfig.encodeCodecConfig.h264Config.level = NV_ENC_LEVEL_H264_51; + } + + // Get encoder capability + { + NV_ENC_CAPS_PARAM CapsParam; + FMemory::Memzero(CapsParam); + CapsParam.version = NV_ENC_CAPS_PARAM_VER; + CapsParam.capsToQuery = NV_ENC_CAPS_ASYNC_ENCODE_SUPPORT; + int32 AsyncMode = 0; + CHECK_NV_RES(NvEncodeAPI->nvEncGetEncodeCaps(EncoderInterface, NvEncInitializeParams.encodeGUID, &CapsParam, &AsyncMode)); + if (AsyncMode == 0) + { + UE_LOG(NvVideoEncoder, Error, TEXT("NvEnc doesn't support async mode")); + return false; + } + + NvEncInitializeParams.enableEncodeAsync = true; + } + + CHECK_NV_RES(NvEncodeAPI->nvEncInitializeEncoder(EncoderInterface, &NvEncInitializeParams)); + + if (!InitializeResources()) + { + return false; + } + + EncoderThread.Reset(new FThread(TEXT("NvVideoEncoder"), [this]() { EncoderCheckLoop(); })); + + bInitialized = true; + + return true; +} + + +bool FNvVideoEncoder::Start() +{ + return true; +} + +void FNvVideoEncoder::Stop() +{ +} + +bool FNvVideoEncoder::SetBitrate(uint32 Bitrate) +{ + // update config and `OutputType` + if (!FBaseVideoEncoder::SetBitrate(Bitrate)) + { + return false; + } + + NvEncInitializeParams.encodeConfig->rcParams.averageBitRate = Bitrate; + + return Reconfigure(); +} + +bool FNvVideoEncoder::SetFramerate(uint32 Framerate) +{ + // update config and `OutputType` + if (!FBaseVideoEncoder::SetFramerate(Framerate)) + { + return false; + } + + NvEncInitializeParams.frameRateNum = Framerate; + + return Reconfigure(); +} + +bool FNvVideoEncoder::Reconfigure() +{ + // reconfigure NvEnc + NV_ENC_RECONFIGURE_PARAMS NvEncReconfigureParams = {}; + NvEncReconfigureParams.version = NV_ENC_RECONFIGURE_PARAMS_VER; + FMemory::Memcpy(&NvEncReconfigureParams.reInitEncodeParams, &NvEncInitializeParams, sizeof(NvEncInitializeParams)); + + CHECK_NV_RES(NvEncodeAPI->nvEncReconfigureEncoder(EncoderInterface, &NvEncReconfigureParams)); + + return true; +} + +DECLARE_CYCLE_STAT(TEXT("FNvVideoEncoder_Process"), STAT_FNvVideoEncoder_Process, STATGROUP_VideoRecordingSystem); +DECLARE_CYCLE_STAT(TEXT("FNvVideoEncoder_Process_CheckEncoded"), STAT_FNvVideoEncoder_Process_CheckEncoded, STATGROUP_VideoRecordingSystem); + +bool FNvVideoEncoder::Process(const FTexture2DRHIRef& Texture, FTimespan Timestamp, FTimespan Duration) +{ + SCOPE_CYCLE_COUNTER(STAT_FNvVideoEncoder_Process); + + check(IsInRenderingThread()); + + return ProcessInput(Texture, Timestamp, Duration); +} + +bool FNvVideoEncoder::ProcessInput(const FTexture2DRHIRef& Texture, FTimespan Timestamp, FTimespan Duration) +{ + UE_LOG(NvVideoEncoder, Verbose, TEXT("Video input #%u: time %.3f, duration %.3f"), (uint32)InputCount, Timestamp.GetTotalSeconds(), Duration.GetTotalSeconds()); + + uint32 BufferIndexToWrite = InputCount % NumBufferedFrames; + FFrame& Frame = BufferedFrames[BufferIndexToWrite]; + // If we don't have any free buffers, then we skip this rendered frame + if (Frame.bEncoding) + { + return false; + } + + Frame.bEncoding = true; + + CSV_SCOPED_TIMING_STAT(GameplayMediaEncoder, CopyBackBuffer); + CopyBackBuffer(Texture, Frame); + + Frame.FrameIdx = InputCount; + Frame.TimeStamp = Timestamp; + Frame.Duration = Duration; + Frame.CaptureTimeStamp = FTimespan::FromSeconds(FPlatformTime::Seconds()); + + FFrame* FramePtr = &Frame; + ExecuteRHICommand([this, FramePtr]() { + EncodeQueue.Push(FramePtr); + }); + + InputCount++; + + return true; +} + +DECLARE_CYCLE_STAT(TEXT("FNvVideoEncoder_CopyBackBuffer"), STAT_FNvVideoEncoder_CopyBackBuffer, STATGROUP_VideoRecordingSystem); + +void FNvVideoEncoder::CopyBackBuffer(const FTexture2DRHIRef& SrcBackBuffer, const FFrame& DstFrame) +{ + SCOPE_CYCLE_COUNTER(STAT_FNvVideoEncoder_CopyBackBuffer); + + IRendererModule* RendererModule = &FModuleManager::GetModuleChecked("Renderer"); + FRHICommandListImmediate& RHICmdList = FRHICommandListExecutor::GetImmediateCommandList(); + + SCOPED_DRAW_EVENTF(RHICmdList, NvVideoEncoder_CopyBackBuffer, TEXT("NvVideoEncoder_CopyBackBuffer %u"), static_cast(DstFrame.FrameIdx)); + + if (SrcBackBuffer->GetFormat() == DstFrame.ResolvedBackBuffer->GetFormat() && + SrcBackBuffer->GetSizeXY() == DstFrame.ResolvedBackBuffer->GetSizeXY()) + { + RHICmdList.CopyToResolveTarget(SrcBackBuffer, DstFrame.ResolvedBackBuffer, FResolveParams()); + } + else // Texture format mismatch, use a shader to do the copy. + { + SetRenderTarget(RHICmdList, DstFrame.ResolvedBackBuffer, FTextureRHIRef()); + RHICmdList.SetViewport(0, 0, 0.0f, DstFrame.ResolvedBackBuffer->GetSizeX(), DstFrame.ResolvedBackBuffer->GetSizeY(), 1.0f); + + FGraphicsPipelineStateInitializer GraphicsPSOInit; + RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit); + GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI(); + GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI(); + GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState::GetRHI(); + + TShaderMap* ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel); + TShaderMapRef VertexShader(ShaderMap); + TShaderMapRef PixelShader(ShaderMap); + + GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GFilterVertexDeclaration.VertexDeclarationRHI; + GraphicsPSOInit.BoundShaderState.VertexShaderRHI = GETSAFERHISHADER_VERTEX(*VertexShader); + GraphicsPSOInit.BoundShaderState.PixelShaderRHI = GETSAFERHISHADER_PIXEL(*PixelShader); + GraphicsPSOInit.PrimitiveType = PT_TriangleList; + + SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit); + + if (DstFrame.ResolvedBackBuffer->GetSizeX() != SrcBackBuffer->GetSizeX() || DstFrame.ResolvedBackBuffer->GetSizeY() != SrcBackBuffer->GetSizeY()) + PixelShader->SetParameters(RHICmdList, TStaticSamplerState::GetRHI(), SrcBackBuffer); + else + PixelShader->SetParameters(RHICmdList, TStaticSamplerState::GetRHI(), SrcBackBuffer); + + RendererModule->DrawRectangle( + RHICmdList, + 0, 0, // Dest X, Y + DstFrame.ResolvedBackBuffer->GetSizeX(), // Dest Width + DstFrame.ResolvedBackBuffer->GetSizeY(), // Dest Height + 0, 0, // Source U, V + 1, 1, // Source USize, VSize + DstFrame.ResolvedBackBuffer->GetSizeXY(), // Target buffer size + FIntPoint(1, 1), // Source texture size + *VertexShader, + EDRF_Default); + } +} + +bool FNvVideoEncoder::InitFrameInputBuffer(FFrame& Frame) +{ + // Create resolved back buffer texture + { + // Make sure format used here is compatible with NV_ENC_BUFFER_FORMAT specified later in NV_ENC_REGISTER_RESOURCE bufferFormat + FRHIResourceCreateInfo CreateInfo; + // TexCreate_Shared textures are forced to be EPixelFormat::PF_B8G8R8A8. + Frame.ResolvedBackBuffer = RHICreateTexture2D(Config.Width, Config.Height, EPixelFormat::PF_B8G8R8A8, 1, 1, TexCreate_RenderTargetable | TexCreate_Shared, CreateInfo); + } + + // Share this texture with the encoder device. + { + ID3D11Texture2D* ResolvedBackBuffer = (ID3D11Texture2D*)Frame.ResolvedBackBuffer->GetTexture2D()->GetNativeResource(); + + IDXGIResource* DXGIResource = NULL; + CHECK_HR(ResolvedBackBuffer->QueryInterface(__uuidof(IDXGIResource), (LPVOID*)&DXGIResource)); + + HANDLE SharedHandle; + CHECK_HR(DXGIResource->GetSharedHandle(&SharedHandle)); + CHECK_HR(DXGIResource->Release()); + + CHECK_HR(EncoderDevice->Device->OpenSharedResource(SharedHandle, __uuidof(ID3D11Texture2D), (LPVOID*)&Frame.SharedBackBuffer)); + } + + FMemory::Memzero(Frame.InputFrame); + // Register input back buffer + { + NV_ENC_REGISTER_RESOURCE RegisterResource; + FMemory::Memzero(RegisterResource); + RegisterResource.version = NV_ENC_REGISTER_RESOURCE_VER; + RegisterResource.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX; + RegisterResource.resourceToRegister = (void*)Frame.SharedBackBuffer; + RegisterResource.width = Config.Width; + RegisterResource.height = Config.Height; + // TexCreate_Shared textures are forced to be EPixelFormat::PF_B8G8R8A8. + RegisterResource.bufferFormat = NV_ENC_BUFFER_FORMAT_ABGR; // Make sure ResolvedBackBuffer is created with a compatible format + CHECK_NV_RES(NvEncodeAPI->nvEncRegisterResource(EncoderInterface, &RegisterResource)); + + Frame.InputFrame.RegisteredResource = RegisterResource.registeredResource; + Frame.InputFrame.BufferFormat = RegisterResource.bufferFormat; + } + + // Map input buffer resource + { + NV_ENC_MAP_INPUT_RESOURCE MapInputResource; + FMemory::Memzero(MapInputResource); + MapInputResource.version = NV_ENC_MAP_INPUT_RESOURCE_VER; + MapInputResource.registeredResource = Frame.InputFrame.RegisteredResource; + CHECK_NV_RES(NvEncodeAPI->nvEncMapInputResource(EncoderInterface, &MapInputResource)); + Frame.InputFrame.MappedResource = MapInputResource.mappedResource; + } + + return true; +} + +bool FNvVideoEncoder::InitializeResources() +{ + for (uint32 i = 0; i < NumBufferedFrames; ++i) + { + FFrame& Frame = BufferedFrames[i]; + + if (!InitFrameInputBuffer(Frame)) + { + return false; + } + + FMemory::Memzero(Frame.OutputFrame); + // Create output bitstream buffer + { + NV_ENC_CREATE_BITSTREAM_BUFFER CreateBitstreamBuffer; + FMemory::Memzero(CreateBitstreamBuffer); + CreateBitstreamBuffer.version = NV_ENC_CREATE_BITSTREAM_BUFFER_VER; + CreateBitstreamBuffer.size = BitstreamSize; + CreateBitstreamBuffer.memoryHeap = NV_ENC_MEMORY_HEAP_SYSMEM_CACHED; + CHECK_NV_RES(NvEncodeAPI->nvEncCreateBitstreamBuffer(EncoderInterface, &CreateBitstreamBuffer)); + Frame.OutputFrame.BitstreamBuffer = CreateBitstreamBuffer.bitstreamBuffer; + } + + RegisterAsyncEvent(&Frame.OutputFrame.EventHandle); + } + + return true; +} + +bool FNvVideoEncoder::ReleaseFrameInputBuffer(FNvVideoEncoder::FFrame& Frame) +{ + if (Frame.InputFrame.MappedResource) + { + CHECK_NV_RES(NvEncodeAPI->nvEncUnmapInputResource(EncoderInterface, Frame.InputFrame.MappedResource)); + Frame.InputFrame.MappedResource = nullptr; + } + + if (Frame.InputFrame.RegisteredResource) + { + CHECK_NV_RES(NvEncodeAPI->nvEncUnregisterResource(EncoderInterface, Frame.InputFrame.RegisteredResource)); + Frame.InputFrame.RegisteredResource = nullptr; + } + + Frame.ResolvedBackBuffer.SafeRelease(); + if (Frame.SharedBackBuffer) + { + Frame.SharedBackBuffer->Release(); + } + + return true; +} + +bool FNvVideoEncoder::RegisterAsyncEvent(void** OutEvent) +{ + NV_ENC_EVENT_PARAMS EventParams; + FMemory::Memzero(EventParams); + EventParams.version = NV_ENC_EVENT_PARAMS_VER; +#if defined PLATFORM_WINDOWS + EventParams.completionEvent = CreateEvent(nullptr, true, false, nullptr); +#endif + CHECK_NV_RES(NvEncodeAPI->nvEncRegisterAsyncEvent(EncoderInterface, &EventParams)); + *OutEvent = EventParams.completionEvent; + + return true; +} + +bool FNvVideoEncoder::UnregisterAsyncEvent(void* Event) +{ + if (Event) + { + NV_ENC_EVENT_PARAMS EventParams; + FMemory::Memzero(EventParams); + EventParams.version = NV_ENC_EVENT_PARAMS_VER; + EventParams.completionEvent = Event; + CHECK_NV_RES(NvEncodeAPI->nvEncUnregisterAsyncEvent(EncoderInterface, &EventParams)); + } + + return true; +} + +bool FNvVideoEncoder::ReleaseResources() +{ + for (uint32 i = 0; i < NumBufferedFrames; ++i) + { + FFrame& Frame = BufferedFrames[i]; + + if (!ReleaseFrameInputBuffer(Frame)) + { + return false; + } + + if (Frame.OutputFrame.BitstreamBuffer) + { + CHECK_NV_RES(NvEncodeAPI->nvEncDestroyBitstreamBuffer(EncoderInterface, Frame.OutputFrame.BitstreamBuffer)); + Frame.OutputFrame.BitstreamBuffer = nullptr; + } + + if (Frame.OutputFrame.EventHandle) + { + UnregisterAsyncEvent(Frame.OutputFrame.EventHandle); + CLOSE_EVENT_HANDLE(Frame.OutputFrame.EventHandle); + Frame.OutputFrame.EventHandle = nullptr; + } + } + + return true; +} + +void FNvVideoEncoder::EncoderCheckLoop() +{ + // This thread will both encode frames and will also wait for the next frame + // to finish encoding. + while (true) + { + // Wait for either the command to encode frames or the information + // that the next frame has finished encoding. + // The signalling events are a pair of handles for windows events so we + // can wait for one or the other. + enum EncodeEvents + { + START_ENCODING_EVENT = 0, + FINISHED_ENCODING_EVENT = 1, + NUM_ENCODING_EVENTS = 2 + }; + HANDLE Handles[NUM_ENCODING_EVENTS]; + Handles[START_ENCODING_EVENT] = EncodeQueue.EncodeEvent; + FFrame& Frame = BufferedFrames[OutputCount % NumBufferedFrames]; + Handles[FINISHED_ENCODING_EVENT] = Frame.OutputFrame.EventHandle; + DWORD Result = WaitForMultipleObjects(NUM_ENCODING_EVENTS, Handles, false, INFINITE); + + if (!bExitEncoderThread) + { + if (Result == WAIT_OBJECT_0 + START_ENCODING_EVENT) + { + // Get the list of all frames we want to encode. + FFrame* Frames[NumBufferedFrames]; + int NumFrames; + EncodeQueue.PopAll(Frames, NumFrames); + for (int Idx = 0; Idx < NumFrames; Idx++) + { + SubmitFrameToEncoder(*Frames[Idx]); + } + } + else if (Result == WAIT_OBJECT_0 + FINISHED_ENCODING_EVENT) + { + // A frame has finished encoding so we can now handle the + // encoded data. + Frame.EncodeEndTimeStamp = FTimespan::FromSeconds(FPlatformTime::Seconds()); + ResetEvent(Frame.OutputFrame.EventHandle); + HandleEncodedFrame(Frame); + ++OutputCount; + } + } + else + { + break; + } + } +} + +DECLARE_CYCLE_STAT(TEXT("FNvVideoEncoder_TransferRenderTargetToHWEncoder"), STAT_FNvVideoEncoder_TransferRenderTargetToHWEncoder, STATGROUP_VideoRecordingSystem); +DECLARE_CYCLE_STAT(TEXT("FNvVideoEncoder_TransferRenderTargetToHWEncoder_nvEncEncodePicture"), STAT_FNvVideoEncoder_TransferRenderTargetToHWEncoder_nvEncEncodePicture, STATGROUP_VideoRecordingSystem); + +bool FNvVideoEncoder::SubmitFrameToEncoder(FFrame& Frame) +{ + SCOPE_CYCLE_COUNTER(STAT_FNvVideoEncoder_TransferRenderTargetToHWEncoder); + CSV_SCOPED_TIMING_STAT(GameplayMediaEncoder, TransferRenderTargetToHwEncoder); + + NV_ENC_PIC_PARAMS PicParams; + FMemory::Memzero(PicParams); + PicParams.version = NV_ENC_PIC_PARAMS_VER; + PicParams.inputBuffer = Frame.InputFrame.MappedResource; + PicParams.bufferFmt = Frame.InputFrame.BufferFormat; + PicParams.inputWidth = Config.Width; + PicParams.inputHeight = Config.Height; + PicParams.outputBitstream = Frame.OutputFrame.BitstreamBuffer; + PicParams.completionEvent = Frame.OutputFrame.EventHandle; + PicParams.inputTimeStamp = Frame.FrameIdx; + PicParams.pictureStruct = NV_ENC_PIC_STRUCT_FRAME; + + Frame.EncodeStartTimeStamp = FTimespan::FromSeconds(FPlatformTime::Seconds()); + + { + SCOPE_CYCLE_COUNTER(STAT_FNvVideoEncoder_TransferRenderTargetToHWEncoder_nvEncEncodePicture); + CSV_SCOPED_TIMING_STAT(GameplayMediaEncoder, TransferRenderTargetToHWEncoder_nvEncEncodePicture); + FRHICommandList& RHICmdList = FRHICommandListExecutor::GetImmediateCommandList(); + SCOPED_DRAW_EVENTF(RHICmdList, NvVideoEncoder_TransferRenderTargetToHWEncoder, TEXT("NvVideoEncoder_TransferRenderTargetToHWEncoder %u"), static_cast(Frame.FrameIdx)); + + CHECK_NV_RES(NvEncodeAPI->nvEncEncodePicture(EncoderInterface, &PicParams)); + } + + return true; +} + +DECLARE_CYCLE_STAT(TEXT("FNvVideoEncoder_ProcessEncodedFrame"), STAT_FNvVideoEncoder_ProcessEncodedFrame, STATGROUP_VideoRecordingSystem); +DECLARE_CYCLE_STAT(TEXT("FNvVideoEncoder_ProcessEncodedFrame_Lock"), STAT_FNvVideoEncoder_ProcessEncodedFrame_Lock, STATGROUP_VideoRecordingSystem); +DECLARE_CYCLE_STAT(TEXT("FNvVideoEncoder_ProcessEncodedFrame_Copy"), STAT_FNvVideoEncoder_ProcessEncodedFrame_Copy, STATGROUP_VideoRecordingSystem); +DECLARE_CYCLE_STAT(TEXT("FNvVideoEncoder_ProcessEncodedFrame_Unlock"), STAT_FNvVideoEncoder_ProcessEncodedFrame_Unlock, STATGROUP_VideoRecordingSystem); +DECLARE_CYCLE_STAT(TEXT("FNvVideoEncoder_ProcessEncodedFrame_Callback"), STAT_FNvVideoEncoder_ProcessEncodedFrame_Callback, STATGROUP_VideoRecordingSystem); + +bool FNvVideoEncoder::HandleEncodedFrame(FNvVideoEncoder::FFrame& Frame) +{ + SCOPE_CYCLE_COUNTER(STAT_FNvVideoEncoder_ProcessEncodedFrame); + + // If the expected frame hasn't been doing encoding, then nothing to do + checkf(Frame.bEncoding, TEXT("This should not happen")); + if (!Frame.bEncoding) + { + return false; + } + + FTimespan Now = FTimespan::FromSeconds(FPlatformTime::Seconds()); + double CaptureToEncodeStartTime = (Frame.EncodeStartTimeStamp - Frame.CaptureTimeStamp).GetTotalMilliseconds(); + double EncodeTime = (Frame.EncodeEndTimeStamp - Frame.EncodeStartTimeStamp).GetTotalMilliseconds(); + double EncodeToWriterTime = (Now - Frame.EncodeEndTimeStamp).GetTotalMilliseconds(); + + SET_FLOAT_STAT(STAT_NvEnc_CaptureToEncodeStart, CaptureToEncodeStartTime); + SET_FLOAT_STAT(STAT_NvEnc_EncodeTime, EncodeTime); + SET_FLOAT_STAT(STAT_NvEnc_EncodeToWriterTime, EncodeToWriterTime); + + // log encoding latency for every 1000th frame + if (Frame.FrameIdx % 1000 == 0) + { + UE_LOG(NvVideoEncoder, Verbose, TEXT("#%d %.2f %.2f %.2f"), + Frame.FrameIdx, + CaptureToEncodeStartTime, + EncodeTime, + EncodeToWriterTime); + } + + bool bIdrFrame = false; + + // Retrieve encoded frame from output buffer + { + NV_ENC_LOCK_BITSTREAM LockBitstream = {}; + LockBitstream.version = NV_ENC_LOCK_BITSTREAM_VER; + LockBitstream.outputBitstream = Frame.OutputFrame.BitstreamBuffer; + LockBitstream.doNotWait = true; + FRHICommandList& RHICmdList = FRHICommandListExecutor::GetImmediateCommandList(); + + { + SCOPE_CYCLE_COUNTER(STAT_FNvVideoEncoder_ProcessEncodedFrame_Lock); + CSV_SCOPED_TIMING_STAT(GameplayMediaEncoder, ProcessEncodedFrame_Lock); + SCOPED_DRAW_EVENTF(RHICmdList, NvVideoEncoder_ProcessEncodedFrame_Lock, TEXT("NvVideoEncoder_ProcessEncodedFrame_Lock %u"), static_cast(Frame.FrameIdx)); + CHECK_NV_RES(NvEncodeAPI->nvEncLockBitstream(EncoderInterface, &LockBitstream)); + } + + { + SCOPE_CYCLE_COUNTER(STAT_FNvVideoEncoder_ProcessEncodedFrame_Copy); + CSV_SCOPED_TIMING_STAT(GameplayMediaEncoder, ProcessEncodedFrame_Copy); + Frame.EncodedFrame.SetNum(LockBitstream.bitstreamSizeInBytes); + FMemory::Memcpy(Frame.EncodedFrame.GetData(), LockBitstream.bitstreamBufferPtr, LockBitstream.bitstreamSizeInBytes); + } + + bIdrFrame = LockBitstream.pictureType == NV_ENC_PIC_TYPE_IDR; + + { + SCOPE_CYCLE_COUNTER(STAT_FNvVideoEncoder_ProcessEncodedFrame_Unlock); + CSV_SCOPED_TIMING_STAT(GameplayMediaEncoder, ProcessEncodedFrame_Unlock); + SCOPED_DRAW_EVENTF(RHICmdList, NvVideoEncoder_ProcessEncodedFrame_Unlock, TEXT("NvVideoEncoder_ProcessEncodedFrame_Unlock %u"), static_cast(Frame.FrameIdx)); + CHECK_NV_RES(NvEncodeAPI->nvEncUnlockBitstream(EncoderInterface, Frame.OutputFrame.BitstreamBuffer)); + } + } + + { + SCOPE_CYCLE_COUNTER(STAT_FNvVideoEncoder_ProcessEncodedFrame_Callback); + + FGameplayMediaEncoderSample OutputSample{ EMediaType::Video }; + if (!OutputSample.CreateSample()) + { + return false; + } + int32 BufferSize = Frame.EncodedFrame.Num(); + uint32 Alignment = 0; + TRefCountPtr WmfBuffer; + CHECK_HR(MFCreateAlignedMemoryBuffer(BufferSize, Alignment, WmfBuffer.GetInitReference())); + + CHECK_HR(OutputSample.GetSample()->SetUINT32(MFSampleExtension_CleanPoint, bIdrFrame ? 1 : 0)); + + // Copy data to the WmfBuffer + uint8* Dst = nullptr; + CHECK_HR(WmfBuffer->Lock(&Dst, nullptr, nullptr)); + FMemory::Memcpy(Dst, Frame.EncodedFrame.GetData(), Frame.EncodedFrame.Num()); + CHECK_HR(WmfBuffer->Unlock()); + CHECK_HR(WmfBuffer->SetCurrentLength(Frame.EncodedFrame.Num())); + + CHECK_HR(OutputSample.GetSample()->AddBuffer(WmfBuffer)); + OutputSample.SetTime(Frame.TimeStamp); + OutputSample.SetDuration(Frame.Duration); + + UE_LOG(NvVideoEncoder, Verbose, TEXT("encoded frame #%d: time %.3f, duration %.3f, size %d%s"), Frame.FrameIdx, OutputSample.GetTime().GetTotalSeconds(), OutputSample.GetDuration().GetTotalSeconds(), BufferSize, OutputSample.IsVideoKeyFrame() ? TEXT(", key frame") : TEXT("")); + + if (!OutputCallback(OutputSample)) + { + return false; + } + } + + Frame.bEncoding = false; + + return true; +} + +#undef CHECK_NV_RES + +GAMEPLAYMEDIAENCODER_END + +#endif // PLATFORM_WINDOWS + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/NvVideoEncoder.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/NvVideoEncoder.h new file mode 100644 index 000000000000..229d3d8179d5 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/NvVideoEncoder.h @@ -0,0 +1,169 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "BaseVideoEncoder.h" + +#if PLATFORM_WINDOWS + +THIRD_PARTY_INCLUDES_START + #include "NvEncoder/nvEncodeAPI.h" +THIRD_PARTY_INCLUDES_END + +#include "D3D11VideoProcessor.h" + +DECLARE_LOG_CATEGORY_EXTERN(NvVideoEncoder, Log, VeryVerbose); + +class FEncoderDevice; +class FThread; + +class FNvVideoEncoder : public FBaseVideoEncoder +{ +public: + explicit FNvVideoEncoder(const FOutputSampleCallback& OutputCallback, TSharedPtr InEncoderDevice); + ~FNvVideoEncoder() override; + + bool Initialize(const FVideoEncoderConfig& Config) override; + bool Start() override; + void Stop() override; + bool Process(const FTexture2DRHIRef& Texture, FTimespan Timestamp, FTimespan Duration) override; + + bool SetBitrate(uint32 Bitrate) override; + bool SetFramerate(uint32 Framerate) override; + +private: + struct FInputFrame + { + void* RegisteredResource = nullptr; + NV_ENC_INPUT_PTR MappedResource = nullptr; + NV_ENC_BUFFER_FORMAT BufferFormat; + }; + + struct FOutputFrame + { + NV_ENC_OUTPUT_PTR BitstreamBuffer = nullptr; + HANDLE EventHandle = nullptr; + }; + + struct FFrame + { + FTexture2DRHIRef ResolvedBackBuffer; + ID3D11Texture2D* SharedBackBuffer = nullptr; + FInputFrame InputFrame; + FOutputFrame OutputFrame; + TArray EncodedFrame; + uint64 FrameIdx = 0; + + // These are passed to the mp4 writer + FTimespan TimeStamp = 0; + FTimespan Duration = 0; + + // Timestamps to measure encoding latency + FTimespan CaptureTimeStamp; + FTimespan EncodeStartTimeStamp; + FTimespan EncodeEndTimeStamp; + + FThreadSafeBool bEncoding = false; + }; + + bool ProcessInput(const FTexture2DRHIRef& Texture, FTimespan Timestamp, FTimespan Duration); + + void CopyBackBuffer(const FTexture2DRHIRef& SrcBackBuffer, const FFrame& DstFrame); + bool InitFrameInputBuffer(FFrame& Frame); + bool InitializeResources(); + bool ReleaseFrameInputBuffer(FNvVideoEncoder::FFrame& Frame); + bool RegisterAsyncEvent(void** OutEvent); + bool UnregisterAsyncEvent(void* Event); + bool ReleaseResources(); + void EncoderCheckLoop(); + bool SubmitFrameToEncoder(FFrame& Frame); + bool HandleEncodedFrame(FNvVideoEncoder::FFrame& Frame); + + bool Reconfigure(); + + void* DllHandle = nullptr; + bool bInitialized = false; + TUniquePtr NvEncodeAPI; + void* EncoderInterface = nullptr; + static const uint32 NumBufferedFrames = 3; + FFrame BufferedFrames[NumBufferedFrames]; + FD3D11VideoProcessor D3D11VideoProcessor; + + NV_ENC_INITIALIZE_PARAMS NvEncInitializeParams; + NV_ENC_CONFIG NvEncConfig; + + // After a back buffer is processed and copied then we will want to send it + // to the encoder. This happens on a different thread so we use a queue of + // frame pointers to tell the thread which frames should be encoded. + struct FEncodeQueue + { + // The frames which we should encode. + // We can never be encoding more frames that can be buffered. + FFrame* Frames[NumBufferedFrames] = { nullptr }; + + // The start position of elements in this FIFO ring buffer queue. + int Start = 0; + + // The number of elements in this FIFO ring buffer queue. + int Length = 0; + + // Allow access by the Render Thread and the Pixel Streaming Encoder + // thread. + FCriticalSection CriticalSection; + + // An event to signal the Pixel Streaming Encoder thread that it can + // encode some frames. + HANDLE EncodeEvent = CreateEvent(nullptr, false, false, nullptr); + + virtual ~FEncodeQueue() + { + CloseHandle(EncodeEvent); + } + + // Add another frame to be encoded. + void Push(FFrame* Frame) + { + FScopeLock ScopedLock(&CriticalSection); + bool bWasEmpty = Length == 0; + int Position = (Start + Length) % NumBufferedFrames; + Frames[Position] = Frame; + Length++; + check(Length <= NumBufferedFrames); + if (bWasEmpty) + { + SetEvent(EncodeEvent); + } + } + + // Get the list of all frame which we should encode. + void PopAll(FFrame* OutFrames[NumBufferedFrames], int& OutNumFrames) + { + FScopeLock ScopedLock(&CriticalSection); + OutNumFrames = Length; + for (int Position = 0; Position < Length; Position++) + { + OutFrames[Position] = Frames[Start]; + Start = (Start + 1) % NumBufferedFrames; + } + Length = 0; + ResetEvent(EncodeEvent); + } + }; + + // We use a separate D3D device with NvEnv so we can do the encoding on a + // separate thread without problems. + TSharedPtr EncoderDevice; + + // The Pixel Streaming Encoder thread which NvEnc encodes on. + TUniquePtr EncoderThread; + + // We enqueue frame pointers to tell the Pixel Streaming Encoder thread + // which frames to encode. + FEncodeQueue EncodeQueue; + + // Whether the Pixel Streaming Encoder thread is complete and should exit. + FThreadSafeBool bExitEncoderThread = false; +}; + +#endif // PLATFORM_WINDOWS + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/UtilityShaders.cpp b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/UtilityShaders.cpp new file mode 100644 index 000000000000..8006de6ca664 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/UtilityShaders.cpp @@ -0,0 +1,15 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +/*============================================================================= + UtilityShaders.cpp: Utility shaders for Windows Media Foundation pipeline. +=============================================================================*/ + +#include "UtilityShaders.h" + +GAMEPLAYMEDIAENCODER_START + +// Shader implementations. +IMPLEMENT_SHADER_TYPE(,FScreenSwizzlePS, TEXT("/Engine/Private/GameplayMediaEncoderShaders.usf"), TEXT("ScreenSwizzlePS"), SF_Pixel); + +GAMEPLAYMEDIAENCODER_END + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/UtilityShaders.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/UtilityShaders.h new file mode 100644 index 000000000000..c375e48a3575 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/UtilityShaders.h @@ -0,0 +1,58 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +/*============================================================================= + UtilityShaders.h: Screen rendering definitions. +=============================================================================*/ + +#pragma once + +#include "CoreMinimal.h" +#include "RHI.h" +#include "RenderResource.h" +#include "Shader.h" +#include "GlobalShader.h" +#include "ShaderParameterUtils.h" + +#include "GameplayMediaEncoderCommon.h" + +/** +* A pixel shader for rendering a textured screen element that converts color channels from RGBA to BGRA. +*/ +class FScreenSwizzlePS : public FGlobalShader +{ + DECLARE_SHADER_TYPE(FScreenSwizzlePS, Global); + +public: + static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) { return true; } + + FScreenSwizzlePS(const ShaderMetaType::CompiledShaderInitializerType& Initializer) : + FGlobalShader(Initializer) + { + InTexture.Bind(Initializer.ParameterMap, TEXT("InTexture"), SPF_Mandatory); + InTextureSampler.Bind(Initializer.ParameterMap, TEXT("InTextureSampler")); + } + FScreenSwizzlePS() {} + + void SetParameters(FRHICommandList& RHICmdList, const FTexture* Texture) + { + SetTextureParameter(RHICmdList, GetPixelShader(), InTexture, InTextureSampler, Texture); + } + + void SetParameters(FRHICommandList& RHICmdList, FSamplerStateRHIParamRef SamplerStateRHI, FTextureRHIParamRef TextureRHI) + { + SetTextureParameter(RHICmdList, GetPixelShader(), InTexture, InTextureSampler, SamplerStateRHI, TextureRHI); + } + + virtual bool Serialize(FArchive& Ar) override + { + bool bShaderHasOutdatedParameters = FGlobalShader::Serialize(Ar); + Ar << InTexture; + Ar << InTextureSampler; + return bShaderHasOutdatedParameters; + } + +private: + FShaderResourceParameter InTexture; + FShaderResourceParameter InTextureSampler; +}; + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/WmfVideoEncoder.cpp b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/WmfVideoEncoder.cpp new file mode 100644 index 000000000000..2989664620d4 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/WmfVideoEncoder.cpp @@ -0,0 +1,525 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "WmfVideoEncoder.h" + +#if PLATFORM_WINDOWS + +#include "ScreenRendering.h" +#include "RendererInterface.h" +#include "RHIStaticStates.h" +#include "PipelineStateCache.h" +#include "Misc/CoreDelegates.h" +#include "Modules/ModuleManager.h" +#include "UtilityShaders.h" +#include "CommonRenderResources.h" + +GAMEPLAYMEDIAENCODER_START + +FWmfVideoEncoder::FWmfVideoEncoder(const FOutputSampleCallback& OutputCallback) : + FBaseVideoEncoder(OutputCallback) +{ +} + +bool FWmfVideoEncoder::Initialize(const FVideoEncoderConfig& InConfig) +{ + // Fails to create H264 video processor in CoCreateInstance + // Error: `CoCreateInstance(CLSID_VideoProcessorMFT, nullptr, CLSCTX_INPROC_SERVER, IID_IMFTransform, reinterpret_cast(&VideoProcessor))` failed: 0x80040154 - Class not registered + if (!FWindowsPlatformMisc::VerifyWindowsVersion(6, 2) /*Is Win8 or higher?*/) + { + UE_LOG(GameplayMediaEncoder, Error, TEXT("WmfVideoEncoder for Windows 7 is not implemented")); + return false; + } + + if (!FBaseVideoEncoder::Initialize(InConfig)) + { + return false; + } + + UE_LOG(GameplayMediaEncoder, Log, TEXT("VideoEncoder config: %dx%d, %d FPS, %.2f Mbps"), InConfig.Width, InConfig.Height, InConfig.Framerate, InConfig.Bitrate / 1000000.0f); + + return InitializeVideoProcessor() && InitializeEncoder(); +} + +bool FWmfVideoEncoder::Process(const FTexture2DRHIRef& Texture, FTimespan Timestamp, FTimespan Duration) +{ + check(IsInRenderingThread()); + + UE_LOG(GameplayMediaEncoder, Verbose, TEXT("Video input #%u: time %.3f, duration %.3f"), (uint32)InputCount, Timestamp.GetTotalSeconds(), Duration.GetTotalSeconds()); + InputCount++; + + if (!EnqueueInputFrame(Texture, Timestamp, Duration)) + { + UE_LOG(GameplayMediaEncoder, Error, TEXT("Failed to enqueue media buffer")); + return false; + } + + return ProcessVideoProcessorInputFrame() && + ProcessVideoProcessorOutputFrame() && + ProcessEncoderInputFrame() && + ProcessEncoderOutputFrame(); +} + +bool FWmfVideoEncoder::Start() +{ + return true; +} + +void FWmfVideoEncoder::Stop() +{ +} + +bool FWmfVideoEncoder::Flush() +{ + //while (!InputFrameQueue.IsEmpty()) + //{ + // ProcessInputFrame(); + // ProcessOutputFrame(); + //} + + //// Signal end of input stream, process remaining unfinished frames + //CHECK_HR(H264Encoder->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, 0)); + //CHECK_HR(H264Encoder->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, 0)); + + //while (OutputFrameProcessedCount.GetValue() < InputFrameProcessedCount) + //{Video sample encoded + // ProcessOutputFrame(); + //} + + return true; +} + +bool FWmfVideoEncoder::InitializeVideoProcessor() +{ + bool bResult = true; + + // Create H264 encoder + CHECK_HR(CoCreateInstance(CLSID_VideoProcessorMFT, nullptr, CLSCTX_INPROC_SERVER, IID_IMFTransform, reinterpret_cast(&VideoProcessor))); + + if (!SetVideoProcessorInputMediaType() || !SetVideoProcessorOutputMediaType()) + { + VideoProcessor->Release(); + return false; + } + + return true; +} + +bool FWmfVideoEncoder::SetVideoProcessorInputMediaType() +{ + TRefCountPtr InputMediaType; + CHECK_HR(MFCreateMediaType(InputMediaType.GetInitReference())); + CHECK_HR(InputMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)); + CHECK_HR(InputMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_ARGB32)); + CHECK_HR(MFSetAttributeSize(InputMediaType, MF_MT_FRAME_SIZE, Config.Width, Config.Height)); + CHECK_HR(VideoProcessor->SetInputType(0, InputMediaType, 0)); + + return true; +} + +bool FWmfVideoEncoder::SetVideoProcessorOutputMediaType() +{ + // `OutputType` is initialized in `FBaseVideoEncoder::Initialize()` + CHECK_HR(VideoProcessor->SetOutputType(0, OutputType, 0)); + + return true; +} + +bool FWmfVideoEncoder::ProcessVideoProcessorInputFrame() +{ + bool bResult = true; + + if (!InputQueue.IsEmpty()) + { + FGameplayMediaEncoderSample Sample; + bResult = InputQueue.Peek(Sample); + check(bResult); + HRESULT HResult = VideoProcessor->ProcessInput(0, Sample.GetSample(), 0); + if (SUCCEEDED(HResult)) + { + bResult = InputQueue.Pop(); + check(bResult); + InputQueueSize.Decrement(); + InputFrameProcessedCount++; + UE_LOG(GameplayMediaEncoder, VeryVerbose, TEXT("Video processor processed %d input frames, queue size %d"), InputFrameProcessedCount, InputQueueSize.GetValue()); + } + else + { + UE_LOG(GameplayMediaEncoder, Error, TEXT("FWmfVideoEncoder->ProcessVideoProcessorInputFrame failed: %d"), HResult); + return false; + } + } + + return true; +} + +bool FWmfVideoEncoder::ProcessVideoProcessorOutputFrame() +{ + bool bOutputIncomplete = true; + while (bOutputIncomplete) + { + FGameplayMediaEncoderSample Sample{ EMediaType::Video }; + CreateInputSample(Sample); + + MFT_OUTPUT_DATA_BUFFER OutputDataBuffer; + OutputDataBuffer.dwStreamID = 0; + OutputDataBuffer.pSample = Sample.GetSample(); + OutputDataBuffer.dwStatus = 0; + OutputDataBuffer.pEvents = nullptr; + + // have to reset sample before use + TRefCountPtr MediaBuffer; + CHECK_HR(Sample.GetSample()->GetBufferByIndex(0, MediaBuffer.GetInitReference())); + CHECK_HR(MediaBuffer->SetCurrentLength(0)); + + DWORD Status; + HRESULT HResult = VideoProcessor->ProcessOutput(0, 1, &OutputDataBuffer, &Status); + if (OutputDataBuffer.pEvents) + { + // https://docs.microsoft.com/en-us/windows/desktop/api/mftransform/nf-mftransform-imftransform-processoutput + // The caller is responsible for releasing any events that the MFT allocates. + OutputDataBuffer.pEvents->Release(); + OutputDataBuffer.pEvents = nullptr; + } + if (SUCCEEDED(HResult)) + { + if (OutputDataBuffer.pSample) + { + EncoderInputQueue.Enqueue(Sample); + EncoderInputQueueSize.Increment(); + } + + bOutputIncomplete = (OutputDataBuffer.dwStatus == MFT_OUTPUT_DATA_BUFFER_INCOMPLETE); + } + else + { + UE_LOG(GameplayMediaEncoder, Error, TEXT("FWmfVideoEncoder::ProcessVideoProcessorOutputFrame failed: %d"), HResult); + return false; + } + } + + return true; +} + +bool FWmfVideoEncoder::CreateInputSample(FGameplayMediaEncoderSample& Sample) +{ + if (!Sample.CreateSample()) + { + return false; + } + + // Use a single 8-bit texture to store NV12 texture as UE4 doesn't support NV12 texture directly. + FRHIResourceCreateInfo CreateInfo; + FTexture2DRHIRef Texture = RHICreateTexture2D(Config.Width, Config.Height * 3 / 2, PF_G8, 1, 1, 0, CreateInfo); + ID3D11Texture2D* DX11Texture = (ID3D11Texture2D*)(GetD3D11TextureFromRHITexture(Texture)->GetResource()); + + TRefCountPtr MediaBuffer; + + if (!FWindowsPlatformMisc::VerifyWindowsVersion(6, 1) /*Win7*/) + { + UE_LOG(GameplayMediaEncoder, Error, TEXT("Win8+ is required")); + return false; + } + + CHECK_HR(MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), DX11Texture, 0, false, MediaBuffer.GetInitReference())); + + CHECK_HR(Sample.GetSample()->AddBuffer(MediaBuffer)); + + return true; +} + +bool FWmfVideoEncoder::InitializeEncoder() +{ + bool bResult = true; + + // Create H264 encoder + CHECK_HR(CoCreateInstance(CLSID_CMSH264EncoderMFT, nullptr, CLSCTX_INPROC_SERVER, IID_IMFTransform, reinterpret_cast(&H264Encoder))); + + if (!SetEncoderOutputMediaType() || + !SetEncoderInputMediaType() || + !CheckEncoderStatus() || + !RetrieveStreamInfo() || + !StartStreaming()) + { + H264Encoder->Release(); + return false; + } + + return true; +} + +bool FWmfVideoEncoder::SetEncoderInputMediaType() +{ + TRefCountPtr InputMediaType; + CHECK_HR(MFCreateMediaType(InputMediaType.GetInitReference())); + CHECK_HR(InputMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)); + // List of input subtypes: https://docs.microsoft.com/en-us/windows/desktop/medfound/h-264-video-encoder + CHECK_HR(InputMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12)); + CHECK_HR(InputMediaType->SetUINT32(MF_MT_AVG_BITRATE, Config.Bitrate)); + CHECK_HR(MFSetAttributeRatio(InputMediaType, MF_MT_FRAME_RATE, Config.Framerate, 1)); + CHECK_HR(MFSetAttributeSize(InputMediaType, MF_MT_FRAME_SIZE, Config.Width, Config.Height)); + CHECK_HR(MFSetAttributeRatio(InputMediaType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1)); + CHECK_HR(InputMediaType->SetUINT32(MF_MT_INTERLACE_MODE, /*MFVideoInterlace_MixedInterlaceOrProgressive*/MFVideoInterlace_Progressive)); + + CHECK_HR(H264Encoder->SetInputType(0, InputMediaType, 0)); + + return true; +} + +bool FWmfVideoEncoder::SetEncoderOutputMediaType() +{ + // `OutputType` is filled in `FBaseVideoEncoder::Initialize` + CHECK_HR(H264Encoder->SetOutputType(0, OutputType, 0)); + + return true; +} + +bool FWmfVideoEncoder::SetBitrate(uint32 Bitrate) +{ + // update `OutputType` and apply it + return FBaseVideoEncoder::SetBitrate(Bitrate) && SetEncoderOutputMediaType(); +} + +bool FWmfVideoEncoder::SetFramerate(uint32 Framerate) +{ + // update `OutputType` and apply it + return FBaseVideoEncoder::SetFramerate(Framerate) && SetEncoderOutputMediaType(); +} + +bool FWmfVideoEncoder::RetrieveStreamInfo() +{ + CHECK_HR(H264Encoder->GetOutputStreamInfo(0, &OutputStreamInfo)); + + return true; +} + +bool FWmfVideoEncoder::CheckEncoderStatus() +{ + DWORD EncoderStatus = 0; + CHECK_HR(H264Encoder->GetInputStatus(0, &EncoderStatus)); + if (MFT_INPUT_STATUS_ACCEPT_DATA != EncoderStatus) + { + return false; + } + + return true; +} + +bool FWmfVideoEncoder::StartStreaming() +{ + // Signal encoder ready to encode + CHECK_HR(H264Encoder->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, 0)); + CHECK_HR(H264Encoder->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0)); + CHECK_HR(H264Encoder->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0)); + + return true; +} + +bool FWmfVideoEncoder::EnqueueInputFrame(const FTexture2DRHIRef& Texture, FTimespan Timestamp, FTimespan Duration) +{ + bool bResult = true; + + FRHIResourceCreateInfo CreateInfo; + FTexture2DRHIRef EncoderInputTexture = RHICreateTexture2D(Config.Width, Config.Height, PF_R8G8B8A8, 1, 1, TexCreate_ShaderResource | TexCreate_RenderTargetable, CreateInfo); + + ResolveBackBuffer(Texture, EncoderInputTexture); + + TRefCountPtr MediaBuffer; + ID3D11Texture2D* DX11Texture = (ID3D11Texture2D*)(GetD3D11TextureFromRHITexture(EncoderInputTexture)->GetResource()); + CHECK_HR(MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), DX11Texture, 0, false, MediaBuffer.GetInitReference())); + + FGameplayMediaEncoderSample Sample{ EMediaType::Video }; + if (!Sample.CreateSample()) + { + return false; + } + CHECK_HR(Sample.GetSample()->AddBuffer(MediaBuffer)); + Sample.SetTime(Timestamp); + Sample.SetDuration(Duration); + + bResult = InputQueue.Enqueue(Sample); + check(bResult); + InputQueueSize.Increment(); + + return true; +} + +bool FWmfVideoEncoder::CreateOutputSample(FGameplayMediaEncoderSample& OutputSample) +{ + TRefCountPtr MediaBuffer; + CHECK_HR(MFCreateMemoryBuffer(OutputStreamInfo.cbSize, MediaBuffer.GetInitReference())); + // Update MF media buffer length + CHECK_HR(MediaBuffer->SetCurrentLength(OutputStreamInfo.cbSize)); + + if (!OutputSample.CreateSample()) + { + return false; + } + CHECK_HR(OutputSample.GetSample()->AddBuffer(MediaBuffer)); + + return true; +} + +bool FWmfVideoEncoder::ProcessEncoderInputFrame() +{ + bool bResult = true; + + if (!EncoderInputQueue.IsEmpty()) + { + FGameplayMediaEncoderSample Sample{ EMediaType::Video }; + bResult = EncoderInputQueue.Peek(Sample); + check(bResult); + HRESULT HResult = H264Encoder->ProcessInput(0, Sample.GetSample(), 0); + if (SUCCEEDED(HResult)) + { + bResult = EncoderInputQueue.Pop(); + check(bResult); + EncoderInputQueueSize.Decrement(); + EncoderInputProcessedCount++; + UE_LOG(GameplayMediaEncoder, VeryVerbose, TEXT("Video encoder processed %d input frames, queue size %d"), EncoderInputProcessedCount, InputQueueSize.GetValue()); + } + else + { + UE_LOG(GameplayMediaEncoder, Error, TEXT("FWmfVideoEncoder::ProcessEncoderInputFrame failed: %d"), HResult); + return false; + } + } + + return true; +} + +bool FWmfVideoEncoder::ProcessEncoderOutputFrame() +{ + DWORD mftOutFlags; + CHECK_HR(H264Encoder->GetOutputStatus(&mftOutFlags)); + + if (mftOutFlags == MFT_OUTPUT_STATUS_SAMPLE_READY) + { + FGameplayMediaEncoderSample OutputSample{ EMediaType::Video }; + if (!CreateOutputSample(OutputSample)) + { + return false; + } + + bool bOutputIncomplete = true; + while (bOutputIncomplete) + { + MFT_OUTPUT_DATA_BUFFER OutputDataBuffer = {}; + OutputDataBuffer.pSample = OutputSample.GetSample(); + + // have to reset sample before use + TRefCountPtr MediaBufferToReset; + CHECK_HR(OutputSample.GetSample()->GetBufferByIndex(0, MediaBufferToReset.GetInitReference())); + CHECK_HR(MediaBufferToReset->SetCurrentLength(0)); + + DWORD Status; + HRESULT HResult = H264Encoder->ProcessOutput(0, 1, &OutputDataBuffer, &Status); + if (OutputDataBuffer.pEvents) + { + // https://docs.microsoft.com/en-us/windows/desktop/api/mftransform/nf-mftransform-imftransform-processoutput + // The caller is responsible for releasing any events that the MFT allocates. + OutputDataBuffer.pEvents->Release(); + OutputDataBuffer.pEvents = nullptr; + } + + if (HResult == MF_E_TRANSFORM_NEED_MORE_INPUT) + { + return true; + } + else if (HResult == MF_E_TRANSFORM_STREAM_CHANGE) + { + if (OutputDataBuffer.dwStatus & MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE) + { + check(false); + } + else + { + check(false); + UE_LOG(GameplayMediaEncoder, Error, TEXT("MF_E_TRANSFORM_STREAM_CHANGE")); + return false; + } + } + else if (SUCCEEDED(HResult)) + { + if (OutputDataBuffer.pSample) + { + DWORD OutputSize; + CHECK_HR(OutputSample.GetSample()->GetTotalLength(&OutputSize)); + + UE_LOG(GameplayMediaEncoder, Verbose, TEXT("Video encoded: #%d, time %.3f, duration %.3f, size %d"), EncodedFrameCount.GetValue(), OutputSample.GetTime().GetTotalSeconds(), OutputSample.GetDuration().GetTotalSeconds(), OutputSize); + + EncodedFrameCount.Increment(); + + if (!OutputCallback(OutputSample)) + { + return false; + } + } + + bOutputIncomplete = (OutputDataBuffer.dwStatus == MFT_OUTPUT_DATA_BUFFER_INCOMPLETE); + } + else + { + UE_LOG(GameplayMediaEncoder, Error, TEXT("FWmfVideoEncoder::ProcessEncoderOutputFrame failed: %d"), HResult); + return false; + } + } + } + + return true; +} + +void FWmfVideoEncoder::ResolveBackBuffer(const FTexture2DRHIRef& BackBuffer, const FTexture2DRHIRef& ResolvedBackBuffer) +{ + IRendererModule* RendererModule = &FModuleManager::GetModuleChecked("Renderer"); + FRHICommandListImmediate& RHICmdList = FRHICommandListExecutor::GetImmediateCommandList(); + + if (BackBuffer->GetFormat() == ResolvedBackBuffer->GetFormat() && + BackBuffer->GetSizeXY() == ResolvedBackBuffer->GetSizeXY()) + { + RHICmdList.CopyToResolveTarget(BackBuffer, ResolvedBackBuffer, FResolveParams()); + } + else // Texture format mismatch, use a shader to do the copy. + { + SetRenderTarget(RHICmdList, ResolvedBackBuffer, FTextureRHIRef()); + RHICmdList.SetViewport(0, 0, 0.0f, ResolvedBackBuffer->GetSizeX(), ResolvedBackBuffer->GetSizeY(), 1.0f); + + FGraphicsPipelineStateInitializer GraphicsPSOInit; + RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit); + GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI(); + GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI(); + GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState::GetRHI(); + + TShaderMap* ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel); + TShaderMapRef VertexShader(ShaderMap); + TShaderMapRef PixelShader(ShaderMap); + + GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GFilterVertexDeclaration.VertexDeclarationRHI; + GraphicsPSOInit.BoundShaderState.VertexShaderRHI = GETSAFERHISHADER_VERTEX(*VertexShader); + GraphicsPSOInit.BoundShaderState.PixelShaderRHI = GETSAFERHISHADER_PIXEL(*PixelShader); + GraphicsPSOInit.PrimitiveType = PT_TriangleList; + + SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit); + + if (ResolvedBackBuffer->GetSizeX() != BackBuffer->GetSizeX() || ResolvedBackBuffer->GetSizeY() != BackBuffer->GetSizeY()) + PixelShader->SetParameters(RHICmdList, TStaticSamplerState::GetRHI(), BackBuffer); + else + PixelShader->SetParameters(RHICmdList, TStaticSamplerState::GetRHI(), BackBuffer); + + RendererModule->DrawRectangle( + RHICmdList, + 0, 0, // Dest X, Y + ResolvedBackBuffer->GetSizeX(), // Dest Width + ResolvedBackBuffer->GetSizeY(), // Dest Height + 0, 0, // Source U, V + 1, 1, // Source USize, VSize + ResolvedBackBuffer->GetSizeXY(), // Target buffer size + FIntPoint(1, 1), // Source texture size + *VertexShader, + EDRF_Default); + } +} + +GAMEPLAYMEDIAENCODER_END + + +#endif // PLATFORM_WINDOWS diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/WmfVideoEncoder.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/WmfVideoEncoder.h new file mode 100644 index 000000000000..d34a017a40e0 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/Windows/WmfVideoEncoder.h @@ -0,0 +1,56 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "BaseVideoEncoder.h" +#include "Containers/Queue.h" + +DECLARE_STATS_GROUP(TEXT("WmfVideoEncoder"), STATGROUP_WmfVideoEncoder, STATCAT_Advanced); + +class FWmfVideoEncoder : public FBaseVideoEncoder +{ +public: + explicit FWmfVideoEncoder(const FOutputSampleCallback& OutputCallback); + + bool Initialize(const FVideoEncoderConfig& Config) override; + bool Start() override; + void Stop() override; + bool Process(const FTexture2DRHIRef& Texture, FTimespan Timestamp, FTimespan Duration) override; + bool Flush(); + + bool SetBitrate(uint32 Bitrate) override; + bool SetFramerate(uint32 Framerate) override; + +private: + bool InitializeVideoProcessor(); + bool SetVideoProcessorInputMediaType(); + bool SetVideoProcessorOutputMediaType(); + bool ProcessVideoProcessorInputFrame(); + bool ProcessVideoProcessorOutputFrame(); + bool CreateInputSample(FGameplayMediaEncoderSample& OutSample); + + bool InitializeEncoder(); + bool SetEncoderInputMediaType(); + bool SetEncoderOutputMediaType(); + bool RetrieveStreamInfo(); + bool CheckEncoderStatus(); + bool StartStreaming(); + bool EnqueueInputFrame(const FTexture2DRHIRef& Texture, FTimespan Timestamp, FTimespan Duration); + bool CreateOutputSample(FGameplayMediaEncoderSample& OutSample); + bool ProcessEncoderInputFrame(); + bool ProcessEncoderOutputFrame(); + void ResolveBackBuffer(const FTexture2DRHIRef& BackBuffer, const FTexture2DRHIRef& ResolvedBackBuffer); + + TRefCountPtr VideoProcessor; + TRefCountPtr H264Encoder; + TQueue InputQueue; + FThreadSafeCounter InputQueueSize = 0; + int32 InputFrameProcessedCount = 0; + TQueue EncoderInputQueue; + FThreadSafeCounter EncoderInputQueueSize = 0; + int32 EncoderInputProcessedCount = 0; + TArray EncodedFrame; + FThreadSafeCounter EncodedFrameCount = 0; + MFT_OUTPUT_STREAM_INFO OutputStreamInfo = {}; +}; + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/WmfAudioEncoder.cpp b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/WmfAudioEncoder.cpp new file mode 100644 index 000000000000..ddd764dd79bf --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/WmfAudioEncoder.cpp @@ -0,0 +1,226 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "WmfAudioEncoder.h" +#include "GameplayMediaEncoderSample.h" + +GAMEPLAYMEDIAENCODER_START + +FWmfAudioEncoder::FWmfAudioEncoder(const FOutputSampleCallback& OutputCallback) : + OutputCallback(OutputCallback) +{} + +bool FWmfAudioEncoder::Initialize(const FWmfAudioEncoderConfig& InConfig) +{ + if (InConfig.SampleRate != 44100 && InConfig.SampleRate != 48000) + { + UE_LOG(GameplayMediaEncoder, Error, TEXT("AAC SampleRate must be 44100 or 48000, configured: %d. see: https://docs.microsoft.com/en-us/windows/desktop/medfound/aac-encoder"), InConfig.SampleRate); + return false; + } + if (InConfig.NumChannels != 1 && InConfig.NumChannels != 2 && InConfig.NumChannels != 6) + { + UE_LOG(GameplayMediaEncoder, Error, TEXT("AAC NumChannels must be 1, 2 or 6 (5.1), configured: %d. see: https://docs.microsoft.com/en-us/windows/desktop/medfound/aac-encoder"), InConfig.NumChannels); + return false; + } + + UE_LOG(GameplayMediaEncoder, Log, TEXT("AudioEncoder config: %d channels, %d Hz, %.2f Kbps"), InConfig.NumChannels, InConfig.SampleRate, InConfig.Bitrate / 1000.0f); + + Config = InConfig; + + CHECK_HR(CoCreateInstance(CLSID_AACMFTEncoder, nullptr, CLSCTX_INPROC_SERVER, IID_IMFTransform, reinterpret_cast(&Encoder))); + + if (!SetInputType() || !SetOutputType() || !RetrieveStreamInfo() || !StartStreaming()) + { + Encoder->Release(); + return false; + } + + return true; +} + +bool FWmfAudioEncoder::SetInputType() +{ + TRefCountPtr MediaType; + CHECK_HR(MFCreateMediaType(MediaType.GetInitReference())); + CHECK_HR(MediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio)); + CHECK_HR(MediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM)); + CHECK_HR(MediaType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16)); // the only value supported + CHECK_HR(MediaType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, Config.SampleRate)); + CHECK_HR(MediaType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, Config.NumChannels)); + + CHECK_HR(Encoder->SetInputType(0, MediaType, 0)); + + return true; +} + +bool FWmfAudioEncoder::SetOutputType() +{ + TRefCountPtr InputType; + CHECK_HR(Encoder->GetInputCurrentType(0, InputType.GetInitReference())); + + CHECK_HR(MFCreateMediaType(OutputType.GetInitReference())); + CHECK_HR(OutputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio)); + CHECK_HR(OutputType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC)); + CHECK_HR(OutputType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16)); // the only value supported + uint32 SampleRate; + CHECK_HR(InputType->GetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, &SampleRate)); + CHECK_HR(OutputType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, SampleRate)); + uint32 NumChannels; + CHECK_HR(InputType->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &NumChannels)); + CHECK_HR(OutputType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, NumChannels)); + CHECK_HR(OutputType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, Config.Bitrate)); + + CHECK_HR(Encoder->SetOutputType(0, OutputType, 0)); + + return true; +} + +bool FWmfAudioEncoder::GetOutputType(TRefCountPtr& OutType) +{ + OutType = OutputType; + return OutputType.IsValid(); +} + +bool FWmfAudioEncoder::RetrieveStreamInfo() +{ + CHECK_HR(Encoder->GetInputStreamInfo(0, &InputStreamInfo)); + CHECK_HR(Encoder->GetOutputStreamInfo(0, &OutputStreamInfo)); + + return true; +} + +bool FWmfAudioEncoder::StartStreaming() +{ + CHECK_HR(Encoder->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0)); + CHECK_HR(Encoder->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0)); + + return true; +} + +bool FWmfAudioEncoder::Process(const int8* SampleData, uint32 Size, FTimespan Timestamp, FTimespan Duration) +{ + UE_LOG(GameplayMediaEncoder, Verbose, TEXT("Audio input: time %.3f, duration %.3f, size %d"), Timestamp.GetTotalSeconds(), Duration.GetTotalSeconds(), Size); + + FGameplayMediaEncoderSample InputSample{ EMediaType::Audio }; + if (!CreateInputSample(SampleData, Size, Timestamp, Duration, InputSample)) + { + return false; + } + + CHECK_HR(Encoder->ProcessInput(0, InputSample.GetSample(), 0)); + + while (true) + { + FGameplayMediaEncoderSample OutputSample{ EMediaType::Audio }; + if (!GetOutputSample(OutputSample)) + { + return false; + } + if (!OutputSample.IsValid()) + { + break; + } + + DWORD OutputSize; + CHECK_HR(OutputSample.GetSample()->GetTotalLength(&OutputSize)); + + UE_LOG(GameplayMediaEncoder, Verbose, TEXT("Audio encoded: time %.3f, duration %.3f, size %d"), OutputSample.GetTime().GetTotalSeconds(), OutputSample.GetDuration().GetTotalSeconds(), OutputSize); + + if (!OutputCallback(OutputSample)) + { + return false; + } + } + + return true; +} + +// TODO(andriy): consider pooling IMFSample allocations, same for video encoder + +bool FWmfAudioEncoder::CreateInputSample(const int8* SampleData, uint32 Size, FTimespan Timestamp, FTimespan Duration, FGameplayMediaEncoderSample& Sample) +{ + if (!Sample.CreateSample()) + { + return false; + } + + int32 BufferSize = FMath::Max(InputStreamInfo.cbSize, Size); + uint32 Alignment = InputStreamInfo.cbAlignment > 1 ? InputStreamInfo.cbAlignment - 1 : 0; + TRefCountPtr WmfBuffer; + CHECK_HR(MFCreateAlignedMemoryBuffer(BufferSize, Alignment, WmfBuffer.GetInitReference())); + + uint8* Dst = nullptr; + CHECK_HR(WmfBuffer->Lock(&Dst, nullptr, nullptr)); + FMemory::Memcpy(Dst, SampleData, Size); + CHECK_HR(WmfBuffer->Unlock()); + + CHECK_HR(WmfBuffer->SetCurrentLength(Size)); + + CHECK_HR(Sample.GetSample()->AddBuffer(WmfBuffer)); + Sample.SetTime(Timestamp); + Sample.SetDuration(Duration); + + return true; +} + +bool FWmfAudioEncoder::CreateOutputSample(FGameplayMediaEncoderSample& Sample) +{ + if (!Sample.CreateSample()) + { + return false; + } + + TRefCountPtr Buffer = nullptr; + uint32 Alignment = OutputStreamInfo.cbAlignment > 1 ? OutputStreamInfo.cbAlignment - 1 : 0; + CHECK_HR(MFCreateAlignedMemoryBuffer(OutputStreamInfo.cbSize, Alignment, Buffer.GetInitReference())); + + CHECK_HR(Sample.GetSample()->AddBuffer(Buffer)); + + return true; +} + +bool FWmfAudioEncoder::GetOutputSample(FGameplayMediaEncoderSample& Sample) +{ + bool bFlag1 = OutputStreamInfo.dwFlags&MFT_OUTPUT_STREAM_PROVIDES_SAMPLES; + bool bFlag2 = OutputStreamInfo.dwFlags&MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES; + + // Right now, we are always creating our samples, so make sure MFT will be ok with that + verify((bFlag1 == false && bFlag2 == false) || (bFlag1 == false && bFlag2 == true)); + + MFT_OUTPUT_DATA_BUFFER Output = {}; + if (!CreateOutputSample(Sample)) + { + return false; + } + Output.pSample = Sample.GetSample(); + + DWORD Status = 0; + HRESULT Res = Encoder->ProcessOutput(0, 1, &Output, &Status); + TRefCountPtr Events = Output.pEvents; // unsure this is released + if (Res == MF_E_TRANSFORM_NEED_MORE_INPUT || !Sample.IsValid()) + { + Sample.Reset(); // do not return empty sample + return true; // not an error, just not enough input + } + else if (Res == MF_E_TRANSFORM_STREAM_CHANGE) + { + if (!SetOutputType()) + { + return false; + } + + return GetOutputSample(Sample); + } + + return SUCCEEDED(Res); +} + +bool FWmfAudioEncoder::Flush() +{ + CHECK_HR(Encoder->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, 0)); + CHECK_HR(Encoder->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, 0)); + + return true; +} + +GAMEPLAYMEDIAENCODER_END + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/WmfAudioEncoder.h b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/WmfAudioEncoder.h new file mode 100644 index 000000000000..8fcd98fea4cf --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Private/Microsoft/WmfAudioEncoder.h @@ -0,0 +1,52 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "GameplayMediaEncoderCommon.h" +#include "GameplayMediaEncoderSample.h" + +struct FWmfAudioEncoderConfig +{ + uint32 NumChannels; + uint32 SampleRate; + uint32 Bitrate; + // bits per sample must be 16 as the only value supported by WMF AAC encoder +}; + +class FWmfAudioEncoder +{ +public: + using FOutputSampleCallback = TFunction; + + explicit FWmfAudioEncoder(const FOutputSampleCallback& OutputCallback); + + bool Initialize(const FWmfAudioEncoderConfig& Config); + bool Process(const int8* SampleData, uint32 Size, FTimespan Timestamp, FTimespan Duration); + bool Flush(); + + bool GetOutputType(TRefCountPtr& OutType); + + const FWmfAudioEncoderConfig& GetConfig() const + { + return Config; + } + +private: + bool SetInputType(); + bool SetOutputType(); + bool RetrieveStreamInfo(); + bool StartStreaming(); + + bool CreateInputSample(const int8* SampleData, uint32 Size, FTimespan Timestamp, FTimespan Duration, FGameplayMediaEncoderSample& Sample); + bool CreateOutputSample(FGameplayMediaEncoderSample& OutSample); + bool GetOutputSample(FGameplayMediaEncoderSample& OutSample); + +private: + FOutputSampleCallback OutputCallback; + + FWmfAudioEncoderConfig Config; + TRefCountPtr Encoder; + TRefCountPtr OutputType; + MFT_INPUT_STREAM_INFO InputStreamInfo = {}; + MFT_OUTPUT_STREAM_INFO OutputStreamInfo = {}; +}; \ No newline at end of file diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Public/GameplayMediaEncoder.h b/Engine/Source/Runtime/GameplayMediaEncoder/Public/GameplayMediaEncoder.h new file mode 100644 index 000000000000..63fd10414003 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Public/GameplayMediaEncoder.h @@ -0,0 +1,122 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" + +#include "Logging/LogMacros.h" +#include "AudioMixerDevice.h" +#include "GameplayMediaEncoderSample.h" + +#include "RHI.h" +#include "RHIResources.h" + +class FBaseVideoEncoder; +class FWmfAudioEncoder; + +class IGameplayMediaEncoderListener +{ +public: + virtual void OnMediaSample(const FGameplayMediaEncoderSample& Sample) = 0; +}; + +class GAMEPLAYMEDIAENCODER_API FGameplayMediaEncoder final : private ISubmixBufferListener +{ +public: + + /** + * Get the singleton + */ + static FGameplayMediaEncoder* Get(); + + FGameplayMediaEncoder(); + ~FGameplayMediaEncoder(); + + bool RegisterListener(IGameplayMediaEncoderListener* Listener); + void UnregisterListener(IGameplayMediaEncoderListener* Listener); + + bool GetAudioOutputType(TRefCountPtr& OutType); + bool GetVideoOutputType(TRefCountPtr& OutType); + + void SetVideoBitrate(uint32 Bitrate); + void SetVideoFramerate(uint32 Framerate); + + bool Initialize(); + void Shutdown(); + bool Start(); + void Stop(); + + static void InitializeCmd() + { + // We call Get(), so it creates the singleton + Get()->Initialize(); + } + + static void ShutdownCmd() + { + // We call Get(), so it creates the singleton + Get()->Shutdown(); + } + + static void StartCmd() + { + // We call Get(), so it creates the singleton + Get()->Start(); + } + + static void StopCmd() + { + // We call Get(), so it creates the singleton + Get()->Stop(); + } + +private: + FTimespan GetMediaTimestamp() const; + + bool OnMediaSampleReady(const FGameplayMediaEncoderSample& Sample); + + // Back buffer capture + void OnBackBufferReady(const FTexture2DRHIRef& BackBuffer); + // ISubmixBufferListener interface + void OnNewSubmixBuffer(const USoundSubmix* OwningSubmix, float* AudioData, int32 NumSamples, int32 NumChannels, const int32 SampleRate, double AudioClock) override; + + bool ProcessAudioFrame(const float* AudioData, int32 NumSamples, int32 NumChannels, int32 SampleRate); + bool ProcessVideoFrame(const FTexture2DRHIRef& BackBuffer); + + bool ChangeVideoConfig(); + + FCriticalSection ListenersCS; + TArray Listeners; + + FCriticalSection AudioProcessingCS; + FCriticalSection VideoProcessingCS; + + TUniquePtr AudioEncoder; + TUniquePtr VideoEncoder; +#if PLATFORM_WINDOWS + TSharedPtr EncoderDevice; +#endif + bool bAudioFormatChecked = false; + bool bDoFrameSkipping = false; + + // Keep this as a member variables, to reuse the memory allocation + Audio::TSampleBuffer PCM16; + + uint64 NumCapturedFrames = 0; + FTimespan StartTime = 0; + FTimespan LastAudioInputTimestamp = 0; + FTimespan LastVideoInputTimestamp = 0; + + // It is possible to suspend the processing of media samples which is + // required during resolution change. + FCriticalSection ProcessMediaSamplesCS; + bool bProcessMediaSamples = true; + + // live streaming: quality adaptation to available uplink b/w + TAtomic NewVideoBitrate{ 0 }; + FThreadSafeBool bChangeBitrate = false; + FTimespan FramerateMonitoringStart = -1; + TAtomic NewVideoFramerate{ 0 }; + FThreadSafeBool bChangeFramerate = false; +}; + diff --git a/Engine/Source/Runtime/GameplayMediaEncoder/Public/GameplayMediaEncoderSample.h b/Engine/Source/Runtime/GameplayMediaEncoder/Public/GameplayMediaEncoderSample.h new file mode 100644 index 000000000000..a0a525692688 --- /dev/null +++ b/Engine/Source/Runtime/GameplayMediaEncoder/Public/GameplayMediaEncoderSample.h @@ -0,0 +1,82 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Templates/RefCounting.h" + +#if PLATFORM_WINDOWS + +#include "Windows/AllowWindowsPlatformTypes.h" +#include "Windows/PreWindowsApi.h" + #include +#include "Windows/PostWindowsApi.h" +#include "Windows/HideWindowsPlatformTypes.h" + +#elif PLATFORM_XBOXONE + +#include "XboxOne/XboxOneAllowPlatformTypes.h" +#include "XboxOne/XboxOnePreApi.h" + #include +#include "XboxOne/XboxOnePostApi.h" +#include "XboxOne/XboxOneHidePlatformTypes.h" +#endif + +enum class EMediaType { Audio = 0, Video = 1, Invalid = 2 }; +inline const TCHAR* MediaTypeStr(EMediaType MediaType) +{ + const TCHAR* Str[] = { TEXT("audio"), TEXT("video"), TEXT("invalid media type") }; + return Str[static_cast(MediaType)]; +} + +class GAMEPLAYMEDIAENCODER_API FGameplayMediaEncoderSample +{ +public: + FGameplayMediaEncoderSample(EMediaType InMediaType = EMediaType::Invalid, IMFSample* InSample = nullptr) : + MediaType(InMediaType), + Sample(InSample) + {} + + EMediaType GetType() const + { + return MediaType; + } + + const IMFSample* GetSample() const + { + return Sample; + } + + IMFSample* GetSample() + { + return Sample; + } + + bool CreateSample(); + + FTimespan GetTime() const; + + void SetTime(FTimespan Time); + + FTimespan GetDuration() const; + + void SetDuration(FTimespan Duration); + + bool IsVideoKeyFrame() const; + + bool IsValid() const + { + return Sample.IsValid(); + } + + void Reset() + { + Sample = nullptr; + } + + FGameplayMediaEncoderSample Clone() const; + +private: + EMediaType MediaType; + TRefCountPtr Sample; +}; \ No newline at end of file diff --git a/Engine/Source/Runtime/GameplayTags/Private/GameplayTagsManager.cpp b/Engine/Source/Runtime/GameplayTags/Private/GameplayTagsManager.cpp index 8729c3e12685..7fef033a595c 100644 --- a/Engine/Source/Runtime/GameplayTags/Private/GameplayTagsManager.cpp +++ b/Engine/Source/Runtime/GameplayTags/Private/GameplayTagsManager.cpp @@ -169,7 +169,7 @@ void UGameplayTagsManager::ConstructGameplayTagTree() { LoadGameplayTagTables(false); } - + { SCOPE_LOG_GAMEPLAYTAGS(TEXT("UGameplayTagsManager::ConstructGameplayTagTree: Construct from data asset")); for (UDataTable* DataTable : GameplayTagTables) @@ -191,7 +191,7 @@ void UGameplayTagsManager::ConstructGameplayTagTree() // Copy from deprecated list in DefaultEngine.ini TArray EngineConfigTags; GConfig->GetArray(TEXT("/Script/GameplayTags.GameplayTagsSettings"), TEXT("+GameplayTags"), EngineConfigTags, GEngineIni); - + for (const FString& EngineConfigTag : EngineConfigTags) { MutableDefault->GameplayTagList.AddUnique(FGameplayTagTableRow(FName(*EngineConfigTag))); @@ -519,7 +519,7 @@ FGameplayTagNetIndex UGameplayTagsManager::GetNetIndexFromTag(const FGameplayTag bool UGameplayTagsManager::ShouldImportTagsFromINI() const { UGameplayTagsSettings* MutableDefault = GetMutableDefault(); - + // Deprecated path bool ImportFromINI = false; if (GConfig->GetBool(TEXT("GameplayTags"), TEXT("ImportTagsFromConfig"), ImportFromINI, GEngineIni)) @@ -710,6 +710,7 @@ bool UGameplayTagsManager::ImportSingleGameplayTag(FGameplayTag& Tag, FName Impo void UGameplayTagsManager::InitializeManager() { check(!SingletonManager); + SCOPED_BOOT_TIMING("UGameplayTagsManager::InitializeManager"); SCOPE_LOG_TIME_IN_SECONDS(TEXT("UGameplayTagsManager::InitializeManager"), nullptr); SingletonManager = NewObject(GetTransientPackage(), NAME_None); @@ -1958,7 +1959,7 @@ FGameplayTagNode::FGameplayTagNode(FName InTag, FName InFullTag, TSharedPtr @@ -31,6 +33,8 @@ static TWeakPtr VirtualKeyboardWidget; //virtualKeyboard shown static volatile bool GVirtualKeyboardShown = false; +//WebView shown +static volatile bool GWebViewShown = false; extern FString GFilePathBase; extern FString GInternalFilePath; @@ -61,10 +65,8 @@ if (Id == 0) \ void FJavaWrapper::FindClassesAndMethods(JNIEnv* Env) { - bool bIsOptional = false; - jclass localGameActivityClass = FindClass(Env, "com/epicgames/ue4/GameActivity", bIsOptional); - GGameActivityClassID = GameActivityClassID = (jclass)Env->NewGlobalRef(localGameActivityClass); - Env->DeleteLocalRef(localGameActivityClass); + auto bIsOptional = false; + GGameActivityClassID = GameActivityClassID = FindClassGlobalRef(Env, "com/epicgames/ue4/GameActivity", bIsOptional); AndroidThunkJava_ShowConsoleWindow = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_ShowConsoleWindow", "(Ljava/lang/String;)V", bIsOptional); AndroidThunkJava_ShowVirtualKeyboardInputDialog = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_ShowVirtualKeyboardInputDialog", "(ILjava/lang/String;Ljava/lang/String;)V", bIsOptional); AndroidThunkJava_HideVirtualKeyboardInputDialog = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_HideVirtualKeyboardInputDialog", "()V", bIsOptional); @@ -119,9 +121,7 @@ void FJavaWrapper::FindClassesAndMethods(JNIEnv* Env) AndroidThunkJava_UnregisterForRemoteNotifications = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_UnregisterForRemoteNotifications", "()V", true); // get field IDs for InputDeviceInfo class members - jclass localInputDeviceInfoClass = FindClass(Env, "com/epicgames/ue4/GameActivity$InputDeviceInfo", bIsOptional); - InputDeviceInfoClass = (jclass)Env->NewGlobalRef(localInputDeviceInfoClass); - Env->DeleteLocalRef(localInputDeviceInfoClass); + InputDeviceInfoClass = FindClassGlobalRef(Env, "com/epicgames/ue4/GameActivity$InputDeviceInfo", bIsOptional); InputDeviceInfo_VendorId = FJavaWrapper::FindField(Env, InputDeviceInfoClass, "vendorId", "I", bIsOptional); InputDeviceInfo_ProductId = FJavaWrapper::FindField(Env, InputDeviceInfoClass, "productId", "I", bIsOptional); InputDeviceInfo_ControllerId = FJavaWrapper::FindField(Env, InputDeviceInfoClass, "controllerId", "I", bIsOptional); @@ -134,19 +134,17 @@ void FJavaWrapper::FindClassesAndMethods(JNIEnv* Env) FindGooglePlayBillingMethods(Env); // get field IDs for LaunchNotificationClass class members - jclass localLaunchNotificationClass = FindClass(Env, "com/epicgames/ue4/GameActivity$LaunchNotification", bIsOptional); - LaunchNotificationClass = (jclass)Env->NewGlobalRef(localLaunchNotificationClass); - Env->DeleteLocalRef(localLaunchNotificationClass); + LaunchNotificationClass = FindClassGlobalRef(Env, "com/epicgames/ue4/GameActivity$LaunchNotification", bIsOptional); LaunchNotificationUsed = FJavaWrapper::FindField(Env, LaunchNotificationClass, "used", "Z", bIsOptional); LaunchNotificationEvent = FJavaWrapper::FindField(Env, LaunchNotificationClass, "event", "Ljava/lang/String;", bIsOptional); LaunchNotificationFireDate = FJavaWrapper::FindField(Env, LaunchNotificationClass, "fireDate", "I", bIsOptional); - jclass localThreadClass = FindClass(Env, "java/lang/Thread", bIsOptional); - ThreadClass = (jclass)Env->NewGlobalRef(localThreadClass); - Env->DeleteLocalRef(localThreadClass); + ThreadClass = FindClassGlobalRef(Env, "java/lang/Thread", bIsOptional); CurrentThreadMethod = FindStaticMethod(Env, ThreadClass, "currentThread", "()Ljava/lang/Thread;", bIsOptional); SetNameMethod = FindMethod(Env, ThreadClass, "setName", "(Ljava/lang/String;)V", bIsOptional); + AndroidThunkJava_RestartApplication = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_RestartApplication", "(Ljava/lang/String;)V", bIsOptional); + // the rest are optional bIsOptional = true; @@ -156,7 +154,7 @@ void FJavaWrapper::FindClassesAndMethods(JNIEnv* Env) AndroidThunkJava_VirtualInputIgnoreClick = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_VirtualInputIgnoreClick", "(II)Z", bIsOptional); - AndroidThunkJava_RestartApplication = FindMethod(Env, GameActivityClassID, "AndroidThunkJava_RestartApplication", "()V", bIsOptional); + SetupEmbeddedCommunication(Env); } void FJavaWrapper::FindGooglePlayMethods(JNIEnv* Env) @@ -187,10 +185,8 @@ void FJavaWrapper::FindGooglePlayBillingMethods(JNIEnv* Env) FPlatformMisc::LowLevelOutputDebugString(TEXT("[JNI] - Failed to determine if app purchasing is enabled!")); } bool bIsStoreOptional = !bSupportsInAppPurchasing; - - jclass localStringClass = Env->FindClass("java/lang/String"); - JavaStringClass = (jclass)Env->NewGlobalRef(localStringClass); - Env->DeleteLocalRef(localStringClass); + + JavaStringClass = FindClassGlobalRef(Env, "java/lang/String", false); AndroidThunkJava_IapSetupService = FindMethod(Env, GoogleServicesClassID, "AndroidThunkJava_IapSetupService", "(Ljava/lang/String;)V", bIsStoreOptional); AndroidThunkJava_IapQueryInAppPurchases = FindMethod(Env, GoogleServicesClassID, "AndroidThunkJava_IapQueryInAppPurchases", "([Ljava/lang/String;)Z", bIsStoreOptional); AndroidThunkJava_IapBeginPurchase = FindMethod(Env, GoogleServicesClassID, "AndroidThunkJava_IapBeginPurchase", "(Ljava/lang/String;)Z", bIsStoreOptional); @@ -207,6 +203,17 @@ jclass FJavaWrapper::FindClass(JNIEnv* Env, const ANSICHAR* ClassName, bool bIsO return Class; } +jclass FJavaWrapper::FindClassGlobalRef(JNIEnv* Env, const ANSICHAR* ClassName, bool bIsOptional) +{ + auto LocalClass = NewScopedJavaObject(Env, Env->FindClass(ClassName)); + CHECK_JNI_RESULT(*LocalClass); + if (LocalClass) + { + return (jclass)Env->NewGlobalRef(*LocalClass); + } + return nullptr; +} + jmethodID FJavaWrapper::FindMethod(JNIEnv* Env, jclass Class, const ANSICHAR* MethodName, const ANSICHAR* MethodSignature, bool bIsOptional) { jmethodID Method = Class == NULL ? NULL : Env->GetMethodID(Class, MethodName, MethodSignature); @@ -508,9 +515,8 @@ void AndroidThunkCpp_ShowProgressDialog(bool bShow, const FString& Message, bool { if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring JavaMessage = Env->NewStringUTF(TCHAR_TO_UTF8(*Message)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_ShowProgressDialog, bShow, JavaMessage, bHorizontal, MaxValue); - Env->DeleteLocalRef(JavaMessage); + auto JavaMessage = FJavaHelper::ToJavaString(Env, Message); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_ShowProgressDialog, bShow, *JavaMessage, bHorizontal, MaxValue); } } @@ -526,42 +532,23 @@ bool AndroidThunkCpp_GetInputDeviceInfo(int32 deviceId, FAndroidInputDeviceInfo { if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jobject deviceInfo = (jobject)Env->CallObjectMethod(FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetInputDeviceInfo, deviceId); + auto deviceInfo = NewScopedJavaObject(Env, (jobject)Env->CallObjectMethod(FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetInputDeviceInfo, deviceId)); if (Env->ExceptionCheck()) { Env->ExceptionDescribe(); Env->ExceptionClear(); - - if (deviceInfo != 0) - { - Env->DeleteLocalRef(deviceInfo); - } } - else if (deviceInfo != 0) + else if (deviceInfo) { bool bIsOptional = false; results.DeviceId = deviceId; - results.VendorId = (int32)Env->GetIntField(deviceInfo, FJavaWrapper::InputDeviceInfo_VendorId); - results.ProductId = (int32)Env->GetIntField(deviceInfo, FJavaWrapper::InputDeviceInfo_ProductId); - results.ControllerId = (int32)Env->GetIntField(deviceInfo, FJavaWrapper::InputDeviceInfo_ControllerId); - - jstring jsName = (jstring)Env->GetObjectField(deviceInfo, FJavaWrapper::InputDeviceInfo_Name); - CHECK_JNI_RESULT(jsName); - const char * nativeName = Env->GetStringUTFChars(jsName, 0); - results.Name = FString(nativeName); - Env->ReleaseStringUTFChars(jsName, nativeName); - Env->DeleteLocalRef(jsName); - - jstring jsDescriptor = (jstring)Env->GetObjectField(deviceInfo, FJavaWrapper::InputDeviceInfo_Descriptor); - CHECK_JNI_RESULT(jsDescriptor); - const char * nativeDescriptor = Env->GetStringUTFChars(jsDescriptor, 0); - results.Descriptor = FString(nativeDescriptor); - Env->ReleaseStringUTFChars(jsDescriptor, nativeDescriptor); - Env->DeleteLocalRef(jsDescriptor); - - // release references - Env->DeleteLocalRef(deviceInfo); + results.VendorId = (int32)Env->GetIntField(*deviceInfo, FJavaWrapper::InputDeviceInfo_VendorId); + results.ProductId = (int32)Env->GetIntField(*deviceInfo, FJavaWrapper::InputDeviceInfo_ProductId); + results.ControllerId = (int32)Env->GetIntField(*deviceInfo, FJavaWrapper::InputDeviceInfo_ControllerId); + results.Name = FJavaHelper::FStringFromLocalRef(Env, (jstring)Env->GetObjectField(*deviceInfo, FJavaWrapper::InputDeviceInfo_Name)); + results.Descriptor = FJavaHelper::FStringFromLocalRef(Env, (jstring)Env->GetObjectField(*deviceInfo, FJavaWrapper::InputDeviceInfo_Descriptor)); + return true; } } @@ -586,14 +573,25 @@ bool AndroidThunkCpp_VirtualInputIgnoreClick(int32 x, int32 y) return Result; } -void AndroidThunkCpp_RestartApplication() +void AndroidThunkCpp_RestartApplication(const FString& IntentString) { if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_RestartApplication); + auto Argument = FJavaHelper::ToJavaString(Env, IntentString); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_RestartApplication, *Argument); } } +JNI_METHOD void Java_com_epicgames_ue4_NativeCalls_WebViewVisible(JNIEnv* jenv, jobject thiz, jboolean bShown) +{ + GWebViewShown = bShown; +} + +bool AndroidThunkCpp_IsWebViewShown() +{ + return GWebViewShown; +} + //Set GVirtualKeyboardShown.This function is declared in the Java-defined class, GameActivity.java: "public native void nativeVirtualKeyboardVisible(boolean bShown)" JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeVirtualKeyboardVisible(JNIEnv* jenv, jobject thiz, jboolean bShown) { @@ -626,9 +624,8 @@ bool AndroidThunkCpp_HasMetaDataKey(const FString& Key) bool Result = false; if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring Argument = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - Result = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_HasMetaDataKey, Argument); - Env->DeleteLocalRef(Argument); + auto Argument = FJavaHelper::ToJavaString(Env, Key); + Result = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_HasMetaDataKey, *Argument); } return Result; } @@ -638,9 +635,8 @@ bool AndroidThunkCpp_GetMetaDataBoolean(const FString& Key) bool Result = false; if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring Argument = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - Result = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetMetaDataBoolean, Argument); - Env->DeleteLocalRef(Argument); + auto Argument = FJavaHelper::ToJavaString(Env, Key); + Result = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetMetaDataBoolean, *Argument); } return Result; } @@ -650,9 +646,8 @@ int32 AndroidThunkCpp_GetMetaDataInt(const FString& Key) int32 Result = 0; if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring Argument = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - Result = FJavaWrapper::CallIntMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetMetaDataInt, Argument); - Env->DeleteLocalRef(Argument); + auto Argument = FJavaHelper::ToJavaString(Env, Key); + Result = FJavaWrapper::CallIntMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetMetaDataInt, *Argument); } return Result; } @@ -662,9 +657,8 @@ int64 AndroidThunkCpp_GetMetaDataLong(const FString& Key) int64 Result = 0; if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring Argument = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - Result = (int64)FJavaWrapper::CallLongMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetMetaDataLong, Argument); - Env->DeleteLocalRef(Argument); + auto Argument = FJavaHelper::ToJavaString(Env, Key); + Result = (int64)FJavaWrapper::CallLongMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetMetaDataLong, *Argument); } return Result; } @@ -674,9 +668,8 @@ float AndroidThunkCpp_GetMetaDataFloat(const FString& Key) float Result = 0.0f; if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring Argument = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - Result = (float)FJavaWrapper::CallFloatMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetMetaDataFloat, Argument); - Env->DeleteLocalRef(Argument); + auto Argument = FJavaHelper::ToJavaString(Env, Key); + Result = (float)FJavaWrapper::CallFloatMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetMetaDataFloat, *Argument); } return Result; } @@ -686,16 +679,8 @@ FString AndroidThunkCpp_GetMetaDataString(const FString& Key) FString Result = FString(""); if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring Argument = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - jstring JavaString = (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetMetaDataString, Argument); - Env->DeleteLocalRef(Argument); - if (JavaString != NULL) - { - const char* JavaChars = Env->GetStringUTFChars(JavaString, 0); - Result = FString(UTF8_TO_TCHAR(JavaChars)); - Env->ReleaseStringUTFChars(JavaString, JavaChars); - Env->DeleteLocalRef(JavaString); - } + auto Argument = FJavaHelper::ToJavaString(Env, Key); + Result = FJavaHelper::FStringFromLocalRef(Env, (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetMetaDataString, *Argument)); } return Result; } @@ -705,9 +690,8 @@ bool AndroidThunkCpp_HasIntentExtrasKey(const FString& Key) bool Result = false; if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring Argument = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - Result = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_HasIntentExtrasKey, Argument); - Env->DeleteLocalRef(Argument); + auto Argument = FJavaHelper::ToJavaString(Env, Key); + Result = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_HasIntentExtrasKey, *Argument); } return Result; } @@ -717,9 +701,8 @@ bool AndroidThunkCpp_GetIntentExtrasBoolean(const FString& Key) bool Result = false; if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring Argument = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - Result = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetIntentExtrasBoolean, Argument); - Env->DeleteLocalRef(Argument); + auto Argument = FJavaHelper::ToJavaString(Env, Key); + Result = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetIntentExtrasBoolean, *Argument); } return Result; } @@ -729,9 +712,8 @@ int32 AndroidThunkCpp_GetIntentExtrasInt(const FString& Key) int32 Result = 0; if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring Argument = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - Result = FJavaWrapper::CallIntMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetIntentExtrasInt, Argument); - Env->DeleteLocalRef(Argument); + auto Argument = FJavaHelper::ToJavaString(Env, Key); + Result = FJavaWrapper::CallIntMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetIntentExtrasInt, *Argument); } return Result; } @@ -741,16 +723,8 @@ FString AndroidThunkCpp_GetIntentExtrasString(const FString& Key) FString Result = FString(""); if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring Argument = Env->NewStringUTF(TCHAR_TO_UTF8(*Key)); - jstring JavaString = (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetIntentExtrasString, Argument); - Env->DeleteLocalRef(Argument); - if (JavaString != NULL) - { - const char* JavaChars = Env->GetStringUTFChars(JavaString, 0); - Result = FString(UTF8_TO_TCHAR(JavaChars)); - Env->ReleaseStringUTFChars(JavaString, JavaChars); - Env->DeleteLocalRef(JavaString); - } + auto Argument = FJavaHelper::ToJavaString(Env, Key); + Result = FJavaHelper::FStringFromLocalRef(Env, (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetIntentExtrasString, *Argument)); } return Result; } @@ -848,9 +822,8 @@ void AndroidThunkCpp_ShowConsoleWindow() } // call the java side - jstring ConsoleTextJava = Env->NewStringUTF(TCHAR_TO_UTF8(*ConsoleText)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_ShowConsoleWindow, ConsoleTextJava); - Env->DeleteLocalRef(ConsoleTextJava); + auto ConsoleTextJava = FJavaHelper::ToJavaString(Env, ConsoleText); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_ShowConsoleWindow, *ConsoleTextJava); } } @@ -862,11 +835,9 @@ void AndroidThunkCpp_ShowVirtualKeyboardInputDialog(TSharedPtrNewStringUTF(TCHAR_TO_UTF8(*Label)); - jstring ContentsJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Contents)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_ShowVirtualKeyboardInputDialog, InputType, LabelJava, ContentsJava); - Env->DeleteLocalRef(ContentsJava); - Env->DeleteLocalRef(LabelJava); + auto LabelJava = FJavaHelper::ToJavaString(Env, Label); + auto ContentsJava = FJavaHelper::ToJavaString(Env, Contents); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_ShowVirtualKeyboardInputDialog, InputType, *LabelJava, *ContentsJava); } } @@ -950,11 +921,9 @@ void AndroidThunkCpp_ShowVirtualKeyboardInput(TSharedPtr VirtualKeyboardWidget = TextWidget; // call the java side - jstring LabelJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Label)); - jstring ContentsJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Contents)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_ShowVirtualKeyboardInput, InputType, LabelJava, ContentsJava); - Env->DeleteLocalRef(ContentsJava); - Env->DeleteLocalRef(LabelJava); + auto LabelJava = FJavaHelper::ToJavaString(Env, Label); + auto ContentsJava = FJavaHelper::ToJavaString(Env, Contents); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_ShowVirtualKeyboardInput, InputType, *LabelJava, *ContentsJava); } } @@ -966,8 +935,8 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeVirtualKeyboardResult( { if (VirtualKeyboardWidget.IsValid()) { - const char* javaChars = jenv->GetStringUTFChars(contents, 0); - + auto Contents = FJavaHelper::FStringFromParam(jenv, contents); + // call to set the widget text on game thread if (FTaskGraphInterface::IsRunning()) { @@ -976,7 +945,7 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeVirtualKeyboardResult( TSharedPtr LockedKeyboardWidget(VirtualKeyboardWidget.Pin()); if (LockedKeyboardWidget.IsValid()) { - LockedKeyboardWidget->SetTextFromVirtualKeyboard(FText::FromString(FString(UTF8_TO_TCHAR(javaChars))), ETextEntryType::TextEntryAccepted); + LockedKeyboardWidget->SetTextFromVirtualKeyboard(FText::FromString(Contents), ETextEntryType::TextEntryAccepted); } // release reference @@ -989,8 +958,6 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeVirtualKeyboardResult( // release reference VirtualKeyboardWidget.Reset(); } - // release string - jenv->ReleaseStringUTFChars(contents, javaChars); } } else @@ -1005,8 +972,8 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeVirtualKeyboardChanged { if (VirtualKeyboardWidget.IsValid()) { - const char* javaChars = jenv->GetStringUTFChars(contents, 0); - + auto Contents = FJavaHelper::FStringFromParam(jenv, contents); + // call to set the widget text on game thread if (FTaskGraphInterface::IsRunning()) { @@ -1015,13 +982,11 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeVirtualKeyboardChanged TSharedPtr LockedKeyboardWidget(VirtualKeyboardWidget.Pin()); if (LockedKeyboardWidget.IsValid()) { - LockedKeyboardWidget->SetTextFromVirtualKeyboard(FText::FromString(FString(UTF8_TO_TCHAR(javaChars))), ETextEntryType::TextEntryUpdated); + LockedKeyboardWidget->SetTextFromVirtualKeyboard(FText::FromString(Contents), ETextEntryType::TextEntryUpdated); } }, TStatId(), NULL, ENamedThreads::GameThread); FTaskGraphInterface::Get().WaitUntilTaskCompletes(SetWidgetText); } - // release string - jenv->ReleaseStringUTFChars(contents, javaChars); } } @@ -1057,9 +1022,8 @@ void AndroidThunkCpp_LaunchURL(const FString& URL) { if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring Argument = Env->NewStringUTF(TCHAR_TO_UTF8(*URL)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_LaunchURL, Argument); - Env->DeleteLocalRef(Argument); + auto Argument = FJavaHelper::ToJavaString(Env, URL); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_LaunchURL, *Argument); } } @@ -1075,9 +1039,8 @@ void AndroidThunkCpp_ShowAdBanner(const FString& AdUnitID, bool bShowOnBottomOfS { if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring AdUnitIDArg = Env->NewStringUTF(TCHAR_TO_UTF8(*AdUnitID)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_ShowAdBanner, AdUnitIDArg, bShowOnBottomOfScreen); - Env->DeleteLocalRef(AdUnitIDArg); + auto AdUnitIDArg = FJavaHelper::ToJavaString(Env, AdUnitID); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_ShowAdBanner, *AdUnitIDArg, bShowOnBottomOfScreen); } } @@ -1101,9 +1064,8 @@ void AndroidThunkCpp_LoadInterstitialAd(const FString& AdUnitID) { if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring AdUnitIDArg = Env->NewStringUTF(TCHAR_TO_UTF8(*AdUnitID)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_LoadInterstitialAd, AdUnitIDArg); - Env->DeleteLocalRef(AdUnitIDArg); + auto AdUnitIDArg = FJavaHelper::ToJavaString(Env, AdUnitID); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_LoadInterstitialAd, *AdUnitIDArg); } } @@ -1143,14 +1105,7 @@ FString AndroidThunkCpp_GetAdvertisingId() if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring adId =(jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_GetAdvertisingId); - if (!Env->IsSameObject(adId, NULL)) - { - const char *nativeAdIdString = Env->GetStringUTFChars(adId, 0); - adIdResult = FString(nativeAdIdString); - Env->ReleaseStringUTFChars(adId, nativeAdIdString); - Env->DeleteLocalRef(adId); - } + adIdResult = FJavaHelper::FStringFromLocalRef(Env, (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_GetAdvertisingId)); } return adIdResult; } @@ -1161,14 +1116,7 @@ FString AndroidThunkCpp_GetAndroidId() if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring androidId = (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetAndroidId); - if (!Env->IsSameObject(androidId, NULL)) - { - const char *nativeandroidIdString = Env->GetStringUTFChars(androidId, 0); - androidIdResult = FString(nativeandroidIdString); - Env->ReleaseStringUTFChars(androidId, nativeandroidIdString); - Env->DeleteLocalRef(androidId); - } + androidIdResult = FJavaHelper::FStringFromLocalRef(Env, (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetAndroidId)); } return androidIdResult; } @@ -1177,13 +1125,10 @@ void AndroidThunkCpp_ShareURL(const FString& URL, const FText& Description, cons { if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring URLArg = Env->NewStringUTF(TCHAR_TO_UTF8(*URL)); - jstring DescArg = Env->NewStringUTF(TCHAR_TO_UTF8(*Description.ToString())); - jstring PromptArg = Env->NewStringUTF(TCHAR_TO_UTF8(*SharePrompt.ToString())); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_ShareURL, URLArg, DescArg, PromptArg, LocationHintX, LocationHintY); - Env->DeleteLocalRef(PromptArg); - Env->DeleteLocalRef(DescArg); - Env->DeleteLocalRef(URLArg); + auto URLArg = FJavaHelper::ToJavaString(Env, URL); + auto DescArg = FJavaHelper::ToJavaString(Env, Description.ToString()); + auto PromptArg = FJavaHelper::ToJavaString(Env, SharePrompt.ToString()); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_ShareURL, *URLArg, *DescArg, *PromptArg, LocationHintX, LocationHintY); } } @@ -1192,9 +1137,8 @@ bool AndroidThunkCpp_IsPackageInstalled(const FString& PackageName) bool result = false; if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring PackageNameArg = Env->NewStringUTF(TCHAR_TO_UTF8(*PackageName)); - result = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_IsPackageInstalled, PackageNameArg); - Env->DeleteLocalRef(PackageNameArg); + auto PackageNameArg = FJavaHelper::ToJavaString(Env, PackageName); + result = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_IsPackageInstalled, *PackageNameArg); } return result; } @@ -1204,13 +1148,10 @@ bool AndroidThunkCpp_LaunchPackage(const FString& PackageName, const FString& Ex bool result = false; if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring PackageNameArg = Env->NewStringUTF(TCHAR_TO_UTF8(*PackageName)); - jstring ExtraKeyArg = Env->NewStringUTF(TCHAR_TO_UTF8(*ExtraKey)); - jstring ExtraValueArg = Env->NewStringUTF(TCHAR_TO_UTF8(*ExtraValue)); - result = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_LaunchPackage, PackageNameArg, ExtraKeyArg, ExtraValueArg); - Env->DeleteLocalRef(ExtraValueArg); - Env->DeleteLocalRef(ExtraKeyArg); - Env->DeleteLocalRef(PackageNameArg); + auto PackageNameArg = FJavaHelper::ToJavaString(Env, PackageName); + auto ExtraKeyArg = FJavaHelper::ToJavaString(Env, ExtraKey); + auto ExtraValueArg = FJavaHelper::ToJavaString(Env, ExtraValue); + result = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_LaunchPackage, *PackageNameArg, *ExtraKeyArg, *ExtraValueArg); } return result; } @@ -1220,13 +1161,11 @@ bool AndroidThunkCpp_SendBroadcast(const FString& PackageName, const FString& Ex bool result = false; if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring PackageNameArg = Env->NewStringUTF(TCHAR_TO_UTF8(*PackageName)); - jstring ExtraKeyArg = Env->NewStringUTF(TCHAR_TO_UTF8(*ExtraKey)); - jstring ExtraValueArg = Env->NewStringUTF(TCHAR_TO_UTF8(*ExtraValue)); - result = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_SendBroadcast, PackageNameArg, ExtraKeyArg, ExtraValueArg, bExit); - Env->DeleteLocalRef(ExtraValueArg); - Env->DeleteLocalRef(ExtraKeyArg); - Env->DeleteLocalRef(PackageNameArg); + auto PackageNameArg = FJavaHelper::ToJavaString(Env, PackageName); + auto ExtraKeyArg = FJavaHelper::ToJavaString(Env, ExtraKey); + auto ExtraValueArg = FJavaHelper::ToJavaString(Env, ExtraValue); + + result = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_SendBroadcast, *PackageNameArg, *ExtraKeyArg, *ExtraValueArg, bExit); } return result; } @@ -1259,9 +1198,8 @@ jobject AndroidJNI_GetJavaAssetManager() { if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jobject local = FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetAssetManager); - GJavaAssetManager = (jobject)Env->NewGlobalRef(local); - Env->DeleteLocalRef(local); + auto local = NewScopedJavaObject(Env, FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_GetAssetManager)); + GJavaAssetManager = (jobject)Env->NewGlobalRef(*local); } } return GJavaAssetManager; @@ -1312,9 +1250,8 @@ void AndroidThunkCpp_Iap_SetupIapService(const FString& InProductKey) { if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring ProductKey = Env->NewStringUTF(TCHAR_TO_UTF8(*InProductKey)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_IapSetupService, ProductKey); - Env->DeleteLocalRef(ProductKey); + auto ProductKey = FJavaHelper::ToJavaString(Env, InProductKey); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_IapSetupService, *ProductKey); } } @@ -1328,21 +1265,17 @@ bool AndroidThunkCpp_Iap_QueryInAppPurchases(const TArray& ProductIDs) CHECK_JNI_METHOD(FJavaWrapper::AndroidThunkJava_IapQueryInAppPurchases); // Populate some java types with the provided product information - jobjectArray ProductIDArray = (jobjectArray)Env->NewObjectArray(ProductIDs.Num(), FJavaWrapper::JavaStringClass, NULL); - if (ProductIDArray != 0) + auto ProductIDArray = NewScopedJavaObject(Env, (jobjectArray)Env->NewObjectArray(ProductIDs.Num(), FJavaWrapper::JavaStringClass, NULL)); + if (ProductIDArray) { for (uint32 Param = 0; Param < ProductIDs.Num(); Param++) { - jstring StringValue = Env->NewStringUTF(TCHAR_TO_UTF8(*ProductIDs[Param])); - Env->SetObjectArrayElement(ProductIDArray, Param, StringValue); - Env->DeleteLocalRef(StringValue); + auto StringValue = FJavaHelper::ToJavaString(Env, ProductIDs[Param]); + Env->SetObjectArrayElement(*ProductIDArray, Param, *StringValue); } - + // Execute the java code for this operation - bResult = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_IapQueryInAppPurchases, ProductIDArray); - - // clean up references - Env->DeleteLocalRef(ProductIDArray); + bResult = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_IapQueryInAppPurchases, *ProductIDArray); } } @@ -1363,9 +1296,8 @@ bool AndroidThunkCpp_Iap_BeginPurchase(const FString& ProductID) { CHECK_JNI_METHOD(FJavaWrapper::AndroidThunkJava_IapBeginPurchase); - jstring ProductIdJava = Env->NewStringUTF(TCHAR_TO_UTF8(*ProductID)); - bResult = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_IapBeginPurchase, ProductIdJava); - Env->DeleteLocalRef(ProductIdJava); + auto ProductIdJava = FJavaHelper::ToJavaString(Env, ProductID); + bResult = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_IapBeginPurchase, *ProductIdJava); } return bResult; @@ -1388,11 +1320,10 @@ bool AndroidThunkCpp_Iap_ConsumePurchase(const FString& ProductToken) { CHECK_JNI_METHOD(FJavaWrapper::AndroidThunkJava_IapConsumePurchase); - jstring ProductTokenJava = Env->NewStringUTF(TCHAR_TO_UTF8(*ProductToken)); + auto ProductTokenJava = FJavaHelper::ToJavaString(Env, ProductToken); //FPlatformMisc::LowLevelOutputDebugStringf(TEXT("[JNI] - AndroidThunkCpp_Iap_ConsumePurchase BEGIN")); - bResult = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_IapConsumePurchase, ProductTokenJava); + bResult = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_IapConsumePurchase, *ProductTokenJava); //FPlatformMisc::LowLevelOutputDebugStringf(TEXT("[JNI] - AndroidThunkCpp_Iap_ConsumePurchase END")); - Env->DeleteLocalRef(ProductTokenJava); } } @@ -1439,26 +1370,21 @@ bool AndroidThunkCpp_Iap_RestorePurchases(const TArray& ProductIDs, con CHECK_JNI_METHOD(FJavaWrapper::AndroidThunkJava_IapRestorePurchases); // Populate some java types with the provided product information - jobjectArray ProductIDArray = (jobjectArray)Env->NewObjectArray(ProductIDs.Num(), FJavaWrapper::JavaStringClass, NULL); - jbooleanArray ConsumeArray = (jbooleanArray)Env->NewBooleanArray(ProductIDs.Num()); + auto ProductIDArray = NewScopedJavaObject(Env, (jobjectArray)Env->NewObjectArray(ProductIDs.Num(), FJavaWrapper::JavaStringClass, NULL)); + auto ConsumeArray = NewScopedJavaObject(Env, (jbooleanArray)Env->NewBooleanArray(ProductIDs.Num())); - jboolean* ConsumeArrayValues = Env->GetBooleanArrayElements(ConsumeArray, 0); + jboolean* ConsumeArrayValues = Env->GetBooleanArrayElements(*ConsumeArray, 0); for (uint32 Param = 0; Param < ProductIDs.Num(); Param++) { - jstring StringValue = Env->NewStringUTF(TCHAR_TO_UTF8(*ProductIDs[Param])); - Env->SetObjectArrayElement(ProductIDArray, Param, StringValue); - Env->DeleteLocalRef(StringValue); + auto StringValue = FJavaHelper::ToJavaString(Env, ProductIDs[Param]); + Env->SetObjectArrayElement(*ProductIDArray, Param, *StringValue); ConsumeArrayValues[Param] = bConsumable[Param]; } - Env->ReleaseBooleanArrayElements(ConsumeArray, ConsumeArrayValues, 0); + Env->ReleaseBooleanArrayElements(*ConsumeArray, ConsumeArrayValues, 0); // Execute the java code for this operation - bResult = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_IapRestorePurchases, ProductIDArray, ConsumeArray); - - // clean up references - Env->DeleteLocalRef(ProductIDArray); - Env->DeleteLocalRef(ConsumeArray); + bResult = FJavaWrapper::CallBooleanMethod(Env, FJavaWrapper::GoogleServicesThis, FJavaWrapper::AndroidThunkJava_IapRestorePurchases, *ProductIDArray, *ConsumeArray); } return bResult; @@ -1478,6 +1404,16 @@ void AndroidThunkCpp_SetDesiredViewSize(int32 Width, int32 Height) { FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_SetDesiredViewSize, Width, Height); } + +// #if BUILD_EMBEDDED_APP + + // also send info to native wrapper around embedded + FEmbeddedCallParamsHelper Helper; + Helper.Command = TEXT("setue4resolution"); + Helper.Parameters = { {TEXT("width"), LexToString(Width)}, {TEXT("height"), LexToString(Height)} }; + FEmbeddedDelegates::GetEmbeddedToNativeParamsDelegateForSubsystem(TEXT("native")).Broadcast(Helper); + +// #endif } void AndroidThunkCpp_ScheduleLocalNotificationAtTime(const FDateTime& FireDateTime, bool LocalTime, const FText& Title, const FText& Body, const FText& Action, const FString& ActivationEvent) @@ -1488,19 +1424,13 @@ void AndroidThunkCpp_ScheduleLocalNotificationAtTime(const FDateTime& FireDateTi JNIEnv* Env = FAndroidApplication::GetJavaEnv(); if (Env != NULL) { - jstring jFireDateTime = Env->NewStringUTF(TCHAR_TO_UTF8(*FireDateTimeFormatted)); - jstring jTitle = Env->NewStringUTF(TCHAR_TO_UTF8(*Title.ToString())); - jstring jBody = Env->NewStringUTF(TCHAR_TO_UTF8(*Body.ToString())); - jstring jAction = Env->NewStringUTF(TCHAR_TO_UTF8(*Action.ToString())); - jstring jActivationEvent = Env->NewStringUTF(TCHAR_TO_UTF8(*ActivationEvent)); - - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_LocalNotificationScheduleAtTime, jFireDateTime, LocalTime, jTitle, jBody, jAction, jActivationEvent); - - Env->DeleteLocalRef(jFireDateTime); - Env->DeleteLocalRef(jTitle); - Env->DeleteLocalRef(jBody); - Env->DeleteLocalRef(jAction); - Env->DeleteLocalRef(jActivationEvent); + auto jFireDateTime = FJavaHelper::ToJavaString(Env, FireDateTimeFormatted); + auto jTitle = FJavaHelper::ToJavaString(Env, Title.ToString()); + auto jBody = FJavaHelper::ToJavaString(Env, Body.ToString()); + auto jAction = FJavaHelper::ToJavaString(Env, Action.ToString()); + auto jActivationEvent = FJavaHelper::ToJavaString(Env, ActivationEvent); + + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_LocalNotificationScheduleAtTime, *jFireDateTime, LocalTime, *jTitle, *jBody, *jAction, *jActivationEvent); } } @@ -1515,21 +1445,14 @@ void AndroidThunkCpp_GetLaunchNotification(bool& NotificationLaunchedApp, FStrin JNIEnv* Env = FAndroidApplication::GetJavaEnv(); if (Env != NULL) { - jobject launchInfo = (jobject)Env->CallObjectMethod(FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_LocalNotificationGetLaunchNotification); - if (launchInfo != 0 && FJavaWrapper::LaunchNotificationUsed != 0) + auto launchInfo = NewScopedJavaObject(Env, (jobject)Env->CallObjectMethod(FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_LocalNotificationGetLaunchNotification)); + if (launchInfo && FJavaWrapper::LaunchNotificationUsed != 0) { - NotificationLaunchedApp = (bool)Env->GetBooleanField(launchInfo, FJavaWrapper::LaunchNotificationUsed); + NotificationLaunchedApp = (bool)Env->GetBooleanField(*launchInfo, FJavaWrapper::LaunchNotificationUsed); - jstring jsName = (jstring)Env->GetObjectField(launchInfo, FJavaWrapper::LaunchNotificationEvent); - CHECK_JNI_RESULT(jsName); - const char * nativeName = Env->GetStringUTFChars(jsName, 0); - ActivationEvent = FString(nativeName); - Env->ReleaseStringUTFChars(jsName, nativeName); - Env->DeleteLocalRef(jsName); - - FireDate = (int32)Env->GetIntField(launchInfo, FJavaWrapper::LaunchNotificationFireDate); - - Env->DeleteLocalRef(launchInfo); + ActivationEvent = FJavaHelper::FStringFromLocalRef(Env, (jstring)Env->GetObjectField(*launchInfo, FJavaWrapper::LaunchNotificationEvent)); + + FireDate = (int32)Env->GetIntField(*launchInfo, FJavaWrapper::LaunchNotificationFireDate); } } } @@ -1568,11 +1491,9 @@ void AndroidThunkCpp_SetThreadName(const char * name) { if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring jname = Env->NewStringUTF(name); - jobject currentThread = Env->CallStaticObjectMethod(FJavaWrapper::ThreadClass, FJavaWrapper::CurrentThreadMethod, nullptr); - Env->CallVoidMethod(currentThread, FJavaWrapper::SetNameMethod, jname); - Env->DeleteLocalRef(jname); - Env->DeleteLocalRef(currentThread); + auto jname = FJavaHelper::ToJavaString(Env, FString(name)); + auto currentThread = NewScopedJavaObject(Env, Env->CallStaticObjectMethod(FJavaWrapper::ThreadClass, FJavaWrapper::CurrentThreadMethod, nullptr)); + Env->CallVoidMethod(*currentThread, FJavaWrapper::SetNameMethod, *jname); } } @@ -1609,29 +1530,19 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* InJavaVM, void* InReserved) } // Cache path to external storage - jclass EnvClass = Env->FindClass("android/os/Environment"); - jmethodID getExternalStorageDir = Env->GetStaticMethodID(EnvClass, "getExternalStorageDirectory", "()Ljava/io/File;"); - jobject externalStoragePath = Env->CallStaticObjectMethod(EnvClass, getExternalStorageDir, nullptr); + auto EnvClass = NewScopedJavaObject(Env, Env->FindClass("android/os/Environment")); + jmethodID getExternalStorageDir = Env->GetStaticMethodID(*EnvClass, "getExternalStorageDirectory", "()Ljava/io/File;"); + auto externalStoragePath = NewScopedJavaObject(Env, Env->CallStaticObjectMethod(*EnvClass, getExternalStorageDir, nullptr)); jmethodID getFilePath = Env->GetMethodID(Env->FindClass("java/io/File"), "getPath", "()Ljava/lang/String;"); - jstring pathString = (jstring)Env->CallObjectMethod(externalStoragePath, getFilePath, nullptr); - const char *nativePathString = Env->GetStringUTFChars(pathString, 0); - // Copy that somewhere safe - GFilePathBase = FString(nativePathString); + // Copy that somewhere safe + GFilePathBase = FJavaHelper::FStringFromLocalRef(Env, (jstring)Env->CallObjectMethod(*externalStoragePath, getFilePath, nullptr)); GOBBFilePathBase = GFilePathBase; // then release... - Env->ReleaseStringUTFChars(pathString, nativePathString); - Env->DeleteLocalRef(pathString); - Env->DeleteLocalRef(externalStoragePath); - Env->DeleteLocalRef(EnvClass); FPlatformMisc::LowLevelOutputDebugStringf(TEXT("Path found as '%s'\n"), *GFilePathBase); // Get the system font directory - jstring fontPath = (jstring)Env->CallStaticObjectMethod(FJavaWrapper::GameActivityClassID, FJavaWrapper::AndroidThunkJava_GetFontDirectory); - const char * nativeFontPathString = Env->GetStringUTFChars(fontPath, 0); - GFontPathBase = FString(nativeFontPathString); - Env->ReleaseStringUTFChars(fontPath, nativeFontPathString); - Env->DeleteLocalRef(fontPath); + GFontPathBase = FJavaHelper::FStringFromLocalRef(Env, (jstring)Env->CallStaticObjectMethod(FJavaWrapper::GameActivityClassID, FJavaWrapper::AndroidThunkJava_GetFontDirectory)); FPlatformMisc::LowLevelOutputDebugStringf(TEXT("Font Path found as '%s'\n"), *GFontPathBase); // Wire up to core delegates, so core code can call out to Java @@ -1673,18 +1584,10 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeSetGlobalActivity(JNIE //GOBBinAPK = (bool)jenv->CallStaticBooleanMethod(FJavaWrapper::GameActivityClassID, isOBBInAPKMethod, nullptr); GOBBinAPK = bOBBinAPK; - const char *nativeAPKFilenameString = jenv->GetStringUTFChars(APKFilename, 0); - GAPKFilename = FString(nativeAPKFilenameString); - jenv->ReleaseStringUTFChars(APKFilename, nativeAPKFilenameString); - - const char *nativeInternalPath = jenv->GetStringUTFChars(internalFilePath, 0); - GInternalFilePath = FString(nativeInternalPath); - jenv->ReleaseStringUTFChars(internalFilePath, nativeInternalPath); - - const char *nativeExternalPath = jenv->GetStringUTFChars(externalFilePath, 0); - GExternalFilePath = FString(nativeExternalPath); - jenv->ReleaseStringUTFChars(externalFilePath, nativeExternalPath); - + GAPKFilename = FJavaHelper::FStringFromParam(jenv, APKFilename); + GInternalFilePath = FJavaHelper::FStringFromParam(jenv, internalFilePath); + GExternalFilePath = FJavaHelper::FStringFromParam(jenv, externalFilePath); + if (bUseExternalFilesDir) { #if UE_BUILD_SHIPPING @@ -1741,9 +1644,8 @@ void AndroidThunkCpp_ClipboardCopy(const FString& Str) { if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring JStr = Env->NewStringUTF(TCHAR_TO_UTF8(*Str)); - FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_ClipboardCopy, JStr); - Env->DeleteLocalRef(JStr); + auto JStr = FJavaHelper::ToJavaString(Env, Str); + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_ClipboardCopy, *JStr); } } @@ -1753,19 +1655,14 @@ FString AndroidThunkCpp_ClipboardPaste() if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) { - jstring PasteString = (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_ClipboardPaste); - const char *nativePasteString = Env->GetStringUTFChars(PasteString, 0); - PasteStringResult = FString(nativePasteString); - Env->ReleaseStringUTFChars(PasteString, nativePasteString); - Env->DeleteLocalRef(PasteString); + PasteStringResult = FJavaHelper::FStringFromLocalRef(Env, (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, FJavaWrapper::AndroidThunkJava_ClipboardPaste)); } return PasteStringResult; } JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeOnSafetyNetAttestationSucceeded(JNIEnv* jenv, jobject thiz, jstring jwsData) { - const char* javaChars = jenv->GetStringUTFChars(jwsData, 0); - FString JwsString = FString(UTF8_TO_TCHAR(javaChars)); + FString JwsString = FJavaHelper::FStringFromParam(jenv, jwsData); // call to OnSafetyNetAttestationResultDelegate on game thread if (FTaskGraphInterface::IsRunning()) @@ -1776,9 +1673,6 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeOnSafetyNetAttestation }, TStatId(), NULL, ENamedThreads::GameThread); FTaskGraphInterface::Get().WaitUntilTaskCompletes(SafetyNetAttestationSucceeded); } - - // release string - jenv->ReleaseStringUTFChars(jwsData, javaChars); } JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeOnSafetyNetAttestationFailed(JNIEnv* jenv, jobject thiz, jint jwsValue) @@ -1793,4 +1687,187 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeOnSafetyNetAttestation FTaskGraphInterface::Get().WaitUntilTaskCompletes(SafetyNetAttestationFailed); } } -#endif \ No newline at end of file + + + +#include "Async/TaskGraphInterfaces.h" + +static jmethodID ReplyMethod; + +void AndroidThunkCpp_OnNativeToEmbeddedReply(FString ID, const FEmbeddedCommunicationMap& InReturnValues, FString InError, FString RoutingFunction) +{ + if (JNIEnv* Env = FAndroidApplication::GetJavaEnv()) + { + // marshall some data + + UE_LOG(LogInit, Display, TEXT("Java call Id: %s, Routing Function: %s, Error %s, Params:"), *ID, *RoutingFunction, *InError); + + // create a string array for the pairs + static auto StringClass = FJavaWrapper::FindClassGlobalRef(Env, "java/lang/String", false); + auto ReturnValues = NewScopedJavaObject(Env, Env->NewObjectArray(InReturnValues.Num() * 2, StringClass, 0)); + int32 Index = 0; + for (auto It : InReturnValues) + { + auto KeyString = FJavaHelper::ToJavaString(Env, It.Key); + auto ValueString = FJavaHelper::ToJavaString(Env, It.Value); + Env->SetObjectArrayElement(*ReturnValues, Index++, *KeyString); + Env->SetObjectArrayElement(*ReturnValues, Index++, *ValueString); + UE_LOG(LogInit, Display, TEXT(" %s : %s"), *It.Key, *It.Value); + } + auto Error = FJavaHelper::ToJavaString(Env, InError); + + // call back into java + auto IDReturn = FJavaHelper::ToJavaString(Env, ID); + auto RoutingFunctionReturn = FJavaHelper::ToJavaString(Env, RoutingFunction); + + FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, ReplyMethod, *IDReturn, *ReturnValues, *Error, *RoutingFunctionReturn); + } +} + + + +JNI_METHOD void Java_com_epicgames_ue4_NativeCalls_CallNativeToEmbedded(JNIEnv* jenv, jobject thiz, jstring InID, jint Priority, jstring InSubsystem, jstring InCommand, jobjectArray InParams, jstring InRoutingFunction) +{ +#if BUILD_EMBEDDED_APP + auto Subsystem = FJavaHelper::FStringFromParam(jenv, InSubsystem); + auto Command = FJavaHelper::FStringFromParam(jenv, InCommand); + auto ID = FJavaHelper::FStringFromParam(jenv, InID); + auto RoutingFunction = FJavaHelper::FStringFromParam(jenv, InRoutingFunction); + + FEmbeddedCallParamsHelper Helper; + Helper.Command = Command; + + FName SubsystemName(*Subsystem); + FName CommandName = *FString::Printf(TEXT("%s_%s"), *Subsystem, *Command); + + // wake up UE + FEmbeddedCommunication::KeepAwake(CommandName, false); + + FPlatformMisc::LowLevelOutputDebugStringf(TEXT("NativeToEmbeddedCall: Subsystem: %s, Command: %s, Params:"), *Subsystem, *Helper.Command); + + if (InParams != nullptr) + { + int32 Count = jenv->GetArrayLength(InParams); + int32 Index = 0; + while (Index < Count) + { + auto javaKey = FJavaHelper::FStringFromLocalRef(jenv, (jstring)(jenv->GetObjectArrayElement(InParams, Index++))); + auto javaValue = FJavaHelper::FStringFromLocalRef(jenv, (jstring)(jenv->GetObjectArrayElement(InParams, Index++))); + + Helper.Parameters.Add(javaKey, javaValue); + FPlatformMisc::LowLevelOutputDebugStringf(TEXT(" %s : %s"), *javaKey, *javaValue); + } + } + + Helper.OnCompleteDelegate = [CommandName, ID, RoutingFunction](const FEmbeddedCommunicationMap& InReturnValues, FString InError) + { + // wake up UE + FEmbeddedCommunication::AllowSleep(CommandName); + + AndroidThunkCpp_OnNativeToEmbeddedReply(ID, InReturnValues, InError, RoutingFunction); + }; + + FEmbeddedCommunication::RunOnGameThread(Priority, [SubsystemName, Helper]() + { + if (FEmbeddedDelegates::GetNativeToEmbeddedParamsDelegateForSubsystem(SubsystemName).IsBound()) + { + FEmbeddedDelegates::GetNativeToEmbeddedParamsDelegateForSubsystem(SubsystemName).Broadcast(Helper); + } + else + { + Helper.OnCompleteDelegate({} , FString::Printf(TEXT("No one is listening to subsystem %s"), *SubsystemName.ToString())); + } + }); +#endif // BUILD_EMBEDDED_APP +} + +JNI_METHOD void Java_com_epicgames_ue4_NativeCalls_SetNamedObject(JNIEnv* jenv, jobject thiz, jstring InName, jobject InObj) +{ + auto Name = FJavaHelper::FStringFromParam(jenv, InName); + FEmbeddedDelegates::SetNamedObject(Name, (void*)InObj); +} + +JNI_METHOD void Java_com_epicgames_ue4_NativeCalls_KeepAwake(JNIEnv* jenv, jobject thiz, jstring InRequester, jboolean bIsForRendering) +{ + auto Requester = FJavaHelper::FStringFromParam(jenv, InRequester); + FEmbeddedCommunication::KeepAwake(*Requester, bIsForRendering); +} + +JNI_METHOD void Java_com_epicgames_ue4_NativeCalls_AllowSleep(JNIEnv* jenv, jobject thiz, jstring InRequester) +{ + auto Requester = FJavaHelper::FStringFromParam(jenv, InRequester); + FEmbeddedCommunication::AllowSleep(*Requester); +} + + +void FJavaWrapper::SetupEmbeddedCommunication(JNIEnv* Env) +{ +#if BUILD_EMBEDDED_APP + ReplyMethod = FJavaWrapper::FindMethod(Env, GGameActivityClassID, "AndroidThunkJava_OnNativeToEmbeddedReply", "(Ljava/lang/Object;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", false); + + FEmbeddedDelegates::GetEmbeddedToNativeParamsDelegateForSubsystem(TEXT("webview")).AddLambda([](const FEmbeddedCallParamsHelper& InMessage) + { + UE_LOG(LogAndroid, Display, TEXT("Calling out from embedded to native for 'webview' subsystem:")); + + AndroidThunkCpp_OnNativeToEmbeddedReply(InMessage.Command, InMessage.Parameters, TEXT(""), TEXT("webviewnotification")); + + // @todo: Do we need to have results passed back? if so we will need a wrapper block that we pass in to all of the above handling things to call back + // same for ios + if (InMessage.OnCompleteDelegate != nullptr) + { + InMessage.OnCompleteDelegate(FEmbeddedCommunicationMap(), TEXT("")); + } + }); + + FEmbeddedDelegates::GetEmbeddedToNativeParamsDelegateForSubsystem(TEXT("native")).AddLambda([](const FEmbeddedCallParamsHelper& InMessage) + { + UE_LOG(LogAndroid, Display, TEXT("Calling out from embedded to native for 'native' subsystem:")); + + AndroidThunkCpp_OnNativeToEmbeddedReply(InMessage.Command, InMessage.Parameters, TEXT(""), TEXT("native")); + + // @todo: Do we need to have results passed back? if so we will need a wrapper block that we pass in to all of the above handling things to call back + // same for ios + if (InMessage.OnCompleteDelegate != nullptr) + { + InMessage.OnCompleteDelegate(FEmbeddedCommunicationMap(), TEXT("")); + } + }); +#endif +} + +JNI_METHOD void Java_com_epicgames_ue4_NativeCalls_ForwardNotification(JNIEnv* jenv, jobject thiz, jstring payload) +{ + // +} + +class FAndroidEmbeddedExec : public FSelfRegisteringExec +{ +public: + FAndroidEmbeddedExec() + : FSelfRegisteringExec() + { + + } + + virtual bool Exec(UWorld* Inworld, const TCHAR* Cmd, FOutputDevice& Ar) override + { + if (FParse::Command(&Cmd, TEXT("Android"))) + { + // commands to override and append commandline options for next boot (see FIOSCommandLineHelper) + if (FParse::Command(&Cmd, TEXT("HideWeb"))) + { + AndroidThunkCpp_OnNativeToEmbeddedReply(TEXT("HideWeb"), {}, TEXT(""), TEXT("native")); + } + else if (FParse::Command(&Cmd, TEXT("ShowWeb"))) + { + AndroidThunkCpp_OnNativeToEmbeddedReply(TEXT("ShowWeb"), {}, TEXT(""), TEXT("native")); + } + } + + return false; + } +} GAndroidEmbeddedExec; + + + +#endif diff --git a/Engine/Source/Runtime/Launch/Private/Android/LaunchAndroid.cpp b/Engine/Source/Runtime/Launch/Private/Android/LaunchAndroid.cpp index 200e9f854cd2..9d277afe9d86 100644 --- a/Engine/Source/Runtime/Launch/Private/Android/LaunchAndroid.cpp +++ b/Engine/Source/Runtime/Launch/Private/Android/LaunchAndroid.cpp @@ -33,6 +33,7 @@ #include "Android/AndroidStats.h" #include "MoviePlayer.h" #include "PreLoadScreenManager.h" +#include "Misc/EmbeddedCommunication.h" #include #include @@ -140,7 +141,8 @@ extern void AndroidThunkCpp_InitHMDs(); extern void AndroidThunkCpp_ShowConsoleWindow(); extern bool AndroidThunkCpp_VirtualInputIgnoreClick(int, int); extern bool AndroidThunkCpp_IsVirtuaKeyboardShown(); -extern void AndroidThunkCpp_RestartApplication(); +extern bool AndroidThunkCpp_IsWebViewShown(); +extern void AndroidThunkCpp_RestartApplication(const FString& IntentString); // Base path for file accesses extern FString GFilePathBase; @@ -164,6 +166,7 @@ static const float EventRefreshRate = 1.0f / 20.0f; static int32_t HandleInputCB(struct android_app* app, AInputEvent* event); //Touch and key input events static void OnAppCommandCB(struct android_app* app, int32_t cmd); //Lifetime events +static bool TryIgnoreClick(AInputEvent* event, size_t actionPointer); bool GHasInterruptionRequest = false; bool GIsInterrupted = false; @@ -436,10 +439,8 @@ int32 AndroidMain(struct android_app* state) FAppEventManager::GetInstance()->SetEmptyQueueHandlerEvent(FPlatformProcess::GetSynchEventFromPool(false)); - { - SCOPED_BOOT_TIMING("GEngineLoop.Init()"); - GEngineLoop.Init(); - } + GEngineLoop.Init(); + bDidCompleteEngineInit = true; UE_LOG(LogAndroid, Log, TEXT("Passed GEngineLoop.Init()")); @@ -697,6 +698,20 @@ void android_main(struct android_app* state) extern bool GAndroidGPUInfoReady; +static bool TryIgnoreClick(AInputEvent* event, size_t actionPointer) +{ + int pointerId = AMotionEvent_getPointerId(event, actionPointer); + int32 x = AMotionEvent_getX(event, actionPointer); + int32 y = AMotionEvent_getY(event, actionPointer); + + //ignore key down events click was within bounds + if (AndroidThunkCpp_VirtualInputIgnoreClick(x, y)) + { + return true; + } + return false; +} + //Called from the event process thread static int32_t HandleInputCB(struct android_app* app, AInputEvent* event) { @@ -873,16 +888,22 @@ static int32_t HandleInputCB(struct android_app* app, AInputEvent* event) if (AndroidThunkCpp_IsVirtuaKeyboardShown() && (type == TouchBegan || type == TouchMoved)) { - int pointerId = AMotionEvent_getPointerId(event, actionPointer); - int32 x = AMotionEvent_getX(event, actionPointer); - int32 y = AMotionEvent_getY(event, actionPointer); - //ignore key down events when the native input was clicked or when the keyboard animation is playing - if (AndroidThunkCpp_VirtualInputIgnoreClick(x, y)) + if (TryIgnoreClick(event, actionPointer)) { return 0; } } + else if (AndroidThunkCpp_IsWebViewShown() && (type == TouchBegan || type == TouchMoved || type == TouchEnded)) + { + //ignore key down events when the the a web view is visible + if (TryIgnoreClick(event, actionPointer) && ((EventSource & 0x80) != 0x80)) + { + UE_LOG(LogAndroid, Verbose, TEXT("Received touch event %d - Ignored"), type); + return 0; + } + UE_LOG(LogAndroid, Verbose, TEXT("Received touch event %d"), type); + } if(isActionTargeted) { if(actionPointer < 0 || pointerCount < (int)actionPointer) @@ -1168,10 +1189,11 @@ static void OnAppCommandCB(struct android_app* app, int32_t cmd) */ if (bShouldRestartFromInterrupt) { - AndroidThunkCpp_RestartApplication(); + AndroidThunkCpp_RestartApplication(TEXT("")); } break; case APP_CMD_PAUSE: + { /** * Command from main thread: the app's activity has been paused. */ @@ -1179,8 +1201,16 @@ static void OnAppCommandCB(struct android_app* app, int32_t cmd) UE_LOG(LogAndroid, Log, TEXT("Case APP_CMD_PAUSE")); FAppEventManager::GetInstance()->EnqueueAppEvent(APP_EVENT_STATE_ON_PAUSE); + bool bAllowReboot = true; +#if FAST_BOOT_HACKS + if (FEmbeddedDelegates::GetNamedObject(TEXT("LoggedInObject")) == nullptr) + { + bAllowReboot = false; + } +#endif + // Restart on resuming if did not complete engine initialization - if (!bDidCompleteEngineInit && bDidGainFocus && !bIgnorePauseOnDownloaderStart) + if (!bDidCompleteEngineInit && bDidGainFocus && !bIgnorePauseOnDownloaderStart && bAllowReboot) { // only do this if early startup enabled FString *EarlyRestart = FAndroidMisc::GetConfigRulesVariable(TEXT("earlyrestart")); @@ -1195,16 +1225,17 @@ static void OnAppCommandCB(struct android_app* app, int32_t cmd) * On the initial loading the pause method must be called immediately * in order to stop the startup movie's sound */ - if (IsPreLoadScreenPlaying()) + if (IsPreLoadScreenPlaying() && bAllowReboot) { bShouldRestartFromInterrupt = true; GetMoviePlayer()->ForceCompletion(); - } + } FPreLoadScreenManager::EnableRendering(false); bNeedToSync = true; break; + } case APP_CMD_STOP: /** * Command from main thread: the app's activity has been stopped. @@ -1277,19 +1308,16 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeOnConfigurationChanged //This function is declared in the Java-defined class, GameActivity.java: "public native void nativeConsoleCommand(String commandString);" JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeConsoleCommand(JNIEnv* jenv, jobject thiz, jstring commandString) { - const char* javaChars = jenv->GetStringUTFChars(commandString, 0); - + auto Command = FJavaHelper::FStringFromParam(jenv, commandString); + if (GEngine != NULL) { - new(GEngine->DeferredCommands) FString(UTF8_TO_TCHAR(javaChars)); + GEngine->DeferredCommands.Add(Command); } else { - FPlatformMisc::LowLevelOutputDebugStringf(TEXT("Ignoring console command (too early): %s"), UTF8_TO_TCHAR(javaChars)); + FPlatformMisc::LowLevelOutputDebugStringf(TEXT("Ignoring console command (too early): %s"), *Command); } - - //Release the string - jenv->ReleaseStringUTFChars(commandString, javaChars); } // This is called from the Java UI thread for initializing VR HMDs @@ -1305,26 +1333,12 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeInitHMDs(JNIEnv* jenv, JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeSetAndroidVersionInformation(JNIEnv* jenv, jobject thiz, jstring androidVersion, jstring phoneMake, jstring phoneModel, jstring phoneBuildNumber, jstring osLanguage ) { - const char *javaAndroidVersion = jenv->GetStringUTFChars(androidVersion, 0 ); - FString UEAndroidVersion = FString(UTF8_TO_TCHAR( javaAndroidVersion )); - jenv->ReleaseStringUTFChars(androidVersion, javaAndroidVersion); - - const char *javaPhoneMake = jenv->GetStringUTFChars(phoneMake, 0 ); - FString UEPhoneMake = FString(UTF8_TO_TCHAR( javaPhoneMake )); - jenv->ReleaseStringUTFChars(phoneMake, javaPhoneMake); - - const char *javaPhoneModel = jenv->GetStringUTFChars(phoneModel, 0 ); - FString UEPhoneModel = FString(UTF8_TO_TCHAR( javaPhoneModel )); - jenv->ReleaseStringUTFChars(phoneModel, javaPhoneModel); - - const char *javaPhoneBuildNumber = jenv->GetStringUTFChars(phoneBuildNumber, 0); - FString UEPhoneBuildNumber = FString(UTF8_TO_TCHAR(javaPhoneBuildNumber)); - jenv->ReleaseStringUTFChars(phoneBuildNumber, javaPhoneBuildNumber); - - const char *javaOSLanguage = jenv->GetStringUTFChars(osLanguage, 0); - FString UEOSLanguage = FString(UTF8_TO_TCHAR(javaOSLanguage)); - jenv->ReleaseStringUTFChars(osLanguage, javaOSLanguage); - + auto UEAndroidVersion = FJavaHelper::FStringFromParam(jenv, androidVersion); + auto UEPhoneMake = FJavaHelper::FStringFromParam(jenv, phoneMake); + auto UEPhoneModel = FJavaHelper::FStringFromParam(jenv, phoneModel); + auto UEPhoneBuildNumber = FJavaHelper::FStringFromParam(jenv, phoneBuildNumber); + auto UEOSLanguage = FJavaHelper::FStringFromParam(jenv, osLanguage); + FAndroidMisc::SetVersionInfo( UEAndroidVersion, UEPhoneMake, UEPhoneModel, UEPhoneBuildNumber, UEOSLanguage ); } @@ -1340,9 +1354,44 @@ JNI_METHOD void Java_com_epicgames_ue4_GameActivity_nativeOnInitialDownloadCompl bIgnorePauseOnDownloaderStart = false; } +// MERGE-TODO: Anticheat concerns with custom input +bool GAllowCustomInput = true; +JNI_METHOD void Java_com_epicgames_ue4_NativeCalls_HandleCustomTouchEvent(JNIEnv* jenv, jobject thiz, jint deviceId, jint pointerId, jint action, jint soucre, jfloat x, jfloat y) +{ + // make sure fake input is allowed, so hacky Java can't run bots + if (!GAllowCustomInput) + { + return; + } + + TArray TouchesArray; + + TouchInput TouchMessage; + TouchMessage.DeviceId = deviceId; + TouchMessage.Handle = pointerId; + switch (action) { + case 0: // MotionEvent.ACTION_DOWN + TouchMessage.Type = TouchBegan; + break; + case 2: // MotionEvent.ACTION_MOVE + TouchMessage.Type = TouchMoved; + break; + default: // MotionEvent.ACTION_UP + TouchMessage.Type = TouchEnded; + break; + } + TouchMessage.Position = FVector2D(x, y); + TouchMessage.LastPosition = FVector2D(x, y); + + TouchesArray.Add(TouchMessage); + + UE_LOG(LogAndroid, Verbose, TEXT("Handle custom touch event %d (%d) x=%f y=%f"), TouchMessage.Type, action, x, y); + FAndroidInputInterface::QueueTouchInput(TouchesArray); +} + bool WaitForAndroidLoseFocusEvent(double TimeoutSeconds) { return FAppEventManager::GetInstance()->WaitForEventInQueue(EAppEventState::APP_EVENT_STATE_WINDOW_LOST_FOCUS, TimeoutSeconds); } -#endif \ No newline at end of file +#endif diff --git a/Engine/Source/Runtime/Launch/Private/IOS/IOSAppDelegateConsoleHandling.cpp b/Engine/Source/Runtime/Launch/Private/IOS/IOSAppDelegateConsoleHandling.cpp index db5466cd78b6..91572e421664 100644 --- a/Engine/Source/Runtime/Launch/Private/IOS/IOSAppDelegateConsoleHandling.cpp +++ b/Engine/Source/Runtime/Launch/Private/IOS/IOSAppDelegateConsoleHandling.cpp @@ -14,6 +14,11 @@ extern bool GShowSplashScreen; */ - (void)ShowConsole { + if (self.ConsoleAlertController != nil) + { + return; + } + // start at the end of the list for history self.ConsoleHistoryValuesIndex = [self.ConsoleHistoryValues count]; @@ -36,6 +41,8 @@ extern bool GShowSplashScreen; // we clicked Ok (not Cancel at index 0), submit the console command UITextField* AlertTextField = self.ConsoleAlertController.textFields.firstObject; [self HandleConsoleCommand:AlertTextField.text]; + + self.ConsoleAlertController = nil; } ]; UIAlertAction* cancelAction = [UIAlertAction @@ -45,6 +52,7 @@ extern bool GShowSplashScreen; { self.AlertResponse = 0; [self.ConsoleAlertController dismissViewControllerAnimated : YES completion : nil]; + self.ConsoleAlertController = nil; } ]; @@ -160,9 +168,9 @@ extern bool GShowSplashScreen; { if (GShowSplashScreen) { - if ([[IOSAppDelegate GetDelegate].Window viewWithTag : 2] != nil) + if ([[IOSAppDelegate GetDelegate].Window viewWithTag : 200] != nil) { - [[[IOSAppDelegate GetDelegate].Window viewWithTag : 2] removeFromSuperview]; + [[[IOSAppDelegate GetDelegate].Window viewWithTag : 200] removeFromSuperview]; } GShowSplashScreen = false; } diff --git a/Engine/Source/Runtime/Launch/Private/IOS/LaunchIOS.cpp b/Engine/Source/Runtime/Launch/Private/IOS/LaunchIOS.cpp index 56a8b6173d8a..b0c1331c3761 100644 --- a/Engine/Source/Runtime/Launch/Private/IOS/LaunchIOS.cpp +++ b/Engine/Source/Runtime/Launch/Private/IOS/LaunchIOS.cpp @@ -20,6 +20,8 @@ #include "GenericPlatform/GenericApplication.h" #include "Misc/ConfigCacheIni.h" #include "MoviePlayer.h" +#include "Containers/Ticker.h" +#include "HAL/ThreadManager.h" #include "PreLoadScreenManager.h" #include "TcpConsoleListener.h" #include "Interfaces/IPv4/IPv4Address.h" @@ -47,65 +49,69 @@ void FAppEntry::Suspend(bool bIsInterrupt) GetMoviePlayer()->Suspend(); } - if (GEngine && GEngine->GetMainAudioDevice()) + // if background audio is active, then we don't want to do suspend any audio + if ([[IOSAppDelegate GetDelegate] IsFeatureActive:EAudioFeature::BackgroundAudio] == false) { - FAudioDevice* AudioDevice = GEngine->GetMainAudioDevice(); - if (bIsInterrupt && DisableAudioSuspendOnAudioInterruptCvar) - { - if (FTaskGraphInterface::IsRunning()) - { - FFunctionGraphTask::CreateAndDispatchWhenReady([AudioDevice]() - { - FAudioThread::RunCommandOnAudioThread([AudioDevice]() - { - AudioDevice->SetTransientMasterVolume(0.0f); - }, TStatId()); - }, TStatId(), NULL, ENamedThreads::GameThread); - } - else - { - AudioDevice->SetTransientMasterVolume(0.0f); - } - } - else - { - if (FTaskGraphInterface::IsRunning()) - { - FGraphEventRef ResignTask = FFunctionGraphTask::CreateAndDispatchWhenReady([AudioDevice]() - { - FAudioThread::RunCommandOnAudioThread([AudioDevice]() - { - AudioDevice->SuspendContext(); - }, TStatId()); - - FAudioCommandFence AudioCommandFence; - AudioCommandFence.BeginFence(); - AudioCommandFence.Wait(); - }, TStatId(), NULL, ENamedThreads::GameThread); - - // Do not wait forever for this task to complete since the game thread may be stuck on waiting for user input from a modal dialog box - double startTime = FPlatformTime::Seconds(); - while((FPlatformTime::Seconds() - startTime) < cMaxThreadWaitTime) - { - FPlatformProcess::Sleep(0.05f); - if(ResignTask->IsComplete()) - { - break; - } - } - } - else - { - AudioDevice->SuspendContext(); - } - } - } - else - { - int32& SuspendCounter = FIOSAudioDevice::GetSuspendCounter(); - if (SuspendCounter == 0) + if (GEngine && GEngine->GetMainAudioDevice()) { - FPlatformAtomics::InterlockedIncrement(&SuspendCounter); + FAudioDevice* AudioDevice = GEngine->GetMainAudioDevice(); + if (bIsInterrupt && DisableAudioSuspendOnAudioInterruptCvar) + { + if (FTaskGraphInterface::IsRunning()) + { + FFunctionGraphTask::CreateAndDispatchWhenReady([AudioDevice]() + { + FAudioThread::RunCommandOnAudioThread([AudioDevice]() + { + AudioDevice->SetTransientMasterVolume(0.0f); + }, TStatId()); + }, TStatId(), NULL, ENamedThreads::GameThread); + } + else + { + AudioDevice->SetTransientMasterVolume(0.0f); + } + } + else + { + if (FTaskGraphInterface::IsRunning()) + { + FGraphEventRef ResignTask = FFunctionGraphTask::CreateAndDispatchWhenReady([AudioDevice]() + { + FAudioThread::RunCommandOnAudioThread([AudioDevice]() + { + AudioDevice->SuspendContext(); + }, TStatId()); + + FAudioCommandFence AudioCommandFence; + AudioCommandFence.BeginFence(); + AudioCommandFence.Wait(); + }, TStatId(), NULL, ENamedThreads::GameThread); + + // Do not wait forever for this task to complete since the game thread may be stuck on waiting for user input from a modal dialog box + double startTime = FPlatformTime::Seconds(); + while((FPlatformTime::Seconds() - startTime) < cMaxThreadWaitTime) + { + FPlatformProcess::Sleep(0.05f); + if(ResignTask->IsComplete()) + { + break; + } + } + } + else + { + AudioDevice->SuspendContext(); + } + } + } + else + { + int32& SuspendCounter = FIOSAudioDevice::GetSuspendCounter(); + if (SuspendCounter == 0) + { + FPlatformAtomics::InterlockedIncrement(&SuspendCounter); + } } } } @@ -117,51 +123,56 @@ void FAppEntry::Resume(bool bIsInterrupt) GetMoviePlayer()->Resume(); } - if (GEngine && GEngine->GetMainAudioDevice()) + // if background audio is active, then we don't want to do suspend any audio + // @todo: should this check if we were suspended, in case this changes while in the background? (suspend with background off, but resume with background audio on? is that a thing?) + if ([[IOSAppDelegate GetDelegate] IsFeatureActive:EAudioFeature::BackgroundAudio] == false) { - FAudioDevice* AudioDevice = GEngine->GetMainAudioDevice(); - - if (bIsInterrupt && DisableAudioSuspendOnAudioInterruptCvar) - { - if (FTaskGraphInterface::IsRunning()) - { - FFunctionGraphTask::CreateAndDispatchWhenReady([AudioDevice]() - { - FAudioThread::RunCommandOnAudioThread([AudioDevice]() - { - AudioDevice->SetTransientMasterVolume(1.0f); - }, TStatId()); - }, TStatId(), NULL, ENamedThreads::GameThread); - } - else - { - AudioDevice->SetTransientMasterVolume(1.0f); - } - } - else - { - if (FTaskGraphInterface::IsRunning()) - { - FFunctionGraphTask::CreateAndDispatchWhenReady([AudioDevice]() - { - FAudioThread::RunCommandOnAudioThread([AudioDevice]() - { - AudioDevice->ResumeContext(); - }, TStatId()); - }, TStatId(), NULL, ENamedThreads::GameThread); - } - else - { - AudioDevice->ResumeContext(); - } - } - } - else - { - int32& SuspendCounter = FIOSAudioDevice::GetSuspendCounter(); - if (SuspendCounter > 0) + if (GEngine && GEngine->GetMainAudioDevice()) { - FPlatformAtomics::InterlockedDecrement(&SuspendCounter); + FAudioDevice* AudioDevice = GEngine->GetMainAudioDevice(); + + if (bIsInterrupt && DisableAudioSuspendOnAudioInterruptCvar) + { + if (FTaskGraphInterface::IsRunning()) + { + FFunctionGraphTask::CreateAndDispatchWhenReady([AudioDevice]() + { + FAudioThread::RunCommandOnAudioThread([AudioDevice]() + { + AudioDevice->SetTransientMasterVolume(1.0f); + }, TStatId()); + }, TStatId(), NULL, ENamedThreads::GameThread); + } + else + { + AudioDevice->SetTransientMasterVolume(1.0f); + } + } + else + { + if (FTaskGraphInterface::IsRunning()) + { + FFunctionGraphTask::CreateAndDispatchWhenReady([AudioDevice]() + { + FAudioThread::RunCommandOnAudioThread([AudioDevice]() + { + AudioDevice->ResumeContext(); + }, TStatId()); + }, TStatId(), NULL, ENamedThreads::GameThread); + } + else + { + AudioDevice->ResumeContext(); + } + } + } + else + { + int32& SuspendCounter = FIOSAudioDevice::GetSuspendCounter(); + if (SuspendCounter > 0) + { + FPlatformAtomics::InterlockedDecrement(&SuspendCounter); + } } } } @@ -169,29 +180,21 @@ void FAppEntry::Resume(bool bIsInterrupt) void FAppEntry::PreInit(IOSAppDelegate* AppDelegate, UIApplication* Application) { // make a controller object - AppDelegate.IOSController = [[IOSViewController alloc] init]; + UIViewController* IOSController = [[IOSViewController alloc] init]; #if PLATFORM_TVOS // @todo tvos: This may need to be exposed to the game so that when you click Menu it will background the app // this is basically the same way Android handles the Back button (maybe we should pass Menu button as back... maybe) - AppDelegate.IOSController.controllerUserInteractionEnabled = NO; + IOSController.controllerUserInteractionEnabled = NO; #endif - // property owns it now - [AppDelegate.IOSController release]; - // point to the GL view we want to use - AppDelegate.RootView = [AppDelegate.IOSController view]; + AppDelegate.RootView = [IOSController view]; - if (AppDelegate.OSVersion >= 6.0f) - { - // this probably works back to OS4, but would need testing - [AppDelegate.Window setRootViewController:AppDelegate.IOSController]; - } - else - { - [AppDelegate.Window addSubview:AppDelegate.RootView]; - } + [AppDelegate.Window setRootViewController:IOSController]; + + // windows owns it now +// [IOSController release]; #if !PLATFORM_TVOS // reset badge count on launch @@ -207,18 +210,6 @@ static void MainThreadInit() // prior to creating any framebuffers CGRect MainFrame = [[UIScreen mainScreen] bounds]; - // we need to swap if compiled with ios7, or compiled with ios8 and running on 7 -#ifndef __IPHONE_8_0 - bool bDoLandscapeSwap = true; -#else - bool bDoLandscapeSwap = AppDelegate.OSVersion < 8.0f; -#endif - - if (bDoLandscapeSwap && !AppDelegate.bDeviceInPortraitMode) - { - Swap(MainFrame.size.width, MainFrame.size.height); - } - // @todo: use code similar for presizing for secondary screens // CGRect FullResolutionRect = // CGRectMake( @@ -234,6 +225,10 @@ static void MainThreadInit() CGRect FullResolutionRect = MainFrame; + // embedded apps are embedded inside a UE4 view, so it's already made +#if BUILD_EMBEDDED_APP + // checkf(AppDelegate.IOSView != nil, TEXT("For embedded apps, the UE4EmbeddedView must have been created and set into the AppDelegate as IOSView")); +#else AppDelegate.IOSView = [[FIOSView alloc] initWithFrame:FullResolutionRect]; AppDelegate.IOSView.clearsContextBeforeDrawing = NO; #if !PLATFORM_TVOS @@ -245,6 +240,7 @@ static void MainThreadInit() // initialize the backbuffer of the view (so the RHI can use it) [AppDelegate.IOSView CreateFramebuffer:YES]; +#endif } @@ -265,7 +261,13 @@ void FAppEntry::PlatformInit() while (!AppDelegate.IOSView || !AppDelegate.IOSView->bIsInitialized) { - FPlatformProcess::Sleep(0.001f); +#if BUILD_EMBEDDED_APP + // while embedded, the native app may be waiting on some processing to happen before showing the view, so we have to let + // processing occur here + FTicker::GetCoreTicker().Tick(0.005f); + FThreadManager::Get().Tick(); +#endif + FPlatformProcess::Sleep(0.005f); } // set the GL context to this thread @@ -282,6 +284,8 @@ extern TcpConsoleListener *ConsoleListener; void FAppEntry::Init() { + SCOPED_BOOT_TIMING("FAppEntry::Init()"); + FPlatformProcess::SetRealTimeMode(); //extern TCHAR GCmdLine[16384]; @@ -378,6 +382,8 @@ int32 FAppEntry::gLaunchLocalNotificationFireDate; FString GSavedCommandLine; +#if !BUILD_EMBEDDED_APP + int main(int argc, char *argv[]) { for(int Option = 1; Option < argc; Option++) @@ -408,3 +414,5 @@ int main(int argc, char *argv[]) return UIApplicationMain(argc, argv, nil, NSStringFromClass([IOSAppDelegate class])); } } + +#endif diff --git a/Engine/Source/Runtime/Launch/Private/Launch.cpp b/Engine/Source/Runtime/Launch/Private/Launch.cpp index b223967e48fc..4771cfad8b34 100644 --- a/Engine/Source/Runtime/Launch/Private/Launch.cpp +++ b/Engine/Source/Runtime/Launch/Private/Launch.cpp @@ -104,6 +104,8 @@ int32 GuardedMain( const TCHAR* CmdLine ) } #endif + BootTimingPoint("DefaultMain"); + // Super early init code. DO NOT MOVE THIS ANYWHERE ELSE! FCoreDelegates::GetPreMainInitDelegate().Broadcast(); @@ -165,6 +167,9 @@ int32 GuardedMain( const TCHAR* CmdLine ) ACCUM_LOADTIME(TEXT("EngineInitialization"), EngineInitializationTime); + BootTimingPoint("Tick loop starting"); + DumpBootTiming(); + while( !GIsRequestingExit ) { EngineTick(); diff --git a/Engine/Source/Runtime/Launch/Private/LaunchEngineLoop.cpp b/Engine/Source/Runtime/Launch/Private/LaunchEngineLoop.cpp index 07bc6ce9e9fd..0600d068be1c 100644 --- a/Engine/Source/Runtime/Launch/Private/LaunchEngineLoop.cpp +++ b/Engine/Source/Runtime/Launch/Private/LaunchEngineLoop.cpp @@ -164,6 +164,8 @@ #endif #endif //WITH_ENGINE +#include "Misc/EmbeddedCommunication.h" + class FSlateRenderer; class SViewport; class IPlatformFile; @@ -217,6 +219,14 @@ class FFeedbackContext; #define REAPPLY_INI_SETTINGS_AFTER_EARLY_LOADING_SCREEN 0 #endif +#ifndef MOUNT_DOWNLOADED_PAKS_AFTER_EARLY_LOADING_SCREEN +#define MOUNT_DOWNLOADED_PAKS_AFTER_EARLY_LOADING_SCREEN 1 +#endif + +#ifndef OPEN_PSO_CACHE_AFTER_EARLY_LOADING_SCREEN +#define OPEN_PSO_CACHE_AFTER_EARLY_LOADING_SCREEN 1 +#endif + #if WITH_ENGINE CSV_DECLARE_CATEGORY_MODULE_EXTERN(CORE_API, Basic); #endif @@ -249,6 +259,12 @@ static FAutoConsoleTaskPriority CPrio_AsyncEndOfFrameGameTasks( ENamedThreads::HighTaskPriority ); +static TAutoConsoleVariable CVarSecondsBeforeEmbeddedAppSleeps( + TEXT("tick.SecondsBeforeEmbeddedAppSleeps"), + 1, + TEXT("When built as embedded, how many ticks to perform before sleeping") +); + /** Task that executes concurrently with Slate when tick.DoAsyncEndOfFrameTasks is true. */ class FExecuteConcurrentWithSlateTickTask { @@ -1042,6 +1058,11 @@ int32 FEngineLoop::PreInit(const TCHAR* CmdLine) FWindowsPlatformMisc::SetGracefulTerminationHandler(); #endif // PLATFORM_WINDOWS +#if BUILD_EMBEDDED_APP + FEmbeddedCommunication::Init(); + FEmbeddedCommunication::KeepAwake(TEXT("Startup"), false); +#endif + FMemory::SetupTLSCachesOnCurrentThread(); // Set the flag for whether we've build DebugGame instead of Development. The engine does not know this (whereas the launch module does) because it is always built in development. @@ -1705,6 +1726,8 @@ int32 FEngineLoop::PreInit(const TCHAR* CmdLine) } } + FEmbeddedCommunication::ForceTick(1); + #if WITH_ENGINE { SCOPED_BOOT_TIMING("System settings and cvar init"); @@ -1795,6 +1818,8 @@ int32 FEngineLoop::PreInit(const TCHAR* CmdLine) FPlatformMisc::RequestExit(false); #endif + FEmbeddedCommunication::ForceTick(2); + #if WITH_ENGINE // allow for game explorer processing (including parental controls) and firewalls installation if (!FPlatformMisc::CommandLineCommands()) @@ -2009,6 +2034,8 @@ int32 FEngineLoop::PreInit(const TCHAR* CmdLine) FInternationalization::Get().LoadAllCultureData(); } + FEmbeddedCommunication::ForceTick(3); + FScopedSlowTask SlowTask(100, NSLOCTEXT("EngineLoop", "EngineLoop_Initializing", "Initializing...")); SlowTask.EnterProgressFrame(10); @@ -2153,6 +2180,8 @@ int32 FEngineLoop::PreInit(const TCHAR* CmdLine) } #endif + FEmbeddedCommunication::ForceTick(4); + #if !UE_SERVER// && !UE_EDITOR if(!IsRunningDedicatedServer() && !IsRunningCommandlet()) { @@ -2267,6 +2296,7 @@ int32 FEngineLoop::PreInit(const TCHAR* CmdLine) if (FPreLoadScreenManager::Get()) { + SCOPED_BOOT_TIMING("PlayFirstPreLoadScreen - FPreLoadScreenManager::Get()->Initialize"); //initialize and play our first Early PreLoad Screen if one is setup FPreLoadScreenManager::Get()->Initialize(SlateRenderer.Get()); FPreLoadScreenManager::Get()->PlayFirstPreLoadScreen(EPreLoadScreenTypes::EarlyStartupScreen); @@ -2283,7 +2313,9 @@ int32 FEngineLoop::PreInit(const TCHAR* CmdLine) { SCOPED_BOOT_TIMING("ReapplyCVarsFromIniAfterLoadScreen"); - if (FCoreDelegates::OnMountAllPakFiles.IsBound() ) + // This can be deleted after ForInstallBundleManager is in Engine + const bool bMountPaks = MOUNT_DOWNLOADED_PAKS_AFTER_EARLY_LOADING_SCREEN; + if (bMountPaks && FCoreDelegates::OnMountAllPakFiles.IsBound() ) { #if 1 FString InstalledGameContentDir = FPaths::Combine(*FPaths::ProjectPersistentDownloadDir(), TEXT("InstalledContent"), FApp::GetProjectName(), TEXT("Content"), TEXT("Paks")); @@ -2314,19 +2346,20 @@ int32 FEngineLoop::PreInit(const TCHAR* CmdLine) // Open the game library which contains the material shaders. FShaderCodeLibrary::OpenLibrary(FApp::GetProjectName(), FPaths::ProjectContentDir()); - if (FPaths::HasProjectPersistentDownloadDir()) + for (const FString& RootDir : FPlatformMisc::GetAdditionalRootDirectories()) { - FShaderCodeLibrary::OpenLibrary(FApp::GetProjectName(), FPaths::Combine(*FPaths::ProjectPersistentDownloadDir(), TEXT("InstalledContent"), FApp::GetProjectName(), TEXT("Content"))); + FShaderCodeLibrary::OpenLibrary(FApp::GetProjectName(), FPaths::Combine(RootDir, FApp::GetProjectName(), TEXT("Content"))); } - // Now our shader code main library is opened, kick off the precompile. - FShaderPipelineCache::OpenPipelineFileCache(GMaxRHIShaderPlatform); + const bool bOpenPSOCache = OPEN_PSO_CACHE_AFTER_EARLY_LOADING_SCREEN; + if (bOpenPSOCache) + { + // Now our shader code main library is opened, kick off the precompile. + FShaderPipelineCache::OpenPipelineFileCache(GMaxRHIShaderPlatform); + } } - { - SCOPED_BOOT_TIMING("InitGameTextLocalization"); - InitGameTextLocalization(); - } + InitGameTextLocalization(); DECLARE_SCOPE_CYCLE_COUNTER(TEXT("Initial UObject load"), STAT_InitialUObjectLoad, STATGROUP_LoadTime); @@ -2336,19 +2369,18 @@ int32 FEngineLoop::PreInit(const TCHAR* CmdLine) SlowTask.EnterProgressFrame(5); -#if USE_EVENT_DRIVEN_ASYNC_LOAD_AT_BOOT_TIME - { - SCOPED_BOOT_TIMING("LoadModule AssetRegistry"); - // If we don't do this now and the async loading thread is active, then we will attempt to load this module from a thread - FModuleManager::Get().LoadModule("AssetRegistry"); - } +#if USE_EVENT_DRIVEN_ASYNC_LOAD_AT_BOOT_TIME && !USE_PER_MODULE_UOBJECT_BOOTSTRAP + // If we don't do this now and the async loading thread is active, then we will attempt to load this module from a thread + FModuleManager::Get().LoadModule("AssetRegistry"); #endif + FEmbeddedCommunication::ForceTick(5); + // Make sure all UObject classes are registered and default properties have been initialized - { - SCOPED_BOOT_TIMING("ProcessNewlyLoadedUObjects"); - ProcessNewlyLoadedUObjects(); - } + ProcessNewlyLoadedUObjects(); + + FEmbeddedCommunication::ForceTick(6); + #if WITH_EDITOR if(FPIEPreviewDeviceModule::IsRequestingPreviewDevice()) { @@ -2389,6 +2421,8 @@ int32 FEngineLoop::PreInit(const TCHAR* CmdLine) // Tell the module manager is may now process newly-loaded UObjects when new C++ modules are loaded FModuleManager::Get().StartProcessingNewlyLoadedObjects(); + FEmbeddedCommunication::ForceTick(7); + // Setup GC optimizations if (bDisableDisregardForGC) { @@ -2823,6 +2857,8 @@ int32 FEngineLoop::PreInit(const TCHAR* CmdLine) return 1; } + FEmbeddedCommunication::ForceTick(8); + FString MatineeName; if(FParse::Param(FCommandLine::Get(),TEXT("DUMPMOVIE")) || FParse::Value(FCommandLine::Get(), TEXT("-MATINEESSCAPTURE="), MatineeName)) @@ -2899,6 +2935,8 @@ int32 FEngineLoop::PreInit(const TCHAR* CmdLine) FAutomationTestFramework::Get().RunSmokeTests(); } + FEmbeddedCommunication::ForceTick(9); + // Note we still have 20% remaining on the slow task: this will be used by the Editor/Engine initialization next return 0; } @@ -2908,6 +2946,9 @@ bool FEngineLoop::LoadCoreModules() { // Always attempt to load CoreUObject. It requires additional pre-init which is called from its module's StartupModule method. #if WITH_COREUOBJECT +#if USE_PER_MODULE_UOBJECT_BOOTSTRAP // otherwise do it later + FModuleManager::Get().OnProcessLoadedObjectsCallback().AddStatic(ProcessNewlyLoadedUObjects); +#endif return FModuleManager::Get().LoadModule(TEXT("CoreUObject")) != nullptr; #else return true; @@ -3192,12 +3233,15 @@ void GameLoopIsStarved() int32 FEngineLoop::Init() { LLM_SCOPE(ELLMTag::EngineInitMemory); + SCOPED_BOOT_TIMING("FEngineLoop::Init"); DECLARE_SCOPE_CYCLE_COUNTER( TEXT( "FEngineLoop::Init" ), STAT_FEngineLoop_Init, STATGROUP_LoadTime ); FScopedSlowTask SlowTask(100); SlowTask.EnterProgressFrame(10); + FEmbeddedCommunication::ForceTick(10); + // Figure out which UEngine variant to use. UClass* EngineClass = nullptr; if( !GIsEditor ) @@ -3230,6 +3274,8 @@ int32 FEngineLoop::Init() #endif } + FEmbeddedCommunication::ForceTick(11); + check( GEngine ); GetMoviePlayer()->PassLoadingScreenWindowBackToGame(); @@ -3244,6 +3290,8 @@ int32 FEngineLoop::Init() GEngine->ParseCommandline(); } + FEmbeddedCommunication::ForceTick(12); + { SCOPED_BOOT_TIMING("InitTime"); InitTime(); @@ -3296,6 +3344,8 @@ int32 FEngineLoop::Init() GEngine->Start(); } + FEmbeddedCommunication::ForceTick(13); + if (FPreLoadScreenManager::Get() && FPreLoadScreenManager::Get()->HasActivePreLoadScreenType(EPreLoadScreenTypes::EngineLoadingScreen)) { SCOPED_BOOT_TIMING("WaitForEngineLoadingScreenToFinish"); @@ -3318,6 +3368,8 @@ int32 FEngineLoop::Init() } #endif + FEmbeddedCommunication::ForceTick(14); + // initialize automation worker #if WITH_AUTOMATION_WORKER FModuleManager::Get().LoadModule("AutomationWorker"); @@ -3347,6 +3399,8 @@ int32 FEngineLoop::Init() FViewport::SetGameRenderingEnabled(true, 3); } + FEmbeddedCommunication::ForceTick(15); + FCoreDelegates::StarvedGameLoop.BindStatic(&GameLoopIsStarved); // Ready to measure thread heartbeat @@ -3360,6 +3414,12 @@ int32 FEngineLoop::Init() SCOPED_BOOT_TIMING("FCoreDelegates::OnFEngineLoopInitComplete.Broadcast()"); FCoreDelegates::OnFEngineLoopInitComplete.Broadcast(); } + +#if BUILD_EMBEDDED_APP + FEmbeddedCommunication::AllowSleep(TEXT("Startup")); + FEmbeddedCommunication::KeepAwake(TEXT("FirstTicks"), true); +#endif + return 0; } @@ -3539,7 +3599,17 @@ bool FEngineLoop::ShouldUseIdleMode() const && !FPlatformApplicationMisc::IsThisApplicationForeground()) { bIdleMode = true; + } + +#if BUILD_EMBEDDED_APP + if (FEmbeddedCommunication::IsAwakeForTicking() == false) + { + bIdleMode = true; + } +#endif + if (bIdleMode) + { for (const FWorldContext& Context : GEngine->GetWorldContexts()) { if (!Context.World()->AreAlwaysLoadedLevelsLoaded()) @@ -3721,8 +3791,15 @@ static inline void EndFrameRenderThread(FRHICommandListImmediate& RHICmdList) #endif // !UE_BUILD_SHIPPING } +#if BUILD_EMBEDDED_APP +#include "Misc/EmbeddedCommunication.h" +#endif + void FEngineLoop::Tick() { + // make sure to catch any FMemStack uses outside of UWorld::Tick + FMemMark MemStackMark(FMemStack::Get()); + #if !UE_BUILD_SHIPPING && !UE_BUILD_TEST && MALLOC_GT_HOOKS FScopedSampleMallocChurn ChurnTracker; #endif @@ -4197,6 +4274,16 @@ void FEngineLoop::Tick() SET_DWORD_STAT(STAT_Hash_NumObjects, GUObjectArray.GetObjectArrayNumMinusAvailable()); #endif } + +#if BUILD_EMBEDDED_APP + static double LastSleepTime = FPlatformTime::Seconds(); + double TimeNow = FPlatformTime::Seconds(); + if (LastSleepTime - TimeNow >= CVarSecondsBeforeEmbeddedAppSleeps.GetValueOnAnyThread()) + { + LastSleepTime = TimeNow; + FEmbeddedCommunication::AllowSleep(TEXT("FirstTicks")); + } +#endif } @@ -4541,6 +4628,8 @@ bool FEngineLoop::AppInit( ) } } + FEmbeddedCommunication::ForceTick(16); + if(bNeedCompile) { // Try to compile it @@ -4593,6 +4682,8 @@ bool FEngineLoop::AppInit( ) IPluginManager::Get().GetLocalizationPathsForEnabledPlugins(OutLocResPaths); }); + FEmbeddedCommunication::ForceTick(17); + PreInitHMDDevice(); // after the above has run we now have the REQUIRED set of engine .INIs (all of the other .INIs) @@ -4690,11 +4781,16 @@ bool FEngineLoop::AppInit( ) bForceSmokeTests |= FParse::Param(FCommandLine::Get(), TEXT("bForceSmokeTests")); FAutomationTestFramework::Get().SetForceSmokeTests(bForceSmokeTests); + FEmbeddedCommunication::ForceTick(18); + // Init other systems. { SCOPED_BOOT_TIMING("FCoreDelegates::OnInit.Broadcast"); FCoreDelegates::OnInit.Broadcast(); } + + FEmbeddedCommunication::ForceTick(19); + return true; } diff --git a/Engine/Source/Runtime/Launch/Public/Android/AndroidJNI.h b/Engine/Source/Runtime/Launch/Public/Android/AndroidJNI.h index d330bd0aeaea..c40996358a65 100644 --- a/Engine/Source/Runtime/Launch/Public/Android/AndroidJNI.h +++ b/Engine/Source/Runtime/Launch/Public/Android/AndroidJNI.h @@ -72,6 +72,7 @@ public: static jmethodID AndroidThunkCpp_VirtualInputIgnoreClick; static jmethodID AndroidThunkCpp_IsVirtuaKeyboardShown; + static jmethodID AndroidThunkCpp_IsWebViewShown; // InputDeviceInfo member field ids static jclass InputDeviceInfoClass; @@ -136,6 +137,7 @@ public: * Helper wrapper functions around the JNIEnv versions with NULL/error handling */ static jclass FindClass(JNIEnv* Env, const ANSICHAR* ClassName, bool bIsOptional); + static jclass FindClassGlobalRef(JNIEnv* Env, const ANSICHAR* ClassName, bool bIsOptional); static jmethodID FindMethod(JNIEnv* Env, jclass Class, const ANSICHAR* MethodName, const ANSICHAR* MethodSignature, bool bIsOptional); static jmethodID FindStaticMethod(JNIEnv* Env, jclass Class, const ANSICHAR* MethodName, const ANSICHAR* MethodSignature, bool bIsOptional); static jfieldID FindField(JNIEnv* Env, jclass Class, const ANSICHAR* FieldName, const ANSICHAR* FieldType, bool bIsOptional); @@ -161,5 +163,8 @@ private: static void FindGooglePlayMethods(JNIEnv* Env); /** Find GooglePlay billing classes and methods */ static void FindGooglePlayBillingMethods(JNIEnv* Env); + + // Setup communication with wrapper apps + static void SetupEmbeddedCommunication(JNIEnv* Env); }; #endif diff --git a/Engine/Source/Runtime/LiveLinkInterface/Private/LiveLinkCurveRemapSettings.cpp b/Engine/Source/Runtime/LiveLinkInterface/Private/LiveLinkCurveRemapSettings.cpp new file mode 100644 index 000000000000..ba7569bab892 --- /dev/null +++ b/Engine/Source/Runtime/LiveLinkInterface/Private/LiveLinkCurveRemapSettings.cpp @@ -0,0 +1,18 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "LiveLinkCurveRemapSettings.h" +#include "Misc/ConfigCacheIni.h" + +#if WITH_EDITOR + +void ULiveLinkCurveRemapSettings::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) +{ + Super::PostEditChangeProperty(PropertyChangedEvent); + + //Changed a setting, so lets change it in our DefaultEngine.ini and save it off + FString DefaultFileName = GetClass()->GetDefaultConfigFilename(); + SaveConfig(CPF_Config, *DefaultFileName); + GConfig->Flush(false, DefaultFileName); +} + +#endif //WITH_EDITOR \ No newline at end of file diff --git a/Engine/Source/Runtime/LiveLinkInterface/Public/ILiveLinkClient.h b/Engine/Source/Runtime/LiveLinkInterface/Public/ILiveLinkClient.h index a0899138680a..d314ec8a26d1 100644 --- a/Engine/Source/Runtime/LiveLinkInterface/Public/ILiveLinkClient.h +++ b/Engine/Source/Runtime/LiveLinkInterface/Public/ILiveLinkClient.h @@ -54,6 +54,9 @@ public: //Efficiently get data virtual const TArray* GetSubjectRawFrames(FName SubjectName) = 0; + //Get the settings structure for a particular source + virtual class ULiveLinkSourceSettings* GetSourceSettingsForEntry(FGuid InEntryGuid) = 0; + //Functions to start recording live link data into a saved buffer that can that can queried dynamically for uses //such as recording in the sequencer or for serialization. //Note that it's the responsibility of the client to handle any changes to the Subjects structure. diff --git a/Engine/Source/Runtime/LiveLinkInterface/Public/LiveLinkCurveRemapSettings.h b/Engine/Source/Runtime/LiveLinkInterface/Public/LiveLinkCurveRemapSettings.h new file mode 100644 index 000000000000..e49506775503 --- /dev/null +++ b/Engine/Source/Runtime/LiveLinkInterface/Public/LiveLinkCurveRemapSettings.h @@ -0,0 +1,37 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "LiveLinkSourceSettings.h" +#include "LiveLinkCurveRemapSettings.generated.h" + +// TODO Move Structs and Enum to Game Mode? + +class UPoseAsset; + +USTRUCT(BlueprintType) +struct FLiveLinkCurveConversionSettings +{ + GENERATED_USTRUCT_BODY() + + UPROPERTY(EditAnywhere, Category = Settings, meta = (AllowedClasses = "PoseAsset")) + TMap CurveConversionAssetMap; +}; + +UCLASS(config=Engine, defaultconfig, meta=(DisplayName="LiveLink")) +class LIVELINKINTERFACE_API ULiveLinkCurveRemapSettings : public ULiveLinkSourceSettings +{ +public: + GENERATED_BODY() + + UPROPERTY(EditAnywhere, config, Category = "Curve Conversion Settings") + FLiveLinkCurveConversionSettings CurveConversionSettings; + +#if WITH_EDITOR + + //UObject override so we can change this setting when changed in editor + virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override; + +#endif // WITH_EDITOR +}; diff --git a/Engine/Source/Runtime/LiveLinkInterface/Public/LiveLinkTypes.h b/Engine/Source/Runtime/LiveLinkInterface/Public/LiveLinkTypes.h index 58b6c81a5ef3..e11a7089fcd1 100644 --- a/Engine/Source/Runtime/LiveLinkInterface/Public/LiveLinkTypes.h +++ b/Engine/Source/Runtime/LiveLinkInterface/Public/LiveLinkTypes.h @@ -46,7 +46,7 @@ public: GENERATED_USTRUCT_BODY() // Time for this frame. Used during interpolation. If this goes backwards we will dump already stored frames. - UPROPERTY(meta=(IgnoreForMemberInitializationTest)) + UPROPERTY(meta = (IgnoreForMemberInitializationTest)) double Time; // Value calculated on create to represent the different between the source time and client time @@ -184,7 +184,7 @@ public: UPROPERTY() TArray CurveElements; - UPROPERTY(meta=(IgnoreForMemberInitializationTest)) + UPROPERTY() FLiveLinkWorldTime WorldTime; UPROPERTY() diff --git a/Engine/Source/Runtime/MediaAssets/Private/Assets/MediaSoundComponent.cpp b/Engine/Source/Runtime/MediaAssets/Private/Assets/MediaSoundComponent.cpp index fed140539f90..ea9934efc418 100644 --- a/Engine/Source/Runtime/MediaAssets/Private/Assets/MediaSoundComponent.cpp +++ b/Engine/Source/Runtime/MediaAssets/Private/Assets/MediaSoundComponent.cpp @@ -29,14 +29,6 @@ FAutoConsoleVariableRef CVarSyncAudioAfterDropouts( TEXT("0: Not Enabled, 1: Enabled"), ECVF_Default); -static int32 FlushBackloggedAudioCVar = 0; -FAutoConsoleVariableRef CVarFlushBackloggedAudio( - TEXT("m.FlushBackloggedAudio"), - FlushBackloggedAudioCVar, - TEXT("Flush backlogged audio samples when max value reached.\n") - TEXT("0: Not Enabled, 4 or higher: Max queued samples"), - ECVF_Default); - DECLARE_FLOAT_COUNTER_STAT(TEXT("MediaUtils MediaSoundComponent Sync"), STAT_MediaUtils_MediaSoundComponentSync, STATGROUP_Media); DECLARE_FLOAT_COUNTER_STAT(TEXT("MediaUtils MediaSoundComponent SampleTime"), STAT_MediaUtils_MediaSoundComponentSampleTime, STATGROUP_Media); DECLARE_DWORD_COUNTER_STAT(TEXT("MediaUtils MediaSoundComponent Queued"), STAT_Media_SoundCompQueued, STATGROUP_Media); @@ -481,20 +473,6 @@ int32 UMediaSoundComponent::OnGenerateAudio(float* OutAudio, int32 NumSamples) } } -#if PLATFORM_WINDOWS - // Garbage collection and other operations can cause calls to OnGenerateAudio() to be spaced too far apart (no audio being processed) - // These gaps are not tracked leading to a backlogged buffer that becomes further and further out of sync - if (FlushBackloggedAudioCVar > 3 && PinnedSampleQueue->Num() > FlushBackloggedAudioCVar) - { - const int32 NumQueued = PinnedSampleQueue->Num(); - for (int32 i = 0; i < NumQueued - 3; ++i) - { - TSharedPtr NextSample; - PinnedSampleQueue->Dequeue(NextSample); - } - } -#endif - SET_FLOAT_STAT(STAT_MediaUtils_MediaSoundComponentSync, FMath::Abs((Time - OutTime).GetTotalMilliseconds())); SET_FLOAT_STAT(STAT_MediaUtils_MediaSoundComponentSampleTime, OutTime.GetTotalMilliseconds()); SET_DWORD_STAT(STAT_Media_SoundCompQueued, PinnedSampleQueue->Num()); diff --git a/Engine/Source/Runtime/NavigationSystem/Private/NavigationSystem.cpp b/Engine/Source/Runtime/NavigationSystem/Private/NavigationSystem.cpp index 77450a918f76..90c22c2100bc 100644 --- a/Engine/Source/Runtime/NavigationSystem/Private/NavigationSystem.cpp +++ b/Engine/Source/Runtime/NavigationSystem/Private/NavigationSystem.cpp @@ -80,6 +80,8 @@ DEFINE_STAT(STAT_Navigation_GatheringNavigationModifiersSync); DEFINE_STAT(STAT_Navigation_ActorsGeometryExportSync); DEFINE_STAT(STAT_Navigation_ProcessingActorsForNavMeshBuilding); DEFINE_STAT(STAT_Navigation_AdjustingNavLinks); +DEFINE_STAT(STAT_Navigation_RegisterNavOctreeElement); +DEFINE_STAT(STAT_Navigation_UnregisterNavOctreeElement); DEFINE_STAT(STAT_Navigation_AddingActorsToNavOctree); DEFINE_STAT(STAT_Navigation_RecastAddGeneratedTiles); DEFINE_STAT(STAT_Navigation_RecastTick); @@ -2386,6 +2388,8 @@ int32 GetDirtyFlagHelper(int32 UpdateFlags, int32 DefaultValue) FSetElementId UNavigationSystemV1::RegisterNavOctreeElement(UObject* ElementOwner, INavRelevantInterface* ElementInterface, int32 UpdateFlags) { + SCOPE_CYCLE_COUNTER(STAT_Navigation_RegisterNavOctreeElement); + FSetElementId SetId; #if WITH_EDITOR @@ -2529,6 +2533,8 @@ bool UNavigationSystemV1::GetNavOctreeElementData(const UObject& NodeOwner, int3 void UNavigationSystemV1::UnregisterNavOctreeElement(UObject* ElementOwner, INavRelevantInterface* ElementInterface, int32 UpdateFlags) { + SCOPE_CYCLE_COUNTER(STAT_Navigation_UnregisterNavOctreeElement); + #if WITH_EDITOR if (IsNavigationUnregisterLocked()) { diff --git a/Engine/Source/Runtime/Online/BuildPatchServices/Private/Installer/OptimisedDelta.cpp b/Engine/Source/Runtime/Online/BuildPatchServices/Private/Installer/OptimisedDelta.cpp index 0702969f4de0..a13a60e24987 100644 --- a/Engine/Source/Runtime/Online/BuildPatchServices/Private/Installer/OptimisedDelta.cpp +++ b/Engine/Source/Runtime/Online/BuildPatchServices/Private/Installer/OptimisedDelta.cpp @@ -36,6 +36,7 @@ namespace BuildPatchServices // IOptimisedDelta interface end. private: + bool RequiresChunkDownload(); void OnDownloadComplete(int32 RequestId, const FDownloadRef& Download); bool ShouldRetry(const FDownloadRef& Download); void SetFailedDownload(); @@ -72,7 +73,8 @@ namespace BuildPatchServices const bool bNoSourceManifest = Configuration.SourceManifest.IsValid() == false; const bool bNotPatching = Configuration.InstallerConfiguration == nullptr ? false : Configuration.InstallerConfiguration->bIsRepair || Configuration.InstallerConfiguration->InstallMode == EInstallMode::PrereqOnly; const bool bSameBuild = bNoSourceManifest ? false : Configuration.SourceManifest->GetBuildId() == Configuration.DestinationManifest->GetBuildId(); - if (bNoSourceManifest || bNotPatching || bSameBuild) + const bool bNoDownload = RequiresChunkDownload() == false; + if (bNoSourceManifest || bNotPatching || bSameBuild || bNoDownload) { DeltaPolicy = EDeltaPolicy::Skip; } @@ -101,6 +103,28 @@ namespace BuildPatchServices return DownloadedBytes.GetValue(); } + bool FOptimisedDelta::RequiresChunkDownload() + { + if (Configuration.SourceManifest.IsValid()) + { + for (const FString& DestinationFile : Configuration.DestinationManifest->GetBuildFileList()) + { + // Get file manifests + const FFileManifest* OldFile = Configuration.SourceManifest->GetFileManifest(DestinationFile); + const FFileManifest* NewFile = Configuration.DestinationManifest->GetFileManifest(DestinationFile); + // Different hash means different file, missing OldFile means added file. + if (!OldFile || OldFile->FileHash != NewFile->FileHash) + { + return true; + } + } + // No new or changed files found. + return false; + } + // No source manifest means full download. + return true; + } + void FOptimisedDelta::OnDownloadComplete(int32 RequestId, const FDownloadRef& Download) { if (Download->WasSuccessful()) diff --git a/Engine/Source/Runtime/Online/HTTP/Private/Curl/CurlHttp.cpp b/Engine/Source/Runtime/Online/HTTP/Private/Curl/CurlHttp.cpp index a9c20453f6e4..6060735c5ead 100644 --- a/Engine/Source/Runtime/Online/HTTP/Private/Curl/CurlHttp.cpp +++ b/Engine/Source/Runtime/Online/HTTP/Private/Curl/CurlHttp.cpp @@ -726,10 +726,15 @@ bool FCurlHttpRequest::SetupRequest() curl_easy_setopt(EasyHandle, CURLOPT_POSTFIELDSIZE, RequestPayload->GetContentLength()); bUseReadFunction = true; } - else if (Verb == TEXT("PUT")) + else if (Verb == TEXT("PUT") || Verb == TEXT("PATCH")) { curl_easy_setopt(EasyHandle, CURLOPT_UPLOAD, 1L); curl_easy_setopt(EasyHandle, CURLOPT_INFILESIZE, RequestPayload->GetContentLength()); + if (Verb != TEXT("PUT")) + { + curl_easy_setopt(EasyHandle, CURLOPT_CUSTOMREQUEST, TCHAR_TO_UTF8(*Verb)); + } + bUseReadFunction = true; } else if (Verb == TEXT("GET")) diff --git a/Engine/Source/Runtime/Online/SSL/Private/SslModule.cpp b/Engine/Source/Runtime/Online/SSL/Private/SslModule.cpp index ed088511dff0..d5b9d23cebd4 100644 --- a/Engine/Source/Runtime/Online/SSL/Private/SslModule.cpp +++ b/Engine/Source/Runtime/Online/SSL/Private/SslModule.cpp @@ -42,7 +42,10 @@ void FSslModule::StartupModule() SslManagerPtr = new FSslManager(); CertificateManagerPtr = new FPlatformSslCertificateManager(); - static_cast(CertificateManagerPtr)->BuildRootCertificateArray(); + { + SCOPED_BOOT_TIMING("BuildRootCertificateArray"); + static_cast(CertificateManagerPtr)->BuildRootCertificateArray(); + } // Load pinned public keys from Engine.ini. For example to pin epicgames.com and its subdomains to require Amazon Root CA 1 or Starfield Services Root Certificate Authority - G2 in the cert chain, // [SSL] diff --git a/Engine/Source/Runtime/Online/XMPP/Private/XmppJingle/XmppMessagesJingle.cpp b/Engine/Source/Runtime/Online/XMPP/Private/XmppJingle/XmppMessagesJingle.cpp index 249bb98ccf56..bae4852ac36f 100644 --- a/Engine/Source/Runtime/Online/XMPP/Private/XmppJingle/XmppMessagesJingle.cpp +++ b/Engine/Source/Runtime/Online/XMPP/Private/XmppJingle/XmppMessagesJingle.cpp @@ -227,9 +227,14 @@ static void ConvertToMessage(FXmppMessage& OutMessage, const FXmppMessageJingle& FJsonSerializer::Serialize((*JsonPayload).ToSharedRef(), JsonWriter); JsonWriter->Close(); } + else if (JsonBody->TryGetStringField(TEXT("payload"), OutMessage.Payload)) + { + // Payload is now in Message.Payload + } else { - JsonBody->TryGetStringField(TEXT("payload"), OutMessage.Payload); + // Treat the entire body as the payload + OutMessage.Payload = UTF8_TO_TCHAR(InMessageJingle.Body.c_str()); } FString TimestampStr; if (JsonBody->TryGetStringField(TEXT("timestamp"), TimestampStr)) diff --git a/Engine/Source/Runtime/Online/XMPP/Private/XmppStrophe/XmppMessagesStrophe.cpp b/Engine/Source/Runtime/Online/XMPP/Private/XmppStrophe/XmppMessagesStrophe.cpp index eaa8664c4d3d..b9ca628658ef 100644 --- a/Engine/Source/Runtime/Online/XMPP/Private/XmppStrophe/XmppMessagesStrophe.cpp +++ b/Engine/Source/Runtime/Online/XMPP/Private/XmppStrophe/XmppMessagesStrophe.cpp @@ -64,7 +64,7 @@ bool FXmppMessagesStrophe::HandleMessageStanza(const FStropheStanza& IncomingSta { JsonBody->TryGetStringField(TEXT("type"), Message.Type); const TSharedPtr* JsonPayload = NULL; - if (JsonBody->TryGetObjectField(TEXT("payload"), JsonPayload) && + if (JsonBody->TryGetObjectField(TEXT("payload"), JsonPayload) && JsonPayload != NULL && (*JsonPayload).IsValid()) { @@ -72,9 +72,14 @@ bool FXmppMessagesStrophe::HandleMessageStanza(const FStropheStanza& IncomingSta FJsonSerializer::Serialize((*JsonPayload).ToSharedRef(), JsonWriter); JsonWriter->Close(); } + else if (JsonBody->TryGetStringField(TEXT("payload"), Message.Payload)) + { + // Payload is now in Message.Payload + } else { - JsonBody->TryGetStringField(TEXT("payload"), Message.Payload); + // Treat the entire body as the payload + Message.Payload = IncomingStanza.GetBodyText().GetValue(); } FString TimestampStr; if (JsonBody->TryGetStringField(TEXT("timestamp"), TimestampStr)) diff --git a/Engine/Source/Runtime/OpenGLDrv/Private/OpenGLShaders.cpp b/Engine/Source/Runtime/OpenGLDrv/Private/OpenGLShaders.cpp index fd6325d129f1..7162e142207e 100644 --- a/Engine/Source/Runtime/OpenGLDrv/Private/OpenGLShaders.cpp +++ b/Engine/Source/Runtime/OpenGLDrv/Private/OpenGLShaders.cpp @@ -4535,12 +4535,15 @@ void FOpenGLProgramBinaryCache::OnShaderPipelineCachePrecompilationComplete(uint { CloseWriteHandle(); -#if PLATFORM_ANDROID && USE_ANDROID_JNI +#if PLATFORM_ANDROID + FAndroidMisc::bNeedsRestartAfterPSOPrecompile = true; if (CVarRestartAndroidAfterPrecompile.GetValueOnAnyThread() == 1) { - extern void AndroidThunkCpp_RestartApplication(); - AndroidThunkCpp_RestartApplication(); - } +#if USE_ANDROID_JNI + extern void AndroidThunkCpp_RestartApplication(const FString& IntentString); + AndroidThunkCpp_RestartApplication(TEXT("")); +#endif + } #endif OpenAsyncReadHandle(); BinaryFileState = EBinaryFileState::ValidCacheFile; diff --git a/Engine/Source/Runtime/OpenGLDrv/Public/OpenGLResources.h b/Engine/Source/Runtime/OpenGLDrv/Public/OpenGLResources.h index 868ff8361c49..d7e274c2932f 100644 --- a/Engine/Source/Runtime/OpenGLDrv/Public/OpenGLResources.h +++ b/Engine/Source/Runtime/OpenGLDrv/Public/OpenGLResources.h @@ -843,7 +843,7 @@ public: } #if ENABLE_LOW_LEVEL_MEM_TRACKER - LLM_SCOPED_PAUSE_TRACKING_WITH_ENUM_AND_AMOUNT(ELLMTag::VertexBuffer, InSize, ELLMTracker::Default, ELLMAllocType::None); + LLM_SCOPED_PAUSE_TRACKING_WITH_ENUM_AND_AMOUNT(ELLMTag::Meshes, InSize, ELLMTracker::Default, ELLMAllocType::None); #endif } @@ -855,7 +855,7 @@ public: } #if ENABLE_LOW_LEVEL_MEM_TRACKER - LLM_SCOPED_PAUSE_TRACKING_WITH_ENUM_AND_AMOUNT(ELLMTag::VertexBuffer, -(int64)GetSize(), ELLMTracker::Default, ELLMAllocType::None); + LLM_SCOPED_PAUSE_TRACKING_WITH_ENUM_AND_AMOUNT(ELLMTag::Meshes, -(int64)GetSize(), ELLMTracker::Default, ELLMAllocType::None); #endif } @@ -952,14 +952,14 @@ public: FOpenGLBaseIndexBuffer(uint32 InStride,uint32 InSize,uint32 InUsage): FRHIIndexBuffer(InStride,InSize,InUsage) { #if ENABLE_LOW_LEVEL_MEM_TRACKER - LLM_SCOPED_PAUSE_TRACKING_WITH_ENUM_AND_AMOUNT(ELLMTag::IndexBuffer, InSize, ELLMTracker::Default, ELLMAllocType::None); + LLM_SCOPED_PAUSE_TRACKING_WITH_ENUM_AND_AMOUNT(ELLMTag::Meshes, InSize, ELLMTracker::Default, ELLMAllocType::None); #endif } ~FOpenGLBaseIndexBuffer(void) { #if ENABLE_LOW_LEVEL_MEM_TRACKER - LLM_SCOPED_PAUSE_TRACKING_WITH_ENUM_AND_AMOUNT(ELLMTag::IndexBuffer, -(int64)GetSize(), ELLMTracker::Default, ELLMAllocType::None); + LLM_SCOPED_PAUSE_TRACKING_WITH_ENUM_AND_AMOUNT(ELLMTag::Meshes, -(int64)GetSize(), ELLMTracker::Default, ELLMAllocType::None); #endif } diff --git a/Engine/Source/Runtime/PreLoadScreen/Private/PreLoadScreenBase.cpp b/Engine/Source/Runtime/PreLoadScreen/Private/PreLoadScreenBase.cpp index 1f27dfa0dc6e..2aaccdfd9f58 100644 --- a/Engine/Source/Runtime/PreLoadScreen/Private/PreLoadScreenBase.cpp +++ b/Engine/Source/Runtime/PreLoadScreen/Private/PreLoadScreenBase.cpp @@ -12,7 +12,9 @@ void FPreLoadScreenBase::Init() } void FPreLoadScreenBase::InitSettingsFromConfig(const FString& ConfigFileName) -{ +{ + SCOPED_BOOT_TIMING("FPreLoadScreenBase::InitSettingsFromConfig"); + const FString UIConfigSection = TEXT("PreLoadScreen.UISettings"); //Find plugin content path from name by going through enabled content plugins and see if one matches. @@ -90,4 +92,4 @@ bool FPreLoadScreenBase::IsDone() const { return !GetWidget().IsValid(); } -} \ No newline at end of file +} diff --git a/Engine/Source/Runtime/PreLoadScreen/Private/PreLoadScreenManager.cpp b/Engine/Source/Runtime/PreLoadScreen/Private/PreLoadScreenManager.cpp index 6f1786a80af9..a3042d156440 100644 --- a/Engine/Source/Runtime/PreLoadScreen/Private/PreLoadScreenManager.cpp +++ b/Engine/Source/Runtime/PreLoadScreen/Private/PreLoadScreenManager.cpp @@ -13,6 +13,10 @@ #include "HAL/ThreadManager.h" #include "Modules/ModuleManager.h" +#if BUILD_EMBEDDED_APP +#include "Misc/EmbeddedCommunication.h" +#endif + #if PLATFORM_ANDROID #if USE_ANDROID_EVENTS #include "Android/AndroidEventManager.h" @@ -134,6 +138,8 @@ void FPreLoadScreenManager::HandleEarlyStartupPlay() IPreLoadScreen* PreLoadScreen = GetActivePreLoadScreen(); if (PreLoadScreen && MainWindow.IsValid()) { + SCOPED_BOOT_TIMING("FPreLoadScreenManager::HandleEarlyStartupPlay()"); + PreLoadScreen->OnPlay(MainWindow.Pin()); if (PreLoadScreen->GetWidget().IsValid()) @@ -147,11 +153,20 @@ void FPreLoadScreenManager::HandleEarlyStartupPlay() bDidDisableScreensaver = FPlatformApplicationMisc::ControlScreensaver(FGenericPlatformApplicationMisc::EScreenSaverAction::Disable); } - //We run this PreLoadScreen until its finished or we lose the MainWindow as EarlyPreLoadPlay is synchronous - while (!PreLoadScreen->IsDone()) - { - EarlyPlayFrameTick(); - } + { + SCOPED_BOOT_TIMING("FPreLoadScreenManager::EarlyPlayFrameTick()"); + + //We run this PreLoadScreen until its finished or we lose the MainWindow as EarlyPreLoadPlay is synchronous +#if BUILD_EMBEDDED_APP && FAST_BOOT_HACKS + FString ObjName(TEXT("LoggedInObject")); + while (FEmbeddedDelegates::GetNamedObject(ObjName) == nullptr || !PreLoadScreen->IsDone()) +#else + while (!PreLoadScreen->IsDone()) +#endif + { + EarlyPlayFrameTick(); + } + } if (bDidDisableScreensaver) { diff --git a/Engine/Source/Runtime/PreLoadScreen/Private/PreLoadSettingsContainer.cpp b/Engine/Source/Runtime/PreLoadScreen/Private/PreLoadSettingsContainer.cpp index 2504dcebfd5e..a03cb665668f 100644 --- a/Engine/Source/Runtime/PreLoadScreen/Private/PreLoadSettingsContainer.cpp +++ b/Engine/Source/Runtime/PreLoadScreen/Private/PreLoadSettingsContainer.cpp @@ -284,12 +284,24 @@ FString FPreLoadSettingsContainerBase::ConvertIfPluginRelativeContentPath(const return ReturnPath; } +void FPreLoadSettingsContainerBase::SetShouldLoadBrushes(bool bInShouldLoadBrushes) +{ + bShouldLoadBrushes = bInShouldLoadBrushes; +} + void FPreLoadSettingsContainerBase::CreateCustomSlateImageBrush(const FString& Identifier, const FString& TexturePath, const FVector2D& ImageDimensions) { - BrushResources.Add(*Identifier, new FSlateDynamicImageBrush(*TexturePath, ImageDimensions)); + if (bShouldLoadBrushes) + { + BrushResources.Add(*Identifier, new FSlateDynamicImageBrush(*TexturePath, ImageDimensions)); - //Make sure this dynamic image resource is registered with the SlateApplication - FSlateApplication::Get().GetRenderer()->GenerateDynamicImageResource(*TexturePath); + //Make sure this dynamic image resource is registered with the SlateApplication + FSlateApplication::Get().GetRenderer()->GenerateDynamicImageResource(*TexturePath); + } + else + { + BrushResources.Add(*Identifier, new FSlateDynamicImageBrush(NAME_None, ImageDimensions)); + } } void FPreLoadSettingsContainerBase::AddLocalizedText(const FString& Identifier, FText LocalizedText) diff --git a/Engine/Source/Runtime/PreLoadScreen/Public/PreLoadSettingsContainer.h b/Engine/Source/Runtime/PreLoadScreen/Public/PreLoadSettingsContainer.h index 809616436d4e..1178e2056a00 100644 --- a/Engine/Source/Runtime/PreLoadScreen/Public/PreLoadSettingsContainer.h +++ b/Engine/Source/Runtime/PreLoadScreen/Public/PreLoadSettingsContainer.h @@ -56,7 +56,8 @@ public: public: FPreLoadSettingsContainerBase() - { + { + bShouldLoadBrushes = true; } virtual ~FPreLoadSettingsContainerBase(); @@ -90,6 +91,9 @@ public: //Sets the PluginContent dir so that when parsing config entries we can accept plugin relative file paths virtual void SetPluginContentDir(const FString& PluginContentDirIn) { PluginContentDir = PluginContentDirIn; } + //Tells the container rather it should actually load image brushes + virtual void SetShouldLoadBrushes(bool bInShouldLoadBrushes); + float TimeToDisplayEachBackground; //Screens are displayed in the order of this array @@ -118,6 +122,9 @@ protected: //This string is used to make file paths relative to a particular Plugin's content directory when parsing file paths. FString PluginContentDir; + // Rather we should load image brushes + bool bShouldLoadBrushes; + // Singleton Instance -- This is only not a TSharedPtr as it needs to be cleaned up by a deferredcleanup call which directly // nukes the underlying object, causing a SharedPtr crash at shutdown. static FPreLoadSettingsContainerBase* Instance; diff --git a/Engine/Source/Runtime/Projects/Private/PluginManager.cpp b/Engine/Source/Runtime/Projects/Private/PluginManager.cpp index 1ada374cb6f8..9fb0c369f4ed 100644 --- a/Engine/Source/Runtime/Projects/Private/PluginManager.cpp +++ b/Engine/Source/Runtime/Projects/Private/PluginManager.cpp @@ -429,25 +429,40 @@ bool FPluginManager::ConfigureEnabledPlugins() // Keep a set of all the plugin names that have been configured. We read configuration data from different places, but only configure a plugin from the first place that it's referenced. TSet ConfiguredPluginNames; - // Check if we want to enable all plugins - if (FParse::Param(FCommandLine::Get(), TEXT("EnableAllPlugins"))) + // Check which plugins have been enabled or excluded via the command line { - TArray ExceptPlugins; + auto ParsePluginsList = [](const TCHAR* InListKey) -> TArray { - FString ExceptPluginsStr; - FParse::Value(FCommandLine::Get(), TEXT("ExceptPlugins="), ExceptPluginsStr, false); - ExceptPluginsStr.ParseIntoArray(ExceptPlugins, TEXT(",")); - } + TArray PluginsList; + FString PluginsListStr; + FParse::Value(FCommandLine::Get(), InListKey, PluginsListStr, false); + PluginsListStr.ParseIntoArray(PluginsList, TEXT(",")); + return PluginsList; + }; - for (const TPair>& PluginPair : AllPlugins) + // Which extra plugins should be enabled? + TArray ExtraPluginsToEnable; + if (FParse::Param(FCommandLine::Get(), TEXT("EnableAllPlugins"))) { - if (!ConfiguredPluginNames.Contains(PluginPair.Key) && !ExceptPlugins.Contains(PluginPair.Key)) + AllPlugins.GenerateKeyArray(ExtraPluginsToEnable); + } + else + { + ExtraPluginsToEnable = ParsePluginsList(TEXT("EnablePlugins=")); + } + if (ExtraPluginsToEnable.Num() > 0) + { + const TArray ExceptPlugins = ParsePluginsList(TEXT("ExceptPlugins=")); + for (const FString& EnablePluginName : ExtraPluginsToEnable) { - if (!ConfigureEnabledPlugin(FPluginReferenceDescriptor(PluginPair.Key, true), EnabledPluginNames)) + if (!ConfiguredPluginNames.Contains(EnablePluginName) && !ExceptPlugins.Contains(EnablePluginName)) { - return false; + if (!ConfigureEnabledPlugin(FPluginReferenceDescriptor(EnablePluginName, true), EnabledPluginNames)) + { + return false; + } + ConfiguredPluginNames.Add(EnablePluginName); } - ConfiguredPluginNames.Add(PluginPair.Key); } } } @@ -1178,7 +1193,7 @@ void FPluginManager::MountNewlyCreatedPlugin(const FString& PluginName) { if (FConfigSection* CoreSystemSection = EngineConfigFile->Find(TEXT("Core.System"))) { - CoreSystemSection->AddUnique("Paths", Plugin->GetContentDir()); + CoreSystemSection->AddUnique("Paths", MoveTemp(ContentDir)); } } } @@ -1210,4 +1225,25 @@ void FPluginManager::MountNewlyCreatedPlugin(const FString& PluginName) } } +FName FPluginManager::PackageNameFromModuleName(FName ModuleName) +{ + FName Result = ModuleName; + for (TMap>::TIterator Iter(AllPlugins); Iter; ++Iter) + { + const TSharedRef& Plugin = Iter.Value(); + const TArray& Modules = Plugin->Descriptor.Modules; + for (int Idx = 0; Idx < Modules.Num(); Idx++) + { + const FModuleDescriptor& Descriptor = Modules[Idx]; + if (Descriptor.Name == ModuleName) + { + UE_LOG(LogPluginManager, Log, TEXT("Module %s belongs to Plugin %s and we assume that is the name of the package with the UObjects is /Script/%s"), *ModuleName.ToString(), *Plugin->Name, *Plugin->Name); + return FName(*Plugin->Name); + } + } + } + return Result; +} + + #undef LOCTEXT_NAMESPACE diff --git a/Engine/Source/Runtime/Projects/Private/PluginManager.h b/Engine/Source/Runtime/Projects/Private/PluginManager.h index 4b74171875e7..53ae4e08aecb 100644 --- a/Engine/Source/Runtime/Projects/Private/PluginManager.h +++ b/Engine/Source/Runtime/Projects/Private/PluginManager.h @@ -111,6 +111,8 @@ public: virtual FNewPluginMountedEvent& OnNewPluginCreated() override; virtual FNewPluginMountedEvent& OnNewPluginMounted() override; virtual void MountNewlyCreatedPlugin(const FString& PluginName) override; + virtual FName PackageNameFromModuleName(FName ModuleName) override; + private: diff --git a/Engine/Source/Runtime/Projects/Public/Interfaces/IPluginManager.h b/Engine/Source/Runtime/Projects/Public/Interfaces/IPluginManager.h index 2916f0e24ec0..e5a4fbd49c6c 100644 --- a/Engine/Source/Runtime/Projects/Public/Interfaces/IPluginManager.h +++ b/Engine/Source/Runtime/Projects/Public/Interfaces/IPluginManager.h @@ -289,6 +289,11 @@ public: */ virtual void MountNewlyCreatedPlugin(const FString& PluginName) = 0; + /** + * Does a reverse lookup to try to figure out what the UObject package name is for a plugin + */ + virtual FName PackageNameFromModuleName(FName ModuleName) = 0; + public: /** diff --git a/Engine/Source/Runtime/RHI/Public/RHIResources.h b/Engine/Source/Runtime/RHI/Public/RHIResources.h index cc6787bd4b2e..43974323b373 100644 --- a/Engine/Source/Runtime/RHI/Public/RHIResources.h +++ b/Engine/Source/Runtime/RHI/Public/RHIResources.h @@ -1713,6 +1713,9 @@ struct FImmutableSamplerState class FGraphicsMinimalPipelineStateInitializer { public: + // Can't use TEnumByte as it changes the struct to be non trivially constructible, breaking memset + using TRenderTargetFormats = TStaticArray; + using TRenderTargetFlags = TStaticArray; FGraphicsMinimalPipelineStateInitializer() : BlendState(nullptr) @@ -1720,6 +1723,8 @@ public: , DepthStencilState(nullptr) , PrimitiveType(PT_Num) { + static_assert(sizeof(EPixelFormat) != sizeof(uint8), "Change TRenderTargetFormats's uint8 to EPixelFormat"); + static_assert(PF_MAX < MAX_uint8, "TRenderTargetFormats assumes EPixelFormat can fit in a uint8!"); } FGraphicsMinimalPipelineStateInitializer( diff --git a/Engine/Source/Runtime/RenderCore/Private/RenderingThread.cpp b/Engine/Source/Runtime/RenderCore/Private/RenderingThread.cpp index ce378ea37b7a..d9d24f22f63d 100644 --- a/Engine/Source/Runtime/RenderCore/Private/RenderingThread.cpp +++ b/Engine/Source/Runtime/RenderCore/Private/RenderingThread.cpp @@ -1221,9 +1221,9 @@ void FlushRenderingCommands(bool bFlushDeferredDeletes) } ENQUEUE_RENDER_COMMAND(FlushPendingDeleteRHIResourcesCmd)( - [bFlushDeferredDeletes](FRHICommandList&) + [bFlushDeferredDeletes](FRHICommandListImmediate& RHICmdList) { - GRHICommandList.GetImmediateCommandList().ImmediateFlush( + RHICmdList.ImmediateFlush( bFlushDeferredDeletes ? EImmediateFlushType::FlushRHIThreadFlushResourcesFlushDeferredDeletes : EImmediateFlushType::FlushRHIThreadFlushResources); diff --git a/Engine/Source/Runtime/Renderer/Private/DistortionRendering.cpp b/Engine/Source/Runtime/Renderer/Private/DistortionRendering.cpp index 7970cfb3c6f6..2a4c9add068d 100644 --- a/Engine/Source/Runtime/Renderer/Private/DistortionRendering.cpp +++ b/Engine/Source/Runtime/Renderer/Private/DistortionRendering.cpp @@ -51,6 +51,16 @@ void SetupDistortionPassUniformBuffer(FRHICommandListImmediate& RHICmdList, cons DistortionPassParameters.DistortionParams.Y = Ratio; DistortionPassParameters.DistortionParams.Z = (float)View.UnscaledViewRect.Width(); DistortionPassParameters.DistortionParams.W = (float)View.UnscaledViewRect.Height(); + + // When ISR is enabled we store two FOVs in the distortion parameters and compute the aspect ratio in the shader instead. + if ((View.IsInstancedStereoPass() || View.bIsMobileMultiViewEnabled) && View.Family->Views.Num() > 0) + { + // When drawing the left eye in a stereo scene, copy the right eye view values into the instanced view uniform buffer. + const EStereoscopicPass StereoPassIndex = (View.StereoPass != eSSP_FULL) ? eSSP_RIGHT_EYE : eSSP_FULL; + + const FViewInfo& InstancedView = static_cast(View.Family->GetStereoEyeView(StereoPassIndex)); + DistortionPassParameters.DistortionParams.Y = InstancedView.ViewMatrices.GetProjectionMatrix().M[0][0]; + } } void SetupMobileDistortionPassUniformBuffer(FRHICommandListImmediate& RHICmdList, const FViewInfo& View, FMobileDistortionPassUniformParameters& DistortionPassParameters) @@ -63,6 +73,16 @@ void SetupMobileDistortionPassUniformBuffer(FRHICommandListImmediate& RHICmdList DistortionPassParameters.DistortionParams.Y = Ratio; DistortionPassParameters.DistortionParams.Z = (float)View.UnscaledViewRect.Width(); DistortionPassParameters.DistortionParams.W = (float)View.UnscaledViewRect.Height(); + + // When ISR is enabled we store two FOVs in the distortion parameters and compute the aspect ratio in the shader instead. + if ((View.IsInstancedStereoPass() || View.bIsMobileMultiViewEnabled) && View.Family->Views.Num() > 0) + { + // When drawing the left eye in a stereo scene, copy the right eye view values into the instanced view uniform buffer. + const EStereoscopicPass StereoPassIndex = (View.StereoPass != eSSP_FULL) ? eSSP_RIGHT_EYE : eSSP_FULL; + + const FViewInfo& InstancedView = static_cast(View.Family->GetStereoEyeView(StereoPassIndex)); + DistortionPassParameters.DistortionParams.Y = InstancedView.ViewMatrices.GetProjectionMatrix().M[0][0]; + } } /** @@ -494,6 +514,33 @@ bool SubmitDistortionMeshDrawCommands(FRHICommandListImmediate& RHICmdList, cons return bDirty; } +static void SetupDistortionPassView(FRHICommandList& RHICmdList, const FViewInfo& View, const FSceneRenderer* SceneRenderer) +{ + if (!View.IsInstancedStereoPass()) + { + RHICmdList.SetViewport(View.ViewRect.Min.X, View.ViewRect.Min.Y, 0.0f, View.ViewRect.Max.X, View.ViewRect.Max.Y, 1.0f); + } + else + { + if (View.bIsMultiViewEnabled) + { + const uint32 LeftMinX = SceneRenderer->Views[0].ViewRect.Min.X; + const uint32 LeftMaxX = SceneRenderer->Views[0].ViewRect.Max.X; + const uint32 RightMinX = SceneRenderer->Views[1].ViewRect.Min.X; + const uint32 RightMaxX = SceneRenderer->Views[1].ViewRect.Max.X; + + const uint32 LeftMaxY = SceneRenderer->Views[0].ViewRect.Max.Y; + const uint32 RightMaxY = SceneRenderer->Views[1].ViewRect.Max.Y; + + RHICmdList.SetStereoViewport(LeftMinX, RightMinX, 0, 0, 0.0f, LeftMaxX, RightMaxX, LeftMaxY, RightMaxY, 1.0f); + } + else + { + RHICmdList.SetViewport(0, 0, 0, SceneRenderer->InstancedStereoWidth, View.ViewRect.Max.Y, 1); + } + } +} + /** * Renders the scene's distortion */ @@ -508,7 +555,7 @@ void FSceneRenderer::RenderDistortion(FRHICommandListImmediate& RHICmdList) for(int32 ViewIndex = 0;ViewIndex < Views.Num();ViewIndex++) { const FViewInfo& View = Views[ViewIndex]; - if (View.bHasDistortionPrimitives) + if (View.bHasDistortionPrimitives && View.ShouldRenderView()) { bRender=true; break; @@ -560,8 +607,13 @@ void FSceneRenderer::RenderDistortion(FRHICommandListImmediate& RHICmdList) SCOPED_CONDITIONAL_DRAW_EVENTF(RHICmdList, EventView, Views.Num() > 1, TEXT("View%d"), ViewIndex); FViewInfo& View = Views[ViewIndex]; + if (!View.ShouldRenderView()) + { + continue; + } + // viewport to match view size - RHICmdList.SetViewport(View.ViewRect.Min.X, View.ViewRect.Min.Y, 0.0f, View.ViewRect.Max.X, View.ViewRect.Max.Y, 1.0f); + SetupDistortionPassView(RHICmdList, View, this); Scene->UniformBuffers.UpdateViewUniformBuffer(View); @@ -570,6 +622,7 @@ void FSceneRenderer::RenderDistortion(FRHICommandListImmediate& RHICmdList) Scene->UniformBuffers.DistortionPassUniformBuffer.UpdateUniformBufferImmediate(DistortionPassParameters); FMeshPassProcessorRenderState DrawRenderState(View, Scene->UniformBuffers.DistortionPassUniformBuffer); + DrawRenderState.SetInstancedViewUniformBuffer(Scene->UniformBuffers.InstancedViewUniformBuffer); // test against depth and write stencil mask DrawRenderState.SetDepthStencilState(TStaticDepthStencilState< diff --git a/Engine/Source/Runtime/Renderer/Private/MobileSceneCaptureRendering.cpp b/Engine/Source/Runtime/Renderer/Private/MobileSceneCaptureRendering.cpp index 88e1cc3e181d..c19de297c994 100644 --- a/Engine/Source/Runtime/Renderer/Private/MobileSceneCaptureRendering.cpp +++ b/Engine/Source/Runtime/Renderer/Private/MobileSceneCaptureRendering.cpp @@ -390,15 +390,18 @@ void UpdateSceneCaptureContentMobile_RenderThread( // Helper class to allow setting render target struct FRenderTargetOverride : public FRenderTarget { - FRenderTargetOverride(FRHITexture2D* In) + FRenderTargetOverride(const FRenderTarget* TargetIn, FRHITexture2D* In) { RenderTargetTextureRHI = In; + OriginalTarget = TargetIn; } - virtual FIntPoint GetSizeXY() const { return FIntPoint(RenderTargetTextureRHI->GetSizeX(), RenderTargetTextureRHI->GetSizeY()); } + virtual FIntPoint GetSizeXY() const override { return FIntPoint(RenderTargetTextureRHI->GetSizeX(), RenderTargetTextureRHI->GetSizeY()); } + virtual float GetDisplayGamma() const override { return OriginalTarget->GetDisplayGamma(); } FTexture2DRHIRef GetTextureParamRef() { return RenderTargetTextureRHI; } - } FlippedRenderTarget( + const FRenderTarget* OriginalTarget; + } FlippedRenderTarget(Target, FlippedPooledRenderTarget.GetReference() ? FlippedPooledRenderTarget.GetReference()->GetRenderTargetItem().TargetableTexture->GetTexture2D() : nullptr); diff --git a/Engine/Source/Runtime/Renderer/Private/MobileShadingRenderer.cpp b/Engine/Source/Runtime/Renderer/Private/MobileShadingRenderer.cpp index 368040370852..eece15a1c0be 100644 --- a/Engine/Source/Runtime/Renderer/Private/MobileShadingRenderer.cpp +++ b/Engine/Source/Runtime/Renderer/Private/MobileShadingRenderer.cpp @@ -69,13 +69,6 @@ static TAutoConsoleVariable CVarMobileMoveSubmissionHintAfterTranslucency TEXT("1: Submission hint occurs after translucency. (Default)"), ECVF_Scalability | ECVF_RenderThreadSafe); -static TAutoConsoleVariable CVarMobileDisableGPUParticleCollision( - TEXT("r.Mobile.DisableGPUParticleCollision"), - 1, - TEXT("0: Allow GPU particle collision simulation if supported (Default).\n") - TEXT("1: Disable GPU particle collision simulation"), - ECVF_RenderThreadSafe); - DECLARE_CYCLE_STAT(TEXT("SceneStart"), STAT_CLMM_SceneStart, STATGROUP_CommandListMarkers); DECLARE_CYCLE_STAT(TEXT("SceneEnd"), STAT_CLMM_SceneEnd, STATGROUP_CommandListMarkers); DECLARE_CYCLE_STAT(TEXT("InitViews"), STAT_CLMM_InitViews, STATGROUP_CommandListMarkers); @@ -210,7 +203,7 @@ void FMobileSceneRenderer::InitViews(FRHICommandListImmediate& RHICmdList) if (bDynamicShadows && !IsSimpleForwardShadingEnabled(ShaderPlatform)) { // Setup dynamic shadows. - InitDynamicShadows(RHICmdList); + InitDynamicShadows(RHICmdList); } else { @@ -236,7 +229,7 @@ void FMobileSceneRenderer::InitViews(FRHICommandListImmediate& RHICmdList) // Create the directional light uniform buffers CreateDirectionalLightUniformBuffers(Views[ViewIndex]); } - + // update buffers used in cached mesh path // in case there are multiple views, these buffers will be updated before rendering each view if (Views.Num() > 0) @@ -254,7 +247,7 @@ void FMobileSceneRenderer::InitViews(FRHICommandListImmediate& RHICmdList) // Now that the indirect lighting cache is updated, we can update the uniform buffers. UpdatePrimitiveIndirectLightingCacheBuffers(); - + OnStartRender(RHICmdList); } @@ -349,7 +342,7 @@ void FMobileSceneRenderer::Render(FRHICommandListImmediate& RHICmdList) } const bool bGammaSpace = !IsMobileHDR(); - + // Custom depth if (!bGammaSpace) { @@ -376,7 +369,7 @@ void FMobileSceneRenderer::Render(FRHICommandListImmediate& RHICmdList) (bForceDepthResolve || bSeparateTranslucencyActive || (View.bIsSceneCapture && (ViewFamily.SceneCaptureSource == ESceneCaptureSource::SCS_SceneColorHDR || ViewFamily.SceneCaptureSource == ESceneCaptureSource::SCS_SceneColorSceneDepth))); // workaround for corrupted depth on vulkan PC, always store depth bKeepDepthContent|= (IsPCPlatform(ShaderPlatform) && IsVulkanPlatform(ShaderPlatform)); - + // FTextureRHIParamRef SceneColor = nullptr; FTextureRHIParamRef SceneColorResolve = nullptr; @@ -384,7 +377,7 @@ void FMobileSceneRenderer::Render(FRHICommandListImmediate& RHICmdList) ERenderTargetActions ColorTargetAction = ERenderTargetActions::Clear_Store; EDepthStencilTargetActions DepthTargetAction = EDepthStencilTargetActions::ClearDepthStencil_DontStoreDepthStencil; bool bMobileMSAA = false; - + if (bGammaSpace && !bRenderToSceneColor) { SceneColor = GetMultiViewSceneColor(SceneContext); @@ -400,12 +393,12 @@ void FMobileSceneRenderer::Render(FRHICommandListImmediate& RHICmdList) SceneDepth = SceneContext.GetSceneDepthSurface(); if (bRequiresTranslucencyPass) - { + { // store targets after opaque so trancluceny render pass can be restarted ColorTargetAction = ERenderTargetActions::Clear_Store; DepthTargetAction = EDepthStencilTargetActions::ClearDepthStencil_StoreDepthStencil; } - + if (bKeepDepthContent) { // store depth if post-processing/capture needs it @@ -458,19 +451,8 @@ void FMobileSceneRenderer::Render(FRHICommandListImmediate& RHICmdList) RHICmdList.EndRenderPass(); } - // Notify the FX system that opaque primitives have been rendered. - if (Scene->FXSystem && IsGPUParticleCollisionEnabled(Views[0])) - { - FMobileSceneTextureUniformParameters MobileSceneTextureParameters; - SetupMobileSceneTextureUniformParameters(SceneContext, FeatureLevel, true, MobileSceneTextureParameters); - TUniformBufferRef MobileSceneTextureUniformBuffer = TUniformBufferRef::CreateUniformBufferImmediate(MobileSceneTextureParameters, UniformBuffer_SingleFrame); - - // This is switching to another RT! - Scene->FXSystem->PostRenderOpaque(RHICmdList, View.ViewUniformBuffer, &FMobileSceneTextureUniformParameters::StaticStructMetadata, MobileSceneTextureUniformBuffer.GetReference()); - } - RHICmdList.SetCurrentStat(GET_STATID(STAT_CLMM_Translucency)); - + // Restart trancluceny render pass if needed if (bRequiresTranslucencyPass) { @@ -516,7 +498,7 @@ void FMobileSceneRenderer::Render(FRHICommandListImmediate& RHICmdList) RenderModulatedShadowProjections(RHICmdList); } } - + // Draw translucency. if (ViewFamily.EngineShowFlags.Translucency) { @@ -536,12 +518,12 @@ void FMobileSceneRenderer::Render(FRHICommandListImmediate& RHICmdList) RHICmdList.EndRenderPass(); RHICmdList.SetCurrentStat(GET_STATID(STAT_CLMM_Post)); - + if (!View.bIsMobileMultiViewDirectEnabled) { CopyMobileMultiViewSceneColor(RHICmdList); } - + if (ViewFamily.bResolveScene) { if (!bGammaSpace) @@ -1024,12 +1006,3 @@ void FMobileSceneRenderer::PreTonemapMSAA(FRHICommandListImmediate& RHICmdList) *VertexShader, EDRF_UseTriangleOptimization); } - -bool FMobileSceneRenderer::IsGPUParticleCollisionEnabled(const FViewInfo& View) -{ - if (!View.bIsPlanarReflection && ViewFamily.EngineShowFlags.Particles) - { - return CVarMobileDisableGPUParticleCollision.GetValueOnRenderThread() == 0; - } - return false; -} diff --git a/Engine/Source/Runtime/Renderer/Private/PostProcess/SceneRenderTargets.h b/Engine/Source/Runtime/Renderer/Private/PostProcess/SceneRenderTargets.h index 962e955962b4..d4701d01a434 100644 --- a/Engine/Source/Runtime/Renderer/Private/PostProcess/SceneRenderTargets.h +++ b/Engine/Source/Runtime/Renderer/Private/PostProcess/SceneRenderTargets.h @@ -116,7 +116,7 @@ static const int32 NumTranslucencyShadowSurfaces = 2; #define STENCIL_LIGHTING_CHANNELS_MASK(Value) uint8((Value & 0x7) << STENCIL_LIGHTING_CHANNELS_BIT_ID) -#define PREVENT_RENDERTARGET_SIZE_THRASHING (PLATFORM_DESKTOP || PLATFORM_XBOXONE || PLATFORM_PS4 || PLATFORM_ANDROID || PLATFORM_IOS) +#define PREVENT_RENDERTARGET_SIZE_THRASHING (PLATFORM_DESKTOP || PLATFORM_XBOXONE || PLATFORM_PS4 || PLATFORM_ANDROID || PLATFORM_IOS || PLATFORM_SWITCH) enum class ESceneColorFormatType { diff --git a/Engine/Source/Runtime/Renderer/Private/ReflectionEnvironmentCapture.cpp b/Engine/Source/Runtime/Renderer/Private/ReflectionEnvironmentCapture.cpp index 2e6b44e072b6..c6587449949d 100644 --- a/Engine/Source/Runtime/Renderer/Private/ReflectionEnvironmentCapture.cpp +++ b/Engine/Source/Runtime/Renderer/Private/ReflectionEnvironmentCapture.cpp @@ -259,7 +259,7 @@ float ComputeSingleAverageBrightnessFromCubemap(FRHICommandListImmediate& RHICmd GraphicsPSOInit.BoundShaderState.VertexShaderRHI = GETSAFERHISHADER_VERTEX(*VertexShader); GraphicsPSOInit.BoundShaderState.PixelShaderRHI = GETSAFERHISHADER_PIXEL(*PixelShader); GraphicsPSOInit.PrimitiveType = PT_TriangleList; - + SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit); PixelShader->SetParameters(RHICmdList, TargetSize, Cubemap); @@ -804,13 +804,19 @@ void CopyCubemapToScratchCubemap(FRHICommandList& RHICmdList, ERHIFeatureLevel:: RHICmdList.TransitionResource(EResourceTransitionAccess::EWritable, EffectiveColorRT.TargetableTexture); + const FTexture* SourceCubemapResource = SourceCubemap->Resource; + if (SourceCubemapResource == nullptr) + { + UE_LOG(LogEngine, Warning, TEXT("Unable to copy from cubemap %s, it's RHI resource is null"), *SourceCubemap->GetPathName()); + return; + } + for (uint32 CubeFace = 0; CubeFace < CubeFace_MAX; CubeFace++) { // Copy the captured scene into the cubemap face FRHIRenderPassInfo RPInfo(EffectiveColorRT.TargetableTexture, ERenderTargetActions::DontLoad_Store, nullptr, 0, CubeFace); RHICmdList.BeginRenderPass(RPInfo, TEXT("CopyCubemapToScratchCubemapRP")); - const FTexture* SourceCubemapResource = SourceCubemap->Resource; const FIntPoint SourceDimensions(SourceCubemapResource->GetSizeX(), SourceCubemapResource->GetSizeY()); const FIntRect ViewRect(0, 0, EffectiveSize, EffectiveSize); RHICmdList.SetViewport(0, 0, 0.0f, EffectiveSize, EffectiveSize, 1.0f); diff --git a/Engine/Source/Runtime/Renderer/Private/SceneCaptureRendering.cpp b/Engine/Source/Runtime/Renderer/Private/SceneCaptureRendering.cpp index 1063d15a64a6..3dd56a5a0ec3 100644 --- a/Engine/Source/Runtime/Renderer/Private/SceneCaptureRendering.cpp +++ b/Engine/Source/Runtime/Renderer/Private/SceneCaptureRendering.cpp @@ -54,6 +54,14 @@ const TCHAR* GShaderSourceModeDefineName[] = TEXT("SOURCE_MODE_BASE_COLOR") }; +static TAutoConsoleVariable CVarEnableViewExtensionsForSceneCapture( + TEXT("r.SceneCapture.EnableViewExtensions"), + 0, + TEXT("Whether to enable view extensions when doing scene capture.\n") + TEXT("0: Disable view extensions (default).\n") + TEXT("1: Enable view extensions.\n"), + ECVF_Default); + /** * A pixel shader for capturing a component of the rendered scene for a scene capture. */ @@ -643,7 +651,12 @@ static FSceneRenderer* CreateSceneRendererForSceneCapture( SceneCaptureComponent->ShowFlags) .SetResolveScene(!bCaptureSceneColor) .SetRealtimeUpdate(SceneCaptureComponent->bCaptureEveryFrame || SceneCaptureComponent->bAlwaysPersistRenderingState)); - + + if (CVarEnableViewExtensionsForSceneCapture.GetValueOnAnyThread() > 0) + { + ViewFamily.ViewExtensions = GEngine->ViewExtensions->GatherActiveExtensions(nullptr); + } + SetupViewVamilyForSceneCapture( ViewFamily, SceneCaptureComponent, diff --git a/Engine/Source/Runtime/Renderer/Private/SceneRendering.h b/Engine/Source/Runtime/Renderer/Private/SceneRendering.h index 693afa717620..b7ca363558ea 100644 --- a/Engine/Source/Runtime/Renderer/Private/SceneRendering.h +++ b/Engine/Source/Runtime/Renderer/Private/SceneRendering.h @@ -1614,8 +1614,6 @@ protected: /** On chip pre-tonemap before scene color MSAA resolve (iOS only) */ void PreTonemapMSAA(FRHICommandListImmediate& RHICmdList); - /** Whether GPU particle collisions simulation is allowed. */ - bool IsGPUParticleCollisionEnabled(const FViewInfo& View); void SortMobileBasePassAfterShadowInit(FExclusiveDepthStencil::Type BasePassDepthStencilAccess, FViewVisibleCommandsPerView& ViewCommandsPerView); void SetupMobileBasePassAfterShadowInit(FExclusiveDepthStencil::Type BasePassDepthStencilAccess, FViewVisibleCommandsPerView& ViewCommandsPerView); diff --git a/Engine/Source/Runtime/Slate/Private/Framework/Application/SlateApplication.cpp b/Engine/Source/Runtime/Slate/Private/Framework/Application/SlateApplication.cpp index b0177990a2c7..e05ee8e66cae 100644 --- a/Engine/Source/Runtime/Slate/Private/Framework/Application/SlateApplication.cpp +++ b/Engine/Source/Runtime/Slate/Private/Framework/Application/SlateApplication.cpp @@ -5733,11 +5733,12 @@ bool FSlateApplication::RoutePointerMoveEvent(const FWidgetPath& WidgetsUnderPoi // User asked us to detect a drag. bool bDragDetected = false; - bool bShouldStartDetectingDrag = true; + // Currently we can only support one dragged widget at a time. + bool bShouldStartDetectingDrag = !DragDropContent.IsValid(); #if WITH_EDITOR //@TODO VREDITOR - Remove and move to interaction component - if (OnDragDropCheckOverride.IsBound()) + if (bShouldStartDetectingDrag && OnDragDropCheckOverride.IsBound()) { bShouldStartDetectingDrag = OnDragDropCheckOverride.Execute(); } diff --git a/Engine/Source/Runtime/SlateCore/Private/Styling/SlateBrush.cpp b/Engine/Source/Runtime/SlateCore/Private/Styling/SlateBrush.cpp index 82cd4f40d716..a528216e9c2f 100644 --- a/Engine/Source/Runtime/SlateCore/Private/Styling/SlateBrush.cpp +++ b/Engine/Source/Runtime/SlateCore/Private/Styling/SlateBrush.cpp @@ -103,4 +103,23 @@ bool FSlateBrush::CanRenderResourceObject(UObject* InResourceObject) const } return true; +} + +void FSlateBrush::SetResourceObject(class UObject* InResourceObject) +{ +#if !(UE_BUILD_TEST || UE_BUILD_SHIPPING) + // This check is not safe to run from all threads, and would crash in debug + if (!ensure(!IsThreadSafeForSlateRendering() || CanRenderResourceObject(InResourceObject))) + { + // If we can't render the resource return, don't let people use them as brushes, we'll just crash later. + return; + } +#endif + + if (ResourceObject != InResourceObject) + { + ResourceObject = InResourceObject; + // Invalidate resource handle + ResourceHandle = FSlateResourceHandle(); + } } \ No newline at end of file diff --git a/Engine/Source/Runtime/SlateCore/Public/Styling/SlateBrush.h b/Engine/Source/Runtime/SlateCore/Public/Styling/SlateBrush.h index f3cf83aa62dc..43dfb64ba0f7 100644 --- a/Engine/Source/Runtime/SlateCore/Public/Styling/SlateBrush.h +++ b/Engine/Source/Runtime/SlateCore/Public/Styling/SlateBrush.h @@ -196,23 +196,7 @@ public: /** * Sets the UObject that represents the brush resource. */ - void SetResourceObject(class UObject* InResourceObject) - { -#if !(UE_BUILD_TEST || UE_BUILD_SHIPPING) - if (!ensure(CanRenderResourceObject(InResourceObject))) - { - // If we can't render the resource return, don't let people use them as brushes, we'll just crash later. - return; - } -#endif - - if (ResourceObject != InResourceObject) - { - ResourceObject = InResourceObject; - // Invalidate resource handle - ResourceHandle = FSlateResourceHandle(); - } - } + void SetResourceObject(class UObject* InResourceObject); /** * Gets the brush's tint color. diff --git a/Engine/Source/Runtime/UMG/Private/Components/ListView.cpp b/Engine/Source/Runtime/UMG/Private/Components/ListView.cpp index 582de8bc8880..cd63f5918a1e 100644 --- a/Engine/Source/Runtime/UMG/Private/Components/ListView.cpp +++ b/Engine/Source/Runtime/UMG/Private/Components/ListView.cpp @@ -34,6 +34,24 @@ void UListView::OnRefreshDesignerItems() void UListView::AddItem(UObject* Item) { ListItems.Add(Item); + + TArray Added; + TArray Removed; + Added.Add(Item); + OnItemsChanged(Added, Removed); + + RequestRefresh(); +} + +void UListView::RemoveItem(UObject* Item) +{ + ListItems.Remove(Item); + + TArray Added; + TArray Removed; + Removed.Add(Item); + OnItemsChanged(Added, Removed); + RequestRefresh(); } @@ -54,7 +72,13 @@ int32 UListView::GetIndexForItem(UObject* Item) const void UListView::ClearListItems() { + TArray Added; + TArray Removed = MoveTemp(ListItems); + ListItems.Reset(); + + OnItemsChanged(Added, Removed); + RequestRefresh(); } @@ -184,6 +208,11 @@ void UListView::BP_ClearSelection() ClearSelection(); } +void UListView::OnItemsChanged(const TArray& AddedItems, const TArray& RemovedItems) +{ + // Allow subclasses to do special things when objects are added or removed from the list. +} + TSharedRef UListView::RebuildListWidget() { return ConstructListView(); diff --git a/Engine/Source/Runtime/UMG/Public/Components/ListView.h b/Engine/Source/Runtime/UMG/Public/Components/ListView.h index 702d6e1406cb..4c02e84cd27f 100644 --- a/Engine/Source/Runtime/UMG/Public/Components/ListView.h +++ b/Engine/Source/Runtime/UMG/Public/Components/ListView.h @@ -40,6 +40,9 @@ public: { ClearListItems(); ListItems.Append(InListItems); + + OnItemsChanged(ListItems, TArray()); + RequestRefresh(); } @@ -70,6 +73,10 @@ public: UFUNCTION(BlueprintCallable, Category = ListView) void AddItem(UObject* Item); + /** Removes an the item from the list */ + UFUNCTION(BlueprintCallable, Category = ListView) + void RemoveItem(UObject* Item); + /** Returns the item at the given index */ UFUNCTION(BlueprintCallable, Category = ListView) UObject* GetItemAt(int32 Index) const; @@ -107,6 +114,8 @@ public: void NavigateToIndex(int32 Index); protected: + virtual void OnItemsChanged(const TArray& AddedItems, const TArray& RemovedItems); + virtual TSharedRef RebuildListWidget() override; virtual void HandleListEntryHovered(UUserWidget& EntryWidget) override; virtual void HandleListEntryUnhovered(UUserWidget& EntryWidget) override; diff --git a/Engine/Source/Runtime/VulkanRHI/Private/VulkanDevice.cpp b/Engine/Source/Runtime/VulkanRHI/Private/VulkanDevice.cpp index d5fffce2aeba..215d7cf2da87 100644 --- a/Engine/Source/Runtime/VulkanRHI/Private/VulkanDevice.cpp +++ b/Engine/Source/Runtime/VulkanRHI/Private/VulkanDevice.cpp @@ -36,6 +36,9 @@ static TAutoConsoleVariable GCVarRobustBufferAccess( ECVF_ReadOnly ); +// Mirror GPixelFormats with format information for buffers +VkFormat GVulkanBufferFormat[PF_MAX]; + EDelayAcquireImageType GVulkanDelayAcquireImage = EDelayAcquireImageType::DelayAcquire; TAutoConsoleVariable CVarDelayAcquireBackBuffer( @@ -425,7 +428,8 @@ void FVulkanDevice::SetupFormats() { GPixelFormats[Index].PlatformFormat = VK_FORMAT_UNDEFINED; GPixelFormats[Index].Supported = false; - + GVulkanBufferFormat[Index] = VK_FORMAT_UNDEFINED; + // Set default component mapping VkComponentMapping& ComponentMapping = PixelFormatComponentMapping[Index]; ComponentMapping.r = VK_COMPONENT_SWIZZLE_R; @@ -441,7 +445,7 @@ void FVulkanDevice::SetupFormats() MapFormatSupport(PF_G8, VK_FORMAT_R8_UNORM); SetComponentMapping(PF_G8, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO); - MapFormatSupport(PF_G16, VK_FORMAT_R16_UNORM); + MapFormatSupportWithFallback(PF_G16, VK_FORMAT_R16_UNORM, {VK_FORMAT_R16_SFLOAT}); SetComponentMapping(PF_G16, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO); MapFormatSupport(PF_FloatRGB, VK_FORMAT_B10G11R11_UFLOAT_PACK32); @@ -450,19 +454,7 @@ void FVulkanDevice::SetupFormats() MapFormatSupport(PF_FloatRGBA, VK_FORMAT_R16G16B16A16_SFLOAT, 8); SetComponentMapping(PF_FloatRGBA, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A); - MapFormatSupport(PF_DepthStencil, VK_FORMAT_D32_SFLOAT_S8_UINT); - if (!GPixelFormats[PF_DepthStencil].Supported) - { - MapFormatSupport(PF_DepthStencil, VK_FORMAT_D24_UNORM_S8_UINT); - if (!GPixelFormats[PF_DepthStencil].Supported) - { - MapFormatSupport(PF_DepthStencil, VK_FORMAT_D16_UNORM_S8_UINT); - if (!GPixelFormats[PF_DepthStencil].Supported) - { - UE_LOG(LogVulkanRHI, Error, TEXT("No stencil texture format supported!")); - } - } - } + MapFormatSupportWithFallback(PF_DepthStencil, VK_FORMAT_D32_SFLOAT_S8_UINT, {VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT}); SetComponentMapping(PF_DepthStencil, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY); MapFormatSupport(PF_ShadowDepth, VK_FORMAT_D16_UNORM); @@ -475,7 +467,7 @@ void FVulkanDevice::SetupFormats() MapFormatSupport(PF_A32B32G32R32F, VK_FORMAT_R32G32B32A32_SFLOAT, 16); SetComponentMapping(PF_A32B32G32R32F, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A); - MapFormatSupport(PF_G16R16, VK_FORMAT_R16G16_UNORM); + MapFormatSupportWithFallback(PF_G16R16, VK_FORMAT_R16G16_UNORM, {VK_FORMAT_R16G16_SFLOAT}); SetComponentMapping(PF_G16R16, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO); MapFormatSupport(PF_G16R16F, VK_FORMAT_R16G16_SFLOAT); @@ -499,28 +491,7 @@ void FVulkanDevice::SetupFormats() MapFormatSupport(PF_R8_UINT, VK_FORMAT_R8_UINT); SetComponentMapping(PF_R8_UINT, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO); - MapFormatSupport(PF_D24, VK_FORMAT_X8_D24_UNORM_PACK32); - if (!GPixelFormats[PF_D24].Supported) - { - MapFormatSupport(PF_D24, VK_FORMAT_D24_UNORM_S8_UINT); - if (!GPixelFormats[PF_D24].Supported) - { - MapFormatSupport(PF_D24, VK_FORMAT_D16_UNORM_S8_UINT); - if (!GPixelFormats[PF_D24].Supported) - { - MapFormatSupport(PF_D24, VK_FORMAT_D32_SFLOAT); - if (!GPixelFormats[PF_D24].Supported) - { - MapFormatSupport(PF_D24, VK_FORMAT_D32_SFLOAT_S8_UINT); - if (!GPixelFormats[PF_D24].Supported) - { - MapFormatSupport(PF_D24, VK_FORMAT_D16_UNORM); - } - } - } - } - } - + MapFormatSupportWithFallback(PF_D24, VK_FORMAT_X8_D24_UNORM_PACK32, {VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT}); SetComponentMapping(PF_D24, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO); MapFormatSupport(PF_R16F, VK_FORMAT_R16_SFLOAT); @@ -535,7 +506,8 @@ void FVulkanDevice::SetupFormats() MapFormatSupport(PF_A2B10G10R10, VK_FORMAT_A2B10G10R10_UNORM_PACK32, 4); SetComponentMapping(PF_A2B10G10R10, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A); - MapFormatSupport(PF_A16B16G16R16, VK_FORMAT_R16G16B16A16_UNORM, 8); + MapFormatSupportWithFallback(PF_A16B16G16R16, VK_FORMAT_R16G16B16A16_UNORM, {VK_FORMAT_R16G16B16A16_SFLOAT}); + GPixelFormats[PF_A16B16G16R16].BlockBytes = 8; SetComponentMapping(PF_A16B16G16R16, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A); MapFormatSupport(PF_A8, VK_FORMAT_R8_UNORM); @@ -565,10 +537,10 @@ void FVulkanDevice::SetupFormats() MapFormatSupport(PF_R32G32B32A32_UINT, VK_FORMAT_R32G32B32A32_UINT); SetComponentMapping(PF_R32G32B32A32_UINT, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A); - MapFormatSupport(PF_R16G16B16A16_SNORM, VK_FORMAT_R16G16B16A16_SNORM); + MapFormatSupportWithFallback(PF_R16G16B16A16_SNORM, VK_FORMAT_R16G16B16A16_SNORM, {VK_FORMAT_R16G16B16A16_SFLOAT}); SetComponentMapping(PF_R16G16B16A16_SNORM, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A); - MapFormatSupport(PF_R16G16B16A16_UNORM, VK_FORMAT_R16G16B16A16_UNORM); + MapFormatSupportWithFallback(PF_R16G16B16A16_UNORM, VK_FORMAT_R16G16B16A16_UNORM, {VK_FORMAT_R16G16B16A16_SFLOAT}); SetComponentMapping(PF_R16G16B16A16_UNORM, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A); MapFormatSupport(PF_R8G8, VK_FORMAT_R8G8_UNORM); @@ -661,7 +633,7 @@ void FVulkanDevice::SetupFormats() for (int32 Index = (int32)VET_None + 1; Index < VET_MAX; ++Index) { EVertexElementType UEType = (EVertexElementType)Index; - VkFormat VulkanFormat = UEToVkFormat(UEType); + VkFormat VulkanFormat = UEToVkBufferFormat(UEType); if (!IsBufferFormatSupported(VulkanFormat)) { UE_LOG(LogVulkanRHI, Warning, TEXT("EVertexFormat(%d) is not supported with Vk format %d"), (int32)UEType, (int32)VulkanFormat); @@ -690,13 +662,40 @@ VkSamplerYcbcrConversion FVulkanDevice::CreateSamplerColorConversion(const VkSam void FVulkanDevice::MapFormatSupport(EPixelFormat UEFormat, VkFormat VulkanFormat) { - FPixelFormatInfo& FormatInfo = GPixelFormats[UEFormat]; - FormatInfo.PlatformFormat = VulkanFormat; - FormatInfo.Supported = IsTextureFormatSupported(VulkanFormat); + MapFormatSupportWithFallback(UEFormat, VulkanFormat, TArrayView()); +} +void FVulkanDevice::MapFormatSupportWithFallback(EPixelFormat UEFormat, VkFormat VulkanFormat, TArrayView FallbackTextureFormats) +{ + VkFormat SupportedTextureFormat = IsTextureFormatSupported(VulkanFormat) ? VulkanFormat : VK_FORMAT_UNDEFINED; + VkFormat SupportedBufferFormat = IsBufferFormatSupported(VulkanFormat) ? VulkanFormat : VK_FORMAT_UNDEFINED; + + FPixelFormatInfo& FormatInfo = GPixelFormats[UEFormat]; + // at this point we don't know if high level code will use this pixel format for buffers or textures + FormatInfo.Supported = (SupportedTextureFormat!= VK_FORMAT_UNDEFINED || SupportedBufferFormat!= VK_FORMAT_UNDEFINED); + FormatInfo.PlatformFormat = SupportedTextureFormat; + + GVulkanBufferFormat[UEFormat] = SupportedBufferFormat; + + if (SupportedTextureFormat == VK_FORMAT_UNDEFINED) + { + for (int32 Idx = 0; Idx < FallbackTextureFormats.Num(); ++Idx) + { + VkFormat FallbackTextureFormat = FallbackTextureFormats[Idx]; + if (IsTextureFormatSupported(FallbackTextureFormat)) + { + SupportedTextureFormat = FallbackTextureFormat; + FormatInfo.PlatformFormat = FallbackTextureFormat; + FormatInfo.Supported = true; + + UE_LOG(LogVulkanRHI, Display, TEXT("EPixelFormat(%d) (images) is not supported with Vk format %d, falling back to Vk format %d"), (int32)UEFormat, (int32)VulkanFormat, (int32)FallbackTextureFormat); + } + } + } + if (!FormatInfo.Supported) { - UE_LOG(LogVulkanRHI, Warning, TEXT("EPixelFormat(%d) is not supported with Vk format %d"), (int32)UEFormat, (int32)VulkanFormat); + UE_LOG(LogVulkanRHI, Error, TEXT("EPixelFormat(%d) is not supported with Vk format %d"), (int32)UEFormat, (int32)VulkanFormat); } } diff --git a/Engine/Source/Runtime/VulkanRHI/Private/VulkanDevice.h b/Engine/Source/Runtime/VulkanRHI/Private/VulkanDevice.h index 6fe228ede878..a0855bebd499 100644 --- a/Engine/Source/Runtime/VulkanRHI/Private/VulkanDevice.h +++ b/Engine/Source/Runtime/VulkanRHI/Private/VulkanDevice.h @@ -301,6 +301,7 @@ public: private: void MapFormatSupport(EPixelFormat UEFormat, VkFormat VulkanFormat); + void MapFormatSupportWithFallback(EPixelFormat UEFormat, VkFormat VulkanFormat, TArrayView FallbackTextureFormats); void MapFormatSupport(EPixelFormat UEFormat, VkFormat VulkanFormat, int32 BlockBytes); void SetComponentMapping(EPixelFormat UEFormat, VkComponentSwizzle r, VkComponentSwizzle g, VkComponentSwizzle b, VkComponentSwizzle a); diff --git a/Engine/Source/Runtime/VulkanRHI/Private/VulkanRHI.cpp b/Engine/Source/Runtime/VulkanRHI/Private/VulkanRHI.cpp index 6575a6b83063..ae4f3d325f68 100644 --- a/Engine/Source/Runtime/VulkanRHI/Private/VulkanRHI.cpp +++ b/Engine/Source/Runtime/VulkanRHI/Private/VulkanRHI.cpp @@ -1320,13 +1320,13 @@ void FVulkanBufferView::Create(FVulkanBuffer& Buffer, EPixelFormat Format, uint3 Offset = InOffset; Size = InSize; check(Format != PF_Unknown); - const FPixelFormatInfo& FormatInfo = GPixelFormats[Format]; - check(FormatInfo.Supported); + VkFormat BufferFormat = GVulkanBufferFormat[Format]; + check(BufferFormat != VK_FORMAT_UNDEFINED); VkBufferViewCreateInfo ViewInfo; ZeroVulkanStruct(ViewInfo, VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO); ViewInfo.buffer = Buffer.GetBufferHandle(); - ViewInfo.format = (VkFormat)FormatInfo.PlatformFormat; + ViewInfo.format = BufferFormat; ViewInfo.offset = Offset; ViewInfo.range = Size; Flags = Buffer.GetFlags() & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; @@ -1345,9 +1345,9 @@ void FVulkanBufferView::Create(FVulkanBuffer& Buffer, EPixelFormat Format, uint3 void FVulkanBufferView::Create(FVulkanResourceMultiBuffer* Buffer, EPixelFormat Format, uint32 InOffset, uint32 InSize) { check(Format != PF_Unknown); - const FPixelFormatInfo& FormatInfo = GPixelFormats[Format]; - check(FormatInfo.Supported); - Create((VkFormat)FormatInfo.PlatformFormat, Buffer, InOffset, InSize); + VkFormat BufferFormat = GVulkanBufferFormat[Format]; + check(BufferFormat != VK_FORMAT_UNDEFINED); + Create(BufferFormat, Buffer, InOffset, InSize); } void FVulkanBufferView::Create(VkFormat Format, FVulkanResourceMultiBuffer* Buffer, uint32 InOffset, uint32 InSize) diff --git a/Engine/Source/Runtime/VulkanRHI/Private/VulkanRHIPrivate.h b/Engine/Source/Runtime/VulkanRHI/Private/VulkanRHIPrivate.h index b6dfb184b6c6..e506cc07f368 100644 --- a/Engine/Source/Runtime/VulkanRHI/Private/VulkanRHIPrivate.h +++ b/Engine/Source/Runtime/VulkanRHI/Private/VulkanRHIPrivate.h @@ -615,7 +615,7 @@ static inline VkAttachmentStoreOp RenderTargetStoreActionToVulkan(ERenderTargetS return OutStoreAction; } -inline VkFormat UEToVkFormat(EPixelFormat UEFormat, const bool bIsSRGB) +inline VkFormat UEToVkTextureFormat(EPixelFormat UEFormat, const bool bIsSRGB) { VkFormat Format = (VkFormat)GPixelFormats[UEFormat].PlatformFormat; if (bIsSRGB && GMaxRHIFeatureLevel > ERHIFeatureLevel::ES2) @@ -661,7 +661,7 @@ inline VkFormat UEToVkFormat(EPixelFormat UEFormat, const bool bIsSRGB) return Format; } -static inline VkFormat UEToVkFormat(EVertexElementType Type) +static inline VkFormat UEToVkBufferFormat(EVertexElementType Type) { switch (Type) { diff --git a/Engine/Source/Runtime/VulkanRHI/Private/VulkanRenderTarget.cpp b/Engine/Source/Runtime/VulkanRHI/Private/VulkanRenderTarget.cpp index ff7190276e47..320c0dc2d164 100644 --- a/Engine/Source/Runtime/VulkanRHI/Private/VulkanRenderTarget.cpp +++ b/Engine/Source/Runtime/VulkanRHI/Private/VulkanRenderTarget.cpp @@ -1093,14 +1093,17 @@ void FVulkanDynamicRHI::RHIReadSurfaceFloatData(FTextureRHIParamRef TextureRHI, StagingBuffer->InvalidateMappedMemory(); - OutputData.SetNum(NumPixels); + uint32 OutWidth = InRect.Max.X - InRect.Min.X; + uint32 OutHeight= InRect.Max.Y - InRect.Min.Y; + OutputData.SetNum(OutWidth * OutHeight); + uint32 OutIndex = 0; FFloat16Color* Dest = OutputData.GetData(); for (int32 Row = InRect.Min.Y; Row < InRect.Max.Y; ++Row) { FFloat16Color* Src = (FFloat16Color*)StagingBuffer->GetMappedPointer() + Row * (Surface.Width >> InMipIndex) + InRect.Min.X; for (int32 Col = InRect.Min.X; Col < InRect.Max.X; ++Col) { - *Dest++ = *Src++; + OutputData[OutIndex++] = *Src++; } } InDevice->GetStagingManager().ReleaseBuffer(InCmdBuffer, StagingBuffer); @@ -1851,7 +1854,7 @@ FVulkanRenderTargetLayout::FVulkanRenderTargetLayout(FVulkanDevice& InDevice, co VkAttachmentDescription& CurrDesc = Desc[NumAttachmentDescriptions]; CurrDesc.samples = static_cast(NumSamples); - CurrDesc.format = UEToVkFormat(RTView.Texture->GetFormat(), (Texture->Surface.UEFlags & TexCreate_SRGB) == TexCreate_SRGB); + CurrDesc.format = UEToVkTextureFormat(RTView.Texture->GetFormat(), (Texture->Surface.UEFlags & TexCreate_SRGB) == TexCreate_SRGB); CurrDesc.loadOp = RenderTargetLoadActionToVulkan(RTView.LoadAction); bFoundClearOp = bFoundClearOp || (CurrDesc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR); CurrDesc.storeOp = RenderTargetStoreActionToVulkan(RTView.StoreAction); @@ -1904,7 +1907,7 @@ FVulkanRenderTargetLayout::FVulkanRenderTargetLayout(FVulkanDevice& InDevice, co NumSamples = Surface->GetNumSamples(); CurrDesc.samples = static_cast(NumSamples); - CurrDesc.format = UEToVkFormat(RTInfo.DepthStencilRenderTarget.Texture->GetFormat(), false); + CurrDesc.format = UEToVkTextureFormat(RTInfo.DepthStencilRenderTarget.Texture->GetFormat(), false); CurrDesc.loadOp = RenderTargetLoadActionToVulkan(RTInfo.DepthStencilRenderTarget.DepthLoadAction); CurrDesc.stencilLoadOp = RenderTargetLoadActionToVulkan(RTInfo.DepthStencilRenderTarget.StencilLoadAction); bFoundClearOp = bFoundClearOp || (CurrDesc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR || CurrDesc.stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR); @@ -2022,7 +2025,7 @@ FVulkanRenderTargetLayout::FVulkanRenderTargetLayout(FVulkanDevice& InDevice, co VkAttachmentDescription& CurrDesc = Desc[NumAttachmentDescriptions]; CurrDesc.samples = static_cast(NumSamples); - CurrDesc.format = UEToVkFormat(ColorEntry.RenderTarget->GetFormat(), (Texture->Surface.UEFlags & TexCreate_SRGB) == TexCreate_SRGB); + CurrDesc.format = UEToVkTextureFormat(ColorEntry.RenderTarget->GetFormat(), (Texture->Surface.UEFlags & TexCreate_SRGB) == TexCreate_SRGB); CurrDesc.loadOp = RenderTargetLoadActionToVulkan(GetLoadAction(ColorEntry.Action)); bFoundClearOp = bFoundClearOp || (CurrDesc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR); CurrDesc.storeOp = RenderTargetStoreActionToVulkan(GetStoreAction(ColorEntry.Action), true); @@ -2068,7 +2071,7 @@ FVulkanRenderTargetLayout::FVulkanRenderTargetLayout(FVulkanDevice& InDevice, co CurrDesc.samples = static_cast(RPInfo.DepthStencilRenderTarget.DepthStencilTarget->GetNumSamples()); ensure(!NumSamples || CurrDesc.samples == NumSamples); NumSamples = CurrDesc.samples; - CurrDesc.format = UEToVkFormat(RPInfo.DepthStencilRenderTarget.DepthStencilTarget->GetFormat(), false); + CurrDesc.format = UEToVkTextureFormat(RPInfo.DepthStencilRenderTarget.DepthStencilTarget->GetFormat(), false); CurrDesc.loadOp = RenderTargetLoadActionToVulkan(GetLoadAction(GetDepthActions(RPInfo.DepthStencilRenderTarget.Action))); CurrDesc.stencilLoadOp = RenderTargetLoadActionToVulkan(GetLoadAction(GetStencilActions(RPInfo.DepthStencilRenderTarget.Action))); bFoundClearOp = bFoundClearOp || (CurrDesc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR || CurrDesc.stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR); @@ -2163,7 +2166,7 @@ FVulkanRenderTargetLayout::FVulkanRenderTargetLayout(const FGraphicsPipelineStat { VkAttachmentDescription& CurrDesc = Desc[NumAttachmentDescriptions]; CurrDesc.samples = static_cast(NumSamples); - CurrDesc.format = UEToVkFormat(UEFormat, (Initializer.RenderTargetFlags[Index] & TexCreate_SRGB) == TexCreate_SRGB); + CurrDesc.format = UEToVkTextureFormat(UEFormat, (Initializer.RenderTargetFlags[Index] & TexCreate_SRGB) == TexCreate_SRGB); CurrDesc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; CurrDesc.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; CurrDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; @@ -2204,7 +2207,7 @@ FVulkanRenderTargetLayout::FVulkanRenderTargetLayout(const FGraphicsPipelineStat FMemory::Memzero(CurrDesc); CurrDesc.samples = static_cast(NumSamples); - CurrDesc.format = UEToVkFormat(Initializer.DepthStencilTargetFormat, false); + CurrDesc.format = UEToVkTextureFormat(Initializer.DepthStencilTargetFormat, false); CurrDesc.loadOp = RenderTargetLoadActionToVulkan(Initializer.DepthTargetLoadAction); CurrDesc.stencilLoadOp = RenderTargetLoadActionToVulkan(Initializer.StencilTargetLoadAction); if (CurrDesc.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR || CurrDesc.stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) diff --git a/Engine/Source/Runtime/VulkanRHI/Private/VulkanState.cpp b/Engine/Source/Runtime/VulkanRHI/Private/VulkanState.cpp index fec94c9a6999..76bd358f4270 100644 --- a/Engine/Source/Runtime/VulkanRHI/Private/VulkanState.cpp +++ b/Engine/Source/Runtime/VulkanRHI/Private/VulkanState.cpp @@ -232,8 +232,13 @@ void FVulkanSamplerState::SetupSamplerCreateInfo(const FSamplerStateInitializerR OutSamplerInfo.addressModeW = TranslateWrapMode(Initializer.AddressW); OutSamplerInfo.mipLodBias = Initializer.MipBias; - OutSamplerInfo.maxAnisotropy = FMath::Clamp((float)ComputeAnisotropyRT(Initializer.MaxAnisotropy), 1.0f, InDevice.GetLimits().maxSamplerAnisotropy); - OutSamplerInfo.anisotropyEnable = OutSamplerInfo.maxAnisotropy > 1; + + OutSamplerInfo.maxAnisotropy = 1.0f; + if (Initializer.Filter != SF_Point) + { + OutSamplerInfo.maxAnisotropy = FMath::Clamp((float)ComputeAnisotropyRT(Initializer.MaxAnisotropy), 1.0f, InDevice.GetLimits().maxSamplerAnisotropy); + } + OutSamplerInfo.anisotropyEnable = OutSamplerInfo.maxAnisotropy > 1.0f; OutSamplerInfo.compareEnable = Initializer.SamplerComparisonFunction != SCF_Never ? VK_TRUE : VK_FALSE; OutSamplerInfo.compareOp = TranslateSamplerCompareFunction(Initializer.SamplerComparisonFunction); diff --git a/Engine/Source/Runtime/VulkanRHI/Private/VulkanSwapChain.cpp b/Engine/Source/Runtime/VulkanRHI/Private/VulkanSwapChain.cpp index 26ccf584c60c..019526b76ddb 100644 --- a/Engine/Source/Runtime/VulkanRHI/Private/VulkanSwapChain.cpp +++ b/Engine/Source/Runtime/VulkanRHI/Private/VulkanSwapChain.cpp @@ -204,7 +204,7 @@ FVulkanSwapChain::FVulkanSwapChain(VkInstance InInstance, FVulkanDevice& InDevic if (InOutPixelFormat == PF_Unknown) { UE_LOG(LogVulkanRHI, Warning, TEXT("Can't find a proper pixel format for the swapchain, trying to pick up the first available")); - VkFormat PlatformFormat = UEToVkFormat(InOutPixelFormat, false); + VkFormat PlatformFormat = UEToVkTextureFormat(InOutPixelFormat, false); bool bSupported = false; for (int32 Index = 0; Index < Formats.Num(); ++Index) { @@ -242,7 +242,7 @@ FVulkanSwapChain::FVulkanSwapChain(VkInstance InInstance, FVulkanDevice& InDevic } } - VkFormat PlatformFormat = UEToVkFormat(InOutPixelFormat, false); + VkFormat PlatformFormat = UEToVkTextureFormat(InOutPixelFormat, false); Device.SetupPresentQueue(Surface); @@ -431,6 +431,9 @@ FVulkanSwapChain::FVulkanSwapChain(VkInstance InInstance, FVulkanDevice& InDevic VERIFYVULKANRESULT_EXPANDED(VulkanRHI::vkCreateSwapchainKHR(Device.GetInstanceHandle(), &SwapChainInfo, VULKAN_CPU_ALLOCATOR, &SwapChain)); + InternalWidth = FMath::Min(Width, SwapChainInfo.imageExtent.width); + InternalHeight = FMath::Min(Height, SwapChainInfo.imageExtent.height); + uint32 NumSwapChainImages; VERIFYVULKANRESULT_EXPANDED(VulkanRHI::vkGetSwapchainImagesKHR(Device.GetInstanceHandle(), SwapChain, &NumSwapChainImages, nullptr)); diff --git a/Engine/Source/Runtime/VulkanRHI/Private/VulkanSwapChain.h b/Engine/Source/Runtime/VulkanRHI/Private/VulkanSwapChain.h index f383e6d7f116..b98af13c46df 100644 --- a/Engine/Source/Runtime/VulkanRHI/Private/VulkanSwapChain.h +++ b/Engine/Source/Runtime/VulkanRHI/Private/VulkanSwapChain.h @@ -43,6 +43,8 @@ protected: int32 SemaphoreIndex; uint32 NumPresentCalls; uint32 NumAcquireCalls; + uint32 InternalWidth = 0; + uint32 InternalHeight = 0; uint32 RTPacingSampleCount = 0; double RTPacingPreviousFrameCPUTime = 0; diff --git a/Engine/Source/Runtime/VulkanRHI/Private/VulkanTexture.cpp b/Engine/Source/Runtime/VulkanRHI/Private/VulkanTexture.cpp index cde34aed290c..13e3e948a11d 100644 --- a/Engine/Source/Runtime/VulkanRHI/Private/VulkanTexture.cpp +++ b/Engine/Source/Runtime/VulkanRHI/Private/VulkanTexture.cpp @@ -190,8 +190,10 @@ VkImage FVulkanSurface::CreateImage( bool bForceLinearTexture) { const VkPhysicalDeviceProperties& DeviceProperties = InDevice.GetDeviceProperties(); + const FPixelFormatInfo& FormatInfo = GPixelFormats[InFormat]; + VkFormat TextureFormat = (VkFormat)FormatInfo.PlatformFormat; - checkf(GPixelFormats[InFormat].Supported, TEXT("Format %d"), (int32)InFormat); + checkf(TextureFormat != VK_FORMAT_UNDEFINED, TEXT("PixelFormat %d, is not supported for images"), (int32)InFormat); VkImageCreateInfo TmpCreateInfo; VkImageCreateInfo* ImageCreateInfoPtr = OutInfo ? OutInfo : &TmpCreateInfo; @@ -226,7 +228,7 @@ VkImage FVulkanSurface::CreateImage( break; } - ImageCreateInfo.format = UEToVkFormat(InFormat, false); + ImageCreateInfo.format = UEToVkTextureFormat(InFormat, false); checkf(ImageCreateInfo.format != VK_FORMAT_UNDEFINED, TEXT("Pixel Format %d not defined!"), (int32)InFormat); if (OutStorageFormat) @@ -236,7 +238,7 @@ VkImage FVulkanSurface::CreateImage( if (OutViewFormat) { - VkFormat ViewFormat = UEToVkFormat(InFormat, (UEFlags & TexCreate_SRGB) == TexCreate_SRGB); + VkFormat ViewFormat = UEToVkTextureFormat(InFormat, (UEFlags & TexCreate_SRGB) == TexCreate_SRGB); *OutViewFormat = ViewFormat; ImageCreateInfo.format = ViewFormat; } @@ -590,6 +592,8 @@ FVulkanSurface::FVulkanSurface(FVulkanDevice& InDevice, VkImageViewType Resource { StorageFormat = (VkFormat)GPixelFormats[PixelFormat].PlatformFormat; check((UEFlags & TexCreate_SRGB) == 0); + checkf(PixelFormat == PF_Unknown || StorageFormat != VK_FORMAT_UNDEFINED, TEXT("PixelFormat %d, is not supported for images"), (int32)PixelFormat); + ViewFormat = StorageFormat; FullAspectMask = VulkanRHI::GetAspectMaskFromUEFormat(PixelFormat, true, true); PartialAspectMask = VulkanRHI::GetAspectMaskFromUEFormat(PixelFormat, false, true); @@ -1275,7 +1279,7 @@ void FVulkanDynamicRHI::InternalUpdateTexture2D(bool bFromRenderingThread, FText const int32 BlockSizeY = GPixelFormats[PixelFormat].BlockSizeY; const int32 BlockSizeZ = GPixelFormats[PixelFormat].BlockSizeZ; const int32 BlockBytes = GPixelFormats[PixelFormat].BlockBytes; - VkFormat Format = UEToVkFormat(PixelFormat, false); + VkFormat Format = UEToVkTextureFormat(PixelFormat, false); ensure(BlockSizeZ == 1); @@ -1350,7 +1354,7 @@ void FVulkanDynamicRHI::InternalUpdateTexture3D(bool bFromRenderingThread, FText const int32 BlockSizeY = GPixelFormats[PixelFormat].BlockSizeY; const int32 BlockSizeZ = GPixelFormats[PixelFormat].BlockSizeZ; const int32 BlockBytes = GPixelFormats[PixelFormat].BlockBytes; - const VkFormat Format = UEToVkFormat(PixelFormat, false); + const VkFormat Format = UEToVkTextureFormat(PixelFormat, false); ensure(BlockSizeZ == 1); @@ -1507,6 +1511,7 @@ VkImageView FVulkanTextureView::StaticCreate(FVulkanDevice& Device, VkImage InIm { ensure(ViewInfo.format == VK_FORMAT_UNDEFINED); ViewInfo.format = (VkFormat)GPixelFormats[PF_DepthStencil].PlatformFormat; + ensure(ViewInfo.format != VK_FORMAT_UNDEFINED); ViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; } @@ -1579,8 +1584,8 @@ FVulkanTextureBase::FVulkanTextureBase(FVulkanDevice& Device, VkImageViewType Re LLM_SCOPE_VULKAN(ELLMTagVulkan::VulkanTextures); if (Surface.ViewFormat == VK_FORMAT_UNDEFINED) { - Surface.StorageFormat = UEToVkFormat(InFormat, false); - Surface.ViewFormat = UEToVkFormat(InFormat, (UEFlags & TexCreate_SRGB) == TexCreate_SRGB); + Surface.StorageFormat = UEToVkTextureFormat(InFormat, false); + Surface.ViewFormat = UEToVkTextureFormat(InFormat, (UEFlags & TexCreate_SRGB) == TexCreate_SRGB); checkf(Surface.StorageFormat != VK_FORMAT_UNDEFINED, TEXT("Pixel Format %d not defined!"), (int32)InFormat); } diff --git a/Engine/Source/Runtime/VulkanRHI/Private/VulkanUAV.cpp b/Engine/Source/Runtime/VulkanRHI/Private/VulkanUAV.cpp index 7d9daa8b41bb..1b9741c12a23 100644 --- a/Engine/Source/Runtime/VulkanRHI/Private/VulkanUAV.cpp +++ b/Engine/Source/Runtime/VulkanRHI/Private/VulkanUAV.cpp @@ -102,22 +102,22 @@ void FVulkanShaderResourceView::UpdateView() { FVulkanTexture2D* VTex2D = ResourceCast(Tex2D); EPixelFormat OriginalFormat = Format; - TextureView.Create(*Device, VTex2D->Surface.Image, VK_IMAGE_VIEW_TYPE_2D, VTex2D->Surface.GetPartialAspectMask(), Format, UEToVkFormat(Format, false), MipLevel, NumMips, 0, 1); + TextureView.Create(*Device, VTex2D->Surface.Image, VK_IMAGE_VIEW_TYPE_2D, VTex2D->Surface.GetPartialAspectMask(), Format, UEToVkTextureFormat(Format, false), MipLevel, NumMips, 0, 1); } else if (FRHITextureCube* TexCube = SourceTexture->GetTextureCube()) { FVulkanTextureCube* VTexCube = ResourceCast(TexCube); - TextureView.Create(*Device, VTexCube->Surface.Image, VK_IMAGE_VIEW_TYPE_CUBE, VTexCube->Surface.GetPartialAspectMask(), Format, UEToVkFormat(Format, false), MipLevel, NumMips, 0, 1); + TextureView.Create(*Device, VTexCube->Surface.Image, VK_IMAGE_VIEW_TYPE_CUBE, VTexCube->Surface.GetPartialAspectMask(), Format, UEToVkTextureFormat(Format, false), MipLevel, NumMips, 0, 1); } else if (FRHITexture3D* Tex3D = SourceTexture->GetTexture3D()) { FVulkanTexture3D* VTex3D = ResourceCast(Tex3D); - TextureView.Create(*Device, VTex3D->Surface.Image, VK_IMAGE_VIEW_TYPE_3D, VTex3D->Surface.GetPartialAspectMask(), Format, UEToVkFormat(Format, false), MipLevel, NumMips, 0, 1); + TextureView.Create(*Device, VTex3D->Surface.Image, VK_IMAGE_VIEW_TYPE_3D, VTex3D->Surface.GetPartialAspectMask(), Format, UEToVkTextureFormat(Format, false), MipLevel, NumMips, 0, 1); } else if (FRHITexture2DArray* Tex2DArray = SourceTexture->GetTexture2DArray()) { FVulkanTexture2DArray* VTex2DArray = ResourceCast(Tex2DArray); - TextureView.Create(*Device, VTex2DArray->Surface.Image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VTex2DArray->Surface.GetPartialAspectMask(), Format, UEToVkFormat(Format, false), MipLevel, NumMips, 0, VTex2DArray->GetSizeZ()); + TextureView.Create(*Device, VTex2DArray->Surface.Image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VTex2DArray->Surface.GetPartialAspectMask(), Format, UEToVkTextureFormat(Format, false), MipLevel, NumMips, 0, VTex2DArray->GetSizeZ()); } else { @@ -189,22 +189,22 @@ void FVulkanUnorderedAccessView::UpdateView() if (FRHITexture2D* Tex2D = SourceTexture->GetTexture2D()) { FVulkanTexture2D* VTex2D = ResourceCast(Tex2D); - TextureView.Create(*Device, VTex2D->Surface.Image, VK_IMAGE_VIEW_TYPE_2D, VTex2D->Surface.GetPartialAspectMask(), Format, UEToVkFormat(Format, false), MipLevel, 1, 0, 1); + TextureView.Create(*Device, VTex2D->Surface.Image, VK_IMAGE_VIEW_TYPE_2D, VTex2D->Surface.GetPartialAspectMask(), Format, UEToVkTextureFormat(Format, false), MipLevel, 1, 0, 1); } else if (FRHITextureCube* TexCube = SourceTexture->GetTextureCube()) { FVulkanTextureCube* VTexCube = ResourceCast(TexCube); - TextureView.Create(*Device, VTexCube->Surface.Image, VK_IMAGE_VIEW_TYPE_CUBE, VTexCube->Surface.GetPartialAspectMask(), Format, UEToVkFormat(Format, false), MipLevel, 1, 0, 1); + TextureView.Create(*Device, VTexCube->Surface.Image, VK_IMAGE_VIEW_TYPE_CUBE, VTexCube->Surface.GetPartialAspectMask(), Format, UEToVkTextureFormat(Format, false), MipLevel, 1, 0, 1); } else if (FRHITexture3D* Tex3D = SourceTexture->GetTexture3D()) { FVulkanTexture3D* VTex3D = ResourceCast(Tex3D); - TextureView.Create(*Device, VTex3D->Surface.Image, VK_IMAGE_VIEW_TYPE_3D, VTex3D->Surface.GetPartialAspectMask(), Format, UEToVkFormat(Format, false), MipLevel, 1, 0, VTex3D->GetSizeZ()); + TextureView.Create(*Device, VTex3D->Surface.Image, VK_IMAGE_VIEW_TYPE_3D, VTex3D->Surface.GetPartialAspectMask(), Format, UEToVkTextureFormat(Format, false), MipLevel, 1, 0, VTex3D->GetSizeZ()); } else if (FRHITexture2DArray* Tex2DArray = SourceTexture->GetTexture2DArray()) { FVulkanTexture2DArray* VTex2DArray = ResourceCast(Tex2DArray); - TextureView.Create(*Device, VTex2DArray->Surface.Image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VTex2DArray->Surface.GetPartialAspectMask(), Format, UEToVkFormat(Format, false), MipLevel, 1, 0, VTex2DArray->GetSizeZ()); + TextureView.Create(*Device, VTex2DArray->Surface.Image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VTex2DArray->Surface.GetPartialAspectMask(), Format, UEToVkTextureFormat(Format, false), MipLevel, 1, 0, VTex2DArray->GetSizeZ()); } else { diff --git a/Engine/Source/Runtime/VulkanRHI/Private/VulkanVertexDeclaration.cpp b/Engine/Source/Runtime/VulkanRHI/Private/VulkanVertexDeclaration.cpp index 63608be61a61..07ceaa599f85 100644 --- a/Engine/Source/Runtime/VulkanRHI/Private/VulkanVertexDeclaration.cpp +++ b/Engine/Source/Runtime/VulkanRHI/Private/VulkanVertexDeclaration.cpp @@ -147,7 +147,7 @@ void FVulkanVertexInputStateInfo::Generate(FVulkanVertexDeclaration* VertexDecla CurrAttribute.binding = StreamToBinding.FindChecked(CurrElement.StreamIndex); CurrAttribute.location = CurrElement.AttributeIndex; - CurrAttribute.format = UEToVkFormat(CurrElement.Type); + CurrAttribute.format = UEToVkBufferFormat(CurrElement.Type); CurrAttribute.offset = CurrElement.Offset; } diff --git a/Engine/Source/Runtime/VulkanRHI/Private/VulkanViewport.cpp b/Engine/Source/Runtime/VulkanRHI/Private/VulkanViewport.cpp index f0d437248f0a..a4732578c2c8 100644 --- a/Engine/Source/Runtime/VulkanRHI/Private/VulkanViewport.cpp +++ b/Engine/Source/Runtime/VulkanRHI/Private/VulkanViewport.cpp @@ -619,7 +619,7 @@ void FVulkanViewport::CreateSwapchain() FName Name = FName(*FString::Printf(TEXT("BackBuffer%d"), Index)); //BackBuffers[Index]->SetName(Name); - TextureViews[Index].Create(*Device, Images[Index], VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, PixelFormat, UEToVkFormat(PixelFormat, false), 0, 1, 0, 1); + TextureViews[Index].Create(*Device, Images[Index], VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, PixelFormat, UEToVkTextureFormat(PixelFormat, false), 0, 1, 0, 1); // Clear the swapchain to avoid a validation warning, and transition to ColorAttachment { @@ -764,8 +764,8 @@ bool FVulkanViewport::Present(FVulkanCommandListContext* Context, FVulkanCmdBuff SCOPE_CYCLE_COUNTER(STAT_VulkanAcquireBackBuffer); GetNextImageIndex(); - uint32 WindowSizeX = SizeX; - uint32 WindowSizeY = SizeY; + uint32 WindowSizeX = FMath::Min(SizeX, SwapChain->InternalWidth); + uint32 WindowSizeY = FMath::Min(SizeY, SwapChain->InternalHeight); Context->RHIPushEvent(TEXT("CopyImageToBackBuffer"), FColor::Blue); CopyImageToBackBuffer(CmdBuffer, true, RenderingBackBuffer->Surface.Image, BackBufferImages[AcquiredImageIndex], SizeX, SizeY, WindowSizeX, WindowSizeY); diff --git a/Engine/Source/Runtime/VulkanRHI/Public/VulkanResources.h b/Engine/Source/Runtime/VulkanRHI/Public/VulkanResources.h index 07699c24d086..c1b967a4b118 100644 --- a/Engine/Source/Runtime/VulkanRHI/Public/VulkanResources.h +++ b/Engine/Source/Runtime/VulkanRHI/Public/VulkanResources.h @@ -52,6 +52,9 @@ struct FSamplerYcbcrConversionInitializer VkChromaLocation YOffset; }; +// Mirror GPixelFormats with format information for buffers +extern VkFormat GVulkanBufferFormat[PF_MAX]; + /** This represents a vertex declaration that hasn't been combined with a specific shader to create a bound shader. */ class FVulkanVertexDeclaration : public FRHIVertexDeclaration { diff --git a/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidJavaWebBrowser.cpp b/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidJavaWebBrowser.cpp index 0270f23573b9..8b434483fb43 100644 --- a/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidJavaWebBrowser.cpp +++ b/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidJavaWebBrowser.cpp @@ -50,14 +50,20 @@ FJavaAndroidWebBrowser::FJavaAndroidWebBrowser(bool swizzlePixels, bool vulkanRe JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); // get field IDs for FrameUpdateInfo class members - jclass localFrameUpdateInfoClass = FAndroidApplication::FindJavaClass("com/epicgames/ue4/WebViewControl$FrameUpdateInfo"); - FrameUpdateInfoClass = (jclass)JEnv->NewGlobalRef(localFrameUpdateInfoClass); - JEnv->DeleteLocalRef(localFrameUpdateInfoClass); + FrameUpdateInfoClass = FAndroidApplication::FindJavaClassGlobalRef("com/epicgames/ue4/WebViewControl$FrameUpdateInfo"); FrameUpdateInfo_Buffer = FindField(JEnv, FrameUpdateInfoClass, "Buffer", "Ljava/nio/Buffer;", false); FrameUpdateInfo_FrameReady = FindField(JEnv, FrameUpdateInfoClass, "FrameReady", "Z", false); FrameUpdateInfo_RegionChanged = FindField(JEnv, FrameUpdateInfoClass, "RegionChanged", "Z", false); } +FJavaAndroidWebBrowser::~FJavaAndroidWebBrowser() +{ + if (auto Env = FAndroidApplication::GetJavaEnv()) + { + Env->DeleteGlobalRef(FrameUpdateInfoClass); + } +} + void FJavaAndroidWebBrowser::Release() { CallMethod(ReleaseMethod); @@ -67,42 +73,32 @@ bool FJavaAndroidWebBrowser::GetVideoLastFrameData(void* & outPixels, int64 & ou { // This can return an exception in some cases JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); - jobject Result = JEnv->CallObjectMethod(Object, GetVideoLastFrameDataMethod.Method); + auto Result = NewScopedJavaObject(JEnv, JEnv->CallObjectMethod(Object, GetVideoLastFrameDataMethod.Method)); if (JEnv->ExceptionCheck()) { JEnv->ExceptionDescribe(); JEnv->ExceptionClear(); - if (nullptr != Result) - { - JEnv->DeleteLocalRef(Result); - } *bRegionChanged = false; return false; } - if (nullptr == Result) + if (!Result) { return false; } - jobject buffer = JEnv->GetObjectField(Result, FrameUpdateInfo_Buffer); - if (nullptr != buffer) + auto buffer = NewScopedJavaObject(JEnv, JEnv->GetObjectField(*Result, FrameUpdateInfo_Buffer)); + if (buffer) { - bool bFrameReady = (bool)JEnv->GetBooleanField(Result, FrameUpdateInfo_FrameReady); - *bRegionChanged = (bool)JEnv->GetBooleanField(Result, FrameUpdateInfo_RegionChanged); + bool bFrameReady = (bool)JEnv->GetBooleanField(*Result, FrameUpdateInfo_FrameReady); + *bRegionChanged = (bool)JEnv->GetBooleanField(*Result, FrameUpdateInfo_RegionChanged); + + outPixels = JEnv->GetDirectBufferAddress(*buffer); + outCount = JEnv->GetDirectBufferCapacity(*buffer); - outPixels = JEnv->GetDirectBufferAddress(buffer); - outCount = JEnv->GetDirectBufferCapacity(buffer); - - // the GetObjectField returns a local ref, but Java will still own the real buffer - JEnv->DeleteLocalRef(buffer); - - JEnv->DeleteLocalRef(Result); - return !(nullptr == outPixels || 0 == outCount); } - - JEnv->DeleteLocalRef(Result); + return false; } @@ -115,30 +111,24 @@ bool FJavaAndroidWebBrowser::UpdateVideoFrame(int32 ExternalTextureId, bool *bRe { // This can return an exception in some cases JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); - jobject Result = JEnv->CallObjectMethod(Object, UpdateVideoFrameMethod.Method, ExternalTextureId); + auto Result = NewScopedJavaObject(JEnv, JEnv->CallObjectMethod(Object, UpdateVideoFrameMethod.Method, ExternalTextureId)); if (JEnv->ExceptionCheck()) { JEnv->ExceptionDescribe(); JEnv->ExceptionClear(); - if (nullptr != Result) - { - JEnv->DeleteLocalRef(Result); - } *bRegionChanged = false; return false; } - if (nullptr == Result) + if (!Result) { *bRegionChanged = false; return false; } - bool bFrameReady = (bool)JEnv->GetBooleanField(Result, FrameUpdateInfo_FrameReady); - *bRegionChanged = (bool)JEnv->GetBooleanField(Result, FrameUpdateInfo_RegionChanged); + bool bFrameReady = (bool)JEnv->GetBooleanField(*Result, FrameUpdateInfo_FrameReady); + *bRegionChanged = (bool)JEnv->GetBooleanField(*Result, FrameUpdateInfo_RegionChanged); - JEnv->DeleteLocalRef(Result); - return bFrameReady; } @@ -146,7 +136,7 @@ bool FJavaAndroidWebBrowser::GetVideoLastFrame(int32 destTexture) { // This can return an exception in some cases JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); - jobject Result = JEnv->CallObjectMethod(Object, GetVideoLastFrameMethod.Method, destTexture); + auto Result = NewScopedJavaObject(JEnv, JEnv->CallObjectMethod(Object, GetVideoLastFrameMethod.Method, destTexture)); if (JEnv->ExceptionCheck()) { JEnv->ExceptionDescribe(); @@ -154,15 +144,13 @@ bool FJavaAndroidWebBrowser::GetVideoLastFrame(int32 destTexture) return false; } - if (nullptr == Result) + if (!Result) { return false; } - bool bFrameReady = (bool)JEnv->GetBooleanField(Result, FrameUpdateInfo_FrameReady); + bool bFrameReady = (bool)JEnv->GetBooleanField(*Result, FrameUpdateInfo_FrameReady); - JEnv->DeleteLocalRef(Result); - return bFrameReady; } @@ -178,17 +166,21 @@ void FJavaAndroidWebBrowser::Update(const int posX, const int posY, const int si void FJavaAndroidWebBrowser::ExecuteJavascript(const FString& Script) { - CallMethod(ExecuteJavascriptMethod, FJavaClassObject::GetJString(Script)); + auto JString = FJavaClassObject::GetJString(Script); + CallMethod(ExecuteJavascriptMethod, *JString); } void FJavaAndroidWebBrowser::LoadURL(const FString& NewURL) { - CallMethod(LoadURLMethod, FJavaClassObject::GetJString(NewURL)); + auto JString = FJavaClassObject::GetJString(NewURL); + CallMethod(LoadURLMethod, *JString); } void FJavaAndroidWebBrowser::LoadString(const FString& Contents, const FString& BaseUrl) { - CallMethod(LoadStringMethod, FJavaClassObject::GetJString(Contents), FJavaClassObject::GetJString(BaseUrl)); + auto JContents = FJavaClassObject::GetJString(Contents); + auto JUrl = FJavaClassObject::GetJString(BaseUrl); + CallMethod(LoadStringMethod, *JContents, *JUrl); } void FJavaAndroidWebBrowser::StopLoad() diff --git a/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidJavaWebBrowser.h b/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidJavaWebBrowser.h index d802be55fe00..d8d80aa9d30b 100644 --- a/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidJavaWebBrowser.h +++ b/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidJavaWebBrowser.h @@ -16,6 +16,7 @@ class FJavaAndroidWebBrowser : public FJavaClassObject { public: FJavaAndroidWebBrowser(bool swizzlePixels, bool vulkanRenderer, int32 width, int32 height, jlong widgetPtr, bool bEnableRemoteDebugging, bool bUseTransparency); + virtual ~FJavaAndroidWebBrowser(); void Release(); bool GetVideoLastFrameData(void* & outPixels, int64 & outCount, bool *bRegionChanged); bool GetVideoLastFrame(int32 destTexture); @@ -85,4 +86,4 @@ public: }; -#endif // USE_ANDROID_JNI \ No newline at end of file +#endif // USE_ANDROID_JNI diff --git a/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidWebBrowserDialog.cpp b/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidWebBrowserDialog.cpp index 265db050012e..3f3281f775fa 100644 --- a/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidWebBrowserDialog.cpp +++ b/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidWebBrowserDialog.cpp @@ -19,9 +19,8 @@ namespace } JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); - const char* Chars = JEnv->GetStringUTFChars(InString, 0); - FText Retval = FText::FromString(UTF8_TO_TCHAR(Chars)); - JEnv->ReleaseStringUTFChars(InString, Chars); + FString Temp = FJavaHelper::FStringFromParam(JEnv, InString); + FText Retval = FText::FromString(Temp); return Retval; } } @@ -48,15 +47,18 @@ void FAndroidWebBrowserDialog::Continue(bool Success, const FText& UserResponse) JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); const char* MethodName = Success?"confirm":"cancel"; const char* MethodSignature = (Success && Type==EWebBrowserDialogType::Prompt)?"(Ljava/lang/String;)V":"()V"; - jclass Class = JEnv->GetObjectClass(Callback); - jmethodID MethodId = JEnv->GetMethodID(Class, MethodName, MethodSignature); + auto Class = NewScopedJavaObject(JEnv, JEnv->GetObjectClass(Callback)); + jmethodID MethodId = JEnv->GetMethodID(*Class, MethodName, MethodSignature); - jstring JUserResponse = nullptr; if (Success && Type==EWebBrowserDialogType::Prompt) { - JUserResponse = FJavaClassObject::GetJString(UserResponse.ToString()); + auto JUserResponse = FJavaClassObject::GetJString(UserResponse.ToString()); + JEnv->CallVoidMethod(Callback, MethodId, *JUserResponse); + } + else + { + JEnv->CallVoidMethod(Callback, MethodId, nullptr); } - JEnv->CallVoidMethod(Callback, MethodId, JUserResponse); } -#endif // USE_ANDROID_JNI \ No newline at end of file +#endif // USE_ANDROID_JNI diff --git a/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidWebBrowserWidget.cpp b/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidWebBrowserWidget.cpp index 00b916309007..b6cf3081d81c 100644 --- a/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidWebBrowserWidget.cpp +++ b/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidWebBrowserWidget.cpp @@ -35,8 +35,8 @@ TSharedPtr SAndroidWebBrowserWidget::GetWidgetPtr(JNIE { FScopeLock L(&WebControlsCS); - jclass Class = JEnv->GetObjectClass(Jobj); - jmethodID JMethod = JEnv->GetMethodID(Class, "GetNativePtr", "()J"); + auto Class = NewScopedJavaObject(JEnv, JEnv->GetObjectClass(Jobj)); + jmethodID JMethod = JEnv->GetMethodID(*Class, "GetNativePtr", "()J"); check(JMethod != nullptr); int64 ObjAddr = JEnv->CallLongMethod(Jobj, JMethod); @@ -478,9 +478,7 @@ jbyteArray SAndroidWebBrowserWidget::HandleShouldInterceptRequest(jstring JUrl) { JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); - const char* JUrlChars = JEnv->GetStringUTFChars(JUrl, 0); - FString Url = UTF8_TO_TCHAR(JUrlChars); - JEnv->ReleaseStringUTFChars(JUrl, JUrlChars); + FString Url = FJavaHelper::FStringFromParam(JEnv, JUrl); FString Response; bool bOverrideResponse = false; @@ -546,9 +544,7 @@ bool SAndroidWebBrowserWidget::HandleShouldOverrideUrlLoading(jstring JUrl) { JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); - const char* JUrlChars = JEnv->GetStringUTFChars(JUrl, 0); - FString Url = UTF8_TO_TCHAR(JUrlChars); - JEnv->ReleaseStringUTFChars(JUrl, JUrlChars); + FString Url = FJavaHelper::FStringFromParam(JEnv, JUrl); bool Retval = false; if (WebBrowserWindowPtr.IsValid()) @@ -605,9 +601,7 @@ void SAndroidWebBrowserWidget::HandleReceivedTitle(jstring JTitle) { JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); - const char* JTitleChars = JEnv->GetStringUTFChars(JTitle, 0); - FString Title = UTF8_TO_TCHAR(JTitleChars); - JEnv->ReleaseStringUTFChars(JTitle, JTitleChars); + FString Title = FJavaHelper::FStringFromParam(JEnv, JTitle); if (WebBrowserWindowPtr.IsValid()) { @@ -626,9 +620,7 @@ void SAndroidWebBrowserWidget::HandlePageLoad(jstring JUrl, bool bIsLoading, int JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); - const char* JUrlChars = JEnv->GetStringUTFChars(JUrl, 0); - FString Url = UTF8_TO_TCHAR(JUrlChars); - JEnv->ReleaseStringUTFChars(JUrl, JUrlChars); + FString Url = FJavaHelper::FStringFromParam(JEnv, JUrl); if (WebBrowserWindowPtr.IsValid()) { TSharedPtr BrowserWindow = WebBrowserWindowPtr.Pin(); @@ -643,9 +635,7 @@ void SAndroidWebBrowserWidget::HandleReceivedError(jint ErrorCode, jstring /* ig { JNIEnv* JEnv = FAndroidApplication::GetJavaEnv(); - const char* JUrlChars = JEnv->GetStringUTFChars(JUrl, 0); - FString Url = UTF8_TO_TCHAR(JUrlChars); - JEnv->ReleaseStringUTFChars(JUrl, JUrlChars); + FString Url = FJavaHelper::FStringFromParam(JEnv, JUrl); if (WebBrowserWindowPtr.IsValid()) { TSharedPtr BrowserWindow = WebBrowserWindowPtr.Pin(); @@ -763,4 +753,4 @@ JNI_METHOD void Java_com_epicgames_ue4_WebViewControl_00024ChromeClient_onReceiv } } -#endif // USE_ANDROID_JNI \ No newline at end of file +#endif // USE_ANDROID_JNI diff --git a/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidWebBrowserWindow.h b/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidWebBrowserWindow.h index fc65e7c5b525..773e15bec06f 100644 --- a/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidWebBrowserWindow.h +++ b/Engine/Source/Runtime/WebBrowser/Private/Android/AndroidWebBrowserWindow.h @@ -184,6 +184,21 @@ public: { return DragWindowDelegate; } + + virtual FOnUnhandledKeyDown& OnUnhandledKeyDown() override + { + return UnhandledKeyDownDelegate; + } + + virtual FOnUnhandledKeyUp& OnUnhandledKeyUp() override + { + return UnhandledKeyUpDelegate; + } + + virtual FOnUnhandledKeyChar& OnUnhandledKeyChar() override + { + return UnhandledKeyCharDelegate; + } public: @@ -273,6 +288,15 @@ private: /** Delegate for suppressing context menu */ FOnSuppressContextMenu SuppressContextMenuDelgate; + + /** Delegate for handling key down events not handled by the browser. */ + FOnUnhandledKeyDown UnhandledKeyDownDelegate; + + /** Delegate for handling key up events not handled by the browser. */ + FOnUnhandledKeyUp UnhandledKeyUpDelegate; + + /** Delegate for handling key char events not handled by the browser. */ + FOnUnhandledKeyChar UnhandledKeyCharDelegate; /** Delegate that is executed when a drag event is detected in an area of the web page tagged as a drag region. */ FOnDragWindow DragWindowDelegate; diff --git a/Engine/Source/Runtime/WebBrowser/Private/CEF/CEFWebBrowserWindow.cpp b/Engine/Source/Runtime/WebBrowser/Private/CEF/CEFWebBrowserWindow.cpp index 5152aa1746a6..6e5e3f2c821a 100644 --- a/Engine/Source/Runtime/WebBrowser/Private/CEF/CEFWebBrowserWindow.cpp +++ b/Engine/Source/Runtime/WebBrowser/Private/CEF/CEFWebBrowserWindow.cpp @@ -1081,28 +1081,43 @@ bool FCEFWebBrowserWindow::OnUnhandledKeyEvent(const CefKeyEvent& CefEvent) case KEYEVENT_KEYDOWN: if (PreviousKeyDownEvent.IsSet()) { - bIgnoreKeyDownEvent = true; - bWasHandled = FSlateApplication::Get().ProcessKeyDownEvent(PreviousKeyDownEvent.GetValue()); + bWasHandled = OnUnhandledKeyDown().IsBound() && OnUnhandledKeyDown().Execute(PreviousKeyDownEvent.GetValue()); + if (!bWasHandled) + { + // If the keydown handler is not bound or if the handler returns false, indicating the key is unhandled, we bubble it up. + bIgnoreKeyDownEvent = true; + bWasHandled = FSlateApplication::Get().ProcessKeyDownEvent(PreviousKeyDownEvent.GetValue()); + bIgnoreKeyDownEvent = false; + } PreviousKeyDownEvent.Reset(); - bIgnoreKeyDownEvent = false; } break; case KEYEVENT_KEYUP: if (PreviousKeyUpEvent.IsSet()) { - bIgnoreKeyUpEvent = true; - bWasHandled = FSlateApplication::Get().ProcessKeyUpEvent(PreviousKeyUpEvent.GetValue()); + bWasHandled = OnUnhandledKeyUp().IsBound() && OnUnhandledKeyUp().Execute(PreviousKeyUpEvent.GetValue()); + if (!bWasHandled) + { + // If the keyup handler is not bound or if the handler returns false, indicating the key is unhandled, we bubble it up. + bIgnoreKeyUpEvent = true; + bWasHandled = FSlateApplication::Get().ProcessKeyUpEvent(PreviousKeyUpEvent.GetValue()); + bIgnoreKeyUpEvent = false; + } PreviousKeyUpEvent.Reset(); - bIgnoreKeyUpEvent = false; } break; case KEYEVENT_CHAR: if (PreviousCharacterEvent.IsSet()) { - bIgnoreCharacterEvent = true; - bWasHandled = FSlateApplication::Get().ProcessKeyCharEvent(PreviousCharacterEvent.GetValue()); + bWasHandled = OnUnhandledKeyChar().IsBound() && OnUnhandledKeyChar().Execute(PreviousCharacterEvent.GetValue()); + if (!bWasHandled) + { + // If the keychar handler is not bound or if the handler returns false, indicating the key is unhandled, we bubble it up. + bIgnoreCharacterEvent = true; + bWasHandled = FSlateApplication::Get().ProcessKeyCharEvent(PreviousCharacterEvent.GetValue()); + bIgnoreCharacterEvent = false; + } PreviousCharacterEvent.Reset(); - bIgnoreCharacterEvent = false; } break; default: diff --git a/Engine/Source/Runtime/WebBrowser/Private/CEF/CEFWebBrowserWindow.h b/Engine/Source/Runtime/WebBrowser/Private/CEF/CEFWebBrowserWindow.h index f0422c8b8f7b..580cae15d565 100644 --- a/Engine/Source/Runtime/WebBrowser/Private/CEF/CEFWebBrowserWindow.h +++ b/Engine/Source/Runtime/WebBrowser/Private/CEF/CEFWebBrowserWindow.h @@ -270,6 +270,21 @@ public: { return DragWindowDelegate; } + + virtual FOnUnhandledKeyDown& OnUnhandledKeyDown() override + { + return UnhandledKeyDownDelegate; + } + + virtual FOnUnhandledKeyUp& OnUnhandledKeyUp() override + { + return UnhandledKeyUpDelegate; + } + + virtual FOnUnhandledKeyChar& OnUnhandledKeyChar() override + { + return UnhandledKeyCharDelegate; + } private: @@ -618,6 +633,15 @@ private: /** Delegate that is executed when a drag event is detected in an area of the web page tagged as a drag region. */ FOnDragWindow DragWindowDelegate; + + /** Delegate for handling key down events not handled by the browser. */ + FOnUnhandledKeyDown UnhandledKeyDownDelegate; + + /** Delegate for handling key up events not handled by the browser. */ + FOnUnhandledKeyUp UnhandledKeyUpDelegate; + + /** Delegate for handling key char events not handled by the browser. */ + FOnUnhandledKeyChar UnhandledKeyCharDelegate; /** Tracks the current mouse cursor */ EMouseCursor::Type Cursor; diff --git a/Engine/Source/Runtime/WebBrowser/Private/IOS/IOSPlatformWebBrowser.h b/Engine/Source/Runtime/WebBrowser/Private/IOS/IOSPlatformWebBrowser.h index 93dd6804e7d6..61c025af4a14 100644 --- a/Engine/Source/Runtime/WebBrowser/Private/IOS/IOSPlatformWebBrowser.h +++ b/Engine/Source/Runtime/WebBrowser/Private/IOS/IOSPlatformWebBrowser.h @@ -254,6 +254,21 @@ public: bool OnJsMessageReceived(const FString& Command, const TArray& Params, const FString& Origin); + virtual FOnUnhandledKeyDown& OnUnhandledKeyDown() override + { + return UnhandledKeyDownDelegate; + } + + virtual FOnUnhandledKeyUp& OnUnhandledKeyUp() override + { + return UnhandledKeyUpDelegate; + } + + virtual FOnUnhandledKeyChar& OnUnhandledKeyChar() override + { + return UnhandledKeyCharDelegate; + } + void NotifyUrlChanged(const FString& InCurrentUrl); public: /** @@ -350,6 +365,14 @@ private: FMobileJSScriptingPtr Scripting; mutable TOptional> GetPageSourceCallback; + /** Delegate for handling key down events not handled by the browser. */ + FOnUnhandledKeyDown UnhandledKeyDownDelegate; + + /** Delegate for handling key up events not handled by the browser. */ + FOnUnhandledKeyUp UnhandledKeyUpDelegate; + + /** Delegate for handling key char events not handled by the browser. */ + FOnUnhandledKeyChar UnhandledKeyCharDelegate; TSharedPtr ParentWindow; diff --git a/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSScripting.cpp b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSScripting.cpp new file mode 100644 index 000000000000..3ed0142afced --- /dev/null +++ b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSScripting.cpp @@ -0,0 +1,655 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "NativeJSScripting.h" + + +#include "NativeJSStructSerializerBackend.h" +#include "NativeJSStructDeserializerBackend.h" +#include "StructSerializer.h" +#include "StructDeserializer.h" +#include "UObject/UnrealType.h" +#include "NativeWebBrowserProxy.h" + +namespace NativeFuncs +{ + const FString ExecuteMethodCommand = TEXT("ExecuteUObjectMethod"); + + typedef TSharedRef> FJsonWriterRef; + + template void WriteValue(FJsonWriterRef Writer, const FString& Key, const ValueType& Value) + { + Writer->WriteValue(Key, Value); + } + void WriteNull(FJsonWriterRef Writer, const FString& Key) + { + Writer->WriteNull(Key); + } + void WriteArrayStart(FJsonWriterRef Writer, const FString& Key) + { + Writer->WriteArrayStart(Key); + } + void WriteObjectStart(FJsonWriterRef Writer, const FString& Key) + { + Writer->WriteObjectStart(Key); + } + void WriteRaw(FJsonWriterRef Writer, const FString& Key, const FString& Value) + { + Writer->WriteRawJSONValue(Key, Value); + } + template void WriteValue(FJsonWriterRef Writer, const int, const ValueType& Value) + { + Writer->WriteValue(Value); + } + void WriteNull(FJsonWriterRef Writer, int) + { + Writer->WriteNull(); + } + void WriteArrayStart(FJsonWriterRef Writer, int) + { + Writer->WriteArrayStart(); + } + void WriteObjectStart(FJsonWriterRef Writer, int) + { + Writer->WriteObjectStart(); + } + void WriteRaw(FJsonWriterRef Writer, int, const FString& Value) + { + Writer->WriteRawJSONValue(Value); + } + + template + bool WriteJsParam(FNativeJSScriptingRef Scripting, FJsonWriterRef Writer, const KeyType& Key, FWebJSParam& Param) + { + switch (Param.Tag) + { + case FWebJSParam::PTYPE_NULL: + WriteNull(Writer, Key); + break; + case FWebJSParam::PTYPE_BOOL: + WriteValue(Writer, Key, Param.BoolValue); + break; + case FWebJSParam::PTYPE_DOUBLE: + WriteValue(Writer, Key, Param.DoubleValue); + break; + case FWebJSParam::PTYPE_INT: + WriteValue(Writer, Key, Param.IntValue); + break; + case FWebJSParam::PTYPE_STRING: + WriteValue(Writer, Key, *Param.StringValue); + break; + case FWebJSParam::PTYPE_OBJECT: + { + if (Param.ObjectValue == nullptr) + { + WriteNull(Writer, Key); + } + else + { + FString ConvertedObject = Scripting->ConvertObject(Param.ObjectValue); + WriteRaw(Writer, Key, ConvertedObject); + } + break; + } + case FWebJSParam::PTYPE_STRUCT: + { + FString ConvertedStruct = Scripting->ConvertStruct(Param.StructValue->GetTypeInfo(), Param.StructValue->GetData()); + WriteRaw(Writer, Key, ConvertedStruct); + break; + } + case FWebJSParam::PTYPE_ARRAY: + { + WriteArrayStart(Writer, Key); + for(int i=0; i < Param.ArrayValue->Num(); ++i) + { + WriteJsParam(Scripting, Writer, i, (*Param.ArrayValue)[i]); + } + Writer->WriteArrayEnd(); + break; + } + case FWebJSParam::PTYPE_MAP: + { + WriteObjectStart(Writer, Key); + for(auto& Pair : *Param.MapValue) + { + WriteJsParam(Scripting, Writer, *Pair.Key, Pair.Value); + } + Writer->WriteObjectEnd(); + break; + } + default: + return false; + } + return true; + } +} + + +FString GetObjectPostInitScript(const FString& Name, const FString& FullyQualifiedName) +{ + return FString::Printf(TEXT("(function(){document.dispatchEvent(new CustomEvent('%s:ready', {details: %s}));})();"), *Name, *FullyQualifiedName); +} + +void FNativeJSScripting::BindUObject(const FString& Name, UObject* Object, bool bIsPermanent ) +{ + const FString ExposedName = GetBindingName(Name, Object); + + FString Converted = ConvertObject(Object); + if (bIsPermanent) + { + // Existing permanent objects must be removed first and each object can only have one permanent binding + if (PermanentUObjectsByName.Contains(ExposedName) || BoundObjects[Object].bIsPermanent) + { + return; + } + + BoundObjects[Object]={true, -1}; + PermanentUObjectsByName.Add(ExposedName, Object); + } + + if(!bLoaded) + { + PageLoaded(); + } + else + { + const FString& EscapedName = ExposedName.ReplaceCharWithEscapedChar(); + FString SetValueScript = FString::Printf(TEXT("window.ue['%s'] = %s;"), *EscapedName, *Converted); + SetValueScript.Append(GetObjectPostInitScript(EscapedName, FString::Printf(TEXT("window.ue['%s']"), *EscapedName))); + ExecuteJavascript(SetValueScript); + } +} + +void FNativeJSScripting::ExecuteJavascript(const FString& Javascript) +{ + TSharedPtr Window = WindowPtr.Pin(); + if (Window.IsValid()) + { + Window->ExecuteJavascript(Javascript); + } +} + +void FNativeJSScripting::UnbindUObject(const FString& Name, UObject* Object, bool bIsPermanent) +{ + const FString ExposedName = GetBindingName(Name, Object); + if (bIsPermanent) + { + // If overriding an existing permanent object, make it non-permanent + if (PermanentUObjectsByName.Contains(ExposedName) && (Object == nullptr || PermanentUObjectsByName[ExposedName] == Object)) + { + Object = PermanentUObjectsByName.FindAndRemoveChecked(ExposedName); + BoundObjects.Remove(Object); + return; + } + else + { + return; + } + } + + FString DeleteValueScript = FString::Printf(TEXT("delete window.ue['%s'];"), *ExposedName.ReplaceCharWithEscapedChar()); + ExecuteJavascript(DeleteValueScript); +} + +int32 ParseParams(const FString& ParamStr, TArray& OutArray) +{ + OutArray.Reset(); + const TCHAR *Start = *ParamStr; + if (Start && *Start != TEXT('\0')) + { + int32 DelimLimit = 4; + while (const TCHAR *At = FCString::Strstr(Start, TEXT("/"))) + { + OutArray.Emplace(At - Start, Start); + Start = At + 1; + if (--DelimLimit == 0) + { + break; + } + } + if (*Start) + { + OutArray.Emplace(Start); + } + } + return OutArray.Num(); +} + +bool FNativeJSScripting::OnJsMessageReceived(const FString& Message) +{ + check(IsInGameThread()); + + bool Result = false; + TArray Params; + if (ParseParams(Message, Params)) + { + FString Command = Params[0]; + Params.RemoveAt(0, 1); + + if (Command == NativeFuncs::ExecuteMethodCommand) + { + Result = HandleExecuteUObjectMethodMessage(Params); + } + } + return Result; +} + +FString FNativeJSScripting::ConvertStruct(UStruct* TypeInfo, const void* StructPtr) +{ + TArray ReturnBuffer; + FMemoryWriter Writer(ReturnBuffer); + + FNativeJSStructSerializerBackend ReturnBackend = FNativeJSStructSerializerBackend(SharedThis(this), Writer); + FStructSerializer::Serialize(StructPtr, *TypeInfo, ReturnBackend); + + // Extract the result value from the serialized JSON object: + ReturnBuffer.Add(0); + ReturnBuffer.Add(0); + auto CastObject = StringCast((UCS2CHAR*)ReturnBuffer.GetData()); + FString ResultJS = FString(CastObject.Get(), CastObject.Length()); + return ResultJS; +} + +FString FNativeJSScripting::ConvertObject(UObject* Object) +{ + RetainBinding(Object); + UClass* Class = Object->GetClass(); + + bool first = true; + FString Result = TEXT("(function(){ return Object.create({"); + for (TFieldIterator FunctionIt(Class, EFieldIteratorFlags::IncludeSuper); FunctionIt; ++FunctionIt) + { + UFunction* Function = *FunctionIt; + if(!first) + { + Result.Append(TEXT(",")); + } + else + { + first = false; + } + Result.Append(*GetBindingName(Function)); + Result.Append(TEXT(": function ")); + Result.Append(*GetBindingName(Function)); + Result.Append(TEXT(" (")); + + bool firstArg = true; + for ( TFieldIterator It(Function); It; ++It ) + { + UProperty* Param = *It; + if (Param->PropertyFlags & CPF_Parm && ! (Param->PropertyFlags & CPF_ReturnParm) ) + { + UStructProperty *StructProperty = Cast(Param); + if (!StructProperty || !StructProperty->Struct->IsChildOf(FWebJSResponse::StaticStruct())) + { + if(!firstArg) + { + Result.Append(TEXT(", ")); + } + else + { + firstArg = false; + } + Result.Append(*GetBindingName(Param)); + } + } + } + + Result.Append(TEXT(")")); + + // We hijack the RPCResponseId and use it for our priority value. 0 means it has not been assigned and we default to 2. 1-5 is high-low priority which we map to the 0-4 range used by EmbeddedCommunication. + int32 Priority = Function->RPCResponseId == 0 ? 2 : FMath::Clamp((int32)Function->RPCResponseId, 1, 5) - 1; + + Result.Append(TEXT(" {return window.ue.$.executeMethod('")); + Result.Append(FString::FromInt(Priority)); + Result.Append(TEXT("',this.$id, arguments)}")); + } + Result.Append(TEXT("},{")); + Result.Append(TEXT("$id: {writable: false, configurable:false, enumerable: false, value: '")); + Result.Append(*PtrToGuid(Object).ToString(EGuidFormats::Digits)); + Result.Append(TEXT("'}})})()")); + return Result; +} + +void FNativeJSScripting::InvokeJSFunction(FGuid FunctionId, int32 ArgCount, FWebJSParam Arguments[], bool bIsError) +{ + if (!IsValid()) + { + return; + } + + FString CallbackScript = FString::Printf(TEXT("window.ue.$.invokeCallback('%s', %s, "), *FunctionId.ToString(EGuidFormats::Digits), (bIsError) ? TEXT("true") : TEXT("false")); + { + TArray Buffer; + FMemoryWriter MemoryWriter(Buffer); + NativeFuncs::FJsonWriterRef JsonWriter = TJsonWriter<>::Create(&MemoryWriter); + JsonWriter->WriteArrayStart(); + for (int i = 0; i < ArgCount; i++) + { + NativeFuncs::WriteJsParam(SharedThis(this), JsonWriter, i, Arguments[i]); + } + JsonWriter->WriteArrayEnd(); + CallbackScript.Append((TCHAR*)Buffer.GetData(), Buffer.Num() / sizeof(TCHAR)); + } + CallbackScript.Append(TEXT(")")); + + ExecuteJavascript(CallbackScript); + +} + +void FNativeJSScripting::InvokeJSFunctionRaw(FGuid FunctionId, const FString& RawJSValue, bool bIsError) +{ + if (!IsValid()) + { + return; + } + + FString CallbackScript = FString::Printf(TEXT("window.ue.$.invokeCallback('%s', %s, [%s])"), + *FunctionId.ToString(EGuidFormats::Digits), (bIsError)?TEXT("true"):TEXT("false"), *RawJSValue); + ExecuteJavascript(CallbackScript); +} + +void FNativeJSScripting::InvokeJSErrorResult(FGuid FunctionId, const FString& Error) +{ + FWebJSParam Args[1] = {FWebJSParam(Error)}; + InvokeJSFunction(FunctionId, 1, Args, true); +} + +bool FNativeJSScripting::HandleExecuteUObjectMethodMessage(const TArray& MessageArgs) +{ + if (MessageArgs.Num() != 4) + { + return false; + } + + const FString& ObjectIdStr = MessageArgs[0]; + FGuid ObjectKey; + UObject* Object = nullptr; + if (FGuid::Parse(ObjectIdStr, ObjectKey)) + { + Object = GuidToPtr(ObjectKey); + } + else if(PermanentUObjectsByName.Contains(ObjectIdStr)) + { + Object = PermanentUObjectsByName[ObjectIdStr]; + } + + if(Object == nullptr) + { + // Unknown uobject id/name + return false; + } + + // Get the promise callback and use that to report any results from executing this function. + FGuid ResultCallbackId; + if (!FGuid::Parse(MessageArgs[1], ResultCallbackId)) + { + // Invalid GUID + return false; + } + + FName MethodName = FName(*MessageArgs[2]); + UFunction* Function = Object->FindFunction(MethodName); + if (!Function) + { + InvokeJSErrorResult(ResultCallbackId, TEXT("Unknown UObject Function")); + return true; + } + + // Coerce arguments to function arguments. + uint16 ParamsSize = Function->ParmsSize; + TArray Params; + UProperty* ReturnParam = nullptr; + UProperty* PromiseParam = nullptr; + + if (ParamsSize > 0) + { + // Find return parameter and a promise argument if present, as we need to handle them differently + for ( TFieldIterator It(Function); It; ++It ) + { + UProperty* Param = *It; + if (Param->PropertyFlags & CPF_Parm) + { + if (Param->PropertyFlags & CPF_ReturnParm) + { + ReturnParam = Param; + } + else + { + UStructProperty *StructProperty = Cast(Param); + if (StructProperty && StructProperty->Struct->IsChildOf(FWebJSResponse::StaticStruct())) + { + PromiseParam = Param; + } + } + if (ReturnParam && PromiseParam) + { + break; + } + } + } + + // UFunction is a subclass of UStruct, so we can treat the arguments as a struct for deserialization + Params.AddUninitialized(ParamsSize); + Function->InitializeStruct(Params.GetData()); + + TArray JsonData; + auto Convert = StringCast(*MessageArgs[3]); + JsonData.Append((uint8*)Convert.Get(), MessageArgs[3].Len() * sizeof(UCS2CHAR)); + FMemoryReader Reader(JsonData); + + FNativeJSStructDeserializerBackend Backend = FNativeJSStructDeserializerBackend(SharedThis(this), Reader); + FStructDeserializer::Deserialize(Params.GetData(), *Function, Backend); + } + + if (PromiseParam) + { + FWebJSResponse* PromisePtr = PromiseParam->ContainerPtrToValuePtr(Params.GetData()); + if (PromisePtr) + { + *PromisePtr = FWebJSResponse(SharedThis(this), ResultCallbackId); + } + } + + Object->ProcessEvent(Function, Params.GetData()); + if ( ! PromiseParam ) // If PromiseParam is set, we assume that the UFunction will ensure it is called with the result + { + if ( ReturnParam ) + { + FStructSerializerPolicies ReturnPolicies; + ReturnPolicies.PropertyFilter = [&ReturnParam](const UProperty* CandidateProperty, const UProperty* ParentProperty) + { + return ParentProperty != nullptr || CandidateProperty == ReturnParam; + }; + TArray ReturnBuffer; + FMemoryWriter Writer(ReturnBuffer); + + FNativeJSStructSerializerBackend ReturnBackend = FNativeJSStructSerializerBackend(SharedThis(this), Writer); + FStructSerializer::Serialize(Params.GetData(), *Function, ReturnBackend, ReturnPolicies); + + // Extract the result value from the serialized JSON object: + ReturnBuffer.Add(0); + ReturnBuffer.Add(0); + auto CastObject = StringCast((UCS2CHAR*)ReturnBuffer.GetData()); + FString ResultJS = FString(CastObject.Get(), CastObject.Length()); + + InvokeJSFunctionRaw(ResultCallbackId, ResultJS, false); + } + else + { + InvokeJSFunction(ResultCallbackId, 0, nullptr, false); + } + } + return true; +} + +FString FNativeJSScripting::GetInitializeScript() +{ + const FString ScriptingInit = + TEXT("(function() {") + TEXT("var util = Object.create({") + + // Simple random-based (RFC-4122 version 4) UUID generator. + // Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, a, or b + // This function returns the UUID as a hex string without the dashes + TEXT("uuid: function()") + TEXT("{") + TEXT(" var b = new Uint8Array(16); window.crypto.getRandomValues(b);") + TEXT(" b[6] = b[6]&0xf|0x40; b[8]=b[8]&0x3f|0x80;") // Set the reserved bits to the correct values + TEXT(" return Array.prototype.reduce.call(b, function(a,i){return a+((0x100|i).toString(16).substring(1))},'').toUpperCase();") + TEXT("}, ") + + // save a callback function in the callback registry + // returns the uuid of the callback for passing to the host application + // ensures that each function object is only stored once. + // (Closures executed multiple times are considered separate objects.) + TEXT("registerCallback: function(callback)") + TEXT("{") + TEXT(" var key;") + TEXT(" for(key in this.callbacks)") + TEXT(" {") + TEXT(" if (!this.callbacks[key].isOneShot && this.callbacks[key].accept === callback)") + TEXT(" {") + TEXT(" return key;") + TEXT(" }") + TEXT(" }") + TEXT(" key = this.uuid();") + TEXT(" this.callbacks[key] = {accept:callback, reject:callback, bIsOneShot:false};") + TEXT(" return key;") + TEXT("}, ") + + TEXT("registerPromise: function(accept, reject, name)") + TEXT("{") + TEXT(" var key = this.uuid();") + TEXT(" this.callbacks[key] = {accept:accept, reject:reject, bIsOneShot:true, name:name};") + TEXT(" return key;") + TEXT("}, ") + + // strip ReturnValue object wrapper if present + TEXT("returnValToObj: function(args)") + TEXT("{") + TEXT(" return Array.prototype.map.call(args, function(item){return item.ReturnValue || item});") + TEXT("}, ") + + // invoke a callback method or promise by uuid + TEXT("invokeCallback: function(key, bIsError, args)") + TEXT("{") + TEXT(" var callback = this.callbacks[key];") + TEXT(" if (typeof callback === 'undefined')") + TEXT(" {") + TEXT(" console.error('Unknown callback id', key);") + TEXT(" return;") + TEXT(" }") + TEXT(" if (callback.bIsOneShot)") + TEXT(" {") + TEXT(" callback.iwanttodeletethis=true;") + TEXT(" delete this.callbacks[key];") + TEXT(" }") + TEXT(" callback[bIsError?'reject':'accept'].apply(window, this.returnValToObj(args));") + TEXT("}, ") + + // convert an argument list to a dictionary of arguments. + // The args argument must be an argument object as it uses the callee member to deduce the argument names + TEXT("argsToDict: function(args)") + TEXT("{") + TEXT(" var res = {};") + TEXT(" args.callee.toString().match(/\\((.+?)\\)/)[1].split(/\\s*,\\s*/).forEach(function(name, idx){res[name]=args[idx]});") + TEXT(" return res;") + TEXT("}, ") + + // encodes and sends a message to the host application + TEXT("sendMessage: function()") + TEXT("{") + // @todo: Each kairos native browser will have a different way of passing a message out, here we use webkit postmessage but we'll need + // to be aware of our target platform when generating this script and adjust accordingly + TEXT(" let delimiter = '/';") + +#if PLATFORM_ANDROID + TEXT(" if(window.JSBridge){") + TEXT(" window.JSBridge.postMessage('', 'browserProxy', 'handlejs', Array.prototype.slice.call(arguments).join(delimiter));") + TEXT(" }") +#else + TEXT(" if(window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.browserProxy){") + TEXT(" window.webkit.messageHandlers.browserProxy.postMessage(Array.prototype.slice.call(arguments).join(delimiter));") + TEXT(" }") +#endif + TEXT("}, ") + + // custom replacer function passed into JSON.stringify to handle cases where there are function objects in the argument list + // of the executeMethod call. In those cases we want to be able to pass them as callbacks. + TEXT("customReplacer: function(key, value)") + TEXT("{") + TEXT(" if (typeof value === 'function')") + TEXT(" {") + TEXT(" return window.ue.$.registerCallback(value);") + TEXT(" }") + TEXT(" return value;") + TEXT("},") + + // uses the above helper methods to execute a method on a uobject instance. + // the method set as callee on args needs to be a named function, as the name of the method to invoke is taken from it + TEXT("executeMethod: function(priority, id, args)") + TEXT("{") + TEXT(" var self = this;") // the closures need access to the outer this object + + // Create a promise object to return back to the caller and create a callback function to handle the response + TEXT(" var promiseID;") + TEXT(" var promise = new Promise(function (accept, reject) ") + TEXT(" {") + TEXT(" promiseID = self.registerPromise(accept, reject, args.callee.name)") + TEXT(" });") + + // Actually invoke the method by sending a message to the host app + TEXT(" this.sendMessage(priority, '") + NativeFuncs::ExecuteMethodCommand + TEXT("', id, promiseID, args.callee.name, JSON.stringify(this.argsToDict(args), this.customReplacer));") + + // Return the promise object to the caller + TEXT(" return promise;") + TEXT("}") + TEXT("},{callbacks: {value:{}}});") + + // Create the global window.ue variable + TEXT("window.ue = Object.create({}, {'$': {writable: false, configurable:false, enumerable: false, value:util}});") + TEXT("})();") + ; + + return ScriptingInit; +} + +void FNativeJSScripting::PageLoaded() +{ + // Expunge temporary objects. + for (TMap::TIterator It(BoundObjects); It; ++It) + { + if (!It->Value.bIsPermanent) + { + It.RemoveCurrent(); + } + } + + FString Script = GetInitializeScript(); + + for(auto& Item : PermanentUObjectsByName) + { + Script.Append(*FString::Printf(TEXT("window.ue['%s'] = %s;"), *Item.Key.ReplaceCharWithEscapedChar(), *ConvertObject(Item.Value))); + } + + // Append postinit for each object we added. + for (auto& Item : PermanentUObjectsByName) + { + const FString& Name = Item.Key.ReplaceCharWithEscapedChar(); + Script.Append(GetObjectPostInitScript(Name, FString::Printf(TEXT("window.ue['%s']"), *Name))); + } + + // Append postinit for window.ue + Script.Append(GetObjectPostInitScript(TEXT("ue"), TEXT("window.ue"))); + + bLoaded = true; + ExecuteJavascript(Script); +} + +FNativeJSScripting::FNativeJSScripting(bool bJSBindingToLoweringEnabled, TSharedRef Window) + : FWebJSScripting(bJSBindingToLoweringEnabled) + , bLoaded(false) +{ + WindowPtr = Window; +} + diff --git a/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSScripting.h b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSScripting.h new file mode 100644 index 000000000000..537a3099f08c --- /dev/null +++ b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSScripting.h @@ -0,0 +1,52 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "CoreMinimal.h" + +#include "WebJSFunction.h" +#include "WebJSScripting.h" + +typedef TSharedRef FNativeJSScriptingRef; +typedef TSharedPtr FNativeJSScriptingPtr; + +class FNativeWebBrowserProxy; + +/** + * Implements handling of bridging UObjects client side with JavaScript renderer side. + */ +class FNativeJSScripting + : public FWebJSScripting + , public TSharedFromThis +{ +public: + //static const FString JSMessageTag; + + FNativeJSScripting(bool bJSBindingToLoweringEnabled, TSharedRef Window); + + virtual void BindUObject(const FString& Name, UObject* Object, bool bIsPermanent = true) override; + virtual void UnbindUObject(const FString& Name, UObject* Object = nullptr, bool bIsPermanent = true) override; + + bool OnJsMessageReceived(const FString& Message); + + FString ConvertStruct(UStruct* TypeInfo, const void* StructPtr); + FString ConvertObject(UObject* Object); + + virtual void InvokeJSFunction(FGuid FunctionId, int32 ArgCount, FWebJSParam Arguments[], bool bIsError=false) override; + virtual void InvokeJSErrorResult(FGuid FunctionId, const FString& Error) override; + void PageLoaded(); + +private: + FString GetInitializeScript(); + void InvokeJSFunctionRaw(FGuid FunctionId, const FString& JSValue, bool bIsError=false); + bool IsValid() + { + return WindowPtr.Pin().IsValid(); + } + + /** Message handling helpers */ + bool HandleExecuteUObjectMethodMessage(const TArray& Params); + void ExecuteJavascript(const FString& Javascript); + + TWeakPtr WindowPtr; + bool bLoaded; +}; diff --git a/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSStructDeserializerBackend.cpp b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSStructDeserializerBackend.cpp new file mode 100644 index 000000000000..03f7dbb3ed0d --- /dev/null +++ b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSStructDeserializerBackend.cpp @@ -0,0 +1,98 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "NativeJSStructDeserializerBackend.h" +#include "NativeJSScripting.h" +#include "UObject/UnrealType.h" +#include "Templates/Casts.h" + +namespace NativeFuncs +{ + // @todo: this function is copied from CEFJSStructDeserializerBackend.cpp. Move shared utility code to a common header file + /** + * Sets the value of the given property. + * + * @param Property The property to set. + * @param Outer The property that contains the property to be set, if any. + * @param Data A pointer to the memory holding the property's data. + * @param ArrayIndex The index of the element to set (if the property is an array). + * @return true on success, false otherwise. + * @see ClearPropertyValue + */ + template + bool SetPropertyValue( UProperty* Property, UProperty* Outer, void* Data, int32 ArrayIndex, const PropertyType& Value ) + { + PropertyType* ValuePtr = nullptr; + UArrayProperty* ArrayProperty = Cast(Outer); + + if (ArrayProperty != nullptr) + { + if (ArrayProperty->Inner != Property) + { + return false; + } + + FScriptArrayHelper ArrayHelper(ArrayProperty, ArrayProperty->template ContainerPtrToValuePtr(Data)); + int32 Index = ArrayHelper.AddValue(); + + ValuePtr = (PropertyType*)ArrayHelper.GetRawPtr(Index); + } + else + { + UPropertyType* TypedProperty = Cast(Property); + + if (TypedProperty == nullptr || ArrayIndex >= TypedProperty->ArrayDim) + { + return false; + } + + ValuePtr = TypedProperty->template ContainerPtrToValuePtr(Data, ArrayIndex); + } + + if (ValuePtr == nullptr) + { + return false; + } + + *ValuePtr = Value; + + return true; + } +} + + +bool FNativeJSStructDeserializerBackend::ReadProperty( UProperty* Property, UProperty* Outer, void* Data, int32 ArrayIndex ) +{ + switch (GetLastNotation()) + { + case EJsonNotation::String: + { + if (Property->IsA()) + { + UStructProperty* StructProperty = Cast(Property); + + if ( StructProperty->Struct == FWebJSFunction::StaticStruct()) + { + + FGuid CallbackID; + if (!FGuid::Parse(GetReader()->GetValueAsString(), CallbackID)) + { + return false; + } + + FWebJSFunction CallbackObject(Scripting, CallbackID); + return NativeFuncs::SetPropertyValue(Property, Outer, Data, ArrayIndex, CallbackObject); + } + } + } + break; + } + + // If we reach this, default to parent class behavior + return FJsonStructDeserializerBackend::ReadProperty(Property, Outer, Data, ArrayIndex); +} + +FNativeJSStructDeserializerBackend::FNativeJSStructDeserializerBackend(FNativeJSScriptingRef InScripting, FMemoryReader& Reader) + : FJsonStructDeserializerBackend(Reader) + , Scripting(InScripting) +{ +} diff --git a/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSStructDeserializerBackend.h b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSStructDeserializerBackend.h new file mode 100644 index 000000000000..8b2529ee3060 --- /dev/null +++ b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSStructDeserializerBackend.h @@ -0,0 +1,21 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "NativeJSScripting.h" +#include "Backends/JsonStructDeserializerBackend.h" +#include "Serialization/MemoryReader.h" + +class FNativeJSStructDeserializerBackend + : public FJsonStructDeserializerBackend +{ +public: + FNativeJSStructDeserializerBackend(FNativeJSScriptingRef InScripting, FMemoryReader& Reader); + + virtual bool ReadProperty( UProperty* Property, UProperty* Outer, void* Data, int32 ArrayIndex ) override; + +private: + FNativeJSScriptingRef Scripting; + +}; diff --git a/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSStructSerializerBackend.cpp b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSStructSerializerBackend.cpp new file mode 100644 index 000000000000..b95509eb86b5 --- /dev/null +++ b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSStructSerializerBackend.cpp @@ -0,0 +1,48 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "Native/NativeJSStructSerializerBackend.h" + +#include "NativeJSScripting.h" +#include "UObject/UnrealType.h" +#include "UObject/PropertyPortFlags.h" +#include "Templates/Casts.h" + +void FNativeJSStructSerializerBackend::WriteProperty(const FStructSerializerState& State, int32 ArrayIndex) +{ + // The parent class serialzes UObjects as NULLs + if (State.ValueType == UObjectProperty::StaticClass()) + { + WriteUObject(State, CastChecked(State.ValueProperty)->GetPropertyValue_InContainer(State.ValueData, ArrayIndex)); + } + // basic property type (json serializable) + else + { + FJsonStructSerializerBackend::WriteProperty(State, ArrayIndex); + } +} + +void FNativeJSStructSerializerBackend::WriteUObject(const FStructSerializerState& State, UObject* Value) +{ + // Note this function uses WriteRawJSONValue to append non-json data to the output stream. + FString RawValue = Scripting->ConvertObject(Value); + if ((State.ValueProperty == nullptr) || (State.ValueProperty->ArrayDim > 1) || (State.ValueProperty->GetOuter()->GetClass() == UArrayProperty::StaticClass())) + { + GetWriter()->WriteRawJSONValue(RawValue); + } + else if (State.KeyProperty != nullptr) + { + FString KeyString; + State.KeyProperty->ExportTextItem(KeyString, State.KeyData, nullptr, nullptr, PPF_None); + GetWriter()->WriteRawJSONValue(KeyString, RawValue); + } + else + { + GetWriter()->WriteRawJSONValue(Scripting->GetBindingName(State.ValueProperty), RawValue); + } +} + +FNativeJSStructSerializerBackend::FNativeJSStructSerializerBackend(TSharedRef InScripting, FMemoryWriter& Writer) + : FJsonStructSerializerBackend(Writer, EStructSerializerBackendFlags::Default) + , Scripting(InScripting) +{ +} \ No newline at end of file diff --git a/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSStructSerializerBackend.h b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSStructSerializerBackend.h new file mode 100644 index 000000000000..fd5eeeeb0df5 --- /dev/null +++ b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeJSStructSerializerBackend.h @@ -0,0 +1,36 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "NativeJSScripting.h" +#include "Backends/JsonStructSerializerBackend.h" + +class UObject; + +/** + * Implements a writer for UStruct serialization using JavaScript. + * + * Based on FJsonStructSerializerBackend, it adds support for certain object types not representable in pure JSON + * + */ +class FNativeJSStructSerializerBackend + : public FJsonStructSerializerBackend +{ +public: + + /** + * Creates and initializes a new instance. + * + * @param InScripting An instance of a web browser scripting obnject. + */ + FNativeJSStructSerializerBackend(FNativeJSScriptingRef InScripting, FMemoryWriter& Writer); + +public: + virtual void WriteProperty(const FStructSerializerState& State, int32 ArrayIndex = 0) override; + +private: + void WriteUObject(const FStructSerializerState& State, UObject* Value); + + FNativeJSScriptingRef Scripting; +}; diff --git a/Engine/Source/Runtime/WebBrowser/Private/Native/NativeWebBrowserProxy.cpp b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeWebBrowserProxy.cpp new file mode 100644 index 000000000000..3dc2279da26d --- /dev/null +++ b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeWebBrowserProxy.cpp @@ -0,0 +1,243 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + + +#include "NativeWebBrowserProxy.h" +#include "NativeJSScripting.h" +#include "Misc/EmbeddedCommunication.h" + + +FNativeWebBrowserProxy::FNativeWebBrowserProxy(bool bInJSBindingToLoweringEnabled) + : bJSBindingToLoweringEnabled(bInJSBindingToLoweringEnabled) +{ + +} + +void FNativeWebBrowserProxy::Initialize() +{ + Scripting = MakeShareable(new FNativeJSScripting(bJSBindingToLoweringEnabled, SharedThis(this))); + FEmbeddedDelegates::GetNativeToEmbeddedParamsDelegateForSubsystem(TEXT("browserProxy")).AddRaw(this, &FNativeWebBrowserProxy::HandleEmbeddedCommunication); +} + +FNativeWebBrowserProxy::~FNativeWebBrowserProxy() +{ + FEmbeddedDelegates::GetNativeToEmbeddedParamsDelegateForSubsystem(TEXT("browserProxy")).RemoveAll(this); +} + +bool FNativeWebBrowserProxy::OnJsMessageReceived(const FString& Message) +{ + return Scripting->OnJsMessageReceived(Message); +} + +void FNativeWebBrowserProxy::HandleEmbeddedCommunication(const FEmbeddedCallParamsHelper& Params) +{ + FString Error; + if (Params.Command == "handlejs") + { + FString Message = Params.Parameters.FindRef(TEXT("script")); + if (!Message.IsEmpty()) + { + if (!OnJsMessageReceived(Message)) + { + Error = TEXT("Command failed"); + } + } + } + else if (Params.Command == "pageload") + { + Scripting->PageLoaded(); + } + + Params.OnCompleteDelegate(FEmbeddedCommunicationMap(), Error); +} + +void FNativeWebBrowserProxy::LoadURL(FString NewURL) +{ +} + +void FNativeWebBrowserProxy::LoadString(FString Contents, FString DummyURL) +{ +} + +void FNativeWebBrowserProxy::SetViewportSize(FIntPoint WindowSize, FIntPoint WindowPos) +{ +} + +FIntPoint FNativeWebBrowserProxy::GetViewportSize() const +{ + return FIntPoint(ForceInitToZero); +} + +FSlateShaderResource* FNativeWebBrowserProxy::GetTexture(bool bIsPopup /*= false*/) +{ + return nullptr; +} + +bool FNativeWebBrowserProxy::IsValid() const +{ + return false; +} + +bool FNativeWebBrowserProxy::IsInitialized() const +{ + return true; +} + +bool FNativeWebBrowserProxy::IsClosing() const +{ + return false; +} + +EWebBrowserDocumentState FNativeWebBrowserProxy::GetDocumentLoadingState() const +{ + return EWebBrowserDocumentState::Loading; +} + +FString FNativeWebBrowserProxy::GetTitle() const +{ + return TEXT(""); +} + +FString FNativeWebBrowserProxy::GetUrl() const +{ + return TEXT(""); +} + +void FNativeWebBrowserProxy::GetSource(TFunction Callback) const +{ + Callback(FString()); +} + +void FNativeWebBrowserProxy::SetSupportsMouseWheel(bool bValue) +{ + +} + +bool FNativeWebBrowserProxy::GetSupportsMouseWheel() const +{ + return false; +} + +bool FNativeWebBrowserProxy::OnKeyDown(const FKeyEvent& InKeyEvent) +{ + return false; +} + +bool FNativeWebBrowserProxy::OnKeyUp(const FKeyEvent& InKeyEvent) +{ + return false; +} + +bool FNativeWebBrowserProxy::OnKeyChar(const FCharacterEvent& InCharacterEvent) +{ + return false; +} + +FReply FNativeWebBrowserProxy::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, bool bIsPopup) +{ + return FReply::Unhandled(); +} + +FReply FNativeWebBrowserProxy::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, bool bIsPopup) +{ + return FReply::Unhandled(); +} + +FReply FNativeWebBrowserProxy::OnMouseButtonDoubleClick(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, bool bIsPopup) +{ + return FReply::Unhandled(); +} + +FReply FNativeWebBrowserProxy::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, bool bIsPopup) +{ + return FReply::Unhandled(); +} + +void FNativeWebBrowserProxy::OnMouseLeave(const FPointerEvent& MouseEvent) +{ +} + +FReply FNativeWebBrowserProxy::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, bool bIsPopup) +{ + return FReply::Unhandled(); +} + + +void FNativeWebBrowserProxy::OnFocus(bool SetFocus, bool bIsPopup) +{ +} + +void FNativeWebBrowserProxy::OnCaptureLost() +{ +} + +bool FNativeWebBrowserProxy::CanGoBack() const +{ + return false; +} + +void FNativeWebBrowserProxy::GoBack() +{ +} + +bool FNativeWebBrowserProxy::CanGoForward() const +{ + return false; +} + +void FNativeWebBrowserProxy::GoForward() +{ +} + +bool FNativeWebBrowserProxy::IsLoading() const +{ + return false; +} + +void FNativeWebBrowserProxy::Reload() +{ +} + +void FNativeWebBrowserProxy::StopLoad() +{ +} + +void FNativeWebBrowserProxy::ExecuteJavascript(const FString& Script) +{ + FEmbeddedCallParamsHelper CallHelper; + CallHelper.Command = TEXT("execjs"); + CallHelper.Parameters = { { TEXT("script"), Script } }; + + FEmbeddedDelegates::GetEmbeddedToNativeParamsDelegateForSubsystem(TEXT("webview")).Broadcast(CallHelper); +} + +void FNativeWebBrowserProxy::CloseBrowser(bool bForce) +{ +} + +void FNativeWebBrowserProxy::BindUObject(const FString& Name, UObject* Object, bool bIsPermanent /*= true*/) +{ + Scripting->BindUObject(Name, Object, bIsPermanent); +} + +void FNativeWebBrowserProxy::UnbindUObject(const FString& Name, UObject* Object /*= nullptr*/, bool bIsPermanent /*= true*/) +{ + Scripting->UnbindUObject(Name, Object, bIsPermanent); +} + +int FNativeWebBrowserProxy::GetLoadError() +{ + return 0; +} + +void FNativeWebBrowserProxy::SetIsDisabled(bool bValue) +{ +} + +TSharedPtr FNativeWebBrowserProxy::GetParentWindow() const +{ + return nullptr; +} + +void FNativeWebBrowserProxy::SetParentWindow(TSharedPtr Window) +{ +} diff --git a/Engine/Source/Runtime/WebBrowser/Private/Native/NativeWebBrowserProxy.h b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeWebBrowserProxy.h new file mode 100644 index 000000000000..0ad71f63fdf0 --- /dev/null +++ b/Engine/Source/Runtime/WebBrowser/Private/Native/NativeWebBrowserProxy.h @@ -0,0 +1,237 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "CoreMinimal.h" +#include "IWebBrowserWindow.h" +#include "NativeJSScripting.h" + +class FNativeWebBrowserProxy + : public IWebBrowserWindow + , public TSharedFromThis +{ + // For creating instances of this class + friend class FWebBrowserSingleton; + +private: + FNativeWebBrowserProxy(bool bJSBindingToLoweringEnabled); + void Initialize(); + void HandleEmbeddedCommunication(const struct FEmbeddedCallParamsHelper& Params); + bool OnJsMessageReceived(const FString& Message); + +public: + virtual ~FNativeWebBrowserProxy(); + +public: + // IWebBrowserWindow Interface + + virtual void LoadURL(FString NewURL) override; + virtual void LoadString(FString Contents, FString DummyURL) override; + virtual void SetViewportSize(FIntPoint WindowSize, FIntPoint WindowPos) override; + virtual FIntPoint GetViewportSize() const override; + + virtual class FSlateShaderResource* GetTexture(bool bIsPopup = false) override; + virtual bool IsValid() const override; + virtual bool IsInitialized() const override; + virtual bool IsClosing() const override; + virtual EWebBrowserDocumentState GetDocumentLoadingState() const override; + virtual FString GetTitle() const override; + virtual FString GetUrl() const override; + virtual void GetSource(TFunction Callback) const override; + virtual bool OnKeyDown(const FKeyEvent& InKeyEvent) override; + virtual bool OnKeyUp(const FKeyEvent& InKeyEvent) override; + virtual bool OnKeyChar(const FCharacterEvent& InCharacterEvent) override; + virtual void SetSupportsMouseWheel(bool bValue) override; + virtual bool GetSupportsMouseWheel() const override; + + virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, bool bIsPopup) override; + virtual FReply OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, bool bIsPopup) override; + virtual FReply OnMouseButtonDoubleClick(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, bool bIsPopup) override; + virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, bool bIsPopup) override; + virtual void OnMouseLeave(const FPointerEvent& MouseEvent) override; + virtual FReply OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, bool bIsPopup) override; + virtual FOnDragWindow& OnDragWindow() override + { + return DragWindowDelegate; + } + virtual void OnFocus(bool SetFocus, bool bIsPopup) override; + virtual void OnCaptureLost() override; + virtual bool CanGoBack() const override; + virtual void GoBack() override; + virtual bool CanGoForward() const override; + virtual void GoForward() override; + virtual bool IsLoading() const override; + virtual void Reload() override; + virtual void StopLoad() override; + virtual void ExecuteJavascript(const FString& Script) override; + virtual void CloseBrowser(bool bForce) override; + virtual void BindUObject(const FString& Name, UObject* Object, bool bIsPermanent = true) override; + virtual void UnbindUObject(const FString& Name, UObject* Object = nullptr, bool bIsPermanent = true) override; + virtual int GetLoadError() override; + virtual void SetIsDisabled(bool bValue) override; + virtual TSharedPtr GetParentWindow() const override; + virtual void SetParentWindow(TSharedPtr Window) override; + + // @todo: None of these are actually called at the moment. + DECLARE_DERIVED_EVENT(FNativeWebBrowserProxy, IWebBrowserWindow::FOnDocumentStateChanged, FOnDocumentStateChanged); + virtual FOnDocumentStateChanged& OnDocumentStateChanged() override + { + return DocumentStateChangedEvent; + } + + DECLARE_DERIVED_EVENT(FNativeWebBrowserProxy, IWebBrowserWindow::FOnTitleChanged, FOnTitleChanged); + virtual FOnTitleChanged& OnTitleChanged() override + { + return TitleChangedEvent; + } + + DECLARE_DERIVED_EVENT(FNativeWebBrowserProxy, IWebBrowserWindow::FOnUrlChanged, FOnUrlChanged); + virtual FOnUrlChanged& OnUrlChanged() override + { + return UrlChangedEvent; + } + + DECLARE_DERIVED_EVENT(FNativeWebBrowserProxy, IWebBrowserWindow::FOnToolTip, FOnToolTip); + virtual FOnToolTip& OnToolTip() override + { + return ToolTipEvent; + } + + DECLARE_DERIVED_EVENT(FNativeWebBrowserProxy, IWebBrowserWindow::FOnNeedsRedraw, FOnNeedsRedraw); + virtual FOnNeedsRedraw& OnNeedsRedraw() override + { + return NeedsRedrawEvent; + } + + virtual FOnBeforeBrowse& OnBeforeBrowse() override + { + return BeforeBrowseDelegate; + } + + virtual FOnLoadUrl& OnLoadUrl() override + { + return LoadUrlDelegate; + } + + virtual FOnCreateWindow& OnCreateWindow() override + { + return CreateWindowDelegate; + } + + virtual FOnCloseWindow& OnCloseWindow() override + { + return CloseWindowDelegate; + } + + virtual FCursorReply OnCursorQuery(const FGeometry& MyGeometry, const FPointerEvent& CursorEvent) override + { + return FCursorReply::Unhandled(); + } + + virtual FOnBeforePopupDelegate& OnBeforePopup() override + { + return BeforePopupDelegate; + } + + DECLARE_DERIVED_EVENT(FNativeWebBrowserProxy, IWebBrowserWindow::FOnShowPopup, FOnShowPopup); + virtual FOnShowPopup& OnShowPopup() override + { + return ShowPopupEvent; + } + + DECLARE_DERIVED_EVENT(FNativeWebBrowserProxy, IWebBrowserWindow::FOnDismissPopup, FOnDismissPopup); + virtual FOnDismissPopup& OnDismissPopup() override + { + return DismissPopupEvent; + } + + virtual FOnShowDialog& OnShowDialog() override + { + return ShowDialogDelegate; + } + + virtual FOnDismissAllDialogs& OnDismissAllDialogs() override + { + return DismissAllDialogsDelegate; + } + + virtual FOnSuppressContextMenu& OnSuppressContextMenu() override + { + return SuppressContextMenuDelgate; + } + + virtual FOnUnhandledKeyDown& OnUnhandledKeyDown() override + { + return UnhandledKeyDownDelegate; + } + + virtual FOnUnhandledKeyUp& OnUnhandledKeyUp() override + { + return UnhandledKeyUpDelegate; + } + + virtual FOnUnhandledKeyChar& OnUnhandledKeyChar() override + { + return UnhandledKeyCharDelegate; + } + +private: + + /** Delegate for broadcasting load state changes. */ + FOnDocumentStateChanged DocumentStateChangedEvent; + + /** Delegate for broadcasting title changes. */ + FOnTitleChanged TitleChangedEvent; + + /** Delegate for broadcasting address changes. */ + FOnUrlChanged UrlChangedEvent; + + /** Delegate for broadcasting when the browser wants to show a tool tip. */ + FOnToolTip ToolTipEvent; + + /** Delegate for notifying that the window needs refreshing. */ + FOnNeedsRedraw NeedsRedrawEvent; + + /** Delegate that is executed prior to browser navigation. */ + FOnBeforeBrowse BeforeBrowseDelegate; + + /** Delegate for overriding Url contents. */ + FOnLoadUrl LoadUrlDelegate; + + /** Delegate for notifying that a popup window is attempting to open. */ + FOnBeforePopupDelegate BeforePopupDelegate; + + /** Delegate for handling requests to create new windows. */ + FOnCreateWindow CreateWindowDelegate; + + /** Delegate for handling requests to close new windows that were created. */ + FOnCloseWindow CloseWindowDelegate; + + /** Delegate for handling requests to show the popup menu. */ + FOnShowPopup ShowPopupEvent; + + /** Delegate for handling requests to dismiss the current popup menu. */ + FOnDismissPopup DismissPopupEvent; + + /** Delegate for showing dialogs. */ + FOnShowDialog ShowDialogDelegate; + + /** Delegate for dismissing all dialogs. */ + FOnDismissAllDialogs DismissAllDialogsDelegate; + + /** Delegate for suppressing context menu */ + FOnSuppressContextMenu SuppressContextMenuDelgate; + + /** Delegate for handling key down events not handled by the browser. */ + FOnUnhandledKeyDown UnhandledKeyDownDelegate; + + /** Delegate for handling key up events not handled by the browser. */ + FOnUnhandledKeyUp UnhandledKeyUpDelegate; + + /** Delegate for handling key char events not handled by the browser. */ + FOnUnhandledKeyChar UnhandledKeyCharDelegate; + + FOnDragWindow DragWindowDelegate; + + bool bJSBindingToLoweringEnabled; + FNativeJSScriptingPtr Scripting; +}; diff --git a/Engine/Source/Runtime/WebBrowser/Private/SWebBrowserView.cpp b/Engine/Source/Runtime/WebBrowser/Private/SWebBrowserView.cpp index f1d5043592f6..8b00e2c6bf1a 100644 --- a/Engine/Source/Runtime/WebBrowser/Private/SWebBrowserView.cpp +++ b/Engine/Source/Runtime/WebBrowser/Private/SWebBrowserView.cpp @@ -92,6 +92,9 @@ void SWebBrowserView::Construct(const FArguments& InArgs, const TSharedPtrOnUnhandledKeyDown().IsBound()) + { + BrowserWindow->OnUnhandledKeyDown().BindSP(this, &SWebBrowserView::UnhandledKeyDown); + } + + if (!BrowserWindow->OnUnhandledKeyUp().IsBound()) + { + BrowserWindow->OnUnhandledKeyUp().BindSP(this, &SWebBrowserView::UnhandledKeyUp); + } + + if (!BrowserWindow->OnUnhandledKeyChar().IsBound()) + { + BrowserWindow->OnUnhandledKeyChar().BindSP(this, &SWebBrowserView::UnhandledKeyChar); + } + BrowserWindow->OnShowDialog().BindSP(this, &SWebBrowserView::HandleShowDialog); BrowserWindow->OnDismissAllDialogs().BindSP(this, &SWebBrowserView::HandleDismissAllDialogs); BrowserWindow->OnShowPopup().AddSP(this, &SWebBrowserView::HandleShowPopup); BrowserWindow->OnDismissPopup().AddSP(this, &SWebBrowserView::HandleDismissPopup); BrowserWindow->OnSuppressContextMenu().BindSP(this, &SWebBrowserView::HandleSuppressContextMenu); + + OnSuppressContextMenu = InArgs._OnSuppressContextMenu; BrowserWindow->OnDragWindow().BindSP(this, &SWebBrowserView::HandleDrag); @@ -646,4 +666,32 @@ bool SWebBrowserView::HandleDrag(const FPointerEvent& MouseEvent) return false; } +bool SWebBrowserView::UnhandledKeyDown(const FKeyEvent& KeyEvent) +{ + if (OnUnhandledKeyDown.IsBound()) + { + return OnUnhandledKeyDown.Execute(KeyEvent); + } + return false; +} + +bool SWebBrowserView::UnhandledKeyUp(const FKeyEvent& KeyEvent) +{ + if (OnUnhandledKeyUp.IsBound()) + { + return OnUnhandledKeyUp.Execute(KeyEvent); + } + return false; +} + +bool SWebBrowserView::UnhandledKeyChar(const FCharacterEvent& CharacterEvent) +{ + if (OnUnhandledKeyChar.IsBound()) + { + return OnUnhandledKeyChar.Execute(CharacterEvent); + } + return false; +} + + #undef LOCTEXT_NAMESPACE diff --git a/Engine/Source/Runtime/WebBrowser/Private/WebBrowserSingleton.cpp b/Engine/Source/Runtime/WebBrowser/Private/WebBrowserSingleton.cpp index ca652476bff0..f2272e48509a 100644 --- a/Engine/Source/Runtime/WebBrowser/Private/WebBrowserSingleton.cpp +++ b/Engine/Source/Runtime/WebBrowser/Private/WebBrowserSingleton.cpp @@ -43,6 +43,10 @@ THIRD_PARTY_INCLUDES_END # endif #endif +#if BUILD_EMBEDDED_APP +# include "Native/NativeWebBrowserProxy.h" +#endif + #if PLATFORM_ANDROID && USE_ANDROID_JNI # include "Android/AndroidWebBrowserWindow.h" # include @@ -315,7 +319,7 @@ FWebBrowserSingleton::FWebBrowserSingleton(const FWebBrowserInitSettings& WebBro SetCurrentThreadName(TCHAR_TO_ANSI( *(FName( NAME_GameThread ).GetPlainNameString()) )); DefaultCookieManager = FCefWebBrowserCookieManagerFactory::Create(CefCookieManager::GetGlobalManager(nullptr)); -#elif PLATFORM_IOS +#elif PLATFORM_IOS && !BUILD_EMBEDDED_APP DefaultCookieManager = MakeShareable(new FIOSCookieManager()); #elif PLATFORM_ANDROID DefaultCookieManager = MakeShareable(new FAndroidCookieManager()); @@ -441,7 +445,7 @@ TSharedPtr FWebBrowserSingleton::CreateBrowserWindow(const FC { bool bBrowserEnabled = true; GConfig->GetBool(TEXT("Browser"), TEXT("bEnabled"), bBrowserEnabled, GEngineIni); - if (!bBrowserEnabled) + if (!bBrowserEnabled || !FApp::CanEverRender()) { return nullptr; } @@ -585,6 +589,17 @@ TSharedPtr FWebBrowserSingleton::CreateBrowserWindow(const FC return nullptr; } +#if BUILD_EMBEDDED_APP +TSharedPtr FWebBrowserSingleton::CreateNativeBrowserProxy() +{ + TSharedPtr NewBrowserWindow = MakeShareable(new FNativeWebBrowserProxy( + bJSBindingsToLoweringEnabled + )); + NewBrowserWindow->Initialize(); + return NewBrowserWindow; +} +#endif //BUILD_EMBEDDED_APP + bool FWebBrowserSingleton::Tick(float DeltaTime) { QUICK_SCOPE_CYCLE_COUNTER(STAT_FWebBrowserSingleton_Tick); diff --git a/Engine/Source/Runtime/WebBrowser/Private/WebBrowserSingleton.h b/Engine/Source/Runtime/WebBrowser/Private/WebBrowserSingleton.h index f7f034b2a73d..e47645a282ea 100644 --- a/Engine/Source/Runtime/WebBrowser/Private/WebBrowserSingleton.h +++ b/Engine/Source/Runtime/WebBrowser/Private/WebBrowserSingleton.h @@ -90,6 +90,10 @@ public: TSharedPtr CreateBrowserWindow(const FCreateBrowserWindowSettings& Settings) override; +#if BUILD_EMBEDDED_APP + TSharedPtr CreateNativeBrowserProxy() override; +#endif + virtual void DeleteBrowserCookies(FString URL = TEXT(""), FString CookieName = TEXT(""), TFunction Completed = nullptr) override; virtual TSharedPtr GetCookieManager() const override diff --git a/Engine/Source/Runtime/WebBrowser/Public/IWebBrowserSingleton.h b/Engine/Source/Runtime/WebBrowser/Public/IWebBrowserSingleton.h index b4b7ca272f28..bcdfc6e9b802 100644 --- a/Engine/Source/Runtime/WebBrowser/Public/IWebBrowserSingleton.h +++ b/Engine/Source/Runtime/WebBrowser/Public/IWebBrowserSingleton.h @@ -131,6 +131,10 @@ public: virtual TSharedPtr CreateBrowserWindow(const FCreateBrowserWindowSettings& Settings) = 0; +#if BUILD_EMBEDDED_APP + virtual TSharedPtr CreateNativeBrowserProxy() = 0; +#endif + /** * Delete all browser cookies. * @@ -181,7 +185,7 @@ public: /** - * Returns wether the CTRL/CMD-SHIFT-I shortcut to show the Chromium Dev tools window is enabled. + * Returns whether the CTRL/CMD-SHIFT-I shortcut to show the Chromium Dev tools window is enabled. * * The relevant handlers for spawning new browser windows have to be set up correctly in addition to this flag being true before anything is shown. * diff --git a/Engine/Source/Runtime/WebBrowser/Public/IWebBrowserWindow.h b/Engine/Source/Runtime/WebBrowser/Public/IWebBrowserWindow.h index 6dbc3be0498d..78f8bd8032c7 100644 --- a/Engine/Source/Runtime/WebBrowser/Public/IWebBrowserWindow.h +++ b/Engine/Source/Runtime/WebBrowser/Public/IWebBrowserWindow.h @@ -369,6 +369,17 @@ public: DECLARE_DELEGATE_RetVal(bool, FOnSuppressContextMenu); virtual FOnSuppressContextMenu& OnSuppressContextMenu() = 0; + /** A delegate that is invoked for each key down event not handled by the browser, return true if event is handled to prevent it from bubbling up. */ + DECLARE_DELEGATE_RetVal_OneParam(bool, FOnUnhandledKeyDown, const FKeyEvent& /*KeyEvent*/); + virtual FOnUnhandledKeyDown& OnUnhandledKeyDown() = 0; + + /** A delegate that is invoked for each up down event not handled by the browser, return true if event is handled to prevent it from bubbling up. */ + DECLARE_DELEGATE_RetVal_OneParam(bool, FOnUnhandledKeyUp, const FKeyEvent& /*KeyEvent*/); + virtual FOnUnhandledKeyUp& OnUnhandledKeyUp() = 0; + + /** A delegate that is invoked for each key char event not handled by the browser, return true if event is handled to prevent it from bubbling up. */ + DECLARE_DELEGATE_RetVal_OneParam(bool, FOnUnhandledKeyChar, const FCharacterEvent& /*CharacterEvent*/); + virtual FOnUnhandledKeyChar& OnUnhandledKeyChar() = 0; /** A delegate that is invoked when drag is detected in an area specified as a drag region on the web page. */ DECLARE_DELEGATE_RetVal_OneParam(bool, FOnDragWindow, const FPointerEvent& /*MouseEvent*/) virtual FOnDragWindow& OnDragWindow() = 0; diff --git a/Engine/Source/Runtime/WebBrowser/Public/SWebBrowserView.h b/Engine/Source/Runtime/WebBrowser/Public/SWebBrowserView.h index 76f40c166d9f..f9a555d48d3d 100644 --- a/Engine/Source/Runtime/WebBrowser/Public/SWebBrowserView.h +++ b/Engine/Source/Runtime/WebBrowser/Public/SWebBrowserView.h @@ -6,8 +6,8 @@ #include "Input/PopupMethodReply.h" #include "Widgets/SWidget.h" #include "Widgets/SCompoundWidget.h" -#include "Framework/SlateDelegates.h" #include "Framework/Application/IMenu.h" +#include "Framework/SlateDelegates.h" #include "Widgets/SViewport.h" #include "IWebBrowserSingleton.h" @@ -40,6 +40,9 @@ public: DECLARE_DELEGATE_RetVal_OneParam(EWebBrowserDialogEventResponse, FOnShowDialog, const TWeakPtr&); DECLARE_DELEGATE_RetVal(bool, FOnSuppressContextMenu); DECLARE_DELEGATE_RetVal_OneParam(bool, FOnDragWindow, const FPointerEvent& /* MouseEvent */); + DECLARE_DELEGATE_RetVal_OneParam(bool, FOnUnhandledKeyDown, const FKeyEvent& /*KeyEvent*/); + DECLARE_DELEGATE_RetVal_OneParam(bool, FOnUnhandledKeyUp, const FKeyEvent& /*KeyEvent*/); + DECLARE_DELEGATE_RetVal_OneParam(bool, FOnUnhandledKeyChar, const FCharacterEvent& /*CharacterEvent*/); SLATE_BEGIN_ARGS(SWebBrowserView) : _InitialURL(TEXT("https://www.google.com")) @@ -122,6 +125,7 @@ public: /** Called to dismiss any dialogs shown via OnShowDialog. */ SLATE_EVENT(FSimpleDelegate, OnDismissAllDialogs) + /** Called to allow supression of the browser context menu. */ SLATE_EVENT(FOnSuppressContextMenu, OnSuppressContextMenu); /** Called to allow overriding of ToolTip widget construction. */ @@ -129,6 +133,15 @@ public: /** Called when drag is detected in a web page area tagged as a drag region. */ SLATE_EVENT(FOnDragWindow, OnDragWindow) + + /** Called to allow the handling of any key down events not handled by the browser. */ + SLATE_EVENT(FOnUnhandledKeyDown, OnUnhandledKeyDown) + + /** Called to allow the handling of any key up events not handled by the browser. */ + SLATE_EVENT(FOnUnhandledKeyUp, OnUnhandledKeyUp) + + /** Called to allow the handling of any key char events not handled by the browser. */ + SLATE_EVENT(FOnUnhandledKeyChar, OnUnhandledKeyChar) SLATE_END_ARGS() @@ -317,6 +330,9 @@ private: void HandleWindowDeactivated(); void HandleWindowActivated(); + bool UnhandledKeyDown(const FKeyEvent& KeyEvent); + bool UnhandledKeyUp(const FKeyEvent& KeyEvent); + bool UnhandledKeyChar(const FCharacterEvent& CharacterEvent); bool HandleDrag(const FPointerEvent& MouseEvent); @@ -390,6 +406,15 @@ private: /** A delegate that is invoked when the browser detects drag event in within drag region */ FOnDragWindow OnDragWindow; + + /** A delegate for handling key down events not handled by browser. */ + FOnUnhandledKeyDown OnUnhandledKeyDown; + + /** A delegate for handling key up events not handled by browser. */ + FOnUnhandledKeyUp OnUnhandledKeyUp; + + /** A delegate for handling key char events not handled by browser. */ + FOnUnhandledKeyChar OnUnhandledKeyChar; protected: bool HandleSuppressContextMenu(); diff --git a/Engine/Source/Runtime/WebBrowser/WebBrowser.Build.cs b/Engine/Source/Runtime/WebBrowser/WebBrowser.Build.cs index 26a8d338132a..22111ea2cef1 100644 --- a/Engine/Source/Runtime/WebBrowser/WebBrowser.Build.cs +++ b/Engine/Source/Runtime/WebBrowser/WebBrowser.Build.cs @@ -17,14 +17,20 @@ public class WebBrowser : ModuleRules "ApplicationCore", "RHI", "InputCore", - "Slate", - "SlateCore", "Serialization", "HTTP" } ); - if (Target.Platform == UnrealTargetPlatform.Android || + PublicDependencyModuleNames.AddRange( + new string[] + { + "Slate", + "SlateCore" + } + ); + + if (Target.Platform == UnrealTargetPlatform.Android || Target.Platform == UnrealTargetPlatform.IOS || Target.Platform == UnrealTargetPlatform.TVOS) { diff --git a/Engine/Source/Runtime/Windows/D3D11RHI/Private/D3D11StructuredBuffer.cpp b/Engine/Source/Runtime/Windows/D3D11RHI/Private/D3D11StructuredBuffer.cpp index 39eff6fdc7f2..aff010269ca6 100644 --- a/Engine/Source/Runtime/Windows/D3D11RHI/Private/D3D11StructuredBuffer.cpp +++ b/Engine/Source/Runtime/Windows/D3D11RHI/Private/D3D11StructuredBuffer.cpp @@ -201,9 +201,6 @@ void FD3D11DynamicRHI::RHIUnlockStructuredBuffer(FStructuredBufferRHIParamRef St // Copy the contents of the temporary memory buffer allocated for writing into the VB. Direct3DDeviceIMContext->UpdateSubresource(StructuredBuffer->Resource,LockedKey.Subresource,NULL,LockedData->GetData(),LockedData->Pitch,0); - // Check the copy is finished before freeing... - Direct3DDeviceIMContext->Flush(); - // Free the temporary memory buffer. LockedData->FreeData(); } diff --git a/Engine/Source/Runtime/Windows/D3D11RHI/Private/D3D11Texture.cpp b/Engine/Source/Runtime/Windows/D3D11RHI/Private/D3D11Texture.cpp index cb89a659f14b..0798cf06fcd4 100644 --- a/Engine/Source/Runtime/Windows/D3D11RHI/Private/D3D11Texture.cpp +++ b/Engine/Source/Runtime/Windows/D3D11RHI/Private/D3D11Texture.cpp @@ -549,6 +549,13 @@ TD3D11Texture2D* FD3D11DynamicRHI::CreateD3D11Texture2D(uint32 D3D11_USAGE TextureUsage = D3D11_USAGE_DEFAULT; bool bCreateShaderResource = true; + // NV12 doesn't support SRV in NV12 format so don't create SRV for it. + // Todo: add support for SRVs of underneath luminance & chrominance textures. + if (Format == PF_NV12) + { + bCreateShaderResource = false; + } + uint32 ActualMSAACount = NumSamples; uint32 ActualMSAAQuality = GetMaxMSAAQuality(ActualMSAACount); @@ -658,6 +665,12 @@ TD3D11Texture2D* FD3D11DynamicRHI::CreateD3D11Texture2D(uint32 bCreateRTV = true; } } + // NV12 doesn't support RTV in NV12 format so don't create RTV for it. + // Todo: add support for RTVs of underneath luminance & chrominance textures. + if (Format == PF_NV12) + { + bCreateRTV = false; + } if (Flags & TexCreate_UAV) { diff --git a/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/HighlightRecorder.cpp b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/HighlightRecorder.cpp new file mode 100644 index 000000000000..50204916efb3 --- /dev/null +++ b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/HighlightRecorder.cpp @@ -0,0 +1,372 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "HighlightRecorder.h" +#include "WmfMp4Writer.h" +#include "GameplayMediaEncoderSample.h" + +#include "Misc/Paths.h" + +#include "Engine/GameEngine.h" +#include "RenderingThread.h" +#include "Rendering/SlateRenderer.h" +#include "Framework/Application/SlateApplication.h" +#include "ProfilingDebugging/CsvProfiler.h" + +#include "HAL/PlatformTime.h" +#include "HAL/PlatformFilemanager.h" +#include "UnrealEngine.h" +#include "VideoRecordingSystem.h" + +DEFINE_LOG_CATEGORY(WMF); +DEFINE_LOG_CATEGORY(HighlightRecorder); + +WINDOWSPLATFORMFEATURES_START + +////////////////////////////////////////////////////////////////////////// +// console commands for testing + +FAutoConsoleCommand HighlightRecorderStart(TEXT("HighlightRecorder.Start"), TEXT("Starts recording of highlight clip, optional parameter: max duration (float, 30 seconds by default)"), FConsoleCommandWithWorldArgsAndOutputDeviceDelegate::CreateStatic(&FHighlightRecorder::Start)); +FAutoConsoleCommand HighlightRecorderStop(TEXT("HighlightRecorder.Stop"), TEXT("Stops recording of highlight clip"), FConsoleCommandDelegate::CreateStatic(&FHighlightRecorder::StopCmd)); +FAutoConsoleCommand HighlightRecorderPause(TEXT("HighlightRecorder.Pause"), TEXT("Pauses recording of highlight clip"), FConsoleCommandDelegate::CreateStatic(&FHighlightRecorder::PauseCmd)); +FAutoConsoleCommand HighlightRecorderResume(TEXT("HighlightRecorder.Resume"), TEXT("Resumes recording of highlight clip"), FConsoleCommandDelegate::CreateStatic(&FHighlightRecorder::ResumeCmd)); +FAutoConsoleCommand HighlightRecorderSave(TEXT("HighlightRecorder.Save"), TEXT("Saves highlight clip, optional parameters: filename (\"test.mp4\" by default) and max duration (float, secs, duration of ring buffer by default)"), FConsoleCommandWithWorldArgsAndOutputDeviceDelegate::CreateStatic(&FHighlightRecorder::SaveCmd)); + +////////////////////////////////////////////////////////////////////////// + +FHighlightRecorder* FHighlightRecorder::Singleton = nullptr; + +CSV_DECLARE_CATEGORY_EXTERN(WindowsVideoRecordingSystem); + +////////////////////////////////////////////////////////////////////////// + +FHighlightRecorder::FHighlightRecorder() +{ + check(Singleton == nullptr); +} + +FHighlightRecorder::~FHighlightRecorder() +{ + Stop(); + UE_LOG(HighlightRecorder, Log, TEXT("destroyed")); +} + +bool FHighlightRecorder::Start(double RingBufferDurationSecs) +{ + CSV_SCOPED_TIMING_STAT(WindowsVideoRecordingSystem, HighlightRecorder_Start); + + if (State != EState::Stopped) + { + UE_LOG(HighlightRecorder, Error, TEXT("cannot start recording, invalid state: %d"), static_cast(State.Load())); + return false; + } + + RingBuffer.Reset(); + RingBuffer.SetMaxDuration(FTimespan::FromSeconds(RingBufferDurationSecs)); + + RecordingStartTime = FTimespan::FromSeconds(FPlatformTime::Seconds()); + PauseTimestamp = 0; + TotalPausedDuration = 0; + NumPushedFrames = 0; + + if (!FGameplayMediaEncoder::Get()->RegisterListener(this)) + { + return false; + } + + State = EState::Recording; + + UE_LOG(HighlightRecorder, Log, TEXT("recording started, ring buffer %.2f secs"), RingBufferDurationSecs); + + return true; +} + +bool FHighlightRecorder::Pause(bool bPause) +{ + CSV_SCOPED_TIMING_STAT(WindowsVideoRecordingSystem, HighlightRecorder_Pause); + + if (State == EState::Stopped) + { + UE_LOG(HighlightRecorder, Error, TEXT("cannot pause/resume recording, recording is stopped")); + return false; + } + + if (bPause && PauseTimestamp == 0.0) + { + PauseTimestamp = GetRecordingTime(); + State = EState::Paused; + UE_LOG(HighlightRecorder, Log, TEXT("paused")); + } + else if (!bPause && PauseTimestamp != 0.0) + { + FTimespan LastPausedDuration = GetRecordingTime() - PauseTimestamp; + TotalPausedDuration += LastPausedDuration; + PauseTimestamp = 0; + FPlatformMisc::MemoryBarrier(); + State = EState::Recording; + UE_LOG(HighlightRecorder, Log, TEXT("resumed after %.3f s"), LastPausedDuration.GetTotalSeconds()); + } + + return true; +} + +void FHighlightRecorder::Stop() +{ + CSV_SCOPED_TIMING_STAT(WindowsVideoRecordingSystem, HighlightRecorder_Stop); + + FGameplayMediaEncoder::Get()->UnregisterListener(this); + State = EState::Stopped; + + UE_LOG(HighlightRecorder, Log, TEXT("recording stopped")); +} + +FTimespan FHighlightRecorder::GetRecordingTime() const +{ + return FTimespan::FromSeconds(FPlatformTime::Seconds()) - RecordingStartTime - TotalPausedDuration; +} + +void FHighlightRecorder::OnMediaSample(const FGameplayMediaEncoderSample& Sample) +{ + // We might be paused, so don't do anything + if (State != EState::Recording) + { + return; + } + + // Only start pushing video frames once we receive a key frame + if (NumPushedFrames == 0 && Sample.GetType() == EMediaType::Video) + { + if (!Sample.IsVideoKeyFrame()) + { + return; + } + + ++NumPushedFrames; + } + + RingBuffer.Push(Sample); +} + +bool FHighlightRecorder::SaveHighlight(const TCHAR* Filename, FDoneCallback InDoneCallback, double MaxDurationSecs) +{ + CSV_SCOPED_TIMING_STAT(WindowsVideoRecordingSystem, HighlightRecorder_Save); + + if (State == EState::Stopped) + { + UE_LOG(HighlightRecorder, Error, TEXT("cannot save clip when recording is stopped")); + return false; + } + + if (bSaving) + { + UE_LOG(HighlightRecorder, Error, TEXT("saving is busy with the previous clip")); + return false; + } + + UE_LOG(HighlightRecorder, Log, TEXT("start saving to %s, max duration %.3f"), Filename, MaxDurationSecs); + + FString LocalFilename = Filename; + + bSaving = true; + DoneCallback = MoveTemp(InDoneCallback); + + { + CSV_SCOPED_TIMING_STAT(WindowsVideoRecordingSystem, HighlightRecorder_SaveThreadCreation); + BackgroundProcessor.Reset(new FThread(TEXT("Highlight Saving"), [this, LocalFilename, MaxDurationSecs]() + { + SaveHighlightInBackground(LocalFilename, MaxDurationSecs); + })); + } + + return true; +} + +// the bool result is solely for convenience (CHECK_HR) and is ignored as it's a thread function and +// nobody checks it's result. Actual result is notified by the callback. +bool FHighlightRecorder::SaveHighlightInBackground(const FString& Filename, double MaxDurationSecs) +{ + CSV_SCOPED_TIMING_STAT(WindowsVideoRecordingSystem, HighlightRecorder_SaveInBackground); + + double T0 = FPlatformTime::Seconds(); + + bool bRes = true; + + TArray Samples = RingBuffer.GetCopy(); + + do // once + { + if (!InitialiseMp4Writer(Filename)) + { + bRes = false; + break; + } + + int SampleIndex; + FTimespan StartTime; + if (!GetSavingStart(Samples, FTimespan::FromSeconds(MaxDurationSecs), SampleIndex, StartTime)) + { + bRes = false; + break; + } + + checkf(Samples[SampleIndex].IsVideoKeyFrame(), TEXT("t %.3f d %.3f"), Samples[SampleIndex].GetTime().GetTotalSeconds(), Samples[SampleIndex].GetDuration().GetTotalSeconds()); + + if (SampleIndex == Samples.Num()) + { + UE_LOG(HighlightRecorder, Error, TEXT("no samples to save to .mp4")); + bRes = false; + break; + } + + UE_LOG(HighlightRecorder, Verbose, TEXT("writting %d samples to .mp4, %.3f s, starting from %.3f s, index %d"), Samples.Num() - SampleIndex, (Samples.Last().GetTime() - StartTime + Samples.Last().GetDuration()).GetTotalSeconds(), StartTime.GetTotalSeconds(), SampleIndex); + + // get samples starting from `StartTime` and push them into Mp4Writer + for (; SampleIndex != Samples.Num() && !bStopSaving; ++SampleIndex) + { + FGameplayMediaEncoderSample& Sample = Samples[SampleIndex]; + Sample.SetTime(Sample.GetTime() - StartTime); + if (!Mp4Writer->Write(Sample)) + { + bRes = false; + break; + } + } + } while (false); + + if (bRes) + { + if (!Mp4Writer->Finalize()) + { + bRes = false; + } + } + + double PassedSecs = FPlatformTime::Seconds() - T0; + UE_LOG(HighlightRecorder, Log, TEXT("saving to %s %s, took %.3f msecs"), *Filename, bRes ? TEXT("succeeded") : TEXT("failed"), PassedSecs); + + bSaving = false; + + DoneCallback(bRes); + + return bRes; +} + +bool FHighlightRecorder::InitialiseMp4Writer(const FString& Filename) +{ + FString VideoCaptureDir = FPaths::VideoCaptureDir(); + auto& PlatformFile = FPlatformFileManager::Get().GetPlatformFile(); + if (!PlatformFile.DirectoryExists(*VideoCaptureDir)) + { + bool bRes = PlatformFile.CreateDirectory(*VideoCaptureDir); + if (!bRes) + { + UE_LOG(HighlightRecorder, Error, TEXT("Can't create directory %s"), *VideoCaptureDir); + return false; + } + } + + FString FullFilename = PlatformFile.ConvertToAbsolutePathForExternalAppForWrite(*(VideoCaptureDir + Filename)); + + Mp4Writer.Reset(new FWmfMp4Writer); + + if (!Mp4Writer->Initialize(*FullFilename)) + { + return false; + } + + TRefCountPtr AudioType; + if (!FGameplayMediaEncoder::Get()->GetAudioOutputType(AudioType)) + { + return false; + } + + DWORD StreamIndex; + if (!Mp4Writer->CreateStream(AudioType, StreamIndex)) + { + return false; + } + + if (StreamIndex != static_cast(EMediaType::Audio)) + { + UE_LOG(HighlightRecorder, Error, TEXT("Invalid audio stream index: %d"), StreamIndex); + return false; + } + + TRefCountPtr VideoType; + if (!FGameplayMediaEncoder::Get()->GetVideoOutputType(VideoType)) + { + return false; + } + + if (!Mp4Writer->CreateStream(VideoType, StreamIndex)) + { + return false; + } + + if (StreamIndex != static_cast(EMediaType::Video)) + { + UE_LOG(HighlightRecorder, Error, TEXT("Invalid video stream index: %d"), StreamIndex); + return false; + } + + if (!Mp4Writer->Start()) + { + return false; + } + + return true; +} + +// finds index and timestamp of the first sample that should be written to .mp4 +bool FHighlightRecorder::GetSavingStart(const TArray& Samples, FTimespan MaxDuration, int& StartIndex, FTimespan& StartTime) const +// the first sample in .mp4 file should have timestamp 0 and all other timestamps should be relative to the +// first one +// 1) if `MaxDurationSecs` > actual ring buffer duration (last sample timestamp - first) -> we need to save all +// samples from the ring buffer. saving start time = first sample timestamp +// 2) if `MaxDurationSecs` < actual ring buffer duration -> we need to start from the first video key-frame with +// timestamp > than ("cur time" - "max duration to save") +{ + // convert max duration to absolute time + StartTime = GetRecordingTime() - MaxDuration; + + if (Samples.Num() == 0) + { + StartIndex = 0; + return true; + } + + FTimespan FirstTimestamp = Samples[0].GetTime(); + + if (FirstTimestamp > StartTime) + { + StartTime = FirstTimestamp; + StartIndex = 0; + return true; + } + + int i = 0; + bool bFound = false; + for (; i != Samples.Num(); ++i) + { + FTimespan Time = Samples[i].GetTime(); + if (Time >= StartTime && Samples[i].IsVideoKeyFrame()) + { + // correct StartTime to match timestamp of the first sample to be written + StartTime = Time; + bFound = true; + break; + } + } + + if (!bFound) + { + UE_LOG(HighlightRecorder, Error, TEXT("No samples to write to .mp4, max duration: %.3f"), MaxDuration.GetTotalSeconds()); + return false; + } + + StartIndex = i; + + return true; +} + +WINDOWSPLATFORMFEATURES_END + diff --git a/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/HighlightRecorder.h b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/HighlightRecorder.h new file mode 100644 index 000000000000..e78aefc8f933 --- /dev/null +++ b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/HighlightRecorder.h @@ -0,0 +1,194 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "WmfPrivate.h" + +#include "RHI.h" +#include "RHIResources.h" +#include "Containers/CircularQueue.h" +#include "HAL/RunnableThread.h" +#include "HAL/Runnable.h" +#include "HAL/ThreadSafeBool.h" + +#include "WmfRingBuffer.h" + +#include "GameplayMediaEncoder.h" + +class FWmfMp4Writer; + +DECLARE_LOG_CATEGORY_EXTERN(HighlightRecorder, Log, VeryVerbose); + +class FThread final : public FRunnable +{ +public: + using FCallback = TFunction; + + explicit FThread(TCHAR const* ThreadName, const FCallback& Callback) : + Callback(Callback) + { + Thread.Reset(FRunnableThread::Create(this, ThreadName, TPri_BelowNormal)); + } + + void Join() + { + Thread->WaitForCompletion(); + } + + virtual uint32 Run() override + { + Callback(); + return 0; + } + +private: + FCallback Callback; + TUniquePtr Thread; + +private: + FThread(const FThread&) = delete; + FThread& operator=(const FThread&) = delete; +}; + +class FHighlightRecorder final : private IGameplayMediaEncoderListener +{ +public: + FHighlightRecorder(); + ~FHighlightRecorder(); + + enum class EState { Stopped, Recording, Paused }; + + EState GetState() const + { return State; } + + bool Start(double RingBufferDurationSecs); + bool Pause(bool bPause); + void Stop(); + bool IsSaving() const + { + return bSaving; + } + + using FDoneCallback = TFunction; + bool SaveHighlight(const TCHAR* Filename, FDoneCallback DoneCallback, double MaxDurationSecs = 1.0 * 60 * 60); + +private: + bool SaveHighlightInBackground(const FString& Filename, double MaxDurationSecs); + bool InitialiseMp4Writer(const FString& Filename); + bool GetSavingStart(const TArray& Samples, FTimespan MaxDuration, int& OutStartIndex, FTimespan& OutStartTime) const; + + // takes into account if we've been paused and shifts current time back to compensate paused state + // so all timestamps are continuous even over paused pieces + FTimespan GetRecordingTime() const; + + // + // IGameplayMediaEncoderListener implementation + // + void OnMediaSample(const FGameplayMediaEncoderSample& Sample) override; + +private: + TAtomic State{ EState::Stopped }; + + TUniquePtr Mp4Writer; + + FWmfRingBuffer RingBuffer; + // we take note of how long we've been paused and then "shift" samples timestamps by paused duration + // so effectively gluing different pieces of video together + + uint64 NumPushedFrames = 0; + + FTimespan RecordingStartTime = 0; + + // if currently paused, when it happened + FTimespan PauseTimestamp = 0; + // for how long recording has been paused since it's started + FTimespan TotalPausedDuration = 0; + + TUniquePtr BackgroundProcessor; + FDoneCallback DoneCallback; + FThreadSafeBool bSaving = false; + FThreadSafeBool bStopSaving = false; + +#pragma region testing +public: + static void Start(const TArray& Args, UWorld*, FOutputDevice& Output) + { + // Initialize the Singleton if necessary. This is only useful if using project other than Fortnite. E.g: QAGame. + // When using QAGame, there is no HighlightFeature, and we just use these direct console commands to test + if (!Singleton) + { + Singleton = new FHighlightRecorder(); + } + + if (Args.Num() > 1) + { + Output.Logf(ELogVerbosity::Error, TEXT("zero or one parameter expected: Start [max_duration_secs=30.0]")); + return; + } + + double MaxDurationSecs = 30; + if (Args.Num() == 1) + { + MaxDurationSecs = FCString::Atod(*Args[0]); + } + Get()->Start(MaxDurationSecs); + } + + static void StopCmd() + { + Get()->Stop(); + delete Singleton; + Singleton = nullptr; + } + + static void PauseCmd() + { + Get()->Pause(true); + } + + static void ResumeCmd() + { + Get()->Pause(false); + } + + static void SaveCmd(const TArray& Args, UWorld*, FOutputDevice& Output) + { + if (Args.Num() > 2) + { + Output.Logf(ELogVerbosity::Error, TEXT("0-2 parameters expected: Save [filename=\"test.mp4\"] [max_duration_secs= ring buffer duration]")); + return; + } + + FString Filename = "test.mp4"; + if (Args.Num() >= 1) + { + Filename = Args[0]; + } + + double MaxDurationSecs = 1 * 60 * 60; + if (Args.Num() == 2) + { + MaxDurationSecs = FCString::Atod(*Args[1]); + } + + Get()->SaveHighlight( + *Filename, + [](bool bRes) + { + UE_LOG(HighlightRecorder, Log, TEXT("saving done: %d"), bRes); + }, + MaxDurationSecs + ); + } + +private: + static FHighlightRecorder* Get() + { + check(Singleton); + return Singleton; + } + static FHighlightRecorder* Singleton; +#pragma endregion testing +}; + + diff --git a/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsPlatformFeatures.cpp b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsPlatformFeatures.cpp new file mode 100644 index 000000000000..b230511622bf --- /dev/null +++ b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsPlatformFeatures.cpp @@ -0,0 +1,30 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "WindowsPlatformFeatures.h" +#include "WmfPrivate.h" +#include "WindowsVideoRecordingSystem.h" +#include "Misc/CommandLine.h" + +IMPLEMENT_MODULE(FWindowsPlatformFeaturesModule, WindowsPlatformFeatures); + +WINDOWSPLATFORMFEATURES_START + +FWindowsPlatformFeaturesModule::FWindowsPlatformFeaturesModule() +{ + // load generic modules + StartupModules(); +} + +IVideoRecordingSystem* FWindowsPlatformFeaturesModule::GetVideoRecordingSystem() +{ + static FWindowsVideoRecordingSystem VideoRecordingSystem; + return &VideoRecordingSystem; +} + +bool FWindowsPlatformFeaturesModule::StartupModules() +{ + FModuleManager::Get().LoadModule(TEXT("GameplayMediaEncoder")); + return true; +} + +WINDOWSPLATFORMFEATURES_END diff --git a/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsPlatformFeatures.h b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsPlatformFeatures.h new file mode 100644 index 000000000000..943f47738146 --- /dev/null +++ b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsPlatformFeatures.h @@ -0,0 +1,26 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "PlatformFeatures.h" +#include "WindowsPlatformFeaturesCommon.h" + +class FWindowsPlatformFeaturesModule : public IPlatformFeaturesModule +{ +public: + + /** Creates a new instance of the audio device implemented by the module. */ + FWindowsPlatformFeaturesModule(); + + virtual IVideoRecordingSystem* GetVideoRecordingSystem() override; + +private: + /** + * Load global/generic modules, and perform any initialization + */ + bool StartupModules(); + +}; + + diff --git a/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsPlatformFeaturesCommon.h b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsPlatformFeaturesCommon.h new file mode 100644 index 000000000000..0613842f9e83 --- /dev/null +++ b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsPlatformFeaturesCommon.h @@ -0,0 +1,21 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +/** + * Used enable/disable optimization for the entire module. + * + */ +#if UE_BUILD_SHIPPING + #define WINDOWSPLATFORMFEATURES_DEBUG 0 +#else + #define WINDOWSPLATFORMFEATURES_DEBUG 0 +#endif + +#if WINDOWSPLATFORMFEATURES_DEBUG + #define WINDOWSPLATFORMFEATURES_START PRAGMA_DISABLE_OPTIMIZATION + #define WINDOWSPLATFORMFEATURES_END PRAGMA_ENABLE_OPTIMIZATION +#else + #define WINDOWSPLATFORMFEATURES_START + #define WINDOWSPLATFORMFEATURES_END +#endif diff --git a/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsVideoRecordingSystem.cpp b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsVideoRecordingSystem.cpp new file mode 100644 index 000000000000..d240a46a4149 --- /dev/null +++ b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsVideoRecordingSystem.cpp @@ -0,0 +1,264 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. +#include "WindowsVideoRecordingSystem.h" +#include "Modules/ModuleManager.h" +#include "Engine/GameEngine.h" +#include "RenderingThread.h" +#include "Rendering/SlateRenderer.h" +#include "Framework/Application/SlateApplication.h" +#include "GameFramework/GameModeBase.h" +#include "Features/IModularFeatures.h" +#include "PlatformFeatures.h" + +#include "ProfilingDebugging/CsvProfiler.h" + +#include "HighlightRecorder.h" + +DEFINE_VIDEOSYSTEMRECORDING_STATS +DEFINE_LOG_CATEGORY(WindowsVideoRecordingSystem); +CSV_DEFINE_CATEGORY(WindowsVideoRecordingSystem, true); + +WINDOWSPLATFORMFEATURES_START + +FWindowsVideoRecordingSystem::FWindowsVideoRecordingSystem() +{ + UE_LOG(WindowsVideoRecordingSystem, Verbose, TEXT("%s"), __FUNCTIONW__); + + EnableRecording(true); +} + +FWindowsVideoRecordingSystem::~FWindowsVideoRecordingSystem() +{ + UE_LOG(WindowsVideoRecordingSystem, Verbose, TEXT("%s"), __FUNCTIONW__); + + EnableRecording(false); +} + +void FWindowsVideoRecordingSystem::EnableRecording(bool bEnableRecording) +{ + SCOPE_CYCLE_COUNTER(STAT_VideoRecordingSystem_EnableRecording); + CSV_SCOPED_TIMING_STAT(WindowsVideoRecordingSystem, EnableRecording); + + if (!FApp::CanEverRender()) + { + UE_LOG(WindowsVideoRecordingSystem, Warning, TEXT("Can't enable recording because this App can't render.")); + return; + } + + UE_LOG(WindowsVideoRecordingSystem, Verbose, TEXT("%s"), __FUNCTIONW__); + if (bEnableRecording && !Recorder) + { + Recorder.Reset(new FHighlightRecorder()); + } + else if (!bEnableRecording && Recorder) + { + Recorder.Reset(); + } +} + +bool FWindowsVideoRecordingSystem::IsEnabled() const +{ + UE_LOG(WindowsVideoRecordingSystem, Verbose, TEXT("%s"), __FUNCTIONW__); + return Recorder.Get()==nullptr ? false : true; +} + +void FWindowsVideoRecordingSystem::NextRecording() +{ + FString Path = FPaths::VideoCaptureDir(); + if (Parameters.bAutoContinue) + { + CurrentFilename = Path + FString::Printf(TEXT("%s_%d.mp4"), *BaseFilename, ++RecordingIndex); + } + else + { + CurrentFilename = Path + BaseFilename; + } +} + +bool FWindowsVideoRecordingSystem::NewRecording(const TCHAR* DestinationFileName, FVideoRecordingParameters InParameters) +{ + SCOPE_CYCLE_COUNTER(STAT_VideoRecordingSystem_NewRecording); + CSV_SCOPED_TIMING_STAT(WindowsVideoRecordingSystem, NewRecording); + + UE_LOG(WindowsVideoRecordingSystem, Verbose, TEXT("%s"), __FUNCTIONW__); + + if (!IsEnabled()) + { + UE_LOG(WindowsVideoRecordingSystem, Warning, TEXT("%s : can't open a new recording. Recording is disabled"), __FUNCTIONW__); + return false; + } + + if (RecordState != EVideoRecordingState::None) + { + UE_LOG(WindowsVideoRecordingSystem, Warning, TEXT("FWindowsVideoRecordingSystem::NewRecording: can't open a new recording, one is already in progress.")); + return false; + } + + Parameters = InParameters; + + RecordingIndex = 0; + BaseFilename = "recording"; + CyclesBeforePausing = 0; + CurrentStartRecordingCycles = 0; + + if (DestinationFileName != nullptr) + { + BaseFilename = DestinationFileName; + } + + NextRecording(); + + if (Recorder->GetState() == FHighlightRecorder::EState::Stopped) + { + // Call Start to initialize the internals, and pause right away + if (Recorder->Start(Parameters.RecordingLengthSeconds) == false) + { + // this could be if running with -nullrhi, and the Pause below will crash + return false; + } + } + bool bPauseRet = Recorder->Pause(true); + check(bPauseRet); + RecordState = EVideoRecordingState::Paused; + + if (Parameters.bAutoStart) + { + StartRecording(); + } + + return true; +} + +void FWindowsVideoRecordingSystem::StartRecording() +{ + SCOPE_CYCLE_COUNTER(STAT_VideoRecordingSystem_StartRecording); + CSV_SCOPED_TIMING_STAT(WindowsVideoRecordingSystem, StartRecording); + + UE_LOG(WindowsVideoRecordingSystem, Verbose, TEXT("%s"), __FUNCTIONW__); + + if (RecordState != EVideoRecordingState::Paused) + { + UE_LOG(WindowsVideoRecordingSystem, Warning, TEXT("%s: can't start recording, invalid state"), __FUNCTIONW__); + return; + } + + UE_LOG(WindowsVideoRecordingSystem, Log, TEXT("%s: starting a recording"), __FUNCTIONW__); + + if (Recorder->GetState() == FHighlightRecorder::EState::Stopped) + { + Recorder->Start(Parameters.RecordingLengthSeconds); + } + if (Recorder->GetState() == FHighlightRecorder::EState::Paused) + { + bool bPauseRet = Recorder->Pause(false); + check(bPauseRet); + } + + RecordState = EVideoRecordingState::Recording; + CurrentStartRecordingCycles = FPlatformTime::Cycles64(); +} + +void FWindowsVideoRecordingSystem::PauseRecording() +{ + SCOPE_CYCLE_COUNTER(STAT_VideoRecordingSystem_PauseRecording); + CSV_SCOPED_TIMING_STAT(WindowsVideoRecordingSystem, PauseRecording); + + UE_LOG(WindowsVideoRecordingSystem, Verbose, TEXT("%s"), __FUNCTIONW__); + + if (RecordState != EVideoRecordingState::Recording) + { + UE_LOG(WindowsVideoRecordingSystem, Warning, TEXT("%s: can't pause recording, invalid state."), __FUNCTIONW__); + return; + } + + UE_LOG(WindowsVideoRecordingSystem, Log, TEXT("%s: pausing a recording"), __FUNCTIONW__); + + CyclesBeforePausing += FPlatformTime::Cycles64() - CurrentStartRecordingCycles; + + bool bPauseRet = Recorder->Pause(true); + check(bPauseRet); + + RecordState = EVideoRecordingState::Paused; +} + +uint64 FWindowsVideoRecordingSystem::GetMinimumRecordingSeconds() const +{ + return 6; +} + +uint64 FWindowsVideoRecordingSystem::GetMaximumRecordingSeconds() const +{ + return 900; +} + +float FWindowsVideoRecordingSystem::GetCurrentRecordingSeconds() const +{ + float Ret = (FPlatformTime::Cycles64() - CurrentStartRecordingCycles + CyclesBeforePausing) * FPlatformTime::GetSecondsPerCycle(); + UE_LOG(WindowsVideoRecordingSystem, Verbose, TEXT("%s: reporting %f"), __FUNCTIONW__, Ret); + return Ret; +} + +// #RVF : Make use of Comment ? +void FWindowsVideoRecordingSystem::FinalizeRecording(const bool bSaveRecording, const FText& Title, const FText& Comment, const bool bStopAutoContinue/* = true*/) +{ + SCOPE_CYCLE_COUNTER(STAT_VideoRecordingSystem_FinalizeRecording); + CSV_SCOPED_TIMING_STAT(WindowsVideoRecordingSystem, FinalizeRecording); + + UE_LOG(WindowsVideoRecordingSystem, Verbose, TEXT("%s"), __FUNCTIONW__); + + if (RecordState == EVideoRecordingState::None) + { + UE_LOG(WindowsVideoRecordingSystem, Warning, TEXT("%s: can't finalize recording, invalid state."), __FUNCTIONW__); + return; + } + + if (bSaveRecording) + { + bool bRet = Recorder->SaveHighlight(*CurrentFilename, [this, bStopAutoContinue, Path = CurrentFilename](bool bRes) + { + // Execute the Finalize event on the GameThread + FGraphEventRef FinalizeEvent = FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( + FSimpleDelegateGraphTask::FDelegate::CreateRaw(this, &FWindowsVideoRecordingSystem::FinalizeCallbackOnGameThread, + bRes, Parameters.bAutoContinue && !bStopAutoContinue, Path, true), + TStatId(), nullptr, ENamedThreads::GameThread); + }); + + if (!bRet) + { + UE_LOG(WindowsVideoRecordingSystem, Warning, TEXT("%s: can't finalize recording."), __FUNCTIONW__); + return; + } + + RecordState = EVideoRecordingState::Finalizing; + } + else + { + // Drop this recording + FinalizeCallbackOnGameThread(false, Parameters.bAutoContinue && !bStopAutoContinue, CurrentFilename, false); + } + +} + +void FWindowsVideoRecordingSystem::FinalizeCallbackOnGameThread(bool bSaved, bool bAutoContinue, FString Path, bool bBroadcast) +{ + UE_LOG(WindowsVideoRecordingSystem, Verbose, TEXT("%s"), __FUNCTIONW__); + RecordState = EVideoRecordingState::None; + + if (bAutoContinue) + { + NextRecording(); + RecordState = EVideoRecordingState::Recording; + } + + if (bBroadcast) + { + OnVideoRecordingFinalized.Broadcast(bSaved, Path); + } +} + +EVideoRecordingState FWindowsVideoRecordingSystem::GetRecordingState() const +{ + return RecordState; +} + +WINDOWSPLATFORMFEATURES_END + diff --git a/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsVideoRecordingSystem.h b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsVideoRecordingSystem.h new file mode 100644 index 000000000000..e2eabf4cef0a --- /dev/null +++ b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WindowsVideoRecordingSystem.h @@ -0,0 +1,59 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "VideoRecordingSystem.h" + +#include "RHI.h" +#include "RHIResources.h" + +#include "HAL/ThreadSafeBool.h" +#include "CoreMinimal.h" +#include "AudioMixerDevice.h" +#include "RHI.h" +#include "RHIResources.h" +#include "PipelineStateCache.h" +#include "WindowsPlatformFeaturesCommon.h" + +DECLARE_LOG_CATEGORY_EXTERN(WindowsVideoRecordingSystem, VeryVerbose, VeryVerbose); + +class FHighlightRecorder; + +class FWindowsVideoRecordingSystem : public IVideoRecordingSystem +{ +public: + FWindowsVideoRecordingSystem(); + ~FWindowsVideoRecordingSystem() override; + + // IVideoRecordingSystem interface + void EnableRecording(const bool bEnableRecording) override; + bool IsEnabled() const override; + bool NewRecording(const TCHAR* DestinationFileName, FVideoRecordingParameters Parameters = FVideoRecordingParameters()) override; + void StartRecording() override; + void PauseRecording() override; + virtual uint64 GetMinimumRecordingSeconds() const override; + virtual uint64 GetMaximumRecordingSeconds() const override; + float GetCurrentRecordingSeconds() const override; + void FinalizeRecording(const bool bSaveRecording, const FText& Title, const FText& Comment, const bool bStopAutoContinue = true) override; + EVideoRecordingState GetRecordingState() const override; + +private: + void NextRecording(); + void FinalizeCallbackOnGameThread(bool bSaved, bool bAutoContinue, FString Path, bool bBroadcast); + + TAtomic RecordState{ EVideoRecordingState::None }; + + FVideoRecordingParameters Parameters; + + FString BaseFilename; + FString CurrentFilename; + uint64 RecordingIndex = 0; + uint64 CurrentStartRecordingCycles = 0; + uint64 CyclesBeforePausing = 0; + + // If this is nullptr, then it means video recording is not enabled + TUniquePtr Recorder; + + bool bAudioFormatChecked = false; +}; + diff --git a/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfMp4Writer.cpp b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfMp4Writer.cpp new file mode 100644 index 000000000000..8a2aad7894b9 --- /dev/null +++ b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfMp4Writer.cpp @@ -0,0 +1,59 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "WmfMp4Writer.h" + +#include "GameplayMediaEncoderSample.h" + +#if WMFMEDIA_SUPPORTED_PLATFORM + #pragma comment(lib, "mfplat") + #pragma comment(lib, "mfuuid") + #pragma comment(lib, "Mfreadwrite") +#endif + +DECLARE_LOG_CATEGORY_EXTERN(MP4, Log, VeryVerbose); + +DEFINE_LOG_CATEGORY(MP4); + +WINDOWSPLATFORMFEATURES_START + +bool FWmfMp4Writer::Initialize(const TCHAR* Filename) +{ + CHECK_HR(MFCreateSinkWriterFromURL(Filename, nullptr, nullptr, Writer.GetInitReference())); + UE_LOG(WMF, Verbose, TEXT("Initialised Mp4Writer for %s"), Filename); + return true; +} + +bool FWmfMp4Writer::CreateStream(IMFMediaType* StreamType, DWORD& StreamIndex) +{ + CHECK_HR(Writer->AddStream(StreamType, &StreamIndex)); + // no transcoding here so input type is the same as output type + CHECK_HR(Writer->SetInputMediaType(StreamIndex, StreamType, nullptr)); + return true; +} + +bool FWmfMp4Writer::Start() +{ + CHECK_HR(Writer->BeginWriting()); + return true; +} + +bool FWmfMp4Writer::Write(const FGameplayMediaEncoderSample& Sample) +{ + CHECK_HR(Writer->WriteSample(static_cast(Sample.GetType()), const_cast(Sample.GetSample()))); + + UE_LOG(MP4, VeryVerbose, TEXT("stream #%d: time %.3f, duration %.3f%s"), static_cast(Sample.GetType()), Sample.GetTime().GetTotalSeconds(), Sample.GetDuration().GetTotalSeconds(), Sample.IsVideoKeyFrame() ? TEXT(", key-frame") : TEXT("")); + + return true; +} + +bool FWmfMp4Writer::Finalize() +{ + CHECK_HR(Writer->Finalize()); + UE_LOG(WMF, VeryVerbose, TEXT("Closed .mp4")); + + return true; +} + +WINDOWSPLATFORMFEATURES_END + + diff --git a/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfMp4Writer.h b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfMp4Writer.h new file mode 100644 index 000000000000..78080728dae0 --- /dev/null +++ b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfMp4Writer.h @@ -0,0 +1,22 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "WmfPrivate.h" + +#include "Math/NumericLimits.h" +#include "GameplayMediaEncoderSample.h" + +class FWmfMp4Writer final +{ +public: + bool Initialize(const TCHAR* Filename); + bool CreateStream(IMFMediaType* StreamType, DWORD& StreamIndex); + bool Start(); + bool Write(const FGameplayMediaEncoderSample& Sample); + bool Finalize(); + +private: + TRefCountPtr Writer; +}; + diff --git a/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfPrivate.h b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfPrivate.h new file mode 100644 index 000000000000..5d195c4bed62 --- /dev/null +++ b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfPrivate.h @@ -0,0 +1,82 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "Logging/LogMacros.h" +#include "CoreMinimal.h" + +#define WMFMEDIA_SUPPORTED_PLATFORM (PLATFORM_WINDOWS && (WINVER >= 0x0600 /*Vista*/) && !UE_SERVER) + +DECLARE_LOG_CATEGORY_EXTERN(WMF, Log, VeryVerbose); + +#include "Windows/AllowWindowsPlatformTypes.h" +THIRD_PARTY_INCLUDES_START + //#include + #include + #include + #include + #include + #include + #include + #include +THIRD_PARTY_INCLUDES_END + +#include "WindowsPlatformFeaturesCommon.h" + +inline const FString GetComErrorDescription(HRESULT Res) +{ + const uint32 BufSize = 4096; + WIDECHAR buffer[4096]; + if (::FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, + nullptr, + Res, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), + buffer, + sizeof(buffer) / sizeof(*buffer), + nullptr)) + { + return buffer; + } + else + { + return TEXT("[cannot find error description]"); + } +} + + +#include "Windows/HideWindowsPlatformTypes.h" + + +// macro to deal with COM calls inside a function that returns `false` on error +#define CHECK_HR(COM_call)\ + {\ + HRESULT Res = COM_call;\ + if (FAILED(Res))\ + {\ + UE_LOG(WMF, Error, TEXT("`" #COM_call "` failed: 0x%X - %s"), Res, *GetComErrorDescription(Res));\ + return false;\ + }\ + } + +// macro to deal with COM calls inside COM method (that returns HRESULT) +#define CHECK_HR_COM(COM_call)\ + {\ + HRESULT Res = COM_call;\ + if (FAILED(Res))\ + {\ + UE_LOG(WMF, Error, TEXT("`" #COM_call "` failed: 0x%X - %s"), Res, *GetComErrorDescription(Res));\ + return Res;\ + }\ + } + +// macro to deal with COM calls inside COM method (that simply returns) +#define CHECK_HR_VOID(COM_call)\ + {\ + HRESULT Res = COM_call;\ + if (FAILED(Res))\ + {\ + UE_LOG(WMF, Error, TEXT("`" #COM_call "` failed: 0x%X - %s"), Res, *GetComErrorDescription(Res));\ + return;\ + }\ + } + diff --git a/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfRingBuffer.cpp b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfRingBuffer.cpp new file mode 100644 index 000000000000..355ed2e82282 --- /dev/null +++ b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfRingBuffer.cpp @@ -0,0 +1,137 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#include "WmfRingBuffer.h" +#include "Misc/ScopeLock.h" + +DECLARE_LOG_CATEGORY_EXTERN(WmfRingBuffer, Log, VeryVerbose); +DEFINE_LOG_CATEGORY(WmfRingBuffer); + +WINDOWSPLATFORMFEATURES_START + +void FWmfRingBuffer::Push(const FGameplayMediaEncoderSample& Sample) +{ + check(MaxDuration != 0); + + FScopeLock Lock(&Mutex); + + if (Samples.Num() == 0 && Sample.GetType() == EMediaType::Audio) + // start always from video sample for simplicity of `Cleanup` impl + { + // drop + } + else if (Samples.Num() == 0) + { + Samples.Add(Sample); + } + else + // video encoding takes longer than audio thus video encoded samples arrive later and need to be placed + // inside the container. Video also is not strictly timestamp-ordered (maybe due to B-frames) + { + FTimespan TimestampToInsert = Sample.GetTime(); + + int i = Samples.Num() - 1; + while (true) + { + if (Samples[i].GetType() == Sample.GetType() // don't change order of same stream cos video is not strictly timestamp-ordered (B-Frames) + || TimestampToInsert >= Samples[i].GetTime()) + { + Samples.Insert(Sample, i + 1); + break; + } + + if (i == 0) + { + if (Sample.GetType() == EMediaType::Video) + { + Samples.Insert(Sample, 0); + } + // else: the first sample in the buffer always should be video key-frame, just drop audio sample + // this can happen during debugging due to big gaps in timestamps + + break; + } + + --i; + } + + // cleanup only on receiving key-frame and only when ring-buffer if full + if (!bCleanupPaused && Sample.IsVideoKeyFrame()) + { + while (GetDuration() > GetMaxDuration()) + { + Cleanup(); + } + } + } +} + +void FWmfRingBuffer::Cleanup() +// removes a/v samples grouped by the oldest key-frame period +{ + FScopeLock Lock(&Mutex); + + check(Samples.Num() != 0); + + check(Samples[0].IsVideoKeyFrame()); + + // find the second key-frame + int i = 1; // skip the first sample which is a keyframe + bool bFound = false; + for (; i != Samples.Num(); ++i) + { + if (Samples[i].IsVideoKeyFrame()) + { + bFound = true; + break; + } + } + check(bFound); + + // remove key-frame period + Samples.RemoveAt(0, i, false); + check(Samples[0].IsVideoKeyFrame()); + + UE_LOG(WmfRingBuffer, VeryVerbose, TEXT("%d samples, %.3f s, %.3f - %.3f:%.3f"), Samples.Num(), GetDuration().GetTotalSeconds(), Samples[0].GetTime().GetTotalSeconds(), Samples.Last().GetTime().GetTotalSeconds(), Samples.Last().GetDuration().GetTotalSeconds()); +} + +void FWmfRingBuffer::PauseCleanup(bool bPause) +{ + bCleanupPaused = bPause; +} + +FTimespan FWmfRingBuffer::GetDuration() const +{ + if (Samples.Num() == 0) + { + return 0; + } + + return Samples.Last().GetTime() - Samples[0].GetTime(); +} + +TArray FWmfRingBuffer::GetCopy() +{ + FScopeLock Lock(&Mutex); + + TArray Copy; + Copy.Reset(Samples.Num()); + + for (const auto& Sample: Samples) + { + // cloning is required because during saving a copy of ring buffer we modify samples timestamps. + // using samples references shared between ring buffer and its copy being saved would cause ring + // buffer timestamp logic corruption + Copy.Add(Sample.Clone()); + } + + return Copy; +} + +void FWmfRingBuffer::Reset() +{ + FScopeLock Lock(&Mutex); + Samples.Empty(); +} + +WINDOWSPLATFORMFEATURES_END + diff --git a/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfRingBuffer.h b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfRingBuffer.h new file mode 100644 index 000000000000..bc6a82cfaf29 --- /dev/null +++ b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/Private/WmfRingBuffer.h @@ -0,0 +1,38 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "WmfPrivate.h" + +#include "HAL/ThreadSafeBool.h" +#include "GameplayMediaEncoderSample.h" + +class FWmfRingBuffer +{ +public: + FTimespan GetMaxDuration() const + { return MaxDuration; } + + void SetMaxDuration(FTimespan InMaxDuration) + { MaxDuration = InMaxDuration; } + + FTimespan GetDuration() const; + + void Push(const FGameplayMediaEncoderSample& Sample); + + void PauseCleanup(bool bPause); + + TArray GetCopy(); + + void Reset(); + +private: + void Cleanup(); + +private: + FTimespan MaxDuration = 0; + TArray Samples; + FCriticalSection Mutex; + FThreadSafeBool bCleanupPaused = false; +}; + diff --git a/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/WindowsPlatformFeatures.Build.cs b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/WindowsPlatformFeatures.Build.cs new file mode 100644 index 000000000000..92d35abb5275 --- /dev/null +++ b/Engine/Source/Runtime/Windows/WindowsPlatformFeatures/WindowsPlatformFeatures.Build.cs @@ -0,0 +1,30 @@ +// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. + +using System.IO; +using UnrealBuildTool; + +public class WindowsPlatformFeatures : ModuleRules +{ + public WindowsPlatformFeatures(ReadOnlyTargetRules Target) : base(Target) + { + // NOTE: General rule is not to access the private folder of another module, + // but to use the ISubmixBufferListener interface, we need to include some private headers + PrivateIncludePaths.Add(System.IO.Path.Combine(Directory.GetCurrentDirectory(), "./Runtime/AudioMixer/Private")); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "ApplicationCore", + "Core", + "CoreUObject", + "Engine", + "AudioMixer", + "GameplayMediaEncoder" + } + ); + + PublicDelayLoadDLLs.Add("mfplat.dll"); + PublicDelayLoadDLLs.Add("mfuuid.dll"); + PublicDelayLoadDLLs.Add("Mfreadwrite.dll"); + } +} diff --git a/Engine/Source/ThirdParty/GoogleARCore/GoogleARCoreSDK.tps b/Engine/Source/ThirdParty/GoogleARCore/GoogleARCoreSDK.tps new file mode 100644 index 000000000000..4e917ad60f06 --- /dev/null +++ b/Engine/Source/ThirdParty/GoogleARCore/GoogleARCoreSDK.tps @@ -0,0 +1,15 @@ + + + GoogleARCore SDK + /Engine/Source/ThirdParty/GoogleARCore/ + 2016-06-07T11:13:40.4185335-04:00 + Allows development of apps for ARCore. + + https://github.com/google-ar/arcore-android-sdk/blob/master/LICENSE + + Licensees + Git + P4 + + /Engine/Source/ThirdParty/Licenses/GoogleARCoreSDK_License.txt + diff --git a/Engine/Source/ThirdParty/GoogleVR/LICENSE b/Engine/Source/ThirdParty/GoogleVR/LICENSE index d64569567334..7a44500e2c96 100644 --- a/Engine/Source/ThirdParty/GoogleVR/LICENSE +++ b/Engine/Source/ThirdParty/GoogleVR/LICENSE @@ -1,3 +1,5 @@ +Except as indicated at the end of this LICENSE file, files in this SDK are +licensed as follows: Apache License Version 2.0, January 2004 @@ -200,3 +202,16 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +=============================================================================== + +All files in the following folders: +- Engine/Source/ThirdParty/GoogleVR/lib/android/ +- Engine/Source/ThirdParty/GoogleVR/lib/common_library/ +- Engine/Source/ThirdParty/GoogleVR/lib/ios/ +- Engine/Source/ThirdParty/GoogleVR/lib/mac/ + +are licensed as follows: + +Coverd by the Google APIs Terms of Service at +https://developers.google.com/terms/ diff --git a/Engine/Source/ThirdParty/Licenses/GoogleARCoreSDK_License.txt b/Engine/Source/ThirdParty/Licenses/GoogleARCoreSDK_License.txt new file mode 100644 index 000000000000..7c5d59e39797 --- /dev/null +++ b/Engine/Source/ThirdParty/Licenses/GoogleARCoreSDK_License.txt @@ -0,0 +1,201 @@ +Except as indicated at the end of this LICENSE file, +files in this SDK are licensed as follows: + + Copyright (c) 2017, Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + +=============================================================================== + +All files in the following folders: +- Engine/Source/ThirdParty/GoogleARCore/lib/ + +are licensed as follows: + +Covered by the **Google APIs Terms of Service** at +[https://developers.google.com/terms/](https://developers.google.com/terms/) diff --git a/Engine/Source/ThirdParty/Licenses/GoogleVRSDK_License.txt b/Engine/Source/ThirdParty/Licenses/GoogleVRSDK_License.txt index 1102552b8bb1..6fcfddead152 100644 --- a/Engine/Source/ThirdParty/Licenses/GoogleVRSDK_License.txt +++ b/Engine/Source/ThirdParty/Licenses/GoogleVRSDK_License.txt @@ -1,14 +1,7 @@ - Copyright (c) 2015, Google Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +Copyright (c) 2015, Google Inc. +Except as indicated at the end of this file, files in this SDK are licensed +as follows: Apache License Version 2.0, January 2004 @@ -185,4 +178,17 @@ incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - END OF TERMS AND CONDITIONS \ No newline at end of file + END OF TERMS AND CONDITIONS + +=============================================================================== + +All files in the following folders: +- Engine/Source/ThirdParty/GoogleVR/lib/android/ +- Engine/Source/ThirdParty/GoogleVR/lib/common_library/ +- Engine/Source/ThirdParty/GoogleVR/lib/ios/ +- Engine/Source/ThirdParty/GoogleVR/lib/mac/ + +are licensed as follows: + +Coverd by the Google APIs Terms of Service at +https://developers.google.com/terms/ diff --git a/Engine/Source/ThirdParty/Vivox/vivox-sdk/Include/vivox-config.h b/Engine/Source/ThirdParty/Vivox/vivox-sdk/Include/vivox-config.h index 772ed04e45db..7026ccc40bd6 100644 --- a/Engine/Source/ThirdParty/Vivox/vivox-sdk/Include/vivox-config.h +++ b/Engine/Source/ThirdParty/Vivox/vivox-sdk/Include/vivox-config.h @@ -23,13 +23,13 @@ */ #pragma once -#define SDK_VERSION "4.9.0002.31657" +#define SDK_VERSION "4.9.0002.31672" #define SDK_BRANCH "HEAD" #define VERSION_MAJOR 4 #define VERSION_MINOR 9 /* so VERSION_MICRO (.e.g. 0008) is not interpreted as octal */ #define VERSION_MICRO (10002 - 10000) -#define VERSION_BUILD 31657 +#define VERSION_BUILD 31672 -#define VERSION_HASH "e3a1bd6b" +#define VERSION_HASH "86742c7e"