Compare commits

...

1 Commits

Author SHA1 Message Date
Devrim Yasar
a8c6e9460f removed varest 2025-04-16 13:25:40 -05:00
41 changed files with 137 additions and 5687 deletions

View File

@ -92,10 +92,7 @@
{ {
"Name": "FFXFSR3Settings", "Name": "FFXFSR3Settings",
"Type": "Runtime", "Type": "Runtime",
"LoadingPhase": "EarliestPossible", "LoadingPhase": "EarliestPossible"
"PlatformAllowList": [
"Win64"
]
} }
] ]
} }

View File

@ -33,7 +33,10 @@
}, },
{ {
"Name": "FSR3", "Name": "FSR3",
"Enabled": true "Enabled": true,
"PlatformAllowList": [
"Win64"
]
} }
] ]
} }

View File

@ -1,8 +0,0 @@
{
"BuildId": "37670630",
"Modules":
{
"VaRest": "UnrealEditor-VaRest.dylib",
"VaRestEditor": "UnrealEditor-VaRestEditor.dylib"
}
}

View File

@ -1,8 +0,0 @@
{
"BuildId": "37670630",
"Modules":
{
"VaRest": "UnrealEditor-VaRest-Win64-DebugGame.dll",
"VaRestEditor": "UnrealEditor-VaRestEditor-Win64-DebugGame.dll"
}
}

View File

@ -1,8 +0,0 @@
{
"BuildId": "37670630",
"Modules":
{
"VaRest": "UnrealEditor-VaRest.dll",
"VaRestEditor": "UnrealEditor-VaRestEditor.dll"
}
}

View File

@ -1,24 +0,0 @@
[CoreRedirects]
+PackageRedirects=(OldName="/VaRestPlugin/", NewName="/VaRest/", MatchSubstring=true)
+ClassRedirects=(OldName="/Script/VaRestPlugin.VaRestJsonObject",NewName="/Script/VaRest.VaRestJsonObject")
+ClassRedirects=(OldName="/Script/VaRestPlugin.VaRestJsonValue",NewName="/Script/VaRest.VaRestJsonValue")
+ClassRedirects=(OldName="/Script/VaRestPlugin.VaRestLibrary",NewName="/Script/VaRest.VaRestLibrary")
+ClassRedirects=(OldName="/Script/VaRestPlugin.VaRestRequestJSON",NewName="/Script/VaRest.VaRestRequestJSON")
+StructRedirects=(OldName="/Script/VaRestPlugin.VaRestCallResponse",NewName="/Script/VaRest.VaRestCallResponse")
+EnumRedirects=(OldName="/Script/VaRestPlugin.EVaJson",NewName="/Script/VaRest.EVaJson")
+EnumRedirects=(OldName="/Script/VaRestPlugin.EVaRestRequestVerb",NewName="/Script/VaRest.EVaRestRequestVerb")
+EnumRedirects=(OldName="/Script/VaRestPlugin.EVaRestRequestContentType",NewName="/Script/VaRest.EVaRestRequestContentType")
+EnumRedirects=(OldName="/Script/VaRestPlugin.EVaRestRequestStatus",NewName="/Script/VaRest.EVaRestRequestStatus")
+EnumRedirects=(OldName="/Script/VaRest.ERequestVerb",NewName="/Script/VaRest.EVaRestRequestVerb")
+EnumRedirects=(OldName="/Script/VaRest.ERequestContentType",NewName="/Script/VaRest.EVaRestRequestContentType")
+EnumRedirects=(OldName="/Script/VaRest.ERequestStatus",NewName="/Script/VaRest.EVaRestRequestStatus")
+EnumRedirects=(OldName="/Script/VaRest.EHttpStatusCode",NewName="/Script/VaRest.EVaRestHttpStatusCode")
+FunctionRedirects=(OldName="VaRestRequestJSON.ConstructRequest",NewName="VaRestRequestJSON.ConstructVaRestRequest")
+FunctionRedirects=(OldName="VaRestRequestJSON.ConstructRequestExt",NewName="VaRestRequestJSON.ConstructVaRestRequestExt")
+FunctionRedirects=(OldName="VaRestJsonObject.ConstructJsonObject",NewName="VaRestJsonObject.ConstructVaRestJsonObject")
+FunctionRedirects=(OldName="VaRestJsonValue.ConstructJsonValueNumber",NewName="VaRestSubsystem.ConstructJsonValueNumber")
+FunctionRedirects=(OldName="VaRestJsonValue.ConstructJsonValueString",NewName="VaRestSubsystem.ConstructJsonValueString")
+FunctionRedirects=(OldName="VaRestJsonValue.ConstructJsonValueBool",NewName="VaRestSubsystem.ConstructJsonValueBool")
+FunctionRedirects=(OldName="VaRestJsonValue.ConstructJsonValueArray",NewName="VaRestSubsystem.ConstructJsonValueArray")
+FunctionRedirects=(OldName="VaRestJsonValue.ConstructJsonValueObject",NewName="VaRestSubsystem.ConstructJsonValueObject")
+FunctionRedirects=(OldName="VaRestJsonValue.ConstructJsonValue",NewName="VaRestSubsystem.ConstructJsonValue")

View File

@ -1,24 +0,0 @@
[CoreRedirects]
+PackageRedirects=(OldName="/VaRestPlugin/", NewName="/VaRest/", MatchSubstring=true)
+ClassRedirects=(OldName="/Script/VaRestPlugin.VaRestJsonObject",NewName="/Script/VaRest.VaRestJsonObject")
+ClassRedirects=(OldName="/Script/VaRestPlugin.VaRestJsonValue",NewName="/Script/VaRest.VaRestJsonValue")
+ClassRedirects=(OldName="/Script/VaRestPlugin.VaRestLibrary",NewName="/Script/VaRest.VaRestLibrary")
+ClassRedirects=(OldName="/Script/VaRestPlugin.VaRestRequestJSON",NewName="/Script/VaRest.VaRestRequestJSON")
+StructRedirects=(OldName="/Script/VaRestPlugin.VaRestCallResponse",NewName="/Script/VaRest.VaRestCallResponse")
+EnumRedirects=(OldName="/Script/VaRestPlugin.EVaJson",NewName="/Script/VaRest.EVaJson")
+EnumRedirects=(OldName="/Script/VaRestPlugin.EVaRestRequestVerb",NewName="/Script/VaRest.EVaRestRequestVerb")
+EnumRedirects=(OldName="/Script/VaRestPlugin.EVaRestRequestContentType",NewName="/Script/VaRest.EVaRestRequestContentType")
+EnumRedirects=(OldName="/Script/VaRestPlugin.EVaRestRequestStatus",NewName="/Script/VaRest.EVaRestRequestStatus")
+EnumRedirects=(OldName="/Script/VaRest.ERequestVerb",NewName="/Script/VaRest.EVaRestRequestVerb")
+EnumRedirects=(OldName="/Script/VaRest.ERequestContentType",NewName="/Script/VaRest.EVaRestRequestContentType")
+EnumRedirects=(OldName="/Script/VaRest.ERequestStatus",NewName="/Script/VaRest.EVaRestRequestStatus")
+EnumRedirects=(OldName="/Script/VaRest.EHttpStatusCode",NewName="/Script/VaRest.EVaRestHttpStatusCode")
+FunctionRedirects=(OldName="VaRestRequestJSON.ConstructRequest",NewName="VaRestRequestJSON.ConstructVaRestRequest")
+FunctionRedirects=(OldName="VaRestRequestJSON.ConstructRequestExt",NewName="VaRestRequestJSON.ConstructVaRestRequestExt")
+FunctionRedirects=(OldName="VaRestJsonObject.ConstructJsonObject",NewName="VaRestJsonObject.ConstructVaRestJsonObject")
+FunctionRedirects=(OldName="VaRestJsonValue.ConstructJsonValueNumber",NewName="VaRestSubsystem.ConstructJsonValueNumber")
+FunctionRedirects=(OldName="VaRestJsonValue.ConstructJsonValueString",NewName="VaRestSubsystem.ConstructJsonValueString")
+FunctionRedirects=(OldName="VaRestJsonValue.ConstructJsonValueBool",NewName="VaRestSubsystem.ConstructJsonValueBool")
+FunctionRedirects=(OldName="VaRestJsonValue.ConstructJsonValueArray",NewName="VaRestSubsystem.ConstructJsonValueArray")
+FunctionRedirects=(OldName="VaRestJsonValue.ConstructJsonValueObject",NewName="VaRestSubsystem.ConstructJsonValueObject")
+FunctionRedirects=(OldName="VaRestJsonValue.ConstructJsonValue",NewName="VaRestSubsystem.ConstructJsonValue")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

View File

@ -1,41 +0,0 @@
---
Language: Cpp
BasedOnStyle: LLVM
IndentWidth: 4
TabWidth: 4
UseTab: ForContinuationAndIndentation
Standard: Cpp11
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignEscapedNewlines: Right
AlignTrailingComments: true
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortLambdasOnASingleLine: All
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: false
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: false
BeforeWhile: true
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBraces: Custom
BreakConstructorInitializersBeforeComma: true
ColumnLimit: 0
PointerAlignment: Left
SpacesInAngles: false
CommentPragmas: '^[^ ]'
---
Language: ObjC
DisableFormat: true
...

View File

@ -1,58 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#include "VaRest.h"
#include "VaRestDefines.h"
#include "VaRestLibrary.h"
#include "VaRestSettings.h"
#include "Developer/Settings/Public/ISettingsModule.h"
#include "UObject/Package.h"
#define LOCTEXT_NAMESPACE "FVaRestModule"
void FVaRestModule::StartupModule()
{
ModuleSettings = NewObject<UVaRestSettings>(GetTransientPackage(), "VaRestSettings", RF_Standalone);
ModuleSettings->AddToRoot();
// Register settings
if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
{
SettingsModule->RegisterSettings("Project", "Plugins", "VaRest",
LOCTEXT("RuntimeSettingsName", "VaRest"),
LOCTEXT("RuntimeSettingsDescription", "Configure VaRest plugin settings"),
ModuleSettings);
}
UE_LOG(LogVaRest, Log, TEXT("%s: VaRest (%s) module started"), *VA_FUNC_LINE, *UVaRestLibrary::GetVaRestVersion());
}
void FVaRestModule::ShutdownModule()
{
if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
{
SettingsModule->UnregisterSettings("Project", "Plugins", "VaRest");
}
if (!GExitPurge)
{
ModuleSettings->RemoveFromRoot();
}
else
{
ModuleSettings = nullptr;
}
}
UVaRestSettings* FVaRestModule::GetSettings() const
{
check(ModuleSettings);
return ModuleSettings;
}
IMPLEMENT_MODULE(FVaRestModule, VaRest)
DEFINE_LOG_CATEGORY(LogVaRest);
#undef LOCTEXT_NAMESPACE

View File

