Matchmaking.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. /*******************************************************************************
  2. Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
  3. NOTICE:All information contained herein is, and remains the property of
  4. PICO Technology Co., Ltd. The intellectual and technical concepts
  5. contained herein are proprietary to PICO Technology Co., Ltd. and may be
  6. covered by patents, patents in process, and are protected by trade secret or
  7. copyright law. Dissemination of this information or reproduction of this
  8. material is strictly forbidden unless prior written permission is obtained from
  9. PICO Technology Co., Ltd.
  10. *******************************************************************************/
  11. using System;
  12. using System.Collections.Generic;
  13. using Pico.Platform.Models;
  14. using UnityEngine;
  15. namespace Pico.Platform
  16. {
  17. /**
  18. * \ingroup Platform
  19. */
  20. public static class MatchmakingService
  21. {
  22. /// <summary>Reports the result of a skill-rating match.
  23. /// @note Applicable to the following matchmaking modes: Quickmatch, Browse (+ Skill Pool)</summary>
  24. ///
  25. /// <param name="roomId">The room ID.</param>
  26. /// <param name="data">The key-value pairs.</param>
  27. /// <returns>Request information of type `Task`, including the request ID, and its response message does not contain data.
  28. /// | Error Code| Error Message |
  29. /// |---|---|
  30. /// |3006209|match result report: not in match|
  31. /// |3006210|match result report: error report data|
  32. /// |3006211|match result report: duplicate report|
  33. /// |3006212|match result report: conflict with other's report|
  34. ///
  35. /// Only for pools with skill-based matchmaking.
  36. /// Call this method after calling `StartMatch()` to begin a skill-rating
  37. /// match. After the match finishes, the server will record the result and
  38. /// update the skill levels of all players involved based on the result. This
  39. /// method is insecure because, as a client API, it is susceptible to tampering
  40. /// and therefore cheating to manipulate skill ratings.
  41. ///
  42. /// A message of type `MessageType.Matchmaking_ReportResultInsecure` will be generated in response.
  43. /// First call `Message.IsError()` to check if any error has occurred.
  44. /// This response has no payload. If no error has occurred, the request is successful.
  45. /// </returns>
  46. public static Task ReportResultsInsecure(UInt64 roomId, Dictionary<string, int> data)
  47. {
  48. KVPairArray kvarray = new KVPairArray((uint) data.Count);
  49. uint n = 0;
  50. foreach (var d in data)
  51. {
  52. var item = kvarray.GetElement(n);
  53. item.SetKey(d.Key);
  54. item.SetIntValue(d.Value);
  55. n++;
  56. }
  57. return new Task(CLIB.ppf_Matchmaking_ReportResultInsecure(roomId, kvarray.GetHandle(), kvarray.Size));
  58. }
  59. /// <summary>Gets the matchmaking statistics for the current user.
  60. /// @note Applicable to the following matchmaking modes: Quickmatch, Browse</summary>
  61. ///
  62. /// <param name="pool">The pool to look in.</param>
  63. /// <param name="maxLevel">(beta feature, don't use it)</param>
  64. /// <param name="approach">(beta feature, don't use it)</param>
  65. /// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `MatchmakingStats`.
  66. /// | Error Code| Error Message |
  67. /// |---|---|
  68. /// |3006201|match enqueue: invalid pool name|
  69. /// |3006208|match enqueue: no skill|
  70. ///
  71. ///
  72. /// When given a pool, the system will look up the current user's wins, losses, draws and skill
  73. /// level. The skill level returned will be between `1` and the maximum level. The approach
  74. /// will determine how should the skill level rise toward the maximum level.
  75. ///
  76. /// A message of type `MessageType.Matchmaking_GetStats` will be generated in response.
  77. /// First call `Message.IsError()` to check if any error has occurred.
  78. /// If no error has occurred, the message will contain a payload of type `MatchmakingStats`.
  79. /// Extract the payload from the message handle with `message.Data`.
  80. /// </returns>
  81. public static Task<MatchmakingStats> GetStats(string pool, uint maxLevel, MatchmakingStatApproach approach = MatchmakingStatApproach.Trailing)
  82. {
  83. if (!CoreService.Initialized)
  84. {
  85. Debug.LogError(CoreService.NotInitializedError);
  86. return null;
  87. }
  88. return new Task<MatchmakingStats>(CLIB.ppf_Matchmaking_GetStats(pool, maxLevel, approach));
  89. }
  90. /// <summary>Gets rooms by matchmakinging pool name.
  91. /// The user can join the room with `RoomService.Join2 to`or cancel the retrieval with `MatchmakingService.Cancel`.
  92. /// @note Applicable to the following matchmaking mode: Browse</summary>
  93. ///
  94. /// <param name="pool">The matchmaking pool name you want to browse.</param>
  95. /// <param name="matchmakingOptions">(Optional) The matchmaking configuration of the browse request.</param>
  96. /// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `MatchmakingBrowseResult`.
  97. /// | Error Code| Error Message |
  98. /// |---|---|
  99. /// |3006201|match enqueue: invalid pool name|
  100. /// |3006205|match browse: access denied|
  101. /// |3006207|match enqueue: invalid query key|
  102. ///
  103. /// A message of type `MessageType.Matchmaking_Browse2` will be generated in response.
  104. /// First call `Message.IsError()` to check if any error has occurred.
  105. /// If no error has occurred, the message will contain a payload of type `MatchmakingBrowseResult`.
  106. /// Extract the payload from the message handle with `message.Data`.
  107. /// </returns>
  108. public static Task<MatchmakingBrowseResult> Browse2(string pool, MatchmakingOptions matchmakingOptions = null)
  109. {
  110. if (!CoreService.Initialized)
  111. {
  112. Debug.LogError(CoreService.NotInitializedError);
  113. return null;
  114. }
  115. if (matchmakingOptions == null)
  116. {
  117. return new Task<MatchmakingBrowseResult>(CLIB.ppf_Matchmaking_Browse2(pool, IntPtr.Zero));
  118. }
  119. else
  120. {
  121. return new Task<MatchmakingBrowseResult>(CLIB.ppf_Matchmaking_Browse2(pool, matchmakingOptions.GetHandle()));
  122. }
  123. }
  124. /// <summary>Gets rooms by matchmakinging pool name and specify the page number and the number of pages per page.</summary>
  125. ///
  126. /// <param name="pool">The matchmaking pool name you want to browse.</param>
  127. /// <param name="matchmakingOptions">(Optional) The matchmaking configuration of the browse request.</param>
  128. /// <param name="pageIndex">(Optional)Start page index.</param>
  129. /// <param name="pageSize">(Optional)the number of pages per page.</param>
  130. /// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `MatchmakingBrowseResult`.
  131. ///
  132. /// A message of type `MessageType.Matchmaking_Browse2CustomPage` will be generated in response.
  133. /// First call `Message.IsError()` to check if any error has occurred.
  134. /// If no error has occurred, the message will contain a payload of type `MatchmakingBrowseResult`.
  135. /// Extract the payload from the message handle with `message.Data`.
  136. /// </returns>
  137. public static Task<MatchmakingBrowseResult> Browse2ForCustomPage(string pool, MatchmakingOptions matchmakingOptions = null, int pageIndex = 0, int pageSize = 5)
  138. {
  139. if (!CoreService.Initialized)
  140. {
  141. Debug.LogError(CoreService.NotInitializedError);
  142. return null;
  143. }
  144. if (matchmakingOptions == null)
  145. {
  146. return new Task<MatchmakingBrowseResult>(CLIB.ppf_Matchmaking_Browse2CustomPage(pool, IntPtr.Zero, pageIndex, pageSize));
  147. }
  148. else
  149. {
  150. return new Task<MatchmakingBrowseResult>(CLIB.ppf_Matchmaking_Browse2CustomPage(pool, matchmakingOptions.GetHandle(), pageIndex, pageSize));
  151. }
  152. }
  153. /// <summary>Cancels a matchmaking request. Call this function
  154. /// to cancel an enqueue request before a match
  155. /// is made. This is typically triggered when a user gives up waiting.
  156. /// If you do not cancel the request but the user goes offline, the user/room
  157. /// will be timed out according to the setting of reserved period on the PICO Developer Platform.
  158. /// @note Applicable to the following matchmaking modes: Quickmatch, Browse</summary>
  159. ///
  160. /// <returns>Request information of type `Task`, including the request ID, and its response message does not contain data.
  161. /// | Error Code| Error Message |
  162. /// |---|---|
  163. /// |3006201|match enqueue: invalid pool name|
  164. /// |3006206|match cancel: not in match|
  165. /// |3006301|server error: unknown|
  166. ///
  167. ///
  168. /// A message of type `MessageType.Matchmaking_Cancel2` will be generated in response.
  169. /// Call `Message.IsError()` to check if any error has occurred.
  170. /// This response has no payload. If no error has occurred, the request is successful.
  171. /// </returns>
  172. public static Task Cancel()
  173. {
  174. if (!CoreService.Initialized)
  175. {
  176. Debug.LogError(CoreService.NotInitializedError);
  177. return null;
  178. }
  179. return new Task(CLIB.ppf_Matchmaking_Cancel2());
  180. }
  181. /// <summary>Creates a matchmaking room, then enqueues and joins it.
  182. /// @note Applicable to the following matchmaking modes: Quickmatch, Browse, Advanced (Can Users Create Rooms=`true`)</summary>
  183. ///
  184. /// <param name="pool">The matchmaking pool to use, which is created on the PICO Developer Platform.</param>
  185. /// <param name="matchmakingOptions">(Optional) Additional matchmaking configuration for this request.</param>
  186. /// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `MatchmakingEnqueueResultAndRoom`.
  187. /// | Error Code| Error Message |
  188. /// |---|---|
  189. /// |3006201|match enqueue: invalid pool name|
  190. /// |3006203|match create room: pool config not allow user create room|
  191. /// |3006207|match enqueue: invalid query key |
  192. /// |3006301|server error: unknown |
  193. /// |3006204|match enqueue: invalid room id(Assigned room id, present in this context, indicates an internal server error) |
  194. /// |3006103|invalid room(The room was found to be invalid when joining the room, which appears in this context, indicating an internal server error) |
  195. /// |3006102|duplicate join room(Duplicate joins are found when joining a room, which appears in this context, indicating an internal server error) |
  196. /// |3006106|exceed max room player number(Exceeding the maximum number of people when joining a room, appears in this context, indicating an internal server error) |
  197. /// |3006105|illegal enter request(Illegal incoming requests, such as not in the allowed whitelist, appear in this context, indicating an internal server error) |
  198. /// |3006108|room is locked(When joining a room, it is found that the room is locked, appears in this context, indicating an internal server error)|
  199. ///
  200. /// A message of type `MessageType.Matchmaking_CreateAndEnqueueRoom2` will be generated in response.
  201. /// First call `message.IsError()` to check if any error has occurred.
  202. /// If no error has occurred, the message will contain a payload of type `MatchmakingEnqueueResultAndRoom`.
  203. /// Extract the payload from the message handle with `message.Data`.
  204. /// </returns>
  205. public static Task<MatchmakingEnqueueResultAndRoom> CreateAndEnqueueRoom2(string pool, MatchmakingOptions matchmakingOptions = null)
  206. {
  207. if (!CoreService.Initialized)
  208. {
  209. Debug.LogError(CoreService.NotInitializedError);
  210. return null;
  211. }
  212. if (matchmakingOptions == null)
  213. {
  214. return new Task<MatchmakingEnqueueResultAndRoom>(CLIB.ppf_Matchmaking_CreateAndEnqueueRoom2(pool, IntPtr.Zero));
  215. }
  216. else
  217. {
  218. return new Task<MatchmakingEnqueueResultAndRoom>(CLIB.ppf_Matchmaking_CreateAndEnqueueRoom2(pool, matchmakingOptions.GetHandle()));
  219. }
  220. }
  221. /// <summary>Enqueues for an available matchmaking room to join.
  222. /// When the server finds a match, it will return a message of
  223. /// type `MessageType.Notification_Matchmaking_MatchFound`. You
  224. /// can join found matching rooms by calling `RoomService.Join2`.
  225. /// If you want to cancel the match early, you can use `MatchmakingService.Cancel`.
  226. /// @note Applicable to the following matchmaking mode: Quickmatch</summary>
  227. ///
  228. /// <param name="pool">The matchmaking pool to use, which is defined on the PICO Developer Platform.</param>
  229. /// <param name="matchmakingOptions">(Optional) Match configuration for Enqueue.</param>
  230. /// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `MatchmakingEnqueueResult`.
  231. /// | Error Code| Error Message |
  232. /// |---|---|
  233. /// |3006201|match enqueue: invalid pool name|
  234. /// |3006401|logic state checking failed|
  235. /// |3006207|match enqueue: invalid query key|
  236. /// |3006301|server error: unknown|
  237. ///
  238. /// A message of type `MessageType.Matchmaking_Enqueue2` will be generated in response.
  239. /// First call `message.IsError()` to check if any error has occurred.
  240. /// If no error has occurred, the message will contain a payload of type `MatchmakingEnqueueResult`.
  241. /// Extract the payload from the message handle with `message.Data`.
  242. /// </returns>
  243. public static Task<MatchmakingEnqueueResult> Enqueue2(string pool, MatchmakingOptions matchmakingOptions = null)
  244. {
  245. if (!CoreService.Initialized)
  246. {
  247. Debug.LogError(CoreService.NotInitializedError);
  248. return null;
  249. }
  250. if (matchmakingOptions == null)
  251. {
  252. return new Task<MatchmakingEnqueueResult>(CLIB.ppf_Matchmaking_Enqueue2(pool, IntPtr.Zero));
  253. }
  254. else
  255. {
  256. return new Task<MatchmakingEnqueueResult>(CLIB.ppf_Matchmaking_Enqueue2(pool, matchmakingOptions.GetHandle()));
  257. }
  258. }
  259. /// <summary>Debugs the state of the current matchmaking pool queue.
  260. /// @note
  261. /// * This function should not be used in production.
  262. /// * Applicable to the following matchmaking modes: Quickmatch, Browse
  263. ///
  264. /// </summary>
  265. ///
  266. /// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `MatchmakingAdminSnapshot`.
  267. /// | Error Code| Error Message |
  268. /// |---|---|
  269. /// |3006201|match enqueue: invalid pool name|
  270. /// |3006301|server error: unknown |
  271. ///
  272. /// A message of type `MessageType.Matchmaking_GetAdminSnapshot` will be generated in response.
  273. /// First call `message.IsError()` to check if any error has occurred.
  274. /// If no error has occurred, the message will contain a payload of type `MatchmakingAdminSnapshot`.
  275. /// Extract the payload from the message handle with `message.Data`.
  276. /// </returns>
  277. public static Task<MatchmakingAdminSnapshot> GetAdminSnapshot()
  278. {
  279. if (!CoreService.Initialized)
  280. {
  281. Debug.LogError(CoreService.NotInitializedError);
  282. return null;
  283. }
  284. return new Task<MatchmakingAdminSnapshot>(CLIB.ppf_Matchmaking_GetAdminSnapshot());
  285. }
  286. /// <summary>Reports that a skill-rating match has started.
  287. /// You can use this method after joining the room.
  288. /// @note
  289. /// * This function is only for pools with skill-based matching.
  290. /// * Applicable to the following matchmaking modes: Quickmatch, Browse (+ Skill Pool)
  291. /// </summary>
  292. ///
  293. /// <param name="roomId">The ID of the room you want to match.</param>
  294. /// <returns>Request information of type `Task`, including the request ID, and its response message does not contain data.
  295. ///
  296. /// A message of type `MessageType.Matchmaking_StartMatch` will be generated in response.
  297. /// Call `message.IsError()` to check if any error has occurred.
  298. /// </returns>
  299. public static Task StartMatch(UInt64 roomId)
  300. {
  301. if (!CoreService.Initialized)
  302. {
  303. Debug.LogError(CoreService.NotInitializedError);
  304. return null;
  305. }
  306. return new Task(CLIB.ppf_Matchmaking_StartMatch(roomId));
  307. }
  308. /// <summary>Sets the callback to get notified when a match has been found. For example,
  309. /// after calling `MatchmakingService.Enqueue`, when the match is successful, you will
  310. /// receive `Notification_Matchmaking_MatchFound`, and then execute the processing function
  311. /// set by this function.</summary>
  312. ///
  313. /// <param name="handler">The callback function will be called when receiving the `Notification_Matchmaking_MatchFound` message.</param>
  314. public static void SetMatchFoundNotificationCallback(Message<Room>.Handler handler)
  315. {
  316. Looper.RegisterNotifyHandler(MessageType.Notification_Matchmaking_MatchFound, handler);
  317. }
  318. /// <summary>A notification will be sent to the player after they have been kicked out of the matchmaking pool.
  319. /// Listen to the event to receive a message.</summary>
  320. ///
  321. /// <param name="handler">The callback function will be called when receiving the `Matchmaking_Cancel2` message and the value of `requestID` is `0`.</param>
  322. public static void SetCancel2NotificationCallback(Message.Handler handler)
  323. {
  324. Looper.RegisterNotifyHandler(MessageType.Matchmaking_Cancel2, handler);
  325. }
  326. }
  327. public class MatchmakingOptions
  328. {
  329. public MatchmakingOptions()
  330. {
  331. Handle = CLIB.ppf_MatchmakingOptions_Create();
  332. }
  333. /// <summary>
  334. /// Sets the data store for a room.
  335. /// </summary>
  336. /// <param name="key">A unique identifier that maps to a value.</param>
  337. /// <param name="value">The data.</param>
  338. public void SetCreateRoomDataStore(string key, string value)
  339. {
  340. CLIB.ppf_MatchmakingOptions_SetCreateRoomDataStoreString(Handle, key, value);
  341. }
  342. /// <summary>
  343. /// Clears the data store for a room.
  344. /// </summary>
  345. public void ClearCreateRoomDataStore()
  346. {
  347. CLIB.ppf_MatchmakingOptions_ClearCreateRoomDataStore(Handle);
  348. }
  349. /// <summary>
  350. /// Sets a join policy for a room.
  351. /// </summary>
  352. /// <param name="value">The enumerations of join policy:
  353. /// * `0`: None
  354. /// * `1`: Everyone
  355. /// * `2`: FriendsOfMembers
  356. /// * `3`: FriendsOfOwner
  357. /// * `4`: InvitedUsers
  358. /// * `5`: Unknown
  359. /// </param>
  360. public void SetCreateRoomJoinPolicy(RoomJoinPolicy value)
  361. {
  362. CLIB.ppf_MatchmakingOptions_SetCreateRoomJoinPolicy(Handle, value);
  363. }
  364. /// <summary>
  365. /// Sets the maximum number of users allowed for a room.
  366. /// </summary>
  367. /// <param name="value">The maximum number of users.</param>
  368. public void SetCreateRoomMaxUsers(uint value)
  369. {
  370. CLIB.ppf_MatchmakingOptions_SetCreateRoomMaxUsers(Handle, value);
  371. }
  372. /// <summary>
  373. /// Sets an integer data setting for a query of a matchmaking pool.
  374. /// </summary>
  375. /// <param name="key">A unique identifier that maps a value.</param>
  376. /// <param name="value">The data (integer).</param>
  377. public void SetEnqueueDataSettings(string key, int value)
  378. {
  379. CLIB.ppf_MatchmakingOptions_SetEnqueueDataSettingsInt(Handle, key, value);
  380. }
  381. /// <summary>
  382. /// Sets a float data setting for a query of a matchmaking pool.
  383. /// </summary>
  384. /// <param name="key">A unique identifier that maps a value.</param>
  385. /// <param name="value">The data.</param>
  386. public void SetEnqueueDataSettings(string key, double value)
  387. {
  388. CLIB.ppf_MatchmakingOptions_SetEnqueueDataSettingsDouble(Handle, key, value);
  389. }
  390. /// <summary>
  391. /// Sets a string data setting for a query of a matchmaking pool.
  392. /// </summary>
  393. /// <param name="key">A unique identifier that maps a value.</param>
  394. /// <param name="value">The data.</param>
  395. public void SetEnqueueDataSettings(string key, string value)
  396. {
  397. CLIB.ppf_MatchmakingOptions_SetEnqueueDataSettingsString(Handle, key, value);
  398. }
  399. /// <summary>
  400. /// Clears data settings for a query of a matchmaking pool.
  401. /// </summary>
  402. public void ClearEnqueueDataSettings()
  403. {
  404. CLIB.ppf_MatchmakingOptions_ClearEnqueueDataSettings(Handle);
  405. }
  406. /// <summary>
  407. /// Sets whether to return the debugging information.
  408. /// </summary>
  409. /// <param name="value">
  410. /// * `true`: return the debugging information with the response payload
  411. /// * `false`: do not return the debugging information
  412. /// </param>
  413. public void SetEnqueueIsDebug(bool value)
  414. {
  415. CLIB.ppf_MatchmakingOptions_SetEnqueueIsDebug(Handle, value);
  416. }
  417. /// <summary>
  418. /// Sets the query for a matchmaking.
  419. /// </summary>
  420. /// <param name="value">The key of the target query.
  421. /// @note One matchmaking pool can include multiple queries which are created on the PICO Developer Platform.
  422. /// You can choose which query to use before starting a matchmaking.
  423. /// </param>
  424. public void SetEnqueueQueryKey(string value)
  425. {
  426. CLIB.ppf_MatchmakingOptions_SetEnqueueQueryKey(Handle, value);
  427. }
  428. /// For passing to native C
  429. public static explicit operator IntPtr(MatchmakingOptions matchmakingOptions)
  430. {
  431. return matchmakingOptions != null ? matchmakingOptions.Handle : IntPtr.Zero;
  432. }
  433. ~MatchmakingOptions()
  434. {
  435. CLIB.ppf_MatchmakingOptions_Destroy(Handle);
  436. }
  437. IntPtr Handle;
  438. public IntPtr GetHandle()
  439. {
  440. return Handle;
  441. }
  442. }
  443. }
粤ICP备19079148号