FORCEINLINE FString BuildJsonStrFromMap(TMap<FString, FString> Map)
{
	FString JsonStr;
	TSharedRef< TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR> > > JsonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR> >::Create(&JsonStr);
	// Close the writer and finalize the output such that JsonStr has what we want
	TArray<FString> keys;
	Map.GetKeys(keys);
	JsonWriter->WriteObjectStart();
	for (int32 k = 0; k < Map.Num(); k++)
	{
		JsonWriter->WriteValue(keys[k], Map[keys[k]]);
	}
	JsonWriter->WriteObjectEnd();
	JsonWriter->Close();

	return JsonStr;
}
Example #2
0
bool FPluginHelpers::SavePluginDescriptor(const FString& NewProjectFilename, const FPluginDescriptor& PluginDescriptor)
{
	FString Text;
	TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&Text);

	Writer->WriteObjectStart();

	// Write all the simple fields

	Writer->WriteValue(TEXT("FileVersion"), PluginDescriptor.FileVersion);

	Writer->WriteValue(TEXT("FriendlyName"), PluginDescriptor.FriendlyName);
	Writer->WriteValue(TEXT("Version"), PluginDescriptor.Version);
	Writer->WriteValue(TEXT("VersionName"), PluginDescriptor.VersionName);
	Writer->WriteValue(TEXT("CreatedBy"), PluginDescriptor.CreatedBy);
	Writer->WriteValue(TEXT("CreatedByURL"), PluginDescriptor.CreatedByURL);
	Writer->WriteValue(TEXT("Category"), PluginDescriptor.Category);
	Writer->WriteValue(TEXT("Description"), PluginDescriptor.Description);
	Writer->WriteValue(TEXT("EnabledByDefault"), PluginDescriptor.bEnabledByDefault);


	// Write the module list
	FModuleDescriptor::WriteArray(Writer.Get(), TEXT("Modules"), PluginDescriptor.Modules);

	Writer->WriteObjectEnd();

	Writer->Close();

	return FFileHelper::SaveStringToFile(Text, *NewProjectFilename);
}
void FMultiBoxCustomizationData::SaveCustomizedBlocks()
{
    FString SaveData;
    TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create( &SaveData );

    Writer->WriteObjectStart();
    Writer->WriteArrayStart(TEXT("CustomBlocks"));
    for (TArray<FCustomBlockTransaction>::TConstIterator It(Transactions); It; ++It)
    {
        const FCustomBlockTransaction& Transaction = *It;

        if( Transaction.Command.IsValid() )
        {
            const FUICommandInfo& Command = *Transaction.Command.Pin();

            Writer->WriteObjectStart();
            Writer->WriteValue(TEXT("CommandName"), Command.GetCommandName().ToString() );
            Writer->WriteValue(TEXT("Context"), Command.GetBindingContext().ToString() );
            Writer->WriteValue(TEXT("Index"), (float)Transaction.BlockIndex );
            Writer->WriteValue(TEXT("TransactionType"), (float)Transaction.TransactionType );
            Writer->WriteObjectEnd();
        }
    }

    Writer->WriteArrayEnd();
    Writer->WriteObjectEnd();
    Writer->Close();

    GConfig->SetString( *GetConfigSectionName(), *CustomizationName.ToString(), *FRemoteConfig::ReplaceIniCharWithSpecialChar(SaveData).ReplaceCharWithEscapedChar(), GEditorPerProjectIni );
}
bool UFlareSaveGameSystem::SaveGame(const FString SaveName, UFlareSaveGame* SaveData)
{
	bool ret = false;
	SaveLock.Lock();
	FLOGV("UFlareSaveGameSystem::SaveGame SaveName=%s", *SaveName);

	UFlareSaveWriter* SaveWriter = NewObject<UFlareSaveWriter>(this, UFlareSaveWriter::StaticClass());
	TSharedRef<FJsonObject> JsonObject = SaveWriter->SaveGame(SaveData);

	// Save the json object
	FString FileContents;
	//TSharedRef< TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>> > JsonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>::Create(&FileContents);
	TSharedRef< TJsonWriter<> > JsonWriter = TJsonWriterFactory<>::Create(&FileContents);

	if (FJsonSerializer::Serialize(JsonObject, JsonWriter))
	{
		JsonWriter->Close();

		ret = FFileHelper::SaveStringToFile(FileContents, *GetSaveGamePath(SaveName));
		FLOG("UFlareSaveGameSystem::SaveGame : Save done");
	}
	else
	{
		FLOGV("Fail to serialize save %s", *SaveName);
		ret = false;
	}

	SaveLock.Unlock();
	return ret;
}
bool UStructToJsonObjectStringInternal(const TSharedRef<FJsonObject>& JsonObject, FString& OutJsonString, int32 Indent)
{
	TSharedRef<TJsonWriter<CharType, PrintPolicy> > JsonWriter = TJsonWriterFactory<CharType, PrintPolicy>::Create(&OutJsonString, Indent);
	bool bSuccess = FJsonSerializer::Serialize(JsonObject, JsonWriter);
	JsonWriter->Close();
	return bSuccess;
}
void AHttpRequestCharacter::TouchStopped(ETouchIndex::Type FingerIndex, FVector Location)
{
	if (FingerIndex == ETouchIndex::Touch1)
	{
        
        /* Added for HTTP requests */
        
        // Create a writer and hold it in this FString
        FString JsonStr;
        TSharedRef< TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR> > > JsonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR> >::Create(&JsonStr);
        JsonWriter->WriteObjectStart();
        JsonWriter->WriteValue(TEXT("user"), TEXT("StormUnited"));
        JsonWriter->WriteObjectEnd();
        // Close the writer and finalize the output such that JsonStr has what we want
        JsonWriter->Close();
        
        TSharedRef<IHttpRequest> HttpRequest = FHttpModule::Get().CreateRequest();
        HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8"));
        HttpRequest->SetURL(TEXT("http://localhost/configuration"));
        HttpRequest->SetVerb(TEXT("POST"));
        HttpRequest->SetContentAsString(JsonStr);
        HttpRequest->OnProcessRequestComplete().BindUObject(this, HttpCompleteCallback);
        HttpRequest->ProcessRequest();
        
        /* Added for HTTP requests */
		StopJumping();
	}
}
FORCEINLINE FString UserRequestJson()
{
	FString JsonStr;
	TSharedRef< TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR> > > JsonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR> >::Create(&JsonStr);
	JsonWriter->WriteObjectStart();
	JsonWriter->WriteValue(TEXT("devicetype"), TEXT("pc#ue4hue"));
	JsonWriter->WriteObjectEnd();
	JsonWriter->Close();
	return JsonStr;
}
void UPhilipsHueBridge::SetLightBrightnessByGroupID(const int32 GroupID, const float Brightness)
{
	int32 Bri = (int32)(255.f*Brightness);
	FString JsonStr;
	TSharedRef< TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR> > > JsonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR> >::Create(&JsonStr);
	JsonWriter->WriteObjectStart();
	JsonWriter->WriteValue(TEXT("bri"), Bri);
	JsonWriter->WriteObjectEnd();
	JsonWriter->Close();
	SetLightGroupActionByIDRaw(0, JsonStr);
}
bool UFlareSaveGameSystem::SaveGame(const FString SaveName, UFlareSaveGame* SaveData)
{
	bool ret = false;
	SaveLock.Lock();
	FLOGV("UFlareSaveGameSystem::SaveGame SaveName=%s", *SaveName);

	UFlareSaveWriter* SaveWriter = NewObject<UFlareSaveWriter>(this, UFlareSaveWriter::StaticClass());
	TSharedRef<FJsonObject> JsonObject = SaveWriter->SaveGame(SaveData);

	// Save the json object
	FString FileContents;
	//TSharedRef< TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>> > JsonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>::Create(&FileContents);
	TSharedRef< TJsonWriter<> > JsonWriter = TJsonWriterFactory<>::Create(&FileContents);

	if (FJsonSerializer::Serialize(JsonObject, JsonWriter))
	{
		JsonWriter->Close();

		bool Compress = true;
		if(Compress)
		{
			uint32 StrLength = FCStringAnsi::Strlen(TCHAR_TO_UTF8(*FileContents));

			uint8* CompressedDataRaw = new uint8[StrLength];
			int32 CompressedSize = StrLength;

			const bool bResult = FCompression::CompressMemory((ECompressionFlags)(COMPRESS_GZIP), CompressedDataRaw, CompressedSize, TCHAR_TO_UTF8(*FileContents), StrLength);
			if (bResult)
			{
				ret = FFileHelper::SaveArrayToFile(TArrayView<const uint8>(CompressedDataRaw, CompressedSize), *GetSaveGamePath(SaveName, true));
			}

			delete[] CompressedDataRaw;
		}
		else
		{
			ret = FFileHelper::SaveStringToFile(FileContents, *GetSaveGamePath(SaveName, false));
		}
		FLOG("UFlareSaveGameSystem::SaveGame : Save done");
	}
	else
	{
		FLOGV("Fail to serialize save %s", *SaveName);
		ret = false;
	}

	SaveLock.Unlock();

	SaveListLock.Lock();
	SaveList.Remove(SaveData);
	SaveListLock.Unlock();

	return ret;
}
bool FJsonObjectConverter::UStructToJsonObjectString(const UStruct* StructDefinition, const void* Struct, FString& OutJsonString, int64 CheckFlags, int64 SkipFlags, int32 Indent)
{
	TSharedRef<FJsonObject> JsonObject = MakeShareable( new FJsonObject() );
	if (UStructToJsonObject(StructDefinition, Struct, JsonObject, CheckFlags, SkipFlags))
	{
		TSharedRef<TJsonWriter<> > JsonWriter = TJsonWriterFactory<>::Create(&OutJsonString, Indent);

		if (FJsonSerializer::Serialize( JsonObject, JsonWriter ))
		{
			JsonWriter->Close();
			return true;
		}
		else
		{
			UE_LOG(LogJson, Warning, TEXT("UStructToJsonObjectString - Unable to write out json"));
			JsonWriter->Close();
		}
	}

	return false;
}
void FLauncherProfileManager::SaveSimpleProfiles()
{
	for (TArray<ILauncherSimpleProfilePtr>::TIterator It(SimpleProfiles); It; ++It)
	{
		FString SimpleProfileFileName = FLauncherProfile::GetProfileFolder() / (*It)->GetDeviceName() + TEXT(".uslp");
		FString Text;
		TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&Text);
		(*It)->Save(Writer.Get());
		Writer->Close();
		FFileHelper::SaveStringToFile(Text, *SimpleProfileFileName);
	}
}
bool FLauncherProfileManager::SaveJSONProfile(const ILauncherProfileRef& Profile)
{
	if (Profile->GetId().IsValid())
	{
		FString Text;
		TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&Text);
		Profile->Save(Writer.Get());
		Writer->Close();
		return FFileHelper::SaveStringToFile(Text, *Profile->GetFilePath());
	}
	return false;
}
FString UCurveTable::GetTableAsJSON() const
{
	// use the pretty print policy since these values are usually getting dumpped for check-in to P4 (or for inspection)
	FString Result;
	TSharedRef< TJsonWriter<TCHAR, TPrettyJsonPrintPolicy<TCHAR> > > JsonWriter = TJsonWriterFactory<TCHAR, TPrettyJsonPrintPolicy<TCHAR> >::Create(&Result);
	if (!WriteTableAsJSON(JsonWriter))
	{
		return TEXT("No data in row curve!\n");
	}
	JsonWriter->Close();
	return Result;
}
void UPhilipsHueBridge::SetLightColorByLightID(const int32 LightID, const FLinearColor InColor)
{
	FVector2D xy = ColorToxy(InColor);
	FString JsonStr;
	TSharedRef< TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR> > > JsonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR> >::Create(&JsonStr);
	FString str = "[" + FString::SanitizeFloat(xy.X) + "," + FString::SanitizeFloat(xy.Y) + "]";
	JsonWriter->WriteObjectStart();
	JsonWriter->WriteRawJSONValue(TEXT("xy"), str);
	JsonWriter->WriteObjectEnd();
	JsonWriter->Close();
	SetLightStateByLightIDRaw(LightID, JsonStr);
}
bool FInternationalizationManifestJsonSerializer::SerializeManifest( TSharedRef< const FInternationalizationManifest > Manifest, FString& Str )
{
	TSharedRef< FJsonObject > JsonManifestObj = MakeShareable( new FJsonObject );
	bool bExecSuccessful = SerializeInternal( Manifest, JsonManifestObj );

	if(bExecSuccessful)
	{
		TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create( &Str );
		bExecSuccessful = FJsonSerializer::Serialize(JsonManifestObj, Writer);
		Writer->Close();
	}
	return bExecSuccessful;
}
bool FJsonInternationalizationArchiveSerializer::SerializeArchive( TSharedRef< const FInternationalizationArchive > InternationalizationArchive, FString& Str )
{
	TSharedRef< FJsonObject > JsonArchiveObj = MakeShareable( new FJsonObject );
	bool bExecSuccessful = SerializeInternal( InternationalizationArchive, JsonArchiveObj );

	if( bExecSuccessful )
	{
		TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create( &Str );
		bExecSuccessful = FJsonSerializer::Serialize( JsonArchiveObj, Writer );
		Writer->Close();
	}
	return bExecSuccessful;
}
bool FProjectDescriptor::Save(const FString& FileName, FText& OutFailReason)
{
	// Write the contents of the descriptor to a string. Make sure the writer is destroyed so that the contents are flushed to the string.
	FString Text;
	TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&Text);
	Write(Writer.Get());
	Writer->Close();

	// Save it to a file
	if ( FFileHelper::SaveStringToFile(Text, *FileName) )
	{
		return true;
	}
	else
	{
		OutFailReason = FText::Format( LOCTEXT("FailedToWriteOutputFile", "Failed to write output file '{0}'. Perhaps the file is Read-Only?"), FText::FromString(FileName) );
		return false;
	}
}
/**
* Posts the current request data to the internet
*
* @param	WorldContextObject		The current context
* @param	url						The URL to post to
*
*/
void UJsonFieldData::PostRequest(UObject* WorldContextObject, const FString &url) {
	FString outStr;
	TSharedRef<TJsonWriter<TCHAR>> JsonWriter = TJsonWriterFactory<TCHAR>::Create(&outStr);
	
	// Start writing the response
	WriteObject(JsonWriter, "", new FJsonValueObject(Data));
	JsonWriter->Close();

	// Log the post data for the user (OPTIONAL)
	UE_LOG(LogTemp, Warning, TEXT("Post data: %s"), *outStr);

	// Create the post request with the generated data
	TSharedRef< IHttpRequest > HttpRequest = FHttpModule::Get().CreateRequest();
	HttpRequest->SetVerb("POST");
	HttpRequest->SetURL(CreateURL(url));
	HttpRequest->SetHeader("Content-Type", "application/json");
	HttpRequest->SetContentAsString(outStr);
	HttpRequest->OnProcessRequestComplete().BindUObject(this, &UJsonFieldData::OnReady);

	// Execute the request
	HttpRequest->ProcessRequest();
}
Example #19
0
FString FPerfCounters::ToJson() const
{
	FString JsonStr;
	TSharedRef< TJsonWriter<> > Json = TJsonWriterFactory<>::Create(&JsonStr);
	Json->WriteObjectStart();
	for (const auto& It : PerfCounterMap)
	{
		const FJsonVariant& JsonValue = It.Value;
		switch (JsonValue.Format)
		{
		case FJsonVariant::String:
			Json->WriteValue(It.Key, JsonValue.StringValue);
			break;
		case FJsonVariant::Number:
			Json->WriteValue(It.Key, JsonValue.NumberValue);
			break;
		case FJsonVariant::Callback:
			if (JsonValue.CallbackValue.IsBound())
			{
				Json->WriteIdentifierPrefix(It.Key);
				JsonValue.CallbackValue.Execute(Json);
			}
			else
			{
				// write an explict null since the callback is unbound and the implication is this would have been an object
				Json->WriteNull(It.Key);
			}
			break;
		case FJsonVariant::Null:
		default:
			// don't write anything since wash may expect a scalar
			break;
		}
	}
	Json->WriteObjectEnd();
	Json->Close();
	return JsonStr;
}
FString FJsonInternationalizationMetaDataSerializer::MetadataToString( const TSharedPtr<FLocMetadataObject> Metadata )
{
    FString StringMetadata = TEXT("");
    if( Metadata.IsValid() )
    {
        TSharedPtr< FJsonObject > JsonKeyMetadata;
        FJsonInternationalizationMetaDataSerializer::SerializeMetadata( Metadata.ToSharedRef(), JsonKeyMetadata );

        if( JsonKeyMetadata.IsValid() )
        {
            JsonKeyMetadata->Values.KeySort( TLess<FString>() );

            TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create( &StringMetadata );
            FJsonSerializer::Serialize( JsonKeyMetadata.ToSharedRef(), Writer );
            Writer->Close();

            StringMetadata.ReplaceInline( TEXT("\t"), TEXT(" ") );
            StringMetadata.ReplaceInline( TEXT("\r\n"), TEXT(" ") );
            StringMetadata.ReplaceInline( TEXT("\n"), TEXT(" ") );
        }
    }
    return StringMetadata;
}
void FAnalyticsProviderET::FlushEvents()
{
	// Make sure we don't try to flush too many times. When we are not caching events it's possible this can be called when there are no events in the array.
	if (CachedEvents.Num() == 0)
	{
		return;
	}

	// There are much better ways to do this, but since most events are recorded and handled on the same (game) thread,
	// this is probably mostly fine for now, and simply favoring not crashing at the moment
	FScopeLock ScopedLock(&CachedEventsCS);

	if(ensure(FModuleManager::Get().IsModuleLoaded("HTTP")))
	{
		FString Payload;

		FDateTime CurrentTime = FDateTime::UtcNow();

		if (!UseLegacyProtocol)
		{
			TSharedRef< TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR> > > JsonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR> >::Create(&Payload);
			JsonWriter->WriteObjectStart();
			JsonWriter->WriteArrayStart(TEXT("Events"));
			for (int32 EventIdx = 0; EventIdx < CachedEvents.Num(); EventIdx++)
			{
				const FAnalyticsEventEntry& Entry = CachedEvents[EventIdx];
				// event entry
				JsonWriter->WriteObjectStart();
				JsonWriter->WriteValue(TEXT("EventName"), Entry.EventName);
				FString DateOffset = (CurrentTime - Entry.TimeStamp).ToString();
				JsonWriter->WriteValue(TEXT("DateOffset"), DateOffset);
				JsonWriter->WriteValue(TEXT("IsEditor"), FString::FromInt(GIsEditor));
				if (Entry.Attributes.Num() > 0)
				{
					// optional attributes for this event
					for (int32 AttrIdx = 0; AttrIdx < Entry.Attributes.Num(); AttrIdx++)
					{
						const FAnalyticsEventAttribute& Attr = Entry.Attributes[AttrIdx];
						JsonWriter->WriteValue(Attr.AttrName, Attr.AttrValue);
					}
				}
				JsonWriter->WriteObjectEnd();
			}
			JsonWriter->WriteArrayEnd();
			JsonWriter->WriteObjectEnd();
			JsonWriter->Close();

			FString URLPath = FString::Printf(TEXT("datarouter/api/v1/public/data?SessionID=%s&AppID=%s&AppVersion=%s&UserID=%s&AppEnvironment=%s&UploadType=%s"),
				*FPlatformHttp::UrlEncode(SessionID),
				*FPlatformHttp::UrlEncode(APIKey),
				*FPlatformHttp::UrlEncode(AppVersion),
				*FPlatformHttp::UrlEncode(UserID),
				*FPlatformHttp::UrlEncode(AppEnvironment),
				*FPlatformHttp::UrlEncode(UploadType));

			// Recreate the URLPath for logging because we do not want to escape the parameters when logging.
			// We cannot simply UrlEncode the entire Path after logging it because UrlEncode(Params) != UrlEncode(Param1) & UrlEncode(Param2) ...
			FString LogString = FString::Printf(TEXT("[%s] AnalyticsET URL:datarouter/api/v1/public/data?SessionID=%s&AppID=%s&AppVersion=%s&UserID=%s&AppEnvironment=%s&UploadType=%s. Payload:%s"),
				*APIKey,
				*SessionID,
				*APIKey,
				*AppVersion,
				*UserID,
				*AppEnvironment,
				*UploadType,
				*Payload);
			UE_LOG(LogAnalytics, VeryVerbose, TEXT("%s"), *LogString);

			// Duplicate the same log message with a separate category. This is used as an "last chance" backup on the servers in the unlikely case 
			// if the backend lost the events due to overload - then we can scrape the logs manually for them.
			UE_LOG(LogAnalyticsDumpEventPayload, Log, TEXT("%s"), *LogString);

			// Create/send Http request for an event
			TSharedRef<IHttpRequest> HttpRequest = FHttpModule::Get().CreateRequest();
			HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8"));

			HttpRequest->SetURL(APIServer + URLPath);
			HttpRequest->SetVerb(TEXT("POST"));
			HttpRequest->SetContentAsString(Payload);
			// Don't set a response callback if we are in our destructor, as the instance will no longer be there to call.
			if (!bInDestructor)
			{
				HttpRequest->OnProcessRequestComplete().BindSP(this, &FAnalyticsProviderET::EventRequestComplete);
			}
 			HttpRequest->ProcessRequest();
		}
		else
		{
			// this is a legacy pathway that doesn't accept batch payloads of cached data. We'll just send one request for each event, which will be slow for a large batch of requests at once.
			for (const auto& Event : CachedEvents)
			{
				FString EventParams;
				if (Event.Attributes.Num() > 0)
				{
					for (int Ndx = 0; Ndx<FMath::Min(Event.Attributes.Num(), 40); ++Ndx)
					{
						EventParams += FString::Printf(TEXT("&AttributeName%d=%s&AttributeValue%d=%s"), 
							Ndx, 
							*FPlatformHttp::UrlEncode(Event.Attributes[Ndx].AttrName), 
							Ndx, 
							*FPlatformHttp::UrlEncode(Event.Attributes[Ndx].AttrValue));
					}
				}

				// log out the un-encoded values to make reading the log easier.
				UE_LOG(LogAnalytics, VeryVerbose, TEXT("[%s] AnalyticsET URL:SendEvent.1?SessionID=%s&AppID=%s&AppVersion=%s&UserID=%s&EventName=%s%s"), 
					*APIKey,
					*SessionID,
					*APIKey,
					*AppVersion,
					*UserID,
					*Event.EventName,
					*EventParams);

				// Create/send Http request for an event
				TSharedRef<IHttpRequest> HttpRequest = FHttpModule::Get().CreateRequest();
				HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("text/plain"));
				// Don't need to URL encode the APIServer or the EventParams, which are already encoded, and contain parameter separaters that we DON'T want encoded.
				HttpRequest->SetURL(FString::Printf(TEXT("%sSendEvent.1?SessionID=%s&AppID=%s&AppVersion=%s&UserID=%s&EventName=%s%s"),
					*APIServer, 
					*FPlatformHttp::UrlEncode(SessionID), 
					*FPlatformHttp::UrlEncode(APIKey), 
					*FPlatformHttp::UrlEncode(AppVersion), 
					*FPlatformHttp::UrlEncode(UserID), 
					*FPlatformHttp::UrlEncode(Event.EventName), 
					*EventParams));
				HttpRequest->SetVerb(TEXT("GET"));
				HttpRequest->OnProcessRequestComplete().BindRaw(this, &FAnalyticsProviderET::EventRequestComplete);
				HttpRequest->ProcessRequest();
			}
		}

		FlushEventsCountdown = MaxCachedElapsedTime;
		CachedEvents.Empty();
	}
}
Example #22
0
void FBuildPatchAppManifest::SerializeToJSON(FString& JSONOutput)
{
#if UE_BUILD_DEBUG // We'll use this to switch between human readable JSON
	TSharedRef< TJsonWriter< TCHAR, TPrettyJsonPrintPolicy< TCHAR > > > Writer = TJsonWriterFactory< TCHAR, TPrettyJsonPrintPolicy< TCHAR > >::Create(&JSONOutput);
#else
	TSharedRef< TJsonWriter< TCHAR, TCondensedJsonPrintPolicy< TCHAR > > > Writer = TJsonWriterFactory< TCHAR, TCondensedJsonPrintPolicy< TCHAR > >::Create(&JSONOutput);
#endif //ALLOW_DEBUG_FILES

	Writer->WriteObjectStart();
	{
		// Write general data
		Writer->WriteValue(TEXT("ManifestFileVersion"), ToStringBlob(static_cast<int32>(Data->ManifestFileVersion)));
		Writer->WriteValue(TEXT("bIsFileData"), Data->bIsFileData);
		Writer->WriteValue(TEXT("AppID"), ToStringBlob(Data->AppID));
		Writer->WriteValue(TEXT("AppNameString"), Data->AppName);
		Writer->WriteValue(TEXT("BuildVersionString"), Data->BuildVersion);
		Writer->WriteValue(TEXT("LaunchExeString"), Data->LaunchExe);
		Writer->WriteValue(TEXT("LaunchCommand"), Data->LaunchCommand);
		Writer->WriteValue(TEXT("PrereqName"), Data->PrereqName);
		Writer->WriteValue(TEXT("PrereqPath"), Data->PrereqPath);
		Writer->WriteValue(TEXT("PrereqArgs"), Data->PrereqArgs);
		// Write file manifest data
		Writer->WriteArrayStart(TEXT("FileManifestList"));
		for (const auto& FileManifest : Data->FileManifestList)
		{
			Writer->WriteObjectStart();
			{
				Writer->WriteValue(TEXT("Filename"), FileManifest.Filename);
				Writer->WriteValue(TEXT("FileHash"), FString::FromBlob(FileManifest.FileHash.Hash, FSHA1::DigestSize));
				if (FileManifest.bIsUnixExecutable)
				{
					Writer->WriteValue(TEXT("bIsUnixExecutable"), FileManifest.bIsUnixExecutable);
				}
				if (FileManifest.bIsReadOnly)
				{
					Writer->WriteValue(TEXT("bIsReadOnly"), FileManifest.bIsReadOnly);
				}
				if (FileManifest.bIsCompressed)
				{
					Writer->WriteValue(TEXT("bIsCompressed"), FileManifest.bIsCompressed);
				}
				const bool bIsSymlink = !FileManifest.SymlinkTarget.IsEmpty();
				if (bIsSymlink)
				{
					Writer->WriteValue(TEXT("SymlinkTarget"), FileManifest.SymlinkTarget);
				}
				else
				{
					Writer->WriteArrayStart(TEXT("FileChunkParts"));
					{
						for (const auto& FileChunkPart : FileManifest.FileChunkParts)
						{
							Writer->WriteObjectStart();
							{
								Writer->WriteValue(TEXT("Guid"), FileChunkPart.Guid.ToString());
								Writer->WriteValue(TEXT("Offset"), ToStringBlob(FileChunkPart.Offset));
								Writer->WriteValue(TEXT("Size"), ToStringBlob(FileChunkPart.Size));
							}
							Writer->WriteObjectEnd();
						}
					}
					Writer->WriteArrayEnd();
				}
			}
			Writer->WriteObjectEnd();
		}
		Writer->WriteArrayEnd();
		// Write chunk hash list
		Writer->WriteObjectStart(TEXT("ChunkHashList"));
		for (const auto& ChunkInfo : Data->ChunkList)
		{
			const FGuid& ChunkGuid = ChunkInfo.Guid;
			const uint64& ChunkHash = ChunkInfo.Hash;
			Writer->WriteValue(ChunkGuid.ToString(), ToStringBlob(ChunkHash));
		}
		Writer->WriteObjectEnd();
		// Write data group list
		Writer->WriteObjectStart(TEXT("DataGroupList"));
		for (const auto& ChunkInfo : Data->ChunkList)
		{
			const FGuid& DataGuid = ChunkInfo.Guid;
			const uint8& DataGroup = ChunkInfo.GroupNumber;
			Writer->WriteValue(DataGuid.ToString(), ToStringBlob(DataGroup));
		}
		Writer->WriteObjectEnd();
		// Write chunk size list
		Writer->WriteObjectStart(TEXT("ChunkFilesizeList"));
		for (const auto& ChunkInfo : Data->ChunkList)
		{
			const FGuid& ChunkGuid = ChunkInfo.Guid;
			const int64& ChunkSize = ChunkInfo.FileSize;
			Writer->WriteValue(ChunkGuid.ToString(), ToStringBlob(ChunkSize));
		}
		Writer->WriteObjectEnd();
		// Write custom fields
		Writer->WriteObjectStart(TEXT("CustomFields"));
		for (const auto& CustomField : Data->CustomFields)
		{
			Writer->WriteValue(CustomField.Key, CustomField.Value);
		}
		Writer->WriteObjectEnd();
	}
	Writer->WriteObjectEnd();

	Writer->Close();
}
Example #23
0
void FAnalyticsProviderET::FlushEvents()
{
	// Make sure we don't try to flush too many times. When we are not caching events it's possible this can be called when there are no events in the array.
	if (CachedEvents.Num() == 0)
	{
		return;
	}

	// There are much better ways to do this, but since most events are recorded and handled on the same (game) thread,
	// this is probably mostly fine for now, and simply favoring not crashing at the moment
	FScopeLock ScopedLock(&CachedEventsCS);

	if(ensure(FModuleManager::Get().IsModuleLoaded("HTTP")))
	{
		FString Payload;

		FDateTime CurrentTime = FDateTime::UtcNow();

		TSharedRef< TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR> > > JsonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR> >::Create(&Payload);
		JsonWriter->WriteObjectStart();
		JsonWriter->WriteArrayStart(TEXT("Events"));
		for (int32 EventIdx = 0; EventIdx < CachedEvents.Num(); EventIdx++)
		{
			const FAnalyticsEventEntry& Entry = CachedEvents[EventIdx];
			// event entry
			JsonWriter->WriteObjectStart();
			JsonWriter->WriteValue(TEXT("EventName"), Entry.EventName);
			FString DateOffset = (CurrentTime - Entry.TimeStamp).ToString();
			JsonWriter->WriteValue(TEXT("DateOffset"), DateOffset);
			JsonWriter->WriteValue(TEXT("IsEditor"), FString::FromInt(GIsEditor));
			if (Entry.Attributes.Num() > 0)
			{
				// optional attributes for this event
				for (int32 AttrIdx = 0; AttrIdx < Entry.Attributes.Num(); AttrIdx++)
				{
					const FAnalyticsEventAttribute& Attr = Entry.Attributes[AttrIdx];				
					JsonWriter->WriteValue(Attr.AttrName, Attr.AttrValue);
				}
			}
			JsonWriter->WriteObjectEnd();
		}
		JsonWriter->WriteArrayEnd();
		JsonWriter->WriteObjectEnd();
		JsonWriter->Close();

		FString URLPath = FString::Printf(TEXT("CollectData.1?SessionID=%s&AppID=%s&AppVersion=%s&UserID=%s"),
			*FGenericPlatformHttp::UrlEncode(SessionID),
			*FGenericPlatformHttp::UrlEncode(APIKey),
			*FGenericPlatformHttp::UrlEncode(AppVersion),
			*FGenericPlatformHttp::UrlEncode(UserID));

		// Recreate the URLPath for logging because we do not want to escape the parameters when logging.
		// We cannot simply UrlEncode the entire Path after logging it because UrlEncode(Params) != UrlEncode(Param1) & UrlEncode(Param2) ...
		UE_LOG(LogAnalytics, VeryVerbose, TEXT("[%s] AnalyticsET URL:CollectData.1?SessionID=%s&AppID=%s&AppVersion=%s&UserID=%s. Payload:%s"), 
			*APIKey, 
			*SessionID,
			*APIKey,
			*AppVersion,
			*UserID,
			*Payload);

		// Create/send Http request for an event
		TSharedRef<IHttpRequest> HttpRequest = FHttpModule::Get().CreateRequest();
		HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json; charset=utf-8"));

		HttpRequest->SetURL(APIServer + URLPath);
		HttpRequest->SetVerb(TEXT("POST"));
		HttpRequest->SetContentAsString(Payload);
		// Don't set a response callback if we are in our destructor, as the instance will no longer be there to call.
		if (!bInDestructor)
		{
			HttpRequest->OnProcessRequestComplete().BindSP(this, &FAnalyticsProviderET::EventRequestComplete);
		}
 		HttpRequest->ProcessRequest();

		FlushEventsCountdown = MaxCachedElapsedTime;
		CachedEvents.Empty();
	}
}