@ -1,801 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#include "VaRestJsonObject.h"
#include "VaRestDefines.h"
#include "VaRestJsonParser.h"
#include "VaRestJsonValue.h"
#include "HAL/FileManager.h"
#include "Misc/Paths.h"
#include "Policies/CondensedJsonPrintPolicy.h"
#include "Serialization/JsonSerializer.h"
#include "Serialization/JsonWriter.h"
typedef TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR>> FCondensedJsonStringWriterFactory;
typedef TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>> FCondensedJsonStringWriter;
UVaRestJsonObject::UVaRestJsonObject(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
, JsonObj(MakeShared<FJsonObject>())
{
}
void UVaRestJsonObject::Reset()
{
JsonObj = MakeShared<FJsonObject>();
}
TSharedRef<FJsonObject>& UVaRestJsonObject::GetRootObject()
{
return JsonObj;
}
void UVaRestJsonObject::SetRootObject(const TSharedPtr<FJsonObject>& JsonObject)
{
if (JsonObject.IsValid())
{
JsonObj = JsonObject.ToSharedRef();
}
else
{
UE_LOG(LogVaRest, Error, TEXT("%s: Trying to set invalid json object as root one. Reset now."), *VA_FUNC_LINE);
Reset();
}
}
//////////////////////////////////////////////////////////////////////////
// Serialization
FString UVaRestJsonObject::EncodeJson() const
{
FString OutputString;
const auto Writer = TJsonWriterFactory<>::Create(&OutputString);
FJsonSerializer::Serialize(JsonObj, Writer);
return OutputString;
}
FString UVaRestJsonObject::EncodeJsonToSingleString() const
{
FString OutputString;
const auto Writer = FCondensedJsonStringWriterFactory::Create(&OutputString);
FJsonSerializer::Serialize(JsonObj, Writer);
return OutputString;
}
bool UVaRestJsonObject::DecodeJson(const FString& JsonString, bool bUseIncrementalParser)
{
if (bUseIncrementalParser)
{
const int32 BytesRead = DeserializeFromTCHARBytes(JsonString.GetCharArray().GetData(), JsonString.Len());
// JsonObj is always valid, but read bytes is zero when something went wrong
if (BytesRead > 0)
{
return true;
}
}
else
{
const TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(*JsonString);
TSharedPtr<FJsonObject> OutJsonObj;
if (FJsonSerializer::Deserialize(Reader, OutJsonObj))
{
JsonObj = OutJsonObj.ToSharedRef();
return true;
}
}
// If we've failed to deserialize the string, we should clear our internal data
Reset();
UE_LOG(LogVaRest, Error, TEXT("Json decoding failed for: %s"), *JsonString);
return false;
}
//////////////////////////////////////////////////////////////////////////
// FJsonObject API
FString UVaRestJsonObject::GetFieldTypeString(const FString& FieldName) const
{
if (!JsonObj->HasTypedField<EJson::Null>(FieldName))
{
return TEXT("Null");
}
else if (!JsonObj->HasTypedField<EJson::String>(FieldName))
{
return TEXT("String");
}
else if (!JsonObj->HasTypedField<EJson::Number>(FieldName))
{
return TEXT("Number");
}
else if (!JsonObj->HasTypedField<EJson::Boolean>(FieldName))
{
return TEXT("Boolean");
}
else if (!JsonObj->HasTypedField<EJson::Object>(FieldName))
{
return TEXT("Object");
}
else if (!JsonObj->HasTypedField<EJson::Array>(FieldName))
{
return TEXT("Array");
}
UE_LOG(LogVaRest, Warning, TEXT("Field with name %s type unknown"), *FieldName);
return "";
}
TArray<FString> UVaRestJsonObject::GetFieldNames() const
{
TArray<FString> Result;
JsonObj->Values.GetKeys(Result);
return Result;
}
bool UVaRestJsonObject::HasField(const FString& FieldName) const
{
if (FieldName.IsEmpty())
{
return false;
}
return JsonObj->HasField(FieldName);
}
void UVaRestJsonObject::RemoveField(const FString& FieldName)
{
if (FieldName.IsEmpty())
{
return;
}
JsonObj->RemoveField(FieldName);
}
UVaRestJsonValue* UVaRestJsonObject::GetField(const FString& FieldName) const
{
if (FieldName.IsEmpty())
{
return nullptr;
}
TSharedPtr<FJsonValue> NewVal = JsonObj->TryGetField(FieldName);
if (NewVal.IsValid())
{
UVaRestJsonValue* NewValue = NewObject<UVaRestJsonValue>();
NewValue->SetRootValue(NewVal);
return NewValue;
}
return nullptr;
}
void UVaRestJsonObject::SetField(const FString& FieldName, UVaRestJsonValue* JsonValue)
{
if (FieldName.IsEmpty())
{
return;
}
JsonObj->SetField(FieldName, JsonValue->GetRootValue());
}
//////////////////////////////////////////////////////////////////////////
// FJsonObject API Helpers (easy to use with simple Json objects)
float UVaRestJsonObject::GetNumberField(const FString& FieldName) const
{
if (!JsonObj->HasTypedField<EJson::Number>(FieldName))
{
UE_LOG(LogVaRest, Warning, TEXT("No field with name %s of type Number"), *FieldName);
return 0.0f;
}
return JsonObj->GetNumberField(FieldName);
}
void UVaRestJsonObject::SetNumberField(const FString& FieldName, float Number)
{
if (FieldName.IsEmpty())
{
return;
}
JsonObj->SetNumberField(FieldName, Number);
}
void UVaRestJsonObject::SetNumberFieldDouble(const FString& FieldName, double Number)
{
if (FieldName.IsEmpty())
{
return;
}
JsonObj->SetNumberField(FieldName, Number);
}
int32 UVaRestJsonObject::GetIntegerField(const FString& FieldName) const
{
if (!JsonObj->HasTypedField<EJson::Number>(FieldName))
{
UE_LOG(LogVaRest, Warning, TEXT("No field with name %s of type Number"), *FieldName);
return 0;
}
return JsonObj->GetIntegerField(FieldName);
}
void UVaRestJsonObject::SetIntegerField(const FString& FieldName, int32 Number)
{
if (FieldName.IsEmpty())
{
return;
}
JsonObj->SetNumberField(FieldName, Number);
}
int64 UVaRestJsonObject::GetInt64Field(const FString& FieldName) const
{
if (!JsonObj->HasTypedField<EJson::Number>(FieldName))
{
UE_LOG(LogVaRest, Warning, TEXT("No field with name %s of type Number"), *FieldName);
return 0;
}
return static_cast<int64>(JsonObj->GetNumberField(FieldName));
}
void UVaRestJsonObject::SetInt64Field(const FString& FieldName, int64 Number)
{
if (FieldName.IsEmpty())
{
return;
}
JsonObj->SetNumberField(FieldName, Number);
}
FString UVaRestJsonObject::GetStringField(const FString& FieldName) const
{
if (!JsonObj->HasTypedField<EJson::String>(FieldName))
{
UE_LOG(LogVaRest, Warning, TEXT("No field with name %s of type String"), *FieldName);
return TEXT("");
}
return JsonObj->GetStringField(FieldName);
}
void UVaRestJsonObject::SetStringField(const FString& FieldName, const FString& StringValue)
{
if (FieldName.IsEmpty())
{
return;
}
JsonObj->SetStringField(FieldName, StringValue);
}
bool UVaRestJsonObject::GetBoolField(const FString& FieldName) const
{
if (!JsonObj->HasTypedField<EJson::Boolean>(FieldName))
{
UE_LOG(LogVaRest, Warning, TEXT("No field with name %s of type Boolean"), *FieldName);
return false;
}
return JsonObj->GetBoolField(FieldName);
}
void UVaRestJsonObject::SetBoolField(const FString& FieldName, bool InValue)
{
if (FieldName.IsEmpty())
{
return;
}
JsonObj->SetBoolField(FieldName, InValue);
}
TArray<UVaRestJsonValue*> UVaRestJsonObject::GetArrayField(const FString& FieldName) const
{
TArray<UVaRestJsonValue*> OutArray;
if (FieldName.IsEmpty())
{
return OutArray;
}
if (!JsonObj->HasTypedField<EJson::Array>(FieldName))
{
UE_LOG(LogVaRest, Warning, TEXT("%s: No field with name %s of type Array"), *VA_FUNC_LINE, *FieldName);
return OutArray;
}
TArray<TSharedPtr<FJsonValue>> ValArray = JsonObj->GetArrayField(FieldName);
for (auto Value : ValArray)
{
UVaRestJsonValue* NewValue = NewObject<UVaRestJsonValue>();
NewValue->SetRootValue(Value);
OutArray.Add(NewValue);
}
return OutArray;
}
void UVaRestJsonObject::SetArrayField(const FString& FieldName, const TArray<UVaRestJsonValue*>& InArray)
{
if (FieldName.IsEmpty())
{
return;
}
TArray<TSharedPtr<FJsonValue>> ValArray;
// Process input array and COPY original values
for (auto InVal : InArray)
{
if (InVal == nullptr)
continue;
const TSharedPtr<FJsonValue> JsonVal = InVal->GetRootValue();
switch (InVal->GetType())
{
case EVaJson::None:
break;
case EVaJson::Null:
ValArray.Add(MakeShareable(new FJsonValueNull()));
break;
case EVaJson::String:
ValArray.Add(MakeShareable(new FJsonValueString(JsonVal->AsString())));
break;
case EVaJson::Number:
ValArray.Add(MakeShareable(new FJsonValueNumber(JsonVal->AsNumber())));
break;
case EVaJson::Boolean:
ValArray.Add(MakeShareable(new FJsonValueBoolean(JsonVal->AsBool())));
break;
case EVaJson::Array:
ValArray.Add(MakeShareable(new FJsonValueArray(JsonVal->AsArray())));
break;
case EVaJson::Object:
ValArray.Add(MakeShareable(new FJsonValueObject(JsonVal->AsObject())));
break;
default:
break;
}
}
JsonObj->SetArrayField(FieldName, ValArray);
}
void UVaRestJsonObject::MergeJsonObject(UVaRestJsonObject* InJsonObject, bool Overwrite)
{
if (!InJsonObject || !InJsonObject->IsValidLowLevel())
{
return;
}
TArray<FString> Keys = InJsonObject->GetFieldNames();
for (auto Key : Keys)
{
if (Overwrite == false && HasField(Key))
{
continue;
}
SetField(Key, InJsonObject->GetField(Key));
}
}
UVaRestJsonObject* UVaRestJsonObject::GetObjectField(const FString& FieldName) const
{
if (!JsonObj->HasTypedField<EJson::Object>(FieldName))
{
UE_LOG(LogVaRest, Warning, TEXT("%s: No field with name %s of type Object"), *VA_FUNC_LINE, *FieldName);
return nullptr;
}
const TSharedPtr<FJsonObject> JsonObjField = JsonObj->GetObjectField(FieldName);
UVaRestJsonObject* OutRestJsonObj = NewObject<UVaRestJsonObject>();
OutRestJsonObj->SetRootObject(JsonObjField);
return OutRestJsonObj;
}
void UVaRestJsonObject::SetObjectField(const FString& FieldName, UVaRestJsonObject* JsonObject)
{
if (FieldName.IsEmpty() || !JsonObject || !JsonObject->IsValidLowLevel())
{
return;
}
JsonObj->SetObjectField(FieldName, JsonObject->GetRootObject());
}
void UVaRestJsonObject::SetMapFields_string(const TMap<FString, FString>& Fields)
{
for (auto& field : Fields)
{
SetStringField(field.Key, field.Value);
}
}
void UVaRestJsonObject::SetMapFields_uint8(const TMap<FString, uint8>& Fields)
{
SetMapFields_Impl(Fields);
}
void UVaRestJsonObject::SetMapFields_int32(const TMap<FString, int32>& Fields)
{
SetMapFields_Impl(Fields);
}
void UVaRestJsonObject::SetMapFields_int64(const TMap<FString, int64>& Fields)
{
SetMapFields_Impl(Fields);
}
void UVaRestJsonObject::SetMapFields_bool(const TMap<FString, bool>& Fields)
{
SetMapFields_Impl(Fields);
}
//////////////////////////////////////////////////////////////////////////
// Array fields helpers (uniform arrays)
TArray<float> UVaRestJsonObject::GetNumberArrayField(const FString& FieldName) const
{
return GetTypeArrayField<float>(FieldName);
}
TArray<int32> UVaRestJsonObject::GetIntegerArrayField(const FString& FieldName) const
{
return GetTypeArrayField<int32>(FieldName);
}
void UVaRestJsonObject::SetNumberArrayField(const FString& FieldName, const TArray<float>& NumberArray)
{
if (FieldName.IsEmpty())
{
return;
}
TArray<TSharedPtr<FJsonValue>> EntriesArray;
for (auto Number : NumberArray)
{
EntriesArray.Add(MakeShareable(new FJsonValueNumber(Number)));
}
JsonObj->SetArrayField(FieldName, EntriesArray);
}
void UVaRestJsonObject::SetNumberArrayFieldDouble(const FString& FieldName, const TArray<double>& NumberArray)
{
if (FieldName.IsEmpty())
{
return;
}
TArray<TSharedPtr<FJsonValue>> EntriesArray;
for (auto Number : NumberArray)
{
EntriesArray.Add(MakeShareable(new FJsonValueNumber(Number)));
}
JsonObj->SetArrayField(FieldName, EntriesArray);
}
TArray<FString> UVaRestJsonObject::GetStringArrayField(const FString& FieldName) const
{
TArray<FString> StringArray;
if (!JsonObj->HasTypedField<EJson::Array>(FieldName) || FieldName.IsEmpty())
{
UE_LOG(LogVaRest, Warning, TEXT("%s: No field with name %s of type Array"), *VA_FUNC_LINE, *FieldName);
return StringArray;
}
const TArray<TSharedPtr<FJsonValue>> JsonArrayValues = JsonObj->GetArrayField(FieldName);
for (TArray<TSharedPtr<FJsonValue>>::TConstIterator It(JsonArrayValues); It; ++It)
{
const auto Value = (*It).Get();
if (Value->Type != EJson::String)
{
UE_LOG(LogVaRest, Error, TEXT("Not String element in array with field name %s"), *FieldName);
}
StringArray.Add((*It)->AsString());
}
return StringArray;
}
void UVaRestJsonObject::SetStringArrayField(const FString& FieldName, const TArray<FString>& StringArray)
{
if (FieldName.IsEmpty())
{
return;
}
TArray<TSharedPtr<FJsonValue>> EntriesArray;
for (auto String : StringArray)
{
EntriesArray.Add(MakeShareable(new FJsonValueString(String)));
}
JsonObj->SetArrayField(FieldName, EntriesArray);
}
TArray<bool> UVaRestJsonObject::GetBoolArrayField(const FString& FieldName) const
{
TArray<bool> BoolArray;
if (!JsonObj->HasTypedField<EJson::Array>(FieldName) || FieldName.IsEmpty())
{
UE_LOG(LogVaRest, Warning, TEXT("%s: No field with name %s of type Array"), *VA_FUNC_LINE, *FieldName);
return BoolArray;
}
const TArray<TSharedPtr<FJsonValue>> JsonArrayValues = JsonObj->GetArrayField(FieldName);
for (TArray<TSharedPtr<FJsonValue>>::TConstIterator It(JsonArrayValues); It; ++It)
{
const auto Value = (*It).Get();
if (Value->Type != EJson::Boolean)
{
UE_LOG(LogVaRest, Error, TEXT("Not Boolean element in array with field name %s"), *FieldName);
}
BoolArray.Add((*It)->AsBool());
}
return BoolArray;
}
void UVaRestJsonObject::SetBoolArrayField(const FString& FieldName, const TArray<bool>& BoolArray)
{
if (FieldName.IsEmpty())
{
return;
}
TArray<TSharedPtr<FJsonValue>> EntriesArray;
for (auto Boolean : BoolArray)
{
EntriesArray.Add(MakeShareable(new FJsonValueBoolean(Boolean)));
}
JsonObj->SetArrayField(FieldName, EntriesArray);
}
TArray<UVaRestJsonObject*> UVaRestJsonObject::GetObjectArrayField(const FString& FieldName) const
{
TArray<UVaRestJsonObject*> OutArray;
if (!JsonObj->HasTypedField<EJson::Array>(FieldName) || FieldName.IsEmpty())
{
UE_LOG(LogVaRest, Warning, TEXT("%s: No field with name %s of type Array"), *VA_FUNC_LINE, *FieldName);
return OutArray;
}
TArray<TSharedPtr<FJsonValue>> ValArray = JsonObj->GetArrayField(FieldName);
for (const auto& Value : ValArray)
{
if (Value->Type != EJson::Object)
{
UE_LOG(LogVaRest, Error, TEXT("Not Object element in array with field name %s"), *FieldName);
}
TSharedPtr<FJsonObject> NewObj = Value->AsObject();
UVaRestJsonObject* NewJson = NewObject<UVaRestJsonObject>();
NewJson->SetRootObject(NewObj);
OutArray.Add(NewJson);
}
return OutArray;
}
void UVaRestJsonObject::SetObjectArrayField(const FString& FieldName, const TArray<UVaRestJsonObject*>& ObjectArray)
{
if (FieldName.IsEmpty())
{
return;
}
TArray<TSharedPtr<FJsonValue>> EntriesArray;
for (auto Value : ObjectArray)
{
if (Value == nullptr)
continue;
EntriesArray.Add(MakeShareable(new FJsonValueObject(Value->GetRootObject())));
}
JsonObj->SetArrayField(FieldName, EntriesArray);
}
//////////////////////////////////////////////////////////////////////////
// Deserialize
int32 UVaRestJsonObject::DeserializeFromUTF8Bytes(const ANSICHAR* Bytes, int32 Size)
{
FJSONReader Reader;
const ANSICHAR* EndByte = Bytes + Size;
while (Bytes < EndByte)
{
TCHAR Char = FUtf8Helper::CodepointFromUtf8(Bytes, EndByte - Bytes);
if (Char > 0xFFFF)
{
Char = UNICODE_BOGUS_CHAR_CODEPOINT;
}
if (!Reader.Read(Char))
{
break;
}
}
SetRootObject(Reader.State.Root);
return Reader.State.Size;
}
int32 UVaRestJsonObject::DeserializeFromTCHARBytes(const TCHAR* Bytes, int32 Size)
{
FJSONReader Reader;
int32 i = 0;
while (i < Size)
{
if (!Reader.Read(Bytes[i++]))
{
break;
}
}
SetRootObject(Reader.State.Root);
return Reader.State.Size;
}
void UVaRestJsonObject::DecodeFromArchive(TUniquePtr<FArchive>& Reader)
{
FArchive& Ar = (*Reader.Get());
uint8 SymbolBytes[2];
// Read first two bytes
Ar << SymbolBytes[0];
Ar << SymbolBytes[1];
bool bIsIntelByteOrder = true;
if (SymbolBytes[0] == 0xff && SymbolBytes[1] == 0xfe)
{
// Unicode Intel byte order. Less 1 for the FFFE header, additional 1 for null terminator.
bIsIntelByteOrder = true;
}
else if (SymbolBytes[0] == 0xfe && SymbolBytes[1] == 0xff)
{
// Unicode non-Intel byte order. Less 1 for the FFFE header, additional 1 for null terminator.
bIsIntelByteOrder = false;
}
FJSONReader JsonReader;
TCHAR Char;
while (!Ar.AtEnd())
{
Ar << SymbolBytes[0];
if (Ar.AtEnd())
{
break;
}
Ar << SymbolBytes[1];
if (bIsIntelByteOrder)
{
Char = CharCast<TCHAR>(static_cast<UCS2CHAR>(static_cast<uint16>(SymbolBytes[0]) + static_cast<uint16>(SymbolBytes[1]) * 256));
}
else
{
Char = CharCast<TCHAR>(static_cast<UCS2CHAR>(static_cast<uint16>(SymbolBytes[1]) + static_cast<uint16>(SymbolBytes[0]) * 256));
}
if (!JsonReader.Read(Char))
{
break;
}
}
SetRootObject(JsonReader.State.Root);
if (!Ar.Close())
{
UE_LOG(LogVaRest, Error, TEXT("UVaRestJsonObject::DecodeFromArchive: Error! Can't close file!"));
}
}
//////////////////////////////////////////////////////////////////////////
// Serialize
bool UVaRestJsonObject::WriteToFile(const FString& Path) const
{
TUniquePtr<FArchive> FileWriter(IFileManager::Get().CreateFileWriter(*Path));
if (!FileWriter)
{
return false;
}
FArchive& Ar = *FileWriter.Get();
UCS2CHAR BOM = UNICODE_BOM;
Ar.Serialize(&BOM, sizeof(UCS2CHAR));
FString Str = FString(TEXT("{"));
WriteStringToArchive(Ar, *Str, Str.Len());
int32 ElementCount = 0;
FJSONWriter JsonWriter;
for (auto JsonObjectValuePair : JsonObj->Values)
{
Str = FString(TEXT("\""));
WriteStringToArchive(Ar, *Str, Str.Len());
const TCHAR* BufferPtr = *JsonObjectValuePair.Key;
for (int i = 0; i < JsonObjectValuePair.Key.Len(); ++i)
{
Str = FString(1, &BufferPtr[i]);
WriteStringToArchive(Ar, *Str, Str.Len());
}
Str = FString(TEXT("\""));
WriteStringToArchive(Ar, *Str, Str.Len());
Str = FString(TEXT(":"));
WriteStringToArchive(Ar, *Str, Str.Len());
++ElementCount;
JsonWriter.Write(JsonObjectValuePair.Value, FileWriter.Get(), ElementCount >= JsonObj->Values.Num());
}
Str = FString(TEXT("}"));
WriteStringToArchive(Ar, *Str, Str.Len());
FileWriter->Close();
return true;
}
bool UVaRestJsonObject::WriteToFilePath(const FString& Path, const bool bIsRelativeToProjectDir)
{
return WriteToFile(bIsRelativeToProjectDir ? FPaths::ProjectDir() / Path : Path);
}
bool UVaRestJsonObject::WriteStringToArchive(FArchive& Ar, const TCHAR* StrPtr, int64 Len)
{
const auto Src = StringCast<UCS2CHAR>(StrPtr, Len);
Ar.Serialize(const_cast<UCS2CHAR*>(Src.Get()), Src.Length() * sizeof(UCS2CHAR));
return true;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,210 +0,0 @@
// Copyright 2015-2019 Mail.Ru Group. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Dom/JsonValue.h"
struct FUtf8Helper
{
/** @See FUTF8ToTCHAR_Convert::CodepointFromUtf8 */
static uint32 CodepointFromUtf8(const ANSICHAR*& SourceString, const uint32 SourceLengthRemaining);
};
class FJsonValueNonConstArray : public FJsonValueArray
{
public:
FJsonValueNonConstArray(const TArray<TSharedPtr<FJsonValue>>& InArray)
: FJsonValueArray(InArray)
{
}
/** return non const array */
TArray<TSharedPtr<FJsonValue>>& AsNonConstArray() { return Value; }
};
class FJsonValueNonConstBoolean : public FJsonValueBoolean
{
public:
FJsonValueNonConstBoolean(bool InBool)
: FJsonValueBoolean(InBool)
{
}
/** return non const bool */
bool& AsNonConstBool() { return Value; }
};
class FJsonValueNonConstString : public FJsonValueString
{
public:
FJsonValueNonConstString(const FString& InString)
: FJsonValueString(InString)
{
}
/** return non const string */
FString& AsNonConstString() { return Value; }
};
class FJsonValueNonConstNumber : public FJsonValueNumber
{
public:
FJsonValueNonConstNumber(double InNumber)
: FJsonValueNumber(InNumber)
{
}
/** return non const number */
double& AsNonConstNumber() { return Value; }
};
enum class EJSONNotation
{
NONE,
STRING,
STRING_SPECIAL,
SKIP,
NUMBER,
ARRAY,
OBJECT,
};
enum class EJSONToken
{
CURLY_BEGIN,
CURLY_END,
SQUARE_BEGIN,
SQUARE_END,
COMMA,
COLON,
ROOT,
ERROR,
};
struct FJSONState
{
/** Key */
FString Key;
/** Data */
FString Data;
/** Root object */
TSharedPtr<FJsonObject> Root;
/** Object list */
TArray<TSharedPtr<FJsonValue>> Objects;
/** Tokens */
TArray<EJSONToken> Tokens;
/** Notation */
EJSONNotation Notation;
/** Current char has escape */
bool bEscape;
/** Has error */
int32 bError;
/** Las quote for string */
TCHAR Quote;
/** Size */
int32 Size;
/** Default constructor */
FJSONState();
EJSONToken GetToken(int32 Index = 0);
FORCEINLINE bool CheckTokens(EJSONToken T1);
FORCEINLINE bool CheckTokens(EJSONToken T1, EJSONToken T2);
FORCEINLINE bool CheckTokens(EJSONToken T1, EJSONToken T2, EJSONToken T3);
FORCEINLINE void PopToken(int32 Num);
FORCEINLINE void PopObject();
FORCEINLINE void PopArray();
FORCEINLINE void PopValue(bool bCheckType = true);
FORCEINLINE FJsonValue* GetLast();
FORCEINLINE FJsonValueObject* GetObject();
FORCEINLINE FJsonValueNonConstArray* GetArray();
FORCEINLINE TSharedPtr<FJsonValueObject> PushObject();
FORCEINLINE TSharedPtr<FJsonValueObject> PushObject(TSharedPtr<FJsonObject> Object);
FORCEINLINE TSharedPtr<FJsonValueNonConstArray> PushArray();
FORCEINLINE TSharedPtr<FJsonValueNonConstBoolean> PushBoolean();
FORCEINLINE TSharedPtr<FJsonValueNull> PushNull();
FORCEINLINE TSharedPtr<FJsonValueNonConstNumber> PushNumber();
FORCEINLINE TSharedPtr<FJsonValueNonConstString> PushString();
FORCEINLINE void ClearData();
FORCEINLINE void ClearKey();
FORCEINLINE void DataToKey();
FORCEINLINE void Error();
};
struct FJSONReader
{
/** State */
FJSONState State;
/** Default constructor */
FJSONReader();
private:
FORCEINLINE bool IsNewLine(const TCHAR& Char);
FORCEINLINE bool IsSpace(const TCHAR& Char);
FORCEINLINE bool FindToken(const TCHAR& Char);
FORCEINLINE void UpdateNotation();
FORCEINLINE void ReadAsString(const TCHAR& Char);
FORCEINLINE void ReadAsStringSpecial(const TCHAR& Char);
FORCEINLINE void ReadAsNumber(const TCHAR& Char);
FORCEINLINE void ReadBasicValue(const TCHAR& Char);
FORCEINLINE void ReadAsArray(const TCHAR& Char);
FORCEINLINE void ReadAsObject(const TCHAR& Char);
FORCEINLINE void Skip(const TCHAR& Char);
public:
bool Read(const TCHAR Char); // @Pushkin
};
struct FJSONWriter
{
FJSONWriter();
FORCEINLINE bool GetStartChar(const TSharedPtr<FJsonValue>& JsonValue, FString& Char);
FORCEINLINE bool GetEndChar(const TSharedPtr<FJsonValue>& JsonValue, FString& Char);
public:
void Write(TSharedPtr<FJsonValue> JsonValue, FArchive* Writer, bool IsLastElement); // @Pushkin
};

View File

@ -1,210 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#include "VaRestJsonValue.h"
#include "VaRestDefines.h"
#include "VaRestJsonObject.h"
UVaRestJsonValue::UVaRestJsonValue(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
void UVaRestJsonValue::Reset()
{
JsonVal = nullptr;
}
TSharedPtr<FJsonValue>& UVaRestJsonValue::GetRootValue()
{
return JsonVal;
}
void UVaRestJsonValue::SetRootValue(TSharedPtr<FJsonValue>& JsonValue)
{
JsonVal = JsonValue;
}
//////////////////////////////////////////////////////////////////////////
// FJsonValue API
EVaJson UVaRestJsonValue::GetType() const
{
if (!JsonVal.IsValid())
{
return EVaJson::None;
}
switch (JsonVal->Type)
{
case EJson::None:
return EVaJson::None;
case EJson::Null:
return EVaJson::Null;
case EJson::String:
return EVaJson::String;
case EJson::Number:
return EVaJson::Number;
case EJson::Boolean:
return EVaJson::Boolean;
case EJson::Array:
return EVaJson::Array;
case EJson::Object:
return EVaJson::Object;
default:
return EVaJson::None;
}
}
FString UVaRestJsonValue::GetTypeString() const
{
if (!JsonVal.IsValid())
{
return "None";
}
switch (JsonVal->Type)
{
case EJson::None:
return TEXT("None");
case EJson::Null:
return TEXT("Null");
case EJson::String:
return TEXT("String");
case EJson::Number:
return TEXT("Number");
case EJson::Boolean:
return TEXT("Boolean");
case EJson::Array:
return TEXT("Array");
case EJson::Object:
return TEXT("Object");
default:
return TEXT("None");
}
}
bool UVaRestJsonValue::IsNull() const
{
if (!JsonVal.IsValid())
{
return true;
}
return JsonVal->IsNull();
}
float UVaRestJsonValue::AsNumber() const
{
if (!JsonVal.IsValid())
{
ErrorMessage(TEXT("Number"));
return 0.f;
}
return static_cast<float>(JsonVal->AsNumber());
}
int32 UVaRestJsonValue::AsInt32() const
{
if (!JsonVal.IsValid())
{
ErrorMessage(TEXT("Number"));
return 0.f;
}
return static_cast<int32>(JsonVal->AsNumber());
}
int64 UVaRestJsonValue::AsInt64() const
{
if (!JsonVal.IsValid())
{
ErrorMessage(TEXT("Number"));
return 0.f;
}
return static_cast<int64>(JsonVal->AsNumber());
}
FString UVaRestJsonValue::AsString() const
{
if (!JsonVal.IsValid())
{
ErrorMessage(TEXT("String"));
return FString();
}
return JsonVal->AsString();
}
bool UVaRestJsonValue::AsBool() const
{
if (!JsonVal.IsValid())
{
ErrorMessage(TEXT("Boolean"));
return false;
}
return JsonVal->AsBool();
}
TArray<UVaRestJsonValue*> UVaRestJsonValue::AsArray() const
{
TArray<UVaRestJsonValue*> OutArray;
if (!JsonVal.IsValid())
{
ErrorMessage(TEXT("Array"));
return OutArray;
}
TArray<TSharedPtr<FJsonValue>> ValArray = JsonVal->AsArray();
for (auto Value : ValArray)
{
UVaRestJsonValue* NewValue = NewObject<UVaRestJsonValue>();
NewValue->SetRootValue(Value);
OutArray.Add(NewValue);
}
return OutArray;
}
UVaRestJsonObject* UVaRestJsonValue::AsObject()
{
if (!JsonVal.IsValid())
{
ErrorMessage(TEXT("Object"));
return nullptr;
}
const TSharedPtr<FJsonObject> NewObj = JsonVal->AsObject();
UVaRestJsonObject* JsonObj = NewObject<UVaRestJsonObject>();
JsonObj->SetRootObject(NewObj);
return JsonObj;
}
//////////////////////////////////////////////////////////////////////////
// Helpers
void UVaRestJsonValue::ErrorMessage(const FString& InType) const
{
UE_LOG(LogVaRest, Error, TEXT("Json Value of type '%s' used as a '%s'."), *GetTypeString(), *InType);
}

View File

@ -1,101 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#include "VaRestLibrary.h"
#include "VaRest.h"
#include "VaRestDefines.h"
#include "VaRestRequestJSON.h"
#include "Engine/World.h"
#include "GenericPlatform/GenericPlatformHttp.h"
#include "Interfaces/IPluginManager.h"
#include "Misc/Base64.h"
UVaRestSettings* UVaRestLibrary::GetVaRestSettings()
{
return FVaRestModule::Get().GetSettings();
}
FString UVaRestLibrary::PercentEncode(const FString& Source)
{
return FGenericPlatformHttp::UrlEncode(Source);
}
FString UVaRestLibrary::Base64Encode(const FString& Source)
{
TArray<uint8> ByteArray;
const FTCHARToUTF8 StringSrc = FTCHARToUTF8(Source.GetCharArray().GetData());
ByteArray.Append((uint8*)StringSrc.Get(), StringSrc.Length());
return FBase64::Encode(ByteArray);
}
bool UVaRestLibrary::Base64Decode(const FString& Source, FString& Dest)
{
TArray<uint8> ByteArray;
const bool Success = FBase64::Decode(Source, ByteArray);
const FUTF8ToTCHAR StringSrc = FUTF8ToTCHAR((const ANSICHAR*)ByteArray.GetData(), ByteArray.Num());
Dest = FString();
Dest.AppendChars(StringSrc.Get(), StringSrc.Length());
return Success;
}
bool UVaRestLibrary::Base64EncodeData(const TArray<uint8>& Data, FString& Dest)
{
if (Data.Num() > 0)
{
Dest = FBase64::Encode(Data);
return true;
}
Dest = FString();
return false;
}
bool UVaRestLibrary::Base64DecodeData(const FString& Source, TArray<uint8>& Dest)
{
return FBase64::Decode(Source, Dest);
}
FString UVaRestLibrary::StringToMd5(const FString& StringToHash)
{
return FMD5::HashAnsiString(*StringToHash);
}
FString UVaRestLibrary::StringToSha1(const FString& StringToHash)
{
FSHA1 Sha1Gen;
Sha1Gen.Update((unsigned char*)TCHAR_TO_ANSI(*StringToHash), FCString::Strlen(*StringToHash));
Sha1Gen.Final();
FString Sha1String;
for (int32 i = 0; i < 20; i++)
{
Sha1String += FString::Printf(TEXT("%02x"), Sha1Gen.m_digest[i]);
}
return Sha1String;
}
FString UVaRestLibrary::GetVaRestVersion()
{
const auto PluginRef = IPluginManager::Get().FindPlugin("VaRest");
return !PluginRef.IsValid() ? FString("invalid") : PluginRef->GetDescriptor().VersionName;
}
FVaRestURL UVaRestLibrary::GetWorldURL(UObject* WorldContextObject)
{
if (WorldContextObject)
{
if (UWorld* World = WorldContextObject->GetWorld())
{
return FVaRestURL(World->URL);
}
}
return FVaRestURL();
}

View File

@ -1,643 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#include "VaRestRequestJSON.h"
#include "VaRestDefines.h"
#include "VaRestJsonObject.h"
#include "VaRestJsonValue.h"
#include "VaRestLibrary.h"
#include "VaRestSettings.h"
#include "Engine/Engine.h"
#include "Engine/LatentActionManager.h"
#include "Engine/World.h"
#include "Interfaces/IHttpResponse.h"
#include "Serialization/JsonSerializer.h"
#include "Serialization/JsonWriter.h"
FString UVaRestRequestJSON::DeprecatedResponseString(TEXT("DEPRECATED: Please use GetResponseContentAsString() instead"));
template <class T>
void FVaRestLatentAction<T>::Cancel()
{
UObject* Obj = Request.Get();
if (Obj != nullptr)
{
((UVaRestRequestJSON*)Obj)->Cancel();
}
}
UVaRestRequestJSON::UVaRestRequestJSON(const class FObjectInitializer& PCIP)
: Super(PCIP)
, BinaryContentType(TEXT("application/octet-stream"))
{
ContinueAction = nullptr;
RequestVerb = EVaRestRequestVerb::GET;
RequestContentType = EVaRestRequestContentType::x_www_form_urlencoded_url;
ResetData();
}
void UVaRestRequestJSON::SetVerb(EVaRestRequestVerb Verb)
{
RequestVerb = Verb;
}
void UVaRestRequestJSON::SetCustomVerb(FString Verb)
{
CustomVerb = Verb;
}
void UVaRestRequestJSON::SetContentType(EVaRestRequestContentType ContentType)
{
RequestContentType = ContentType;
}
void UVaRestRequestJSON::SetBinaryContentType(const FString& ContentType)
{
BinaryContentType = ContentType;
}
void UVaRestRequestJSON::SetBinaryRequestContent(const TArray<uint8>& Bytes)
{
RequestBytes = Bytes;
}
void UVaRestRequestJSON::SetStringRequestContent(const FString& Content)
{
StringRequestContent = Content;
}
void UVaRestRequestJSON::SetHeader(const FString& HeaderName, const FString& HeaderValue)
{
RequestHeaders.Add(HeaderName, HeaderValue);
}
//////////////////////////////////////////////////////////////////////////
// Destruction and reset
void UVaRestRequestJSON::ResetData()
{
ResetRequestData();
ResetResponseData();
}
void UVaRestRequestJSON::ResetRequestData()
{
if (RequestJsonObj != nullptr)
{
RequestJsonObj->Reset();
}
else
{
RequestJsonObj = NewObject<UVaRestJsonObject>();
}
// See issue #90
// HttpRequest = FHttpModule::Get().CreateRequest();
RequestBytes.Empty();
StringRequestContent.Empty();
}
void UVaRestRequestJSON::ResetResponseData()
{
if (ResponseJsonObj != nullptr)
{
ResponseJsonObj->Reset();
}
else
{
ResponseJsonObj = NewObject<UVaRestJsonObject>();
}
if (ResponseJsonValue != nullptr)
{
ResponseJsonValue->Reset();
}
else
{
ResponseJsonValue = NewObject<UVaRestJsonValue>();
}
ResponseHeaders.Empty();
ResponseCode = -1;
ResponseSize = 0;
bIsValidJsonResponse = false;
// #127 Reset string to deprecated state
ResponseContent = DeprecatedResponseString;
ResponseBytes.Empty();
ResponseContentLength = 0;
}
void UVaRestRequestJSON::Cancel()
{
ContinueAction = nullptr;
ResetResponseData();
}
//////////////////////////////////////////////////////////////////////////
// JSON data accessors
UVaRestJsonObject* UVaRestRequestJSON::GetRequestObject() const
{
check(RequestJsonObj);
return RequestJsonObj;
}
void UVaRestRequestJSON::SetRequestObject(UVaRestJsonObject* JsonObject)
{
if (JsonObject == nullptr)
{
UE_LOG(LogVaRest, Error, TEXT("%s: Provided JsonObject is nullptr"), *VA_FUNC_LINE);
return;
}
RequestJsonObj = JsonObject;
}
UVaRestJsonObject* UVaRestRequestJSON::GetResponseObject() const
{
check(ResponseJsonObj);
return ResponseJsonObj;
}
void UVaRestRequestJSON::SetResponseObject(UVaRestJsonObject* JsonObject)
{
if (JsonObject == nullptr)
{
UE_LOG(LogVaRest, Error, TEXT("%s: Provided JsonObject is nullptr"), *VA_FUNC_LINE);
return;
}
ResponseJsonObj = JsonObject;
}
UVaRestJsonValue* UVaRestRequestJSON::GetResponseValue() const
{
check(ResponseJsonValue);
return ResponseJsonValue;
}
///////////////////////////////////////////////////////////////////////////
// Response data access
FString UVaRestRequestJSON::GetURL() const
{
return HttpRequest->GetURL();
}
EVaRestRequestVerb UVaRestRequestJSON::GetVerb() const
{
return RequestVerb;
}
EVaRestRequestStatus UVaRestRequestJSON::GetStatus() const
{
return EVaRestRequestStatus((uint8)HttpRequest->GetStatus());
}
int32 UVaRestRequestJSON::GetResponseCode() const
{
return ResponseCode;
}
FString UVaRestRequestJSON::GetResponseHeader(const FString& HeaderName)
{
FString Result;
FString* Header = ResponseHeaders.Find(HeaderName);
if (Header != nullptr)
{
Result = *Header;
}
return Result;
}
TArray<FString> UVaRestRequestJSON::GetAllResponseHeaders() const
{
TArray<FString> Result;
for (TMap<FString, FString>::TConstIterator It(ResponseHeaders); It; ++It)
{
Result.Add(It.Key() + TEXT(": ") + It.Value());
}
return Result;
}
int32 UVaRestRequestJSON::GetResponseContentLength() const
{
return ResponseContentLength;
}
const TArray<uint8>& UVaRestRequestJSON::GetResponseContent() const
{
return ResponseBytes;
}
//////////////////////////////////////////////////////////////////////////
// URL processing
void UVaRestRequestJSON::SetURL(const FString& Url)
{
// Be sure to trim URL because it can break links on iOS
FString TrimmedUrl = Url;
TrimmedUrl.TrimStartInline();
TrimmedUrl.TrimEndInline();
HttpRequest->SetURL(TrimmedUrl);
}
void UVaRestRequestJSON::ProcessURL(const FString& Url)
{
SetURL(Url);
ProcessRequest();
}
void UVaRestRequestJSON::ApplyURL(const FString& Url, UVaRestJsonObject*& Result, UObject* WorldContextObject, FLatentActionInfo LatentInfo)
{
// Be sure to trim URL because it can break links on iOS
FString TrimmedUrl = Url;
TrimmedUrl.TrimStartInline();
TrimmedUrl.TrimEndInline();
HttpRequest->SetURL(TrimmedUrl);
// Prepare latent action
if (UWorld* World = GEngine->GetWorldFromContextObjectChecked(WorldContextObject))
{
FLatentActionManager& LatentActionManager = World->GetLatentActionManager();
FVaRestLatentAction<UVaRestJsonObject*>* Kont = LatentActionManager.FindExistingAction<FVaRestLatentAction<UVaRestJsonObject*>>(LatentInfo.CallbackTarget, LatentInfo.UUID);
if (Kont != nullptr)
{
Kont->Cancel();
LatentActionManager.RemoveActionsForObject(LatentInfo.CallbackTarget);
}
LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, ContinueAction = new FVaRestLatentAction<UVaRestJsonObject*>(this, Result, LatentInfo));
}
ProcessRequest();
}
void UVaRestRequestJSON::ExecuteProcessRequest()
{
if (HttpRequest->GetURL().Len() == 0)
{
UE_LOG(LogVaRest, Error, TEXT("Request execution attempt with empty URL"));
return;
}
ProcessRequest();
}
void UVaRestRequestJSON::ProcessRequest()
{
// Force add to root once request is launched
AddToRoot();
// Set verb
switch (RequestVerb)
{
case EVaRestRequestVerb::GET:
HttpRequest->SetVerb(TEXT("GET"));
break;
case EVaRestRequestVerb::POST:
HttpRequest->SetVerb(TEXT("POST"));
break;
case EVaRestRequestVerb::PUT:
HttpRequest->SetVerb(TEXT("PUT"));
break;
case EVaRestRequestVerb::DEL:
HttpRequest->SetVerb(TEXT("DELETE"));
break;
case EVaRestRequestVerb::CUSTOM:
HttpRequest->SetVerb(CustomVerb);
break;
default:
break;
}
// Set content-type
switch (RequestContentType)
{
case EVaRestRequestContentType::x_www_form_urlencoded_url:
{
HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/x-www-form-urlencoded"));
FString UrlParams = "";
uint16 ParamIdx = 0;
// Loop through all the values and prepare additional url part
for (auto RequestIt = RequestJsonObj->GetRootObject()->Values.CreateIterator(); RequestIt; ++RequestIt)
{
FString Key = RequestIt.Key();
FString Value = RequestIt.Value().Get()->AsString();
if (!Key.IsEmpty() && !Value.IsEmpty())
{
UrlParams += ParamIdx == 0 ? "?" : "&";
UrlParams += UVaRestLibrary::PercentEncode(Key) + "=" + UVaRestLibrary::PercentEncode(Value);
}
ParamIdx++;
}
// Apply params
HttpRequest->SetURL(HttpRequest->GetURL() + UrlParams);
// Add optional string content
if (!StringRequestContent.IsEmpty())
{
HttpRequest->SetContentAsString(StringRequestContent);
}
// Check extended log to avoid security vulnerability (#133)
if (UVaRestLibrary::GetVaRestSettings()->bExtendedLog)
{
UE_LOG(LogVaRest, Log, TEXT("%s: Request (urlencoded): %s %s %s %s"), *VA_FUNC_LINE, *HttpRequest->GetVerb(), *HttpRequest->GetURL(), *UrlParams, *StringRequestContent);
}
else
{
UE_LOG(LogVaRest, Log, TEXT("%s: Request (urlencoded): %s %s (check bExtendedLog for additional data)"), *VA_FUNC_LINE, *HttpRequest->GetVerb(), *HttpRequest->GetURL());
}
break;
}
case EVaRestRequestContentType::x_www_form_urlencoded_body:
{
HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/x-www-form-urlencoded"));
FString UrlParams = "";
uint16 ParamIdx = 0;
// Add optional string content
if (!StringRequestContent.IsEmpty())
{
UrlParams = StringRequestContent;
}
else
{
// Loop through all the values and prepare additional url part
for (auto RequestIt = RequestJsonObj->GetRootObject()->Values.CreateIterator(); RequestIt; ++RequestIt)
{
FString Key = RequestIt.Key();
FString Value = RequestIt.Value().Get()->AsString();
if (!Key.IsEmpty() && !Value.IsEmpty())
{
UrlParams += ParamIdx == 0 ? "" : "&";
UrlParams += UVaRestLibrary::PercentEncode(Key) + "=" + UVaRestLibrary::PercentEncode(Value);
}
ParamIdx++;
}
}
// Apply params
HttpRequest->SetContentAsString(UrlParams);
// Check extended log to avoid security vulnerability (#133)
if (UVaRestLibrary::GetVaRestSettings()->bExtendedLog)
{
UE_LOG(LogVaRest, Log, TEXT("%s: Request (url body): %s %s %s"), *VA_FUNC_LINE, *HttpRequest->GetVerb(), *HttpRequest->GetURL(), *UrlParams);
}
else
{
UE_LOG(LogVaRest, Log, TEXT("%s: Request (url body): %s %s (check bExtendedLog for additional data)"), *VA_FUNC_LINE, *HttpRequest->GetVerb(), *HttpRequest->GetURL());
}
break;
}
case EVaRestRequestContentType::binary:
{
HttpRequest->SetHeader(TEXT("Content-Type"), BinaryContentType);
HttpRequest->SetContent(RequestBytes);
UE_LOG(LogVaRest, Log, TEXT("Request (binary): %s %s"), *HttpRequest->GetVerb(), *HttpRequest->GetURL());
break;
}
case EVaRestRequestContentType::json:
{
HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
// Body is ignored for get requests, so we shouldn't place json into it even if it's empty
if (RequestVerb == EVaRestRequestVerb::GET)
{
break;
}
// Serialize data to json string
FString OutputString;
TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&OutputString);
FJsonSerializer::Serialize(RequestJsonObj->GetRootObject(), Writer);
// Set Json content
HttpRequest->SetContentAsString(OutputString);
if (UVaRestLibrary::GetVaRestSettings()->bExtendedLog)
{
UE_LOG(LogVaRest, Log, TEXT("Request (json): %s %s %sJSON(%s%s%s)JSON"), *HttpRequest->GetVerb(), *HttpRequest->GetURL(), LINE_TERMINATOR, LINE_TERMINATOR, *OutputString, LINE_TERMINATOR);
}
else
{
UE_LOG(LogVaRest, Log, TEXT("Request (json): %s %s (check bExtendedLog for additional data)"), *HttpRequest->GetVerb(), *HttpRequest->GetURL());
}
break;
}
default:
break;
}
// Apply additional headers
for (TMap<FString, FString>::TConstIterator It(RequestHeaders); It; ++It)
{
HttpRequest->SetHeader(It.Key(), It.Value());
}
// Bind event
HttpRequest->OnProcessRequestComplete().BindUObject(this, &UVaRestRequestJSON::OnProcessRequestComplete);
// Execute the request
HttpRequest->ProcessRequest();
}
//////////////////////////////////////////////////////////////////////////
// Request callbacks
void UVaRestRequestJSON::OnProcessRequestComplete(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
// Remove from root on completion
RemoveFromRoot();
// Be sure that we have no data from previous response
ResetResponseData();
// Check we have a response and save response code as int32
if (Response.IsValid())
{
ResponseCode = Response->GetResponseCode();
}
// Check we have result to process futher
if (!bWasSuccessful || !Response.IsValid())
{
UE_LOG(LogVaRest, Error, TEXT("Request failed (%d): %s"), ResponseCode, *Request->GetURL());
// Broadcast the result event
OnRequestFail.Broadcast(this);
OnStaticRequestFail.Broadcast(this);
return;
}
#if PLATFORM_DESKTOP
// Log response state
UE_LOG(LogVaRest, Log, TEXT("Response (%d): %sJSON(%s%s%s)JSON"), ResponseCode, LINE_TERMINATOR, LINE_TERMINATOR, *Response->GetContentAsString(), LINE_TERMINATOR);
#endif
// Process response headers
TArray<FString> Headers = Response->GetAllHeaders();
for (FString Header : Headers)
{
FString Key;
FString Value;
if (Header.Split(TEXT(": "), &Key, &Value))
{
ResponseHeaders.Add(Key, Value);
}
}
if (UVaRestLibrary::GetVaRestSettings()->bUseChunkedParser)
{
// Try to deserialize data to JSON
const TArray<uint8>& Bytes = Response->GetContent();
ResponseSize = ResponseJsonObj->DeserializeFromUTF8Bytes((const ANSICHAR*)Bytes.GetData(), Bytes.Num());
// Log errors
if (ResponseSize == 0)
{
// As we assume it's recommended way to use current class, but not the only one,
// it will be the warning instead of error
UE_LOG(LogVaRest, Warning, TEXT("JSON could not be decoded!"));
}
}
else
{
// Use default unreal one
const TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(*Response->GetContentAsString());
TSharedPtr<FJsonValue> OutJsonValue;
if (FJsonSerializer::Deserialize(Reader, OutJsonValue))
{
ResponseJsonValue->SetRootValue(OutJsonValue);
if (ResponseJsonValue->GetType() == EVaJson::Object)
{
ResponseJsonObj->SetRootObject(ResponseJsonValue->GetRootValue()->AsObject());
ResponseSize = Response->GetContentLength();
}
}
}
// Decide whether the request was successful
bIsValidJsonResponse = bWasSuccessful && (ResponseSize > 0);
if (!bIsValidJsonResponse)
{
// Save response data as a string
ResponseContent = Response->GetContentAsString();
ResponseSize = ResponseContent.GetAllocatedSize();
ResponseBytes = Response->GetContent();
ResponseContentLength = Response->GetContentLength();
}
// Broadcast the result events on next tick
OnRequestComplete.Broadcast(this);
OnStaticRequestComplete.Broadcast(this);
// Finish the latent action
if (ContinueAction)
{
FVaRestLatentAction<UVaRestJsonObject*>* K = ContinueAction;
ContinueAction = nullptr;
K->Call(ResponseJsonObj);
}
}
//////////////////////////////////////////////////////////////////////////
// Tags
void UVaRestRequestJSON::AddTag(FName Tag)
{
if (Tag != NAME_None)
{
Tags.AddUnique(Tag);
}
}
int32 UVaRestRequestJSON::RemoveTag(FName Tag)
{
return Tags.Remove(Tag);
}
bool UVaRestRequestJSON::HasTag(FName Tag) const
{
return (Tag != NAME_None) && Tags.Contains(Tag);
}
//////////////////////////////////////////////////////////////////////////
// Data
FString UVaRestRequestJSON::GetResponseContentAsString(bool bCacheResponseContent)
{
// Check we have valid json response
if (!bIsValidJsonResponse)
{
// We've cached response content in OnProcessRequestComplete()
return ResponseContent;
}
// Check we have valid response object
if (!ResponseJsonObj || !ResponseJsonObj->IsValidLowLevel())
{
// Discard previous cached string if we had one
ResponseContent = DeprecatedResponseString;
return TEXT("Invalid response");
}
// Check if we should re-genetate it in runtime
if (!bCacheResponseContent)
{
UE_LOG(LogVaRest, Warning, TEXT("%s: Use of uncashed getter could be slow"), *VA_FUNC_LINE);
return ResponseJsonObj->EncodeJson();
}
// Check that we haven't cached content yet
if (ResponseContent == DeprecatedResponseString)
{
UE_LOG(LogVaRest, Warning, TEXT("%s: Response content string is cached"), *VA_FUNC_LINE);
ResponseContent = ResponseJsonObj->EncodeJson();
}
// Return previously cached content now
return ResponseContent;
}

View File

@ -1,10 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#include "VaRestSettings.h"
UVaRestSettings::UVaRestSettings(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
bExtendedLog = false;
bUseChunkedParser = false;
}

View File

@ -1,217 +0,0 @@
// Copyright 2014-2020 Vladimir Alyamkin. All Rights Reserved.
#include "VaRestSubsystem.h"
#include "VaRestDefines.h"
#include "VaRestJsonObject.h"
#include "VaRestJsonValue.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
#include "Serialization/JsonReader.h"
#include "Serialization/JsonSerializer.h"
#include "Subsystems/SubsystemBlueprintLibrary.h"
UVaRestSubsystem::UVaRestSubsystem()
: UEngineSubsystem()
{
}
void UVaRestSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
Super::Initialize(Collection);
UE_LOG(LogVaRest, Log, TEXT("%s: VaRest subsystem initialized"), *VA_FUNC_LINE);
}
void UVaRestSubsystem::Deinitialize()
{
// Do nothing for now
Super::Deinitialize();
}
void UVaRestSubsystem::CallURL(const FString& URL, EVaRestRequestVerb Verb, EVaRestRequestContentType ContentType, UVaRestJsonObject* VaRestJson, const FVaRestCallDelegate& Callback)
{
// Check we have valid data json
if (VaRestJson == nullptr)
{
VaRestJson = ConstructVaRestJsonObject();
}
UVaRestRequestJSON* Request = ConstructVaRestRequest();
Request->SetVerb(Verb);
Request->SetContentType(ContentType);
Request->SetRequestObject(VaRestJson);
FVaRestCallResponse Response;
Response.Request = Request;
Response.Callback = Callback;
Response.CompleteDelegateHandle = Request->OnStaticRequestComplete.AddUObject(this, &UVaRestSubsystem::OnCallComplete);
Response.FailDelegateHandle = Request->OnStaticRequestFail.AddUObject(this, &UVaRestSubsystem::OnCallComplete);
RequestMap.Add(Request, Response);
Request->ResetResponseData();
Request->ProcessURL(URL);
}
void UVaRestSubsystem::OnCallComplete(UVaRestRequestJSON* Request)
{
if (!RequestMap.Contains(Request))
{
return;
}
const auto Response = RequestMap.Find(Request);
Request->OnStaticRequestComplete.Remove(Response->CompleteDelegateHandle);
Request->OnStaticRequestFail.Remove(Response->FailDelegateHandle);
Response->Callback.ExecuteIfBound(Request);
Response->Request = nullptr;
RequestMap.Remove(Request);
}
UVaRestRequestJSON* UVaRestSubsystem::ConstructVaRestRequest()
{
return NewObject<UVaRestRequestJSON>(this);
}
UVaRestRequestJSON* UVaRestSubsystem::ConstructVaRestRequestExt(EVaRestRequestVerb Verb, EVaRestRequestContentType ContentType)
{
UVaRestRequestJSON* Request = ConstructVaRestRequest();
Request->SetVerb(Verb);
Request->SetContentType(ContentType);
return Request;
}
UVaRestJsonObject* UVaRestSubsystem::ConstructVaRestJsonObject()
{
return NewObject<UVaRestJsonObject>(this);
}
UVaRestJsonObject* UVaRestSubsystem::StaticConstructVaRestJsonObject()
{
auto SelfSystem = CastChecked<UVaRestSubsystem>(USubsystemBlueprintLibrary::GetEngineSubsystem(UVaRestSubsystem::StaticClass()), ECastCheckedType::NullChecked);
return SelfSystem->ConstructVaRestJsonObject();
}
UVaRestJsonValue* UVaRestSubsystem::ConstructJsonValueNumber(float Number)
{
TSharedPtr<FJsonValue> NewVal = MakeShareable(new FJsonValueNumber(Number));
UVaRestJsonValue* NewValue = NewObject<UVaRestJsonValue>(this);
NewValue->SetRootValue(NewVal);
return NewValue;
}
UVaRestJsonValue* UVaRestSubsystem::ConstructJsonValueString(const FString& StringValue)
{
TSharedPtr<FJsonValue> NewVal = MakeShareable(new FJsonValueString(StringValue));
UVaRestJsonValue* NewValue = NewObject<UVaRestJsonValue>(this);
NewValue->SetRootValue(NewVal);
return NewValue;
}
UVaRestJsonValue* UVaRestSubsystem::ConstructJsonValueBool(bool InValue)
{
TSharedPtr<FJsonValue> NewVal = MakeShareable(new FJsonValueBoolean(InValue));
UVaRestJsonValue* NewValue = NewObject<UVaRestJsonValue>(this);
NewValue->SetRootValue(NewVal);
return NewValue;
}
UVaRestJsonValue* UVaRestSubsystem::ConstructJsonValueArray(const TArray<UVaRestJsonValue*>& InArray)
{
// Prepare data array to create new value
TArray<TSharedPtr<FJsonValue>> ValueArray;
for (auto InVal : InArray)
{
ValueArray.Add(InVal->GetRootValue());
}
TSharedPtr<FJsonValue> NewVal = MakeShareable(new FJsonValueArray(ValueArray));
UVaRestJsonValue* NewValue = NewObject<UVaRestJsonValue>(this);
NewValue->SetRootValue(NewVal);
return NewValue;
}
UVaRestJsonValue* UVaRestSubsystem::ConstructJsonValueObject(UVaRestJsonObject* JsonObject)
{
TSharedPtr<FJsonValue> NewVal = MakeShareable(new FJsonValueObject(JsonObject->GetRootObject()));
UVaRestJsonValue* NewValue = NewObject<UVaRestJsonValue>(this);
NewValue->SetRootValue(NewVal);
return NewValue;
}
UVaRestJsonValue* UVaRestSubsystem::ConstructJsonValue(const TSharedPtr<FJsonValue>& InValue)
{
TSharedPtr<FJsonValue> NewVal = InValue;
UVaRestJsonValue* NewValue = NewObject<UVaRestJsonValue>(this);
NewValue->SetRootValue(NewVal);
return NewValue;
}
UVaRestJsonValue* UVaRestSubsystem::DecodeJsonValue(const FString& JsonString)
{
const TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(*JsonString);
TSharedPtr<FJsonValue> OutJsonValue;
if (FJsonSerializer::Deserialize(Reader, OutJsonValue))
{
return ConstructJsonValue(OutJsonValue);
}
return nullptr;
}
UVaRestJsonObject* UVaRestSubsystem::DecodeJsonObject(const FString& JsonString)
{
const TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(*JsonString);
TSharedPtr<FJsonObject> OutJsonObj;
if (FJsonSerializer::Deserialize(Reader, OutJsonObj))
{
auto NewJsonObj = NewObject<UVaRestJsonObject>(this);
NewJsonObj->SetRootObject(OutJsonObj);
return NewJsonObj;
}
return nullptr;
}
class UVaRestJsonObject* UVaRestSubsystem::LoadJsonFromFile(const FString& Path, const bool bIsRelativeToContentDir)
{
auto* Json = ConstructVaRestJsonObject();
FString JSONString;
if (FFileHelper::LoadFileToString(JSONString, *(bIsRelativeToContentDir ? FPaths::ProjectContentDir() / Path : Path)))
{
if (Json->DecodeJson(JSONString))
{
return Json;
}
else
{
UE_LOG(LogVaRest, Error, TEXT("%s: Can't decode json from file %s"), *VA_FUNC_LINE, *Path);
}
}
else
{
UE_LOG(LogVaRest, Error, TEXT("%s: Can't open file %s"), *VA_FUNC_LINE, *Path);
}
return nullptr;
}

