SIOJLibrary.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. // Modifications Copyright 2018-current Getnamo. All Rights Reserved
  2. // Copyright 2016 Vladimir Alyamkin. All Rights Reserved.
  3. #pragma once
  4. #include "Kismet/BlueprintFunctionLibrary.h"
  5. #include "SIOJTypes.h"
  6. #include "SIOJConvert.h"
  7. #include "SIOJsonObject.h"
  8. #include "SIOJRequestJSON.h"
  9. #include "SIOJsonValue.h"
  10. #include "SIOJLibrary.generated.h"
  11. DECLARE_DYNAMIC_DELEGATE_OneParam(FSIOJCallDelegate, USIOJRequestJSON*, Request);
  12. USTRUCT()
  13. struct FSIOJCallResponse
  14. {
  15. GENERATED_USTRUCT_BODY()
  16. UPROPERTY()
  17. USIOJRequestJSON* Request;
  18. UPROPERTY()
  19. UObject* WorldContextObject;
  20. UPROPERTY()
  21. FSIOJCallDelegate Callback;
  22. FDelegateHandle CompleteDelegateHandle;
  23. FDelegateHandle FailDelegateHandle;
  24. FSIOJCallResponse()
  25. : Request(nullptr)
  26. , WorldContextObject(nullptr)
  27. {
  28. }
  29. };
  30. /**
  31. * Usefull tools for REST communications
  32. */
  33. UCLASS()
  34. class SIOJSON_API USIOJLibrary : public UBlueprintFunctionLibrary
  35. {
  36. GENERATED_BODY()
  37. //////////////////////////////////////////////////////////////////////////
  38. // Helpers
  39. public:
  40. /** Applies percent-encoding to text */
  41. UFUNCTION(BlueprintCallable, Category = "SIOJ|Utility")
  42. static FString PercentEncode(const FString& Source);
  43. /**
  44. * Encodes a FString into a Base64 string
  45. *
  46. * @param Source The string data to convert
  47. * @return A string that encodes the binary data in a way that can be safely transmitted via various Internet protocols
  48. */
  49. UFUNCTION(BlueprintPure, Category = "SIOJ|Utility", meta = (DisplayName = "Base64 Encode (String)"))
  50. static FString Base64Encode(const FString& Source);
  51. /**
  52. * Encodes a Byte array into a Base64 string
  53. *
  54. * @param Source The string data to convert
  55. * @return A string that encodes the binary data in a way that can be safely transmitted via various Internet protocols
  56. */
  57. UFUNCTION(BlueprintPure, Category = "SIOJ|Utility", meta = (DisplayName = "Base64 Encode (Bytes)"))
  58. static FString Base64EncodeBytes(const TArray<uint8>& Source);
  59. /**
  60. * Decodes a Base64 string into a FString
  61. *
  62. * @param Source The stringified data to convert
  63. * @param Dest The out buffer that will be filled with the decoded data
  64. * @return True if the buffer was decoded, false if it failed to decode
  65. */
  66. UFUNCTION(BlueprintPure, Category = "SIOJ|Utility", meta = (DisplayName = "Base64 Decode (To String)"))
  67. static bool Base64Decode(const FString& Source, FString& Dest);
  68. /**
  69. * Decodes a Base64 string into a Byte array
  70. *
  71. * @param Source The stringified data to convert
  72. * @param Dest The out buffer that will be filled with the decoded data
  73. * @return True if the buffer was decoded, false if it failed to decode
  74. */
  75. UFUNCTION(BlueprintPure, Category = "SIOJ|Utility", meta = (DisplayName = "Base64 Decode (To Bytes)"))
  76. static bool Base64DecodeBytes(const FString& Source, TArray<uint8>& Dest);
  77. //////////////////////////////////////////////////////////////////////////
  78. // Easy URL processing
  79. /**
  80. * Decodes a json string into an array of stringified json Values
  81. *
  82. * @param JsonString Input stringified json
  83. * @param OutJsonValueArray The decoded Array of JsonValue
  84. */
  85. UFUNCTION(BlueprintPure, Category = "SIOJ|Utility")
  86. static bool StringToJsonValueArray(const FString& JsonString, TArray<USIOJsonValue*>& OutJsonValueArray);
  87. /**
  88. * Uses the reflection system to convert an unreal struct into a JsonObject
  89. *
  90. * @param AnyStruct The struct you wish to convert
  91. * @return Converted Json Object
  92. */
  93. UFUNCTION(BlueprintPure, Category = "SocketIOFunctions", CustomThunk, meta = (CustomStructureParam = "AnyStruct"))
  94. static USIOJsonObject* StructToJsonObject(TFieldPath<FProperty> AnyStruct);
  95. //Convert property into c++ accessible form
  96. DECLARE_FUNCTION(execStructToJsonObject)
  97. {
  98. //Get properties and pointers from stack
  99. Stack.Step(Stack.Object, NULL);
  100. FStructProperty* StructProperty = CastField<FStructProperty>(Stack.MostRecentProperty);
  101. void* StructPtr = Stack.MostRecentPropertyAddress;
  102. // We need this to wrap up the stack
  103. P_FINISH;
  104. auto BPJsonObject = NewObject<USIOJsonObject>();
  105. auto JsonObject = USIOJConvert::ToJsonObject(StructProperty->Struct, StructPtr, true);
  106. BPJsonObject->SetRootObject(JsonObject);
  107. *(USIOJsonObject**)RESULT_PARAM = BPJsonObject;
  108. }
  109. UFUNCTION(BlueprintPure, CustomThunk, meta = (DisplayName = "To JsonValue (Struct)", BlueprintAutocast, CustomStructureParam = "AnyStruct"), Category = "Utilities|SocketIO")
  110. static USIOJsonValue* StructToJsonValue(TFieldPath<FProperty> AnyStruct);
  111. DECLARE_FUNCTION(execStructToJsonValue)
  112. {
  113. //Get properties and pointers from stack
  114. Stack.Step(Stack.Object, NULL);
  115. FStructProperty* StructProperty = CastField<FStructProperty>(Stack.MostRecentProperty);
  116. void* StructPtr = Stack.MostRecentPropertyAddress;
  117. // We need this to wrap up the stack
  118. P_FINISH;
  119. auto JsonObject = USIOJConvert::ToJsonObject(StructProperty->Struct, StructPtr, true);
  120. TSharedPtr<FJsonValue> JsonValue = MakeShareable(new FJsonValueObject(JsonObject));
  121. USIOJsonValue* BPJsonValue = NewObject<USIOJsonValue>();
  122. BPJsonValue->SetRootValue(JsonValue);
  123. *(USIOJsonValue**)RESULT_PARAM = BPJsonValue;
  124. }
  125. /**
  126. * Uses the reflection system to fill an unreal struct from data defined in JsonObject.
  127. *
  128. * @param JsonObject The source JsonObject for properties to fill
  129. * @param AnyStruct The struct you wish to fill
  130. * @return Whether all properties filled correctly
  131. */
  132. UFUNCTION(BlueprintCallable, Category = "SocketIOFunctions", CustomThunk, meta = (CustomStructureParam = "AnyStruct"))
  133. static bool JsonObjectToStruct(USIOJsonObject* JsonObject, TFieldPath<FProperty> AnyStruct);
  134. DECLARE_FUNCTION(execJsonObjectToStruct)
  135. {
  136. //Get properties and pointers from stack
  137. P_GET_OBJECT(USIOJsonObject, JsonObject);
  138. Stack.Step(Stack.Object, NULL);
  139. FStructProperty* StructProperty = CastField<FStructProperty>(Stack.MostRecentProperty);
  140. void* StructPtr = Stack.MostRecentPropertyAddress;
  141. P_FINISH;
  142. //Pass in the reference to the json object
  143. bool Success = USIOJConvert::JsonObjectToUStruct(JsonObject->GetRootObject(), StructProperty->Struct, StructPtr, true);
  144. *(bool*)RESULT_PARAM = Success;
  145. }
  146. //Convenience - Saving/Loading structs from files
  147. UFUNCTION(BlueprintCallable, Category = "SocketIOFunctions", CustomThunk, meta = (CustomStructureParam = "AnyStruct"))
  148. static bool SaveStructToJsonFile(TFieldPath<FProperty> AnyStruct, const FString& FilePath);
  149. UFUNCTION(BlueprintCallable, Category = "SocketIOFunctions", CustomThunk, meta = (CustomStructureParam = "AnyStruct"))
  150. static bool LoadJsonFileToStruct(const FString& FilePath, TFieldPath<FProperty> AnyStruct);
  151. //custom thunk needed to handle wildcard structs
  152. DECLARE_FUNCTION(execSaveStructToJsonFile)
  153. {
  154. Stack.StepCompiledIn<FStructProperty>(NULL);
  155. FStructProperty* StructProp = CastField<FStructProperty>(Stack.MostRecentProperty);
  156. void* StructPtr = Stack.MostRecentPropertyAddress;
  157. FString FilePath;
  158. Stack.StepCompiledIn<FStrProperty>(&FilePath);
  159. P_FINISH;
  160. P_NATIVE_BEGIN;
  161. *(bool*)RESULT_PARAM = USIOJConvert::ToJsonFile(FilePath, StructProp->Struct, StructPtr);
  162. P_NATIVE_END;
  163. }
  164. //custom thunk needed to handle wildcard structs
  165. DECLARE_FUNCTION(execLoadJsonFileToStruct)
  166. {
  167. FString FilePath;
  168. Stack.StepCompiledIn<FStrProperty>(&FilePath);
  169. Stack.StepCompiledIn<FStructProperty>(NULL);
  170. FStructProperty* StructProp = CastField<FStructProperty>(Stack.MostRecentProperty);
  171. void* StructPtr = Stack.MostRecentPropertyAddress;
  172. P_FINISH;
  173. P_NATIVE_BEGIN;
  174. *(bool*)RESULT_PARAM = USIOJConvert::JsonFileToUStruct(FilePath, StructProp->Struct, StructPtr, true);
  175. P_NATIVE_END;
  176. }
  177. //Conversion Nodes - comments added for blueprint hover with compact nodes
  178. //To JsonValue (Array)
  179. UFUNCTION(BlueprintPure, meta = (DisplayName = "To JsonValue (Array)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Utilities|SocketIO")
  180. static USIOJsonValue* Conv_ArrayToJsonValue(const TArray<USIOJsonValue*>& InArray);
  181. //To JsonValue (JsonObject)
  182. UFUNCTION(BlueprintPure, meta = (DisplayName = "To JsonValue (JsonObject)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Utilities|SocketIO")
  183. static USIOJsonValue* Conv_JsonObjectToJsonValue(USIOJsonObject* InObject);
  184. //To JsonValue (Bytes)
  185. UFUNCTION(BlueprintPure, meta = (DisplayName = "To JsonValue (Bytes)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Utilities|SocketIO")
  186. static USIOJsonValue* Conv_BytesToJsonValue(const TArray<uint8>& InBytes);
  187. //To JsonValue (String)
  188. UFUNCTION(BlueprintPure, meta = (DisplayName = "To JsonValue (String)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Utilities|SocketIO")
  189. static USIOJsonValue* Conv_StringToJsonValue(const FString& InString);
  190. //To JsonValue (Integer)
  191. UFUNCTION(BlueprintPure, meta = (DisplayName = "To JsonValue (Integer)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Utilities|SocketIO")
  192. static USIOJsonValue* Conv_IntToJsonValue(int32 InInt);
  193. //To JsonValue (Float)
  194. UFUNCTION(BlueprintPure, meta = (DisplayName = "To JsonValue (Float)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Utilities|SocketIO")
  195. static USIOJsonValue* Conv_FloatToJsonValue(float InFloat);
  196. //To JsonValue (Bool)
  197. UFUNCTION(BlueprintPure, meta = (DisplayName = "To JsonValue (Bool)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Utilities|SocketIO")
  198. static USIOJsonValue* Conv_BoolToJsonValue(bool InBool);
  199. //To String (JsonValue) - doesn't autocast due to get display name
  200. UFUNCTION(BlueprintPure, meta = (DisplayName = "To String (JsonValue)", BlueprintAutocast), Category = "Utilities|SocketIO")
  201. static FString Conv_SIOJsonValueToString(class USIOJsonValue* InValue);
  202. //To Integer (JsonValue)
  203. UFUNCTION(BlueprintPure, meta = (DisplayName = "To Integer (JsonValue)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Utilities|SocketIO")
  204. static int32 Conv_JsonValueToInt(class USIOJsonValue* InValue);
  205. //To Float (JsonValue)
  206. UFUNCTION(BlueprintPure, meta = (DisplayName = "To Float (JsonValue)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Utilities|SocketIO")
  207. static float Conv_JsonValueToFloat(class USIOJsonValue* InValue);
  208. //To Bool (JsonValue)
  209. UFUNCTION(BlueprintPure, meta = (DisplayName = "To Bool (JsonValue)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Utilities|SocketIO")
  210. static bool Conv_JsonValueToBool(class USIOJsonValue* InValue);
  211. //To Bytes (JsonValue)
  212. UFUNCTION(BlueprintPure, meta = (DisplayName = "To Bytes (JsonValue)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Utilities|SocketIO")
  213. static TArray<uint8> Conv_JsonValueToBytes(class USIOJsonValue* InValue);
  214. //To String (JsonObject) - doesn't autocast due to get display name
  215. UFUNCTION(BlueprintPure, meta = (DisplayName = "To String (JsonObject)", BlueprintAutocast), Category = "Utilities|SocketIO")
  216. static FString Conv_SIOJsonObjectToString(class USIOJsonObject* InObject);
  217. //To Object (JsonValue)
  218. UFUNCTION(BlueprintPure, meta = (DisplayName = "To Object (JsonValue)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Utilities|SocketIO")
  219. static USIOJsonObject* Conv_JsonValueToJsonObject(class USIOJsonValue* InValue);
  220. public:
  221. /** Easy way to process http requests */
  222. UFUNCTION(BlueprintCallable, Category = "SIOJ|Utility", meta = (WorldContext = "WorldContextObject"))
  223. static void CallURL(UObject* WorldContextObject, const FString& URL, ESIORequestVerb Verb, ESIORequestContentType ContentType, USIOJsonObject* SIOJJson, const FSIOJCallDelegate& Callback);
  224. /** Easy way to fetch resources using get */
  225. UFUNCTION(BlueprintCallable, Category = "SIOJ|Utility", meta = (Latent, LatentInfo = "LatentInfo", WorldContext = "WorldContextObject"))
  226. static void GetURLBinary(UObject* WorldContextObject, const FString& URL, ESIORequestVerb Verb, ESIORequestContentType ContentType, TArray<uint8>& OutResultData, struct FLatentActionInfo LatentInfo);
  227. /** Called when URL is processed (one for both success/unsuccess events)*/
  228. static void OnCallComplete(USIOJRequestJSON* Request);
  229. private:
  230. static TMap<USIOJRequestJSON*, FSIOJCallResponse> RequestMap;
  231. };