static void ParseCodeLink(const FString &InternalLink) { // Tokens used by the code parsing. Details in the parse section static const FString ProjectSpecifier(TEXT("[PROJECTPATH]")); static const FString ProjectPathSpecifier(TEXT("[PROJECT]")); static const FString EnginePathSpecifier(TEXT("[ENGINEPATH]")); FString Path; int32 Line = 0; int32 Col = 0; TArray<FString> Tokens; InternalLink.ParseIntoArray(Tokens, TEXT(","), 0); int32 TokenStringsCount = Tokens.Num(); if (TokenStringsCount > 0) { Path = Tokens[0]; } if (TokenStringsCount > 1) { TTypeFromString<int32>::FromString(Line, *Tokens[1]); } if (TokenStringsCount > 2) { TTypeFromString<int32>::FromString(Col, *Tokens[2]); } ISourceCodeAccessModule& SourceCodeAccessModule = FModuleManager::LoadModuleChecked<ISourceCodeAccessModule>("SourceCodeAccess"); ISourceCodeAccessor& SourceCodeAccessor = SourceCodeAccessModule.GetAccessor(); if (Path.Contains(EnginePathSpecifier) == true) { // replace engine path specifier with path to engine Path.ReplaceInline(*EnginePathSpecifier, *FPaths::EngineDir()); } if (Path.Contains(ProjectSpecifier) == true) { // replace project specifier with path to project Path.ReplaceInline(*ProjectSpecifier, FApp::GetGameName()); } if (Path.Contains(ProjectPathSpecifier) == true) { // replace project specifier with path to project Path.ReplaceInline(*ProjectPathSpecifier, *FPaths::GetProjectFilePath()); } Path = FPaths::ConvertRelativePathToFull(Path); SourceCodeAccessor.OpenFileAtLine(Path, Line, Col); if( FEngineAnalytics::IsAvailable() ) { TArray<FAnalyticsEventAttribute> EventAttributes; EventAttributes.Add(FAnalyticsEventAttribute(TEXT("CodeLink"), InternalLink)); FEngineAnalytics::GetProvider().RecordEvent( TEXT("Rocket.Tutorials.CodeLinkClicked"), EventAttributes ); } }
/** * @EventName Editor.AbnormalShutdown * * @Trigger Fired only by the editor at startup, once for each "abnormal shutdown" detected that has not already been sent. * * @Type Static * * @EventParam SessionId Analytics SessionID of the session that abnormally terminated. * @EventParam EngineVersion EngineVersion of the session that abnormally terminated. * @EventParam ShutdownType - one of Crashed, Debugger, or AbormalShutdown * * Crashed - we definitely detected a crash (whether or not a debugger was attached) * * Debugger - the session crashed or shutdown abnormally, but we had a debugger attached at startup, so abnormal termination is much more likely because the user was debugging. * * AbnormalShutdown - this happens when we didn't detect a normal shutdown, but none of the above cases is the cause. * @EventParam Timestamp - the UTC time of the last known time the crashed session was running, within 5 minutes. * * @TODO: Debugger should be a completely separate flag, since it's orthogonal to whether we detect a crash or shutdown. * * @Comments The editor will only try to check for abnormal terminations if it determines it is a real editor run (not a commandlet or PIE, or editor -game run), and the user has not disabled sending Engine Usage data to Epic via the Editor global preferences. * * SessionId can be used to find the actual session associated with this crash in the data. * * Use THIS instead of the current event's analytics AppVersion field, since the crash could be from an old version. Could technically be found by searching the data for the SessionId and checking the version there, but sending it here simplifies the backend processing and ensure we have the version here even if we never got the original events. * * If multiple versions of the editor or launched, this code will properly track each one and its shutdown status. So during startup, an editor instance may need to fire off several events. * * When attributing abnormal terminations to engine versions, be sure to use the EngineVersion associated with this event, and not the AppVersion. AppVersion is for the session that is currently sending the event, not for the session that crashed. That is why EngineVersion is sent separately. * * The editor updates this timestamp every 5 minutes, so we should know the time of the crash within 5 minutes. It should technically correlate with the last heartbeat we receive in the data for that session. */ void SendAbnormalShutdownReport(const FSessionRecord& Record) { FGameProjectGenerationModule& GameProjectModule = FModuleManager::LoadModuleChecked<FGameProjectGenerationModule>(TEXT("GameProjectGeneration")); bool bHasCode = GameProjectModule.Get().ProjectHasCodeFiles(); #if PLATFORM_WINDOWS const FString PlatformName(TEXT("Windows")); #elif PLATFORM_MAC const FString PlatformName(TEXT("Mac")); #elif PLATFORM_LINUX const FString PlatformName(TEXT("Linux")); #else const FString PlatformName(TEXT("Unknown")); #endif FGuid SessionId; FString SessionIdString = Record.SessionId; if (FGuid::Parse(SessionIdString, SessionId)) { // convert session guid to one with braces for sending to analytics SessionIdString = SessionId.ToString(EGuidFormats::DigitsWithHyphensInBraces); } FString ShutdownTypeString = Record.bCrashed ? EditorAnalyticsDefs::CrashSessionToken : (Record.bIsDebugger ? EditorAnalyticsDefs::DebuggerSessionToken : EditorAnalyticsDefs::AbnormalSessionToken); TArray< FAnalyticsEventAttribute > AbnormalShutdownAttributes; AbnormalShutdownAttributes.Add(FAnalyticsEventAttribute(FString("SessionId"), SessionIdString)); AbnormalShutdownAttributes.Add(FAnalyticsEventAttribute(FString("EngineVersion"), Record.EngineVersion)); AbnormalShutdownAttributes.Add(FAnalyticsEventAttribute(FString("ShutdownType"), ShutdownTypeString)); AbnormalShutdownAttributes.Add(FAnalyticsEventAttribute(FString("Timestamp"), Record.Timestamp.ToIso8601())); FEditorAnalytics::ReportEvent(TEXT("Editor.AbnormalShutdown"), PlatformName, bHasCode, AbnormalShutdownAttributes); }
void STutorialButton::DismissAlert() { RefreshStatus(); if( FEngineAnalytics::IsAvailable() ) { TArray<FAnalyticsEventAttribute> EventAttributes; EventAttributes.Add(FAnalyticsEventAttribute(TEXT("Context"), Context.ToString())); EventAttributes.Add(FAnalyticsEventAttribute(TEXT("TimeSinceAlertStarted"), (AlertStartTime != 0.0f && ShouldShowAlert()) ? (FPlatformTime::Seconds() - AlertStartTime) : -1.0f)); FEngineAnalytics::GetProvider().RecordEvent( TEXT("Rocket.Tutorials.DismissedTutorialAlert"), EventAttributes ); } // If they actually right click and choose "Dismiss Alert", we'll go ahead and suppress the tutorial reminder for this feature for good (all sessions.) const bool bDismissAcrossSessions = true; if (CachedAttractTutorial != nullptr) { GetMutableDefault<UTutorialStateSettings>()->DismissTutorial(CachedAttractTutorial, bDismissAcrossSessions); CachedAttractTutorial = nullptr; } if( CachedLaunchTutorial != nullptr) { GetMutableDefault<UTutorialStateSettings>()->DismissTutorial(CachedLaunchTutorial, bDismissAcrossSessions); CachedLaunchTutorial = nullptr; } GetMutableDefault<UTutorialStateSettings>()->SaveProgress(); bTutorialDismissed = true; RefreshStatus(); }
FReply STutorialButton::HandleButtonClicked() { if (bPendingClickAction) { //There's already a click pending return FReply::Handled(); } RefreshStatus(); if (FEngineAnalytics::IsAvailable()) { TArray<FAnalyticsEventAttribute> EventAttributes; EventAttributes.Add(FAnalyticsEventAttribute(TEXT("Context"), Context.ToString())); EventAttributes.Add(FAnalyticsEventAttribute(TEXT("TimeSinceAlertStarted"), (AlertStartTime != 0.0f && ShouldShowAlert()) ? (FPlatformTime::Seconds() - AlertStartTime) : -1.0f)); EventAttributes.Add(FAnalyticsEventAttribute(TEXT("LaunchedBrowser"), ShouldLaunchBrowser())); FEngineAnalytics::GetProvider().RecordEvent(TEXT("Rocket.Tutorials.ClickedContextButton"), EventAttributes); } bPendingClickAction = true; RegisterActiveTimer(0.f, FWidgetActiveTimerDelegate::CreateSP(this, &STutorialButton::HandleButtonClicked_AssetRegistryChecker)); FIntroTutorials& IntroTutorials = FModuleManager::GetModuleChecked<FIntroTutorials>(TEXT("IntroTutorials")); IntroTutorials.AttachWidget(LoadingWidget); return FReply::Handled(); }
void FEditorAnalytics::ReportEvent(FString EventName, FString PlatformName, bool bHasCode) { if( FEngineAnalytics::IsAvailable() ) { const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>(); TArray<FAnalyticsEventAttribute> ParamArray; ParamArray.Add(FAnalyticsEventAttribute(TEXT("ProjectID"), ProjectSettings.ProjectID.ToString())); ParamArray.Add(FAnalyticsEventAttribute(TEXT("Platform"), PlatformName)); ParamArray.Add(FAnalyticsEventAttribute(TEXT("ProjectType"), bHasCode ? TEXT("C++ Code") : TEXT("Content Only"))); FEngineAnalytics::GetProvider().RecordEvent( EventName, ParamArray ); } }
void FAnalyticsProviderFlurry::RecordCurrencyGiven(const FString& GameCurrencyType, int GameCurrencyAmount) { FString EventName = "Currency Given"; // Build the dictionary TArray<FAnalyticsEventAttribute> AttributesDict; AttributesDict.Add(FAnalyticsEventAttribute("GameCurrencyType", GameCurrencyType)); AttributesDict.Add(FAnalyticsEventAttribute("GameCurrencyAmount", FString::FromInt(GameCurrencyAmount))); // Send the event RecordEvent(EventName, AttributesDict); UE_LOG(LogAnalytics, Display, TEXT("AndroidFlurry::RecordCurrencyGiven('%s', %d)"), *GameCurrencyType, GameCurrencyAmount); }
void FAnalyticsProviderFlurry::RecordItemPurchase(const FString& ItemId, int ItemQuantity, const TArray<FAnalyticsEventAttribute>& EventAttrs) { FString EventName = "Item Purchase"; // Build the dictionary TArray<FAnalyticsEventAttribute> AttributesDict; AttributesDict.Add(FAnalyticsEventAttribute("ItemId", ItemId)); AttributesDict.Add(FAnalyticsEventAttribute("ItemQuantity", FString::FromInt(ItemQuantity))); AttributesDict.Append(EventAttrs); // Send the event RecordEvent(EventName, AttributesDict); UE_LOG(LogAnalytics, Display, TEXT("AndroidFlurry::RecordItemPurchase('%s', %d, %d)"), *ItemId, ItemQuantity, EventAttrs.Num()); }
void FAnalyticsProviderFlurry::RecordProgress(const FString& ProgressType, const FString& ProgressHierarchy, const TArray<FAnalyticsEventAttribute>& EventAttrs) { FString EventName = "Progress"; // Build the dictionary TArray<FAnalyticsEventAttribute> AttributesDict; AttributesDict.Add(FAnalyticsEventAttribute("ProgressType", ProgressType)); AttributesDict.Add(FAnalyticsEventAttribute("ProgressHierarchy", ProgressHierarchy)); AttributesDict.Append(EventAttrs); // Send the event RecordEvent(EventName, AttributesDict); UE_LOG(LogAnalytics, Display, TEXT("AndroidFlurry::RecordProgress('%s', %s, %d)"), *ProgressType, *ProgressHierarchy, EventAttrs.Num()); }
virtual void FireEvent_FriendRemoved(const FUniqueNetId& LocalUserId, const IFriendItem& Friend, const FString& RemoveReason) const override { static const FString EventName = TEXT("Social.FriendRemoved"); if (AnalyticsProvider.IsValid()) { if (LocalUserId.IsValid()) { TArray<FAnalyticsEventAttribute> Attributes; Attributes.Add(FAnalyticsEventAttribute(TEXT("User"), LocalUserId.ToString())); Attributes.Add(FAnalyticsEventAttribute(TEXT("Friend"), Friend.GetUniqueID()->ToString())); Attributes.Add(FAnalyticsEventAttribute(TEXT("RemoveReason"), RemoveReason)); AddPresenceAttributes(LocalUserId, Attributes); AnalyticsProvider->RecordEvent(EventName, Attributes); } } }
void FEditorAnalytics::ReportBuildRequirementsFailure(FString EventName, FString PlatformName, bool bHasCode, int32 Requirements) { TArray<FAnalyticsEventAttribute> ParamArray; ParamArray.Add(FAnalyticsEventAttribute(TEXT("Time"), 0.0)); if (Requirements & ETargetPlatformReadyStatus::SDKNotFound) { ReportEvent(EventName, PlatformName, bHasCode, EAnalyticsErrorCodes::SDKNotFound, ParamArray); } if (Requirements & ETargetPlatformReadyStatus::ProvisionNotFound) { ReportEvent(EventName, PlatformName, bHasCode, EAnalyticsErrorCodes::ProvisionNotFound, ParamArray); } if (Requirements & ETargetPlatformReadyStatus::SigningKeyNotFound) { ReportEvent(EventName, PlatformName, bHasCode, EAnalyticsErrorCodes::CertificateNotFound, ParamArray); } if (Requirements & ETargetPlatformReadyStatus::CodeUnsupported) { ReportEvent(EventName, PlatformName, bHasCode, EAnalyticsErrorCodes::CodeUnsupported, ParamArray); } if (Requirements & ETargetPlatformReadyStatus::PluginsUnsupported) { ReportEvent(EventName, PlatformName, bHasCode, EAnalyticsErrorCodes::PluginsUnsupported, ParamArray); } }
static void ParseAssetLink(const FString& InternalLink, const FString* Action) { UObject* RequiredObject = LoadObject<UObject>(nullptr, *InternalLink); if (RequiredObject != nullptr) { if(Action && *Action == TEXT("select")) { FContentBrowserModule& ContentBrowserModule = FModuleManager::Get().LoadModuleChecked<FContentBrowserModule>("ContentBrowser"); TArray<UObject*> AssetToBrowse; AssetToBrowse.Add(RequiredObject); ContentBrowserModule.Get().SyncBrowserToAssets(AssetToBrowse); } else { FAssetEditorManager::Get().OpenEditorForAsset(RequiredObject); } if( FEngineAnalytics::IsAvailable() ) { TArray<FAnalyticsEventAttribute> EventAttributes; EventAttributes.Add(FAnalyticsEventAttribute(TEXT("AssetLink"), InternalLink)); FEngineAnalytics::GetProvider().RecordEvent( TEXT("Rocket.Tutorials.AssetLinkClicked"), EventAttributes ); } } }
virtual void FireEvent_SendGameInvite(const FUniqueNetId& LocalUserId, const FUniqueNetId& ToUser) const override { static const FString EventName = TEXT("Social.GameInvite.Send"); if (AnalyticsProvider.IsValid()) { if (LocalUserId.IsValid()) { TArray<FAnalyticsEventAttribute> Attributes; Attributes.Add(FAnalyticsEventAttribute(TEXT("User"), LocalUserId.ToString())); Attributes.Add(FAnalyticsEventAttribute(TEXT("Friend"), ToUser.ToString())); AddPresenceAttributes(LocalUserId, Attributes); AnalyticsProvider->RecordEvent(EventName, Attributes); } } }
virtual void FireEvent_RecordToggleChat(const FUniqueNetId& LocalUserId, const FString& Channel, bool bEnabled) const override { static const FString EventName = TEXT("Social.Chat.Toggle"); if (AnalyticsProvider.IsValid()) { if (LocalUserId.IsValid()) { TArray<FAnalyticsEventAttribute> Attributes; Attributes.Add(FAnalyticsEventAttribute(TEXT("User"), LocalUserId.ToString())); Attributes.Add(FAnalyticsEventAttribute(TEXT("Channel"), Channel)); Attributes.Add(FAnalyticsEventAttribute(TEXT("bEnabled"), bEnabled)); AddPresenceAttributes(LocalUserId, Attributes); AnalyticsProvider->RecordEvent(EventName, Attributes); } } }
void FPrimaryCrashProperties::SendPostUploadAnalytics() { TArray<FAnalyticsEventAttribute> CrashAttributes; CrashAttributes.Add(FAnalyticsEventAttribute(TEXT("CrashGUID"), CrashGUID)); if (FCrashReportAnalytics::IsAvailable()) { // Connect the crash report client analytics provider. IAnalyticsProvider& Analytics = FCrashReportAnalytics::GetProvider(); if (bIsEnsure) { Analytics.RecordEvent(TEXT("CrashReportClient.ReportEnsureUploaded"), CrashAttributes); } else { Analytics.RecordEvent(TEXT("CrashReportClient.ReportCrashUploaded"), CrashAttributes); } } // duplicate the event to QoS Reporter if (FQoSReporter::IsAvailable()) { if (bIsEnsure) { FQoSReporter::GetProvider().RecordEvent(TEXT("CrashReportClient.ReportEnsureUploaded"), CrashAttributes); } else { FQoSReporter::GetProvider().RecordEvent(TEXT("CrashReportClient.ReportCrashUploaded"), CrashAttributes); } } }
void FAnalyticsProviderFlurry::RecordItemPurchase(const FString& ItemId, const FString& Currency, int PerItemCost, int ItemQuantity) { FString EventName = "Item Purchase"; // Build the dictionary TArray<FAnalyticsEventAttribute> AttributesDict; AttributesDict.Add(FAnalyticsEventAttribute("ItemId", ItemId)); AttributesDict.Add(FAnalyticsEventAttribute("Currency", Currency)); AttributesDict.Add(FAnalyticsEventAttribute("PerItemCost", FString::FromInt(PerItemCost))); AttributesDict.Add(FAnalyticsEventAttribute("ItemQuantity", FString::FromInt(ItemQuantity))); // Send the event RecordEvent(EventName, AttributesDict); UE_LOG(LogAnalytics, Display, TEXT("AndroidFlurry::RecordItemPurchase('%s', '%s', %d, %d)"), *ItemId, *Currency, PerItemCost, ItemQuantity); }
void FEditorAnalytics::ReportEvent(FString EventName, FString PlatformName, bool bHasCode, int32 ErrorCode, TArray<FAnalyticsEventAttribute>& ExtraParams) { if( FEngineAnalytics::IsAvailable() ) { const UGeneralProjectSettings& ProjectSettings = *GetDefault<UGeneralProjectSettings>(); TArray<FAnalyticsEventAttribute> ParamArray; ParamArray.Add(FAnalyticsEventAttribute(TEXT("ProjectID"), ProjectSettings.ProjectID.ToString())); ParamArray.Add(FAnalyticsEventAttribute(TEXT("Platform"), PlatformName)); ParamArray.Add(FAnalyticsEventAttribute(TEXT("ProjectType"), bHasCode ? TEXT("C++ Code") : TEXT("Content Only"))); ParamArray.Add(FAnalyticsEventAttribute(TEXT("ErrorCode"), ErrorCode)); const FString ErrorMessage = TranslateErrorCode(ErrorCode); ParamArray.Add(FAnalyticsEventAttribute(TEXT("ErrorName"), ErrorMessage)); ParamArray.Append(ExtraParams); FEngineAnalytics::GetProvider().RecordEvent( EventName, ParamArray ); } }
void FAnalyticsProviderFlurry::RecordCurrencyPurchase(const FString& GameCurrencyType, int GameCurrencyAmount, const FString& RealCurrencyType, float RealMoneyCost, const FString& PaymentProvider) { FString EventName = "Currency Purchase"; // Build the dictionary TArray<FAnalyticsEventAttribute> AttributesDict; AttributesDict.Add(FAnalyticsEventAttribute("GameCurrencyType", GameCurrencyType)); AttributesDict.Add(FAnalyticsEventAttribute("GameCurrencyAmount", FString::FromInt(GameCurrencyAmount))); AttributesDict.Add(FAnalyticsEventAttribute("RealCurrencyType", RealCurrencyType)); AttributesDict.Add(FAnalyticsEventAttribute("RealMoneyCost", FString::Printf(TEXT("%.02f"), RealMoneyCost))); AttributesDict.Add(FAnalyticsEventAttribute("PaymentProvider", PaymentProvider)); // Send the event RecordEvent(EventName, AttributesDict); UE_LOG(LogAnalytics, Display, TEXT("AndroidFlurry::RecordCurrencyPurchase('%s', %d, '%s', %.02f, %s)"), *GameCurrencyType, GameCurrencyAmount, *RealCurrencyType, RealMoneyCost, *PaymentProvider); }
void AddPresenceAttributes(const FUniqueNetId& UserId, TArray<FAnalyticsEventAttribute>& Attributes) const { IOnlinePresencePtr OnlinePresence = Online::GetPresenceInterface(TEXT("MCP")); if (OnlinePresence.IsValid()) { TSharedPtr<FOnlineUserPresence> Presence; OnlinePresence->GetCachedPresence(UserId, Presence); if (Presence.IsValid()) { FVariantData* ClientIdData = Presence->Status.Properties.Find(DefaultClientIdKey); if (ClientIdData != nullptr) { Attributes.Add(FAnalyticsEventAttribute(TEXT("ClientId"), ClientIdData->ToString())); } Attributes.Add(FAnalyticsEventAttribute(TEXT("Status"), Presence->Status.StatusStr)); } } }
void SDocumentationToolTip::Tick( const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime ) { const FModifierKeysState ModifierKeys = FSlateApplication::Get().GetModifierKeys(); const bool NeedsUpdate = IsDisplayingDocumentationLink != GEditor->EditorUserSettings->bDisplayDocumentationLink; if ( !IsShowingFullTip && ModifierKeys.IsAltDown() && ModifierKeys.IsControlDown() ) { if ( !FullTipContent.IsValid() && DocumentationPage.IsValid() && DocumentationPage->HasExcerpt( ExcerptName ) ) { ConstructFullTipContent(); } else if ( GEditor->EditorUserSettings->bDisplayDocumentationLink ) { ReloadDocumentation(); } if ( FullTipContent.IsValid() ) { WidgetContent->SetContent( FullTipContent.ToSharedRef() ); IsShowingFullTip = true; // Analytics event if (FEngineAnalytics::IsAvailable()) { TArray<FAnalyticsEventAttribute> Params; Params.Add(FAnalyticsEventAttribute(TEXT("Page"), DocumentationLink)); Params.Add(FAnalyticsEventAttribute(TEXT("Excerpt"), ExcerptName)); FEngineAnalytics::GetProvider().RecordEvent(TEXT("Editor.Usage.Documentation.FullTooltipShown"), Params); } } } else if ( ( IsShowingFullTip || NeedsUpdate ) && ( !ModifierKeys.IsAltDown() || !ModifierKeys.IsControlDown() ) ) { if ( NeedsUpdate ) { ReloadDocumentation(); IsDisplayingDocumentationLink = GEditor->EditorUserSettings->bDisplayDocumentationLink; } WidgetContent->SetContent( SimpleTipContent.ToSharedRef() ); IsShowingFullTip = false; } }
virtual void FireEvent_AddFriend(const FUniqueNetId& LocalUserId, const FString& FriendName, const FUniqueNetId& FriendId, EFindFriendResult::Type Result, bool bRecentPlayer) const override { static const FString EventName = TEXT("Social.AddFriend"); if (AnalyticsProvider.IsValid()) { if (LocalUserId.IsValid()) { TArray<FAnalyticsEventAttribute> Attributes; Attributes.Add(FAnalyticsEventAttribute(TEXT("User"), LocalUserId.ToString())); Attributes.Add(FAnalyticsEventAttribute(TEXT("Friend"), FriendId.ToString())); Attributes.Add(FAnalyticsEventAttribute(TEXT("FriendName"), FriendName)); Attributes.Add(FAnalyticsEventAttribute(TEXT("Result"), EFindFriendResult::ToString(Result))); Attributes.Add(FAnalyticsEventAttribute(TEXT("bRecentPlayer"), bRecentPlayer)); AddPresenceAttributes(LocalUserId, Attributes); AnalyticsProvider->RecordEvent(EventName, Attributes); } } }
void SSuperSearchBox::OnMenuOpenChanged( bool bIsOpen ) { #if WITH_EDITOR if (bIsOpen == false) { if(FEngineAnalytics::IsAvailable()) { TArray< FAnalyticsEventAttribute > SearchAttribs; SearchAttribs.Add(FAnalyticsEventAttribute(TEXT("SearchTerm"), InputText->GetText().ToString() )); SearchAttribs.Add(FAnalyticsEventAttribute(TEXT("NumFoundResults"), GetNumRealSuggestions(Suggestions))); SearchAttribs.Add(FAnalyticsEventAttribute(TEXT("ClickedTitle"), EntryClicked.Get() ? EntryClicked->Title : "") ); SearchAttribs.Add(FAnalyticsEventAttribute(TEXT("ClickedOnSomething"), EntryClicked.IsValid()) ); FEngineAnalytics::GetProvider().RecordEvent(TEXT("Editor.Usage.SuperSearch"), SearchAttribs); } InputText->SetText(FText::GetEmpty()); } #endif EntryClicked = NULL; }
void STutorialRoot::HandleBackClicked() { if( FEngineAnalytics::IsAvailable() && CurrentTutorial != nullptr) { TArray<FAnalyticsEventAttribute> EventAttributes; EventAttributes.Add(FAnalyticsEventAttribute(TEXT("Context.Tutorial"), FIntroTutorials::AnalyticsEventNameFromTutorial(CurrentTutorial))); EventAttributes.Add(FAnalyticsEventAttribute(TEXT("Context.StageIndex"), CurrentTutorialStage)); FEngineAnalytics::GetProvider().RecordEvent( TEXT("Rocket.Tutorials.ClickedBackButton"), EventAttributes ); } GoToPreviousStage(); for(auto& TutorialWidget : TutorialWidgets) { if(TutorialWidget.Value.IsValid()) { TSharedPtr<SEditorTutorials> PinnedTutorialWidget = TutorialWidget.Value.Pin(); PinnedTutorialWidget->RebuildCurrentContent(); } } }
void STutorialRoot::HandleCloseClicked() { if(CurrentTutorial != nullptr) { CurrentTutorial->HandleTutorialClosed(); // Update the current stage when we close bool bHaveSeenTutorial = false; CurrentTutorialStage = GetDefault<UTutorialStateSettings>()->GetProgress(CurrentTutorial, bHaveSeenTutorial); GetMutableDefault<UTutorialStateSettings>()->RecordProgress(CurrentTutorial, CurrentTutorialStage); GetMutableDefault<UTutorialStateSettings>()->SaveProgress(); } // submit analytics data if( FEngineAnalytics::IsAvailable() && CurrentTutorial != nullptr && CurrentTutorialStage < CurrentTutorial->Stages.Num() ) { UEditorTutorial* AttractTutorial = nullptr; UEditorTutorial* LaunchTutorial = nullptr; FString BrowserFilter; GetDefault<UEditorTutorialSettings>()->FindTutorialInfoForContext(TEXT("LevelEditor"), AttractTutorial, LaunchTutorial, BrowserFilter); // prepare and send analytics data bool const bClosedInitialAttract = (CurrentTutorial == AttractTutorial); FString const CurrentExcerptTitle = bClosedInitialAttract ? TEXT("InitialAttract") : CurrentTutorial->Stages[CurrentTutorialStage].Name.ToString(); int32 const CurrentExcerptIndex = bClosedInitialAttract ? -1 : CurrentTutorialStage; float const CurrentPageElapsedTime = bClosedInitialAttract ? 0.f : (float)(FPlatformTime::Seconds() - CurrentTutorialStartTime); TArray<FAnalyticsEventAttribute> EventAttributes; EventAttributes.Add(FAnalyticsEventAttribute(TEXT("LastStageIndex"), CurrentExcerptIndex)); EventAttributes.Add(FAnalyticsEventAttribute(TEXT("LastStageTitle"), CurrentExcerptTitle)); EventAttributes.Add(FAnalyticsEventAttribute(TEXT("TimeSpentInTutorial"), CurrentPageElapsedTime)); EventAttributes.Add(FAnalyticsEventAttribute(TEXT("TutorialAsset"), FIntroTutorials::AnalyticsEventNameFromTutorial(CurrentTutorial))); FEngineAnalytics::GetProvider().RecordEvent( TEXT("Rocket.Tutorials.Closed"), EventAttributes ); } //Tutorial is no longer current CurrentTutorial = nullptr; }
void FAnalyticsProviderFlurry::RecordError(const FString& Error, const TArray<FAnalyticsEventAttribute>& EventAttrs) { FString EventName = "Error"; // Build the dictionary TArray<FAnalyticsEventAttribute> AttributesDict; AttributesDict.Add(FAnalyticsEventAttribute("Error", Error)); AttributesDict.Append(EventAttrs); // Send the event RecordEvent(EventName, AttributesDict); UE_LOG(LogAnalytics, Display, TEXT("AndroidFlurry::RecordError('%s', %d)"), *Error, EventAttrs.Num()); }
void STutorialRoot::HandleHomeClicked() { if(CurrentTutorial != nullptr) { CurrentTutorial->HandleTutorialClosed(); GetMutableDefault<UTutorialStateSettings>()->RecordProgress(CurrentTutorial, CurrentTutorialStage); GetMutableDefault<UTutorialStateSettings>()->SaveProgress(); } // submit analytics data if( FEngineAnalytics::IsAvailable() && CurrentTutorial != nullptr && CurrentTutorialStage < CurrentTutorial->Stages.Num() ) { FString const CurrentExcerptTitle = CurrentTutorial->Stages[CurrentTutorialStage].Name.ToString(); int32 const CurrentExcerptIndex = CurrentTutorialStage; float const CurrentPageElapsedTime = (float)(FPlatformTime::Seconds() - CurrentTutorialStartTime); TArray<FAnalyticsEventAttribute> EventAttributes; EventAttributes.Add(FAnalyticsEventAttribute(TEXT("LastStageIndex"), CurrentExcerptIndex)); EventAttributes.Add(FAnalyticsEventAttribute(TEXT("LastStageTitle"), CurrentExcerptTitle)); EventAttributes.Add(FAnalyticsEventAttribute(TEXT("TimeSpentInTutorial"), CurrentPageElapsedTime)); EventAttributes.Add(FAnalyticsEventAttribute(TEXT("TutorialAsset"), FIntroTutorials::AnalyticsEventNameFromTutorial(CurrentTutorial))); FEngineAnalytics::GetProvider().RecordEvent( TEXT("Rocket.Tutorials.Home"), EventAttributes ); } CurrentTutorial = nullptr; CurrentTutorialStage = 0; for(auto& TutorialWidget : TutorialWidgets) { if(TutorialWidget.Value.IsValid()) { TSharedPtr<SEditorTutorials> PinnedTutorialWidget = TutorialWidget.Value.Pin(); PinnedTutorialWidget->RebuildCurrentContent(); } } }
static void OnBrowserLinkClicked(const FSlateHyperlinkRun::FMetadata& Metadata) { const FString* Url = Metadata.Find(TEXT("href")); if(Url) { if( FEngineAnalytics::IsAvailable() ) { TArray<FAnalyticsEventAttribute> EventAttributes; EventAttributes.Add(FAnalyticsEventAttribute(TEXT("BrowserLink"), *Url)); FEngineAnalytics::GetProvider().RecordEvent( TEXT("Rocket.Tutorials.BrowserLinkClicked"), EventAttributes ); } FPlatformProcess::LaunchURL(**Url, nullptr, nullptr); } }
static void OnDocLinkClicked(const FSlateHyperlinkRun::FMetadata& Metadata) { const FString* Url = Metadata.Find(TEXT("href")); if(Url) { if( FEngineAnalytics::IsAvailable() ) { TArray<FAnalyticsEventAttribute> EventAttributes; EventAttributes.Add(FAnalyticsEventAttribute(TEXT("DocLink"), *Url)); FEngineAnalytics::GetProvider().RecordEvent( TEXT("Rocket.Tutorials.DocLinkClicked"), EventAttributes ); } IDocumentation::Get()->Open(*Url, FDocumentationSourceInfo(TEXT("tutorials"))); } }
static void ParseTutorialLink(const FString &InternalLink) { UBlueprint* Blueprint = LoadObject<UBlueprint>(nullptr, *InternalLink); if (Blueprint && Blueprint->GeneratedClass) { FIntroTutorials& IntroTutorials = FModuleManager::GetModuleChecked<FIntroTutorials>(TEXT("IntroTutorials")); IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>(TEXT("MainFrame")); IntroTutorials.LaunchTutorial(Blueprint->GeneratedClass->GetDefaultObject<UEditorTutorial>(), IIntroTutorials::ETutorialStartType::TST_RESTART, MainFrameModule.GetParentWindow()); if( FEngineAnalytics::IsAvailable() ) { TArray<FAnalyticsEventAttribute> EventAttributes; EventAttributes.Add(FAnalyticsEventAttribute(TEXT("TutorialLink"), InternalLink)); FEngineAnalytics::GetProvider().RecordEvent( TEXT("Rocket.Tutorials.TutorialLinkClicked"), EventAttributes ); } } }
void FEpicSurvey::OpenEpicSurveyWindow() { if ( SurveyWindow.IsValid() ) { SurveyWindow.Pin()->BringToFront(); } else { auto Window = SNew(SWindow) .Title(LOCTEXT( "WindowTitle", "Epic Survey" )) .ClientSize(FVector2D(1000.0f, 600.0f)) .SupportsMaximize(true) .SupportsMinimize(false); Window->SetOnWindowClosed( FOnWindowClosed::CreateRaw(this, &FEpicSurvey::OnEpicSurveyWindowClosed ) ); if ( ActiveSurvey->GetInitializationState() == EContentInitializationState::NotStarted ) { ActiveSurvey->Initialize(); auto* Settings = GetMutableDefault<UEditorSettings>(); if ( !Settings->InProgressSurveys.Contains( ActiveSurvey->GetIdentifier() ) ) { Settings->InProgressSurveys.Add( ActiveSurvey->GetIdentifier() ); Settings->PostEditChange(); if ( FEngineAnalytics::IsAvailable() ) { TArray< FAnalyticsEventAttribute > EventAttributes; EventAttributes.Add( FAnalyticsEventAttribute( TEXT("SurveyID"), ActiveSurvey->GetIdentifier().ToString() ) ); FEngineAnalytics::GetProvider().RecordEvent( TEXT("OpenedSurvey"), EventAttributes); } } } Window->SetContent( SNew( SSurvey, SharedThis( this ), ActiveSurvey.ToSharedRef() ) ); SurveyWindow = Window; FSlateApplication::Get().AddWindowAsNativeChild(Window, RootWindow.Pin().ToSharedRef()); } }
void FPrimaryCrashProperties::SendAnalytics() { // Connect the crash report client analytics provider. FCrashReportAnalytics::Initialize(); IAnalyticsProvider& Analytics = FCrashReportAnalytics::GetProvider(); TArray<FAnalyticsEventAttribute> CrashAttributes; CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "bHasPrimaryData" ), bHasPrimaryData ) ); CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "CrashVersion" ), (int32)CrashVersion ) ); CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "CrashGUID" ), CrashGUID ) ); // AppID = GameName CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "GameName" ), GameName ) ); // AppVersion = EngineVersion CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "EngineVersion" ), EngineVersion.ToString() ) ); // @see UpdateIDs() CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "MachineID" ), MachineId.AsString() ) ); CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "UserName" ), UserName.AsString() ) ); CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "EpicAccountId" ), EpicAccountId.AsString() ) ); CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "Platform" ), PlatformFullName.AsString() ) ); CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "TimeOfCrash" ), TimeOfCrash.AsString() ) ); CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "EngineMode" ), EngineMode ) ); CrashAttributes.Add( FAnalyticsEventAttribute( TEXT( "AppDefaultLocale" ), AppDefaultLocale ) ); Analytics.RecordEvent( TEXT( "CrashReportClient.ReportCrash" ), CrashAttributes ); // Shutdown analytics. FCrashReportAnalytics::Shutdown(); }