View File

@ -1,43 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#pragma once
#include "Modules/ModuleManager.h"
class UVaRestSettings;
class FVaRestModule : public IModuleInterface
{
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
/**
* 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 FVaRestModule& Get()
{
return FModuleManager::LoadModuleChecked<FVaRestModule>("VaRest");
}
/**
* 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("VaRest");
}
/** Getter for internal settings object to support runtime configuration changes */
UVaRestSettings* GetSettings() const;
protected:
/** Module settings */
UVaRestSettings* ModuleSettings;
};

View File

@ -1,20 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#pragma once
#include "Runtime/Launch/Resources/Version.h"
#include "CoreMinimal.h"
#include "Logging/LogCategory.h"
#include "Logging/LogMacros.h"
#include "Logging/LogVerbosity.h"
// You should place include statements to your module's private header files here. You only need to
// add includes for headers that are used in most of your module's source files though.
DECLARE_LOG_CATEGORY_EXTERN(LogVaRest, Log, All);
#define VA_FUNC (FString(__FUNCTION__)) // Current Class Name + Function Name where this is called
#define VA_LINE (FString::FromInt(__LINE__)) // Current Line Number in the code where this is called
#define VA_FUNC_LINE (VA_FUNC + "(" + VA_LINE + ")") // Current Class and Line Number where this is called!

