!I 1937152 from //dev_game_hunt/consoles_candidate: !B Remove allocations of unnecess...
[CRYENGINE.git] / Code / CryPlugins / CryLobby / Module / PSNOrbis / CryPSN2WebApi.h
blob1755481b2a43d738943fbd2c47c1f8ace3699559
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 /*
4 Handles Orbis Web API. Creates a worker thread to process blocking GET requests, also registers PushEvent listener.
5 All responses get pushed onto the m_lobbyThreadQueueBuilding queue to be processed on the network thread.
6 */
8 #ifndef __CRYPSN2_WEBAPI_H__
9 #define __CRYPSN2_WEBAPI_H__
10 #pragma once
12 #if CRY_PLATFORM_ORBIS
13 #if USE_PSN
15 #include <json2.h>
17 class CCryPSNSupport;
18 class CCryPSNOrbisWebApiThread;
19 class CCryPSNWebApiUtility;
20 class CCryPSNWebApiJobController;
22 #define INVALID_PSN_WEBAPI_PUSHEVENT_ID (-1)
23 #define INVALID_PSN_WEBAPI_SENDREQUEST_ID (-1)
24 #define INVALID_WEBAPI_JOB_ID (-1)
26 #define CRY_WEBAPI_ERROR_FAIL (-1)
27 #define CRY_WEBAPI_ERROR_END_OF_BODY (-2)
28 #define CRY_WEBAPI_ERROR_SEND_ALREADY_IN_PROGRESS (-3)
29 #define CRY_WEBAPI_ERROR_NO_SEND_IN_PROGRESS (-4)
30 #define CRY_WEBAPI_ERROR_BAD_CONTENTLENGTH (-5)
32 #define CRY_WEBAPI_HEADER_CONTENT_TYPE "Content-Type"
33 #define CRY_WEBAPI_HEADER_CONTENT_LENGTH "Content-Length"
34 #define CRY_WEBAPI_CONTENT_TYPE_JSON "application/json"
36 #define CRY_WEBAPI_HEADER_VALUE_SIZE (64)
37 #define CRY_WEBAPI_TEMP_PATH_SIZE (256)
38 #define CRY_WEBAPI_TEMP_BUFFER_SIZE (256)
40 #if !defined(_RELEASE)
41 #define CRY_WEBAPI_RESPONSE_DEBUG_STR_LEN (64)
42 #endif
44 struct SCryPSNWebApiResponseBody
46 enum EResponseBodyType
48 E_UNKNOWN = 0,
49 E_JSON,
50 E_RAW,
53 sce::Json::Value jsonTreeRoot;
54 TMemHdl rawResponseBodyHdl;
55 size_t rawResponseBodySize;
56 EResponseBodyType eType;
58 #if !defined(_RELEASE)
59 char debugStr[CRY_WEBAPI_RESPONSE_DEBUG_STR_LEN];
60 #endif
63 // WebAPI has its own threads, with queues, because all calls are blocking.
64 typedef int32 CryWebApiJobId;
65 typedef void (* TCryPSNWebApiThreadJobFunc)(CryWebApiJobId id, TMemHdl paramsHdl, CCryPSNWebApiJobController* pController, CCryPSNOrbisWebApiThread* _this);
67 struct SCryPSNWebApiThreadJobInfo
69 TCryPSNWebApiThreadJobFunc m_pJobFunc;
70 TMemHdl m_paramsHdl;
71 CryWebApiJobId m_id;
73 SCryPSNWebApiThreadJobInfo(CryWebApiJobId id, TCryPSNWebApiThreadJobFunc pFunc, TMemHdl paramsHdl)
75 m_id = id;
76 m_pJobFunc = pFunc;
77 m_paramsHdl = paramsHdl;
81 //////////////////////////////////////////////////////////////////////////////////////////////
83 #define WEBAPI_WORKBUFFER_MAX_SIZE (4 * 1024)
85 class CCryPSNOrbisWebApiThread
86 : public IThread
88 public:
89 CCryPSNOrbisWebApiThread(CCryPSNWebApiJobController* pController)
90 : m_pController(pController)
91 , m_bAlive(true)
93 memset(&m_request, 0, sizeof(m_request));
94 m_request.requestId = INVALID_PSN_WEBAPI_SENDREQUEST_ID;
95 m_serverError.Reset();
98 // Start accepting work on thread
99 virtual void ThreadEntry(); // IThread
100 void SignalStopWork();
102 CryWebApiJobId Push(TCryPSNWebApiThreadJobFunc pFunc, TMemHdl paramsHdl);
103 void Flush();
105 // Add new WebApi request jobs below here
106 // FriendsList
107 static void GetFriendsList(CryWebApiJobId id, TMemHdl paramsHdl, CCryPSNWebApiJobController* pController, CCryPSNOrbisWebApiThread* _this);
108 // Presence
109 static void SetPresence(CryWebApiJobId id, TMemHdl paramsHdl, CCryPSNWebApiJobController* pController, CCryPSNOrbisWebApiThread* _this);
110 // RecentPlayers
111 static void AddRecentPlayers(CryWebApiJobId id, TMemHdl paramsHdl, CCryPSNWebApiJobController* pController, CCryPSNOrbisWebApiThread* _this);
112 // ActivityFeed
113 static void PostActivity(CryWebApiJobId id, TMemHdl paramsHdl, CCryPSNWebApiJobController* pController, CCryPSNOrbisWebApiThread* _this);
114 // Session advertising
115 static void CreateSession(CryWebApiJobId id, TMemHdl paramsHdl, CCryPSNWebApiJobController* pController, CCryPSNOrbisWebApiThread* _this);
116 static void DeleteSession(CryWebApiJobId id, TMemHdl paramsHdl, CCryPSNWebApiJobController* pController, CCryPSNOrbisWebApiThread* _this);
117 static void UpdateSession(CryWebApiJobId id, TMemHdl paramsHdl, CCryPSNWebApiJobController* pController, CCryPSNOrbisWebApiThread* _this);
118 static void JoinSession(CryWebApiJobId id, TMemHdl paramsHdl, CCryPSNWebApiJobController* pController, CCryPSNOrbisWebApiThread* _this);
119 static void LeaveSession(CryWebApiJobId id, TMemHdl paramsHdl, CCryPSNWebApiJobController* pController, CCryPSNOrbisWebApiThread* _this);
120 static void GetSessionLinkData(CryWebApiJobId id, TMemHdl paramsHdl, CCryPSNWebApiJobController* pController, CCryPSNOrbisWebApiThread* _this);
121 // PSN Store
122 static void GetCommerceList(CryWebApiJobId id, TMemHdl paramsHdl, CCryPSNWebApiJobController* pController, CCryPSNOrbisWebApiThread* _this);
123 static void GetEntitlementList(CryWebApiJobId id, TMemHdl paramsHdl, CCryPSNWebApiJobController* pController, CCryPSNOrbisWebApiThread* _this);
124 static void ConsumeEntitlement(CryWebApiJobId id, TMemHdl paramsHdl, CCryPSNWebApiJobController* pController, CCryPSNOrbisWebApiThread* _this);
126 private:
128 struct SRequestAndResponse
130 int64 requestId;
131 char workBuffer[WEBAPI_WORKBUFFER_MAX_SIZE];
132 uint32 nRecvBufferUsed;
133 uint32 nRecvBufferParsed;
136 struct SServerError
138 SceNpWebApiResponseInformationOption serverError;
139 #ifdef _DEBUG
140 static const int kErrorBufSize = 256;
141 char serverErrorBuffer[kErrorBufSize]; // This buffer can be inspected in the debugger, it will contain JSON error data
142 #endif
144 void Reset()
146 memset(this, 0, sizeof(SServerError));
147 #ifdef _DEBUG
148 serverError.pErrorObject = serverErrorBuffer;
149 serverError.errorObjectSize = sizeof(serverErrorBuffer);
150 #endif
154 static CryWebApiJobId sm_nextFreeJobId;
156 sce::Json::Parser Parser;
157 SRequestAndResponse m_request;
158 SServerError m_serverError;
159 CCryPSNWebApiJobController* m_pController;
160 CryMutex m_mtx;
161 CryConditionVariable m_cond;
162 std::deque<SCryPSNWebApiThreadJobInfo> m_jobQueue;
163 bool m_bAlive;
165 int SendRequest(SceNpWebApiHttpMethod httpMethod, const char* pContentType, const char* pAPIGroup, const char* pPath);
166 int SendRequestText(SceNpWebApiHttpMethod httpMethod, const char* pContentType, const char* pAPIGroup, const char* pPath, const char* pBody);
167 int SendRequestData(SceNpWebApiHttpMethod httpMethod, const char* pContentType, const char* pAPIGroup, const char* pPath, const void* pData, size_t sizeofData);
168 int StoreRawResponseBody(SCryPSNWebApiResponseBody* pResponseBody);
169 int ReadResponse(SCryPSNWebApiResponseBody* pResponseBody);
171 static int DataProvideCallback(char& data, void* pWebAPIJobThread);
173 CryWebApiJobId GetUniqueJobId();
176 //////////////////////////////////////////////////////////////////////////////////////////////
178 #define WEBAPI_JSON_DEBUG_INDENTS (64)
180 class CCryPSNWebApiUtility : public sce::Json::MemAllocator
182 protected:
184 struct SPrintJSONIndent
186 uint32 m_debugIndent;
187 char m_debugIndentString[WEBAPI_JSON_DEBUG_INDENTS + 1];
189 SPrintJSONIndent()
190 : m_debugIndent(0)
192 memset(m_debugIndentString, ' ', WEBAPI_JSON_DEBUG_INDENTS);
193 m_debugIndentString[m_debugIndent] = '\0';
194 m_debugIndentString[WEBAPI_JSON_DEBUG_INDENTS] = '\0';
196 void operator++(void)
198 if (m_debugIndent <= WEBAPI_JSON_DEBUG_INDENTS - 2)
200 m_debugIndentString[m_debugIndent] = ' ';
201 m_debugIndent += 2;
202 m_debugIndentString[m_debugIndent] = '\0';
205 void operator--(void)
207 if (m_debugIndent >= 2)
209 m_debugIndentString[m_debugIndent] = ' ';
210 m_debugIndent -= 2;
211 m_debugIndentString[m_debugIndent] = '\0';
214 const char* c_str() const
216 return m_debugIndentString;
220 sce::Json::Initializer Initializer;
221 CCryPSNSupport* m_pSupport;
222 CCryLobby* m_pLobby;
224 int m_webApiCtxId;
225 int m_pushEventFilterId;
226 int m_servicePushEventFilterId;
228 bool m_bIsInitialised;
230 int m_debugJsonAllocs;
232 // utility for printing a json tree
233 void DebugPrintJSONObject(const sce::Json::Object& obj, SPrintJSONIndent& indent);
234 void DebugPrintJSONArray(const sce::Json::Array& ary, SPrintJSONIndent& indent);
235 void DebugPrintJSONValue(const sce::Json::Value& val, SPrintJSONIndent& indent);
237 public:
239 CCryPSNWebApiUtility()
240 : m_pSupport(nullptr)
241 , m_pLobby(nullptr)
242 , m_webApiCtxId(0)
243 , m_pushEventFilterId(0)
244 , m_servicePushEventFilterId(0)
245 , m_bIsInitialised(false)
246 , m_debugJsonAllocs(0)
249 ~CCryPSNWebApiUtility() { Terminate(); }
251 int Initialise(int webApiCtxId, CCryPSNSupport* pSupport);
252 void Terminate();
253 bool IsInitialised() { return m_bIsInitialised; }
255 int GetWebApiContextId() const { return m_webApiCtxId; }
256 int GetWebApiPushEventFilterId() const { return m_pushEventFilterId; }
257 int GetWebApiServicePushEventFilterId() const { return m_servicePushEventFilterId; }
259 CCryPSNSupport* GetPSNSupport() const { return m_pSupport; }
260 CCryLobby* GetLobby() const { return m_pLobby; }
262 // utility for printing a json tree
263 int PrintResponseJSONTree(const SCryPSNWebApiResponseBody* pResponseBody);
265 TMemHdl NewResponseBody(char* debugString);
266 int FreeResponseBody(TMemHdl responseBodyHdl);
268 TMemHdl AllocMem(size_t numBytes);
269 void FreeMem(TMemHdl hdl);
271 // From sce::Json::MemAllocator - Only used by Json library
272 virtual void* allocate(size_t numBytes, void* pUserData);
273 virtual void deallocate(void* ptr, void* pUserData);
275 // utility for encoding and decoding base64
276 char* Base64Encode(const uint8* buffer, int len, TMemHdl& hdl);
277 uint8* Base64Decode(const char* buffer, int len, TMemHdl& hdl);
280 //////////////////////////////////////////////////////////////////////////////////////////////
282 class CCryPSNWebApiJobController
284 protected:
286 CCryPSNWebApiUtility* m_pWebApiUtility;
287 CCryPSNOrbisWebApiThread* m_pWebApiThread; // 1 for now
289 int m_webApiUserCtxId;
290 int m_pushEventCallbackId;
291 int m_servicePushEventCallbackId;
293 bool m_bIsInitialised;
295 static void PushEventCallback(int, int, const SceNpPeerAddressA*, const SceNpPeerAddressA*, const SceNpWebApiPushEventDataType*, const char*, size_t, void*);
296 static void ServicePushEventCallback(int, int, const char*, SceNpServiceLabel, const SceNpPeerAddressA*, const SceNpPeerAddressA*, const SceNpWebApiPushEventDataType*, const char*, size_t, void*);
298 public:
300 CCryPSNWebApiJobController()
301 : m_pWebApiUtility(nullptr)
302 , m_pWebApiThread(nullptr)
303 , m_webApiUserCtxId(0)
304 , m_pushEventCallbackId(0)
305 , m_servicePushEventCallbackId(0)
306 , m_bIsInitialised(false)
309 ~CCryPSNWebApiJobController() { Terminate(); }
311 int Initialise(CCryPSNWebApiUtility* pUtility, SceNpId npId);
312 int Terminate();
313 bool IsInitialised() { return m_bIsInitialised; }
315 int GetContextId() const { return m_webApiUserCtxId; }
316 CCryPSNWebApiUtility* GetUtility() const { return m_pWebApiUtility; }
318 CryWebApiJobId AddJob(TCryPSNWebApiThreadJobFunc job, TMemHdl paramsHdl);
321 //////////////////////////////////////////////////////////////////////////////////////////////
323 #endif // USE_PSN
324 #endif // CRY_PLATFORM_ORBIS
326 #endif // __CRYPSN2_WEBAPI_H__