Загрузка PICO Unity OpenXR Integration SDK
This commit is contained in:
@ -0,0 +1,339 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
*
|
||||
* The Achievements service can help build a "positive feedback mechanism"
|
||||
* in your games. You can create prizes such as trophies and badges and
|
||||
* distribute them to players when they hit a goal, like completing the
|
||||
* beginner tutorial or reaching level x. Advanced achievements such as
|
||||
* completing a hidden level/task should be closely integrated with game
|
||||
* content design and, meanwhile, collaborate with prizes like diamonds
|
||||
* or props to make your games more challenging and further enhance players'
|
||||
* engagement.
|
||||
*/
|
||||
public static class AchievementsService
|
||||
{
|
||||
/// <summary>Adds a count to a specified count achievement. The count will be added to the current count. For example,
|
||||
/// if the current count is 1 and the count you would like to add is 7, the final count will be 8 if the request succeeds.
|
||||
/// @note Available to count achievements only.
|
||||
/// </summary>
|
||||
/// <param name="name">The API name of the achievement.</param>
|
||||
/// <param name="count">The count you want to add. The largest count supported by this function is the maximum
|
||||
/// value of a signed 64-bit integer. If the count is larger than that, it is
|
||||
/// clamped to that maximum value before being passed to the servers.
|
||||
/// </param>
|
||||
/// <param name="extraData">Custom extension fields that can be used to record key information when unlocking achievements.</param>
|
||||
/// <returns>The request ID of this async function.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |10729|invalid api name|
|
||||
/// |10733|invalid count|
|
||||
/// |10725|extra data too long|
|
||||
/// |10720|achievement is not exist|
|
||||
/// |10723|load achievement data failed|
|
||||
/// |10726|achievement is unreleased|
|
||||
/// |10727|achievement is archived|
|
||||
/// |10722|no write permission|
|
||||
/// |10736|invalid parameter|
|
||||
/// |10735|invalid extra data|
|
||||
/// |10734|operation is not allowed on the type|
|
||||
/// |10728|achievement is unlocked|
|
||||
/// |10724|save achievement data failed|
|
||||
///
|
||||
/// A message of type `MessageType.Achievements_AddCount` will be generated in response.
|
||||
/// First call `Message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `AchievementUpdate`.
|
||||
/// Extract the payload from the message handle with `Message.Data`.
|
||||
///
|
||||
/// `AchievementUpdate` contains the following:
|
||||
/// * `JustUnlocked`: Whether the achievement has been successfully unlocked.
|
||||
/// * `Name`: The API name of the achievement.
|
||||
/// </returns>
|
||||
public static Task<AchievementUpdate> AddCount(string name, long count, byte[] extraData)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
GCHandle hobj = GCHandle.Alloc(extraData, GCHandleType.Pinned);
|
||||
IntPtr pobj = hobj.AddrOfPinnedObject();
|
||||
var result = new Task<AchievementUpdate>(CLIB.ppf_Achievements_AddCount(name, count, pobj, (uint) (extraData != null ? extraData.Length : 0)));
|
||||
if (hobj.IsAllocated)
|
||||
hobj.Free();
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Unlocks the bit(s) of a specified bitfield achievement. The status of the bit(s) is then unchangeable.
|
||||
/// @note Available to bitfield achievements only.
|
||||
/// </summary>
|
||||
/// <param name="name">The API name of the achievement to unlock bit(s) for.</param>
|
||||
/// <param name="fields">A string containing either the `0` or `1` characters, for example, `100011`. Every `1` will unlock a bit in the corresponding position of a bitfield.</param>
|
||||
/// <param name="extraData">Custom extension fields that can be used to record key information when unlocking achievements.</param>
|
||||
/// <returns>The request ID of this async function.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |10729|invalid api name|
|
||||
/// |10731|invalid field|
|
||||
/// |10725|extra data too long|
|
||||
/// |10720|achievement is not exist|
|
||||
/// |10723|load achievement data failed|
|
||||
/// |10726|achievement is unreleased|
|
||||
/// |10727|achievement is archived|
|
||||
/// |10722|no write permission|
|
||||
/// |10736|invalid parameter|
|
||||
/// |10735|invalid extra data|
|
||||
/// |10734|operation is not allowed on the type|
|
||||
/// |10728|achievement is unlocked|
|
||||
/// |10724|save achievement data failed|
|
||||
///
|
||||
/// A message of type `MessageType.Achievements_AddFields` will be generated in response.
|
||||
/// First call `Message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `AchievementUpdate`.
|
||||
/// Extract the payload from the message handle with `Message.Data`.
|
||||
///
|
||||
/// `AchievementUpdate` contains the following:
|
||||
/// * `JustUnlocked`: Whether the achievement has been successfully unlocked.
|
||||
/// * `Name`: The API name of the achievement.
|
||||
/// </returns>
|
||||
public static Task<AchievementUpdate> AddFields(string name, string fields, byte[] extraData)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
GCHandle hobj = GCHandle.Alloc(extraData, GCHandleType.Pinned);
|
||||
IntPtr pobj = hobj.AddrOfPinnedObject();
|
||||
var result = new Task<AchievementUpdate>(CLIB.ppf_Achievements_AddFields(name, fields, pobj, (uint) (extraData != null ? extraData.Length : 0)));
|
||||
if (hobj.IsAllocated)
|
||||
hobj.Free();
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Gets the information about all achievements, including API names, descriptions, types,
|
||||
/// the targets which must be reached to unlock those achievements, and more.</summary>
|
||||
/// <param name="pageIdx">Defines which page of achievements to return. The first page index is `0`.</param>
|
||||
/// <param name="pageSize">The size of the page.</param>
|
||||
/// <returns>The request ID of this async function.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |10721|invalid api name|
|
||||
/// |10736|invalid parameter|
|
||||
/// |10720|achievement is not exist|
|
||||
/// |10723|load achievement data failed|
|
||||
///
|
||||
/// A message of type `MessageType.Achievements_GetAllDefinitions` will be generated in response.
|
||||
/// First call `Message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `AchievementDefinitionList`.
|
||||
/// Extract the payload from the message handle with `Message.Data`.
|
||||
///
|
||||
/// `AchievementDefinitionList` contains the following:
|
||||
/// * `Type`: The type of the achievement.
|
||||
/// * `Name`: The API name of the achievement.
|
||||
/// * `BitfieldLength`: The total bits in the bitfield. For bitfield achievements only.
|
||||
/// * `Target`: The number of events to complete for unlocking the achievement. For count or bitfield achievements only.
|
||||
/// * `Description`: The description of the achievement.
|
||||
/// * `Title`: The display name of the achievement that users see.
|
||||
/// * `IsArchived`: Whether the achievement is archived. Archiving will not delete the achievement or users' progress on it.
|
||||
/// * `IsSecret`: Whether the achievement is hidden until it is unlocked by users.
|
||||
/// * `ID`: The data ID.
|
||||
/// * `UnlockedDescription`: The message displayed to users when they unlock the achievement.
|
||||
/// * `WritePolicy`: Who are able to write achievement progress.
|
||||
/// * `LockedImageURL`: The local path to the image displayed to users before they unlock the achievement.
|
||||
/// * `UnlockedImageURL`: The local path to the image displayed to users after they unlock the achievement.
|
||||
/// </returns>
|
||||
public static Task<AchievementDefinitionList> GetAllDefinitions(int pageIdx, int pageSize)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<AchievementDefinitionList>(CLIB.ppf_Achievements_GetAllDefinitions(pageIdx, pageSize));
|
||||
}
|
||||
|
||||
/// <summary>Gets the user's progress on all achievements, including API names,
|
||||
/// whether or not the achievements are unlocked, the time at which they were unlocked,
|
||||
/// achievement types and, depending on the type, the progress made towards unlocking them, and more.</summary>
|
||||
/// <param name="pageIdx">Defines which page of achievements to return. The first page index is `0`.</param>
|
||||
/// <param name="pageSize">The size of the page.</param>
|
||||
/// <returns>The request ID of this async function.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |10721|invalid api name|
|
||||
/// |10723|load achievement data failed|
|
||||
///
|
||||
/// A message of type `MessageType.Achievements_GetAllProgress` will be generated in response.
|
||||
/// First call `Message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `AchievementProgressList`.
|
||||
/// Extract the payload from the message handle with `Message.Data`.
|
||||
///
|
||||
/// `AchievementProgressList` contains the following:
|
||||
/// * `ID`: The data ID.
|
||||
/// * `Bitfield`: A bitfield displaying the bits unlocked for a bitfield achievement, for example, `1110001`.
|
||||
/// * `Count`: The number of events completed for unlocking a count achievement.
|
||||
/// * `IsUnlocked`: Whether the achievement is unlocked.
|
||||
/// * `Name`: The API name of the achievement.
|
||||
/// * `UnlockTime`: The time at which the achievement was unlocked.
|
||||
/// * `ExtraData`: The key information recorded when unlocking the achievement.
|
||||
/// </returns>
|
||||
public static Task<AchievementProgressList> GetAllProgress(int pageIdx, int pageSize)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<AchievementProgressList>(CLIB.ppf_Achievements_GetAllProgress(pageIdx, pageSize));
|
||||
}
|
||||
|
||||
/// <summary>Gets the information about specified achievements, including API names, descriptions, types,
|
||||
/// the targets which must be reached to unlock those achievements, and more.</summary>
|
||||
/// <param name="names">The API names of the achievements.</param>
|
||||
/// <returns>The request ID of this async function.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |10729|invalid api name|
|
||||
/// |10730|too many api names|
|
||||
/// |10721|invalid request|
|
||||
/// |10736|invalid parameter|
|
||||
/// |10720|achievement is not exist|
|
||||
/// |10723|load achievement data failed|
|
||||
///
|
||||
/// A message of type `MessageType.Achievements_GetDefinitionsByName` will be generated in response.
|
||||
/// First call `Message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `AchievementDefinitionList`.
|
||||
/// Extract the payload from the message handle with `Message.Data`.
|
||||
///
|
||||
/// `AchievementDefinitionList` contains the following:
|
||||
/// * `Type`: The type of the achievement.
|
||||
/// * `Name`: The API name of the achievement.
|
||||
/// * `BitfieldLength`: The total bits in the bitfield. For bitfield achievements only.
|
||||
/// * `Target`: The number of events to complete for unlocking the achievement. For count or bitfield achievements only.
|
||||
/// * `Description`: The description of the achievement.
|
||||
/// * `Title`: The display name of the achievement that users see.
|
||||
/// * `IsArchived`: Whether the achievement is archived. Archiving will not delete the achievement or users' progress on it.
|
||||
/// * `IsSecret`: Whether the achievement is hidden until it is unlocked by users.
|
||||
/// * `ID`: The data ID.
|
||||
/// * `UnlockedDescription`: The message displayed to users when they unlock the achievement.
|
||||
/// * `WritePolicy`: Who are able to write achievement progress.
|
||||
/// * `LockedImageURL`: The local path to the image displayed to users before they unlock the achievement.
|
||||
/// * `UnlockedImageURL`: The local path to the image displayed to users after they unlock the achievement.
|
||||
/// </returns>
|
||||
public static Task<AchievementDefinitionList> GetDefinitionsByName(string[] names)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<AchievementDefinitionList>(CLIB.ppf_Achievements_GetDefinitionsByName(names));
|
||||
}
|
||||
|
||||
/// <summary>Gets the user's progress on specified achievements, including API names,
|
||||
/// whether or not the achievements are unlocked, the time at which they were unlocked,
|
||||
/// achievement types and, depending on the type, the progress made towards unlocking them, and more.</summary>
|
||||
/// <param name="names">The API names of the achievements.</param>
|
||||
/// <returns>The request ID of this async function.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |10729|invalid api name|
|
||||
/// |10730|too many api names|
|
||||
/// |10721|invalid request|
|
||||
/// |10723|load achievement data failed|
|
||||
///
|
||||
/// A message of type `MessageType.Achievements_GetProgressByName` will be generated in response.
|
||||
/// First call `Message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `AchievementProgressList`.
|
||||
/// Extract the payload from the message handle with `Message.Data`.
|
||||
///
|
||||
/// `AchievementProgressList` contains the following:
|
||||
/// * `ID`: The data ID.
|
||||
/// * `Bitfield`: A bitfield displaying the bits unlocked for a bitfield achievement, for example, `1110001`.
|
||||
/// * `Count`: The number of events completed for unlocking a count achievement.
|
||||
/// * `IsUnlocked`: Whether the achievement is unlocked.
|
||||
/// * `Name`: The API name of the achievement.
|
||||
/// * `UnlockTime`: The time at which the achievement was unlocked.
|
||||
/// * `ExtraData`: Records the key information when unlocking the achievement.
|
||||
/// </returns>
|
||||
public static Task<AchievementProgressList> GetProgressByName(string[] names)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<AchievementProgressList>(CLIB.ppf_Achievements_GetProgressByName(names));
|
||||
}
|
||||
|
||||
/// <summary>Unlocks a specified achievement of any type even if the target for
|
||||
/// unlocking this achievement is not reached.
|
||||
/// </summary>
|
||||
/// <param name="name">The API name of the achievement to unlock.</param>
|
||||
/// <param name="extraData">Custom extension fields that can be used to record key information when unlocking achievements.</param>
|
||||
/// <returns>The request ID of this async function.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |10729|invalid api name|
|
||||
/// |10725|extra data too long|
|
||||
/// |10720|achievement is not exist|
|
||||
/// |10723|load achievement data failed|
|
||||
/// |10726|achievement is unreleased|
|
||||
/// |10727|achievement is archived|
|
||||
/// |10722|no write permission|
|
||||
/// |10736|invalid parameter|
|
||||
/// |10735|invalid extra data|
|
||||
/// |10728|achievement is unlocked|
|
||||
/// |10724|save achievement data failed|
|
||||
///
|
||||
/// A message of type `MessageType.Achievements_Unlock` will be generated in response.
|
||||
/// First call `Message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `AchievementUpdate`.
|
||||
/// Extract the payload from the message handle with `Message.Data`.
|
||||
///
|
||||
/// `AchievementUpdate` contains the following:
|
||||
/// * `JustUnlocked`: Whether the achievement has been successfully unlocked.
|
||||
/// * `Name`: The API name of the achievement.
|
||||
/// </returns>
|
||||
public static Task<AchievementUpdate> Unlock(string name, byte[] extraData)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
GCHandle hobj = GCHandle.Alloc(extraData, GCHandleType.Pinned);
|
||||
IntPtr pobj = hobj.AddrOfPinnedObject();
|
||||
var result = new Task<AchievementUpdate>(CLIB.ppf_Achievements_Unlock(name, pobj, (uint) (extraData != null ? extraData.Length : 0)));
|
||||
if (hobj.IsAllocated)
|
||||
hobj.Free();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc57c56aed09492bb5ddfa820fcd982c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,209 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
using SystemInfo = Pico.Platform.Models.SystemInfo;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
*
|
||||
* ApplicationService provides functions like launch other application,jump to store, get launch details.
|
||||
*/
|
||||
public static class ApplicationService
|
||||
{
|
||||
/// <summary>
|
||||
/// Launches another app by app package name.
|
||||
/// @note If the user does not have that app installed, the user will be directed to the app's download page on the PICO Store.
|
||||
/// </summary>
|
||||
/// <param name="packageName">The package name of the to-be-launched app.</param>
|
||||
/// <param name="options">The options for launching the app. Pass `null` or leave this parameter empty.</param>
|
||||
/// <returns>If something goes wrong, a description message will be returned.</returns>
|
||||
public static Task<string> LaunchApp(string packageName, ApplicationOptions options = null)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<string>(CLIB.ppf_Application_LaunchOtherApp(packageName, (IntPtr) options));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Launches another app by app ID.
|
||||
/// @note If the user does not have that app installed, the user will be directed to the app's download page on the PICO Store.
|
||||
/// </summary>
|
||||
/// <param name="appId">The ID of the to-be-launched app.</param>
|
||||
/// <param name="options">The options for launching the app. Pass `null` or leave this parameter empty.</param>
|
||||
/// <returns>If something goes wrong, a description message will be returned.</returns>
|
||||
public static Task<string> LaunchAppByAppId(string appId, ApplicationOptions options = null)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<string>(CLIB.ppf_Application_LaunchOtherAppByAppID(appId, (IntPtr) options));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Launches the PICO Store app and go to the current app's details page.
|
||||
///
|
||||
/// You can direct user to the PICO Store to upgrade the installed app by this
|
||||
/// method. To judge whether there is a new version in the PICO Store, you can call
|
||||
/// \ref GetVersion.
|
||||
///
|
||||
/// @note
|
||||
/// * If the current app has never published in the PICO Store, the response error code is non-zero.
|
||||
/// * The current app will quit once the PICO Store app is launched.
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns>A string that describes the launch info.</returns>
|
||||
public static Task<string> LaunchStore()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<string>(CLIB.ppf_Application_LaunchStore());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the app's current version info and the latest version info.
|
||||
///
|
||||
/// You can compare the current version info and the latest version info, and
|
||||
/// then decide whether to call \ref LaunchStore to direct users to the current app's details page to upgrade the app.
|
||||
/// </summary>
|
||||
/// <returns>The response will contain the latest version info in the PICO Store
|
||||
/// and the app's current version info.
|
||||
/// </returns>
|
||||
public static Task<ApplicationVersion> GetVersion()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<ApplicationVersion>(CLIB.ppf_Application_GetVersion());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the details about an app launch event.
|
||||
/// </summary>
|
||||
/// <returns>App launch details, including `LaunchResult` and `LaunchType`:
|
||||
/// * `LaunchResult`:
|
||||
/// * `0`: Unknown
|
||||
/// * `1`: Success
|
||||
/// * `2`: FailedRoomFull
|
||||
/// * `3`: FailedGameAlreadyStarted
|
||||
/// * `4`: FailedRoomNotFound
|
||||
/// * `5`: FailedUserDeclined
|
||||
/// * `6`: FailedOtherReason
|
||||
/// * `LaunchType`:
|
||||
/// * `0`: Unknown
|
||||
/// * `1`: Normal
|
||||
/// * `2`: Invite
|
||||
/// * `3`: Coordinated
|
||||
/// * `4`: Deeplink
|
||||
/// </returns>
|
||||
public static LaunchDetails GetLaunchDetails()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new LaunchDetails(CLIB.ppf_ApplicationLifecycle_GetLaunchDetails());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the device's system information synchronously.
|
||||
/// </summary>
|
||||
/// <returns>A structure contains the device's system information, including the device's system version, language code,
|
||||
/// country/region code, product name, and more.</returns>
|
||||
public static SystemInfo GetSystemInfo()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new SystemInfo(CLIB.ppf_Application_GetSystemInfo());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs whether a user has been successfully directed to the desired destination via a deep link.
|
||||
/// </summary>
|
||||
/// <param name="trackId">The tracking ID of the app launch event.</param>
|
||||
/// <param name="result">The app launch result:
|
||||
/// * `0`: Unknown
|
||||
/// * `1`: Success
|
||||
/// * `2`: FailedRoomFull
|
||||
/// * `3`: FailedGameAlreadyStarted
|
||||
/// * `4`: FailedRoomNotFound
|
||||
/// * `5`: FailedUserDeclined
|
||||
/// * `6`: FailedOtherReason
|
||||
/// </param>
|
||||
public static void LogDeeplinkResult(string trackId, LaunchResult result)
|
||||
{
|
||||
CLIB.ppf_ApplicationLifecycle_LogDeeplinkResult(trackId, result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When the launch intent is changed, you will receive this notification.
|
||||
/// Then you can call \ref GetLaunchDetails to retrieve the launch details.
|
||||
/// </summary>
|
||||
/// <param name="callback">The callback function.</param>
|
||||
public static void SetLaunchIntentChangedCallback(Message<string>.Handler callback)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_ApplicationLifecycle_LaunchIntentChanged, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ApplicationOptions
|
||||
{
|
||||
public ApplicationOptions()
|
||||
{
|
||||
Handle = CLIB.ppf_ApplicationOptions_Create();
|
||||
}
|
||||
|
||||
|
||||
public void SetDeeplinkMessage(string value)
|
||||
{
|
||||
CLIB.ppf_ApplicationOptions_SetDeeplinkMessage(Handle, value);
|
||||
}
|
||||
|
||||
/// For passing to native C
|
||||
public static explicit operator IntPtr(ApplicationOptions options)
|
||||
{
|
||||
return options?.Handle ?? IntPtr.Zero;
|
||||
}
|
||||
|
||||
~ApplicationOptions()
|
||||
{
|
||||
CLIB.ppf_ApplicationOptions_Destroy(Handle);
|
||||
}
|
||||
|
||||
readonly IntPtr Handle;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d95f2760768458048bb7e3ea645369ef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,251 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
*
|
||||
* Downloadable content (DLC) represents the contents/files such as expansion packs that users can purchase and download, which can help grow your revenue. Each DLC is associated with an add-on and has an individual SKU as its unique identifier. Users must purchase the app before purchasing the DLCs provided in it. DLCs are downloadable in apps only.
|
||||
*
|
||||
* DLC enables you to update your app in a more flexible and lightweight way. Once you want to update the content for a published app, you only need to upload new resources such as levels and cosmetics as DLCs on the PICO Developer Platform, but do not need to upload a new build. Users can thereby purchase, download, and experience the latest resources without having to update or reinstall your app.
|
||||
*/
|
||||
public static class AssetFileService
|
||||
{
|
||||
/// <summary>
|
||||
/// Deletes an installed asset file by asset file ID. The corresponding
|
||||
/// asset file will be removed from the device.
|
||||
/// </summary>
|
||||
/// <param name="assetFileId">The ID of the asset file to delete.</param>
|
||||
/// <returns>
|
||||
/// An object containing the asset file ID, asset file name, and a success flag.
|
||||
/// </returns>
|
||||
public static Task<AssetFileDeleteResult> DeleteById(ulong assetFileId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<AssetFileDeleteResult>(CLIB.ppf_AssetFile_DeleteById(assetFileId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes an installed asset file by asset file name. The corresponding
|
||||
/// asset file will be removed from the device.
|
||||
/// </summary>
|
||||
/// <param name="assetFileName">The name of the asset file to delete.</param>
|
||||
/// <returns>
|
||||
/// An object containing the asset file ID, asset file name, and a success flag.
|
||||
/// </returns>
|
||||
public static Task<AssetFileDeleteResult> DeleteByName(string assetFileName)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<AssetFileDeleteResult>(CLIB.ppf_AssetFile_DeleteByName(assetFileName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Downloads an asset file by asset file ID.
|
||||
/// </summary>
|
||||
/// <param name="assetFileId">The ID of the asset file to download.</param>
|
||||
/// <returns>
|
||||
/// An object containing the asset file ID and asset file name.
|
||||
///
|
||||
/// If the response returns code `0`, the download will start and
|
||||
/// the system will periodically push information about the download progress.
|
||||
/// If the user has not purchased the asset file, a non-zero error code will be returned.
|
||||
/// </returns>
|
||||
public static Task<AssetFileDownloadResult> DownloadById(ulong assetFileId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<AssetFileDownloadResult>(CLIB.ppf_AssetFile_DownloadById(assetFileId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Downloads an asset file by asset file name.
|
||||
/// </summary>
|
||||
/// <param name="assetFileName">The name of the asset file to download.</param>
|
||||
/// <returns>
|
||||
/// An object containing the asset file ID and asset file name.
|
||||
///
|
||||
/// If the response returns code `0`, the download will start and
|
||||
/// the system will periodically push information about the download progress.
|
||||
/// If the user has not purchased the asset file, a non-zero error code will be returned.
|
||||
/// </returns>
|
||||
public static Task<AssetFileDownloadResult> DownloadByName(string assetFileName)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<AssetFileDownloadResult>(CLIB.ppf_AssetFile_DownloadByName(assetFileName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancels the download of an asset file by asset file ID.
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="assetFileId">The ID of the asset file to cancel download for.</param>
|
||||
/// <returns>
|
||||
/// An object contains the asset file ID, asset file name, and a success flag.
|
||||
/// </returns>
|
||||
public static Task<AssetFileDownloadCancelResult> DownloadCancelById(ulong assetFileId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<AssetFileDownloadCancelResult>(CLIB.ppf_AssetFile_DownloadCancelById(assetFileId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancels the download of an asset file by asset file name.
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="assetFileName">The name of the asset file to cancel download for.</param>
|
||||
/// <returns>
|
||||
/// An object contains the asset file ID, asset file name, and a success flag.
|
||||
/// </returns>
|
||||
public static Task<AssetFileDownloadCancelResult> DownloadCancelByName(string assetFileName)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<AssetFileDownloadCancelResult>(CLIB.ppf_AssetFile_DownloadCancelByName(assetFileName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the download status of an asset file by asset file ID.
|
||||
/// </summary>
|
||||
/// <param name="assetId">The ID of the asset file to get the download status for.</param>
|
||||
/// <returns>
|
||||
/// An object containing the asset file ID, asset file name, and whether the asset file is downloaded.
|
||||
/// </returns>
|
||||
public static Task<AssetStatus> StatusById(ulong assetId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<AssetStatus>(CLIB.ppf_AssetFile_StatusById(assetId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the download status of an asset file by asset file name.
|
||||
/// </summary>
|
||||
/// <param name="assetFileName">The name of the asset file to get the download status for.</param>
|
||||
/// <returns>
|
||||
/// An object containing the asset file ID, asset file name, and whether the asset file is downloaded.
|
||||
/// </returns>
|
||||
public static Task<AssetStatus> StatusByName(string assetFileName)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<AssetStatus>(CLIB.ppf_AssetFile_StatusByName(assetFileName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the asset file list.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An asset file list. Each `AssetDetails` contains fields indicating
|
||||
/// whether an asset file is purchased or downloaded.
|
||||
/// </returns>
|
||||
public static Task<AssetDetailsList> GetList()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<AssetDetailsList>(CLIB.ppf_AssetFile_GetList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next page of the asset file list.
|
||||
/// </summary>
|
||||
/// <param name="list">The current page of the asset file list.</param>
|
||||
/// <returns>The next page of the asset file list.</returns>
|
||||
public static Task<AssetDetailsList> GetNextAssetDetailsListPage(AssetDetailsList list)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!list.HasNextPage)
|
||||
{
|
||||
Debug.LogWarning("GetNextAssetDetailsListPage: List has no next page");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(list.NextPageParam))
|
||||
{
|
||||
Debug.LogWarning("GetNextAssetDetailsListPage: list.NextPageParam is empty");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<AssetDetailsList>(CLIB.ppf_AssetFile_GetNextAssetDetailsArrayPage(list.NextPageParam));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This notification is used to track the download progress of asset file.
|
||||
/// The `Transferred` field indicates the number of bytes downloaded.
|
||||
/// The `CompleteStatus` field indicates the download status.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback function.</param>
|
||||
public static void SetOnDownloadUpdateCallback(Message<AssetFileDownloadUpdate>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_AssetFile_DownloadUpdate, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the downloaded asset file is different from the original one,
|
||||
/// the asset file will be automatically removed, and the app will receive a notification.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback function.</param>
|
||||
public static void SetOnDeleteForSafetyCallback(Message<AssetFileDeleteForSafety>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_AssetFile_DeleteForSafety, handler);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b713a81e59d43a3a50d0dc59b3fda40
|
||||
timeCreated: 1661772509
|
@ -0,0 +1,232 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
*
|
||||
* Challenges create fun-to-join competitions among users, which
|
||||
* can therefore provide users with more opportunities to interact
|
||||
* with others. Challenges are asynchronous events, so users do not
|
||||
* have to be online and do challenges at the same time.
|
||||
|
||||
* Both you and your app's users are able to create challenges,
|
||||
* configure challenge settings (including name, visibility, start
|
||||
* time, and end time), and invite friends to join challenges to
|
||||
* have fun together. Users can also join the challenges created
|
||||
* by PICO.
|
||||
*/
|
||||
public static class ChallengesService
|
||||
{
|
||||
/// <summary>Invites specified user(s).</summary>
|
||||
/// <param name="challengeID">The ID of the challenge to which user(s) are invited.</param>
|
||||
/// <param name="userID">The ID(s) of the user(s) to invite.</param>
|
||||
/// <returns>Returns the `Challenge` struct that contains the information about the challenge,
|
||||
/// such as challenge ID, the leaderboard the challenge belongs to, the challenge's end date and start date, etc.</returns>
|
||||
public static Task<Challenge> Invite(UInt64 challengeID, string[] userID)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Challenge>(CLIB.ppf_Challenges_Invites(challengeID, userID));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets the information for a specified challenge.</summary>
|
||||
/// <param name="challengeID">The ID of the challenge to get information for.</param>
|
||||
/// <returns>Returns the `Challenge` struct that contains the information about the challenge,
|
||||
/// such as challenge ID, the leaderboard the challenge belongs to, the challenge's end date and start date, etc.</returns>
|
||||
public static Task<Challenge> Get(UInt64 challengeID)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Challenge>(CLIB.ppf_Challenges_Get(challengeID));
|
||||
}
|
||||
|
||||
/// <summary>Gets a list of challenge entries.</summary>
|
||||
/// <param name="challengeID">The ID of the challenge whose entries are to be returned.</param>
|
||||
/// <param name="filter">Restricts the scope of entries to return:
|
||||
/// * `0`: None (returns all entries of the specified leaderboard)
|
||||
/// * `1`: Friends (returns the entries of the friends of the current logged-in user)
|
||||
/// * `2`: Unknown (returns no entry)
|
||||
/// * `3`: UserIds (returns the entries of specified users)
|
||||
/// </param>
|
||||
/// <param name="startAt">Defines where to start returning challenge entries, the enumerations are:
|
||||
/// * `0`: Top (return entries from top 1)
|
||||
/// * `1`: CenteredOnViewer (place the current logged-in user's entry in the middle of the list on the first page.
|
||||
/// For example, if the total number of entries is 10, `pageSize` is set to `5`, and the user's rank is top 5, the ranks displayed
|
||||
/// on the first page will be top 3, 4, 5, 6, and 7. Top 1 and 2 will not be displayed, and top 8, 9, and 10 will be
|
||||
/// displayed on the second page)
|
||||
/// * `2`: CenteredOnViewerOrTop (place the current logged-in user's entry on the top of the list on the first page.
|
||||
/// For example, if the total number of entries is 10, `pageSize` is set to `5`, and the user's rank is top 5,
|
||||
/// the ranks displayed on the first page will be top 5, 6, 7, 8, and 9. Top 1, 2, 3, and 4 will not be displayed,
|
||||
/// and top 10 will be displayed on the second page)
|
||||
/// * `3`: Unknown (returns an empty list)
|
||||
/// </param>
|
||||
/// <param name="pageIdx">Defines which page of entries to return. The first page index is `0`.
|
||||
/// For example, if you want to get the first page of entries, pass `0`; if you want to get the second page of entries, pass `1`.
|
||||
/// </param>
|
||||
/// <param name="pageSize">Defines the number of entries to return on the page.</param>
|
||||
/// <returns>Returns a list of matching entries.</returns>
|
||||
public static Task<ChallengeEntryList> GetEntries(UInt64 challengeID,
|
||||
LeaderboardFilterType filter, LeaderboardStartAt startAt, int pageIdx, int pageSize)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<ChallengeEntryList>(
|
||||
CLIB.ppf_Challenges_GetEntries(challengeID, filter, startAt, pageIdx, pageSize));
|
||||
}
|
||||
|
||||
/// <summary>Gets a list of challenge entries after a specified rank.</summary>
|
||||
/// <param name="challengeID">The ID of the challenge whose entries are to be returned.</param>
|
||||
/// <param name="afterRank">Defines the rank after which the entries are to be returned.</param>
|
||||
/// <param name="pageIdx">Defines which page of entries to return. The first page index is `0`.
|
||||
/// For example, if you want to get the first page of entries, pass `0`; if you want to get the second page of entries, pass `1`.
|
||||
/// </param>
|
||||
/// <param name="pageSize">Defines the number of entries to return on each page.</param>
|
||||
/// <returns>Returns a list of matching entries.</returns>
|
||||
public static Task<ChallengeEntryList> GetEntriesAfterRank(UInt64 challengeID,
|
||||
ulong afterRank, int pageIdx, int pageSize)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<ChallengeEntryList>(
|
||||
CLIB.ppf_Challenges_GetEntriesAfterRank(challengeID, afterRank, pageIdx, pageSize));
|
||||
}
|
||||
|
||||
/// <summary>Gets a list of challenge entries for specified users.</summary>
|
||||
/// <param name="challengeID">The ID of the challenge whose entries are to be returned.</param>
|
||||
/// <param name="startAt">Defines where to start returning challenge entries, the enumerations are:
|
||||
/// * `0`: Top (return entries from top 1)
|
||||
/// * `1`: CenteredOnViewer (place the current logged-in user's entry in the middle of the list on the first page.
|
||||
/// For example, if the total number of entries is 10, `pageSize` is set to `5`, and the user's rank is top 5, the ranks displayed
|
||||
/// on the first page will be top 3, 4, 5, 6, and 7. Top 1 and 2 will not be displayed, and top 8, 9, and 10 will be
|
||||
/// displayed on the second page)
|
||||
/// * `2`: CenteredOnViewerOrTop (place the current logged-in user's entry on the top of the list on the first page.
|
||||
/// For example, if the total number of entries is 10, `pageSize` is set to `5`, and the user's rank is top 5,
|
||||
/// the ranks displayed on the first page will be top 5, 6, 7, 8, and 9. Top 1, 2, 3, and 4 will not be displayed,
|
||||
/// and top 10 will be displayed on the second page)
|
||||
/// * `3`: Unknown (returns an empty list)
|
||||
/// </param>
|
||||
/// <param name="userIDs">Defines a list of user IDs to get entries for.</param>
|
||||
/// <param name="pageIdx">Defines which page of entries to return. The first page index is `0`.
|
||||
/// For example, if you want to get the first page of entries, pass `0`; if you want to get the second page of entries, pass `1`.
|
||||
/// </param>
|
||||
/// <param name="pageSize">Defines the number of entries to return on each page.</param>
|
||||
/// <returns>Returns a list of matching entries.</returns>
|
||||
public static Task<ChallengeEntryList> GetEntriesByIds(UInt64 challengeID,
|
||||
LeaderboardStartAt startAt, string[] userIDs, int pageIdx, int pageSize)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<ChallengeEntryList>(CLIB.ppf_Challenges_GetEntriesByIds(challengeID, startAt, userIDs, pageIdx, pageSize));
|
||||
}
|
||||
|
||||
/// <summary>Gets a list of challenges.</summary>
|
||||
/// <param name="challengeOptions">Restricts the scope of challenges to return. You can define the start date and
|
||||
/// end date of challenges, the leaderboard the challenges belong to, etc.
|
||||
/// </param>
|
||||
/// <param name="pageIdx">Defines which page of challenges to return. The first page index is `0`.
|
||||
/// For example, if you want to get the first page of entries, pass `0`; if you want to get the second page of entries, pass `1`.
|
||||
/// </param>
|
||||
/// <param name="pageSize">Defines the number of challenges to return on each page.</param>
|
||||
/// <returns>Returns a list of matching challenges.</returns>
|
||||
public static Task<ChallengeList> GetList(ChallengeOptions challengeOptions, int pageIdx, int pageSize)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<ChallengeList>(CLIB.ppf_Challenges_GetList((IntPtr) challengeOptions, pageIdx, pageSize));
|
||||
}
|
||||
|
||||
/// <summary>Lets the current user join a challenge.</summary>
|
||||
/// <param name="challengeID">The ID of the challenge to join.</param>
|
||||
/// <returns>Returns the `Challenge` struct that contains the information about the challenge,
|
||||
/// such as challenge ID, the leaderboard the challenge belongs to, the challenge's end date and start date, etc.</returns>
|
||||
public static Task<Challenge> Join(UInt64 challengeID)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Challenge>(CLIB.ppf_Challenges_Join(challengeID));
|
||||
}
|
||||
|
||||
/// <summary>Lets the current user leave a challenge.</summary>
|
||||
/// <param name="challengeID">The ID of the challenge to leave.</param>
|
||||
/// <returns>Returns the `Challenge` struct that contains the information about the challenge,
|
||||
/// such as challenge ID, the leaderboard the challenge belongs to, the challenge's end date and start date, etc.</returns>
|
||||
public static Task<Challenge> Leave(UInt64 challengeID)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Challenge>(CLIB.ppf_Challenges_Leave(challengeID));
|
||||
}
|
||||
|
||||
/// <summary>Launches the invitation flow to let the current user invite friends to a specified challenge.
|
||||
/// This launches the system default invite UI where all of the user's friends are displayed.
|
||||
/// This is intended to be a shortcut for developers not wanting to build their own invite-friends UI.</summary>
|
||||
/// <param name="challengeID">The ID of the challenge.</param>
|
||||
public static Task LaunchInvitableUserFlow(UInt64 challengeID)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Challenges_LaunchInvitableUserFlow(challengeID));
|
||||
}
|
||||
|
||||
/// <summary>Sets the callback to get notified when the user has accepted an invitation.
|
||||
/// @note You can get the ChallengeID by 'Message.Data'.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback function will be called when receiving the `Notification_Challenge_LaunchByInvite` message.</param>
|
||||
public static void SetChallengeInviteAcceptedOrLaunchAppNotificationCallback(Message<string>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Challenge_LaunchByInvite, handler);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31e084e3699a42aab6084064d4789f2d
|
||||
timeCreated: 1664349933
|
@ -0,0 +1,26 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
public class CloudStorageService
|
||||
{
|
||||
/// <summary>
|
||||
/// Starts cloud data backup whenever needed.
|
||||
/// </summary>
|
||||
/// <returns>Returns nothing for a success, otherwise returns error information.</returns>
|
||||
public static Task StartNewBackup()
|
||||
{
|
||||
return new Task(CLIB.ppf_CloudStorage_StartNewBackup());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca8e54478ee44174dac9eb355d755c7f
|
||||
timeCreated: 1679484591
|
@ -0,0 +1,47 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
* Application or games need comply with the laws where they distributes. So developers
|
||||
* should take compliance into consideration. This module provides some useful methods
|
||||
* to implement compliance.
|
||||
*/
|
||||
public static class ComplianceService
|
||||
{
|
||||
/// <summary>
|
||||
/// Detects sensitive words in texts.
|
||||
/// </summary>
|
||||
/// <param name="scene">Indicates where the text appears. For example, the text can appear in a username, room name, in-room chat, etc.</param>
|
||||
/// <param name="content">The text to check, which can be a username, room-chat message, etc.</param>
|
||||
/// <returns>
|
||||
/// Whether the text contains sensitive words. If it contains, the app should not allow
|
||||
/// the user to publish the text and can take the strategy proposed by the
|
||||
/// result.
|
||||
/// </returns>
|
||||
public static Task<DetectSensitiveResult> DetectSensitive(DetectSensitiveScene scene, string content)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<DetectSensitiveResult>(CLIB.ppf_Compliance_DetectSensitive(scene, content));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18f2fcae6c334637ae67cdb01c26dab2
|
||||
timeCreated: 1679567015
|
@ -0,0 +1,256 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Pico.Platform.Framework;
|
||||
using Unity.XR.PXR;
|
||||
using UnityEngine;
|
||||
|
||||
[assembly: InternalsVisibleTo("Assembly-CSharp-Editor")]
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \defgroup Platform Services
|
||||
*/
|
||||
/**
|
||||
* \ingroup Platform
|
||||
*
|
||||
*/
|
||||
public static class CoreService
|
||||
{
|
||||
public static bool Initialized = false;
|
||||
public static string NotInitializedError = "Platform SDK has not been initialized!";
|
||||
|
||||
/// <summary>Gets whether the Platform SDK has been initialized.</summary>
|
||||
/// <returns>
|
||||
/// * `true`: initialized
|
||||
/// * `false`: not initialized
|
||||
/// </returns>
|
||||
public static bool IsInitialized()
|
||||
{
|
||||
return Initialized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the app ID for the current app.
|
||||
/// </summary>
|
||||
/// <returns>The app ID.</returns>
|
||||
/// <exception cref="UnityException">If the app ID cannot be found, this exception will be thrown.</exception>
|
||||
public static string GetAppID(string appId = null)
|
||||
{
|
||||
string configAppID = PXR_PlatformSetting.Instance.appID.Trim();
|
||||
if (!string.IsNullOrWhiteSpace(appId) && !string.IsNullOrWhiteSpace(configAppID) && appId != configAppID)
|
||||
{
|
||||
throw new UnityException("The parameter appId is inconsistent with the configured appId");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(appId))
|
||||
{
|
||||
return appId;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(configAppID))
|
||||
{
|
||||
return configAppID;
|
||||
}
|
||||
|
||||
throw new UnityException("Cannot find appId");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the Platform SDK asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="appId">The app ID for the Platform SDK. If not provided, Unity editor configuration will be applied.</param>
|
||||
/// <returns>The initialization result.</returns>
|
||||
/// <exception cref="UnityException">If the input app ID is null or empty or if the initialization fails, this exception will be thrown.</exception>
|
||||
/// <exception cref="NotImplementedException">If the current platform is not supported, this exception will be thrown.</exception>
|
||||
public static Task<PlatformInitializeResult> AsyncInitialize(string appId = null)
|
||||
{
|
||||
if (Initialized)
|
||||
{
|
||||
return new Task<PlatformInitializeResult>(0);
|
||||
}
|
||||
|
||||
appId = GetAppID(appId);
|
||||
if (String.IsNullOrWhiteSpace(appId))
|
||||
{
|
||||
throw new UnityException("AppID cannot be null or empty");
|
||||
}
|
||||
|
||||
Task<PlatformInitializeResult> task;
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
|
||||
var requestId = CLIB.ppf_InitializeAndroidAsynchronous(appId, activity.GetRawObject(), IntPtr.Zero);
|
||||
if (requestId == 0)
|
||||
{
|
||||
throw new Exception("PICO PlatformSDK failed to initialize");
|
||||
}
|
||||
|
||||
task = new Task<PlatformInitializeResult>(requestId);
|
||||
}
|
||||
else if ((Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor))
|
||||
{
|
||||
var config = Resources.Load<TextAsset>("PicoSdkPCConfig");
|
||||
var logDirectory = Path.GetFullPath("Logs");
|
||||
if (config == null)
|
||||
{
|
||||
throw new UnityException($"cannot find PC config file Resources/PicoSdkPCConfig");
|
||||
}
|
||||
|
||||
if (!Directory.Exists(logDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(logDirectory);
|
||||
}
|
||||
|
||||
var requestId = CLIB.ppf_PcInitAsynchronousWrapper(appId, config.text, logDirectory);
|
||||
if (requestId == 0)
|
||||
{
|
||||
throw new Exception("PICO PlatformSDK failed to initialize");
|
||||
}
|
||||
else
|
||||
{
|
||||
task = new Task<PlatformInitializeResult>(requestId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException("PICO platform is not implemented on this platform yet.");
|
||||
}
|
||||
|
||||
Initialized = true;
|
||||
Runner.RegisterGameObject();
|
||||
return task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the Platform SDK synchronously.
|
||||
/// </summary>
|
||||
/// <param name="appId">The app ID for the Platform SDK. If not provided, Unity editor configuration will be applied.</param>
|
||||
/// <exception cref="NotImplementedException">If the current platform is not supported, this exception will be thrown.</exception>
|
||||
/// <exception cref="UnityException">If the initialization fails, this exception will be thrown.</exception>
|
||||
public static void Initialize(string appId = null)
|
||||
{
|
||||
if (Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
appId = GetAppID(appId);
|
||||
if (String.IsNullOrWhiteSpace(appId))
|
||||
{
|
||||
throw new UnityException("AppID must not be null or empty");
|
||||
}
|
||||
|
||||
PlatformInitializeResult initializeResult;
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
|
||||
|
||||
initializeResult = CLIB.ppf_InitializeAndroid(appId, activity.GetRawObject(), IntPtr.Zero);
|
||||
|
||||
if (initializeResult == PlatformInitializeResult.Success ||
|
||||
initializeResult == PlatformInitializeResult.AlreadyInitialized)
|
||||
{
|
||||
Initialized = true;
|
||||
}
|
||||
}
|
||||
else if ((Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor))
|
||||
{
|
||||
var config = Resources.Load<TextAsset>("PicoSdkPCConfig");
|
||||
if (config == null)
|
||||
{
|
||||
throw new UnityException($"cannot find PC config file Resources/PicoSdkPCConfig");
|
||||
}
|
||||
|
||||
var logDirectory = Path.GetFullPath("Logs");
|
||||
if (!Directory.Exists(logDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(logDirectory);
|
||||
}
|
||||
|
||||
initializeResult = CLIB.ppf_PcInitWrapper(appId, config.text, logDirectory);
|
||||
if (initializeResult == PlatformInitializeResult.Success ||
|
||||
initializeResult == PlatformInitializeResult.AlreadyInitialized)
|
||||
{
|
||||
Initialized = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException("PICO platform is not implemented on this platform yet.");
|
||||
}
|
||||
|
||||
if (!Initialized)
|
||||
{
|
||||
throw new UnityException($"PICO Platform failed to initialize:{initializeResult}.");
|
||||
}
|
||||
|
||||
Runner.RegisterGameObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* \overload Task<GameInitializeResult> GameInitialize(string accessToken)
|
||||
*/
|
||||
/// <summary>
|
||||
/// Initializes game-related modules, such as room, matchmaking, and network.
|
||||
/// </summary>
|
||||
/// <param name="accessToken">The access token of Platform SDK. You can get the access token by calling `UserService.GetAccessToken()`.</param>
|
||||
public static Task<GameInitializeResult> GameInitialize(string accessToken)
|
||||
{
|
||||
if (Initialized)
|
||||
{
|
||||
return new Task<GameInitializeResult>(CLIB.ppf_Game_InitializeWithToken(accessToken));
|
||||
}
|
||||
|
||||
Debug.LogError(NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* \overload Task<GameInitializeResult> GameInitialize()
|
||||
*/
|
||||
/// <summary>
|
||||
/// Initializes modules without token related with game, such as room, matchmaking, and net.
|
||||
/// </summary>
|
||||
public static Task<GameInitializeResult> GameInitialize()
|
||||
{
|
||||
if (Initialized)
|
||||
{
|
||||
return new Task<GameInitializeResult>(CLIB.ppf_Game_InitializeAuto());
|
||||
}
|
||||
|
||||
Debug.LogError(NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uninitializes game-related modules, such as room, matchmaking, and network.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool GameUninitialize()
|
||||
{
|
||||
if (Initialized)
|
||||
{
|
||||
return CLIB.ppf_Game_UnInitialize();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 496980589199efc479aff90a62629be7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,139 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
public class HighlightService
|
||||
{
|
||||
/// <summary>
|
||||
/// Starts a new session. Before using screen recording and capturing-related functions, make sure you are in a session.
|
||||
/// </summary>
|
||||
/// <returns>The session ID, which is a string.</returns>
|
||||
public static Task<string> StartSession()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<string>(CLIB.ppf_Highlight_StartSession());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Captures the screen.
|
||||
/// </summary>
|
||||
/// <returns>The information about this capture, including image path and job ID.</returns>
|
||||
public static Task<CaptureInfo> CaptureScreen()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<CaptureInfo>(CLIB.ppf_Highlight_CaptureScreen());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts recording the screen.
|
||||
/// </summary>
|
||||
public static Task StartRecord()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Highlight_StartRecord());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops recording the screen.
|
||||
/// </summary>
|
||||
/// <returns>The infomraiton about this recording, including video path, video duration, video size, and job ID.</returns>
|
||||
public static Task<RecordInfo> StopRecord()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<RecordInfo>(CLIB.ppf_Highlight_StopRecord());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lists all the media resources for a session.
|
||||
/// </summary>
|
||||
/// <param name="sessionId">Passes the ID of the session which is returned by `StartSession`.</param>
|
||||
/// <returns>The information about the images captured and videos recorded during this session.</returns>
|
||||
public static Task<SessionMedia> ListMedia(string sessionId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<SessionMedia>(CLIB.ppf_Highlight_ListMedia(sessionId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves an image or a video to the device's local storage.
|
||||
/// </summary>
|
||||
/// <param name="jobId">Passes the ID of the screen-capturing or screen-recording task where the image or video is created.</param>
|
||||
/// <param name="sessionId">Passes the ID of the session where the task takes place.</param>
|
||||
/// <returns>The job ID and session ID of the image or video saved.</returns>
|
||||
public static Task SaveMedia(string jobId, string sessionId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Highlight_SaveMedia(jobId, sessionId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shares an image or a video to the social media on the mobile phone.
|
||||
/// </summary>
|
||||
/// <param name="jobId">Passes the ID of the screen-capturing or screen-recording task where the image or video is created.</param>
|
||||
/// <param name="sessionId">Passes the ID of the session where the task takes place.</param>
|
||||
/// <returns>The job ID and session ID of the image or video shared.</returns>
|
||||
public static Task ShareMedia(string jobId, string sessionId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Highlight_ShareMedia(jobId, sessionId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The maiximum duration for a video is 15 minutes.
|
||||
/// After the `StartRecord` function is called, if the `StopRecord` function is not called in time or if the recording is ended due to other causes, the system will automatically stop recording and return the recording information.
|
||||
/// </summary>
|
||||
/// <param name="handler">Returns the recording information.</param>
|
||||
public static void SetOnRecordStopHandler(Message<RecordInfo>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Highlight_OnRecordStop, handler);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49c5348fb263404a8d2d84556f274a40
|
||||
timeCreated: 1686138735
|
@ -0,0 +1,208 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
*
|
||||
* You can diversify user experience and grow your revenue by selling
|
||||
* products such as cosmetics, props, and coins/diamonds within your
|
||||
* app. The PICO Unity Integration SDK provides In-App Purchase (IAP)
|
||||
* service which enables users to purchase products within your app.
|
||||
* The IAP service packages a series of payments systems such as Alipay,
|
||||
* bank card, and Paypal, thereby providing you with a one-stop
|
||||
* multi-payment-method solution.
|
||||
*/
|
||||
public static class IAPService
|
||||
{
|
||||
/// <summary>
|
||||
/// Records the order fulfillment result for a consumable.
|
||||
/// @note Users are unable to repurchase the same comsumable until the previous order is fulfilled.
|
||||
/// </summary>
|
||||
/// <param name="sku">The SKU of the add-on to fulfill.</param>
|
||||
public static Task ConsumePurchase(string sku)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_IAP_ConsumePurchase(sku));
|
||||
}
|
||||
|
||||
/// <summary>Gets a list of purchasable add-ons in the current app.</summary>
|
||||
/// <param name="skus">The SKUs of the add-ons to retrieve. If this parameter is empty, all purchasable add-ons will be returned.</param>
|
||||
/// <returns>A list of purchasable add-ons with their information, including the description, price, SKU, and more.</returns>
|
||||
public static Task<ProductList> GetProductsBySKU(string[] skus)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (skus == null)
|
||||
{
|
||||
skus = Array.Empty<string>();
|
||||
}
|
||||
|
||||
return new Task<ProductList>(CLIB.ppf_IAP_GetProductsBySKU(skus));
|
||||
}
|
||||
|
||||
/// <summary>Gets a list of purchased add-ons for a user, including durables and unfilfilled consumables.</summary>
|
||||
/// <returns>A list of the user's purchased add-ons.</returns>
|
||||
public static Task<PurchaseList> GetViewerPurchases()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<PurchaseList>(CLIB.ppf_IAP_GetViewerPurchases());
|
||||
}
|
||||
|
||||
/// @deprecated LaunchCheckoutFlow(string sku,string price,string currency) can be replaced by \ref LaunchCheckoutFlow2(Product product)
|
||||
/// <summary>
|
||||
/// Launches the checkout flow for a user to make a payment.
|
||||
/// \note This method doesn't support subscription add-ons, you need to
|
||||
/// use \ref LaunchCheckoutFlow2 instead.
|
||||
/// </summary>
|
||||
/// <param name="sku">The SKU of the product the user wants to purchase.</param>
|
||||
/// <param name="price">The price for the product.</param>
|
||||
/// <param name="currency">The currency of the payment.</param>
|
||||
/// <returns>Returns the purchased product if the user successfully pays the money.
|
||||
/// Otherwise the purchase will be null. You can get the failure reason from the returned error code and error message.</returns>
|
||||
[Obsolete("Please use LaunchCheckoutFlow2(Product product)", false)]
|
||||
public static Task<Purchase> LaunchCheckoutFlow(string sku, string price, string currency)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Purchase>(CLIB.ppf_IAP_LaunchCheckoutFlow(sku, price, currency));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Launches the checkout flow for a user to make a payment.
|
||||
/// </summary>
|
||||
/// <param name="product">The add-on's information which can be acquired by \ref GetProductsBySKU.
|
||||
/// </param>
|
||||
/// <returns>Returns the purchased add-on if the user successfully makes the payment.
|
||||
/// Otherwise the purchase will be null. You can get the failure reason from the returned error code and error message.
|
||||
/// </returns>
|
||||
public static Task<Purchase> LaunchCheckoutFlow2(Product product)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Purchase>(CLIB.ppf_IAP_LaunchCheckoutFlowV2(product.SKU, product.Price, product.Currency, product.OuterId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Launches the checkout flow for a user to make a payment.
|
||||
/// </summary>
|
||||
/// <param name="product">The add-on's information which can be acquired by \ref GetProductsBySKU.
|
||||
/// </param>
|
||||
/// <param name="orderComment">The comment for the order. If the user successfully purchases this add-on,
|
||||
/// The order's comment can be accessed in \ref Purchase. The length of this field cannot exceed 1024 bytes in UTF-8 encoding.
|
||||
/// </param>
|
||||
/// <returns>Returns the purchased add-on if the user successfully makes the payment.
|
||||
/// Otherwise the purchase will be null. You can get the failure reason from the returned error code and error message.
|
||||
/// </returns>
|
||||
public static Task<Purchase> LaunchCheckoutFlow3(Product product, string orderComment)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Purchase>(CLIB.ppf_IAP_LaunchCheckoutFlowV3(product.SKU, product.Price, product.Currency, product.OuterId, orderComment));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the subscription status of a subscription add-on.
|
||||
/// </summary>
|
||||
/// <param name="sku">The SKU of the add-on.</param>
|
||||
/// <returns>
|
||||
/// The subscription status of the add-on. If the user is not entitled to access the add-on, the result will be an empty struct.
|
||||
/// </returns>
|
||||
public static Task<SubscriptionStatus> GetSubscriptionStatus(string sku)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<SubscriptionStatus>(CLIB.ppf_IAP_GetSubscriptionStatus(sku));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next page of purchasable add-ons.
|
||||
/// </summary>
|
||||
/// <param name="list">The current page of purchasable add-ons.</param>
|
||||
/// <returns>The next page of purchasable add-ons.</returns>
|
||||
public static Task<ProductList> GetNextProductListPage(ProductList list)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!list.HasNextPage)
|
||||
{
|
||||
Debug.LogWarning("Pico.Platform.GetNextProductListPage: List has no next page");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<ProductList>(
|
||||
CLIB.ppf_IAP_GetNextProductArrayPage(list.NextPageParam)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next page of purchased add-ons.
|
||||
/// </summary>
|
||||
/// <param name="list">The current page of purchased add-ons.</param>
|
||||
/// <returns>The next page of purchased add-ons.</returns>
|
||||
public static Task<PurchaseList> GetNextPurchaseListPage(PurchaseList list)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!list.HasNextPage)
|
||||
{
|
||||
Debug.LogWarning("Pico.Platform.GetNextPurchaseListPage: List has no next page");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<PurchaseList>(CLIB.ppf_IAP_GetNextPurchaseArrayPage(list.NextPageParam));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e074c6a46e5d441b80ada0813183cb79
|
||||
timeCreated: 1655278625
|
@ -0,0 +1,275 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
* Leaderboard is one of the basic and important features of an app.
|
||||
* By displaying users' rankings in a multi-dimensional approach, leaderboards can give rise to a competitive atmosphere among users in specific scenarios such as gaming, drive users to improve their skills, and therefore increase app engagement. You can also use leaderboards to promote the app and attract new users.
|
||||
* Currently, Leaderboard service offers the following key features:
|
||||
* * Create leaderboards
|
||||
* * Get leaderboard data
|
||||
* * Update leaderboard data
|
||||
*/
|
||||
public static class LeaderboardService
|
||||
{
|
||||
/// <summary>Gets the information for a specified leaderboard.</summary>
|
||||
///
|
||||
/// <param name="leaderboardName">The name of the leaderboard to get information for.</param>
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `LeaderboardList`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |10701|request server failed|
|
||||
/// |10703|checking parameter failed|
|
||||
/// |10704|leaderboard is not exist|
|
||||
///
|
||||
/// A message of type `MessageType.Leaderboard_Get` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `LeaderboardList`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<LeaderboardList> Get(string leaderboardName)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<LeaderboardList>(CLIB.ppf_Leaderboard_Get(leaderboardName));
|
||||
}
|
||||
|
||||
/// <summary>Gets a list of entries.</summary>
|
||||
///
|
||||
/// <param name="leaderboardName">The name of the leaderboard whose entries are to be returned.</param>
|
||||
/// <param name="pageSize">The number of entries to return on each page.</param>
|
||||
/// <param name="pageIdx">Defines which page of entries to return. The first page index is `0`.
|
||||
/// For example, if you want to get the first page of entries, pass `0`; if you want to get the second page of entries, pass `1`.
|
||||
/// </param>
|
||||
/// <param name="filter">Restricts the scope of entries to return:
|
||||
/// * `0`: None (returns all entries of the specified leaderboard)
|
||||
/// * `1`: Friends (returns the entries of the friends of the current logged-in user)
|
||||
/// * `2`: Unknown (returns no entry)
|
||||
/// * `3`: UserIds (returns the entries of specified users)
|
||||
/// </param>
|
||||
/// <param name="startAt">Defines where to start returning leaderboard entries, the enumerations are:
|
||||
/// * `0`: Top (return entries from top 1)
|
||||
/// * `1`: CenteredOnViewer (place the current logged-in user's entry in the middle of the list on the first page.
|
||||
/// For example, if the total number of entries is 10, `pageSize` is set to `5`, and the user's rank is top 5, the ranks displayed
|
||||
/// on the first page will be top 3, 4, 5, 6, and 7. Top 1 and 2 will not be displayed, and top 8, 9, and 10 will be
|
||||
/// displayed on the second page)
|
||||
/// * `2`: CenteredOnViewerOrTop (place the current logged-in user's entry on the top of the list on the first page.
|
||||
/// For example, if the total number of entries is 10, `pageSize` is set to `5`, and the user's rank is top 5,
|
||||
/// the ranks displayed on the first page will be top 5, 6, 7, 8, and 9. Top 1, 2, 3, and 4 will not be displayed,
|
||||
/// and top 10 will be displayed on the second page)
|
||||
/// * `3`: Unknown (returns an empty list)
|
||||
/// </param>
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `LeaderboardEntryList`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006501|request server failed|
|
||||
/// |3006503|checking parameter failed|
|
||||
/// |3006504|leaderboard is not exist|
|
||||
/// |3006506|load leaderboard data failed|
|
||||
/// |3006509|get friend failed|
|
||||
/// |3006510|get user account failed|
|
||||
///
|
||||
/// A message of type `MessageType.Leaderboard_GetEntries` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `LeaderboardEntryList`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<LeaderboardEntryList> GetEntries(string leaderboardName, int pageSize, int pageIdx, LeaderboardFilterType filter, LeaderboardStartAt startAt)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<LeaderboardEntryList>(CLIB.ppf_Leaderboard_GetEntries(leaderboardName, pageSize, pageIdx, filter, startAt));
|
||||
}
|
||||
|
||||
/// <summary>Gets a list of entries after a specified rank.</summary>
|
||||
///
|
||||
/// <param name="leaderboardName">The name of the leaderboard whose entries are to be returned.</param>
|
||||
/// <param name="pageSize">The number of entries to return on each page.</param>
|
||||
/// <param name="pageIdx">Defines which page of entries to return. The first page index is `0`.
|
||||
/// For example, if you want to get the first page of entries, pass `0`; if you want to get the second page of entries, pass `1`.
|
||||
/// </param>
|
||||
/// <param name="afterRank">Defines after which rank to return entries.</param>
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `LeaderboardEntryList`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |10701|request server failed|
|
||||
/// |10703|checking parameter failed|
|
||||
/// |10704|leaderboard is not exist|
|
||||
/// |10706|load leaderboard data failed|
|
||||
/// |10709|get friend failed|
|
||||
/// |10710|get user account failed|
|
||||
///
|
||||
/// A message of type `MessageType.Leaderboard_GetEntriesAfterRank` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `LeaderboardEntryList`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<LeaderboardEntryList> GetEntriesAfterRank(string leaderboardName, int pageSize, int pageIdx,
|
||||
ulong afterRank)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<LeaderboardEntryList>(
|
||||
CLIB.ppf_Leaderboard_GetEntriesAfterRank(leaderboardName, pageSize, pageIdx, afterRank));
|
||||
}
|
||||
|
||||
/// <summary>Gets a list of entries for specified users.</summary>
|
||||
///
|
||||
/// <param name="leaderboardName">The name of the leaderboard whose entries are to be returned.</param>
|
||||
/// <param name="pageSize">The number of entries to return on each page.</param>
|
||||
/// <param name="pageIdx">Defines which page of entries to return. The first page index is `0`.
|
||||
/// For example, if you want to get the first page of entries, pass `0`; if you want to get the second page of entries, pass `1`.
|
||||
/// </param>
|
||||
/// <param name="startAt">Defines where to start returning leaderboard entries, the enumerations are:
|
||||
/// * `0`: Top (return entries from top 1)
|
||||
/// * `1`: CenteredOnViewer (place the current logged-in user's entry in the middle of the list on the first page.
|
||||
/// For example, if the total number of entries is 10, `pageSize` is set to `5`, and the user's rank is top 5, the ranks displayed
|
||||
/// on the first page will be top 3, 4, 5, 6, and 7. Top 1 and 2 will not be displayed, and top 8, 9, and 10 will be
|
||||
/// displayed on the second page)
|
||||
/// * `2`: CenteredOnViewerOrTop (place the current logged-in user's entry on the top of the list on the first page.
|
||||
/// For example, if the total number of entries is 10, `pageSize` is set to `5`, and the user's rank is top 5,
|
||||
/// the ranks displayed on the first page will be top 5, 6, 7, 8, and 9. Top 1, 2, 3, and 4 will not be displayed,
|
||||
/// and top 10 will be displayed on the second page)
|
||||
/// * `3`: Unknown (returns an empty list)
|
||||
/// </param>
|
||||
/// <param name="userIDs">The ID list of the users to get entries for.</param>
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `LeaderboardEntryList`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |10701|request server failed|
|
||||
/// |10703|checking parameter failed|
|
||||
/// |10704|leaderboard is not exist|
|
||||
/// |10706|load leaderboard data failed|
|
||||
/// |10709|get friend failed|
|
||||
/// |10710|get user account failed|
|
||||
///
|
||||
/// A message of type `MessageType.Leaderboard_GetEntriesByIds` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `LeaderboardEntryList`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<LeaderboardEntryList> GetEntriesByIds(string leaderboardName, int pageSize, int pageIdx,
|
||||
LeaderboardStartAt startAt, string[] userIDs)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<LeaderboardEntryList>(CLIB.ppf_Leaderboard_GetEntriesByIds(leaderboardName,
|
||||
pageSize, pageIdx, startAt, userIDs));
|
||||
}
|
||||
|
||||
/// <summary>Writes an entry to a leaderboard.</summary>
|
||||
///
|
||||
/// <param name="leaderboardName">The name of the leaderboard to write an entry to.</param>
|
||||
/// <param name="score">The score to write.</param>
|
||||
/// <param name="extraData">A 2KB custom data field that is associated with the leaderboard entry. This can be a game replay or anything that provides more details about the entry to the viewer.</param>
|
||||
/// <param name="forceUpdate">Defines whether to force update the score. If set to `true`, the score always updates even if it is not the user's best score.</param>
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `bool`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |10701|request server failed|
|
||||
/// |10703|checking parameter failed|
|
||||
/// |10704|leaderboard is not exist|
|
||||
/// |10705|no write permission|
|
||||
/// |10706|load leaderboard data failed|
|
||||
/// |10707|save leaderboard data failed|
|
||||
/// |10708|extra data too long|
|
||||
/// |10714|out of write time limit|
|
||||
///
|
||||
/// A message of type `MessageType.Leaderboard_WriteEntry` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `bool`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<bool> WriteEntry(string leaderboardName, long score, byte[] extraData = null,
|
||||
bool forceUpdate = false)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
GCHandle hobj = GCHandle.Alloc(extraData, GCHandleType.Pinned);
|
||||
IntPtr pobj = hobj.AddrOfPinnedObject();
|
||||
var result = new Task<bool>(CLIB.ppf_Leaderboard_WriteEntry(leaderboardName, score, pobj,
|
||||
(uint) (extraData != null ? extraData.Length : 0), forceUpdate));
|
||||
if (hobj.IsAllocated)
|
||||
hobj.Free();
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Writes an entry to a leaderboard. The entry can include the supplementary metric for tiebreakers.</summary>
|
||||
///
|
||||
/// <param name="leaderboardName">The name of the leaderboard to write an entry to.</param>
|
||||
/// <param name="score">The score to write.</param>
|
||||
/// <param name="supplementaryMetric">The metric that can be used for tiebreakers.</param>
|
||||
/// <param name="extraData">A 2KB custom data field that is associated with the leaderboard entry. This can be a game replay or anything that provides more details about the entry to the viewer.</param>
|
||||
/// <param name="forceUpdate">Defines whether to force update the score. If set to `true`, the score always updates even if it is not the user's best score.</param>
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `bool`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |10701|request server failed|
|
||||
/// |10703|checking parameter failed|
|
||||
/// |10704|leaderboard is not exist|
|
||||
/// |10705|no write permission|
|
||||
/// |10706|load leaderboard data failed|
|
||||
/// |10707|save leaderboard data failed|
|
||||
/// |10708|extra data too long|
|
||||
/// |10714|out of write time limit|
|
||||
///
|
||||
/// A message of type `MessageType.Leaderboard_WriteEntryWithSupplementaryMetric` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `bool`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<bool> WriteEntryWithSupplementaryMetric(string leaderboardName, long score,
|
||||
long supplementaryMetric, byte[] extraData = null, bool forceUpdate = false)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
GCHandle hobj = GCHandle.Alloc(extraData, GCHandleType.Pinned);
|
||||
IntPtr pobj = hobj.AddrOfPinnedObject();
|
||||
var result = new Task<bool>(CLIB.ppf_Leaderboard_WriteEntryWithSupplementaryMetric(leaderboardName, score,
|
||||
supplementaryMetric, pobj, (uint) (extraData != null ? extraData.Length : 0), forceUpdate));
|
||||
if (hobj.IsAllocated)
|
||||
hobj.Free();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: afa08af6e76749e1b2ccad3292287c4f
|
||||
timeCreated: 1655221139
|
@ -0,0 +1,482 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
*/
|
||||
public static class MatchmakingService
|
||||
{
|
||||
/// <summary>Reports the result of a skill-rating match.
|
||||
/// @note Applicable to the following matchmaking modes: Quickmatch, Browse (+ Skill Pool)</summary>
|
||||
///
|
||||
/// <param name="roomId">The room ID.</param>
|
||||
/// <param name="data">The key-value pairs.</param>
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message does not contain data.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006209|match result report: not in match|
|
||||
/// |3006210|match result report: error report data|
|
||||
/// |3006211|match result report: duplicate report|
|
||||
/// |3006212|match result report: conflict with other's report|
|
||||
///
|
||||
/// Only for pools with skill-based matchmaking.
|
||||
/// Call this method after calling `StartMatch()` to begin a skill-rating
|
||||
/// match. After the match finishes, the server will record the result and
|
||||
/// update the skill levels of all players involved based on the result. This
|
||||
/// method is insecure because, as a client API, it is susceptible to tampering
|
||||
/// and therefore cheating to manipulate skill ratings.
|
||||
///
|
||||
/// A message of type `MessageType.Matchmaking_ReportResultInsecure` will be generated in response.
|
||||
/// First call `Message.IsError()` to check if any error has occurred.
|
||||
/// This response has no payload. If no error has occurred, the request is successful.
|
||||
/// </returns>
|
||||
public static Task ReportResultsInsecure(UInt64 roomId, Dictionary<string, int> data)
|
||||
{
|
||||
KVPairArray kvarray = new KVPairArray((uint) data.Count);
|
||||
uint n = 0;
|
||||
foreach (var d in data)
|
||||
{
|
||||
var item = kvarray.GetElement(n);
|
||||
item.SetKey(d.Key);
|
||||
item.SetIntValue(d.Value);
|
||||
n++;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Matchmaking_ReportResultInsecure(roomId, kvarray.GetHandle(), kvarray.Size));
|
||||
}
|
||||
|
||||
/// <summary>Gets the matchmaking statistics for the current user.
|
||||
/// @note Applicable to the following matchmaking modes: Quickmatch, Browse</summary>
|
||||
///
|
||||
/// <param name="pool">The pool to look in.</param>
|
||||
/// <param name="maxLevel">(beta feature, don't use it)</param>
|
||||
/// <param name="approach">(beta feature, don't use it)</param>
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `MatchmakingStats`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006201|match enqueue: invalid pool name|
|
||||
/// |3006208|match enqueue: no skill|
|
||||
///
|
||||
///
|
||||
/// When given a pool, the system will look up the current user's wins, losses, draws and skill
|
||||
/// level. The skill level returned will be between `1` and the maximum level. The approach
|
||||
/// will determine how should the skill level rise toward the maximum level.
|
||||
///
|
||||
/// A message of type `MessageType.Matchmaking_GetStats` will be generated in response.
|
||||
/// First call `Message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `MatchmakingStats`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<MatchmakingStats> GetStats(string pool, uint maxLevel, MatchmakingStatApproach approach = MatchmakingStatApproach.Trailing)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<MatchmakingStats>(CLIB.ppf_Matchmaking_GetStats(pool, maxLevel, approach));
|
||||
}
|
||||
|
||||
/// <summary>Gets rooms by matchmakinging pool name.
|
||||
/// The user can join the room with `RoomService.Join2 to`or cancel the retrieval with `MatchmakingService.Cancel`.
|
||||
/// @note Applicable to the following matchmaking mode: Browse</summary>
|
||||
///
|
||||
/// <param name="pool">The matchmaking pool name you want to browse.</param>
|
||||
/// <param name="matchmakingOptions">(Optional) The matchmaking configuration of the browse request.</param>
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `MatchmakingBrowseResult`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006201|match enqueue: invalid pool name|
|
||||
/// |3006205|match browse: access denied|
|
||||
/// |3006207|match enqueue: invalid query key|
|
||||
///
|
||||
/// A message of type `MessageType.Matchmaking_Browse2` will be generated in response.
|
||||
/// First call `Message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `MatchmakingBrowseResult`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<MatchmakingBrowseResult> Browse2(string pool, MatchmakingOptions matchmakingOptions = null)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (matchmakingOptions == null)
|
||||
{
|
||||
return new Task<MatchmakingBrowseResult>(CLIB.ppf_Matchmaking_Browse2(pool, IntPtr.Zero));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Task<MatchmakingBrowseResult>(CLIB.ppf_Matchmaking_Browse2(pool, matchmakingOptions.GetHandle()));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets rooms by matchmakinging pool name and specify the page number and the number of pages per page.</summary>
|
||||
///
|
||||
/// <param name="pool">The matchmaking pool name you want to browse.</param>
|
||||
/// <param name="matchmakingOptions">(Optional) The matchmaking configuration of the browse request.</param>
|
||||
/// <param name="pageIndex">(Optional)Start page index.</param>
|
||||
/// <param name="pageSize">(Optional)the number of pages per page.</param>
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `MatchmakingBrowseResult`.
|
||||
///
|
||||
/// A message of type `MessageType.Matchmaking_Browse2CustomPage` will be generated in response.
|
||||
/// First call `Message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `MatchmakingBrowseResult`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<MatchmakingBrowseResult> Browse2ForCustomPage(string pool, MatchmakingOptions matchmakingOptions = null, int pageIndex = 0, int pageSize = 5)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (matchmakingOptions == null)
|
||||
{
|
||||
return new Task<MatchmakingBrowseResult>(CLIB.ppf_Matchmaking_Browse2CustomPage(pool, IntPtr.Zero, pageIndex, pageSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Task<MatchmakingBrowseResult>(CLIB.ppf_Matchmaking_Browse2CustomPage(pool, matchmakingOptions.GetHandle(), pageIndex, pageSize));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Cancels a matchmaking request. Call this function
|
||||
/// to cancel an enqueue request before a match
|
||||
/// is made. This is typically triggered when a user gives up waiting.
|
||||
/// If you do not cancel the request but the user goes offline, the user/room
|
||||
/// will be timed out according to the setting of reserved period on the PICO Developer Platform.
|
||||
/// @note Applicable to the following matchmaking modes: Quickmatch, Browse</summary>
|
||||
///
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message does not contain data.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006201|match enqueue: invalid pool name|
|
||||
/// |3006206|match cancel: not in match|
|
||||
/// |3006301|server error: unknown|
|
||||
///
|
||||
///
|
||||
/// A message of type `MessageType.Matchmaking_Cancel2` will be generated in response.
|
||||
/// Call `Message.IsError()` to check if any error has occurred.
|
||||
/// This response has no payload. If no error has occurred, the request is successful.
|
||||
/// </returns>
|
||||
public static Task Cancel()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Matchmaking_Cancel2());
|
||||
}
|
||||
|
||||
/// <summary>Creates a matchmaking room, then enqueues and joins it.
|
||||
/// @note Applicable to the following matchmaking modes: Quickmatch, Browse, Advanced (Can Users Create Rooms=`true`)</summary>
|
||||
///
|
||||
/// <param name="pool">The matchmaking pool to use, which is created on the PICO Developer Platform.</param>
|
||||
/// <param name="matchmakingOptions">(Optional) Additional matchmaking configuration for this request.</param>
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `MatchmakingEnqueueResultAndRoom`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006201|match enqueue: invalid pool name|
|
||||
/// |3006203|match create room: pool config not allow user create room|
|
||||
/// |3006207|match enqueue: invalid query key |
|
||||
/// |3006301|server error: unknown |
|
||||
/// |3006204|match enqueue: invalid room id(Assigned room id, present in this context, indicates an internal server error) |
|
||||
/// |3006103|invalid room(The room was found to be invalid when joining the room, which appears in this context, indicating an internal server error) |
|
||||
/// |3006102|duplicate join room(Duplicate joins are found when joining a room, which appears in this context, indicating an internal server error) |
|
||||
/// |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) |
|
||||
/// |3006105|illegal enter request(Illegal incoming requests, such as not in the allowed whitelist, appear in this context, indicating an internal server error) |
|
||||
/// |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)|
|
||||
///
|
||||
/// A message of type `MessageType.Matchmaking_CreateAndEnqueueRoom2` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `MatchmakingEnqueueResultAndRoom`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<MatchmakingEnqueueResultAndRoom> CreateAndEnqueueRoom2(string pool, MatchmakingOptions matchmakingOptions = null)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (matchmakingOptions == null)
|
||||
{
|
||||
return new Task<MatchmakingEnqueueResultAndRoom>(CLIB.ppf_Matchmaking_CreateAndEnqueueRoom2(pool, IntPtr.Zero));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Task<MatchmakingEnqueueResultAndRoom>(CLIB.ppf_Matchmaking_CreateAndEnqueueRoom2(pool, matchmakingOptions.GetHandle()));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Enqueues for an available matchmaking room to join.
|
||||
/// When the server finds a match, it will return a message of
|
||||
/// type `MessageType.Notification_Matchmaking_MatchFound`. You
|
||||
/// can join found matching rooms by calling `RoomService.Join2`.
|
||||
/// If you want to cancel the match early, you can use `MatchmakingService.Cancel`.
|
||||
/// @note Applicable to the following matchmaking mode: Quickmatch</summary>
|
||||
///
|
||||
/// <param name="pool">The matchmaking pool to use, which is defined on the PICO Developer Platform.</param>
|
||||
/// <param name="matchmakingOptions">(Optional) Match configuration for Enqueue.</param>
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `MatchmakingEnqueueResult`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006201|match enqueue: invalid pool name|
|
||||
/// |3006401|logic state checking failed|
|
||||
/// |3006207|match enqueue: invalid query key|
|
||||
/// |3006301|server error: unknown|
|
||||
///
|
||||
/// A message of type `MessageType.Matchmaking_Enqueue2` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `MatchmakingEnqueueResult`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<MatchmakingEnqueueResult> Enqueue2(string pool, MatchmakingOptions matchmakingOptions = null)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (matchmakingOptions == null)
|
||||
{
|
||||
return new Task<MatchmakingEnqueueResult>(CLIB.ppf_Matchmaking_Enqueue2(pool, IntPtr.Zero));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Task<MatchmakingEnqueueResult>(CLIB.ppf_Matchmaking_Enqueue2(pool, matchmakingOptions.GetHandle()));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Debugs the state of the current matchmaking pool queue.
|
||||
/// @note
|
||||
/// * This function should not be used in production.
|
||||
/// * Applicable to the following matchmaking modes: Quickmatch, Browse
|
||||
///
|
||||
/// </summary>
|
||||
///
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message will contain data of type `MatchmakingAdminSnapshot`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006201|match enqueue: invalid pool name|
|
||||
/// |3006301|server error: unknown |
|
||||
///
|
||||
/// A message of type `MessageType.Matchmaking_GetAdminSnapshot` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `MatchmakingAdminSnapshot`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<MatchmakingAdminSnapshot> GetAdminSnapshot()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<MatchmakingAdminSnapshot>(CLIB.ppf_Matchmaking_GetAdminSnapshot());
|
||||
}
|
||||
|
||||
/// <summary>Reports that a skill-rating match has started.
|
||||
/// You can use this method after joining the room.
|
||||
/// @note
|
||||
/// * This function is only for pools with skill-based matching.
|
||||
/// * Applicable to the following matchmaking modes: Quickmatch, Browse (+ Skill Pool)
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="roomId">The ID of the room you want to match.</param>
|
||||
/// <returns>Request information of type `Task`, including the request ID, and its response message does not contain data.
|
||||
///
|
||||
/// A message of type `MessageType.Matchmaking_StartMatch` will be generated in response.
|
||||
/// Call `message.IsError()` to check if any error has occurred.
|
||||
/// </returns>
|
||||
public static Task StartMatch(UInt64 roomId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Matchmaking_StartMatch(roomId));
|
||||
}
|
||||
|
||||
/// <summary>Sets the callback to get notified when a match has been found. For example,
|
||||
/// after calling `MatchmakingService.Enqueue`, when the match is successful, you will
|
||||
/// receive `Notification_Matchmaking_MatchFound`, and then execute the processing function
|
||||
/// set by this function.</summary>
|
||||
///
|
||||
/// <param name="handler">The callback function will be called when receiving the `Notification_Matchmaking_MatchFound` message.</param>
|
||||
public static void SetMatchFoundNotificationCallback(Message<Room>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Matchmaking_MatchFound, handler);
|
||||
}
|
||||
|
||||
/// <summary>A notification will be sent to the player after they have been kicked out of the matchmaking pool.
|
||||
/// Listen to the event to receive a message.</summary>
|
||||
///
|
||||
/// <param name="handler">The callback function will be called when receiving the `Matchmaking_Cancel2` message and the value of `requestID` is `0`.</param>
|
||||
public static void SetCancel2NotificationCallback(Message.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Matchmaking_Cancel2, handler);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class MatchmakingOptions
|
||||
{
|
||||
public MatchmakingOptions()
|
||||
{
|
||||
Handle = CLIB.ppf_MatchmakingOptions_Create();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the data store for a room.
|
||||
/// </summary>
|
||||
/// <param name="key">A unique identifier that maps to a value.</param>
|
||||
/// <param name="value">The data.</param>
|
||||
public void SetCreateRoomDataStore(string key, string value)
|
||||
{
|
||||
CLIB.ppf_MatchmakingOptions_SetCreateRoomDataStoreString(Handle, key, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the data store for a room.
|
||||
/// </summary>
|
||||
public void ClearCreateRoomDataStore()
|
||||
{
|
||||
CLIB.ppf_MatchmakingOptions_ClearCreateRoomDataStore(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a join policy for a room.
|
||||
/// </summary>
|
||||
/// <param name="value">The enumerations of join policy:
|
||||
/// * `0`: None
|
||||
/// * `1`: Everyone
|
||||
/// * `2`: FriendsOfMembers
|
||||
/// * `3`: FriendsOfOwner
|
||||
/// * `4`: InvitedUsers
|
||||
/// * `5`: Unknown
|
||||
/// </param>
|
||||
public void SetCreateRoomJoinPolicy(RoomJoinPolicy value)
|
||||
{
|
||||
CLIB.ppf_MatchmakingOptions_SetCreateRoomJoinPolicy(Handle, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the maximum number of users allowed for a room.
|
||||
/// </summary>
|
||||
/// <param name="value">The maximum number of users.</param>
|
||||
public void SetCreateRoomMaxUsers(uint value)
|
||||
{
|
||||
CLIB.ppf_MatchmakingOptions_SetCreateRoomMaxUsers(Handle, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets an integer data setting for a query of a matchmaking pool.
|
||||
/// </summary>
|
||||
/// <param name="key">A unique identifier that maps a value.</param>
|
||||
/// <param name="value">The data (integer).</param>
|
||||
public void SetEnqueueDataSettings(string key, int value)
|
||||
{
|
||||
CLIB.ppf_MatchmakingOptions_SetEnqueueDataSettingsInt(Handle, key, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a float data setting for a query of a matchmaking pool.
|
||||
/// </summary>
|
||||
/// <param name="key">A unique identifier that maps a value.</param>
|
||||
/// <param name="value">The data.</param>
|
||||
public void SetEnqueueDataSettings(string key, double value)
|
||||
{
|
||||
CLIB.ppf_MatchmakingOptions_SetEnqueueDataSettingsDouble(Handle, key, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a string data setting for a query of a matchmaking pool.
|
||||
/// </summary>
|
||||
/// <param name="key">A unique identifier that maps a value.</param>
|
||||
/// <param name="value">The data.</param>
|
||||
public void SetEnqueueDataSettings(string key, string value)
|
||||
{
|
||||
CLIB.ppf_MatchmakingOptions_SetEnqueueDataSettingsString(Handle, key, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears data settings for a query of a matchmaking pool.
|
||||
/// </summary>
|
||||
public void ClearEnqueueDataSettings()
|
||||
{
|
||||
CLIB.ppf_MatchmakingOptions_ClearEnqueueDataSettings(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets whether to return the debugging information.
|
||||
/// </summary>
|
||||
/// <param name="value">
|
||||
/// * `true`: return the debugging information with the response payload
|
||||
/// * `false`: do not return the debugging information
|
||||
/// </param>
|
||||
public void SetEnqueueIsDebug(bool value)
|
||||
{
|
||||
CLIB.ppf_MatchmakingOptions_SetEnqueueIsDebug(Handle, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the query for a matchmaking.
|
||||
/// </summary>
|
||||
/// <param name="value">The key of the target query.
|
||||
/// @note One matchmaking pool can include multiple queries which are created on the PICO Developer Platform.
|
||||
/// You can choose which query to use before starting a matchmaking.
|
||||
/// </param>
|
||||
public void SetEnqueueQueryKey(string value)
|
||||
{
|
||||
CLIB.ppf_MatchmakingOptions_SetEnqueueQueryKey(Handle, value);
|
||||
}
|
||||
|
||||
|
||||
/// For passing to native C
|
||||
public static explicit operator IntPtr(MatchmakingOptions matchmakingOptions)
|
||||
{
|
||||
return matchmakingOptions != null ? matchmakingOptions.Handle : IntPtr.Zero;
|
||||
}
|
||||
|
||||
~MatchmakingOptions()
|
||||
{
|
||||
CLIB.ppf_MatchmakingOptions_Destroy(Handle);
|
||||
}
|
||||
|
||||
IntPtr Handle;
|
||||
|
||||
public IntPtr GetHandle()
|
||||
{
|
||||
return Handle;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 51d1402fc42ddf141ba5d9bb9e470a26
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,194 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
*/
|
||||
public static class NetworkService
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads the messages from other users in the room.
|
||||
/// </summary>
|
||||
public static Packet ReadPacket()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
var handle = CLIB.ppf_Net_ReadPacket();
|
||||
if (handle == IntPtr.Zero)
|
||||
return null;
|
||||
return new Packet(handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends messages to a specified user. The maximum messaging frequency is 1000/s.
|
||||
/// </summary>
|
||||
/// <param name="userId">The ID of the user to send messages to.</param>
|
||||
/// <param name="bytes">The message length (in bytes). The maximum bytes allowed is 512.</param>
|
||||
/// <returns>
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool SendPacket(string userId, byte[] bytes)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
Debug.LogError("User ID is null or empty!");
|
||||
return false;
|
||||
}
|
||||
|
||||
GCHandle hobj = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
IntPtr pobj = hobj.AddrOfPinnedObject();
|
||||
var ok = CLIB.ppf_Net_SendPacket(userId, (UIntPtr) bytes.Length, pobj);
|
||||
if (hobj.IsAllocated)
|
||||
hobj.Free();
|
||||
return ok;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends messages to a specified user. The maximum messaging frequency is 1000/s.
|
||||
/// </summary>
|
||||
/// <param name="userId">The ID of the user to send messages to.</param>
|
||||
/// <param name="bytes">The message length (in bytes). The maximum bytes allowed is 512.</param>
|
||||
/// <param name="reliable">When `reliable` is set to `true`, messages between lost and resume will not be lost.
|
||||
/// The retention time is determined by the `reserve_period` parameter configured for the matchmaking pool, with a maximum of 1 minute.
|
||||
/// When `reliable` is set to `false`, this function works the same as the other `SendPacket` function.</param>
|
||||
/// <returns>
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool SendPacket(string userId, byte[] bytes, bool reliable)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
Debug.LogError("User ID is null or empty!");
|
||||
return false;
|
||||
}
|
||||
|
||||
GCHandle hobj = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
IntPtr pobj = hobj.AddrOfPinnedObject();
|
||||
var ok = CLIB.ppf_Net_SendPacket2(userId, (UIntPtr) bytes.Length, pobj, reliable);
|
||||
if (hobj.IsAllocated)
|
||||
{
|
||||
hobj.Free();
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends messages to other users in the room. The maximum messaging frequency is 1000/s.
|
||||
/// </summary>
|
||||
/// <param name="bytes">The message length (in bytes). The maximum bytes allowed is 512.</param>
|
||||
/// <returns>
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool SendPacketToCurrentRoom(byte[] bytes)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return false;
|
||||
}
|
||||
|
||||
GCHandle hobj = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
IntPtr pobj = hobj.AddrOfPinnedObject();
|
||||
var ok = CLIB.ppf_Net_SendPacketToCurrentRoom((UIntPtr) bytes.Length, pobj);
|
||||
if (hobj.IsAllocated)
|
||||
{
|
||||
hobj.Free();
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends messages to other users in the room. The maximum messaging frequency is 1000/s.
|
||||
/// </summary>
|
||||
/// <param name="bytes">The message length (in bytes). The maximum bytes allowed is 512.</param>
|
||||
/// <param name="reliable">When `reliable` is set to `true`, messages between lost and resume will not be lost.
|
||||
/// The retention time is determined by the `reserve_period` parameter configured for the matchmaking pool, with a maximum of 1 minute.
|
||||
/// When `reliable` is set to `false`, this function works the same as the other `SendPacketToCurrentRoom` function.</param>
|
||||
/// <returns>
|
||||
/// * `true`: success
|
||||
/// * `false`: failure
|
||||
/// </returns>
|
||||
public static bool SendPacketToCurrentRoom(byte[] bytes, bool reliable)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return false;
|
||||
}
|
||||
|
||||
GCHandle hobj = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
IntPtr pobj = hobj.AddrOfPinnedObject();
|
||||
var ok = CLIB.ppf_Net_SendPacketToCurrentRoom2((UIntPtr) bytes.Length, pobj, reliable);
|
||||
if (hobj.IsAllocated)
|
||||
hobj.Free();
|
||||
return ok;
|
||||
}
|
||||
|
||||
public static void SetPlatformGameInitializeAsynchronousCallback(Message<GameInitializeResult>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.PlatformGameInitializeAsynchronous, handler);
|
||||
}
|
||||
|
||||
/// <summary>Sets the callback to get notified when the game network fluctuates.
|
||||
/// Listen to this event to receive a relevant message. Use `Message.Data` to get the network situation in the game.</summary>
|
||||
///
|
||||
/// <param name="handler">Callback handler. The callback function will be called when receiving the `Notification_Game_ConnectionEvent` message and the value of `requestID` is `0`.</param>
|
||||
public static void SetNotification_Game_ConnectionEventCallback(Message<GameConnectionEvent>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Game_ConnectionEvent, handler);
|
||||
}
|
||||
|
||||
public static void SetNotification_Game_Request_FailedCallback(Message<GameRequestFailedReason>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Game_RequestFailed, handler);
|
||||
}
|
||||
|
||||
/// <summary>Sets the callback to get notified when the game state needs to be reset.
|
||||
/// Listen to this event to receive a relevant message. If you receive this message, you will need to reset your gaming state. For example,
|
||||
/// * If you are in a room before receiving this message, you will need to check and reset your room state after receving this message.
|
||||
/// * If you are in a matchmaking queue before receiving this message, you will need to check and reset your matchmaking state after receiving this message.</summary>
|
||||
///
|
||||
/// <param name="handler">Callback handler. The callback function will be called when receiving the "Notification_Game_StateReset" message and the value of `requestID` is `0`.</param>
|
||||
public static void SetNotification_Game_StateResetCallback(Message.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Game_StateReset, handler);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8590c499f74c2f346a273d23e44feadd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,64 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
*/
|
||||
public static class NotificationService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a list of all pending room invites for your app. For example, notifications that may have been sent before the user launches your app.
|
||||
/// </summary>
|
||||
/// <param name="pageIdx">Defines which page of pending room invites to return. The first page index is `0`.</param>
|
||||
/// <param name="pageSize">Defines the number of pending room invites returned on each page.</param>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message will contain data of type `RoomInviteNotificationList`.
|
||||
///
|
||||
/// A message of type `MessageType.Notification_GetRoomInvites` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `RoomInviteNotificationList`.
|
||||
/// Extract the payload from the message handle with `message.Data`.</returns>
|
||||
public static Task<RoomInviteNotificationList> GetRoomInviteNotifications(int pageIdx, int pageSize)
|
||||
{
|
||||
if (CoreService.IsInitialized())
|
||||
{
|
||||
return new Task<RoomInviteNotificationList>(CLIB.ppf_Notification_GetRoomInvites(pageIdx, pageSize));
|
||||
}
|
||||
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks a notification as read.
|
||||
/// </summary>
|
||||
/// <param name="notificationID">The ID of the notificaiton to mark.</param>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message does not contain data.
|
||||
/// A message of type `MessageType.Notification_MarkAsRead` will be generated in response. Call `message.IsError()` to check if any error has occurred.
|
||||
/// </returns>
|
||||
public static Task MarkAsRead(UInt64 notificationID)
|
||||
{
|
||||
if (CoreService.IsInitialized())
|
||||
{
|
||||
return new Task(CLIB.ppf_Notification_MarkAsRead(notificationID));
|
||||
}
|
||||
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4c79e1681394a0292f762df49b5cdd4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,502 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
*/
|
||||
public static class PresenceService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a list of invitable users for the current logged-in user.
|
||||
/// @note Currently, only invitable friends will be returned.
|
||||
/// </summary>
|
||||
/// <param name="options">Restricts the scope of friends returned. If no user ID is passed, all friends will
|
||||
/// be returned. If specific user IDs are passed, the information about specified friends will be returned.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A list of friends that can be invited to the current destination.
|
||||
/// </returns>
|
||||
public static Task<UserList> GetInvitableUsers(InviteOptions options)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<UserList>(CLIB.ppf_Presence_GetInvitableUsers((IntPtr) options));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of invited users for the current logged-in user.
|
||||
/// You need set Presence before call this function.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A list of users that have been invited.
|
||||
/// </returns>
|
||||
public static Task<ApplicationInviteList> GetSentInvites()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<ApplicationInviteList>(CLIB.ppf_Presence_GetSentInvites());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the next page of invited users.
|
||||
/// </summary>
|
||||
/// <param name="list">The current page of invited users.</param>
|
||||
/// <returns>The next page of invited users.</returns>
|
||||
public static Task<ApplicationInviteList> GetNextApplicationInviteListPage(ApplicationInviteList list)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!list.HasNextPage)
|
||||
{
|
||||
Debug.LogWarning("GetNextApplicationInviteListPage: List has no next page");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(list.NextPageParam))
|
||||
{
|
||||
Debug.LogWarning("GetNextApplicationInviteListPage: list.NextPageParam is empty");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<ApplicationInviteList>(CLIB.ppf_Presence_GetNextApplicationInviteArrayPage(list.NextPageParam));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invites specified user(s) to the current destination.
|
||||
/// </summary>
|
||||
/// <param name="userIds">The ID(s) of the user(s) to invite.</param>
|
||||
public static Task<SendInvitesResult> SendInvites(string[] userIds)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (userIds == null)
|
||||
userIds = Array.Empty<string>();
|
||||
return new Task<SendInvitesResult>(CLIB.ppf_Presence_SendInvites(userIds));
|
||||
}
|
||||
|
||||
/// <summary>Sets presence data for the current logged-in user.</summary>
|
||||
/// <param name="options">Presence-related options, including:
|
||||
/// * `DestinationApiName`: string, the API name of the destination.
|
||||
/// * `IsJoinable`: bool,
|
||||
/// * `true`: joinable
|
||||
/// * `false`: not joinable
|
||||
/// * `LobbySessionId`: string, a lobby session ID identifies a user group or team. Users with the same lobby session ID can play together or form a team in a game.
|
||||
/// * `MatchSessionId`: string, a match session ID identifies all users within a same destination, such as a map or a level. Users with different lobby session IDs will have the same match session ID when playing the same match.
|
||||
/// * `Extra`: string, extra presence data defined by the developer.
|
||||
/// </param>
|
||||
public static Task Set(PresenceOptions options)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Presence_Set((IntPtr) options));
|
||||
}
|
||||
|
||||
/// @deprecated SetDestination can be replaced by \ref Set()
|
||||
/// <summary>
|
||||
/// Replaces the current logged-in user's destination with the provided one.
|
||||
/// @note Other presence parameter settings will remain the same.
|
||||
/// </summary>
|
||||
/// <param name="apiName">The API name of the new destination.</param>
|
||||
[Obsolete("SetDestination can be replaced by Set()", false)]
|
||||
public static Task SetDestination(string apiName)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Presence_SetDestination(apiName));
|
||||
}
|
||||
|
||||
/// @deprecated SetIsJoinable can be replaced by \ref Set()
|
||||
/// <summary>Sets whether the current logged-in user is joinable.
|
||||
/// @note Other presence parameter settings will remain the same. If the user's destination or session
|
||||
/// ID has not been set, the user cannot be set as joinable.</summary>
|
||||
/// <param name="joinable">Defines whether the user is joinable:
|
||||
/// * `true`: joinable
|
||||
/// * `false`: not joinable
|
||||
/// </param>
|
||||
[Obsolete("SetIsJoinable can be replaced by Set()", false)]
|
||||
public static Task SetIsJoinable(bool joinable)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Presence_SetIsJoinable(joinable));
|
||||
}
|
||||
|
||||
/// @deprecated SetLobbySession can be replaced by \ref Set()
|
||||
/// <summary>
|
||||
/// Replaces the current logged-in user's lobby session ID with the provided one.
|
||||
/// @note Other presence parameter settings will remain the same.
|
||||
/// </summary>
|
||||
/// <param name="lobbySessionId">The new lobby session ID.</param>
|
||||
[Obsolete("SetLobbySession can be replaced by Set()", false)]
|
||||
public static Task SetLobbySession(string lobbySessionId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Presence_SetLobbySession(lobbySessionId));
|
||||
}
|
||||
|
||||
/// @deprecated SetMatchSession can be replaced by \ref Set()
|
||||
/// <summary>
|
||||
/// Replaces the current logged-in user's match session ID with the provided one.
|
||||
/// @note Other presence parameter settings will remain the same.
|
||||
/// </summary>
|
||||
/// <param name="matchSessionId">The new match session ID.</param>
|
||||
[Obsolete("SetMatchSession can be replaced by Set()", false)]
|
||||
public static Task SetMatchSession(string matchSessionId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Presence_SetMatchSession(matchSessionId));
|
||||
}
|
||||
|
||||
/// @deprecated SetExtra can be replaced by \ref Set()
|
||||
/// <summary>
|
||||
/// Sets extra presence data for the current logged-in user.
|
||||
/// </summary>
|
||||
/// <param name="extra">The extra presence data, which is defined by the developer and will be returned in the user's presence information.</param>
|
||||
[Obsolete("SetExtra can be replaced by Set()", false)]
|
||||
public static Task SetExtra(string extra)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Presence_SetExtra(extra));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears presence data for the current logged-in user.
|
||||
/// @note You need to clear a user's presence data when the user exits your app, leaves a specific destination within the app, or does not want others to see their destination and status.
|
||||
/// </summary>
|
||||
public static Task Clear()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Presence_Clear());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of destinations created on the PICO Developer Platform.
|
||||
/// </summary>
|
||||
/// <returns>The list of destinations.</returns>
|
||||
public static Task<DestinationList> GetDestinations()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<DestinationList>(CLIB.ppf_Presence_GetDestinations());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next page of destinations.
|
||||
/// </summary>
|
||||
/// <param name="destinationList">The current page of destinations.</param>
|
||||
/// <returns>The next page of destinations.</returns>
|
||||
public static Task<DestinationList> GetNextDestinationListPage(DestinationList destinationList)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<DestinationList>(CLIB.ppf_Presence_GetNextDestinationArrayPage(destinationList.NextPageParam));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Launches the invite panel provided in the PICO Friends app. Users can invite other people on the panel.
|
||||
/// @note Before calling this method, you should set presence data correctly.
|
||||
/// </summary>
|
||||
/// <returns>Returns a message. Check `Message.Error` to see whether the panel has been successfully launched.</returns>
|
||||
public static Task LaunchInvitePanel()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Presence_LaunchInvitePanel());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shares a video made of images to Douyin (a video app in Mainland China).
|
||||
/// @note Available in Mainland China only.
|
||||
/// </summary>
|
||||
/// <param name="imagePaths">The local path to images.</param>
|
||||
/// <returns>Returns a message. Check `Message.Error` to see whether the video has been successfully shared.</returns>
|
||||
public static Task ShareVideoByImages(List<string> imagePaths)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
var options = new ShareMediaOptions();
|
||||
foreach (var imagePath in imagePaths)
|
||||
{
|
||||
options.AddImagePath(imagePath);
|
||||
}
|
||||
|
||||
options.SetShareMediaType(ShareMediaType.Image);
|
||||
return new Task(CLIB.ppf_Presence_ShareMedia((IntPtr) options));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shares a video to Douyin (a video app in Mainland China).
|
||||
/// @note Available in Mainland China only.
|
||||
/// </summary>
|
||||
/// <param name="videoPath">The local path to the video.</param>
|
||||
/// <param name="videoThumbPath">The local path to the video thumbnail.
|
||||
/// If not defined, the first frame of the video will become the thumbnail.
|
||||
/// </param>
|
||||
/// <returns>Returns a message. Check `Message.Error` to see whether the video has been successfully shared.</returns>
|
||||
public static Task ShareVideo(string videoPath, string videoThumbPath)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
var options = new ShareMediaOptions();
|
||||
options.SetShareMediaType(ShareMediaType.Video);
|
||||
options.SetVideoPath(videoPath);
|
||||
options.SetVideoThumbPath(videoThumbPath);
|
||||
return new Task(CLIB.ppf_Presence_ShareMedia((IntPtr) options));
|
||||
}
|
||||
|
||||
/// When the user clicks on the invitation message, the system will launch your app and
|
||||
/// the callback will be triggered. Read the fields of \ref Pico.Platform.Models.PresenceJoinIntent
|
||||
/// to figure out where the user wants to go. If the user is unable to go there,
|
||||
/// show the user the info about why they cannot go there.
|
||||
public static void SetJoinIntentReceivedNotificationCallback(Message<PresenceJoinIntent>.Handler callback)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(
|
||||
MessageType.Notification_Presence_JoinIntentReceived,
|
||||
callback
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public class ShareMediaOptions
|
||||
{
|
||||
public ShareMediaOptions()
|
||||
{
|
||||
Handle = CLIB.ppf_ShareMediaOptions_Create();
|
||||
}
|
||||
|
||||
|
||||
public void SetShareMediaType(ShareMediaType value)
|
||||
{
|
||||
CLIB.ppf_ShareMediaOptions_SetShareMediaType(Handle, value);
|
||||
}
|
||||
|
||||
|
||||
public void SetVideoPath(string value)
|
||||
{
|
||||
CLIB.ppf_ShareMediaOptions_SetVideoPath(Handle, value);
|
||||
}
|
||||
|
||||
|
||||
public void SetVideoThumbPath(string value)
|
||||
{
|
||||
CLIB.ppf_ShareMediaOptions_SetVideoThumbPath(Handle, value);
|
||||
}
|
||||
|
||||
|
||||
public void AddImagePath(string ele)
|
||||
{
|
||||
CLIB.ppf_ShareMediaOptions_AddImagePath(Handle, ele);
|
||||
}
|
||||
|
||||
public void ClearImagePaths()
|
||||
{
|
||||
CLIB.ppf_ShareMediaOptions_ClearImagePaths(Handle);
|
||||
}
|
||||
|
||||
|
||||
public void SetShareAppType(ShareAppType value)
|
||||
{
|
||||
CLIB.ppf_ShareMediaOptions_SetShareAppType(Handle, value);
|
||||
}
|
||||
|
||||
/// For passing to native C
|
||||
public static explicit operator IntPtr(ShareMediaOptions options)
|
||||
{
|
||||
return options != null ? options.Handle : IntPtr.Zero;
|
||||
}
|
||||
|
||||
~ShareMediaOptions()
|
||||
{
|
||||
CLIB.ppf_ShareMediaOptions_Destroy(Handle);
|
||||
}
|
||||
|
||||
IntPtr Handle;
|
||||
}
|
||||
|
||||
public class PresenceOptions
|
||||
{
|
||||
public PresenceOptions()
|
||||
{
|
||||
Handle = CLIB.ppf_PresenceOptions_Create();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a destination for the current logged-in user.
|
||||
/// </summary>
|
||||
/// <param name="value">The API name of the destination.</param>
|
||||
public void SetDestinationApiName(string value)
|
||||
{
|
||||
CLIB.ppf_PresenceOptions_SetDestinationApiName(Handle, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets whether the current logged-in user is joinable.
|
||||
/// </summary>
|
||||
/// <param name="value">
|
||||
/// * `true`: joinable
|
||||
/// * `false`: not joinable
|
||||
/// </param>
|
||||
public void SetIsJoinable(bool value)
|
||||
{
|
||||
CLIB.ppf_PresenceOptions_SetIsJoinable(Handle, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a lobby session ID for the current logged-in user.
|
||||
/// </summary>
|
||||
/// <param name="value">The lobby session ID.</param>
|
||||
public void SetLobbySessionId(string value)
|
||||
{
|
||||
CLIB.ppf_PresenceOptions_SetLobbySessionId(Handle, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a match session ID for the current logged-in user.
|
||||
/// </summary>
|
||||
/// <param name="value">The match session ID.</param>
|
||||
public void SetMatchSessionId(string value)
|
||||
{
|
||||
CLIB.ppf_PresenceOptions_SetMatchSessionId(Handle, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets extra presence data for the current logged-in user.
|
||||
/// </summary>
|
||||
/// <param name="value">Extra presence data defined by the developer.</param>
|
||||
public void SetExtra(string value)
|
||||
{
|
||||
CLIB.ppf_PresenceOptions_SetExtra(Handle, value);
|
||||
}
|
||||
|
||||
|
||||
/// For passing to native C
|
||||
public static explicit operator IntPtr(PresenceOptions options)
|
||||
{
|
||||
return options != null ? options.Handle : IntPtr.Zero;
|
||||
}
|
||||
|
||||
~PresenceOptions()
|
||||
{
|
||||
CLIB.ppf_PresenceOptions_Destroy(Handle);
|
||||
}
|
||||
|
||||
IntPtr Handle;
|
||||
}
|
||||
|
||||
public class InviteOptions
|
||||
{
|
||||
public InviteOptions()
|
||||
{
|
||||
Handle = CLIB.ppf_InviteOptions_Create();
|
||||
}
|
||||
|
||||
|
||||
public void AddSuggestedUser(string ele)
|
||||
{
|
||||
CLIB.ppf_InviteOptions_AddSuggestedUser(Handle, ele);
|
||||
}
|
||||
|
||||
public void ClearSuggestedUsers()
|
||||
{
|
||||
CLIB.ppf_InviteOptions_ClearSuggestedUsers(Handle);
|
||||
}
|
||||
|
||||
|
||||
/// For passing to native C
|
||||
public static explicit operator IntPtr(InviteOptions options)
|
||||
{
|
||||
return options != null ? options.Handle : IntPtr.Zero;
|
||||
}
|
||||
|
||||
~InviteOptions()
|
||||
{
|
||||
CLIB.ppf_InviteOptions_Destroy(Handle);
|
||||
}
|
||||
|
||||
IntPtr Handle;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec5d2740554cc9147b92daecb097798d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,978 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AOT;
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Android;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
*
|
||||
* Real-time communications (RTC) technology enables users in the same room to communicate with each other through voice chat.
|
||||
*
|
||||
* RTC service uses a centralized communication structure instead of an end-to-end one. After users have joined a room and enabled voice chat, the microphone keeps capturing audio data from users and uploading the data to the RTC server. Then, the RTC server transmits the audio data to each client in the room, and the client broadcasts the audio data received.
|
||||
*/
|
||||
public static class RtcService
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the RTC engine.
|
||||
/// @note You should call this method before using the RTC service.
|
||||
/// </summary>
|
||||
/// <returns>The status that indicates whether the initialization is successful.</returns>
|
||||
public static RtcEngineInitResult InitRtcEngine()
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.Android && !Permission.HasUserAuthorizedPermission(Permission.Microphone))
|
||||
{
|
||||
Permission.RequestUserPermission(Permission.Microphone);
|
||||
}
|
||||
|
||||
return CLIB.ppf_Rtc_InitRtcEngine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the token required by \ref JoinRoom.
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room that the token is for.</param>
|
||||
/// <param name="userId">The ID of the user that the token is for.</param>
|
||||
/// <param name="ttl">The time-to-live (ttl) of the token. The unit is seconds.
|
||||
/// The user will be kicked out from the room after ttl seconds.
|
||||
/// </param>
|
||||
/// <param name="privileges">The dictionary that maps privilege to ttl. The unit is seconds. </param>
|
||||
public static Task<string> GetToken(string roomId, string userId, int ttl, Dictionary<RtcPrivilege, int> privileges)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
var tokenOption = new RtcGetTokenOptions();
|
||||
tokenOption.SetRoomId(roomId);
|
||||
tokenOption.SetUserId(userId);
|
||||
tokenOption.SetTtl(ttl);
|
||||
if (privileges != null)
|
||||
{
|
||||
foreach (var i in privileges)
|
||||
{
|
||||
tokenOption.SetPrivileges(i.Key, i.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return new Task<string>(CLIB.ppf_Rtc_GetToken((IntPtr) tokenOption));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Joins a user to a specified room.
|
||||
///
|
||||
/// @note
|
||||
/// * If code `0` is returned, you should use \ref SetOnJoinRoomResultCallback to handle the
|
||||
/// final join room result.
|
||||
/// * If a non-zero code is returned, you should call \ref LeaveRoom firstly to join the room in the next time.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room to join.</param>
|
||||
/// <param name="userId">The ID of user.</param>
|
||||
/// <param name="token">The token required for joining the room. You can get the token by calling \ref GetToken.</param>
|
||||
/// <param name="roomProfileType">Room type:
|
||||
/// * `0`: communication room
|
||||
/// * `1`: live broadcasting room
|
||||
/// * `2`: game room
|
||||
/// * `3`: cloud game room
|
||||
/// * `4`: low-latency room
|
||||
/// </param>
|
||||
/// <param name="isAutoSubscribeAudio">Whether to automatically subscribe to the audio in the room:
|
||||
/// * `true`: subscribe
|
||||
/// * `false`: do not subscribe
|
||||
/// </param>
|
||||
/// <returns>`0` indicates success, and other codes indicate failure.
|
||||
/// | Code| Description |
|
||||
/// |---|---|
|
||||
/// |0|Success.|
|
||||
/// |-1|Invalid `roomID` or `userId`.|
|
||||
/// |-2|The user is already in this room.|
|
||||
/// |-3|The RTC engine is null. You should initialize the RTC engine before joining a room.|
|
||||
/// |-4|Creating the room failed.|
|
||||
/// </returns>
|
||||
public static int JoinRoom(string roomId, string userId, string token, RtcRoomProfileType roomProfileType, bool isAutoSubscribeAudio)
|
||||
{
|
||||
var roomOption = new RtcRoomOptions();
|
||||
roomOption.SetRoomId(roomId);
|
||||
roomOption.SetUserId(userId);
|
||||
roomOption.SetToken(token);
|
||||
roomOption.SetRoomProfileType(roomProfileType);
|
||||
roomOption.SetIsAutoSubscribeAudio(isAutoSubscribeAudio);
|
||||
return CLIB.ppf_Rtc_JoinRoom((IntPtr) roomOption);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Joins a user to a room.
|
||||
/// </summary>
|
||||
/// <param name="joinRoomOptions">The options to join a room.</param>
|
||||
/// <param name="leaveIfInRoom">Retry to join the room if the request returns error code `-2` (the user is already in the room).</param>
|
||||
/// <returns>`0` indicates success, and other codes indicate failure.
|
||||
/// | Code| Description |
|
||||
/// |---|---|
|
||||
/// |0|Success.|
|
||||
/// |-1|Invalid `roomID` or `userId`.|
|
||||
/// |-2|The user is already in this room.|
|
||||
/// |-3|The RTC engine is null. You should initialize the RTC engine before joining a room.|
|
||||
/// |-4|Creating the room failed.|
|
||||
/// </returns>
|
||||
public static int JoinRoom2(RtcRoomOptions joinRoomOptions, bool leaveIfInRoom = true)
|
||||
{
|
||||
var res = CLIB.ppf_Rtc_JoinRoom((IntPtr) joinRoomOptions);
|
||||
if (leaveIfInRoom && res == -2)
|
||||
{
|
||||
LeaveRoom(joinRoomOptions.RoomId);
|
||||
res = CLIB.ppf_Rtc_JoinRoom((IntPtr) joinRoomOptions);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Leaves a room and retries to join it when the previous request fails and returns error code `-2` (the user is already in this room).
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room to join.</param>
|
||||
/// <param name="userId">The ID of user.</param>
|
||||
/// <param name="token">The token required for joining the room. You can get the token by calling `GetToken`.</param>
|
||||
/// <param name="roomProfileType">Room type:
|
||||
/// * `0`: communication room
|
||||
/// * `1`: live broadcasting room
|
||||
/// * `2`: game room
|
||||
/// * `3`: cloud game room
|
||||
/// * `4`: low-latency room
|
||||
/// </param>
|
||||
/// <param name="isAutoSubscribeAudio">Whether to automatically subscribe to the audio in the room:
|
||||
/// * `true`: subscribe
|
||||
/// * `false`: do not subscribe
|
||||
/// </param>
|
||||
/// <returns>`0` indicates success, and other codes indicate failure.
|
||||
/// | Code| Description |
|
||||
/// |---|---|
|
||||
/// |0|Success.|
|
||||
/// |-1|Invalid `roomID` or `userId`.|
|
||||
/// |-2|The user is already in this room.|
|
||||
/// |-3|The RTC engine is null. You should initialize the RTC engine before joining a room.|
|
||||
/// |-4|Creating the room failed.|
|
||||
/// </returns>
|
||||
public static int JoinRoomWithRetry(string roomId, string userId, string token, RtcRoomProfileType roomProfileType, bool isAutoSubscribeAudio)
|
||||
{
|
||||
var roomOption = new RtcRoomOptions();
|
||||
roomOption.SetRoomId(roomId);
|
||||
roomOption.SetUserId(userId);
|
||||
roomOption.SetToken(token);
|
||||
roomOption.SetRoomProfileType(roomProfileType);
|
||||
roomOption.SetIsAutoSubscribeAudio(isAutoSubscribeAudio);
|
||||
var res = CLIB.ppf_Rtc_JoinRoom((IntPtr) roomOption);
|
||||
if (res == -2)
|
||||
{
|
||||
LeaveRoom(roomId);
|
||||
res = CLIB.ppf_Rtc_JoinRoom((IntPtr) roomOption);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Leaves a specified room.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room to leave.</param>
|
||||
/// <returns>`0` indicates success, and other codes indicate failure.
|
||||
///
|
||||
/// | Code| Description |
|
||||
/// |---|---|
|
||||
/// |0|Success.|
|
||||
/// |-1|The RTC engine is not initialized.|
|
||||
/// |-2|The user is not in the room.|
|
||||
/// </returns>
|
||||
public static int LeaveRoom(string roomId)
|
||||
{
|
||||
return CLIB.ppf_Rtc_LeaveRoom(roomId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the audio playback device.
|
||||
/// </summary>
|
||||
/// <param name="device">The device ID.</param>
|
||||
public static void SetAudioPlaybackDevice(RtcAudioPlaybackDevice device)
|
||||
{
|
||||
CLIB.ppf_Rtc_SetAudioPlaybackDevice(device);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribing from all the audio streams of a room, thereby making the local user unable to hear anything from the room.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room whose audio streams are to be unsubscribed from.</param>
|
||||
public static void RoomPauseAllSubscribedStream(string roomId)
|
||||
{
|
||||
CLIB.ppf_Rtc_RoomPauseAllSubscribedStream(roomId, RtcPauseResumeMediaType.Audio);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resubscribing to all the audio streams of a room, thereby making the local user hear the voice from every in-room user.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room whose audio streams are to be resubscribed to.</param>
|
||||
public static void RoomResumeAllSubscribedStream(string roomId)
|
||||
{
|
||||
CLIB.ppf_Rtc_RoomResumeAllSubscribedStream(roomId, RtcPauseResumeMediaType.Audio);
|
||||
}
|
||||
|
||||
public delegate int ProcessAudioFrameFunction(RtcAudioFrame frame);
|
||||
|
||||
static ProcessAudioFrameFunction audioProcessor = null;
|
||||
|
||||
[MonoPInvokeCallback(typeof(CLIB.RtcProcessAudioFrameFunction))]
|
||||
static int InnerAudioProcessor(IntPtr ptr)
|
||||
{
|
||||
if (audioProcessor != null)
|
||||
{
|
||||
return audioProcessor(new RtcAudioFrame(ptr));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register local audio processor. You can use this function to modify the recorded audio.
|
||||
/// </summary>
|
||||
/// <param name="processor">The processor function.
|
||||
/// If it returns 0,means the function didn't change the data.
|
||||
/// If its return value is negative integer, means the function encounters error.
|
||||
/// If its return value is positive integer, means the function handled successfully.
|
||||
/// </param>
|
||||
/// <param name="channel">The channel of the audio you want to process.</param>
|
||||
/// <param name="sampleRate">The sample rate of the audio you want to process.</param>
|
||||
public static void RegisterLocalAudioProcessor(ProcessAudioFrameFunction processor, RtcAudioChannel channel, RtcAudioSampleRate sampleRate)
|
||||
{
|
||||
// here should hold the processor to avoid GC delete the processor and `InnerAudioProcessor` will call this.
|
||||
audioProcessor = processor;
|
||||
CLIB.ppf_Rtc_RegisterLocalAudioProcessor(InnerAudioProcessor, channel, sampleRate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables audio properties report. Once enabled, you will regularly receive audio report data.
|
||||
/// </summary>
|
||||
/// <param name="interval">
|
||||
/// The interval (in milliseconds) between one report and the next. You can set this parameter to `0` or any negative integer to stop receiving audio properties report.
|
||||
/// For any integer between (0, 100), the SDK will regard it as invalid and automatically set this parameter to `100`; any integer equal to or greater than `100` is valid.
|
||||
/// </param>
|
||||
public static void EnableAudioPropertiesReport(int interval)
|
||||
{
|
||||
var conf = new RtcAudioPropertyOptions();
|
||||
conf.SetInterval(interval);
|
||||
CLIB.ppf_Rtc_EnableAudioPropertiesReport((IntPtr) conf);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Publishes the local audio stream to a room, thereby making the local user's voice heard by other in-room users.
|
||||
/// @note
|
||||
/// * A user can only publish the local audio stream to one room at the same time.
|
||||
/// * If a user wants to publish the local audio stream to another room,
|
||||
/// `UnPublishRoom(oldRoomId)` should be called first to stop publishing the local audio stream to the current room and then `Publish(newRoomId)` should be called.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room that the local audio stream is published to.</param>
|
||||
public static void PublishRoom(string roomId)
|
||||
{
|
||||
CLIB.ppf_Rtc_RoomPublishStream(roomId, RtcMediaStreamType.Audio);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops publishing the local audio stream to a room, so other in-room users are unable to hear the local user's voice.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room to stop publishing the local audio stream to.</param>
|
||||
public static void UnPublishRoom(string roomId)
|
||||
{
|
||||
CLIB.ppf_Rtc_RoomUnPublishStream(roomId, RtcMediaStreamType.Audio);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys a specified room. The resources occupied by the room will be released after destruction.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room to destroy.</param>
|
||||
public static void DestroyRoom(string roomId)
|
||||
{
|
||||
CLIB.ppf_Rtc_DestroyRoom(roomId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts audio capture via the microphone.
|
||||
/// </summary>
|
||||
public static void StartAudioCapture()
|
||||
{
|
||||
CLIB.ppf_Rtc_StartAudioCapture();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops audio capture.
|
||||
/// </summary>
|
||||
public static void StopAudioCapture()
|
||||
{
|
||||
CLIB.ppf_Rtc_StopAudioCapture();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the volume of the captured audio.
|
||||
/// </summary>
|
||||
/// <param name="volume">The target volume. The valid value ranges from `0` to `400`. `100` indicates keeping the original volume.</param>
|
||||
public static void SetCaptureVolume(int volume)
|
||||
{
|
||||
CLIB.ppf_Rtc_SetCaptureVolume(RtcStreamIndex.Main, volume);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the playback volume.
|
||||
/// </summary>
|
||||
/// <param name="volume">The target volume. The valid value ranges from `0` to `400`. `100` indicates keeping the original volume.</param>
|
||||
public static void SetPlaybackVolume(int volume)
|
||||
{
|
||||
CLIB.ppf_Rtc_SetPlaybackVolume(volume);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Switches the in-ear monitoring mode on/off. Once the in-ear monitoring mode is enabled, one can hear their own voice.
|
||||
/// </summary>
|
||||
/// <param name="mode">Whether to switch the in-ear monitoring mode on/off:
|
||||
/// * `0`: off
|
||||
/// * `1`: on
|
||||
/// </param>
|
||||
public static void SetEarMonitorMode(RtcEarMonitorMode mode)
|
||||
{
|
||||
CLIB.ppf_Rtc_SetEarMonitorMode(mode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the volume for in-ear monitoring.
|
||||
/// </summary>
|
||||
/// <param name="volume">The target volume. The valid value range from `0` to `400`.</param>
|
||||
public static void SetEarMonitorVolume(int volume)
|
||||
{
|
||||
CLIB.ppf_Rtc_SetEarMonitorVolume(volume);
|
||||
}
|
||||
|
||||
/// @deprecated MuteLocalAudio() can be replaced by \ref UnPublishRoom(string roomId)
|
||||
/// <summary>
|
||||
/// Mutes local audio to make one's voice unable to be heard by other in-room users.
|
||||
/// </summary>
|
||||
/// <param name="rtcMuteState">The state of local audio:
|
||||
/// * `0`: off
|
||||
/// * `1`: on
|
||||
/// </param>
|
||||
[Obsolete("MuteLocalAudio can be replaced by UnPublishRoom(roomId)", true)]
|
||||
public static void MuteLocalAudio(RtcMuteState rtcMuteState)
|
||||
{
|
||||
CLIB.ppf_Rtc_MuteLocalAudio(rtcMuteState);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the token in a room.
|
||||
///
|
||||
/// When a token's ttl is about to expire, you will receive a notification
|
||||
/// through \ref SetOnTokenWillExpire. If you still want to stay in the room,
|
||||
/// you should call \ref GetToken to get a new token and call \ref UpdateToken
|
||||
/// with the new token. If you don't update token timely,you will be kicked
|
||||
/// out from the room.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room you are in.</param>
|
||||
/// <param name="token">The token to update.</param>
|
||||
public static void UpdateToken(string roomId, string token)
|
||||
{
|
||||
CLIB.ppf_Rtc_UpdateToken(roomId, token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the audio scenario.
|
||||
/// @note Different audio scenarios can impact the voice quality and how the earphones work.
|
||||
/// </summary>
|
||||
/// <param name="scenarioType">The audio scenario type:
|
||||
/// * `0`: Music
|
||||
/// * `1`: HighQualityCommunication
|
||||
/// * `2`: Communication
|
||||
/// * `3`: Media
|
||||
/// * `4`: GameStreaming
|
||||
/// </param>
|
||||
public static void SetAudioScenario(RtcAudioScenarioType scenarioType)
|
||||
{
|
||||
CLIB.ppf_Rtc_SetAudioScenario(scenarioType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the volume for a remote user in a room.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room.</param>
|
||||
/// <param name="userId">The ID of the remote user.</param>
|
||||
/// <param name="volume">The volume to set for the remote user, which ranges from `0` to `400` and `100` indicates the default volume.</param>
|
||||
public static void RoomSetRemoteAudioPlaybackVolume(string roomId, string userId, int volume)
|
||||
{
|
||||
CLIB.ppf_Rtc_RoomSetRemoteAudioPlaybackVolume(roomId, userId, volume);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to the audio stream of a specific user in a room.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room.</param>
|
||||
/// <param name="userId">The ID of the user in the room.</param>
|
||||
public static void RoomSubscribeStream(string roomId, string userId)
|
||||
{
|
||||
CLIB.ppf_Rtc_RoomSubscribeStream(roomId, userId, RtcMediaStreamType.Audio);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes from the audio stream of a specific user in a room.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room.</param>
|
||||
/// <param name="userId">The ID of the user in the room.</param>
|
||||
public static void RoomUnSubscribeStream(string roomId, string userId)
|
||||
{
|
||||
CLIB.ppf_Rtc_RoomUnsubscribeStream(roomId, userId, RtcMediaStreamType.Audio);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a binary message to a room. All in-room users will receive this message.
|
||||
///
|
||||
/// The message's bytes size shouldn't be greater than 64kB.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room.</param>
|
||||
/// <param name="message">The binary message to be sent.</param>
|
||||
/// <returns>A room message ID of the int64 type, which is automatically generated and incremented.</returns>
|
||||
public static long SendRoomBinaryMessage(string roomId, byte[] message)
|
||||
{
|
||||
var ptr = new PtrManager(message);
|
||||
var ans = CLIB.ppf_Rtc_SendRoomBinaryMessage(roomId, ptr.ptr, message.Length);
|
||||
ptr.Free();
|
||||
return ans;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a text message to a room. All in-room users will receive this message.
|
||||
///
|
||||
/// The message's bytes size shouldn't be greater than 64kB.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room.</param>
|
||||
/// <param name="message">The message to be sent.</param>
|
||||
/// <returns>A room message ID of the int64 type, which is automatically generated and incremented.</returns>
|
||||
public static long SendRoomMessage(string roomId, string message)
|
||||
{
|
||||
return CLIB.ppf_Rtc_SendRoomMessage(roomId, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a binary message to a user. Only the user can receive this message.
|
||||
///
|
||||
/// The message's bytes size shouldn't be greater than 64kB.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room the user is in.</param>
|
||||
/// <param name="userId">The ID of the user the message is sent to.</param>
|
||||
/// <param name="message">The message to be sent.</param>
|
||||
/// <returns>A user message ID of the int64 type, which is automatically generated and incremented.</returns>
|
||||
public static long SendUserBinaryMessage(string roomId, string userId, byte[] message)
|
||||
{
|
||||
var ptr = new PtrManager(message);
|
||||
var ans = CLIB.ppf_Rtc_SendUserBinaryMessage(roomId, userId, ptr.ptr, message.Length);
|
||||
ptr.Free();
|
||||
return ans;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a text message to a user. Only the user can receive this message.
|
||||
/// The message's bytes size shouldn't be greater than 64kB.
|
||||
/// </summary>
|
||||
/// <param name="roomId">The ID of the room the user is in.</param>
|
||||
/// <param name="userId">The ID of the user the message is sent to.</param>
|
||||
/// <param name="message">The message to be sent.</param>
|
||||
/// <returns>A user message ID of the int64 type, which is automatically generated and incremented.</returns>
|
||||
public static long SendUserMessage(string roomId, string userId, string message)
|
||||
{
|
||||
return CLIB.ppf_Rtc_SendUserMessage(roomId, userId, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends stream sync info. The sync info data will be sent in the same packet with the audio data. Users who subscribe to this audio stream will receive the stream sync info message.
|
||||
/// </summary>
|
||||
/// <param name="data">The stream sync info.</param>
|
||||
/// <param name="repeatCount">The stream sync info will be sent repeatedly for the times set in `repeatCount`.
|
||||
/// It's designed to avoid losing package and ensuring that the sync info can be sent successfully.
|
||||
/// However, if `repeatCount` is too large, it will cause the sync info to pile up in the queue.
|
||||
/// Setting this parameter to `0` is recommended.
|
||||
/// </param>
|
||||
/// <returns>Any code equal to or below `0` indicates success, and others codes indicate failure.
|
||||
/// | Code | Description|
|
||||
/// |---|---|
|
||||
/// |>=0|Send successfully.Indicates the times sent successfully.|
|
||||
/// |-1|Send Failed. Message length exceeded 255B|
|
||||
/// |-2|Send Failed. The data is empty.|
|
||||
/// |-3|Send Failed. Send sync info with a un-publish screen stream.|
|
||||
/// |-4|Send Failed. Send sync info with a un-publish audio stream.|
|
||||
/// </returns>
|
||||
public static int SendStreamSyncInfo(byte[] data, int repeatCount)
|
||||
{
|
||||
var config = new RtcStreamSyncInfoOptions();
|
||||
config.SetRepeatCount(repeatCount);
|
||||
config.SetStreamIndex(RtcStreamIndex.Main);
|
||||
config.SetStreamType(RtcSyncInfoStreamType.Audio);
|
||||
var ptr = new PtrManager(data);
|
||||
var ans = CLIB.ppf_Rtc_SendStreamSyncInfo(ptr.ptr, data.Length, (IntPtr) config);
|
||||
ptr.Free();
|
||||
return ans;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when the token is about to expire.
|
||||
/// @note The token will expire 30 seconds after you receive this notification.
|
||||
/// * If you still want to stay in the room, you can get a new token by calling `UpdateToken`.
|
||||
/// * If you do not update the token after receiving this notification, you will be kicked out of the room in 30 seconds.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback function, the string in the message indicates the room ID.</param>
|
||||
public static void SetOnTokenWillExpire(Message<string>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnTokenWillExpire, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when a to-room message is received.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnRoomMessageReceived(Message<RtcRoomMessageReceived>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnRoomMessageReceived, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when a to-room binary message is received.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnRoomBinaryMessageReceived(Message<RtcBinaryMessageReceived>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnRoomBinaryMessageReceived, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when a to-user message is received.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnUserMessageReceived(Message<RtcUserMessageReceived>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnUserMessageReceived, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when a to-user binary message is received.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnUserBinaryMessageReceived(Message<RtcBinaryMessageReceived>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnUserBinaryMessageReceived, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get whether the to-room message is sent successfully.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnRoomMessageSendResult(Message<RtcMessageSendResult>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnRoomMessageSendResult, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get whether the to-user message is sent successfully.
|
||||
/// </summary>
|
||||
/// <param name="handler"></param>
|
||||
public static void SetOnUserMessageSendResult(Message<RtcMessageSendResult>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnUserMessageSendResult, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when a remote user publishes audio stream.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnUserPublishStream(Message<RtcUserPublishInfo>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnUserPublishStream, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when a remote user cancels publishing audio stream.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnUserUnPublishStream(Message<RtcUserUnPublishInfo>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnUserUnPublishStream, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when the stream sync info is received.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnStreamSyncInfoReceived(Message<RtcStreamSyncInfo>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnStreamSyncInfoReceived, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback of `JoinRoom` to get `RtcJoinRoomResult`.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnJoinRoomResultCallback(Message<RtcJoinRoomResult>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnJoinRoom, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback of `LeaveRoom` to get `RtcLeaveRoomResult`.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnLeaveRoomResultCallback(Message<RtcLeaveRoomResult>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnLeaveRoom, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when someone has joined the room.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnUserJoinRoomResultCallback(Message<RtcUserJoinInfo>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnUserJoinRoom, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when someone has left the room.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnUserLeaveRoomResultCallback(Message<RtcUserLeaveInfo>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnUserLeaveRoom, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to regularly get room statistics after joining a room.
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnRoomStatsCallback(Message<RtcRoomStats>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnRoomStats, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get warning messages from the RTC engine.
|
||||
/// The warning codes and descriptions are given below.
|
||||
///
|
||||
/// |Warning Code|Description|
|
||||
/// |---|---|
|
||||
/// |-2001|Joining the room failed.|
|
||||
/// |-2002|Publishing audio stream failed.|
|
||||
/// |-2003|Subscribing to the audio stream failed because the stream cannot be found.|
|
||||
/// |-2004|Subscribing to the audio stream failed due to server error.|
|
||||
/// |-2013|When the people count in the room exceeds 500, the client will not be informed of user join and leave info anymore.|
|
||||
/// |-5001|The camera permission is missing.|
|
||||
/// |-5002|The microphone permission is missing.|
|
||||
/// |-5003|Starting the audio capture device failed.|
|
||||
/// |-5004|Starting the audio playback device failed.|
|
||||
/// |-5005|No available audio capture device.|
|
||||
/// |-5006|No available audio playback device.|
|
||||
/// |-5007|The audio capture device failed to capture valid audio data.|
|
||||
/// |-5008|Invalid media device operation.|
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnWarnCallback(Message<int>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnWarn, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get error messages from the RTC engine.
|
||||
/// The error codes and descriptions are given below.
|
||||
///
|
||||
/// |Error Code|Description|
|
||||
/// |---|---|
|
||||
/// |-1000|Invalid token.|
|
||||
/// |-1001|Unknown error.|
|
||||
/// |-1002|No permission to publish audio stream.|
|
||||
/// |-1003|No permission to subscribe audio stream.|
|
||||
/// |-1004|A user with the same user Id joined this room. You are kicked out of the room.|
|
||||
/// |-1005|Incorrect configuration on the Developer Platform.|
|
||||
/// |-1007|Invalid room id.|
|
||||
/// |-1009|Token expired. You should get a new token and join the room.|
|
||||
/// |-1010|Token is invalid when you call `UpdateToken`|
|
||||
/// |-1011|The room is dismissed and all user is moved out from the room.|
|
||||
/// |-1070|Subscribing to audio stream failed. Perhaps the number of subscribed audio streams has exceeded the limit.|
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnErrorCallback(Message<int>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnError, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get warning messages from the room.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnRoomWarnCallback(Message<RtcRoomWarn>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnRoomWarn, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get error messages from the room.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnRoomErrorCallback(Message<RtcRoomError>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnRoomError, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when the state of the connection to the RTC server has changed.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnConnectionStateChangeCallback(Message<RtcConnectionState>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnConnectionStateChange, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when the user has muted local audio.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
[Obsolete("SetOnUserMuteAudio is deprecated,please use SetOnUserPublishStream/SetOnUserUnPublishStream", true)]
|
||||
public static void SetOnUserMuteAudio(Message<RtcMuteInfo>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnUserMuteAudio, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when the user has started audio capture.
|
||||
///
|
||||
/// When a remote user called \ref StartAudioCapture,RTC engine will call this callback.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnUserStartAudioCapture(Message<string>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnUserStartAudioCapture, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when the user has stopped audio capture.
|
||||
///
|
||||
/// When a remote user called \ref StopAudioCapture,RTC engine will call this callback.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnUserStopAudioCapture(Message<string>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnUserStopAudioCapture, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to get notified when the audio playback device has been changed.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnAudioPlaybackDeviceChange(Message<RtcAudioPlaybackDevice>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnAudioPlaybackDeviceChanged, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to receive local audio report.
|
||||
/// Rtc engine will call this callback periodically once you call \ref EnableAudioPropertiesReport.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnLocalAudioPropertiesReport(Message<RtcLocalAudioPropertiesReport>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnLocalAudioPropertiesReport, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the callback to receive remote audio report.
|
||||
/// Rtc engine will call this callback periodically once you call \ref EnableAudioPropertiesReport.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback handler.</param>
|
||||
public static void SetOnRemoteAudioPropertiesReport(Message<RtcRemoteAudioPropertiesReport>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Rtc_OnRemoteAudioPropertiesReport, handler);
|
||||
}
|
||||
}
|
||||
|
||||
public class RtcStreamSyncInfoOptions
|
||||
{
|
||||
private IntPtr Handle;
|
||||
|
||||
public RtcStreamSyncInfoOptions()
|
||||
{
|
||||
Handle = CLIB.ppf_RtcStreamSyncInfoOptions_Create();
|
||||
}
|
||||
|
||||
public void SetRepeatCount(int value)
|
||||
{
|
||||
CLIB.ppf_RtcStreamSyncInfoOptions_SetRepeatCount(Handle, value);
|
||||
}
|
||||
|
||||
public void SetStreamIndex(RtcStreamIndex value)
|
||||
{
|
||||
CLIB.ppf_RtcStreamSyncInfoOptions_SetStreamIndex(Handle, value);
|
||||
}
|
||||
|
||||
public void SetStreamType(RtcSyncInfoStreamType value)
|
||||
{
|
||||
CLIB.ppf_RtcStreamSyncInfoOptions_SetStreamType(Handle, value);
|
||||
}
|
||||
|
||||
public static explicit operator IntPtr(RtcStreamSyncInfoOptions options)
|
||||
{
|
||||
return options != null ? options.Handle : IntPtr.Zero;
|
||||
}
|
||||
|
||||
~RtcStreamSyncInfoOptions()
|
||||
{
|
||||
CLIB.ppf_RtcStreamSyncInfoOptions_Destroy(Handle);
|
||||
}
|
||||
}
|
||||
|
||||
public class RtcRoomOptions
|
||||
{
|
||||
public string RoomId;
|
||||
|
||||
public RtcRoomOptions()
|
||||
{
|
||||
Handle = CLIB.ppf_RtcRoomOptions_Create();
|
||||
}
|
||||
|
||||
|
||||
public void SetRoomProfileType(RtcRoomProfileType value)
|
||||
{
|
||||
CLIB.ppf_RtcRoomOptions_SetRoomProfileType(Handle, value);
|
||||
}
|
||||
|
||||
|
||||
public void SetIsAutoSubscribeAudio(bool value)
|
||||
{
|
||||
CLIB.ppf_RtcRoomOptions_SetIsAutoSubscribeAudio(Handle, value);
|
||||
}
|
||||
|
||||
public void SetRoomId(string value)
|
||||
{
|
||||
this.RoomId = value;
|
||||
CLIB.ppf_RtcRoomOptions_SetRoomId(Handle, value);
|
||||
}
|
||||
|
||||
|
||||
public void SetUserId(string value)
|
||||
{
|
||||
CLIB.ppf_RtcRoomOptions_SetUserId(Handle, value);
|
||||
}
|
||||
|
||||
|
||||
public void SetUserExtra(string value)
|
||||
{
|
||||
CLIB.ppf_RtcRoomOptions_SetUserExtra(Handle, value);
|
||||
}
|
||||
|
||||
|
||||
public void SetToken(string value)
|
||||
{
|
||||
CLIB.ppf_RtcRoomOptions_SetToken(Handle, value);
|
||||
}
|
||||
|
||||
/// For passing to native C
|
||||
public static explicit operator IntPtr(RtcRoomOptions options)
|
||||
{
|
||||
return options != null ? options.Handle : IntPtr.Zero;
|
||||
}
|
||||
|
||||
~RtcRoomOptions()
|
||||
{
|
||||
CLIB.ppf_RtcRoomOptions_Destroy(Handle);
|
||||
}
|
||||
|
||||
private IntPtr Handle;
|
||||
}
|
||||
|
||||
public class RtcGetTokenOptions
|
||||
{
|
||||
public RtcGetTokenOptions()
|
||||
{
|
||||
Handle = CLIB.ppf_RtcGetTokenOptions_Create();
|
||||
}
|
||||
|
||||
|
||||
public void SetUserId(string value)
|
||||
{
|
||||
CLIB.ppf_RtcGetTokenOptions_SetUserId(Handle, value);
|
||||
}
|
||||
|
||||
|
||||
public void SetRoomId(string value)
|
||||
{
|
||||
CLIB.ppf_RtcGetTokenOptions_SetRoomId(Handle, value);
|
||||
}
|
||||
|
||||
public void SetTtl(int value)
|
||||
{
|
||||
CLIB.ppf_RtcGetTokenOptions_SetTtl(Handle, value);
|
||||
}
|
||||
|
||||
public void SetPrivileges(RtcPrivilege key, int value)
|
||||
{
|
||||
CLIB.ppf_RtcGetTokenOptions_SetPrivileges(Handle, key, value);
|
||||
}
|
||||
|
||||
public void ClearPrivileges()
|
||||
{
|
||||
CLIB.ppf_RtcGetTokenOptions_ClearPrivileges(Handle);
|
||||
}
|
||||
|
||||
/// For passing to native C
|
||||
public static explicit operator IntPtr(RtcGetTokenOptions options)
|
||||
{
|
||||
return options != null ? options.Handle : IntPtr.Zero;
|
||||
}
|
||||
|
||||
~RtcGetTokenOptions()
|
||||
{
|
||||
CLIB.ppf_RtcGetTokenOptions_Destroy(Handle);
|
||||
}
|
||||
|
||||
private IntPtr Handle;
|
||||
}
|
||||
|
||||
public class RtcAudioPropertyOptions
|
||||
{
|
||||
public IntPtr Handle;
|
||||
|
||||
public RtcAudioPropertyOptions()
|
||||
{
|
||||
Handle = CLIB.ppf_RtcAudioPropertyOptions_Create();
|
||||
}
|
||||
|
||||
public void SetInterval(int value)
|
||||
{
|
||||
CLIB.ppf_RtcAudioPropertyOptions_SetInterval(Handle, value);
|
||||
}
|
||||
|
||||
~RtcAudioPropertyOptions()
|
||||
{
|
||||
CLIB.ppf_RtcAudioPropertyOptions_Destroy(Handle);
|
||||
}
|
||||
|
||||
/// For passing to native C
|
||||
public static explicit operator IntPtr(RtcAudioPropertyOptions options)
|
||||
{
|
||||
return options != null ? options.Handle : IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5156f6aeca9c5bd4caf2a75e964824db
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,736 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
*/
|
||||
public static class RoomService
|
||||
{
|
||||
/// <summary>Gets the room options for create a private room. You can use it when you use \ref RoomService.CreateAndJoinPrivate2.</summary>
|
||||
/// <param name="dataStore">The key/value pairs to add.</param>
|
||||
/// <returns>The room options for create a private room.</returns>
|
||||
public static RoomOptions GetCreatePrivateRoomOptions(Dictionary<string, string> dataStore)
|
||||
{
|
||||
RoomOptions options = new RoomOptions();
|
||||
foreach (var data in dataStore)
|
||||
{
|
||||
options.SetDataStore(data.Key, data.Value);
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/// <summary>Gets the room options for joining or creating a named room. You can use it when you use \ref RoomService.JoinOrCreateNamedRoom.</summary>
|
||||
/// <param name="dataStore">The key/value pairs to add.</param>
|
||||
/// <param name="name">The name of the named room.</param>
|
||||
/// <param name="password">The password of the named room.</param>
|
||||
/// <returns>The room options for joining or creating a named room.</returns>
|
||||
public static RoomOptions GetJoinOrCreateNamedRoomOptions(Dictionary<string, string> dataStore, string name, string password)
|
||||
{
|
||||
RoomOptions options = new RoomOptions();
|
||||
foreach (var data in dataStore)
|
||||
{
|
||||
options.SetDataStore(data.Key, data.Value);
|
||||
}
|
||||
|
||||
options.SetRoomName(name);
|
||||
options.SetPassword(password);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/// <summary>Gets the list of named rooms created for the app.</summary>
|
||||
/// <param name="pageIndex">Defines which page of entries to return. The index for the first page is `0`.</param>
|
||||
/// <param name="pageSize">The number of entries returned on each page. Value range: [5,20].</param>
|
||||
/// <returns>The request ID of this async function.
|
||||
///
|
||||
/// A message of type `MessageType.Room_GetNamedRooms` will be generated in response.
|
||||
/// First call `Message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `RoomList`.
|
||||
/// Extract the payload from the message handle with `Message.Data`.
|
||||
/// </returns>
|
||||
public static Task<RoomList> GetNamedRooms(int pageIndex, int pageSize)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<RoomList>(CLIB.ppf_Room_GetNamedRooms(pageIndex, pageSize));
|
||||
}
|
||||
|
||||
/// <summary>Join or create a named room.</summary>
|
||||
/// <param name="joinPolicy">The join policy of the room. Currently only support 'RoomJoinPolicy Everyone'.</param>
|
||||
/// <param name="createIfNotExist">Determines whether to create a new room if the named room does not exist:
|
||||
/// * `true`: create
|
||||
/// * `false`: do not create
|
||||
/// </param>
|
||||
/// <param name="maxUsers">The maximum number of users allowed in the room, including the creator.</param>
|
||||
/// <param name="options">Additional room configuration for this request.</param>
|
||||
/// <returns>The request ID of this async function.
|
||||
///
|
||||
/// A message of type `MessageType.Room_JoinNamed` will be generated in response.
|
||||
/// First call `Message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `Room`.
|
||||
/// Extract the payload from the message handle with `Message.Data`.
|
||||
/// </returns>
|
||||
public static Task<Room> JoinOrCreateNamedRoom(RoomJoinPolicy joinPolicy, bool createIfNotExist, uint maxUsers, RoomOptions options)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Room>(CLIB.ppf_Room_JoinNamed(joinPolicy, createIfNotExist, maxUsers, options.GetHandle()));
|
||||
}
|
||||
|
||||
/// <summary>Launches the invitation flow to let the current user invite friends to a specified room.
|
||||
/// This launches the system default invite UI where all of the user's friends are displayed.
|
||||
/// This is intended to be a shortcut for developers not wanting to build their own invite-friends UI.
|
||||
/// </summary>
|
||||
/// <param name="roomID">The ID of the room.</param>
|
||||
/// <returns>The request ID of this async function.
|
||||
/// A message of type `MessageType.Room_LaunchInvitableUserFlow` will be generated in response.
|
||||
/// Call `message.IsError()` to check if any error has occurred.
|
||||
/// </returns>
|
||||
public static Task LaunchInvitableUserFlow(UInt64 roomID)
|
||||
{
|
||||
if (!CoreService.IsInitialized())
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Room_LaunchInvitableUserFlow(roomID));
|
||||
}
|
||||
|
||||
/// <summary>Updates the data store of the current room (the caller should be the room owner).
|
||||
/// @note Room data stores only allow string values. The maximum key length is 32 bytes and the maximum value length is 64 bytes.
|
||||
/// If you provide illegal values, this method will return an error.</summary>
|
||||
/// <param name="roomId">The ID of the room that you currently own (call `Room.OwnerOptional` to check).</param>
|
||||
/// <param name="data">The key/value pairs to add or update. Null value will clear a given key.</param>
|
||||
/// <returns>The request ID of this async function.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006004|change datastore failed: need room owner|
|
||||
///
|
||||
/// A message of type `MessageType.Room_UpdateDataStore` will be generated in response.
|
||||
/// First call `Message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `Room`.
|
||||
/// Extract the payload from the message handle with `Message.Data`.
|
||||
/// </returns>
|
||||
public static Task<Room> UpdateDataStore(UInt64 roomId, Dictionary<string, string> data)
|
||||
{
|
||||
KVPairArray kvarray = new KVPairArray((uint) data.Count);
|
||||
uint n = 0;
|
||||
foreach (var d in data)
|
||||
{
|
||||
var item = kvarray.GetElement(n);
|
||||
item.SetKey(d.Key);
|
||||
item.SetStringValue(d.Value);
|
||||
n++;
|
||||
}
|
||||
|
||||
return new Task<Room>(CLIB.ppf_Room_UpdateDataStore(roomId, kvarray.GetHandle(), kvarray.Size));
|
||||
}
|
||||
|
||||
/// <summary>Creates a new private room and joins it.
|
||||
/// @note This type of room can be obtained by querying the room where
|
||||
/// a friend is, so it is suitable for playing with friends.</summary>
|
||||
///
|
||||
/// <param name="policy">Specifies who can join the room:
|
||||
/// * `0`: nobody
|
||||
/// * `1`: everybody
|
||||
/// * `2`: friends of members
|
||||
/// * `3`: friends of the room owner
|
||||
/// * `4`: invited users
|
||||
/// * `5`: unknown
|
||||
/// </param>
|
||||
/// <param name="maxUsers">The maximum number of members allowed in the room, including the room creator.</param>
|
||||
/// <param name="roomOptions">Room configuration for this request.</param>
|
||||
/// <returns>Request information of type Task, including the request id, and its response message will contain data of type `Room`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006101|room create: unknown error|
|
||||
/// |3006114|setting of 'room max user' is too large|
|
||||
///
|
||||
/// A message of type `MessageType.Room_CreateAndJoinPrivate2` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `Room`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<Room> CreateAndJoinPrivate2(RoomJoinPolicy policy, uint maxUsers, RoomOptions roomOptions)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Room>(CLIB.ppf_Room_CreateAndJoinPrivate2(policy, maxUsers, roomOptions.GetHandle()));
|
||||
}
|
||||
|
||||
/// <summary>Gets the information about a specified room.</summary>
|
||||
/// <param name="roomId">The ID of the room to get information for.</param>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message will contain data of type `Room`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006103|invalid room|
|
||||
/// |3006301|server error: unknown|
|
||||
///
|
||||
/// A message of type `MessageType.Room_Get` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `Room`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<Room> Get(UInt64 roomId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Room>(CLIB.ppf_Room_Get(roomId));
|
||||
}
|
||||
|
||||
/// <summary>Gets the data of the room you are currently in.</summary>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message will contain data of type `Room`.
|
||||
/// |Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006104|not in room|
|
||||
///
|
||||
/// A message of type `MessageType.Room_GetCurrent` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload with of type `Room`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<Room> GetCurrent()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Room>(CLIB.ppf_Room_GetCurrent());
|
||||
}
|
||||
|
||||
/// <summary>Gets the current room of the specified user.
|
||||
/// @note The user's privacy settings may not allow you to access their room.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="userId">The ID of the user.</param>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message will contain data of type `Room`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006104|not in room|
|
||||
/// |3006009|tgt player is not in game now|
|
||||
/// |3006301|server error: unknown|
|
||||
///
|
||||
/// A message of type `MessageType.Room_GetCurrentForUser` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `Room`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<Room> GetCurrentForUser(string userId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Room>(CLIB.ppf_Room_GetCurrentForUser(userId));
|
||||
}
|
||||
|
||||
/// <summary>Gets a list of members the user can invite to the room.
|
||||
/// These members are drawn from the user's friends list and recently
|
||||
/// encountered list, and filtered based on relevance and interests.
|
||||
/// @note: Only applicable to private rooms and named rooms.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="roomOptions">Additional configuration for this request.
|
||||
/// If you pass `null`, the response will return code `0`.</param>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message will contain data of type `UserList`.
|
||||
///
|
||||
/// A message of type `MessageType.Room_GetInvitableUsers2` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `UserList`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<UserList> GetInvitableUsers2(RoomOptions roomOptions = null)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (roomOptions == null)
|
||||
{
|
||||
return new Task<UserList>(CLIB.ppf_Room_GetInvitableUsers2(IntPtr.Zero));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Task<UserList>(CLIB.ppf_Room_GetInvitableUsers2(roomOptions.GetHandle()));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the list of moderated rooms created for the application.</summary>
|
||||
///
|
||||
/// <param name="index">Start page index.</param>
|
||||
/// <param name="size">Page entry number in response (should range from `5` to `20`).</param>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message will contain data of type `RoomList`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006301|server error: unknown|
|
||||
///
|
||||
/// A message of type `MessageType.Room_GetModeratedRooms` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `RoomList`, the room info does not contain the `UserList` info.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<RoomList> GetModeratedRooms(int index, int size)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<RoomList>(CLIB.ppf_Room_GetModeratedRooms(index, size));
|
||||
}
|
||||
|
||||
/// <summary>Invites a user to the current room.
|
||||
/// @note The user invited will receive a notification of type `MessageType.Notification_Room_InviteReceived`.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="roomId">The ID of the room.</param>
|
||||
/// <param name="token">The user's invitation token, which is returned by `RoomService.GetInvitableUsers2()`.</param>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message will contain data of type `Room`.
|
||||
///
|
||||
/// A message of type `MessageType.Room_InviteUser` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `Room`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<Room> InviteUser(UInt64 roomId, string token)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Room>(CLIB.ppf_Room_InviteUser(roomId, token));
|
||||
}
|
||||
|
||||
/// <summary>Joins the target room and meanwhile leaves the current room.</summary>
|
||||
///
|
||||
/// <param name="roomId">The ID of the room to join.</param>
|
||||
/// <param name="options">(Optional) Additional room configuration for this request.</param>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message will contain data of type `Room`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006401|logic state checking failed|
|
||||
/// |3006103|invalid room|
|
||||
/// |3006102|duplicate join room(regarded as normal entry)|
|
||||
/// |3006106|exceed max room player number|
|
||||
/// |3006105|illegal enter request(Players outside the legal list enter)|
|
||||
/// |3006108|room is locked|
|
||||
///
|
||||
/// A message of type `MessageType.Room_Join2` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `Room`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<Room> Join2(UInt64 roomId, RoomOptions options)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Room>(CLIB.ppf_Room_Join2(roomId, options.GetHandle()));
|
||||
}
|
||||
|
||||
/// <summary>Kicks a user out of a room. For use by homeowners only.</summary>
|
||||
///
|
||||
/// <param name="roomId">The ID of the room.</param>
|
||||
/// <param name="userId">The ID of the user to be kicked (cannot be yourself).</param>
|
||||
/// <param name="kickDuration">The Length of the ban (in seconds).</param>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message will contain data of type `Room`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006006|kick user failed: need room owner|
|
||||
/// |3006007|kick user failed: tgt user is not in the room|
|
||||
/// |3006008|kick user failed: can not kick self|
|
||||
///
|
||||
/// A message of type `MessageType.Room_KickUser` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `Room`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<Room> KickUser(UInt64 roomId, string userId, int kickDuration)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Room>(CLIB.ppf_Room_KickUser(roomId, userId, kickDuration));
|
||||
}
|
||||
|
||||
/// <summary>Leaves the current room.
|
||||
/// @note The room you are now in will be returned if the request succeeds.</summary>
|
||||
///
|
||||
/// <param name="roomId">The ID of the room.</param>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message will contain data of type `Room`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006401|logic state checking failed(e.g. not in the room)|
|
||||
/// |3006301|server error: unknown|
|
||||
///
|
||||
/// A message of type `MessageType.Room_Leave` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `Room`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<Room> Leave(UInt64 roomId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Room>(CLIB.ppf_Room_Leave(roomId));
|
||||
}
|
||||
|
||||
/// <summary>Sets the description of a room. For use by homeowners only.</summary>
|
||||
///
|
||||
/// <param name="roomId">The ID of the room to set description for.</param>
|
||||
/// <param name="description">The new description of the room.</param>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message will contain data of type `Room`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006005|set description failed: need room owner|
|
||||
///
|
||||
/// A message of type `MessageType.Room_SetDescription` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `Room`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<Room> SetDescription(UInt64 roomId, string description)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Room>(CLIB.ppf_Room_SetDescription(roomId, description));
|
||||
}
|
||||
|
||||
/// <summary>Locks/unlocks the membership of a room (the caller should be the room owner) to allow/disallow new members from being able to join the room.
|
||||
/// @note Locking membership will prevent other users from joining the room through `Join2()`, invitations, etc. Users that are in the room at the time of lock will be able to rejoin.</summary>
|
||||
///
|
||||
/// <param name="roomId">The ID of the room to lock/unlock membership for.</param>
|
||||
/// <param name="membershipLockStatus">The new membership status to set for the room:
|
||||
/// * `0`: Unknown
|
||||
/// * `1`: lock
|
||||
/// * `2`: unlock
|
||||
/// </param>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message will contain data of type `Room`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006104|not in room |
|
||||
/// |3006109|update membership lock: need room owner|
|
||||
///
|
||||
/// A message of type `MessageType.Room_UpdateMembershipLockStatus` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `Room`
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<Room> UpdateMembershipLockStatus(UInt64 roomId, RoomMembershipLockStatus membershipLockStatus)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Room>(CLIB.ppf_Room_UpdateMembershipLockStatus(roomId, membershipLockStatus));
|
||||
}
|
||||
|
||||
/// <summary>Modifies the owner of the room, this person needs to be the person in this room.</summary>
|
||||
///
|
||||
/// <param name="roomId">The ID of the room to change ownership for.</param>
|
||||
/// <param name="userId">The ID of the new user to own the room. The new user must be in the same room.</param>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message does not contain data.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006001|change owner failed: need room owner|
|
||||
/// |3006003|change owner failed: duplicate setting|
|
||||
/// |3006002|change owner failed: new owner not in this room|
|
||||
///
|
||||
/// A message of type `MessageType.Room_UpdateOwner` will be generated in response.
|
||||
/// Call `message.IsError()` to check if any error has occurred.
|
||||
/// </returns>
|
||||
public static Task UpdateOwner(UInt64 roomId, string userId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task(CLIB.ppf_Room_UpdateOwner(roomId, userId));
|
||||
}
|
||||
|
||||
/// <summary>Sets the join policy for a specified private room.</summary>
|
||||
///
|
||||
/// <param name="roomId">The ID of the room you want to set join policy for.</param>
|
||||
/// <param name="policy">Specifies who can join the room:
|
||||
/// * `0`: nobody
|
||||
/// * `1`: everybody
|
||||
/// * `2`: friends of members
|
||||
/// * `3`: friends of the room owner
|
||||
/// * `4`: invited users
|
||||
/// * `5`: unknown
|
||||
/// </param>
|
||||
/// <returns>Request information of type `Task`, including the request id, and its response message will contain data of type `Room`.
|
||||
/// | Error Code| Error Message |
|
||||
/// |---|---|
|
||||
/// |3006104|not in room |
|
||||
/// |3006112|update room join policy: need room owner|
|
||||
///
|
||||
/// A message of type `MessageType.Room_UpdatePrivateRoomJoinPolicy` will be generated in response.
|
||||
/// First call `message.IsError()` to check if any error has occurred.
|
||||
/// If no error has occurred, the message will contain a payload of type `Room`.
|
||||
/// Extract the payload from the message handle with `message.Data`.
|
||||
/// </returns>
|
||||
public static Task<Room> UpdatePrivateRoomJoinPolicy(UInt64 roomId, RoomJoinPolicy policy)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<Room>(CLIB.ppf_Room_UpdatePrivateRoomJoinPolicy(roomId, policy));
|
||||
}
|
||||
|
||||
/// <summary>Sets the callback to get notified when the user has accepted an invitation.
|
||||
/// @note You can get the RoomID by 'Message.Data'. Then you can call 'RoomService.Join2' to join it.
|
||||
/// </summary>
|
||||
/// <param name="handler">The callback function will be called when receiving the `Notification_Room_InviteAccepted` message.</param>
|
||||
public static void SetRoomInviteAcceptedNotificationCallback(Message<string>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Room_InviteAccepted, handler);
|
||||
}
|
||||
|
||||
/// <summary>Sets the callback to get notified when the current room has been updated. Use `Message.Data` to extract the room.</summary>
|
||||
///
|
||||
/// <param name="handler">The callback function will be called when receiving the `Notification_Room_RoomUpdate` message.</param>
|
||||
public static void SetUpdateNotificationCallback(Message<Room>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Room_RoomUpdate, handler);
|
||||
}
|
||||
|
||||
/// <summary>Sets the callback to get notified when the user has been kicked out of a room.
|
||||
/// Listen to this event to receive a relevant message. Use `Message.Data` to extract the room.</summary>
|
||||
///
|
||||
/// <param name="handler">The callback function will be called when receiving the `Room_KickUser` message and the value of `requestID` is `0`.</param>
|
||||
public static void SetKickUserNotificationCallback(Message<Room>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Room_KickUser, handler);
|
||||
}
|
||||
|
||||
/// <summary>Sets the callback to get notified when the room description has been updated.
|
||||
/// Listen to this event to receive a relevant message. Use `Message.Data` to extract the room.</summary>
|
||||
///
|
||||
/// <param name="handler">The callback function will be called when receiving the `Room_SetDescription` message and the value of `requestID` is `0`.</param>
|
||||
public static void SetSetDescriptionNotificationCallback(Message<Room>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Room_SetDescription, handler);
|
||||
}
|
||||
|
||||
/// <summary>Sets the callback to get notified when the room data has been modified.
|
||||
/// Listen to this event to receive a relevant message. Use `Message.Data` to extract the room.</summary>
|
||||
///
|
||||
/// <param name="handler">The callback function will be called when receiving the `Room_UpdateDataStore` message and the value of `requestID` is `0`.</param>
|
||||
public static void SetUpdateDataStoreNotificationCallback(Message<Room>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Room_UpdateDataStore, handler);
|
||||
}
|
||||
|
||||
/// <summary>If a player is passively removed from a room (for example, if they initiate another match within the room and are subsequently removed by the system or if they are kicked out of the room), they will receive a notification.
|
||||
/// Listen to this event to receive a relevant message.
|
||||
/// Use `Message.Data` to extract the room.</summary>
|
||||
///
|
||||
/// <param name="handler">The callback function will be called when receiving the `Room_Leave` message and the value of `requestID` is `0`.</param>
|
||||
public static void SetLeaveNotificationCallback(Message<Room>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Room_Leave, handler);
|
||||
}
|
||||
|
||||
/// <summary>If a player comes across network or disaster recovery problems after joining a room, they may not receive a notification confirming that they've successfully entered the room.
|
||||
/// In such cases, the server will resend the notification to ensure that the user receives it.
|
||||
/// Use `Message.Data` to extract the room.</summary>
|
||||
///
|
||||
/// <param name="handler">The callback function will be called when receiving the `Room_Join2` message and the value of `requestID` is `0`.</param>
|
||||
public static void SetJoin2NotificationCallback(Message<Room>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Room_Join2, handler);
|
||||
}
|
||||
|
||||
/// <summary>When there is a change in the room owner, the new owner will receive a notification.
|
||||
/// Listen to this event to receive a relevant message.
|
||||
/// Use `Message.Data` to extract the room.</summary>
|
||||
///
|
||||
/// <param name="handler">The callback function will be called when receiving the `Room_UpdateOwner` message and the value of `requestID` is `0`.</param>
|
||||
public static void SetUpdateOwnerNotificationCallback(Message.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Room_UpdateOwner, handler);
|
||||
}
|
||||
|
||||
/// <summary>Sets the callback to get notified when the membership status of a room has been changed.
|
||||
/// Listen to this event to receive a relevant message. Use `Message.Data` to extract the room.</summary>
|
||||
///
|
||||
/// <param name="handler">The callback function will be called when receiving the "Room_UpdateMembershipLockStatus" message and the value of `requestID` is `0`.</param>
|
||||
public static void SetUpdateMembershipLockStatusNotificationCallback(Message<Room>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Room_UpdateMembershipLockStatus, handler);
|
||||
}
|
||||
}
|
||||
|
||||
public class RoomOptions
|
||||
{
|
||||
public RoomOptions()
|
||||
{
|
||||
Handle = CLIB.ppf_RoomOptions_Create();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the data store for a room.
|
||||
/// </summary>
|
||||
/// <param name="key">A unique identifier that maps to a value.</param>
|
||||
/// <param name="value">The data.</param>
|
||||
public void SetDataStore(string key, string value)
|
||||
{
|
||||
CLIB.ppf_RoomOptions_SetDataStoreString(Handle, key, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the data store for a room.
|
||||
/// </summary>
|
||||
public void ClearDataStore()
|
||||
{
|
||||
CLIB.ppf_RoomOptions_ClearDataStore(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets whether to exclude recently-met users.
|
||||
/// </summary>
|
||||
/// <param name="value">
|
||||
/// * `true`: exclude
|
||||
/// * `false`: not exclude
|
||||
/// </param>
|
||||
public void SetExcludeRecentlyMet(bool value)
|
||||
{
|
||||
CLIB.ppf_RoomOptions_SetExcludeRecentlyMet(Handle, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the maximum number of users to return.
|
||||
/// </summary>
|
||||
/// <param name="value">The maximum number of users to return.</param>
|
||||
public void SetMaxUserResults(uint value)
|
||||
{
|
||||
CLIB.ppf_RoomOptions_SetMaxUserResults(Handle, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a room ID.
|
||||
/// @note Only available to \ref RoomService.GetInvitableUsers2.
|
||||
/// </summary>
|
||||
/// <param name="value">The room ID.</param>
|
||||
public void SetRoomId(UInt64 value)
|
||||
{
|
||||
CLIB.ppf_RoomOptions_SetRoomId(Handle, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a name for the room.
|
||||
/// @note Only available to \ref RoomService.JoinOrCreateNamedRoom and \ref RoomService.GetNamedRooms.
|
||||
/// </summary>
|
||||
/// <param name="roomName">The room's name. The maximum length is 64 characters.</param>
|
||||
public void SetRoomName(string roomName)
|
||||
{
|
||||
CLIB.ppf_RoomOptions_SetName(Handle, roomName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a password for the room.
|
||||
/// @note Only available to \ref RoomService.JoinOrCreateNamedRoom and \ref RoomService.GetNamedRooms.
|
||||
/// </summary>
|
||||
/// <param name="password">The room's password. The maximum length is 64 characters.</param>
|
||||
public void SetPassword(string password)
|
||||
{
|
||||
CLIB.ppf_RoomOptions_SetPassword(Handle, password);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables/Disables the update of room data.
|
||||
/// </summary>
|
||||
/// <param name="value">
|
||||
/// * `true`: enable
|
||||
/// * `false`: disable
|
||||
/// </param>
|
||||
public void SetTurnOffUpdates(bool value)
|
||||
{
|
||||
CLIB.ppf_RoomOptions_SetTurnOffUpdates(Handle, value);
|
||||
}
|
||||
|
||||
|
||||
/// For passing to native C
|
||||
public static explicit operator IntPtr(RoomOptions roomOptions)
|
||||
{
|
||||
return roomOptions != null ? roomOptions.Handle : IntPtr.Zero;
|
||||
}
|
||||
|
||||
~RoomOptions()
|
||||
{
|
||||
CLIB.ppf_RoomOptions_Destroy(Handle);
|
||||
}
|
||||
|
||||
IntPtr Handle;
|
||||
|
||||
public IntPtr GetHandle()
|
||||
{
|
||||
return Handle;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 288ca2a98b45b4d47957eae7a66fc97c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,120 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using Pico.Platform.Models;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
public class SpeechService
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the automatic speech recognition engine.
|
||||
/// </summary>
|
||||
/// <returns>The initialization result.</returns>
|
||||
public static AsrEngineInitResult InitAsrEngine()
|
||||
{
|
||||
return CLIB.ppf_Speech_InitAsrEngine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts automatic speech recognition (ASR).
|
||||
/// </summary>
|
||||
/// <param name="autoStop">Specifies whether to automatically stop ASR when the speaker stops speaking (i.e., when no voice is detected):
|
||||
/// * `true`: auto stop
|
||||
/// * `false`: do not auto stop
|
||||
/// </param>
|
||||
/// <param name="showPunctual">Specifies whether to show punctuations in the text:
|
||||
/// * `true`: show
|
||||
/// * `false`: do not show
|
||||
/// </param>
|
||||
/// <param name="vadMaxDurationInSeconds">Specifies the maximum duration allowed for speaking per time. Unit: milliseconds.</param>
|
||||
/// <returns>
|
||||
/// `0` indicates success and other values indicates failure.
|
||||
/// </returns>
|
||||
public static int StartAsr(bool autoStop, bool showPunctual, int vadMaxDurationInSeconds)
|
||||
{
|
||||
var option = new StartAsrOptions();
|
||||
option.SetAutoStop(autoStop);
|
||||
option.SetShowPunctual(showPunctual);
|
||||
option.SetVadMaxDurationInSeconds(vadMaxDurationInSeconds);
|
||||
return CLIB.ppf_Speech_StartAsr((IntPtr) option);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops automatic speech recognition.
|
||||
/// </summary>
|
||||
public static void StopAsr()
|
||||
{
|
||||
CLIB.ppf_Speech_StopAsr();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When automatic speech recognition is enabled, it constantly converts the transmitted speech into text and returns it through the callback.
|
||||
/// @note After reconnection following a network disconnection during the recognition process, only the text recognized from the speech after the reconnection will be returned,
|
||||
/// and the text recognized from the speech before the disconnection will not be returned.
|
||||
/// </summary>
|
||||
/// <param name="handler">Returns the recognition result.</param>
|
||||
public static void SetOnAsrResultCallback(Message<AsrResult>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Speech_OnAsrResult, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If an error occurs during the speech recognition process, it will be returned through this callback.
|
||||
/// </summary>
|
||||
/// <param name="handler">Returns the information about the error.</param>
|
||||
public static void SetOnSpeechErrorCallback(Message<SpeechError>.Handler handler)
|
||||
{
|
||||
Looper.RegisterNotifyHandler(MessageType.Notification_Speech_OnSpeechError, handler);
|
||||
}
|
||||
}
|
||||
|
||||
public class StartAsrOptions
|
||||
{
|
||||
public StartAsrOptions()
|
||||
{
|
||||
Handle = CLIB.ppf_StartAsrOptions_Create();
|
||||
}
|
||||
|
||||
|
||||
public void SetAutoStop(bool value)
|
||||
{
|
||||
CLIB.ppf_StartAsrOptions_SetAutoStop(Handle, value);
|
||||
}
|
||||
|
||||
|
||||
public void SetVadMaxDurationInSeconds(int value)
|
||||
{
|
||||
CLIB.ppf_StartAsrOptions_SetVadMaxDurationInSeconds(Handle, value);
|
||||
}
|
||||
|
||||
|
||||
public void SetShowPunctual(bool value)
|
||||
{
|
||||
CLIB.ppf_StartAsrOptions_SetShowPunctual(Handle, value);
|
||||
}
|
||||
|
||||
/// For passing to native C
|
||||
public static explicit operator IntPtr(StartAsrOptions options)
|
||||
{
|
||||
return options != null ? options.Handle : IntPtr.Zero;
|
||||
}
|
||||
|
||||
~StartAsrOptions()
|
||||
{
|
||||
CLIB.ppf_StartAsrOptions_Destroy(Handle);
|
||||
}
|
||||
|
||||
public IntPtr Handle;
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c640c57562fe4afd8f49c65022cc336b
|
||||
timeCreated: 1679484591
|
@ -0,0 +1,108 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
*
|
||||
* SportService provides multiple APIs for you to access
|
||||
* users' exercise data from the built-in PICO app — PICO Fitness.
|
||||
|
||||
* When users are working out with PICO VR headsets, the app records
|
||||
* their exercise data, including exercise duration, calories burned,
|
||||
* exercise plan, preferences, and more.
|
||||
|
||||
* With the APIs provided by the service, you can gather data to
|
||||
* understand the exercise habits of individuals, thereby providing
|
||||
* users with a better exercise experience.
|
||||
*/
|
||||
public static class SportService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a user's basic information and exercise plan.
|
||||
/// </summary>
|
||||
/// <returns>The \ref Pico.Platform.Models.SportUserInfo class containing the following:
|
||||
/// * `Gender`
|
||||
/// * `Birthday`
|
||||
/// * `Stature`: The natural height in centimeters.
|
||||
/// * `Weight`: The weight in kilograms.
|
||||
/// * `SportLevel`: `1`-low; `2`-medium; `3`-high.
|
||||
/// * `DailyDurationInMinutes`: The planned daily exercise duration (in minutes).
|
||||
/// * `DaysPerWeek`: The planned days for exercise per week.
|
||||
/// * `SportTarget`: "lose weight" or "stay healthy".
|
||||
/// </returns>
|
||||
public static Task<SportUserInfo> GetUserInfo()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<SportUserInfo>(CLIB.ppf_Sport_GetUserInfo());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a summary of the user's daily exercise data for a specified period within the recent 90 days.
|
||||
/// For example, if the period you set is between 2022/08/16 and 2022/08/18, the exercise data generated on 08/16, 08/17, and 08/18 will be returned.
|
||||
/// </summary>
|
||||
/// <param name="beginTime">A DateTime struct defining the begin time of the period. The begin time should be no earlier than 90 days before the current time.</param>
|
||||
/// <param name="endTime">A DateTime struct defining the end time of the period, .</param>
|
||||
/// <returns>The \ref Pico.Platform.Models.SportDailySummaryList class containing the exercise data generated on each day within the specified period, including:
|
||||
/// * `Id`: Summary ID.
|
||||
/// * `Date`: The date when the data was generated.
|
||||
/// * `DurationInSeconds`: The actual daily exercise duration in seconds.
|
||||
/// * `PlanDurationInMinutes`: The planned daily exercise duration in minutes.
|
||||
/// * `Calorie`: The actual daily calorie burned.
|
||||
/// * `PlanCalorie`: The planned daily calorie to burn.
|
||||
/// </returns>
|
||||
public static Task<SportDailySummaryList> GetDailySummary(DateTime beginTime, DateTime endTime)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<SportDailySummaryList>(CLIB.ppf_Sport_GetDailySummary(TimeUtil.DateTimeToMilliSeconds(beginTime), TimeUtil.DateTimeToMilliSeconds(endTime)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a summary of the user's exercise data for a specified period within
|
||||
/// the recent 24 hours. The period should not exceed 24 hours.
|
||||
/// </summary>
|
||||
/// <param name="beginTime">A DateTime struct defining the begin time of the period. The begin time should be no earlier than 24 hours before the current time.</param>
|
||||
/// <param name="endTime">A DateTime struct defining the end time of the period.</param>
|
||||
/// <returns>The \ref Pico.Platform.Models.SportSummary class containing the following:
|
||||
/// * `DurationInSeconds`: The actual exercise duration.
|
||||
/// * `Calorie`: The actual calorie burned.
|
||||
/// * `StartTime`: The start time you defined.
|
||||
/// * `EndTime`: The end time you defined.
|
||||
/// </returns>
|
||||
public static Task<SportSummary> GetSummary(DateTime beginTime, DateTime endTime)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<SportSummary>(CLIB.ppf_Sport_GetSummary(TimeUtil.DateTimeToMilliSeconds(beginTime), TimeUtil.DateTimeToMilliSeconds(endTime)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9138eed51e124e57aac6c3c6a2198ce9
|
||||
timeCreated: 1657617033
|
@ -0,0 +1,290 @@
|
||||
/*******************************************************************************
|
||||
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
|
||||
|
||||
NOTICE:All information contained herein is, and remains the property of
|
||||
PICO Technology Co., Ltd. The intellectual and technical concepts
|
||||
contained herein are proprietary to PICO Technology Co., Ltd. and may be
|
||||
covered by patents, patents in process, and are protected by trade secret or
|
||||
copyright law. Dissemination of this information or reproduction of this
|
||||
material is strictly forbidden unless prior written permission is obtained from
|
||||
PICO Technology Co., Ltd.
|
||||
*******************************************************************************/
|
||||
|
||||
using System;
|
||||
using Pico.Platform.Models;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pico.Platform
|
||||
{
|
||||
/**
|
||||
* \ingroup Platform
|
||||
*
|
||||
* Account & Friends service allows developers to access the info of a specified account, get the friends list of the currently logged-in users, send friend requests, and more.
|
||||
*/
|
||||
public static class UserService
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns an access token for this user. Starting from SDK V2.2.0,
|
||||
/// the system caches the access token upon the first request, allowing subsequent requests to use the cached token information stored locally.
|
||||
/// @note User's permission is required if the user uses this app for the first time.
|
||||
/// </summary>
|
||||
/// <returns>The access token for the current user.</returns>
|
||||
public static Task<string> GetAccessToken()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<string>(CLIB.ppf_User_GetAccessToken());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the organization ID for a specified user.
|
||||
/// Different users have different organization IDs.
|
||||
/// A user has only one fixed unique organization ID for all the apps created by the same organization.
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="userID">The ID of the user. It's the user's openID in the current app.</param>
|
||||
/// <returns>The `OrgScopedID` structure that contains the user's organization ID.</returns>
|
||||
public static Task<OrgScopedID> GetOrgScopedID(string userID)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<OrgScopedID>(CLIB.ppf_User_GetOrgScopedID(userID));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the information about the current logged-in user.
|
||||
/// </summary>
|
||||
/// <returns>The User structure that contains the details about the user.</returns>
|
||||
public static Task<User> GetLoggedInUser()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<User>(CLIB.ppf_User_GetLoggedInUser());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the information about a specified user.
|
||||
/// @note The same user has different user IDs for different apps.
|
||||
/// </summary>
|
||||
/// <param name="userId">The ID of the user.</param>
|
||||
/// <returns>The User structure that contains the details about the specified user.</returns>
|
||||
public static Task<User> Get(string userId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<User>(CLIB.ppf_User_Get(userId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the friend list of the current user.
|
||||
/// @note Friends who don't use this app won't appear in this list.
|
||||
/// </summary>
|
||||
/// <returns>The friend list of the current user.</returns>
|
||||
public static Task<UserList> GetFriends()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<UserList>(CLIB.ppf_User_GetLoggedInUserFriends());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the relationship between the current user and other users.
|
||||
/// </summary>
|
||||
/// <param name="userIds">The list of user IDs.
|
||||
/// The request queries the current user's relationship with specified users.
|
||||
/// A single request can pass no more than 20 user IDs.</param>
|
||||
/// <returns>`UserRelationResult` which is a dictionary of user relationships.</returns>
|
||||
public static Task<UserRelationResult> GetUserRelations(string[] userIds)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<UserRelationResult>(CLIB.ppf_User_GetRelations(userIds));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Launches the flow to apply for friendship with someone.
|
||||
/// </summary>
|
||||
/// <param name="userId">The ID of the user that the friend request is sent to.</param>
|
||||
/// <returns>`LaunchFriendRequest` that indicates whether the request is sent successfully.</returns>
|
||||
public static Task<LaunchFriendResult> LaunchFriendRequestFlow(string userId)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<LaunchFriendResult>(CLIB.ppf_User_LaunchFriendRequestFlow(userId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the friends of the logged-in user and the rooms the friends might be in.
|
||||
/// </summary>
|
||||
/// <returns>`UserRoomList` that contains the friend and room data. If a friend is not in any room, the `room` field will be null.</returns>
|
||||
public static Task<UserRoomList> GetFriendsAndRooms()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<UserRoomList>(CLIB.ppf_User_GetLoggedInUserFriendsAndRooms());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next page of user and room list.
|
||||
/// </summary>
|
||||
/// <param name="list">The user and room list from the current page.</param>
|
||||
/// <returns>The user and room list from the next page.</returns>
|
||||
public static Task<UserRoomList> GetNextUserAndRoomListPage(UserRoomList list)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!list.HasNextPage)
|
||||
{
|
||||
Debug.LogWarning("GetNextUserAndRoomListPage: List has no next page");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(list.NextPageParam))
|
||||
{
|
||||
Debug.LogWarning("GetNextUserAndRoomListPage: list.NextPageParam is empty");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<UserRoomList>(CLIB.ppf_User_GetNextUserAndRoomArrayPage(list.NextPageParam));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next page of user list.
|
||||
/// </summary>
|
||||
/// <param name="list">The user list from the current page.</param>
|
||||
/// <returns>The user list from the next page.</returns>
|
||||
public static Task<UserList> GetNextUserListPage(UserList list)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!list.HasNextPage)
|
||||
{
|
||||
Debug.LogWarning("GetNextUserListPage: List has no next page");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(list.NextPageParam))
|
||||
{
|
||||
Debug.LogWarning("GetNextUserListPage: list.NextPageParam is empty");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<UserList>(CLIB.ppf_User_GetNextUserArrayPage(list.NextPageParam));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets authorized permissions.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A struct containing the access token and permission list. The `UserID` field is empty so do NOT use it.
|
||||
/// </returns>
|
||||
public static Task<PermissionResult> GetAuthorizedPermissions()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<PermissionResult>(CLIB.ppf_User_GetAuthorizedPermissions());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests user permissions. The user will received a pop-up notification window.
|
||||
/// </summary>
|
||||
/// <param name="permissionList">The list of permissions to request. You can use constants in \ref Pico.Platform.Models.Permissions.
|
||||
/// </param>
|
||||
/// <returns>A struct containing the access token and permission list.</returns>
|
||||
public static Task<PermissionResult> RequestUserPermissions(params string[] permissionList)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<PermissionResult>(CLIB.ppf_User_RequestUserPermissions(permissionList));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the current user is entitled to use the current app.
|
||||
///
|
||||
/// If the user is not entitled, the system will close the app and show a dialog box to remind the user to buy the app from the PICO Store.
|
||||
/// For customizations, you can set param `killApp` to `false` and then customize the dialog.
|
||||
/// </summary>
|
||||
/// <param name="killApp">Determines whether the system closes the app if the user fails to pass the entitlement check.
|
||||
/// The default value is `true`.
|
||||
/// </param>
|
||||
/// <returns>The entitlement check result.</returns>
|
||||
public static Task<EntitlementCheckResult> EntitlementCheck(bool killApp = true)
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<EntitlementCheckResult>(CLIB.ppf_User_EntitlementCheck(killApp));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID token for the current user. The ID token is used for OIDC login.
|
||||
/// You can use \ref ApplicationService.GetSystemInfo to determine the region of user's device and then choose the proper OIDC identity provider.
|
||||
/// Read the following articles for more information:
|
||||
/// * [Unity Service signin with openID connect](https://docs.unity.com/authentication/en/manual/platform-signin-openid-connect)
|
||||
/// * [PICO SDK guide](http://developer-global.pico-interactive.com/document/unity/accounts-and-friends/)
|
||||
/// @note User's permission is required if the user uses this app for the first time. Call \ref UserService.RequestUserPermissions to request desired permissions in a batch.
|
||||
/// </summary>
|
||||
/// <returns>The ID token for the current user.</returns>
|
||||
public static Task<string> GetIdToken()
|
||||
{
|
||||
if (!CoreService.Initialized)
|
||||
{
|
||||
Debug.LogError(CoreService.NotInitializedError);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Task<string>(CLIB.ppf_User_GetIdToken());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d99829583dd409e439ddfb0930207154
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user