View File

@ -1,289 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#pragma once
#include "VaRestDefines.h"
#include "Dom/JsonObject.h"
#include "Templates/UnrealTypeTraits.h"
#include "VaRestJsonObject.generated.h"
class UVaRestJsonValue;
/**
* Blueprintable FJsonObject wrapper
*/
UCLASS(BlueprintType, Blueprintable)
class VAREST_API UVaRestJsonObject : public UObject
{
GENERATED_UCLASS_BODY()
public:
/** Reset all internal data */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void Reset();
/** Get the root Json object */
TSharedRef<FJsonObject>& GetRootObject();
/** Set the root Json object */
void SetRootObject(const TSharedPtr<FJsonObject>& JsonObject);
//////////////////////////////////////////////////////////////////////////
// Serialization
/** Serialize Json to string (formatted with line breaks) */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
FString EncodeJson() const;
/** Serialize Json to string (single string without line breaks) */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
FString EncodeJsonToSingleString() const;
/** Construct Json object from string */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
bool DecodeJson(const FString& JsonString, bool bUseIncrementalParser = true);
//////////////////////////////////////////////////////////////////////////
// FJsonObject API
/** Gets the type of value as string for a given field */
UFUNCTION(BlueprintPure, Category = "VaRest|Json")
FString GetFieldTypeString(const FString& FieldName) const;
/** Returns a list of field names that exist in the object */
UFUNCTION(BlueprintPure, Category = "VaRest|Json")
TArray<FString> GetFieldNames() const;
/** Checks to see if the FieldName exists in the object */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
bool HasField(const FString& FieldName) const;
/** Remove field named FieldName */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void RemoveField(const FString& FieldName);
/** Get the field named FieldName as a JsonValue */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
UVaRestJsonValue* GetField(const FString& FieldName) const;
/** Add a field named FieldName with a Value */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetField(const FString& FieldName, UVaRestJsonValue* JsonValue);
/** Get the field named FieldName as a Json Array */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
TArray<UVaRestJsonValue*> GetArrayField(const FString& FieldName) const;
/** Set an ObjectField named FieldName and value of Json Array */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetArrayField(const FString& FieldName, const TArray<UVaRestJsonValue*>& InArray);
/** Adds all of the fields from one json object to this one */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void MergeJsonObject(UVaRestJsonObject* InJsonObject, bool Overwrite);
//////////////////////////////////////////////////////////////////////////
// FJsonObject API Helpers (easy to use with simple Json objects)
/** Get the field named FieldName as a number. Ensures that the field is present and is of type Json number.
* Attn.!! float used instead of double to make the function blueprintable! */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
float GetNumberField(const FString& FieldName) const;
/** DEPRECATED Attn.!! float used instead of double to make the function blueprintable! */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetNumberField(const FString& FieldName, float Number);
/** Add a field named FieldName with Number as value */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetNumberFieldDouble(const FString& FieldName, double Number);
/** Get the field named FieldName as an Integer. Ensures that the field is present and is of type Json number. */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
int32 GetIntegerField(const FString& FieldName) const;
/** Add a field named FieldName with Integer as value. */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetIntegerField(const FString& FieldName, int32 Number);
/** Get the field named FieldName as an Int64. Ensures that the field is present and is of type Json number. */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
int64 GetInt64Field(const FString& FieldName) const;
/** Add a field named FieldName with Int64 as value. */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetInt64Field(const FString& FieldName, int64 Number);
/** Get the field named FieldName as a string. */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
FString GetStringField(const FString& FieldName) const;
/** Add a field named FieldName with value of StringValue */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetStringField(const FString& FieldName, const FString& StringValue);
/** Get the field named FieldName as a boolean. */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
bool GetBoolField(const FString& FieldName) const;
/** Set a boolean field named FieldName and value of InValue */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetBoolField(const FString& FieldName, bool InValue);
/** Get the field named FieldName as a Json object. */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
UVaRestJsonObject* GetObjectField(const FString& FieldName) const;
/** Set an ObjectField named FieldName and value of JsonObject */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetObjectField(const FString& FieldName, UVaRestJsonObject* JsonObject);
/** Set a map of fields with String values */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetMapFields_string(const TMap<FString, FString>& Fields);
/** Set a map of fields with uint8 values */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetMapFields_uint8(const TMap<FString, uint8>& Fields);
/** Set a map of fields with int32 values */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetMapFields_int32(const TMap<FString, int32>& Fields);
/** Set a map of fields with int64 values */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetMapFields_int64(const TMap<FString, int64>& Fields);
/** Set a map of fields with bool values */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetMapFields_bool(const TMap<FString, bool>& Fields);
private:
/** Internal implementation for setting map fields. */
template <typename T>
void SetMapFields_Impl(const TMap<FString, T>& Fields)
{
for (auto& field : Fields)
{
// No need to support all int types as they're not supported by BP
if (std::is_same_v<T, uint8> || std::is_same_v<T, int32> || std::is_same_v<T, int64> || std::is_same_v<T, float>)
{
SetNumberField(field.Key, field.Value);
}
else if (std::is_same_v<T, bool>)
{
SetBoolField(field.Key, (bool)field.Value);
}
}
}
/** Internal implementation to get number arrays of different types */
template <typename T>
TArray<T> GetTypeArrayField(const FString& FieldName) const
{
TArray<T> NumberArray;
if (!JsonObj->HasTypedField<EJson::Array>(FieldName) || FieldName.IsEmpty())
{
UE_LOG(LogVaRest, Warning, TEXT("%s: No field with name %s of type Array"), *VA_FUNC_LINE, *FieldName);
return NumberArray;
}
const TArray<TSharedPtr<FJsonValue>> JsonArrayValues = JsonObj->GetArrayField(FieldName);
for (TArray<TSharedPtr<FJsonValue>>::TConstIterator It(JsonArrayValues); It; ++It)
{
const auto Value = (*It).Get();
if (Value->Type != EJson::Number)
{
UE_LOG(LogVaRest, Error, TEXT("Not Number element in array with field name %s"), *FieldName);
}
NumberArray.Add((*It)->AsNumber());
}
return NumberArray;
}
//////////////////////////////////////////////////////////////////////////
// Array fields helpers (uniform arrays)
public:
/** Get the field named FieldName as a Number Array. Use it only if you're sure that array is uniform!
* Attn.!! float used instead of double to make the function blueprintable! */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
TArray<float> GetNumberArrayField(const FString& FieldName) const;
/** Get the field named FieldName as a Number Array. Use it only if you're sure that array is uniform! */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
TArray<int32> GetIntegerArrayField(const FString& FieldName) const;
/** DEPRECATED Attn.!! float used instead of double to make the function blueprintable! */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetNumberArrayField(const FString& FieldName, const TArray<float>& NumberArray);
/** Set an ObjectField named FieldName and value of Number Array */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetNumberArrayFieldDouble(const FString& FieldName, const TArray<double>& NumberArray);
/** Get the field named FieldName as a String Array. Use it only if you're sure that array is uniform! */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
TArray<FString> GetStringArrayField(const FString& FieldName) const;
/** Set an ObjectField named FieldName and value of String Array */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetStringArrayField(const FString& FieldName, const TArray<FString>& StringArray);
/** Get the field named FieldName as a Bool Array. Use it only if you're sure that array is uniform! */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
TArray<bool> GetBoolArrayField(const FString& FieldName) const;
/** Set an ObjectField named FieldName and value of Bool Array */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetBoolArrayField(const FString& FieldName, const TArray<bool>& BoolArray);
/** Get the field named FieldName as an Object Array. Use it only if you're sure that array is uniform! */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
TArray<UVaRestJsonObject*> GetObjectArrayField(const FString& FieldName) const;
/** Set an ObjectField named FieldName and value of Ob Array */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void SetObjectArrayField(const FString& FieldName, const TArray<UVaRestJsonObject*>& ObjectArray);
//////////////////////////////////////////////////////////////////////////
// Deserialize
public:
/** Deserialize byte content to json */
int32 DeserializeFromUTF8Bytes(const ANSICHAR* Bytes, int32 Size);
/** Deserialize byte content to json */
int32 DeserializeFromTCHARBytes(const TCHAR* Bytes, int32 Size);
/** Deserialize byte stream from reader */
void DecodeFromArchive(TUniquePtr<FArchive>& Reader);
//////////////////////////////////////////////////////////////////////////
// Serialize
public:
/** Save json to file */
bool WriteToFile(const FString& Path) const;
/**
* Blueprint Save json to filepath
*
* @param bIsRelativeToProjectDir If set to 'false' path is treated as absolute
*/
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
bool WriteToFilePath(const FString& Path, const bool bIsRelativeToProjectDir = true);
static bool WriteStringToArchive(FArchive& Ar, const TCHAR* StrPtr, int64 Len);
//////////////////////////////////////////////////////////////////////////
// Data
private:
/** Internal JSON data */
TSharedRef<FJsonObject> JsonObj;
};

