iFun Engine API  1.0.0-b2821
Great Technology for Great Games
 All Classes Files Functions Variables Typedefs Macros
deploy_api_service.h
Go to the documentation of this file.
1 // Copyright (C) 2018 iFunFactory Inc. All Rights Reserved.
2 //
3 // This work is confidential and proprietary to iFunFactory Inc. and
4 // must not be used, disclosed, copied, or distributed without the prior
5 // consent of iFunFactory Inc.
6 
9 #ifndef INCLUDE_FUNAPI_MANAGEMENT_DEPLOY_API_SERVICE_H_
10 #define INCLUDE_FUNAPI_MANAGEMENT_DEPLOY_API_SERVICE_H_
11 
12 
13 #include <boost/function.hpp>
14 #include <boost/noncopyable.hpp>
15 #include <boost/regex.hpp>
16 #include <boost/shared_ptr.hpp>
17 #include <boost/variant.hpp>
18 
20 #include <funapi/time/wall_clock.h>
21 #include <funapi/types.h>
22 
23 #include <string>
24 #include <vector>
25 
26 namespace fun {
27 
28 class Json;
29 
30 // HTTP response writers
31 struct ResponseWriter : private boost::noncopyable {
32  virtual ~ResponseWriter();
33 };
34 
35 
37  // Writes HTTP response with given status code
38  virtual void Write(const fun::http::StatusCode code) = 0;
39 };
40 
41 
42 template<typename T>
44  // Writes HTTP status code and result of type `T' to HTTP response
45  virtual void Write(const fun::http::StatusCode code, T *result) = 0;
46 };
47 
48 
53 
54 
55 class DeployApiService : public boost::noncopyable {
56  // Interface class for iFunDeploy APIs
57  // 아이펀 디플로이를 위한 인터페이스 클래스
58  // https://docs.ifun-deploy.com/
59  public:
60  struct PageInfo {
61  // NOTE: {0, 0} means that paging is disabled.
62  uint32_t page_no; // page number; starts from 1
63  uint32_t page_size; // number of entries for a single page
64 
65  PageInfo();
66  };
67 
68  struct DeployApiHandlerBase : private boost::noncopyable {
69  struct BanUserErrorInfo;
70  struct UnbanUserErrorInfo;
71 
76 
77  virtual ~DeployApiHandlerBase();
78 
79  // Should return searchable condition list for accounts
80  virtual void GetUserSearchConditions(
81  const Ptr<StringVectorResponseWriter> &writer) const;
82 
83  // Searches account for a given condition
84  virtual void SearchUsers(
85  const std::string &condition_name,
86  const std::string &condition_value,
87  const PageInfo &page_info,
88  const Ptr<JsonVectorResponseWriter> &writer) const;
89 
90  // Returns user data as JSON for user identified by "id".
91  // In case of failure, should pass appropritate HTTP status code.
92  virtual void GetUser(
93  const std::string &id,
94  const Ptr<JsonResponseWriter> &writer) const;
95 
96  // PUT /v1/cs-api/account/<id>/<field>/<value>
97  virtual void UpdateUser(
98  const std::string &id,
99  const std::string &field,
100  const std::string &value,
101  const Ptr<VoidResponseWriter> &writer) const;
102 
103  // Returns connection status for the account as string
104  virtual void IsLoggedIn(
105  const std::string &key,
106  const Ptr<BoolResponseWriter> &writer) const;
107 
108  // Forces user to be logged-out
109  virtual void ForceLogout(
110  const std::string &id,
111  const Ptr<VoidResponseWriter> &writer) const;
112 
113  // User ban
114  // {
116  std::string id;
117  std::string description;
118  };
119 
121  std::string id;
122  std::string description;
123  };
124 
125  virtual void GetUserBanned(
126  const std::string &key,
127  const Ptr<BoolResponseWriter> &writer) const;
128 
129  DEPRECATED(virtual void BanUser(
130  const std::string &key, const Ptr<VoidResponseWriter> &writer) const);
131 
132  virtual void BanUsers(
133  const std::vector<std::string> &user_ids,
134  const Ptr<BanUsersResponseWriter> &writer) const;
135 
136  DEPRECATED(virtual void UnbanUser(
137  const std::string &key, const Ptr<VoidResponseWriter> &writer) const);
138 
139  virtual void UnbanUsers(
140  const std::vector<std::string> &user_ids,
141  const Ptr<UnbanUsersResponseWriter> &writer) const;
142  // }
143 
144  // Characters API
145  // {
146  virtual void GetCharacters(
147  const std::string &user_id,
148  const Ptr<JsonVectorResponseWriter> &writer) const;
149 
150  virtual void GetCharacter(
151  const std::string &character_id,
152  const Ptr<JsonResponseWriter> &writer) const;
153 
154  virtual void UpdateCharacter(
155  const std::string &character_id,
156  const std::string &field,
157  const std::string &value,
158  const Ptr<VoidResponseWriter> &writer) const;
159 
160  // vector of (inventory type, vector of inventory id)
161  typedef std::vector<std::pair<std::string, std::vector<std::string> > >
162  InventoryInfo;
163  virtual void GetCharacterInventoryInfo(
164  const std::string &character_id,
165  const Ptr<ResponseWriterT<InventoryInfo> > &writer) const;
166 
167  // result should be JSON array, which holds item data
168  virtual void GetInventory(
169  const std::string &type,
170  const std::string &inventory_id,
171  const PageInfo &page_info,
172  const Ptr<JsonVectorResponseWriter> &writer) const;
173 
174  // iFunDeploy expects there are `expected_item_quantity` items for item_id.
175  // In this function, one should decrease the quantity of item
176  // by `quantity_to_reclaim`.
177  virtual void DeleteInventoryItem(
178  const std::string &inventory_type,
179  const std::string &inventory_id,
180  const std::string &item_id,
181  const int64_t expected_item_quantity,
182  const int64_t quantity_to_reclaim,
183  const Ptr<VoidResponseWriter> &writer) const;
184 
185  struct ReclaimInfo {
186  struct ReclaimedItem {
187  std::string item_id;
188  int64_t expected_item_quantity; // expected quantity of the item
189  int64_t quantity_to_reclaim; // # of items to be decreased
190  };
191 
192  std::string inventory_type;
193  std::string inventory_id;
194  std::vector<ReclaimedItem> reclaimed;
195  };
196 
197  virtual void DeleteMultipleInventoryItems(
198  const std::vector<ReclaimInfo> &reclaimed,
199  const Ptr<VoidResponseWriter> &writer) const;
200 
201  // send gift to specific users
202  virtual void GiveGift(
203  const std::string &target_type, // target type; (account or character)
204  const std::string &title, // title of the gift message
205  const std::string &content, // body of the gift message
206  const fun::WallClock::Value &expires, // expiration time for the gift
207  const std::vector<std::pair<std::string, uint64_t> > &items,
208  const std::vector<std::string> &users, // recipients
209  const Ptr<VoidResponseWriter> &writer) const;
210 
211  // send gift to all the users
212  virtual void GiveGiftToAll(
213  const std::string &target_type, // target type; (account or character)
214  const std::string &title, // title of the gift message
215  const std::string &content, // body of the gift message
216  const fun::WallClock::Value &expires, // expiration time for the gift
217  const std::vector<std::pair<std::string, uint64_t> > &items,
218  const Ptr<VoidResponseWriter> &writer) const;
219  // }
220  protected:
221  DeployApiHandlerBase(); // Never instantiate DeployApiHandlerBase
222  };
223 
224  // Restrict editable fields for user, character
225  static bool SetEditableFieldsForUser(
226  const std::vector<std::string> &field_list);
227  static bool SetEditableFieldsForCharacter(
228  const std::vector<std::string> &field_list);
229 
230  // Restrict items which could be sent to user as a gift.
231  // item_list should be vector of (item-id, item-name) pairs.
232  static bool SetGiftableItems(
233  const std::vector<std::pair<std::string, std::string> > &item_list);
234 
235  // Event API
236  // {
238  enum ValueType {
239  //int, float, string
240  VT_INT = 0, // int64_t
241  VT_FLOAT = 1, // double
242  VT_STRING = 2, // std::string
243  };
244 
245  std::string id; // identifier to distinguish rewards in single campaign
246  std::string name; // display name; can be empty string.
247  ValueType value_type;
248  };
249 
250  struct Campaign {
251  std::string name;
252  std::vector<CampaignRewardSchema> reward_schemas;
253  };
254 
255  // Arguments passed from iFun Deploy to campaign.
256  // 아이펀 디플로이에서 캠페인 콜백에게 전달하는 인자.
258  std::string name;
259  std::string description;
260 
261  // Arguments will be parsed as specified in CampaignRewardSchema.
262  // 각 인자는 CampaignRewardSchema 에 지정한 타입으로 파싱합니다.
263  // VT_INT: int64_t
264  // VT_DOUBLE: double
265  // VT_STRING: string
266  typedef boost::variant<int64_t, double, std::string> Value;
267 
268  // list of named pairs. (reward)
269  // 보상에 해당하는 이름, 값 쌍 목록.
270  std::vector<std::pair<std::string, Value> > values;
271 
272  fun::WallClock::Value begin_ts;
273  fun::WallClock::Value end_ts;
274 
275  bool is_recurring; // is recurring event (or not). 반복 이벤트인지 여부.
276 
277  // For recurring campaign (반복 이벤트)
279  // day of week for the campaign (0 = Sun, 1 = Mon, ...)
280  // 이벤트에 해당하는 요일 (0 = 일, 1 = 월, ...)
281  std::vector<boost::date_time::weekdays> days_of_the_week;
282 
283  int32_t begin_ts_of_day; // 0 .. 86400 (in timezone)
284  int32_t end_ts_of_day; // 0 .. 86400 (in timezone)
285 
286  std::string timezone; // timezone in tz database (eg. Asia/Seoul)
287  } recurring_schedule;
288  };
289 
290  typedef boost::function<bool (const Campaign & /*data*/,
291  const std::string & /*type*/, const std::string & /*id*/,
292  const CampaignArgument & /*arg*/)> BeginCampaignCallback;
293 
294  typedef boost::function<bool (const Campaign & /*campaign_type*/,
295  const std::string & /*type*/, const std::string & /*id*/)>
296  EndCampaignCallback;
297 
298  typedef boost::function<bool (const Campaign &campaign_type,
299  const std::string &type, const std::string &id)>
300  CancelCampaignCallback;
301 
302  static bool RegisterCampaignType(const std::string &campaign_id,
303  const Campaign &campaign);
304  // called when the campaign begins
305  static void RegisterBeginCampaignCallback(const BeginCampaignCallback &cb);
306 
307  // called when the campaign ends
308  static void RegisterEndCampaignCallback(const EndCampaignCallback &cb);
309 
310  // called when the campaign is canceled
311  static void RegisterCancelCampaignCallback(const CancelCampaignCallback &cb);
312  // }
313 
314  // You should pass handler as subclass of DeployApiHandlerBase.
315  // If you pass DeployApiHandlerBase as handler, it will terminate execution.
316  template <typename T>
317  static void RegisterDeployApiHandler(boost::shared_ptr<T> handler);
318 
320  struct ExtraData : boost::noncopyable {
321  static Ptr<ExtraData> Create();
322  virtual ~ExtraData();
323 
324  // Export as JSON, which can be passed as `extra_data` argument
325  // for RegisterCustomQueryHandler.
326  virtual fun::Json Export() const = 0;
327 
328  // Create dropdown list for parameter `name`.
329  // It would make iFunDeploy UI to use select box.
330  virtual bool SetDropdownList(
331  const std::string &name, const std::vector<std::string> &values) = 0;
332 
333  protected:
334  ExtraData();
335  };
336 
339  // Takes second JSON object as argument (which should be passed in HTTP
340  // request body), then write response to writer function.
341  // Handler may write non-200 status code to indicate the error.
342  // (If the json body is not set, iFuEngine will set the JSON body as
343  // {"error": "error string for http status code"}.)
344  // The first argument is used to indicate paging.
345  typedef boost::function<void (
346  const PageInfo & /*page_info*/,
347  const fun::Json & /*request*/,
348  Ptr<JsonResponseWriter> & /*response writer*/)> CustomApiHandler;
349 
350  // Register a handler for iFunDeploy custom query
351  static void RegisterCustomQueryHandler(
352  const std::string &name, // display name
353  const http::Method &method, // HTTP verb
354  const std::string &uri, // URI (MUST NOT include regex)
355  // JSON attributes which should be provided by JSON request body
356  const std::vector<std::string> &request_fields,
357  // JSON attributes which should be placed in JSON response
358  // (for successful response)
359  const std::vector<std::string> &response_fields,
360  const CustomApiHandler &handler,
361  // Optional data which can be used by iFunDeploy to provide
362  // addtional UI component or functionality.
363  const Ptr<ExtraData> &extra_data);
364 
365  static void RegisterCustomQueryHandler(
366  const std::string &name, // display name
367  const http::Method &method, // HTTP verb
368  const std::string &uri, // URI (MUST NOT include regex)
369  // JSON attributes which should be provided by JSON request body
370  const std::vector<std::string> &request_fields,
371  // JSON attributes which should be placed in JSON response
372  // (for successful response)
373  const std::vector<std::string> &response_fields,
374  const CustomApiHandler &handler,
375  // Optional data which can be used by iFunDeploy to provide
376  // addtional UI component or functionality.
377  // You may use alternative RegisterCustomQueryHandler
378  // with ExtraData API.
379  const fun::Json &extra_data=fun::Json());
381 
382  private:
383  static void _AddImplementedHandler(const std::string &account_handler_name);
384  static void _DoRegister(boost::shared_ptr<DeployApiHandlerBase> handler);
385 };
386 
387 
390 
393 
394 
397 namespace detail {
398 
399 #define HAS_MEMBER_FUNCTION(NAME, ARGS) \
400 template <typename T> \
401 class Has ## NAME { \
402 private: \
403  typedef char Yes; \
404  typedef Yes No[2]; \
405 \
406  template <typename U, U> struct Same; \
407  template <typename C> static Yes& Test(Same< \
408  void (C::*)ARGS const, &C:: NAME>*); \
409  template <typename> static No& Test(...); \
410 \
411 public: \
412  static bool const value = sizeof(Test<T>(0)) == sizeof(Yes); \
413 }
414 
415 
416 #define CHECK_MEMBER_FUNCTION(NAME) \
417  if (detail::Has ## NAME<T>::value) { _AddImplementedHandler(#NAME); }
418 
419 
420 HAS_MEMBER_FUNCTION(GetUserSearchConditions,
421  (const Ptr<StringVectorResponseWriter>&));
422 HAS_MEMBER_FUNCTION(SearchUsers,
423  (const std::string&, const std::string&, const DeployApiService::PageInfo&,
424  const Ptr<JsonVectorResponseWriter>&));
425 HAS_MEMBER_FUNCTION(GetUser,
426  (const std::string&, const Ptr<JsonResponseWriter>&));
427 HAS_MEMBER_FUNCTION(UpdateUser,
428  (const std::string&, const std::string&, const std::string&,
429  const Ptr<VoidResponseWriter>&));
430 HAS_MEMBER_FUNCTION(IsLoggedIn,
431  (const std::string&, const Ptr<BoolResponseWriter>&));
432 HAS_MEMBER_FUNCTION(ForceLogout,
433  (const std::string&, const Ptr<VoidResponseWriter>&));
434 
435 HAS_MEMBER_FUNCTION(GetUserBanned,
436  (const std::string&, const Ptr<BoolResponseWriter>&));
437 HAS_MEMBER_FUNCTION(BanUser,
438  (const std::string&, const Ptr<VoidResponseWriter>&));
439 HAS_MEMBER_FUNCTION(BanUsers,
440  (const std::vector<std::string>&,
441  const Ptr<BanUsersResponseWriter>&));
442 HAS_MEMBER_FUNCTION(UnbanUser,
443  (const std::string&, const Ptr<VoidResponseWriter>&));
444 HAS_MEMBER_FUNCTION(UnbanUsers,
445  (const std::vector<std::string>&,
446  const Ptr<UnbanUsersResponseWriter>&));
447 
448 HAS_MEMBER_FUNCTION(GetCharacters,
449  (const std::string &, const Ptr<JsonVectorResponseWriter>&));
450 HAS_MEMBER_FUNCTION(GetCharacter,
451  (const std::string &, const Ptr<JsonResponseWriter>&));
452 HAS_MEMBER_FUNCTION(UpdateCharacter,
453  (const std::string&, const std::string&, const std::string&,
454  const Ptr<VoidResponseWriter> &));
455 HAS_MEMBER_FUNCTION(GiveGift,
456  (const std::string&, const std::string&, const std::string&,
457  const fun::WallClock::Value&,
458  const std::vector<std::pair<std::string, uint64_t> >&,
459  const std::vector<std::string>&,
460  const Ptr<VoidResponseWriter> &));
461 HAS_MEMBER_FUNCTION(GiveGiftToAll,
462  (const std::string&, const std::string&,
463  const fun::WallClock::Value&,
464  const std::vector<std::pair<std::string, uint64_t> >&,
465  const Ptr<VoidResponseWriter> &));
466 HAS_MEMBER_FUNCTION(GetCharacterInventoryInfo,
467  (const std::string &,
468  const Ptr<ResponseWriterT<
469  DeployApiService::DeployApiHandlerBase::InventoryInfo> >&));
470 HAS_MEMBER_FUNCTION(GetInventory,
471  (const std::string&, const std::string &,
473  const Ptr<JsonVectorResponseWriter>&));
474 HAS_MEMBER_FUNCTION(DeleteInventoryItem,
475  (const std::string&, const std::string&, const std::string &,
476  const int64_t, const int64_t, const Ptr<VoidResponseWriter> &));
477 HAS_MEMBER_FUNCTION(DeleteMultipleInventoryItems,
478  (const std::vector<DeployApiService::DeployApiHandlerBase::ReclaimInfo> &,
479  const Ptr<VoidResponseWriter> &));
480 
482 
483 } // namespace detail
484 
485 // NOTE: You MUST NOT call this specialized function.
486 template <>
487 void DeployApiService::RegisterDeployApiHandler<
488  DeployApiService::DeployApiHandlerBase>(
489  boost::shared_ptr<DeployApiService::DeployApiHandlerBase> handler);
490 
491 
492 template <typename T>
493 void DeployApiService::RegisterDeployApiHandler(boost::shared_ptr<T> handler) {
494  CHECK_MEMBER_FUNCTION(GetUserSearchConditions);
495  CHECK_MEMBER_FUNCTION(SearchUsers);
496 
497  CHECK_MEMBER_FUNCTION(GetUser);
498  CHECK_MEMBER_FUNCTION(UpdateUser);
499  CHECK_MEMBER_FUNCTION(IsLoggedIn);
500  CHECK_MEMBER_FUNCTION(ForceLogout);
501 
502  CHECK_MEMBER_FUNCTION(GetUserBanned);
503  CHECK_MEMBER_FUNCTION(BanUser);
504  CHECK_MEMBER_FUNCTION(BanUsers);
505  CHECK_MEMBER_FUNCTION(UnbanUser);
506  CHECK_MEMBER_FUNCTION(UnbanUsers);
507 
508  CHECK_MEMBER_FUNCTION(GetCharacters);
509  CHECK_MEMBER_FUNCTION(GetCharacter);
510  CHECK_MEMBER_FUNCTION(UpdateCharacter);
511  CHECK_MEMBER_FUNCTION(GiveGift);
512  if (not detail::HasGiveGift<T>::value) {
513  CHECK_MEMBER_FUNCTION(GiveGiftToAll);
514  }
515  CHECK_MEMBER_FUNCTION(GetCharacterInventoryInfo);
516  CHECK_MEMBER_FUNCTION(GetInventory);
517  CHECK_MEMBER_FUNCTION(DeleteInventoryItem);
518  CHECK_MEMBER_FUNCTION(DeleteMultipleInventoryItems);
519 
520  _DoRegister(static_cast<boost::shared_ptr<DeployApiHandlerBase> >(handler));
521 }
522 
523 } // namespace fun
524 
525 #endif // INCLUDE_FUNAPI_MANAGEMENT_DEPLOY_API_SERVICE_H_
Definition: deploy_api_service.h:43
Definition: deploy_api_service.h:55
Definition: deploy_api_service.h:250
boost::function< void(const PageInfo &, const fun::Json &, Ptr< JsonResponseWriter > &)> CustomApiHandler
Custom query handlers for iFunDeploy {.
Definition: deploy_api_service.h:348
Definition: deploy_api_service.h:68
Definition: deploy_api_service.h:237
Definition: json.h:27
Definition: deploy_api_service.h:257
Definition: deploy_api_service.h:60
Defines extra data for custom query.
Definition: deploy_api_service.h:320
Definition: deploy_api_service.h:31
Definition: deploy_api_service.h:36