SIOJLibrary.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. // Modifications Copyright 2018-current Getnamo. All Rights Reserved
  2. // Copyright 2016 Vladimir Alyamkin. All Rights Reserved.
  3. #include "SIOJLibrary.h"
  4. #include "ISIOJson.h"
  5. #include "Json/Public/Dom/JsonObject.h"
  6. #include "Json/Public/Dom/JsonValue.h"
  7. #include "SIOJsonValue.h"
  8. #include "SIOJsonObject.h"
  9. #include "Misc/Base64.h"
  10. #include "Engine/Engine.h"
  11. //////////////////////////////////////////////////////////////////////////
  12. // Helpers
  13. FString USIOJLibrary::PercentEncode(const FString& Source)
  14. {
  15. FString OutText = Source;
  16. OutText = OutText.Replace(TEXT(" "), TEXT("%20"));
  17. OutText = OutText.Replace(TEXT("!"), TEXT("%21"));
  18. OutText = OutText.Replace(TEXT("\""), TEXT("%22"));
  19. OutText = OutText.Replace(TEXT("#"), TEXT("%23"));
  20. OutText = OutText.Replace(TEXT("$"), TEXT("%24"));
  21. OutText = OutText.Replace(TEXT("&"), TEXT("%26"));
  22. OutText = OutText.Replace(TEXT("'"), TEXT("%27"));
  23. OutText = OutText.Replace(TEXT("("), TEXT("%28"));
  24. OutText = OutText.Replace(TEXT(")"), TEXT("%29"));
  25. OutText = OutText.Replace(TEXT("*"), TEXT("%2A"));
  26. OutText = OutText.Replace(TEXT("+"), TEXT("%2B"));
  27. OutText = OutText.Replace(TEXT(","), TEXT("%2C"));
  28. OutText = OutText.Replace(TEXT("/"), TEXT("%2F"));
  29. OutText = OutText.Replace(TEXT(":"), TEXT("%3A"));
  30. OutText = OutText.Replace(TEXT(";"), TEXT("%3B"));
  31. OutText = OutText.Replace(TEXT("="), TEXT("%3D"));
  32. OutText = OutText.Replace(TEXT("?"), TEXT("%3F"));
  33. OutText = OutText.Replace(TEXT("@"), TEXT("%40"));
  34. OutText = OutText.Replace(TEXT("["), TEXT("%5B"));
  35. OutText = OutText.Replace(TEXT("]"), TEXT("%5D"));
  36. OutText = OutText.Replace(TEXT("{"), TEXT("%7B"));
  37. OutText = OutText.Replace(TEXT("}"), TEXT("%7D"));
  38. return OutText;
  39. }
  40. FString USIOJLibrary::Base64Encode(const FString& Source)
  41. {
  42. return FBase64::Encode(Source);
  43. }
  44. FString USIOJLibrary::Base64EncodeBytes(const TArray<uint8>& Source)
  45. {
  46. return FBase64::Encode(Source);
  47. }
  48. bool USIOJLibrary::Base64Decode(const FString& Source, FString& Dest)
  49. {
  50. return FBase64::Decode(Source, Dest);
  51. }
  52. bool USIOJLibrary::Base64DecodeBytes(const FString& Source, TArray<uint8>& Dest)
  53. {
  54. return FBase64::Decode(Source, Dest);
  55. }
  56. bool USIOJLibrary::StringToJsonValueArray(const FString& JsonString, TArray<USIOJsonValue*>& OutJsonValueArray)
  57. {
  58. TArray < TSharedPtr<FJsonValue>> RawJsonValueArray;
  59. TSharedRef< TJsonReader<> > Reader = TJsonReaderFactory<>::Create(*JsonString);
  60. FJsonSerializer::Deserialize(Reader, RawJsonValueArray);
  61. for (auto Value : RawJsonValueArray)
  62. {
  63. auto SJsonValue = NewObject<USIOJsonValue>();
  64. SJsonValue->SetRootValue(Value);
  65. OutJsonValueArray.Add(SJsonValue);
  66. }
  67. return OutJsonValueArray.Num() > 0;
  68. }
  69. //////////////////////////////////////////////////////////////////////////
  70. // Easy URL processing
  71. TMap<USIOJRequestJSON*, FSIOJCallResponse> USIOJLibrary::RequestMap;
  72. FString USIOJLibrary::Conv_SIOJsonObjectToString(USIOJsonObject* InObject)
  73. {
  74. if(InObject)
  75. {
  76. return InObject->EncodeJson();
  77. }
  78. return "";
  79. }
  80. USIOJsonObject* USIOJLibrary::Conv_JsonValueToJsonObject(class USIOJsonValue* InValue)
  81. {
  82. if(InValue)
  83. {
  84. return InValue->AsObject();
  85. }
  86. return nullptr;
  87. }
  88. USIOJsonValue* USIOJLibrary::Conv_ArrayToJsonValue(const TArray<USIOJsonValue*>& InArray)
  89. {
  90. return USIOJsonValue::ConstructJsonValueArray(nullptr, InArray);
  91. }
  92. USIOJsonValue* USIOJLibrary::Conv_JsonObjectToJsonValue(USIOJsonObject* InObject)
  93. {
  94. return USIOJsonValue::ConstructJsonValueObject(InObject, nullptr);
  95. }
  96. USIOJsonValue* USIOJLibrary::Conv_BytesToJsonValue(const TArray<uint8>& InBytes)
  97. {
  98. return USIOJsonValue::ConstructJsonValueBinary(nullptr, InBytes);
  99. }
  100. USIOJsonValue* USIOJLibrary::Conv_StringToJsonValue(const FString& InString)
  101. {
  102. return USIOJsonValue::ConstructJsonValueString(nullptr, InString);
  103. }
  104. USIOJsonValue* USIOJLibrary::Conv_IntToJsonValue(int32 InInt)
  105. {
  106. TSharedPtr<FJsonValue> NewVal = MakeShareable(new FJsonValueNumber(InInt));
  107. USIOJsonValue* NewValue = NewObject<USIOJsonValue>();
  108. NewValue->SetRootValue(NewVal);
  109. return NewValue;
  110. }
  111. USIOJsonValue* USIOJLibrary::Conv_FloatToJsonValue(float InFloat)
  112. {
  113. return USIOJsonValue::ConstructJsonValueNumber(nullptr, InFloat);
  114. }
  115. USIOJsonValue* USIOJLibrary::Conv_BoolToJsonValue(bool InBool)
  116. {
  117. return USIOJsonValue::ConstructJsonValueBool(nullptr, InBool);
  118. }
  119. FString USIOJLibrary::Conv_SIOJsonValueToString(class USIOJsonValue* InValue)
  120. {
  121. if (InValue)
  122. {
  123. return InValue->AsString();
  124. }
  125. return TEXT("");
  126. }
  127. int32 USIOJLibrary::Conv_JsonValueToInt(USIOJsonValue* InValue)
  128. {
  129. if(InValue)
  130. {
  131. return (int32)InValue->AsNumber();
  132. }
  133. return 0;
  134. }
  135. float USIOJLibrary::Conv_JsonValueToFloat(USIOJsonValue* InValue)
  136. {
  137. if (InValue)
  138. {
  139. return InValue->AsNumber();
  140. }
  141. return 0.f;
  142. }
  143. bool USIOJLibrary::Conv_JsonValueToBool(USIOJsonValue* InValue)
  144. {
  145. if (InValue)
  146. {
  147. return InValue->AsBool();
  148. }
  149. return false;
  150. }
  151. TArray<uint8> USIOJLibrary::Conv_JsonValueToBytes(USIOJsonValue* InValue)
  152. {
  153. if (InValue)
  154. {
  155. return InValue->AsBinary();
  156. }
  157. return TArray<uint8>();
  158. }
  159. void USIOJLibrary::CallURL(UObject* WorldContextObject, const FString& URL, ESIORequestVerb Verb, ESIORequestContentType ContentType, USIOJsonObject* SIOJJson, const FSIOJCallDelegate& Callback)
  160. {
  161. UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
  162. if (World == nullptr)
  163. {
  164. UE_LOG(LogSIOJ, Error, TEXT("USIOJLibrary: Wrong world context"))
  165. return;
  166. }
  167. // Check we have valid data json
  168. if (SIOJJson == nullptr)
  169. {
  170. SIOJJson = USIOJsonObject::ConstructJsonObject(WorldContextObject);
  171. }
  172. USIOJRequestJSON* Request = NewObject<USIOJRequestJSON>();
  173. Request->SetVerb(Verb);
  174. Request->SetContentType(ContentType);
  175. Request->SetRequestObject(SIOJJson);
  176. FSIOJCallResponse Response;
  177. Response.Request = Request;
  178. Response.WorldContextObject = WorldContextObject;
  179. Response.Callback = Callback;
  180. Response.CompleteDelegateHandle = Request->OnStaticRequestComplete.AddStatic(&USIOJLibrary::OnCallComplete);
  181. Response.FailDelegateHandle = Request->OnStaticRequestFail.AddStatic(&USIOJLibrary::OnCallComplete);
  182. RequestMap.Add(Request, Response);
  183. Request->ResetResponseData();
  184. Request->ProcessURL(URL);
  185. }
  186. void USIOJLibrary::GetURLBinary(UObject* WorldContextObject, const FString& URL, ESIORequestVerb Verb, ESIORequestContentType ContentType, TArray<uint8>& OutResultData, struct FLatentActionInfo LatentInfo)
  187. {
  188. UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
  189. if (World == nullptr)
  190. {
  191. UE_LOG(LogSIOJ, Error, TEXT("USIOJLibrary: Wrong world context"))
  192. return;
  193. }
  194. USIOJRequestJSON* Request = NewObject<USIOJRequestJSON>();
  195. FCULatentAction *LatentAction = FCULatentAction::CreateLatentAction(LatentInfo, WorldContextObject);
  196. Request->SetVerb(Verb);
  197. Request->SetContentType(ContentType);
  198. Request->bShouldHaveBinaryResponse = true;
  199. Request->OnProcessURLCompleteCallback = [LatentAction, &OutResultData](TArray<uint8>& ResultData)
  200. {
  201. if (LatentAction)
  202. {
  203. OutResultData = ResultData;
  204. LatentAction->Call(); //resume the latent action
  205. }
  206. };
  207. Request->ResetResponseData();
  208. Request->ProcessURL(URL);
  209. }
  210. void USIOJLibrary::OnCallComplete(USIOJRequestJSON* Request)
  211. {
  212. if (!RequestMap.Contains(Request))
  213. {
  214. return;
  215. }
  216. FSIOJCallResponse* Response = RequestMap.Find(Request);
  217. Request->OnStaticRequestComplete.Remove(Response->CompleteDelegateHandle);
  218. Request->OnStaticRequestFail.Remove(Response->FailDelegateHandle);
  219. Response->Callback.ExecuteIfBound(Request);
  220. Response->WorldContextObject = nullptr;
  221. Response->Request = nullptr;
  222. RequestMap.Remove(Request);
  223. }