View File

@ -1,101 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#pragma once
#include "VaRestJsonValue.generated.h"
class UVaRestJsonObject;
class FJsonValue;
/**
* Represents all the types a Json Value can be.
*/
UENUM(BlueprintType)
enum class EVaJson : uint8
{
None,
Null,
String,
Number,
Boolean,
Array,
Object,
};
/**
* Blueprintable FJsonValue wrapper
*/
UCLASS(BlueprintType, Blueprintable)
class VAREST_API UVaRestJsonValue : public UObject
{
GENERATED_UCLASS_BODY()
public:
/** Reset all internal data */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
void Reset();
/** Get the root Json value */
TSharedPtr<FJsonValue>& GetRootValue();
/** Set the root Json value */
void SetRootValue(TSharedPtr<FJsonValue>& JsonValue);
//////////////////////////////////////////////////////////////////////////
// FJsonValue API
/** Get type of Json value (Enum) */
UFUNCTION(BlueprintPure, Category = "VaRest|Json")
EVaJson GetType() const;
/** Get type of Json value (String) */
UFUNCTION(BlueprintPure, Category = "VaRest|Json")
FString GetTypeString() const;
/** Returns true if this value is a 'null' */
UFUNCTION(BlueprintPure, Category = "VaRest|Json")
bool IsNull() const;
/** Returns this value as a double, throwing an error if this is not an Json Number
* Attn.!! float used instead of double to make the function blueprintable! */
UFUNCTION(BlueprintPure, Category = "VaRest|Json")
float AsNumber() const;
/** Returns this value as a int32, throwing an error if this is not an Json Number */
UFUNCTION(BlueprintPure, Category = "VaRest|Json")
int32 AsInt32() const;
/** Returns this value as a int64, throwing an error if this is not an Json Number */
UFUNCTION(BlueprintPure, Category = "VaRest|Json")
int64 AsInt64() const;
/** Returns this value as a string, throwing an error if this is not an Json String */
UFUNCTION(BlueprintPure, Category = "VaRest|Json")
FString AsString() const;
/** Returns this value as a boolean, throwing an error if this is not an Json Bool */
UFUNCTION(BlueprintPure, Category = "VaRest|Json")
bool AsBool() const;
/** Returns this value as an array, throwing an error if this is not an Json Array */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
TArray<UVaRestJsonValue*> AsArray() const;
/** Returns this value as an object, throwing an error if this is not an Json Object */
UFUNCTION(BlueprintCallable, Category = "VaRest|Json")
UVaRestJsonObject* AsObject();
//////////////////////////////////////////////////////////////////////////
// Data
private:
/** Internal JSON data */
TSharedPtr<FJsonValue> JsonVal;
//////////////////////////////////////////////////////////////////////////
// Helpers
protected:
/** Simple error logger */
void ErrorMessage(const FString& InType) const;
};

View File

@ -1,109 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#pragma once
#include "Kismet/BlueprintFunctionLibrary.h"
#include "VaRestTypes.h"
#include "VaRestLibrary.generated.h"
class UVaRestSettings;
/**
* Useful tools for REST communications
*/
UCLASS()
class VAREST_API UVaRestLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
//////////////////////////////////////////////////////////////////////////
// Data Accessors
public:
/** Direct access to the plugin settings */
UFUNCTION(BlueprintPure, Category = "VaRest|Common")
static UVaRestSettings* GetVaRestSettings();
//////////////////////////////////////////////////////////////////////////
// Helpers
public:
/** Applies percent-encoding to text */
UFUNCTION(BlueprintPure, Category = "VaRest|Utility")
static FString PercentEncode(const FString& Source);
/**
* Encodes a FString into a Base64 string
*
* @param Source The string data to convert
* @return A string that encodes the binary data in a way that can be safely transmitted via various Internet protocols
*/
UFUNCTION(BlueprintPure, Category = "VaRest|Utility", meta = (DisplayName = "Base64 Encode"))
static FString Base64Encode(const FString& Source);
/**
* Decodes a Base64 string into a FString
*
* @param Source The stringified data to convert
* @param Dest The out buffer that will be filled with the decoded data
* @return True if the buffer was decoded, false if it failed to decode
*/
UFUNCTION(BlueprintPure, Category = "VaRest|Utility", meta = (DisplayName = "Base64 Decode"))
static bool Base64Decode(const FString& Source, FString& Dest);
/**
* Encodes a byte array into a Base64 string
*
* @param Dara The data to convert
* @return A string that encodes the binary data in a way that can be safely transmitted via various Internet protocols
*/
UFUNCTION(BlueprintPure, Category = "VaRest|Utility", meta = (DisplayName = "Base64 Encode Data"))
static bool Base64EncodeData(const TArray<uint8>& Data, FString& Dest);
/**
* Decodes a Base64 string into a byte array
*
* @param Source The stringified data to convert
* @param Dest The out buffer that will be filled with the decoded data
* @return True if the buffer was decoded, false if it failed to decode
*/
UFUNCTION(BlueprintPure, Category = "VaRest|Utility", meta = (DisplayName = "Base64 Decode Data"))
static bool Base64DecodeData(const FString& Source, TArray<uint8>& Dest);
/**
* Helper to perform the very common case of hashing an ASCII string into a hex representation.
*
* @param String Hex representation of the hash (32 lower-case hex digits)
*/
UFUNCTION(BlueprintPure, Category = "VaRest|Utility", meta = (DisplayName = "String to MD5"))
static FString StringToMd5(const FString& StringToHash);
/**
* Helper to perform the SHA1 hash operation on string.
*/
UFUNCTION(BlueprintPure, Category = "VaRest|Utility", meta = (DisplayName = "String to SHA1"))
static FString StringToSha1(const FString& StringToHash);
/**
* Helper method to convert a status code from HTTP to an enum for easier readability
*/
UFUNCTION(BlueprintPure, Category = "VaRest|Utility", meta = (DisplayName = "HTTP Status Int To Enum"))
static FORCEINLINE EVaRestHttpStatusCode::Type HTTPStatusIntToEnum(int32 StatusCode) { return (EVaRestHttpStatusCode::Type)StatusCode; }
/**
* Get the plugin's version
*/
UFUNCTION(BlueprintPure, Category = "VaRest|Utility", meta = (DisplayName = "Get VaRest Version"))
static FString GetVaRestVersion();
//////////////////////////////////////////////////////////////////////////
// Common Network Helpers
public:
/**
* Get the URL that was used when loading this World
*/
UFUNCTION(BlueprintPure, Category = "VaRest|Utility", meta = (WorldContext = "WorldContextObject"))
static FVaRestURL GetWorldURL(UObject* WorldContextObject);
};

View File

@ -1,358 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#pragma once
#include "Engine/LatentActionManager.h"
#include "Http.h"
#include "HttpModule.h"
#include "Interfaces/IHttpRequest.h"
#include "LatentActions.h"
#include "VaRestTypes.h"
#include "VaRestRequestJSON.generated.h"
class UVaRestJsonValue;
class UVaRestJsonObject;
class UVaRestSettings;
/**
* @author Original latent action class by https://github.com/unktomi
*/
template <class T>
class FVaRestLatentAction : public FPendingLatentAction
{
public:
virtual void Call(const T& Value)
{
Result = Value;
Called = true;
}
void operator()(const T& Value)
{
Call(Value);
}
void Cancel();
FVaRestLatentAction(FWeakObjectPtr RequestObj, T& ResultParam, const FLatentActionInfo& LatentInfo)
: Called(false)
, Request(RequestObj)
, ExecutionFunction(LatentInfo.ExecutionFunction)
, OutputLink(LatentInfo.Linkage)
, CallbackTarget(LatentInfo.CallbackTarget)
, Result(ResultParam)
{
}
virtual void UpdateOperation(FLatentResponse& Response) override
{
Response.FinishAndTriggerIf(Called, ExecutionFunction, OutputLink, CallbackTarget);
}
virtual void NotifyObjectDestroyed()
{
Cancel();
}
virtual void NotifyActionAborted()
{
Cancel();
}
private:
bool Called;
FWeakObjectPtr Request;
public:
const FName ExecutionFunction;
const int32 OutputLink;
const FWeakObjectPtr CallbackTarget;
T& Result;
};
/** Generate a delegates for callback events */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnRequestComplete, class UVaRestRequestJSON*, Request);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnRequestFail, class UVaRestRequestJSON*, Request);
DECLARE_MULTICAST_DELEGATE_OneParam(FOnStaticRequestComplete, class UVaRestRequestJSON*);
DECLARE_MULTICAST_DELEGATE_OneParam(FOnStaticRequestFail, class UVaRestRequestJSON*);
/**
* General helper class http requests via blueprints
*/
UCLASS(BlueprintType, Blueprintable)
class VAREST_API UVaRestRequestJSON : public UObject
{
GENERATED_UCLASS_BODY()
public:
//////////////////////////////////////////////////////////////////////////
// Construction
/** Set verb to the request */
UFUNCTION(BlueprintCallable, Category = "VaRest|Request")
void SetVerb(EVaRestRequestVerb Verb);
/** Set custom verb to the request */
UFUNCTION(BlueprintCallable, Category = "VaRest|Request")
void SetCustomVerb(FString Verb);
/** Set content type to the request. If you're using the x-www-form-urlencoded,
* params/constaints should be defined as key=ValueString pairs from Json data */
UFUNCTION(BlueprintCallable, Category = "VaRest|Request")
void SetContentType(EVaRestRequestContentType ContentType);
/** Set content type of the request for binary post data */
UFUNCTION(BlueprintCallable, Category = "VaRest|Request")
void SetBinaryContentType(const FString& ContentType);
/** Set content of the request for binary post data */
UFUNCTION(BlueprintCallable, Category = "VaRest|Request")
void SetBinaryRequestContent(const TArray<uint8>& Content);
/** Set content of the request as a plain string */
UFUNCTION(BlueprintCallable, Category = "VaRest|Request")
void SetStringRequestContent(const FString& Content);
/** Sets optional header info */
UFUNCTION(BlueprintCallable, Category = "VaRest|Request")
void SetHeader(const FString& HeaderName, const FString& HeaderValue);
//////////////////////////////////////////////////////////////////////////
// Destruction and reset
/** Reset all internal saved data */
UFUNCTION(BlueprintCallable, Category = "VaRest|Utility")
void ResetData();
/** Reset saved request data */
UFUNCTION(BlueprintCallable, Category = "VaRest|Request")
void ResetRequestData();
/** Reset saved response data */
UFUNCTION(BlueprintCallable, Category = "VaRest|Response")
void ResetResponseData();
/** Cancel latent response waiting */
UFUNCTION(BlueprintCallable, Category = "VaRest|Response")
void Cancel();
//////////////////////////////////////////////////////////////////////////
// JSON data accessors
/** Get the Request Json object */
UFUNCTION(BlueprintCallable, Category = "VaRest|Request")
UVaRestJsonObject* GetRequestObject() const;
/** Set the Request Json object */
UFUNCTION(BlueprintCallable, Category = "VaRest|Request")
void SetRequestObject(UVaRestJsonObject* JsonObject);
/** Get the Response Json object */
UFUNCTION(BlueprintCallable, Category = "VaRest|Response")
UVaRestJsonObject* GetResponseObject() const;
/** Set the Response Json object */
UFUNCTION(BlueprintCallable, Category = "VaRest|Response")
void SetResponseObject(UVaRestJsonObject* JsonObject);
/** Get the Response Json value */
UFUNCTION(BlueprintCallable, Category = "VaRest|Response")
UVaRestJsonValue* GetResponseValue() const;
///////////////////////////////////////////////////////////////////////////
// Request/response data access
/** Get url of http request */
UFUNCTION(BlueprintPure, Category = "VaRest|Request")
FString GetURL() const;
/** Get verb to the request */
UFUNCTION(BlueprintPure, Category = "VaRest|Request")
EVaRestRequestVerb GetVerb() const;
/** Get status of http request */
UFUNCTION(BlueprintPure, Category = "VaRest|Request")
EVaRestRequestStatus GetStatus() const;
/** Get the response code of the last query */
UFUNCTION(BlueprintPure, Category = "VaRest|Response")
int32 GetResponseCode() const;
/** Get value of desired response header */
UFUNCTION(BlueprintPure, Category = "VaRest|Response")
FString GetResponseHeader(const FString& HeaderName);
/** Get list of all response headers */
UFUNCTION(BlueprintPure, Category = "VaRest|Response")
TArray<FString> GetAllResponseHeaders() const;
/**
* Shortcut to get the Content-Length header value. Will not always return non-zero.
* If you want the real length of the payload, get the payload and check it's length.
*
* @return the content length (if available)
*/
UFUNCTION(BlueprintPure, Category = "VaRest|Response")
int32 GetResponseContentLength() const;
/**
* Get the content payload of the request or response.
*
* @param Content - array that will be filled with the content.
*/
UFUNCTION(BlueprintPure, Category = "VaRest|Response")
const TArray<uint8>& GetResponseContent() const;
//////////////////////////////////////////////////////////////////////////
// URL processing
public:
/** Setting request URL */
UFUNCTION(BlueprintCallable, Category = "VaRest|Request")
void SetURL(const FString& Url = TEXT("http://alyamkin.com"));
/** Open URL with current setup */
UFUNCTION(BlueprintCallable, Category = "VaRest|Request")
virtual void ProcessURL(const FString& Url = TEXT("http://alyamkin.com"));
/** Open URL in latent mode */
UFUNCTION(BlueprintCallable, Category = "VaRest|Request", meta = (Latent, LatentInfo = "LatentInfo", HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
virtual void ApplyURL(const FString& Url, UVaRestJsonObject*& Result, UObject* WorldContextObject, struct FLatentActionInfo LatentInfo);
/** Check URL and execute process request */
UFUNCTION(BlueprintCallable, Category = "VaRest|Request")
virtual void ExecuteProcessRequest();
protected:
/** Apply current internal setup to request and process it */
void ProcessRequest();
//////////////////////////////////////////////////////////////////////////
// Request callbacks
private:
/** Internal bind function for the IHTTPRequest::OnProcessRequestCompleted() event */
void OnProcessRequestComplete(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);
public:
/** Event occured when the request has been completed */
UPROPERTY(BlueprintAssignable, Category = "VaRest|Event")
FOnRequestComplete OnRequestComplete;
/** Event occured when the request wasn't successfull */
UPROPERTY(BlueprintAssignable, Category = "VaRest|Event")
FOnRequestFail OnRequestFail;
/** Event occured when the request has been completed */
FOnStaticRequestComplete OnStaticRequestComplete;
/** Event occured when the request wasn't successfull */
FOnStaticRequestFail OnStaticRequestFail;
//////////////////////////////////////////////////////////////////////////
// Tags
public:
/** Add tag to this request */
UFUNCTION(BlueprintCallable, Category = "VaRest|Utility")
void AddTag(FName Tag);
/**
* Remove tag from this request
*
* @return Number of removed elements
*/
UFUNCTION(BlueprintCallable, Category = "VaRest|Utility")
int32 RemoveTag(FName Tag);
/** See if this request contains the supplied tag */
UFUNCTION(BlueprintCallable, Category = "VaRest|Utility")
bool HasTag(FName Tag) const;
protected:
/** Array of tags that can be used for grouping and categorizing */
TArray<FName> Tags;
//////////////////////////////////////////////////////////////////////////
// Data
public:
/**
* Get request response stored as a string
* @param bCacheResponseContent - Set true if you plan to use it few times to prevent deserialization each time
*/
UFUNCTION(BlueprintCallable, Category = "VaRest|Response")
FString GetResponseContentAsString(bool bCacheResponseContent = true);
public:
/** Response size */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "VaRest|Response")
int32 ResponseSize;
/** DEPRECATED: Please use GetResponseContentAsString() instead */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "VaRest|Response")
FString ResponseContent;
/** Is the response valid JSON? */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "VaRest|Response")
bool bIsValidJsonResponse;
protected:
/** Default value for deprecated ResponseContent variable */
static FString DeprecatedResponseString;
protected:
/** Latent action helper */
FVaRestLatentAction<UVaRestJsonObject*>* ContinueAction;
/** Internal request data stored as JSON */
UPROPERTY()
UVaRestJsonObject* RequestJsonObj;
TArray<uint8> RequestBytes;
FString BinaryContentType;
/** Raw response storage */
TArray<uint8> ResponseBytes;
int32 ResponseContentLength;
/** Used for special cases when used wants to have plain string data in request.
* Attn.! Content-type x-www-form-urlencoded only. */
FString StringRequestContent;
/** Response data stored as JSON */
UPROPERTY()
UVaRestJsonObject* ResponseJsonObj;
/** Response data stored as JSON value */
UPROPERTY()
UVaRestJsonValue* ResponseJsonValue;
/** Verb for making request (GET,POST,etc) */
EVaRestRequestVerb RequestVerb;
/** Content type to be applied for request */
EVaRestRequestContentType RequestContentType;
/** Mapping of header section to values. Used to generate final header string for request */
TMap<FString, FString> RequestHeaders;
/** Cached key/value header pairs. Parsed once request completes */
TMap<FString, FString> ResponseHeaders;
/** Http Response code */
int32 ResponseCode;
/** Custom verb that will be used with RequestContentType == CUSTOM */
FString CustomVerb;
/** Request we're currently processing */
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> HttpRequest = FHttpModule::Get().CreateRequest();
public:
/** Returns reference to internal request object */
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> GetHttpRequest() const { return HttpRequest; };
};

View File

@ -1,20 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#pragma once
#include "VaRestSettings.generated.h"
UCLASS(config = Engine, defaultconfig)
class VAREST_API UVaRestSettings : public UObject
{
GENERATED_UCLASS_BODY()
public:
/** You can disable request content logging to avoid security vulnerability */
UPROPERTY(Config, EditAnywhere, Category = "VaRest")
bool bExtendedLog;
/** Use custom chunked parses (best for memory, but has issues with hex-encoded utf-8) */
UPROPERTY(Config, EditAnywhere, Category = "VaRest")
bool bUseChunkedParser;
};

View File

@ -1,129 +0,0 @@
// Copyright 2014-2020 Vladimir Alyamkin. All Rights Reserved.
#pragma once
#include "VaRestJsonObject.h"
#include "VaRestJsonValue.h"
#include "VaRestRequestJSON.h"
#include "Subsystems/EngineSubsystem.h"
#include "VaRestSubsystem.generated.h"
DECLARE_DYNAMIC_DELEGATE_OneParam(FVaRestCallDelegate, UVaRestRequestJSON*, Request);
USTRUCT()
struct FVaRestCallResponse
{
GENERATED_BODY()
UPROPERTY()
UVaRestRequestJSON* Request;
UPROPERTY()
FVaRestCallDelegate Callback;
FDelegateHandle CompleteDelegateHandle;
FDelegateHandle FailDelegateHandle;
FVaRestCallResponse()
: Request(nullptr)
{
}
};
UCLASS()
class VAREST_API UVaRestSubsystem : public UEngineSubsystem
{
GENERATED_BODY()
public:
UVaRestSubsystem();
// Begin USubsystem
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual void Deinitialize() override;
// End USubsystem
//////////////////////////////////////////////////////////////////////////
// Easy URL processing
public:
/** Easy way to process http requests */
UFUNCTION(BlueprintCallable, Category = "VaRest|Utility")
void CallURL(const FString& URL, EVaRestRequestVerb Verb, EVaRestRequestContentType ContentType, UVaRestJsonObject* VaRestJson, const FVaRestCallDelegate& Callback);
/** Called when URL is processed (one for both success/unsuccess events)*/
void OnCallComplete(UVaRestRequestJSON* Request);
protected:
UPROPERTY()
TMap<UVaRestRequestJSON*, FVaRestCallResponse> RequestMap;
//////////////////////////////////////////////////////////////////////////
// Construction helpers
public:
/** Creates new request (totally empty) */
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Construct Json Request (Empty)"), Category = "VaRest|Subsystem")
UVaRestRequestJSON* ConstructVaRestRequest();
/** Creates new request with defined verb and content type */
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Construct Json Request"), Category = "VaRest|Subsystem")
UVaRestRequestJSON* ConstructVaRestRequestExt(EVaRestRequestVerb Verb, EVaRestRequestContentType ContentType);
/** Create new Json object */
UFUNCTION(BlueprintCallable, meta = (DisplayName = "Construct Json Object"), Category = "VaRest|Subsystem")
UVaRestJsonObject* ConstructVaRestJsonObject();
/** Create new Json object (static one for MakeJson node, hack for #293) */
UFUNCTION()
static UVaRestJsonObject* StaticConstructVaRestJsonObject();
/** Create new Json Number value
* Attn.!! float used instead of double to make the function blueprintable! */
UFUNCTION(BlueprintPure, meta = (DisplayName = "Construct Json Number Value"), Category = "VaRest|Subsystem")
UVaRestJsonValue* ConstructJsonValueNumber(float Number);
/** Create new Json String value */
UFUNCTION(BlueprintPure, meta = (DisplayName = "Construct Json String Value"), Category = "VaRest|Subsystem")
UVaRestJsonValue* ConstructJsonValueString(const FString& StringValue);
/** Create new Json Bool value */
UFUNCTION(BlueprintPure, meta = (DisplayName = "Construct Json Bool Value"), Category = "VaRest|Subsystem")
UVaRestJsonValue* ConstructJsonValueBool(bool InValue);
/** Create new Json Array value */
UFUNCTION(BlueprintPure, meta = (DisplayName = "Construct Json Array Value"), Category = "VaRest|Subsystem")
UVaRestJsonValue* ConstructJsonValueArray(const TArray<UVaRestJsonValue*>& InArray);
/** Create new Json Object value */
UFUNCTION(BlueprintPure, meta = (DisplayName = "Construct Json Object Value"), Category = "VaRest|Subsystem")
UVaRestJsonValue* ConstructJsonValueObject(UVaRestJsonObject* JsonObject);
/** Create new Json value from FJsonValue (to be used from VaRestJsonObject) */
UVaRestJsonValue* ConstructJsonValue(const TSharedPtr<FJsonValue>& InValue);
//////////////////////////////////////////////////////////////////////////
// Serialization
public:
/** Construct Json value from string */
UFUNCTION(BlueprintCallable, Category = "VaRest|Subsystem")
UVaRestJsonValue* DecodeJsonValue(const FString& JsonString);
/** Construct Json object from string */
UFUNCTION(BlueprintCallable, Category = "VaRest|Subsystem")
UVaRestJsonObject* DecodeJsonObject(const FString& JsonString);
//////////////////////////////////////////////////////////////////////////
// File system integration
public:
/**
* Load JSON from formatted text file
* @param bIsRelativeToContentDir if set to 'false' path is treated as absolute
*/
UFUNCTION(BlueprintCallable, Category = "VaRest|Utility")
UVaRestJsonObject* LoadJsonFromFile(const FString& Path, const bool bIsRelativeToContentDir = true);
};

View File

@ -1,199 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#pragma once
#include "Engine/EngineBaseTypes.h"
#include "VaRestTypes.generated.h"
/** Verb (GET, PUT, POST) used by the request */
UENUM(BlueprintType)
enum class EVaRestRequestVerb : uint8
{
GET,
POST,
PUT,
DEL UMETA(DisplayName = "DELETE"),
/** Set CUSTOM verb by SetCustomVerb() function */
CUSTOM
};
// clang-format off
/** Content type (json, urlencoded, etc.) used by the request */
UENUM(BlueprintType)
enum class EVaRestRequestContentType : uint8
{
x_www_form_urlencoded_url UMETA(DisplayName = "x-www-form-urlencoded (URL)"),
x_www_form_urlencoded_body UMETA(DisplayName = "x-www-form-urlencoded (Request Body)"),
json,
binary
};
// clang-format on
/** Enumerates the current state of an Http request */
UENUM(BlueprintType)
enum class EVaRestRequestStatus : uint8
{
/** Has not been started via ProcessRequest() */
NotStarted,
/** Currently being ticked and processed */
Processing,
/** Finished but failed */
Failed,
/** Failed because it was unable to connect (safe to retry) */
Failed_ConnectionError,
/** Finished and was successful */
Succeeded
};
// Taken from Interfaces/IHttpResponse.h (had to make BlueprintType :/)
UENUM(BlueprintType)
namespace EVaRestHttpStatusCode
{
/**
* Response codes that can come back from an Http request
*/
enum Type
{
// status code not set yet
Unknown = 0 UMETA(DisplayName = "Unknown = 0"),
// the request can be continued.
Continue = 100 UMETA(DisplayName = "Continue = 100"),
// the server has switched protocols in an upgrade header.
SwitchProtocol = 101 UMETA(DisplayName = "SwitchProtocol = 101"),
// the request completed successfully.
Ok = 200 UMETA(DisplayName = "Ok = 200"),
// the request has been fulfilled and resulted in the creation of a new resource.
Created = 201 UMETA(DisplayName = "Created = 201"),
// the request has been accepted for processing, but the processing has not been completed.
Accepted = 202 UMETA(DisplayName = "Accepted = 202"),
// the returned meta information in the entity-header is not the definitive set available from the origin server.
Partial = 203 UMETA(DisplayName = "Partial = 203"),
// the server has fulfilled the request, but there is no new information to send back.
NoContent = 204 UMETA(DisplayName = "NoContent = 204"),
// the request has been completed, and the client program should reset the document view that caused the request to be sent to allow the user to easily initiate another input action.
ResetContent = 205 UMETA(DisplayName = "ResetContent = 205"),
// the server has fulfilled the partial get request for the resource.
PartialContent = 206 UMETA(DisplayName = "PartialContent = 206"),
// the server couldn't decide what to return.
Ambiguous = 300 UMETA(DisplayName = "Ambiguous = 300"),
// the requested resource has been assigned to a new permanent uri (uniform resource identifier), and any future references to this resource should be done using one of the returned uris.
Moved = 301 UMETA(DisplayName = "Moved = 301"),
// the requested resource resides temporarily under a different uri (uniform resource identifier).
Redirect = 302 UMETA(DisplayName = "Redirect = 302"),
// the response to the request can be found under a different uri (uniform resource identifier) and should be retrieved using a get http verb on that resource.
RedirectMethod = 303 UMETA(DisplayName = "RedirectMethod = 303"),
// the requested resource has not been modified.
NotModified = 304 UMETA(DisplayName = "NotModified = 304"),
// the requested resource must be accessed through the proxy given by the location field.
UseProxy = 305 UMETA(DisplayName = "UseProxy = 305"),
// the redirected request keeps the same http verb. http/1.1 behavior.
RedirectKeepVerb = 307 UMETA(DisplayName = "RedirectKeepVerb = 307"),
// the request could not be processed by the server due to invalid syntax.
BadRequest = 400 UMETA(DisplayName = "BadRequest = 400"),
// the requested resource requires user authentication.
Denied = 401 UMETA(DisplayName = "Denied = 401"),
// not currently implemented in the http protocol.
PaymentReq = 402 UMETA(DisplayName = "PaymentReq = 402"),
// the server understood the request, but is refusing to fulfill it.
Forbidden = 403 UMETA(DisplayName = "Forbidden = 403"),
// the server has not found anything matching the requested uri (uniform resource identifier).
NotFound = 404 UMETA(DisplayName = "NotFound = 404"),
// the http verb used is not allowed.
BadMethod = 405 UMETA(DisplayName = "BadMethod = 405"),
// no responses acceptable to the client were found.
NoneAcceptable = 406 UMETA(DisplayName = "NoneAcceptable = 406"),
// proxy authentication required.
ProxyAuthReq = 407 UMETA(DisplayName = "ProxyAuthReq = 407"),
// the server timed out waiting for the request.
RequestTimeout = 408 UMETA(DisplayName = "RequestTimeout = 408"),
// the request could not be completed due to a conflict with the current state of the resource. the user should resubmit with more information.
Conflict = 409 UMETA(DisplayName = "Conflict = 409"),
// the requested resource is no longer available at the server, and no forwarding address is known.
Gone = 410 UMETA(DisplayName = "Gone = 410"),
// the server refuses to accept the request without a defined content length.
LengthRequired = 411 UMETA(DisplayName = "LengthRequired = 411"),
// the precondition given in one or more of the request header fields evaluated to false when it was tested on the server.
PrecondFailed = 412 UMETA(DisplayName = "PrecondFailed = 412"),
// the server is refusing to process a request because the request entity is larger than the server is willing or able to process.
RequestTooLarge = 413 UMETA(DisplayName = "RequestTooLarge = 413"),
// the server is refusing to service the request because the request uri (uniform resource identifier) is longer than the server is willing to interpret.
UriTooLong = 414 UMETA(DisplayName = "UriTooLong = 414"),
// the server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method.
UnsupportedMedia = 415 UMETA(DisplayName = "UnsupportedMedia = 415"),
// too many requests, the server is throttling
TooManyRequests = 429 UMETA(DisplayName = "TooManyRequests = 429"),
// the request should be retried after doing the appropriate action.
RetryWith = 449 UMETA(DisplayName = "RetryWith = 449"),
// the server encountered an unexpected condition that prevented it from fulfilling the request.
ServerError = 500 UMETA(DisplayName = "ServerError = 500"),
// the server does not support the functionality required to fulfill the request.
NotSupported = 501 UMETA(DisplayName = "NotSupported = 501"),
// the server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request.
BadGateway = 502 UMETA(DisplayName = "BadGateway = 502"),
// the service is temporarily overloaded.
ServiceUnavail = 503 UMETA(DisplayName = "ServiceUnavail = 503"),
// the request was timed out waiting for a gateway.
GatewayTimeout = 504 UMETA(DisplayName = "GatewayTimeout = 504"),
// the server does not support, or refuses to support, the http protocol version that was used in the request message.
VersionNotSup = 505 UMETA(DisplayName = "VersionNotSup = 505")
};
} // namespace EVaRestHttpStatusCode
/**
* FURL structure wrapper for BP access
*/
USTRUCT(BlueprintType)
struct VAREST_API FVaRestURL
{
GENERATED_BODY()
/** Protocol, i.e. "unreal" or "http" */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "URL")
FString Protocol;
/** Optional hostname, i.e. "204.157.115.40" or "unreal.epicgames.com", blank if local. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "URL")
FString Host;
/** Optional host port */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "URL")
int32 Port;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "URL")
int32 Valid;
/** Map name, i.e. "SkyCity", default is "Entry" */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "URL")
FString Map;
/** Optional place to download Map if client does not possess it */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "URL")
FString RedirectURL;
/** Options */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "URL")
TArray<FString> Op;
/** Portal to enter through, default is "" */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "URL")
FString Portal;
FVaRestURL()
: Port(0)
, Valid(0)
{
}
FVaRestURL(FURL& InUrl)
: Protocol(InUrl.Protocol)
, Host(InUrl.Host)
, Port(InUrl.Port)
, Valid(InUrl.Valid)
, Map(InUrl.Map)
, RedirectURL(InUrl.RedirectURL)
, Op(InUrl.Op)
, Portal(InUrl.Portal)
{
}
};

View File

@ -1,34 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
using System.IO;
namespace UnrealBuildTool.Rules
{
public class VaRest : ModuleRules
{
public VaRest(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PrecompileForTargets = PrecompileTargetsType.Any;
IncludeOrderVersion = EngineIncludeOrderVersion.Latest;
PrivateIncludePaths.AddRange(
new string[] {
"VaRest/Private",
// ... add other private include paths required here ...
});
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
"CoreUObject",
"Engine",
"HTTP",
"Json",
"Projects" // Required by IPluginManager etc (used to get plugin information)
// ... add other public dependencies that you statically link with here ...
});
}
}
}

View File

@ -1,22 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#include "VaRestEditor.h"
#include "Modules/ModuleManager.h"
#define LOCTEXT_NAMESPACE "FVaRestEditorModule"
void FVaRestEditorModule::StartupModule()
{
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
}
void FVaRestEditorModule::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.
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FVaRestEditorModule, VaRestEditor)

View File

@ -1,561 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
// Original code by https://github.com/unktomi
#include "VaRest_BreakJson.h"
#include "BlueprintActionDatabaseRegistrar.h"
#include "BlueprintNodeSpawner.h"
#include "EdGraph/EdGraph.h"
#include "EdGraph/EdGraphNodeUtils.h" // for FNodeTextCache
#include "EdGraphSchema_K2.h"
#include "EdGraphUtilities.h"
#include "EditorCategoryUtils.h"
#include "KismetCompiler.h"
#include "Runtime/Launch/Resources/Version.h"
#define LOCTEXT_NAMESPACE "VaRest_BreakJson"
class FKCHandler_BreakJson : public FNodeHandlingFunctor
{
public:
FKCHandler_BreakJson(FKismetCompilerContext& InCompilerContext)
: FNodeHandlingFunctor(InCompilerContext)
{
}
virtual void Compile(FKismetFunctionContext& Context, UEdGraphNode* Node) override
{
UEdGraphPin* InputPin = nullptr;
for (int32 PinIndex = 0; PinIndex < Node->Pins.Num(); ++PinIndex)
{
UEdGraphPin* Pin = Node->Pins[PinIndex];
if (Pin && (EGPD_Input == Pin->Direction))
{
InputPin = Pin;
break;
}
}
UEdGraphPin* InNet = FEdGraphUtilities::GetNetFromPin(InputPin);
UClass* Class = Cast<UClass>(StaticLoadObject(UClass::StaticClass(), nullptr, TEXT("class'VaRest.VaRestJsonObject'")));
FBPTerminal** SourceTerm = Context.NetMap.Find(InNet);
if (SourceTerm == nullptr)
{
return;
}
for (int32 PinIndex = 0; PinIndex < Node->Pins.Num(); ++PinIndex)
{
UEdGraphPin* Pin = Node->Pins[PinIndex];
if (Pin && (EGPD_Output == Pin->Direction))
{
if (Pin->LinkedTo.Num() < 1)
{
continue;
}
FBPTerminal** Target = Context.NetMap.Find(Pin);
const FName& FieldName = Pin->PinName;
const FName& FieldType = Pin->PinType.PinCategory;
FBPTerminal* FieldNameTerm = Context.CreateLocalTerminal(ETerminalSpecification::TS_Literal);
FieldNameTerm->Type.PinCategory = CompilerContext.GetSchema()->PC_String;
FieldNameTerm->SourcePin = Pin;
FieldNameTerm->Name = FieldName.ToString();
FieldNameTerm->TextLiteral = FText::FromName(FieldName);
FBlueprintCompiledStatement& Statement = Context.AppendStatementForNode(Node);
FName FunctionName;
const bool bIsArray = Pin->PinType.ContainerType == EPinContainerType::Array;
if (FieldType == CompilerContext.GetSchema()->PC_Boolean)
{
FunctionName = bIsArray ? TEXT("GetBoolArrayField") : TEXT("GetBoolField");
}
else if (FieldType == CompilerContext.GetSchema()->PC_Real)
{
FunctionName = bIsArray ? TEXT("GetNumberArrayField") : TEXT("GetNumberField");
}
else if (FieldType == CompilerContext.GetSchema()->PC_String)
{
FunctionName = bIsArray ? TEXT("GetStringArrayField") : TEXT("GetStringField");
}
else if (FieldType == CompilerContext.GetSchema()->PC_Object)
{
FunctionName = bIsArray ? TEXT("GetObjectArrayField") : TEXT("GetObjectField");
}
else
{
continue;
}
UFunction* FunctionPtr = Class->FindFunctionByName(FunctionName);
Statement.Type = KCST_CallFunction;
Statement.FunctionToCall = FunctionPtr;
Statement.FunctionContext = *SourceTerm;
Statement.bIsParentContext = false;
Statement.LHS = *Target;
Statement.RHS.Add(FieldNameTerm);
}
}
}
FBPTerminal* RegisterInputTerm(FKismetFunctionContext& Context, UVaRest_BreakJson* Node)
{
// Find input pin
UEdGraphPin* InputPin = nullptr;
for (int32 PinIndex = 0; PinIndex < Node->Pins.Num(); ++PinIndex)
{
UEdGraphPin* Pin = Node->Pins[PinIndex];
if (Pin && (EGPD_Input == Pin->Direction))
{
InputPin = Pin;
break;
}
}
check(NULL != InputPin);
// Find structure source net
UEdGraphPin* Net = FEdGraphUtilities::GetNetFromPin(InputPin);
FBPTerminal** TermPtr = Context.NetMap.Find(Net);
if (!TermPtr)
{
FBPTerminal* Term = Context.CreateLocalTerminalFromPinAutoChooseScope(Net, Context.NetNameMap->MakeValidName(Net));
Context.NetMap.Add(Net, Term);
return Term;
}
return *TermPtr;
}
void RegisterOutputTerm(FKismetFunctionContext& Context, UEdGraphPin* OutputPin, FBPTerminal* ContextTerm)
{
FBPTerminal* Term = Context.CreateLocalTerminalFromPinAutoChooseScope(OutputPin, Context.NetNameMap->MakeValidName(OutputPin));
Context.NetMap.Add(OutputPin, Term);
}
virtual void RegisterNets(FKismetFunctionContext& Context, UEdGraphNode* InNode) override
{
UVaRest_BreakJson* Node = Cast<UVaRest_BreakJson>(InNode);
FNodeHandlingFunctor::RegisterNets(Context, Node);
check(NULL != Node);
if (FBPTerminal* StructContextTerm = RegisterInputTerm(Context, Node))
{
for (int32 PinIndex = 0; PinIndex < Node->Pins.Num(); ++PinIndex)
{
UEdGraphPin* Pin = Node->Pins[PinIndex];
if (nullptr != Pin && EGPD_Output == Pin->Direction)
{
RegisterOutputTerm(Context, Pin, StructContextTerm);
}
}
}
}
};
/**
* Main node class
*/
UVaRest_BreakJson::UVaRest_BreakJson(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
FNodeHandlingFunctor* UVaRest_BreakJson::CreateNodeHandler(class FKismetCompilerContext& CompilerContext) const
{
return new FKCHandler_BreakJson(CompilerContext);
}
void UVaRest_BreakJson::AllocateDefaultPins()
{
const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();
UClass* Class = Cast<UClass>(StaticLoadObject(UClass::StaticClass(), nullptr, TEXT("class'VaRest.VaRestJsonObject'")));
UEdGraphPin* Pin = CreatePin(EGPD_Input, K2Schema->PC_Object, TEXT(""), Class, TEXT("Target"));
K2Schema->SetPinAutogeneratedDefaultValueBasedOnType(Pin);
CreateProjectionPins(Pin);
}
FLinearColor UVaRest_BreakJson::GetNodeTitleColor() const
{
return FLinearColor(255.0f, 255.0f, 0.0f);
}
void UVaRest_BreakJson::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent)
{
const FName PropertyName = (PropertyChangedEvent.Property != nullptr) ? PropertyChangedEvent.Property->GetFName() : NAME_None;
if (PropertyName == GET_MEMBER_NAME_STRING_CHECKED(UVaRest_BreakJson, Outputs) ||
PropertyName == GET_MEMBER_NAME_STRING_CHECKED(FVaRest_NamedType, Name) ||
PropertyName == GET_MEMBER_NAME_STRING_CHECKED(FVaRest_NamedType, Type) ||
PropertyName == GET_MEMBER_NAME_STRING_CHECKED(FVaRest_NamedType, bIsArray))
{
ReconstructNode();
GetGraph()->NotifyGraphChanged();
}
Super::PostEditChangeProperty(PropertyChangedEvent);
}
void UVaRest_BreakJson::GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const
{
// actions get registered under specific object-keys; the idea is that
// actions might have to be updated (or deleted) if their object-key is
// mutated (or removed)... here we use the node's class (so if the node
// type disappears, then the action should go with it)
UClass* ActionKey = GetClass();
// to keep from needlessly instantiating a UBlueprintNodeSpawner, first
// check to make sure that the registrar is looking for actions of this type
// (could be regenerating actions for a specific asset, and therefore the
// registrar would only accept actions corresponding to that asset)
if (ActionRegistrar.IsOpenForRegistration(ActionKey))
{
UBlueprintNodeSpawner* NodeSpawner = UBlueprintNodeSpawner::Create(GetClass());
check(NodeSpawner != nullptr);
ActionRegistrar.AddBlueprintAction(ActionKey, NodeSpawner);
}
}
FText UVaRest_BreakJson::GetMenuCategory() const
{
static FNodeTextCache CachedCategory;
if (CachedCategory.IsOutOfDate(this))
{
// FText::Format() is slow, so we cache this to save on performance
CachedCategory.SetCachedText(FEditorCategoryUtils::BuildCategoryString(FCommonEditorCategory::Utilities, LOCTEXT("ActionMenuCategory", "VaRest")), this);
}
return CachedCategory;
}
void UVaRest_BreakJson::CreateProjectionPins(UEdGraphPin* Source)
{
const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();
UClass* Class = Cast<UClass>(StaticLoadObject(UClass::StaticClass(), nullptr, TEXT("class'VaRest.VaRestJsonObject'")));
for (TArray<FVaRest_NamedType>::TIterator it(Outputs); it; ++it)
{
FName Type;
FName SubCategory;
UObject* Subtype = nullptr;
switch ((*it).Type)
{
case EVaRest_JsonType::JSON_Bool:
Type = K2Schema->PC_Boolean;
break;
case EVaRest_JsonType::JSON_Number:
Type = K2Schema->PC_Real;
SubCategory = K2Schema->PC_Double;
break;
case EVaRest_JsonType::JSON_String:
Type = K2Schema->PC_String;
break;
case EVaRest_JsonType::JSON_Object:
Type = K2Schema->PC_Object;
Subtype = Class;
break;
}
UEdGraphNode::FCreatePinParams OutputPinParams;
OutputPinParams.ContainerType = (*it).bIsArray ? EPinContainerType::Array : EPinContainerType::None;
UEdGraphPin* OutputPin = CreatePin(EGPD_Output, Type, SubCategory, Subtype, (*it).Name, OutputPinParams);
}
}
FText UVaRest_BreakJson::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
return LOCTEXT("VaRest_Break_Json.NodeTitle", "Break Json");
}
class FKCHandler_MakeJson : public FNodeHandlingFunctor
{
public:
FKCHandler_MakeJson(FKismetCompilerContext& InCompilerContext)
: FNodeHandlingFunctor(InCompilerContext)
{
}
virtual void Compile(FKismetFunctionContext& Context, UEdGraphNode* Node) override
{
UEdGraphPin* OutputPin = nullptr;
for (int32 PinIndex = 0; PinIndex < Node->Pins.Num(); ++PinIndex)
{
UEdGraphPin* Pin = Node->Pins[PinIndex];
if (Pin && (EGPD_Output == Pin->Direction))
{
OutputPin = Pin;
break;
}
}
UClass* Class = Cast<UClass>(StaticLoadObject(UClass::StaticClass(), nullptr, TEXT("class'VaRest.VaRestJsonObject'")));
FBPTerminal** TargetTerm = Context.NetMap.Find(OutputPin);
if (TargetTerm == nullptr)
{
return;
}
{
UClass* SubsystemClass = Cast<UClass>(StaticLoadObject(UClass::StaticClass(), nullptr, TEXT("class'VaRest.VaRestSubsystem'")));
const FName FunctionName = TEXT("StaticConstructVaRestJsonObject");
UFunction* FunctionPtr = SubsystemClass->FindFunctionByName(FunctionName);
FBlueprintCompiledStatement& Statement = Context.AppendStatementForNode(Node);
Statement.Type = KCST_CallFunction;
Statement.FunctionToCall = FunctionPtr;
Statement.FunctionContext = nullptr;
Statement.bIsParentContext = false;
Statement.LHS = *TargetTerm;
FBPTerminal* NullTerm = Context.CreateLocalTerminal(ETerminalSpecification::TS_Literal);
NullTerm->Type.PinCategory = CompilerContext.GetSchema()->PC_Object;
NullTerm->ObjectLiteral = nullptr;
NullTerm->SourcePin = OutputPin;
Statement.RHS.Add(NullTerm);
}
for (int32 PinIndex = 0; PinIndex < Node->Pins.Num(); ++PinIndex)
{
UEdGraphPin* Pin = Node->Pins[PinIndex];
if (Pin && (EGPD_Input == Pin->Direction))
{
FBPTerminal** Source = Context.NetMap.Find(FEdGraphUtilities::GetNetFromPin(Pin));
const FName& FieldName = Pin->PinName;
const FName& FieldType = Pin->PinType.PinCategory;
FBPTerminal* FieldNameTerm = Context.CreateLocalTerminal(ETerminalSpecification::TS_Literal);
FieldNameTerm->Type.PinCategory = CompilerContext.GetSchema()->PC_String;
FieldNameTerm->SourcePin = Pin;
FieldNameTerm->Name = FieldName.ToString();
FieldNameTerm->TextLiteral = FText::FromName(FieldName);
FBlueprintCompiledStatement& Statement = Context.AppendStatementForNode(Node);
FName FunctionName;
const bool bIsArray = Pin->PinType.ContainerType == EPinContainerType::Array;
if (FieldType == CompilerContext.GetSchema()->PC_Boolean)
{
FunctionName = bIsArray ? TEXT("SetBoolArrayField") : TEXT("SetBoolField");
}
else if (FieldType == CompilerContext.GetSchema()->PC_Real)
{
FunctionName = bIsArray ? TEXT("SetNumberArrayFieldDouble") : TEXT("SetNumberFieldDouble");
}
else if (FieldType == CompilerContext.GetSchema()->PC_String)
{
FunctionName = bIsArray ? TEXT("SetStringArrayField") : TEXT("SetStringField");
}
else if (FieldType == CompilerContext.GetSchema()->PC_Object)
{
FunctionName = bIsArray ? TEXT("SetObjectArrayField") : TEXT("SetObjectField");
}
else
{
continue;
}
UFunction* FunctionPtr = Class->FindFunctionByName(FunctionName);
Statement.Type = KCST_CallFunction;
Statement.FunctionToCall = FunctionPtr;
Statement.FunctionContext = *TargetTerm;
Statement.bIsParentContext = false;
Statement.LHS = nullptr;
Statement.RHS.Add(FieldNameTerm);
Statement.RHS.Add(*Source);
}
}
}
FBPTerminal* RegisterInputTerm(FKismetFunctionContext& Context, UEdGraphPin* InputPin)
{
// Find structure source net
UEdGraphPin* Net = FEdGraphUtilities::GetNetFromPin(InputPin);
FBPTerminal** TermPtr = Context.NetMap.Find(Net);
if (!TermPtr)
{
FBPTerminal* Term = Context.CreateLocalTerminalFromPinAutoChooseScope(Net, Context.NetNameMap->MakeValidName(Net));
Context.NetMap.Add(Net, Term);
return Term;
}
return *TermPtr;
}
void RegisterOutputTerm(FKismetFunctionContext& Context, UEdGraphPin* OutputPin)
{
FBPTerminal* Term = Context.CreateLocalTerminalFromPinAutoChooseScope(OutputPin, Context.NetNameMap->MakeValidName(OutputPin));
Context.NetMap.Add(OutputPin, Term);
}
virtual void RegisterNets(FKismetFunctionContext& Context, UEdGraphNode* InNode) override
{
UVaRest_MakeJson* Node = Cast<UVaRest_MakeJson>(InNode);
FNodeHandlingFunctor::RegisterNets(Context, Node);
check(NULL != Node);
{
for (int32 PinIndex = 0; PinIndex < Node->Pins.Num(); ++PinIndex)
{
UEdGraphPin* Pin = Node->Pins[PinIndex];
if (EGPD_Output == Pin->Direction)
{
RegisterOutputTerm(Context, Pin);
}
else
{
RegisterInputTerm(Context, Pin);
}
}
}
}
};
/**
* Main node class
*/
UVaRest_MakeJson::UVaRest_MakeJson(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
FNodeHandlingFunctor* UVaRest_MakeJson::CreateNodeHandler(class FKismetCompilerContext& CompilerContext) const
{
return new FKCHandler_MakeJson(CompilerContext);
}
void UVaRest_MakeJson::AllocateDefaultPins()
{
const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();
UClass* Class = Cast<UClass>(StaticLoadObject(UClass::StaticClass(), nullptr, TEXT("class'VaRest.VaRestJsonObject'")));
UEdGraphPin* Pin = CreatePin(EGPD_Output, K2Schema->PC_Object, TEXT(""), Class, TEXT("Target"));
K2Schema->SetPinAutogeneratedDefaultValueBasedOnType(Pin);
CreateProjectionPins(Pin);
}
FLinearColor UVaRest_MakeJson::GetNodeTitleColor() const
{
return FLinearColor(255.0f, 255.0f, 0.0f);
}
void UVaRest_MakeJson::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent)
{
const FName PropertyName = (PropertyChangedEvent.Property != nullptr) ? PropertyChangedEvent.Property->GetFName() : NAME_None;
if (PropertyName == GET_MEMBER_NAME_STRING_CHECKED(UVaRest_MakeJson, Inputs) ||
PropertyName == GET_MEMBER_NAME_STRING_CHECKED(FVaRest_NamedType, Name) ||
PropertyName == GET_MEMBER_NAME_STRING_CHECKED(FVaRest_NamedType, Type) ||
PropertyName == GET_MEMBER_NAME_STRING_CHECKED(FVaRest_NamedType, bIsArray))
{
ReconstructNode();
GetGraph()->NotifyGraphChanged();
}
Super::PostEditChangeProperty(PropertyChangedEvent);
}
void UVaRest_MakeJson::GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const
{
// actions get registered under specific object-keys; the idea is that
// actions might have to be updated (or deleted) if their object-key is
// mutated (or removed)... here we use the node's class (so if the node
// type disappears, then the action should go with it)
UClass* ActionKey = GetClass();
// to keep from needlessly instantiating a UBlueprintNodeSpawner, first
// check to make sure that the registrar is looking for actions of this type
// (could be regenerating actions for a specific asset, and therefore the
// registrar would only accept actions corresponding to that asset)
if (ActionRegistrar.IsOpenForRegistration(ActionKey))
{
UBlueprintNodeSpawner* NodeSpawner = UBlueprintNodeSpawner::Create(GetClass());
check(NodeSpawner != nullptr);
ActionRegistrar.AddBlueprintAction(ActionKey, NodeSpawner);
}
}
FText UVaRest_MakeJson::GetMenuCategory() const
{
static FNodeTextCache CachedCategory;
if (CachedCategory.IsOutOfDate(this))
{
// FText::Format() is slow, so we cache this to save on performance
CachedCategory.SetCachedText(FEditorCategoryUtils::BuildCategoryString(FCommonEditorCategory::Utilities, LOCTEXT("ActionMenuCategory", "VaRest")), this);
}
return CachedCategory;
}
void UVaRest_MakeJson::CreateProjectionPins(UEdGraphPin* Source)
{
const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();
UClass* Class = Cast<UClass>(StaticLoadObject(UClass::StaticClass(), nullptr, TEXT("class'VaRest.VaRestJsonObject'")));
for (TArray<FVaRest_NamedType>::TIterator it(Inputs); it; ++it)
{
FName Type;
FName SubCategory;
UObject* Subtype = nullptr;
switch ((*it).Type)
{
case EVaRest_JsonType::JSON_Bool:
Type = K2Schema->PC_Boolean;
break;
case EVaRest_JsonType::JSON_Number:
Type = K2Schema->PC_Real;
SubCategory = K2Schema->PC_Double;
break;
case EVaRest_JsonType::JSON_String:
Type = K2Schema->PC_String;
break;
case EVaRest_JsonType::JSON_Object:
Type = K2Schema->PC_Object;
Subtype = Class;
break;
}
UEdGraphNode::FCreatePinParams InputPinParams;
InputPinParams.ContainerType = (*it).bIsArray ? EPinContainerType::Array : EPinContainerType::None;
UEdGraphPin* InputPin = CreatePin(EGPD_Input, Type, SubCategory, Subtype, (*it).Name, InputPinParams);
InputPin->SetSavePinIfOrphaned(false);
}
}
FText UVaRest_MakeJson::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
return LOCTEXT("VaRest_Make_Json.NodeTitle", "Make Json");
}
#undef LOCTEXT_NAMESPACE

View File

@ -1,14 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
#pragma once
#include "Modules/ModuleInterface.h"
class FVaRestEditorModule : public IModuleInterface
{
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};

View File

@ -1,100 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
// Original code by https://github.com/unktomi
#pragma once
#include "Runtime/Launch/Resources/Version.h"
#include "CoreMinimal.h"
#include "K2Node.h"
#include "VaRest_BreakJson.generated.h"
UENUM(BlueprintType)
enum class EVaRest_JsonType : uint8
{
// JSON_Null UMETA(DisplayName = "Null"),
JSON_Bool UMETA(DisplayName = "Boolean"),
JSON_Number UMETA(DisplayName = "Number"),
JSON_String UMETA(DisplayName = "String"),
JSON_Object UMETA(DisplayName = "Object")
};
USTRUCT(BlueprintType)
struct FVaRest_NamedType
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, Category = NamedType)
FName Name;
UPROPERTY(EditAnywhere, Category = NamedType)
EVaRest_JsonType Type;
UPROPERTY(EditAnywhere, Category = NamedType)
bool bIsArray;
FVaRest_NamedType()
: Type(EVaRest_JsonType::JSON_String)
, bIsArray(false)
{
}
};
UCLASS(BlueprintType, Blueprintable)
class VARESTEDITOR_API UVaRest_MakeJson : public UK2Node
{
GENERATED_UCLASS_BODY()
public:
// Begin UEdGraphNode interface.
virtual void AllocateDefaultPins() override;
virtual FLinearColor GetNodeTitleColor() const override;
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
// End UEdGraphNode interface.
// Begin UK2Node interface
virtual bool IsNodePure() const { return true; }
virtual bool ShouldShowNodeProperties() const { return true; }
void GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const override;
virtual FText GetMenuCategory() const override;
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual class FNodeHandlingFunctor* CreateNodeHandler(class FKismetCompilerContext& CompilerContext) const override;
// End UK2Node interface.
protected:
virtual void CreateProjectionPins(UEdGraphPin* Source);
public:
UPROPERTY(EditAnywhere, Category = PinOptions)
TArray<FVaRest_NamedType> Inputs;
};
UCLASS(BlueprintType, Blueprintable)
class VARESTEDITOR_API UVaRest_BreakJson : public UK2Node
{
GENERATED_UCLASS_BODY()
public:
// Begin UEdGraphNode interface.
virtual void AllocateDefaultPins() override;
virtual FLinearColor GetNodeTitleColor() const override;
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
// End UEdGraphNode interface.
// Begin UK2Node interface
virtual bool IsNodePure() const { return true; }
virtual bool ShouldShowNodeProperties() const { return true; }
void GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const override;
virtual FText GetMenuCategory() const override;
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual class FNodeHandlingFunctor* CreateNodeHandler(class FKismetCompilerContext& CompilerContext) const override;
// End UK2Node interface.
protected:
virtual void CreateProjectionPins(UEdGraphPin* Source);
public:
UPROPERTY(EditAnywhere, Category = PinOptions)
TArray<FVaRest_NamedType> Outputs;
};

View File

@ -1,60 +0,0 @@
// Copyright 2014-2019 Vladimir Alyamkin. All Rights Reserved.
using UnrealBuildTool;
public class VaRestEditor : ModuleRules
{
public VaRestEditor(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
IncludeOrderVersion = EngineIncludeOrderVersion.Latest;
PrivateIncludePaths.AddRange(
new string[] {
"VaRestEditor/Private",
// ... add other private include paths required here ...
});
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
"VaRest"
// ... add other public dependencies that you statically link with here ...
});
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
"InputCore",
"AssetTools",
"UnrealEd", // for FAssetEditorManager
"KismetWidgets",
"KismetCompiler",
"BlueprintGraph",
"GraphEditor",
"Kismet", // for FWorkflowCentricApplication
"PropertyEditor",
"EditorStyle",
"Sequencer",
"DetailCustomizations",
"Settings",
"RenderCore"
});
DynamicallyLoadedModuleNames.AddRange(
new string[]
{
// ... add any modules that your module loads dynamically here ...
});
}
}

View File

@ -1,28 +0,0 @@
{
"FileVersion": 3,
"Version": 32,
"VersionName": "1.1-r32",
"FriendlyName": "VaRest",
"Description": "Plugin that makes REST (JSON) server communication easy to use",
"Category": "Network",
"CreatedBy": "Vladimir Alyamkin",
"CreatedByURL": "https://ufna.dev",
"DocsURL": "https://bit.ly/VaRest-Docs",
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/e47be161e7a24e928560290abd5dcc4f",
"SupportURL": "",
"EngineVersion": "5.5.0+",
"CanContainContent": false,
"Installed": true,
"Modules": [
{
"Name": "VaRest",
"Type": "Runtime",
"LoadingPhase": "PreDefault"
},
{
"Name": "VaRestEditor",
"Type": "UncookedOnly",
"LoadingPhase": "Default"
}
]
}

View File

@ -17,7 +17,6 @@ public class LuckyWorldV2 : ModuleRules
"LuckyMujoco", "LuckyMujoco",
"LuckyTextWrite", "LuckyTextWrite",
"SocketIOClient", "SocketIOClient",
"VaRest",
"SIOJson", "SIOJson",
"NavigationSystem" "NavigationSystem"
}); });

View File

@ -9,9 +9,11 @@
#include "GameFramework/GameUserSettings.h" #include "GameFramework/GameUserSettings.h"
#include "Kismet/KismetMathLibrary.h" #include "Kismet/KismetMathLibrary.h"
#include "FunctionLibraries/LuckyRobotsFunctionLibrary.h" #include "FunctionLibraries/LuckyRobotsFunctionLibrary.h"
#include "VaRestSubsystem.h"
#include "Subsystems/SubsystemBlueprintLibrary.h" #include "Subsystems/SubsystemBlueprintLibrary.h"
#include "Gameplay/TargetSelector.h" #include "Gameplay/TargetSelector.h"
#include "Serialization/JsonSerializer.h"
#include "Dom/JsonObject.h"
#include "JsonObjectConverter.h"
void ULuckyRobotsGameInstance::DoSendMessage(const FString& SendValue) void ULuckyRobotsGameInstance::DoSendMessage(const FString& SendValue)
{ {
@ -289,30 +291,48 @@ TArray<FSelectableItemData> ULuckyRobotsGameInstance::GetSelectableItemList(EIte
void ULuckyRobotsGameInstance::GetMessageParse(FString Json) void ULuckyRobotsGameInstance::GetMessageParse(FString Json)
{ {
auto VaRestSubsystem = CastChecked<UVaRestSubsystem>(USubsystemBlueprintLibrary::GetEngineSubsystem(UVaRestSubsystem::StaticClass()), ECastCheckedType::NullChecked); TSharedPtr<FJsonObject> JsonObject;
if (VaRestSubsystem) TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Json);
if (FJsonSerializer::Deserialize(Reader, JsonObject) && JsonObject.IsValid())
{ {
UVaRestJsonObject* VaRestJsonObject = VaRestSubsystem->ConstructVaRestJsonObject(); const TArray<TSharedPtr<FJsonValue>>* LuckyCodeArray;
if (VaRestJsonObject) if (JsonObject->TryGetArrayField(TEXT("LuckyCode"), LuckyCodeArray))
{
if (VaRestJsonObject->DecodeJson(Json, true))
{
TArray<UVaRestJsonValue*> VaRestJsonValueList = VaRestJsonObject->GetArrayField("LuckyCode");
if (VaRestJsonValueList.Num() > 0)
{ {
LuckyCodeList.Empty(); LuckyCodeList.Empty();
for (auto VaRestJsonValue : VaRestJsonValueList) for (const TSharedPtr<FJsonValue>& Value : *LuckyCodeArray)
{ {
if (VaRestJsonValue) const TSharedPtr<FJsonObject>* TempObjectPtr;
if (Value->TryGetObject(TempObjectPtr))
{ {
UVaRestJsonObject* TempObject = VaRestJsonValue->AsObject(); const TSharedPtr<FJsonObject>& TempObject = *TempObjectPtr;
if (TempObject) if (TempObject.IsValid())
{ {
FLuckyCode TempLuckyCode; FLuckyCode TempLuckyCode;
TempLuckyCode.ID = FCString::Atoi(*(TempObject->GetStringField("ID"))); int32 TempID = 0;
TempLuckyCode.Code = TempObject->GetStringField("code"); FString IDString;
TempLuckyCode.Time = FCString::Atof(*(TempObject->GetStringField("time"))); if (TempObject->TryGetStringField(TEXT("ID"), IDString))
TempLuckyCode.bCallback = (TempObject->GetStringField("callback") == "on"); {
TempID = FCString::Atoi(*IDString);
}
TempLuckyCode.ID = TempID;
FString CodeString;
TempObject->TryGetStringField(TEXT("code"), CodeString);
TempLuckyCode.Code = CodeString;
double TempTime = 0.0;
FString TimeString;
if (TempObject->TryGetStringField(TEXT("time"), TimeString))
{
TempTime = FCString::Atod(*TimeString);
}
TempLuckyCode.Time = static_cast<float>(TempTime);
FString CallbackString;
TempObject->TryGetStringField(TEXT("callback"), CallbackString);
TempLuckyCode.bCallback = (CallbackString.Equals(TEXT("on"), ESearchCase::IgnoreCase));
LuckyCodeList.Add(TempLuckyCode); LuckyCodeList.Add(TempLuckyCode);
} }
} }
@ -320,61 +340,94 @@ void ULuckyRobotsGameInstance::GetMessageParse(FString Json)
} }
else else
{ {
UVaRestJsonValue* VaRestJsonValue = VaRestJsonObject->GetField("LuckyCapture"); const TSharedPtr<FJsonObject>* LuckyCaptureObject;
if (VaRestJsonValue) if (JsonObject->TryGetObjectField(TEXT("LuckyCapture"), LuckyCaptureObject))
{ {
UVaRestJsonObject* TempObject = VaRestJsonValue->AsObject(); const TSharedPtr<FJsonObject>& TempObject = *LuckyCaptureObject;
if (TempObject) if (TempObject.IsValid())
{ {
bIsCapture = (TempObject->GetStringField("capture") == "on"); FString CaptureString;
bIsCaptureHand = (TempObject->GetStringField("is_capture_hand") == "on"); TempObject->TryGetStringField(TEXT("capture"), CaptureString);
bIsCaptureHead = (TempObject->GetStringField("is_capture_head") == "on"); bIsCapture = (CaptureString.Equals(TEXT("on"), ESearchCase::IgnoreCase));
bScenarioCapture = (TempObject->GetStringField("scenario_capture") == "on");
FString CaptureHandString;
TempObject->TryGetStringField(TEXT("is_capture_hand"), CaptureHandString);
bIsCaptureHand = (CaptureHandString.Equals(TEXT("on"), ESearchCase::IgnoreCase));
FString CaptureHeadString;
TempObject->TryGetStringField(TEXT("is_capture_head"), CaptureHeadString);
bIsCaptureHead = (CaptureHeadString.Equals(TEXT("on"), ESearchCase::IgnoreCase));
FString ScenarioCaptureString;
TempObject->TryGetStringField(TEXT("scenario_capture"), ScenarioCaptureString);
bScenarioCapture = (ScenarioCaptureString.Equals(TEXT("on"), ESearchCase::IgnoreCase));
TargetPosition = FTransform(); TargetPosition = FTransform();
SetCurrentFileName(TempObject->GetStringField("file_name"));
SetCurrentFolderName(TempObject->GetStringField("folder_name")); FString FileNameString;
SetCurrentCaptureNumber(FCString::Atoi(*TempObject->GetStringField("capture_name"))); TempObject->TryGetStringField(TEXT("file_name"), FileNameString);
SetCurrentIsInfiniteCapture(TempObject->GetStringField("infinite_capture") == "on"); SetCurrentFileName(FileNameString);
SetCurrentWritesPerSec(FCString::Atoi(*TempObject->GetStringField("per_second")));
SetCurrentIsRandomPeople(TempObject->GetStringField("random_people") == "on"); FString FolderNameString;
} TempObject->TryGetStringField(TEXT("folder_name"), FolderNameString);
SetCurrentFolderName(FolderNameString);
int32 CaptureNumberInt = 0;
FString CaptureNumberString;
if(TempObject->TryGetStringField(TEXT("capture_name"), CaptureNumberString))
{
CaptureNumberInt = FCString::Atoi(*CaptureNumberString);
}
SetCurrentCaptureNumber(CaptureNumberInt);
FString InfiniteCaptureString;
TempObject->TryGetStringField(TEXT("infinite_capture"), InfiniteCaptureString);
SetCurrentIsInfiniteCapture(InfiniteCaptureString.Equals(TEXT("on"), ESearchCase::IgnoreCase));
int32 WritesPerSecInt = 0;
FString WritesPerSecString;
if(TempObject->TryGetStringField(TEXT("per_second"), WritesPerSecString))
{
WritesPerSecInt = FCString::Atoi(*WritesPerSecString);
}
SetCurrentWritesPerSec(WritesPerSecInt);
FString RandomPeopleString;
TempObject->TryGetStringField(TEXT("random_people"), RandomPeopleString);
SetCurrentIsRandomPeople(RandomPeopleString.Equals(TEXT("on"), ESearchCase::IgnoreCase));
} }
} }
} }
} }
else
{
UE_LOG(LogTemp, Error, TEXT("Failed to deserialize JSON in GetMessageParse: %s"), *Json);
} }
} }
FParsedData ULuckyRobotsGameInstance::DoJsonParse(const FString& JsonString) FParsedData ULuckyRobotsGameInstance::DoJsonParse(const FString& JsonString)
{ {
FParsedData ParsedData; FParsedData ParsedData;
TSharedPtr<FJsonObject> JsonObject;
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(JsonString);
auto VaRestSubsystem = CastChecked<UVaRestSubsystem>(USubsystemBlueprintLibrary::GetEngineSubsystem(UVaRestSubsystem::StaticClass()), ECastCheckedType::NullChecked); if (FJsonSerializer::Deserialize(Reader, JsonObject) && JsonObject.IsValid())
if (!VaRestSubsystem)
{ {
return ParsedData; const TSharedPtr<FJsonObject>* StartupInstructionsObject;
if (JsonObject->TryGetObjectField(TEXT("startup_instructions"), StartupInstructionsObject))
{
const TSharedPtr<FJsonObject>& TempObject = *StartupInstructionsObject;
if (TempObject.IsValid())
{
TempObject->TryGetStringField(TEXT("level"), ParsedData.LevelName);
TempObject->TryGetStringField(TEXT("character"), ParsedData.CharacterName);
TempObject->TryGetStringField(TEXT("quality"), ParsedData.Quality);
} }
UVaRestJsonObject* VaRestJsonObject = VaRestSubsystem->ConstructVaRestJsonObject();
if (!VaRestJsonObject)
{
return ParsedData;
}
if (VaRestJsonObject->DecodeJson(JsonString, true))
{
UVaRestJsonObject* TempJsonObject = VaRestJsonObject->GetObjectField("startup_instructions");
if (TempJsonObject)
{
ParsedData.LevelName = TempJsonObject->GetStringField("level");
ParsedData.CharacterName = TempJsonObject->GetStringField("character");
ParsedData.Quality = TempJsonObject->GetStringField("quality");
} }
} }
else else
{ {
UE_LOG(LogTemp, Error, TEXT("Parse Problem")); UE_LOG(LogTemp, Error, TEXT("Failed to deserialize JSON in DoJsonParse: %s"), *JsonString);
} }
return ParsedData; return ParsedData;

View File

@ -6,8 +6,9 @@
#include "Core/LuckyRobotsGameInstance.h" #include "Core/LuckyRobotsGameInstance.h"
#include "FunctionLibraries/LuckyRobotsFunctionLibrary.h" #include "FunctionLibraries/LuckyRobotsFunctionLibrary.h"
#include "Subsystems/SubsystemBlueprintLibrary.h" #include "Subsystems/SubsystemBlueprintLibrary.h"
#include "VaRestSubsystem.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "Dom/JsonObject.h"
#include "Serialization/JsonSerializer.h"
void UMainScreenUserWidget::NativeConstruct() void UMainScreenUserWidget::NativeConstruct()
{ {
@ -219,25 +220,22 @@ void UMainScreenUserWidget::OnMessageDispatchedHandler(const FString& Message)
void UMainScreenUserWidget::DoSendReadyJson() void UMainScreenUserWidget::DoSendReadyJson()
{ {
auto VaRestSubsystem = CastChecked<UVaRestSubsystem>(USubsystemBlueprintLibrary::GetEngineSubsystem(UVaRestSubsystem::StaticClass()), ECastCheckedType::NullChecked); TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject());
JsonObject->SetStringField(TEXT("name"), TEXT("game_is_loaded"));
if (!VaRestSubsystem) FString SendedString;
TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&SendedString);
if (FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer))
{ {
return;
}
UVaRestJsonObject* VaRestJsonObject = VaRestSubsystem->ConstructVaRestJsonObject();
if (!VaRestJsonObject)
{
return;
}
VaRestJsonObject->SetStringField("name", "game_is_loaded");
ULuckyRobotsGameInstance* GameInstance = Cast<ULuckyRobotsGameInstance>(GetGameInstance()); ULuckyRobotsGameInstance* GameInstance = Cast<ULuckyRobotsGameInstance>(GetGameInstance());
if (GameInstance) if (GameInstance)
{ {
FString SendedString = VaRestJsonObject->EncodeJsonToSingleString();
GameInstance->DoSendMessage(SendedString); GameInstance->DoSendMessage(SendedString);
UE_LOG(LogTemp, Log, TEXT("Sended: %s"), *SendedString); UE_LOG(LogTemp, Log, TEXT("Sended: %s"), *SendedString);
} }
}
else
{
UE_LOG(LogTemp, Error, TEXT("Failed to serialize JSON in DoSendReadyJson"));
}
} }