Загрузка PICO Unity OpenXR Integration SDK

This commit is contained in:
2024-12-21 10:28:02 +03:00
parent b2ecc77b2a
commit a2c2504d48
628 changed files with 68895 additions and 2 deletions

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: afc99c2a85af4b79b8d17dadaf00b40e
timeCreated: 1660284708

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d10b07d0efa7915488f7ac6e32eb5eb6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,118 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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 System.Runtime.InteropServices;
namespace Pico.Platform
{
public partial class CLIB
{
public static ulong ppf_Achievements_GetProgressByName(string[] names)
{
var namesHandle = new PtrArray(names);
var result = ppf_Achievements_GetProgressByName(namesHandle.a, names.Length);
namesHandle.Free();
return result;
}
public static ulong ppf_Achievements_GetDefinitionsByName(string[] names)
{
var namesHandle = new PtrArray(names);
var result = ppf_Achievements_GetDefinitionsByName(namesHandle.a, names.Length);
namesHandle.Free();
return result;
}
public static ulong ppf_IAP_GetProductsBySKU(string[] names)
{
var namesHandle = new PtrArray(names);
var result = ppf_IAP_GetProductsBySKU(namesHandle.a, names.Length);
namesHandle.Free();
return result;
}
public static ulong ppf_Leaderboard_GetEntriesByIds(string leaderboardName, int pageSize, int pageIdx, LeaderboardStartAt startAt, string[] userIDs)
{
var userIds = new PtrArray(userIDs);
var result = ppf_Leaderboard_GetEntriesByIds(leaderboardName, pageSize, pageIdx, startAt, userIds.a, (uint) userIDs.Length);
userIds.Free();
return result;
}
public static ulong ppf_Challenges_GetEntriesByIds(ulong challengeID, LeaderboardStartAt startAt, string[] userIDs, int pageIdx, int pageSize)
{
var userIds = new PtrArray(userIDs);
var result = ppf_Challenges_GetEntriesByIds(challengeID, startAt, userIds.a, (uint) userIDs.Length, pageIdx, pageSize);
userIds.Free();
return result;
}
public static ulong ppf_Challenges_Invites(ulong challengeID, string[] userIDs)
{
var userIds = new PtrArray(userIDs);
var result = ppf_Challenges_Invites(challengeID, userIds.a, (uint) userIDs.Length);
userIds.Free();
return result;
}
public static ulong ppf_User_RequestUserPermissions(string[] permissions)
{
var ptrs = new PtrArray(permissions);
var result = ppf_User_RequestUserPermissions(ptrs.a, permissions.Length);
ptrs.Free();
return result;
}
public static ulong ppf_User_GetRelations(string[] userIds)
{
var ptrs = new PtrArray(userIds);
var result = ppf_User_GetRelations(ptrs.a, userIds.Length);
ptrs.Free();
return result;
}
public static ulong ppf_Presence_SendInvites(string[] userIDs)
{
var ptrs = new PtrArray(userIDs);
var result = ppf_Presence_SendInvites(ptrs.a, (uint) userIDs.Length);
ptrs.Free();
return result;
}
public static Dictionary<string, string> DataStoreFromNative(IntPtr ppfDataStore)
{
var map = new Dictionary<string, string>();
var size = (int) ppf_DataStore_GetNumKeys(ppfDataStore);
for (var i = 0; i < size; i++)
{
string key = ppf_DataStore_GetKey(ppfDataStore, i);
map[key] = ppf_DataStore_GetValue(ppfDataStore, key);
}
return map;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int RtcProcessAudioFrameFunction(IntPtr audioFrameHandle);
[DllImport("pxrplatformloader", EntryPoint = "ppf_Rtc_RegisterLocalAudioProcessor", CallingConvention = CallingConvention.Cdecl)]
public static extern void ppf_Rtc_RegisterLocalAudioProcessor(RtcProcessAudioFrameFunction rtcProcessAudioFrameFunction, RtcAudioChannel channel, RtcAudioSampleRate sampleRate);
[DllImport("pxrplatformloader", EntryPoint = "ppf_InitializeAndroid", CallingConvention = CallingConvention.Cdecl)]
public static extern PlatformInitializeResult ppf_InitializeAndroid(string appId, IntPtr activityObj, IntPtr env);
[DllImport("pxrplatformloader", EntryPoint = "ppf_InitializeAndroidAsynchronous", CallingConvention = CallingConvention.Cdecl)]
public static extern ulong ppf_InitializeAndroidAsynchronous(string appId, IntPtr activityObj, IntPtr env);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d8426d258c3f4a19950866175d24fdcf
timeCreated: 1660302689

View File

@ -0,0 +1,171 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace Pico.Platform
{
public class UTF8Marshaller : ICustomMarshaler
{
public void CleanUpManagedData(object ManagedObj)
{
}
public void CleanUpNativeData(IntPtr pNativeData)
=> Marshal.FreeHGlobal(pNativeData);
public int GetNativeDataSize() => -1;
public IntPtr MarshalManagedToNative(object managedObj)
{
if (managedObj == null)
return IntPtr.Zero;
if (!(managedObj is string))
throw new MarshalDirectiveException("UTF8Marshaler must be used on a string.");
return MarshalUtil.StringToPtr((string) managedObj);
}
public object MarshalNativeToManaged(IntPtr str)
{
if (str == IntPtr.Zero)
return null;
return MarshalUtil.PtrToString(str);
}
public static ICustomMarshaler GetInstance(string pstrCookie)
{
if (marshaler == null)
marshaler = new UTF8Marshaller();
return marshaler;
}
private static UTF8Marshaller marshaler;
}
public class PtrManager
{
public IntPtr ptr;
private bool freed = false;
public PtrManager(byte[] a)
{
this.ptr = MarshalUtil.ByteArrayToNative(a);
}
public void Free()
{
if (freed) return;
freed = true;
Marshal.FreeHGlobal(ptr);
}
~PtrManager()
{
this.Free();
}
}
class PtrArray
{
public IntPtr[] a;
private bool freed = false;
public PtrArray(string[] a)
{
if (a == null)
{
a = Array.Empty<string>();
}
this.a = a.Select(x => MarshalUtil.StringToPtr(x)).ToArray();
}
public void Free()
{
if (freed) return;
freed = true;
foreach (var i in a)
{
Marshal.FreeHGlobal(i);
}
}
~PtrArray()
{
this.Free();
}
}
public static class MarshalUtil
{
public static IntPtr StringToPtr(string s)
{
if (s == null) return IntPtr.Zero;
// not null terminated
byte[] strbuf = Encoding.UTF8.GetBytes(s);
IntPtr buffer = Marshal.AllocHGlobal(strbuf.Length + 1);
Marshal.Copy(strbuf, 0, buffer, strbuf.Length);
// write the terminating null
Marshal.WriteByte(buffer + strbuf.Length, 0);
return buffer;
}
public static string PtrToString(IntPtr p)
{
return GetString(Encoding.UTF8, p);
}
public static string GetString(Encoding encoding, IntPtr str)
{
if (str == IntPtr.Zero)
return null;
int byteCount = 0;
if (Equals(encoding, Encoding.UTF32))
{
while (Marshal.ReadInt32(str, byteCount) != 0) byteCount += sizeof(int);
}
else if (Equals(encoding, Encoding.Unicode) || Equals(encoding, Encoding.BigEndianUnicode))
{
while (Marshal.ReadInt16(str, byteCount) != 0) byteCount += sizeof(short);
}
else
{
while (Marshal.ReadByte(str, byteCount) != 0) byteCount += sizeof(byte);
}
var bytes = new byte[byteCount];
Marshal.Copy(str, bytes, 0, byteCount);
return encoding.GetString(bytes);
}
public static byte[] ByteArrayFromNative(IntPtr ptr, uint length)
{
var ans = new byte[length];
Marshal.Copy(ptr, ans, 0, (int) length);
return ans;
}
public static IntPtr ByteArrayToNative(byte[] a)
{
var ptr = Marshal.AllocHGlobal(a.Length);
Marshal.Copy(a, 0, ptr, a.Length);
return ptr;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a97b494aeb644a0f9e1f1dc041b13a4e
timeCreated: 1660145702

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b9532b7f0304176428dc114e63d9533a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,170 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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.Concurrent;
using UnityEngine;
namespace Pico.Platform
{
public class Looper
{
private static readonly ConcurrentDictionary<ulong, Delegate> TaskMap = new ConcurrentDictionary<ulong, Delegate>();
private static readonly ConcurrentDictionary<MessageType, Delegate> NotifyMap = new ConcurrentDictionary<MessageType, Delegate>();
public static readonly ConcurrentDictionary<MessageType, MessageParser> MessageParserMap = new ConcurrentDictionary<MessageType, MessageParser>();
public static void ProcessMessages(uint limit = 0)
{
if (limit == 0)
{
while (true)
{
var msg = PopMessage();
if (msg == null)
{
break;
}
dispatchMessage(msg);
}
}
else
{
for (var i = 0; i < limit; ++i)
{
var msg = PopMessage();
if (msg == null)
{
break;
}
dispatchMessage(msg);
}
}
}
public static Message PopMessage()
{
if (!CoreService.Initialized)
{
return null;
}
var handle = CLIB.ppf_PopMessage();
if (handle == IntPtr.Zero)
{
return null;
}
MessageType messageType = CLIB.ppf_Message_GetType(handle);
Message msg = MessageQueue.ParseMessage(handle);
if (msg == null)
{
if (MessageParserMap.TryGetValue(messageType, out MessageParser parser))
{
msg = parser(handle);
}
}
if (msg == null)
{
Debug.LogError($"Cannot parse message type {messageType}");
}
CLIB.ppf_FreeMessage(handle);
return msg;
}
private static void dispatchMessage(Message msg)
{
if (msg.RequestID != 0)
{
// handle task
if (TaskMap.TryGetValue(msg.RequestID, out var handler))
{
try
{
handler.DynamicInvoke(msg);
}
catch (Exception e)
{
Debug.LogError($"dispatchMessage failed {e}");
}
finally
{
TaskMap.TryRemove(msg.RequestID, out handler);
}
}
else
{
Debug.LogError($"No handler for task: requestId={msg.RequestID}, msg.Type = {msg.Type}. You should call `OnComplete()` when use request API.");
}
}
else
{
// handle notification
if (NotifyMap.TryGetValue(msg.Type, out var handler))
{
handler.DynamicInvoke(msg);
}
else
{
//Debug.LogError($"No handler for notification: msg.Type = {msg.Type}");
}
}
}
public static void RegisterTaskHandler(ulong taskId, Delegate handler)
{
if (taskId == 0)
{
Debug.LogError("The task is invalid.");
return;
}
TaskMap[taskId] = handler;
}
public static void RegisterNotifyHandler(MessageType type, Delegate handler)
{
if (handler == null)
{
Debug.LogError("Cannot register null notification handler.");
return;
}
NotifyMap[type] = handler;
}
public static void RegisterMessageParser(MessageType messageType, MessageParser messageParser)
{
if (messageParser == null)
{
Debug.LogError($"invalid message parser for {messageType}");
return;
}
if (MessageParserMap.ContainsKey(messageType))
{
Debug.LogWarning($"Duplicate register of {messageType}");
}
MessageParserMap.TryAdd(messageType, messageParser);
}
public static void Clear()
{
TaskMap.Clear();
NotifyMap.Clear();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 26c0fea4ad144b74f9173e5b4ad26287
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,117 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
public class Error
{
public readonly int Code;
public readonly string Message;
public Error(int code, string msg)
{
this.Code = code;
this.Message = msg;
}
public Error(IntPtr handle)
{
this.Code = CLIB.ppf_Error_GetCode(handle);
this.Message = CLIB.ppf_Error_GetMessage(handle);
}
public override string ToString()
{
return $"Error(Code={this.Code},Message={this.Message})";
}
}
public class MessageArray<T> : List<T>
{
/**@brief The next page parameter. It's empty when it doesn't has next page.*/
public string NextPageParam;
/**@brief The previous page parameter. It's empty when it doesn't has previous page.*/
public string PreviousPageParam;
public bool HasNextPage => !String.IsNullOrEmpty(NextPageParam);
public bool HasPreviousPage => !String.IsNullOrEmpty(PreviousPageParam);
}
}
namespace Pico.Platform
{
public class Message
{
public delegate void Handler(Message message);
public readonly MessageType Type;
public readonly ulong RequestID;
public readonly Error Error;
public Message(IntPtr msgPointer)
{
Type = CLIB.ppf_Message_GetType(msgPointer);
RequestID = CLIB.ppf_Message_GetRequestID(msgPointer);
if (CLIB.ppf_Message_IsError(msgPointer))
{
Error = new Error(CLIB.ppf_Message_GetError(msgPointer));
}
}
public bool IsError => Error != null && Error.Code != 0;
[Obsolete("Use Error instead")]
public Error GetError()
{
return Error;
}
}
public class Message<T> : Message
{
public new delegate void Handler(Message<T> message);
public readonly T Data;
public delegate T GetDataFromMessage(IntPtr msgPointer);
public Message(IntPtr msgPointer, GetDataFromMessage getData) : base(msgPointer)
{
if (!IsError)
{
Data = getData(msgPointer);
}
}
}
public delegate Message MessageParser(IntPtr ptr);
public static class CommonParsers
{
public static Message StringParser(IntPtr msgPointer)
{
return new Message<string>(msgPointer, ptr => { return CLIB.ppf_Message_GetString(ptr); });
}
public static Message VoidParser(IntPtr msgPointer)
{
return new Message(msgPointer);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 47be01e871da24aba8e67d2bd8b6646c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,923 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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 MessageQueue
{
public static Message ParseMessage(IntPtr msgPointer)
{
Message msg = null;
MessageType messageType = CLIB.ppf_Message_GetType(msgPointer);
switch (messageType)
{
case MessageType.PlatformInitializeAndroidAsynchronous:
{
msg = new Message<PlatformInitializeResult>(msgPointer, ptr => { return (PlatformInitializeResult) CLIB.ppf_Message_GetInt32(ptr); });
break;
}
case MessageType.CloudStorage_StartNewBackup:
{
msg = new Message(msgPointer);
break;
}
#region speech
case MessageType.Notification_Speech_OnAsrResult:
{
msg = new Message<AsrResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetAsrResult(ptr);
return new AsrResult(obj);
});
break;
}
case MessageType.Notification_Speech_OnSpeechError:
{
msg = new Message<SpeechError>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetSpeechError(ptr);
return new SpeechError(obj);
});
break;
}
#endregion
#region Highlight
case MessageType.Highlight_StartSession:
{
msg = new Message<string>(msgPointer, ptr => { return CLIB.ppf_Message_GetString(ptr); });
break;
}
case MessageType.Highlight_CaptureScreen:
{
msg = new Message<CaptureInfo>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetCaptureInfo(ptr);
if (obj == IntPtr.Zero) return null;
return new CaptureInfo(obj);
});
break;
}
case MessageType.Highlight_ListMedia:
{
msg = new Message<SessionMedia>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetSessionMedia(ptr);
if (obj == IntPtr.Zero) return null;
return new SessionMedia(obj);
});
break;
}
case MessageType.Highlight_SaveMedia:
case MessageType.Highlight_ShareMedia:
case MessageType.Highlight_StartRecord:
{
msg = new Message(msgPointer);
break;
}
case MessageType.Highlight_StopRecord:
case MessageType.Notification_Highlight_OnRecordStop:
{
msg = new Message<RecordInfo>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRecordInfo(ptr);
if (obj == IntPtr.Zero) return null;
return new RecordInfo(obj);
});
break;
}
#endregion
#region compliance
case MessageType.Compliance_DetectSensitive:
{
msg = new Message<DetectSensitiveResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetDetectSensitiveResult(ptr);
if (obj == IntPtr.Zero) return null;
return new DetectSensitiveResult(obj);
});
break;
}
#endregion
#region Sport
case MessageType.Sport_GetSummary:
{
msg = new Message<SportSummary>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetSportSummary(ptr);
if (obj == IntPtr.Zero) return null;
return new SportSummary(obj);
});
break;
}
case MessageType.Sport_GetDailySummary:
{
msg = new Message<SportDailySummaryList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetSportDailySummaryArray(ptr);
if (obj == IntPtr.Zero) return null;
return new SportDailySummaryList(obj);
});
break;
}
case MessageType.Sport_GetUserInfo:
{
msg = new Message<SportUserInfo>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetSportUserInfo(ptr);
if (obj == IntPtr.Zero) return null;
return new SportUserInfo(obj);
});
break;
}
#endregion
#region User
case MessageType.User_EntitlementCheck:
{
msg = new Message<EntitlementCheckResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetEntitlementCheckResult(ptr);
if (obj == IntPtr.Zero) return null;
return new EntitlementCheckResult(obj);
});
break;
}
case MessageType.User_GetAuthorizedPermissions:
case MessageType.User_RequestUserPermissions:
{
msg = new Message<PermissionResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetPermissionResult(ptr);
if (obj == IntPtr.Zero) return null;
return new PermissionResult(obj);
});
break;
}
case MessageType.User_GetLoggedInUserFriendsAndRooms:
{
msg = new Message<UserRoomList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetUserAndRoomArray(ptr);
if (obj == IntPtr.Zero) return null;
var data = new UserRoomList(obj);
return data;
});
break;
}
case MessageType.Presence_GetSentInvites:
{
msg = new Message<ApplicationInviteList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetApplicationInviteArray(ptr);
if (obj == IntPtr.Zero) return null;
var data = new ApplicationInviteList(obj);
return data;
});
break;
}
case MessageType.Presence_SendInvites:
{
msg = new Message<SendInvitesResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetSendInvitesResult(ptr);
if (obj == IntPtr.Zero) return null;
var data = new SendInvitesResult(obj);
return data;
});
break;
}
case MessageType.Presence_GetDestinations:
{
msg = new Message<DestinationList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetDestinationArray(ptr);
if (obj == IntPtr.Zero) return null;
var data = new DestinationList(obj);
return data;
});
break;
}
case MessageType.User_GetAccessToken:
case MessageType.User_GetIdToken:
case MessageType.Rtc_GetToken:
case MessageType.Notification_Rtc_OnTokenWillExpire:
case MessageType.Notification_Rtc_OnUserStartAudioCapture:
case MessageType.Notification_Rtc_OnUserStopAudioCapture:
case MessageType.Application_LaunchOtherApp:
case MessageType.Application_LaunchStore:
case MessageType.Notification_Room_InviteAccepted:
case MessageType.Notification_Challenge_LaunchByInvite:
case MessageType.Notification_ApplicationLifecycle_LaunchIntentChanged:
{
msg = new Message<string>(msgPointer, ptr => { return CLIB.ppf_Message_GetString(ptr); });
break;
}
case MessageType.Notification_Presence_JoinIntentReceived:
{
msg = new Message<PresenceJoinIntent>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetPresenceJoinIntent(ptr);
if (obj == IntPtr.Zero) return null;
return new PresenceJoinIntent(obj);
});
break;
}
case MessageType.Application_GetVersion:
{
msg = new Message<ApplicationVersion>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetApplicationVersion(ptr);
if (obj == IntPtr.Zero) return null;
return new ApplicationVersion(obj);
});
break;
}
case MessageType.User_GetLoggedInUser:
case MessageType.User_Get:
{
msg = new Message<User>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetUser(ptr);
if (obj == IntPtr.Zero) return null;
return new User(obj);
});
break;
}
case MessageType.User_GetOrgScopedID:
{
msg = new Message<OrgScopedID>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetOrgScopedID(ptr);
if (obj == IntPtr.Zero) return null;
return new OrgScopedID(obj);
});
break;
}
case MessageType.User_LaunchFriendRequestFlow:
{
msg = new Message<LaunchFriendResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetLaunchFriendRequestFlowResult(ptr);
if (obj == IntPtr.Zero) return null;
return new LaunchFriendResult(obj);
});
break;
}
case MessageType.User_GetLoggedInUserFriends:
case MessageType.Room_GetInvitableUsers2:
case MessageType.Presence_GetInvitableUsers:
{
msg = new Message<UserList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetUserArray(ptr);
if (obj == IntPtr.Zero) return null;
return new UserList(obj);
});
break;
}
case MessageType.User_GetRelations:
{
msg = new Message<UserRelationResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetUserRelationResult(ptr);
if (obj == IntPtr.Zero) return null;
return new UserRelationResult(obj);
});
break;
}
#endregion
#region RTC
case MessageType.Notification_Rtc_OnRoomMessageReceived:
{
msg = new Message<RtcRoomMessageReceived>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcRoomMessageReceived(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcRoomMessageReceived(obj);
});
break;
}
case MessageType.Notification_Rtc_OnUserMessageReceived:
{
msg = new Message<RtcUserMessageReceived>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcUserMessageReceived(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcUserMessageReceived(obj);
});
break;
}
case MessageType.Notification_Rtc_OnRoomMessageSendResult:
case MessageType.Notification_Rtc_OnUserMessageSendResult:
{
msg = new Message<RtcMessageSendResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcMessageSendResult(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcMessageSendResult(obj);
});
break;
}
case MessageType.Notification_Rtc_OnRoomBinaryMessageReceived:
case MessageType.Notification_Rtc_OnUserBinaryMessageReceived:
{
msg = new Message<RtcBinaryMessageReceived>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcBinaryMessageReceived(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcBinaryMessageReceived(obj);
});
break;
}
case MessageType.Notification_Rtc_OnUserPublishScreen:
case MessageType.Notification_Rtc_OnUserPublishStream:
{
msg = new Message<RtcUserPublishInfo>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcUserPublishInfo(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcUserPublishInfo(ptr);
});
break;
}
case MessageType.Notification_Rtc_OnUserUnPublishScreen:
case MessageType.Notification_Rtc_OnUserUnPublishStream:
{
msg = new Message<RtcUserUnPublishInfo>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcUserUnPublishInfo(ptr);
if (obj == IntPtr.Zero)
{
return null;
}
return new RtcUserUnPublishInfo(obj);
});
break;
}
case MessageType.Notification_Rtc_OnStreamSyncInfoReceived:
{
msg = new Message<RtcStreamSyncInfo>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcStreamSyncInfo(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcStreamSyncInfo(obj);
});
break;
}
case MessageType.Notification_Rtc_OnVideoDeviceStateChanged:
{
break;
}
case MessageType.Notification_Rtc_OnRoomError:
{
msg = new Message<RtcRoomError>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcRoomError(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcRoomError(obj);
});
break;
}
case MessageType.Notification_Rtc_OnRoomWarn:
{
msg = new Message<RtcRoomWarn>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcRoomWarn(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcRoomWarn(obj);
});
break;
}
case MessageType.Notification_Rtc_OnConnectionStateChange:
{
msg = new Message<RtcConnectionState>(msgPointer, ptr => { return (RtcConnectionState) CLIB.ppf_Message_GetInt32(ptr); });
break;
}
case MessageType.Notification_Rtc_OnError:
case MessageType.Notification_Rtc_OnWarn:
{
msg = new Message<Int32>(msgPointer, ptr => { return CLIB.ppf_Message_GetInt32(ptr); });
break;
}
case MessageType.Notification_Rtc_OnRoomStats:
{
msg = new Message<RtcRoomStats>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcRoomStats(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcRoomStats(obj);
});
break;
}
case MessageType.Notification_Rtc_OnJoinRoom:
{
msg = new Message<RtcJoinRoomResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcJoinRoomResult(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcJoinRoomResult(obj);
});
break;
}
case MessageType.Notification_Rtc_OnLeaveRoom:
{
msg = new Message<RtcLeaveRoomResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcLeaveRoomResult(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcLeaveRoomResult(obj);
});
break;
}
case MessageType.Notification_Rtc_OnUserLeaveRoom:
{
msg = new Message<RtcUserLeaveInfo>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcUserLeaveInfo(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcUserLeaveInfo(obj);
});
break;
}
case MessageType.Notification_Rtc_OnUserJoinRoom:
{
msg = new Message<RtcUserJoinInfo>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcUserJoinInfo(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcUserJoinInfo(obj);
});
break;
}
case MessageType.Notification_Rtc_OnAudioPlaybackDeviceChanged:
{
msg = new Message<RtcAudioPlaybackDevice>(msgPointer, ptr => { return (RtcAudioPlaybackDevice) CLIB.ppf_Message_GetInt32(ptr); });
break;
}
case MessageType.Notification_Rtc_OnMediaDeviceStateChanged:
{
msg = new Message<RtcMediaDeviceChangeInfo>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcMediaDeviceChangeInfo(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcMediaDeviceChangeInfo(obj);
});
break;
}
case MessageType.Notification_Rtc_OnLocalAudioPropertiesReport:
{
msg = new Message<RtcLocalAudioPropertiesReport>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcLocalAudioPropertiesReport(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcLocalAudioPropertiesReport(obj);
});
break;
}
case MessageType.Notification_Rtc_OnRemoteAudioPropertiesReport:
{
msg = new Message<RtcRemoteAudioPropertiesReport>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcRemoteAudioPropertiesReport(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcRemoteAudioPropertiesReport(obj);
});
break;
}
case MessageType.Notification_Rtc_OnUserMuteAudio:
{
msg = new Message<RtcMuteInfo>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRtcMuteInfo(ptr);
if (obj == IntPtr.Zero) return null;
return new RtcMuteInfo(obj);
});
break;
}
#endregion
#region IAP
case MessageType.IAP_GetViewerPurchases:
{
msg = new Message<PurchaseList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetPurchaseArray(ptr);
if (obj == IntPtr.Zero) return null;
return new PurchaseList(obj);
});
break;
}
case MessageType.IAP_GetSubscriptionStatus:
{
msg = new Message<SubscriptionStatus>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetSubscriptionStatus(ptr);
if (obj == IntPtr.Zero) return null;
return new SubscriptionStatus(obj);
});
break;
}
case MessageType.IAP_LaunchCheckoutFlow:
{
msg = new Message<Purchase>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetPurchase(ptr);
if (obj == IntPtr.Zero) return null;
return new Purchase(obj);
});
break;
}
case MessageType.IAP_GetProductsBySKU:
{
msg = new Message<ProductList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetProductArray(ptr);
if (obj == IntPtr.Zero) return null;
return new ProductList(obj);
});
break;
}
#endregion
#region DLC
case MessageType.AssetFile_DeleteById:
case MessageType.AssetFile_DeleteByName:
{
msg = new Message<AssetFileDeleteResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetAssetFileDeleteResult(ptr);
if (obj == IntPtr.Zero) return null;
return new AssetFileDeleteResult(obj);
});
break;
}
case MessageType.AssetFile_DownloadById:
case MessageType.AssetFile_DownloadByName:
{
msg = new Message<AssetFileDownloadResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetAssetFileDownloadResult(ptr);
if (obj == IntPtr.Zero) return null;
return new AssetFileDownloadResult(obj);
});
break;
}
case MessageType.AssetFile_DownloadCancelById:
case MessageType.AssetFile_DownloadCancelByName:
{
msg = new Message<AssetFileDownloadCancelResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetAssetFileDownloadCancelResult(ptr);
if (obj == IntPtr.Zero) return null;
return new AssetFileDownloadCancelResult(obj);
});
break;
}
case MessageType.AssetFile_GetList:
case MessageType.AssetFile_GetNextAssetDetailsArrayPage:
{
msg = new Message<AssetDetailsList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetAssetDetailsArray(ptr);
if (obj == IntPtr.Zero) return null;
return new AssetDetailsList(obj);
});
break;
}
case MessageType.AssetFile_StatusById:
case MessageType.AssetFile_StatusByName:
{
msg = new Message<AssetStatus>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetAssetStatus(ptr);
if (obj == IntPtr.Zero) return null;
return new AssetStatus(obj);
});
break;
}
case MessageType.Notification_AssetFile_DownloadUpdate:
{
msg = new Message<AssetFileDownloadUpdate>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetAssetFileDownloadUpdate(ptr);
if (obj == IntPtr.Zero) return null;
return new AssetFileDownloadUpdate(obj);
});
break;
}
case MessageType.Notification_AssetFile_DeleteForSafety:
{
msg = new Message<AssetFileDeleteForSafety>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetAssetFileDeleteForSafety(ptr);
if (obj == IntPtr.Zero) return null;
return new AssetFileDeleteForSafety(obj);
});
break;
}
#endregion
#region stark game
case MessageType.Matchmaking_Cancel2:
case MessageType.Matchmaking_ReportResultInsecure:
case MessageType.Matchmaking_StartMatch:
case MessageType.Room_LaunchInvitableUserFlow:
case MessageType.Challenges_LaunchInvitableUserFlow:
case MessageType.Room_UpdateOwner:
case MessageType.Notification_MarkAsRead:
case MessageType.Notification_Game_StateReset:
case MessageType.Presence_Clear:
case MessageType.Presence_Set:
case MessageType.IAP_ConsumePurchase:
case MessageType.Presence_LaunchInvitePanel:
case MessageType.Presence_ShareMedia:
{
msg = new Message(msgPointer);
break;
}
case MessageType.Matchmaking_GetAdminSnapshot:
{
msg = new Message<MatchmakingAdminSnapshot>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetMatchmakingAdminSnapshot(ptr);
return new MatchmakingAdminSnapshot(obj);
});
break;
}
case MessageType.Matchmaking_Browse2:
{
msg = new Message<MatchmakingBrowseResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetMatchmakingBrowseResult(ptr);
return new MatchmakingBrowseResult(obj);
});
break;
}
case MessageType.Matchmaking_Browse2CustomPage:
{
msg = new Message<MatchmakingBrowseResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetMatchmakingBrowseCustomPageResult(ptr);
return new MatchmakingBrowseResult(obj);
});
break;
}
case MessageType.Matchmaking_Enqueue2:
case MessageType.Matchmaking_EnqueueRoom2:
{
msg = new Message<MatchmakingEnqueueResult>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetMatchmakingEnqueueResult(ptr);
return new MatchmakingEnqueueResult(obj);
});
break;
}
case MessageType.Matchmaking_CreateAndEnqueueRoom2:
{
msg = new Message<MatchmakingEnqueueResultAndRoom>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetMatchmakingEnqueueResultAndRoom(ptr);
return new MatchmakingEnqueueResultAndRoom(obj);
});
break;
}
case MessageType.Matchmaking_GetStats:
{
msg = new Message<MatchmakingStats>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetMatchmakingStats(ptr);
return new MatchmakingStats(obj);
});
break;
}
case MessageType.Room_GetCurrent:
case MessageType.Room_GetCurrentForUser:
case MessageType.Notification_Room_RoomUpdate:
case MessageType.Room_CreateAndJoinPrivate:
case MessageType.Room_CreateAndJoinPrivate2:
case MessageType.Room_InviteUser:
case MessageType.Room_Join:
case MessageType.Room_Join2:
case MessageType.Room_JoinNamed:
case MessageType.Room_KickUser:
case MessageType.Room_Leave:
case MessageType.Room_SetDescription:
case MessageType.Room_UpdateDataStore:
case MessageType.Room_UpdateMembershipLockStatus:
case MessageType.Room_UpdatePrivateRoomJoinPolicy:
case MessageType.Notification_Matchmaking_MatchFound:
case MessageType.Room_Get:
{
msg = new Message<Room>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRoom(ptr);
return new Room(obj);
});
break;
}
case MessageType.Room_GetModeratedRooms:
case MessageType.Room_GetNamedRooms:
case MessageType.Room_GetNextRoomArrayPage:
{
msg = new Message<RoomList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRoomArray(ptr);
return new RoomList(obj);
});
break;
}
case MessageType.PlatformGameInitializeAsynchronous:
{
msg = new Message<GameInitializeResult>(msgPointer, ptr =>
{
var objHandle = CLIB.ppf_Message_GetPlatformGameInitialize(ptr);
var obj = CLIB.ppf_PlatformGameInitialize_GetResult(objHandle);
return obj;
});
break;
}
case MessageType.Notification_Game_ConnectionEvent:
{
msg = new Message<GameConnectionEvent>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetGameConnectionEvent(ptr);
return obj;
});
break;
}
case MessageType.Notification_Game_RequestFailed:
{
msg = new Message<GameRequestFailedReason>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetGameRequestFailedReason(ptr);
return obj;
});
break;
}
case MessageType.Leaderboard_Get:
case MessageType.Leaderboard_GetNextLeaderboardArrayPage:
{
msg = new Message<LeaderboardList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetLeaderboardArray(ptr);
return new LeaderboardList(obj);
});
break;
}
case MessageType.Leaderboard_GetEntries:
case MessageType.Leaderboard_GetEntriesAfterRank:
case MessageType.Leaderboard_GetEntriesByIds:
case MessageType.Leaderboard_GetNextEntries:
case MessageType.Leaderboard_GetPreviousEntries:
{
msg = new Message<LeaderboardEntryList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetLeaderboardEntryArray(ptr);
return new LeaderboardEntryList(obj);
});
break;
}
case MessageType.Leaderboard_WriteEntry:
case MessageType.Leaderboard_WriteEntryWithSupplementaryMetric:
{
msg = new Message<bool>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetLeaderboardUpdateStatus(ptr);
return CLIB.ppf_LeaderboardUpdateStatus_GetDidUpdate(obj);
});
break;
}
case MessageType.Achievements_GetAllDefinitions:
case MessageType.Achievements_GetDefinitionsByName:
case MessageType.Achievements_GetNextAchievementDefinitionArrayPage:
msg = new Message<AchievementDefinitionList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetAchievementDefinitionArray(ptr);
return new AchievementDefinitionList(obj);
});
break;
case MessageType.Achievements_GetAllProgress:
case MessageType.Achievements_GetNextAchievementProgressArrayPage:
case MessageType.Achievements_GetProgressByName:
msg = new Message<AchievementProgressList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetAchievementProgressArray(ptr);
return new AchievementProgressList(obj);
});
break;
case MessageType.Achievements_AddCount:
case MessageType.Achievements_AddFields:
case MessageType.Achievements_Unlock:
msg = new Message<AchievementUpdate>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetAchievementUpdate(ptr);
return new AchievementUpdate(obj);
});
break;
case MessageType.Notification_GetNextRoomInviteNotificationArrayPage:
case MessageType.Notification_GetRoomInvites:
{
msg = new Message<RoomInviteNotificationList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetRoomInviteNotificationArray(ptr);
return new RoomInviteNotificationList(obj);
});
break;
}
case MessageType.Challenges_Invite:
case MessageType.Challenges_Get:
case MessageType.Challenges_Join:
case MessageType.Challenges_Leave:
{
msg = new Message<Challenge>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetChallenge(ptr);
return new Challenge(obj);
});
break;
}
case MessageType.Challenges_GetList:
{
msg = new Message<ChallengeList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetChallengeArray(ptr);
return new ChallengeList(obj);
});
break;
}
case MessageType.Challenges_GetEntries:
case MessageType.Challenges_GetEntriesAfterRank:
case MessageType.Challenges_GetEntriesByIds:
{
msg = new Message<ChallengeEntryList>(msgPointer, ptr =>
{
var obj = CLIB.ppf_Message_GetChallengeEntryArray(ptr);
return new ChallengeEntryList(obj);
});
break;
}
#endregion stark game
default:
break;
}
return msg;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fe58099ac2904f4991b8ba3b7810910c
timeCreated: 1666324189

View File

@ -0,0 +1,77 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace Unity.XR.PXR
{
#if UNITY_EDITOR
[InitializeOnLoad]
#endif
public sealed class PXR_PlatformSetting : ScriptableObject
{
public enum simulationType
{
Null,
Invalid,
Valid
}
[SerializeField] public bool entitlementCheckSimulation;
[SerializeField] public bool startTimeEntitlementCheck;
[SerializeField] public string appID;
[SerializeField] public bool useHighlight = true;
public List<string> deviceSN = new List<string>();
private static PXR_PlatformSetting instance;
public static PXR_PlatformSetting Instance
{
get
{
if (instance == null)
{
instance = Resources.Load<PXR_PlatformSetting>("PXR_PlatformSetting");
#if UNITY_EDITOR
string path = Application.dataPath + "/Resources";
if (!Directory.Exists(path))
{
AssetDatabase.CreateFolder("Assets", "Resources");
if (instance == null)
{
instance = CreateInstance<PXR_PlatformSetting>();
AssetDatabase.CreateAsset(instance, "Assets/Resources/PXR_PlatformSetting.asset");
}
}
else
{
if (instance == null)
{
instance = CreateInstance<PXR_PlatformSetting>();
AssetDatabase.CreateAsset(instance, "Assets/Resources/PXR_PlatformSetting.asset");
}
}
#endif
}
return instance;
}
set { instance = value; }
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 508edb944d24e574595a91425051a8e4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,53 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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 UnityEngine;
namespace Pico.Platform.Framework
{
public class Runner : MonoBehaviour
{
public static void RegisterGameObject()
{
var name = "Pico.Platform.Runner";
GameObject g = GameObject.Find(name);
if (g == null)
{
g = new GameObject(name);
}
if (g.GetComponent<Runner>() == null)
{
g.AddComponent<Runner>();
}
}
void Awake()
{
DontDestroyOnLoad(gameObject);
}
void Update()
{
Looper.ProcessMessages();
}
void OnApplicationQuit()
{
Looper.Clear();
if (Application.isEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor)
{
CLIB.ppf_PcUnInitialize();
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 995e5a6d1a26dd847ab40cf7d49cbe44
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,97 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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.Threading.Tasks;
using UnityEngine;
namespace Pico.Platform
{
public class Task
{
public readonly ulong TaskId;
public bool HasSetCallback = false;
public Task(ulong taskId)
{
this.TaskId = taskId;
}
public Task OnComplete(Message.Handler handler)
{
if (handler == null)
{
throw new UnityException("call Task.Oncomplete with null handler.");
}
if (HasSetCallback)
{
throw new UnityException("OnComplete() or Async() can call only once time.");
}
HasSetCallback = true;
Looper.RegisterTaskHandler(TaskId, handler);
return this;
}
public System.Threading.Tasks.Task<Message> Async()
{
if (HasSetCallback)
{
throw new UnityException("OnComplete() or Async() can call only once time.");
}
HasSetCallback = true;
TaskCompletionSource<Message> x = new TaskCompletionSource<Message>();
Message.Handler fun = msg => { x.SetResult(msg); };
Looper.RegisterTaskHandler(this.TaskId, fun);
return x.Task;
}
}
public class Task<T> : Task
{
public Task(ulong taskId) : base(taskId)
{
}
public Task<T> OnComplete(Message<T>.Handler handler)
{
if (handler == null)
{
throw new UnityException("call Task.Oncomplete with null handler.");
}
if (HasSetCallback)
{
throw new UnityException("OnComplete() or Async() can call only once time.");
}
HasSetCallback = true;
Looper.RegisterTaskHandler(TaskId, handler);
return this;
}
public new System.Threading.Tasks.Task<Message<T>> Async()
{
if (HasSetCallback)
{
throw new UnityException("OnComplete() or Async() can call only once time.");
}
HasSetCallback = true;
TaskCompletionSource<Message<T>> x = new TaskCompletionSource<Message<T>>();
Message<T>.Handler fun = msg => { x.SetResult(msg); };
Looper.RegisterTaskHandler(this.TaskId, fun);
return x.Task;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ef1d06cfc9dd85546b917ec0d259ff35
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,51 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform
{
public class TimeUtil
{
public static DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
public static int GetUtcSeconds()
{
return DateTimeToSeconds(DateTime.Now);
}
public static long GetUtcMilliSeconds()
{
return DateTimeToMilliSeconds(DateTime.Now);
}
public static int DateTimeToSeconds(DateTime t)
{
return (int) (t.ToUniversalTime() - UnixEpoch).TotalSeconds;
}
public static long DateTimeToMilliSeconds(DateTime t)
{
return (long) (t.ToUniversalTime() - UnixEpoch).TotalMilliseconds;
}
public static DateTime MilliSecondsToDateTime(long milliSeconds)
{
return UnixEpoch.AddMilliseconds(milliSeconds).ToLocalTime();
}
public static DateTime SecondsToDateTime(long seconds)
{
return UnixEpoch.AddSeconds(seconds).ToLocalTime();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9526d9f6bdb74495807e3f0f81ca6b86
timeCreated: 1659948411

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b0d84e8a0a284315a65f4d42754492a4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,182 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
/// <summary>Achievement update info.</summary>
public class AchievementUpdate
{
/// Whether the achievement is unlocked in this time.
public readonly bool JustUnlocked;
/// Achievement name.
public readonly string Name;
public AchievementUpdate(IntPtr o)
{
JustUnlocked = CLIB.ppf_AchievementUpdate_GetJustUnlocked(o);
Name = CLIB.ppf_AchievementUpdate_GetName(o);
}
}
/// <summary>Achievement info.</summary>
public class AchievementDefinition
{
/// Achievement type.
public readonly AchievementType Type;
/// Achievement name.
public readonly string Name;
/// The target to reach for unlocking a bitfield achievement.
public readonly uint BitfieldLength;
/// The target to reach for unlocking a count achievement.
public readonly long Target;
/// Achievement description.
public readonly string Description;
/// Achievement title.
public readonly string Title;
/// Whether the achievement is archieved.
public readonly bool IsArchived;
/// Whether the achievement is a secret achievement. If so, it can be visible after being unlocked only.
public readonly bool IsSecret;
/// Achievement ID.
public readonly ulong ID;
/// The description shown to users when unlocking the achievement.
public readonly string UnlockedDescription;
/// The write policy of the achievement.
public readonly AchievementWritePolicy WritePolicy;
/// The URL of the image displayed when the achievement is still locked.
public readonly string LockedImageURL;
/// The URL of the image displayed when the achievement is unlocked.
public readonly string UnlockedImageURL;
public AchievementDefinition(IntPtr o)
{
Type = CLIB.ppf_AchievementDefinition_GetType(o);
Name = CLIB.ppf_AchievementDefinition_GetName(o);
BitfieldLength = CLIB.ppf_AchievementDefinition_GetBitfieldLength(o);
Target = CLIB.ppf_AchievementDefinition_GetTarget(o);
Description = CLIB.ppf_AchievementDefinition_GetDescription(o);
Title = CLIB.ppf_AchievementDefinition_GetTitle(o);
IsArchived = CLIB.ppf_AchievementDefinition_IsArchived(o);
IsSecret = CLIB.ppf_AchievementDefinition_IsSecret(o);
ID = CLIB.ppf_AchievementDefinition_GetID(o);
UnlockedDescription = CLIB.ppf_AchievementDefinition_GetUnlockedDescription(o);
WritePolicy = CLIB.ppf_AchievementDefinition_GetWritePolicy(o);
LockedImageURL = CLIB.ppf_AchievementDefinition_GetLockedImageURL(o);
UnlockedImageURL = CLIB.ppf_AchievementDefinition_GetUnlockedImageURL(o);
}
}
/// <summary>Achievement definition list.
/// Each element is \ref AchievementDefinition.
/// </summary>
public class AchievementDefinitionList : MessageArray<AchievementDefinition>
{
/// The total number of `AchievementDefinition`.
public readonly ulong TotalSize;
public AchievementDefinitionList(IntPtr a)
{
TotalSize = (ulong) CLIB.ppf_AchievementDefinitionArray_GetTotalSize(a);
var count = (int) CLIB.ppf_AchievementDefinitionArray_GetSize(a);
this.Capacity = count;
for (uint i = 0; i < count; i++)
{
this.Add(new AchievementDefinition(CLIB.ppf_AchievementDefinitionArray_GetElement(a, (UIntPtr) i)));
}
NextPageParam = CLIB.ppf_AchievementDefinitionArray_HasNextPage(a) ? "true" : string.Empty;
}
}
/// <summary>Achievement progress info. </summary>
public class AchievementProgress
{
/// Achievement ID.
public readonly ulong ID;
/// The progress of a bitfield achievement. `1` represents a completed bit.
public readonly string Bitfield;
/// The progress of a count achievement.
public readonly long Count;
/// Whether the achievement is unlocked
public readonly bool IsUnlocked;
/// Achievement name.
public readonly string Name;
/// The time when the achievement is unlocked.
public readonly DateTime UnlockTime;
/// Additional info, no more than 2KB.
public readonly byte[] ExtraData;
public AchievementProgress(IntPtr o)
{
ID = CLIB.ppf_AchievementProgress_GetID(o);
Bitfield = CLIB.ppf_AchievementProgress_GetBitfield(o);
Count = CLIB.ppf_AchievementProgress_GetCount(o);
IsUnlocked = CLIB.ppf_AchievementProgress_GetIsUnlocked(o);
Name = CLIB.ppf_AchievementProgress_GetName(o);
uint size = CLIB.ppf_AchievementProgress_GetExtraDataLength(o);
ExtraData = new byte[size];
Marshal.Copy(CLIB.ppf_AchievementProgress_GetExtraData(o), ExtraData, 0, (int) size);
var unlockTime = CLIB.ppf_AchievementProgress_GetUnlockTime(o);
if (unlockTime != 0)
{
UnlockTime = TimeUtil.SecondsToDateTime((long) unlockTime);
}
}
}
/// <summary>The list of achievements with their progress info.
/// Each element is \ref AchievementProgress.
/// </summary>
public class AchievementProgressList : MessageArray<AchievementProgress>
{
/// The total number of achievements with progress info.
public readonly ulong TotalSize;
public AchievementProgressList(IntPtr a)
{
TotalSize = (ulong) CLIB.ppf_AchievementProgressArray_GetTotalSize(a);
var count = (int) CLIB.ppf_AchievementProgressArray_GetSize(a);
this.Capacity = count;
for (uint i = 0; i < count; i++)
{
this.Add(new AchievementProgress(CLIB.ppf_AchievementProgressArray_GetElement(a, (UIntPtr) i)));
}
NextPageParam = CLIB.ppf_AchievementProgressArray_HasNextPage(a) ? "true" : string.Empty;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d92845d996c24a5e858d06fe078a5997
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,133 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
/// <summary>App launch details.</summary>
public class LaunchDetails
{
/// How the app was launched:
/// * `Normal`: launched by clicking the app's icon
/// * `RoomInvite`: launched by clicking the room invitation message card
/// * `Deeplink`: launched by clicking the presence invitation message card or calling \ref ApplicationService.LaunchApp
/// * `ChallengeInvite`: launched by clicking the challenge invitation message card
///
public readonly LaunchType LaunchType;
/// Deeplink message. You can pass a deeplink when you call \ref ApplicationService.LaunchApp,
/// and the other app will receive the deeplink.This field will have a value only when `LaunchType` is `LaunchApp`.
public readonly string DeeplinkMessage;
/// Destination API name configured on the PICO Developer Platform.For a presence invitation, the inviters'
/// presence data will contain this field which will be passed when the invitee clicks on the message card.
public readonly string DestinationApiName;
/// The lobby session ID that identifies a group or team.
/// For a presence invitation, the inviters' presence data will contain this field which will be passed
/// when the invitee clicks on the message card.
public readonly string LobbySessionID;
/// The match session ID that identifies a competition.
/// For a presence invitation, the inviters' presence data will contain this field which will be passed when the invitee clicks on the message card.
public readonly string MatchSessionID;
/** The customized extra presence info.
* For a presence invitation, the inviters' presence data will contain this field which will be passed when the invitee clicks on the message card.
* You can use this field to add self-defined presence data. The data size cannot exceed 2MB.
*/
public readonly string Extra;
/// Room ID.For a room invitation, after calling \ref RoomService.InviteUser, this field will be passed when the invitee clicks on the message card.
public readonly UInt64 RoomID;
/// For a challenge invitation, after calling \ref ChallengesService.Invite, this field will be passed when the invitee clicks on the message card.
public readonly UInt64 ChallengeID;
/// Tracking ID.
public readonly string TrackingID;
public LaunchDetails(IntPtr o)
{
DeeplinkMessage = CLIB.ppf_LaunchDetails_GetDeeplinkMessage(o);
DestinationApiName = CLIB.ppf_LaunchDetails_GetDestinationApiName(o);
LobbySessionID = CLIB.ppf_LaunchDetails_GetLobbySessionID(o);
MatchSessionID = CLIB.ppf_LaunchDetails_GetMatchSessionID(o);
Extra = CLIB.ppf_LaunchDetails_GetExtra(o);
RoomID = CLIB.ppf_LaunchDetails_GetRoomID(o);
ChallengeID = CLIB.ppf_LaunchDetails_GetChallengeID(o);
TrackingID = CLIB.ppf_LaunchDetails_GetTrackingID(o);
LaunchType = CLIB.ppf_LaunchDetails_GetLaunchType(o);
}
}
/// <summary>
/// The system information of the device.
/// </summary>
public class SystemInfo
{
/** The current ROM version (i.e., system version) of the device, such as "5.5.0" and "5.6.0".*/
public readonly string ROMVersion;
/** The locale of the device. Locale is combined with language and country code. Such as "zh-CN" and "en-US".*/
public readonly string Locale;
/** The product name of the device, such as "PICO 4".*/
public readonly string ProductName;
/** Whether the device's ROM is CN version. PICO provides different ROM versions in different countries/regions.*/
public readonly bool IsCnDevice;
/** The Matrix's version name. Matrix is a system app which provides system functions for platform services.*/
public readonly string MatrixVersionName;
/** The Matrix's version code. */
public readonly long MatrixVersionCode;
public SystemInfo(IntPtr o)
{
ROMVersion = CLIB.ppf_SystemInfo_GetROMVersion(o);
Locale = CLIB.ppf_SystemInfo_GetLocale(o);
ProductName = CLIB.ppf_SystemInfo_GetProductName(o);
IsCnDevice = CLIB.ppf_SystemInfo_GetIsCnDevice(o);
MatrixVersionName = CLIB.ppf_SystemInfo_GetMatrixVersionName(o);
MatrixVersionCode = CLIB.ppf_SystemInfo_GetMatrixVersionCode(o);
}
}
/// <summary>
/// App's version info.
/// </summary>
public class ApplicationVersion
{
/// The current version code of the installed app.
public readonly long CurrentCode;
/// The current version name of the installed app.
public readonly string CurrentName;
/// The latest version code of the app in the PICO Store.
public readonly long LatestCode;
/// The latest version name of the app in the PICO Store.
public readonly string LatestName;
public ApplicationVersion(IntPtr o)
{
CurrentCode = CLIB.ppf_ApplicationVersion_GetCurrentCode(o);
CurrentName = CLIB.ppf_ApplicationVersion_GetCurrentName(o);
LatestCode = CLIB.ppf_ApplicationVersion_GetLatestCode(o);
LatestName = CLIB.ppf_ApplicationVersion_GetLatestName(o);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 821a71a2140642259ab07bb49f9ae2c0
timeCreated: 1665579240

View File

@ -0,0 +1,258 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
public static class DownloadStatus
{
public const string Downloaded = "downloaded";
public const string Available = "available";
public const string InProgress = "in-progress";
}
/// <summary>
/// Constants indicates whether the user purchased the in-app product.
/// </summary>
public static class IapStatus
{
/// Purchased
public const string Entitled = "entitled";
/// Not purchased.
public const string NotEntitled = "not-entitled";
}
/// <summary> Indicates where the DLC file is displayed.</summary>
public static class AssetType
{
/// The DLC file is displayed in the PICO Store and the app.
public const string Store = "store";
/// The DLC file is displayed in the app only.
public const string Default = "default";
}
public class AssetDetails
{
/// The unique identifier of DLC file.
public ulong AssetId;
/** Some DLC files can be displayed in the PICO Store. Now it has two values: `default` or `store`.
* You can refer to \ref AssetType for details.
*/
public string AssetType;
/// One of `downloaded`, `available`, and `in-progress`. You can refer to \ref DownloadStatus for details.
public string DownloadStatus;
/// The path to the downloaded DLC file. For a non-downloaded DLC file, this field will be empty.
public string Filepath;
/// The meta info of the DLC file.
public string Metadata;
/// The name of the DLC file.
public string Filename;
/// The version of the DLC file.
public int Version;
/// One of `entitled`, `not-entitled`. You can refer to \ref IapStatus for details.
public string IapStatus;
/// The SKU of the in-app product that the DLC file associated with.
public string IapSku;
/// The name of the in-app product that the DLC fiel associated with.
public string IapName;
/// The price of this DLC file.
public string IapPrice;
/// The currency required for purchasing the DLC file.
public string IapCurrency;
/// The description of the in-app product that the DLC file associated with.
public string IapDescription;
/// The icon of the in-app product that the DLC file associated with.
public string IapIcon;
public AssetDetails(IntPtr o)
{
AssetId = CLIB.ppf_AssetDetails_GetAssetId(o);
AssetType = CLIB.ppf_AssetDetails_GetAssetType(o);
DownloadStatus = CLIB.ppf_AssetDetails_GetDownloadStatus(o);
IapStatus = CLIB.ppf_AssetDetails_GetIapStatus(o);
Filepath = CLIB.ppf_AssetDetails_GetFilepath(o);
Metadata = CLIB.ppf_AssetDetails_GetMetadata(o);
Filename = CLIB.ppf_AssetDetails_GetFilename(o);
Version = CLIB.ppf_AssetDetails_GetVersion(o);
IapSku = CLIB.ppf_AssetDetails_GetIapSku(o);
IapName = CLIB.ppf_AssetDetails_GetIapName(o);
IapPrice = CLIB.ppf_AssetDetails_GetIapPrice(o);
IapCurrency = CLIB.ppf_AssetDetails_GetIapCurrency(o);
IapDescription = CLIB.ppf_AssetDetails_GetIapDescription(o);
IapIcon = CLIB.ppf_AssetDetails_GetIapIcon(o);
}
}
/// <summary>
/// Each element is \ref AssetDetails
/// </summary>
public class AssetDetailsList : MessageArray<AssetDetails>
{
public AssetDetailsList(IntPtr a)
{
var count = (int) CLIB.ppf_AssetDetailsArray_GetSize(a);
this.Capacity = count;
for (int i = 0; i < count; i++)
{
this.Add(new AssetDetails(CLIB.ppf_AssetDetailsArray_GetElement(a, (UIntPtr) i)));
}
NextPageParam = CLIB.ppf_AssetDetailsArray_GetNextPageParam(a);
}
}
/// <summary>
/// If the downloaded DLC file is different from the original one,
/// the DLC file will be automatically removed, and the app will receive a notification.
/// </summary>
public class AssetFileDeleteForSafety
{
/// The ID of the DLC file.
public readonly ulong AssetId;
/// The description for why this asset file is deleted.
public readonly string Reason;
public AssetFileDeleteForSafety(IntPtr o)
{
AssetId = CLIB.ppf_AssetFileDeleteForSafety_GetAssetId(o);
Reason = CLIB.ppf_AssetFileDeleteForSafety_GetReason(o);
}
}
/// <summary>
/// The callback for \ref AssetFileService.DeleteById and \ref AssetFileService.DeleteByName.
/// </summary>
public class AssetFileDeleteResult
{
/// The path to the DLC file.
public readonly string Filepath;
/// Whether the DLC file is deleted successfully.
public readonly bool Success;
/// The ID of the DLC file.
public readonly ulong AssetId;
public AssetFileDeleteResult(IntPtr o)
{
Filepath = CLIB.ppf_AssetFileDeleteResult_GetFilepath(o);
Success = CLIB.ppf_AssetFileDeleteResult_GetSuccess(o);
AssetId = CLIB.ppf_AssetFileDeleteResult_GetAssetId(o);
}
}
/// <summary>Indicates whether the download of the DLC file is successfully canceled.</summary>
public class AssetFileDownloadCancelResult
{
/// The path to the DLC file.
public readonly string Filepath;
/// Whether the download is successfully canceled.
public readonly bool Success;
/// The ID of the DLC file.
public readonly ulong AssetId;
public AssetFileDownloadCancelResult(IntPtr o)
{
Filepath = CLIB.ppf_AssetFileDownloadCancelResult_GetFilepath(o);
Success = CLIB.ppf_AssetFileDownloadCancelResult_GetSuccess(o);
AssetId = CLIB.ppf_AssetFileDownloadCancelResult_GetAssetId(o);
}
}
/// <summary>The result returned after calling \ref AssetFileService.DownloadById or \ref AssetFileService.DownloadByName.</summary>
public class AssetFileDownloadResult
{
/// The ID of the DLC file.
public readonly ulong AssetId;
/// The path to the DLC file.
public readonly string Filepath;
public AssetFileDownloadResult(IntPtr o)
{
AssetId = CLIB.ppf_AssetFileDownloadResult_GetAssetId(o);
Filepath = CLIB.ppf_AssetFileDownloadResult_GetFilepath(o);
}
}
/// <summary>
/// You will receive this message periodically once you call \ref AssetFileService.DownloadById
/// or \ref AssetFileService.DownloadByName.
/// </summary>
public class AssetFileDownloadUpdate
{
/// The ID of the DLC file.
public readonly ulong AssetId;
/// The total bytes of the DLC file.
public readonly ulong BytesTotal;
/// The transferred bytes of the DLC file.
public readonly long BytesTransferred;
/// The download status of the DLC file.
public readonly AssetFileDownloadCompleteStatus CompleteStatus;
public AssetFileDownloadUpdate(IntPtr o)
{
AssetId = CLIB.ppf_AssetFileDownloadUpdate_GetAssetId(o);
BytesTotal = CLIB.ppf_AssetFileDownloadUpdate_GetBytesTotal(o);
BytesTransferred = CLIB.ppf_AssetFileDownloadUpdate_GetBytesTransferred(o);
CompleteStatus = CLIB.ppf_AssetFileDownloadUpdate_GetCompleteStatus(o);
}
}
/// <summary>
/// The callback for \ref AssetFileService.StatusById or \ref AssetFileService.StatusByName.
/// </summary>
public class AssetStatus
{
/// The ID of the DLC file.
public readonly ulong AssetId;
/// The name of the DLC file.
public readonly string Filename;
/// The path to the DLC file.
public readonly string Filepath;
/// The download status of the DLC file. You can refer to \ref DownloadStatus for details.
public readonly string DownloadStatus;
public AssetStatus(IntPtr o)
{
AssetId = CLIB.ppf_AssetStatus_GetAssetId(o);
Filename = CLIB.ppf_AssetStatus_GetFilename(o);
Filepath = CLIB.ppf_AssetStatus_GetFilepath(o);
DownloadStatus = CLIB.ppf_AssetStatus_GetDownloadStatus(o);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fa00ebe2dc4b4ccab93a18d008dece77
timeCreated: 1661769967

View File

@ -0,0 +1,268 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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 UnityEngine;
namespace Pico.Platform.Models
{
/// <summary>Challenge setting options.</summary>
public class ChallengeOptions
{
/// For creating challenge options
public ChallengeOptions()
{
Handle = CLIB.ppf_ChallengeOptions_Create();
}
/// Set the end date. Currently, not used.
public void SetEndDate(DateTime value)
{
CLIB.ppf_ChallengeOptions_SetEndDate(Handle, Convert.ToUInt64(TimeUtil.DateTimeToSeconds(value)));
}
/// Set whether to get active challenges.
public void SetIncludeActiveChallenges(bool value)
{
CLIB.ppf_ChallengeOptions_SetIncludeActiveChallenges(Handle, value);
}
/// Set whether to get future challenges whose start dates are latter than the current time.
public void SetIncludeFutureChallenges(bool value)
{
CLIB.ppf_ChallengeOptions_SetIncludeFutureChallenges(Handle, value);
}
/// Set whether to get past challenges whose end dates are earlier than the current time.
public void SetIncludePastChallenges(bool value)
{
CLIB.ppf_ChallengeOptions_SetIncludePastChallenges(Handle, value);
}
/// (Optional) Set the name of the leaderboard that the challenges associated with.
public void SetLeaderboardName(string value)
{
CLIB.ppf_ChallengeOptions_SetLeaderboardName(Handle, value);
}
/// Set the start date. Currently, not used.
public void SetStartDate(DateTime value)
{
CLIB.ppf_ChallengeOptions_SetStartDate(Handle, Convert.ToUInt64(TimeUtil.DateTimeToSeconds(value)));
}
/// Set the challenge title. Currently, not used.
public void SetTitle(string value)
{
CLIB.ppf_ChallengeOptions_SetTitle(Handle, value);
}
/// Set the filter for quering specified challenges.
public void SetViewerFilter(ChallengeViewerFilter value)
{
CLIB.ppf_ChallengeOptions_SetViewerFilter(Handle, value);
}
/// Set to get the challenges of a specific visibility type.
public void SetVisibility(ChallengeVisibility value)
{
CLIB.ppf_ChallengeOptions_SetVisibility(Handle, value);
}
public static explicit operator IntPtr(ChallengeOptions options)
{
return options != null ? options.Handle : IntPtr.Zero;
}
~ChallengeOptions()
{
CLIB.ppf_ChallengeOptions_Destroy(Handle);
}
IntPtr Handle;
public IntPtr GetHandle()
{
return Handle;
}
}
/// <summary>Challenge info.</summary>
public class Challenge
{
/// The creator of the challenge.
public readonly ChallengeCreationType CreationType;
/// Challenge ID
public readonly UInt64 ID;
/// Challenge's start date.
public readonly DateTime StartDate;
/// Challenge's end date.
public readonly DateTime EndDate;
/// Participants of the challenge, which might be null. Should check if it is null before use.
public readonly UserList ParticipantsOptional;
/// Users invited to the challenge, which might be null. Should check if it is null before use.
public readonly UserList InvitedUsersOptional;
/// The info about the leaderboard that the challenge associated with.
public readonly Leaderboard Leaderboard;
/// Challenge's title.
public readonly string Title;
/// Challenge's visibility.
public readonly ChallengeVisibility Visibility;
public Challenge(IntPtr o)
{
CreationType = CLIB.ppf_Challenge_GetCreationType(o);
try
{
EndDate = TimeUtil.SecondsToDateTime((long) CLIB.ppf_Challenge_GetEndDate(o));
}
catch (Exception e)
{
Debug.LogWarning($"Challenge Set EndDate: ppf_Challenge_GetEndDate(o) = {CLIB.ppf_Challenge_GetEndDate(o)}, Exception: {e}");
}
ID = CLIB.ppf_Challenge_GetID(o);
{
var pointer = CLIB.ppf_Challenge_GetInvitedUsers(o);
if (pointer == IntPtr.Zero)
{
InvitedUsersOptional = null;
}
else
{
InvitedUsersOptional = new UserList(pointer);
}
}
Leaderboard = new Leaderboard(CLIB.ppf_Challenge_GetLeaderboard(o));
{
var pointer = CLIB.ppf_Challenge_GetParticipants(o);
if (pointer == IntPtr.Zero)
{
ParticipantsOptional = null;
}
else
{
ParticipantsOptional = new UserList(pointer);
}
}
try
{
StartDate = TimeUtil.SecondsToDateTime((long) CLIB.ppf_Challenge_GetStartDate(o));
}
catch (Exception e)
{
Debug.LogWarning($"Challenge Set StartDate: ppf_Challenge_GetStartDate(o) = {CLIB.ppf_Challenge_GetStartDate(o)}, Exception: {e}");
}
Title = CLIB.ppf_Challenge_GetTitle(o);
Visibility = CLIB.ppf_Challenge_GetVisibility(o);
}
}
/// <summary>Challenge list. Each Element is \ref Challenge.</summary>
public class ChallengeList : MessageArray<Challenge>
{
public ChallengeList(IntPtr a)
{
TotalCount = CLIB.ppf_ChallengeArray_GetTotalCount(a);
NextPageParam = CLIB.ppf_ChallengeArray_HasNextPage(a) ? "true" : string.Empty;
PreviousPageParam = CLIB.ppf_ChallengeArray_HasPreviousPage(a) ? "true" : String.Empty;
int count = (int) CLIB.ppf_ChallengeArray_GetSize(a);
this.Capacity = count;
for (uint i = 0; i < count; i++)
{
this.Add(new Challenge(CLIB.ppf_ChallengeArray_GetElement(a, (UIntPtr) i)));
}
}
/// The total number of challenges in the list.
public readonly ulong TotalCount;
}
/// <summary>Challenge entry info.</summary>
public class ChallengeEntry
{
/// The entry's display score.
public readonly string DisplayScore;
/// The entry's additional info, no more than 2KB.
public readonly byte[] ExtraData;
/// The ID of the challenge that the entry belongs to.
public readonly UInt64 ID;
/// The rank of the entry.
public readonly int Rank;
/// The score of the entry.
public readonly long Score;
/// The time when the entry was written.
public readonly DateTime Timestamp;
/// The user the entry belongs to.
public readonly User User;
public ChallengeEntry(IntPtr o)
{
DisplayScore = CLIB.ppf_ChallengeEntry_GetDisplayScore(o);
var extraDataPtr = CLIB.ppf_ChallengeEntry_GetExtraData(o);
var extraDataSize = CLIB.ppf_ChallengeEntry_GetExtraDataLength(o);
ExtraData = MarshalUtil.ByteArrayFromNative(extraDataPtr, extraDataSize);
ID = CLIB.ppf_ChallengeEntry_GetID(o);
Rank = CLIB.ppf_ChallengeEntry_GetRank(o);
Score = CLIB.ppf_ChallengeEntry_GetScore(o);
try
{
Timestamp = TimeUtil.SecondsToDateTime((long) CLIB.ppf_ChallengeEntry_GetTimestamp(o));
}
catch (Exception e)
{
Debug.LogWarning($"ChallengeEntry Set Timestamp: ppf_ChallengeEntry_GetTimestamp(o) = {CLIB.ppf_ChallengeEntry_GetTimestamp(o)}, Exception: {e}");
}
User = new User(CLIB.ppf_ChallengeEntry_GetUser(o));
}
}
/// <summary>Challenge entry list. Each element is \ref ChallengeEntry.</summary>
public class ChallengeEntryList : MessageArray<ChallengeEntry>
{
public ChallengeEntryList(IntPtr a)
{
TotalCount = CLIB.ppf_ChallengeEntryArray_GetTotalCount(a);
NextPageParam = CLIB.ppf_ChallengeEntryArray_HasNextPage(a) ? "true" : string.Empty;
PreviousPageParam = CLIB.ppf_ChallengeEntryArray_HasPreviousPage(a) ? "true" : string.Empty;
int count = (int) CLIB.ppf_ChallengeEntryArray_GetSize(a);
this.Capacity = count;
for (uint i = 0; i < count; i++)
{
this.Add(new ChallengeEntry(CLIB.ppf_ChallengeEntryArray_GetElement(a, (UIntPtr) i)));
}
}
/// The total number of entries in the list.
public readonly ulong TotalCount;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e107cf0bdc434409aaf2cf952cc37436
timeCreated: 1664352647

View File

@ -0,0 +1,115 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
public class KVPairArray
{
public uint Size { get; private set; }
IntPtr Handle;
public IntPtr GetHandle()
{
return Handle;
}
public KVPairArray(uint size)
{
Size = size;
Handle = CLIB.ppf_KeyValuePairArray_Create((UIntPtr) size);
}
~KVPairArray()
{
CLIB.ppf_KeyValuePairArray_Destroy(Handle);
Handle = IntPtr.Zero;
}
public KVPair GetElement(uint index)
{
return new KVPair(CLIB.ppf_KeyValuePairArray_GetElement(Handle, (UIntPtr) index));
}
}
public class KVPair
{
IntPtr Handle;
bool destroyable = true;
public KVPair()
{
Handle = CLIB.ppf_KeyValuePair_Create();
}
public KVPair(IntPtr o)
{
Handle = o;
destroyable = false;
}
public void SetIntValue(int value)
{
CLIB.ppf_KeyValuePair_SetIntValue(Handle, value);
}
public void SetStringValue(string value)
{
CLIB.ppf_KeyValuePair_SetStringValue(Handle, value);
}
public void SetDoubleValue(double value)
{
CLIB.ppf_KeyValuePair_SetDoubleValue(Handle, value);
}
public int GetIntValue()
{
return CLIB.ppf_KeyValuePair_GetIntValue(Handle);
}
public string GetStringValue()
{
return CLIB.ppf_KeyValuePair_GetStringValue(Handle);
}
public double GetDoubleValue()
{
return CLIB.ppf_KeyValuePair_GetDoubleValue(Handle);
}
public void SetKey(string key)
{
CLIB.ppf_KeyValuePair_SetKey(Handle, key);
}
public string GetKey()
{
return CLIB.ppf_KeyValuePair_GetKey(Handle);
}
public KVPairType GetValueType()
{
return (KVPairType) CLIB.ppf_KeyValuePair_GetValueType(Handle);
}
~KVPair()
{
if (destroyable)
{
CLIB.ppf_KeyValuePair_Destroy(Handle);
Handle = IntPtr.Zero;
}
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: af96c3f14f761724db9f93a693fbad2e
timeCreated: 1523486800
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,31 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
public class DetectSensitiveResult
{
/// The filtered text is a string which replace sensitive words with `*`.
public readonly string FilteredText;
/// The proposed strategy to handle user operation.
public readonly SensitiveProposal Proposal;
public DetectSensitiveResult(IntPtr o)
{
FilteredText = CLIB.ppf_DetectSensitiveResult_GetFilteredText(o);
Proposal = CLIB.ppf_DetectSensitiveResult_GetProposal(o);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3b2e5ad6aabe48df833647b8ce43f0b3
timeCreated: 1679567051

View File

@ -0,0 +1,110 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
/// <summary>
/// Information about screen capturing.
/// </summary>
public class CaptureInfo
{
/// <summary>
/// The path where the image is located.
/// </summary>
public readonly string ImagePath;
/// <summary>
/// The ID of the screen-capturing task.
/// </summary>
public readonly string JobId;
public CaptureInfo(IntPtr o)
{
ImagePath = CLIB.ppf_CaptureInfo_GetImagePath(o);
JobId = CLIB.ppf_CaptureInfo_GetJobId(o);
}
}
/// <summary>
/// Information about screen recording.
/// </summary>
public class RecordInfo
{
/// <summary>
/// The path where the video is located.
/// </summary>
public readonly string VideoPath;
/// <summary>
/// The duration of the video. Unit: milliseconds.
/// </summary>
public readonly int DurationInMilliSeconds;
/// <summary>
/// The width of the video.
/// </summary>
public readonly int Width;
/// <summary>
/// The height of the video.
/// </summary>
public readonly int Height;
/// <summary>
/// The ID of the screen-recording task.
/// </summary>
public readonly string JobId;
public RecordInfo(IntPtr o)
{
VideoPath = CLIB.ppf_RecordInfo_GetVideoPath(o);
DurationInMilliSeconds = CLIB.ppf_RecordInfo_GetDurationInMilliSeconds(o);
Width = CLIB.ppf_RecordInfo_GetWidth(o);
Height = CLIB.ppf_RecordInfo_GetHeight(o);
JobId = CLIB.ppf_RecordInfo_GetJobId(o);
}
}
/// <summary>
/// Information about the images captured and videos recorded in a session.
/// </summary>
public class SessionMedia
{
/// <summary>
/// Image information, including image paths and job IDs.
/// </summary>
public readonly CaptureInfo[] Images;
/// <summary>
/// Video information, including video paths, video durations, video sizes, and job IDs.
/// </summary>
public readonly RecordInfo[] Videos;
public SessionMedia(IntPtr o)
{
{
int sz = (int) CLIB.ppf_SessionMedia_GetImagesSize(o);
Images = new CaptureInfo[sz];
for (int i = 0; i < sz; i++)
{
Images[i] = new CaptureInfo(CLIB.ppf_SessionMedia_GetImages(o, (UIntPtr) i));
}
}
{
int sz = (int) CLIB.ppf_SessionMedia_GetVideosSize(o);
Videos = new RecordInfo[sz];
for (int i = 0; i < sz; i++)
{
Videos[i] = new RecordInfo(CLIB.ppf_SessionMedia_GetVideos(o, (UIntPtr) i));
}
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6effacd11a404d7983207e0418286b47
timeCreated: 1686138789

View File

@ -0,0 +1,225 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
/// <summary>
/// The add-on that can be purchased in the app.
///
/// You can create in-app products on the PICO Developer Platform.
/// </summary>
public class Product
{
/// The description of the add-on.
public readonly string Description;
/// The detailed description of the add-on.
public readonly string DetailDescription;
/// The price of the add-on, which is a number string.
public readonly string Price;
/// The currency required for purchasing the add-on.
public readonly string Currency;
/// The name of the add-on.
public readonly string Name;
/// The unique identifier of the add-on.
public readonly string SKU;
/// The icon of the add-on, which is an image URL.
public readonly string Icon;
/// The type of the add-on
public readonly AddonsType AddonsType;
/// The period type for the subscription add-on. Only valid when it's a subscription add-on.
public readonly PeriodType PeriodType;
/// The trial period unit for the subscription add-on. Only valid when it's a subscription add-on.
public readonly PeriodType TrialPeriodUnit;
/// The trial period value for the subscription add-on. Only valid when it's a subscription add-on.
public readonly int TrialPeriodValue;
/// The original price of the add-on, which means the price without discount.
public readonly string OriginalPrice;
/// The order ID of the subscription. Only valid when it's a subscription add-on.
public readonly string OuterId;
/// Whether the subscription is auto renewed. Only valid when it's a subscription add-on.
public readonly bool IsContinuous;
public Product(IntPtr o)
{
Description = CLIB.ppf_Product_GetDescription(o);
DetailDescription = CLIB.ppf_Product_GetDetailDescription(o);
Price = CLIB.ppf_Product_GetPrice(o);
Currency = CLIB.ppf_Product_GetCurrency(o);
Name = CLIB.ppf_Product_GetName(o);
SKU = CLIB.ppf_Product_GetSKU(o);
Icon = CLIB.ppf_Product_GetIcon(o);
AddonsType = CLIB.ppf_Product_GetAddonsType(o);
PeriodType = CLIB.ppf_Product_GetPeriodType(o);
TrialPeriodUnit = CLIB.ppf_Product_GetTrialPeriodUnit(o);
TrialPeriodValue = CLIB.ppf_Product_GetTrialPeriodValue(o);
OuterId = CLIB.ppf_Product_GetOuterId(o);
OriginalPrice = CLIB.ppf_Product_GetOriginalPrice(o);
IsContinuous = CLIB.ppf_Product_IsContinuous(o);
}
}
/// <summary>
/// Each element is \ref Product.
/// </summary>
public class ProductList : MessageArray<Product>
{
public ProductList(IntPtr a)
{
var count = (int) CLIB.ppf_ProductArray_GetSize(a);
this.Capacity = count;
for (int i = 0; i < count; i++)
{
this.Add(new Product(CLIB.ppf_ProductArray_GetElement(a, (UIntPtr) i)));
}
NextPageParam = CLIB.ppf_ProductArray_GetNextPageParam(a);
}
}
/// <summary>
/// The add-on that the current user has purchased.
/// </summary>
public class Purchase
{
/// The expiration time. Only valid when it's a subscription add-on.
public readonly DateTime ExpirationTime;
/// The grant time. Only valid when it's a subscription add-on.
public readonly DateTime GrantTime;
/// The ID of the purchase order.
public readonly string ID;
/// The unique identifier of the add-on in the purchase order.
public readonly string SKU;
/// The icon of the add-on.
public readonly string Icon;
/// The type of the purchased add-on.
public readonly AddonsType AddonsType;
/// The order ID of the subscription. Only valid when it's a subscription add-on.
public readonly string OuterId;
/// The current period type of subscription. Only valid when it's a subscription add-on.
public readonly PeriodType CurrentPeriodType;
/// The next period type of subscription. Only valid when it's a subscription add-on.
public readonly PeriodType NextPeriodType;
/// The next pay time of subscription. Only valid when it's a subscription add-on.
public readonly DateTime NextPayTime;
/// The discount info of the purchase.
public readonly DiscountType DiscountType;
/// The comment for the order. Developers can add order comment to a purchase. See also: \ref IAPService.LaunchCheckoutFlow3
public readonly string OrderComment;
public Purchase(IntPtr o)
{
ExpirationTime = TimeUtil.MilliSecondsToDateTime(CLIB.ppf_Purchase_GetExpirationTime(o));
GrantTime = TimeUtil.MilliSecondsToDateTime(CLIB.ppf_Purchase_GetGrantTime(o));
ID = CLIB.ppf_Purchase_GetID(o);
SKU = CLIB.ppf_Purchase_GetSKU(o);
Icon = CLIB.ppf_Purchase_GetIcon(o);
AddonsType = CLIB.ppf_Purchase_GetAddonsType(o);
OuterId = CLIB.ppf_Purchase_GetOuterId(o);
CurrentPeriodType = CLIB.ppf_Purchase_GetCurrentPeriodType(o);
NextPeriodType = CLIB.ppf_Purchase_GetNextPeriodType(o);
NextPayTime = TimeUtil.MilliSecondsToDateTime(CLIB.ppf_Purchase_GetNextPayTime(o));
DiscountType = CLIB.ppf_Purchase_GetDiscountType(o);
OrderComment = CLIB.ppf_Purchase_GetOrderComment(o);
}
}
/// <summary>
/// Each element is \ref Purchase.
/// </summary>
public class PurchaseList : MessageArray<Purchase>
{
public PurchaseList(IntPtr a)
{
var count = (int) CLIB.ppf_PurchaseArray_GetSize(a);
this.Capacity = count;
for (int i = 0; i < count; i++)
{
this.Add(new Purchase(CLIB.ppf_PurchaseArray_GetElement(a, (UIntPtr) i)));
}
NextPageParam = CLIB.ppf_PurchaseArray_GetNextPageParam(a);
}
}
/// <summary>
/// \ref IAPService.GetSubscriptionStatus returns the subscription status of a subscription add-on.
/// </summary>
public class SubscriptionStatus
{
/// The SKU of the add-on. SKU is the add-on's unique identifier.
public readonly string SKU;
/// The order ID of the subscription. Only valid when it's a subscription add-on.
public readonly string OuterId;
/// The start time of the subscription.
public readonly DateTime StartTime;
/// The end time of the subscription.
public readonly DateTime EndTime;
/// The period type of the subscription.
public readonly PeriodType PeriodType;
/// The entitlement status of the add-on, which indicates whether the user is entitled to use the add-on.
public readonly EntitlementStatus EntitlementStatus;
/// If `EntitlementStatus` is `Cancel`, `CancelReason` indicates why the subscription has been canceled.
public readonly CancelReason CancelReason;
/// Whether the subscription is in free trial.
public readonly bool IsFreeTrial;
/// The next period of the subscription.
public readonly int NextPeriod;
public SubscriptionStatus(IntPtr o)
{
SKU = CLIB.ppf_SubscriptionStatus_GetSKU(o);
OuterId = CLIB.ppf_SubscriptionStatus_GetOuterId(o);
StartTime = TimeUtil.MilliSecondsToDateTime(CLIB.ppf_SubscriptionStatus_GetStartTime(o));
EndTime = TimeUtil.MilliSecondsToDateTime(CLIB.ppf_SubscriptionStatus_GetEndTime(o));
PeriodType = CLIB.ppf_SubscriptionStatus_GetPeriodType(o);
EntitlementStatus = CLIB.ppf_SubscriptionStatus_GetEntitlementStatus(o);
CancelReason = CLIB.ppf_SubscriptionStatus_GetCancelReason(o);
IsFreeTrial = CLIB.ppf_SubscriptionStatus_GetIsFreeTrial(o);
NextPeriod = CLIB.ppf_SubscriptionStatus_GetNextPeriod(o);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2178942333fc436ab70032c2073b63bb
timeCreated: 1655278125

View File

@ -0,0 +1,146 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
/// <summary>Leaderboard info.</summary>
public class Leaderboard
{
/// The unique identifier of the leaderboard, which is configured on the PICO Developer Platform.
public readonly string ApiName;
/// Leaderboard ID.
public readonly ulong ID;
/** Associate a destination to the leaderboard so that users can be directed to a specific location in the app.
* If the leaderboard for that challenge is associated with a destination, the app will be launched, and the user will be directed to the destination.
* If the leaderboard for that challenge is not associated with any destination, the app will be launched, and the user will be directed to the Home page.
*/
public readonly Destination DestinationOptional;
public Leaderboard(IntPtr o)
{
ApiName = CLIB.ppf_Leaderboard_GetApiName(o);
ID = CLIB.ppf_Leaderboard_GetID(o);
var pointer = CLIB.ppf_Leaderboard_GetDestination(o);
if (pointer == IntPtr.Zero)
DestinationOptional = null;
else
DestinationOptional = new Destination(pointer);
}
}
/// <summary>Leaderboard list. Each element is \ref Leaderboard.</summary>
public class LeaderboardList : MessageArray<Leaderboard>
{
/// The total number of leaderboards in the list.
public readonly ulong TotalCount;
public LeaderboardList(IntPtr a)
{
TotalCount = CLIB.ppf_LeaderboardArray_GetTotalCount(a);
NextPageParam = CLIB.ppf_LeaderboardArray_HasNextPage(a) ? "true" : string.Empty;
var count = (int) CLIB.ppf_LeaderboardArray_GetSize(a);
this.Capacity = count;
for (var i = 0; i < count; i++)
{
Add(new Leaderboard(CLIB.ppf_LeaderboardArray_GetElement(a, (UIntPtr) i)));
}
}
}
/// <summary>Supplementary metric.</summary>
public class SupplementaryMetric
{
/// The ID of the supplementary metric.
public readonly UInt64 ID;
/// The value of the supplementary metric.
public readonly long Metric;
public SupplementaryMetric(IntPtr o)
{
ID = CLIB.ppf_SupplementaryMetric_GetID(o);
Metric = CLIB.ppf_SupplementaryMetric_GetMetric(o);
}
}
/// <summary>Leaderboard entry info.</summary>
public class LeaderboardEntry
{
/// The entry's display score.
public readonly string DisplayScore;
/// Additional info, no more than 2KB.
public readonly byte[] ExtraData;
/// Entry ID.
public readonly UInt64 ID;
/// The entry's ranking on the leaderboard. For example, returns `1` for top1.
public readonly int Rank;
/// The score used to rank the entry.
public readonly long Score;
/// The supplementary metric used for tiebreakers. This field can be null. Need to check whether it is null before use.
public readonly SupplementaryMetric SupplementaryMetricOptional;
/// The time when the entry was written to the leaderboard.
public readonly DateTime Timestamp;
/// The user the entry belongs to.
public readonly User User;
public LeaderboardEntry(IntPtr o)
{
DisplayScore = CLIB.ppf_LeaderboardEntry_GetDisplayScore(o);
var extraDataPtr = CLIB.ppf_LeaderboardEntry_GetExtraData(o);
var extraDataSize = CLIB.ppf_LeaderboardEntry_GetExtraDataLength(o);
ExtraData = MarshalUtil.ByteArrayFromNative(extraDataPtr, extraDataSize);
ID = CLIB.ppf_LeaderboardEntry_GetID(o);
Rank = CLIB.ppf_LeaderboardEntry_GetRank(o);
Score = CLIB.ppf_LeaderboardEntry_GetScore(o);
Timestamp = TimeUtil.SecondsToDateTime((long) CLIB.ppf_LeaderboardEntry_GetTimestamp(o));
User = new User(CLIB.ppf_LeaderboardEntry_GetUser(o));
{
var pointer = CLIB.ppf_LeaderboardEntry_GetSupplementaryMetric(o);
if (pointer == IntPtr.Zero)
{
SupplementaryMetricOptional = null;
}
else
{
SupplementaryMetricOptional = new SupplementaryMetric(pointer);
}
}
}
}
/// <summary>Leaderboard entry list. Each element is \ref LeaderboardEntry.</summary>
public class LeaderboardEntryList : MessageArray<LeaderboardEntry>
{
/// The total number of entries on the leaderboard.
public readonly ulong TotalCount;
public LeaderboardEntryList(IntPtr a)
{
NextPageParam = CLIB.ppf_LeaderboardEntryArray_HasNextPage(a) ? "true" : string.Empty;
PreviousPageParam = CLIB.ppf_LeaderboardEntryArray_HasPreviousPage(a) ? "true" : string.Empty;
var count = (int) CLIB.ppf_LeaderboardEntryArray_GetSize(a);
this.Capacity = count;
for (uint i = 0; i < count; i++)
{
this.Add(new LeaderboardEntry(CLIB.ppf_LeaderboardEntryArray_GetElement(a, (UIntPtr) i)));
}
TotalCount = CLIB.ppf_LeaderboardEntryArray_GetTotalCount(a);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 457e9a7eddbc4d46ab8add0d8ebc03d6
timeCreated: 1655221465

View File

@ -0,0 +1,202 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
/// <summary>Matchmaking admin snapshot. You will receive this after calling \ref MatchmakingService.GetAdminSnapshot.</summary>
public class MatchmakingAdminSnapshot
{
/// List of matchmaking candidates
public readonly MatchmakingAdminSnapshotCandidateList CandidateList;
/// The current matching threshold.
public readonly double MyCurrentThreshold;
public MatchmakingAdminSnapshot(IntPtr o)
{
CandidateList = new MatchmakingAdminSnapshotCandidateList(CLIB.ppf_MatchmakingAdminSnapshot_GetCandidates(o));
MyCurrentThreshold = CLIB.ppf_MatchmakingAdminSnapshot_GetMyCurrentThreshold(o);
}
}
/// <summary>Matchmaking candidate.</summary>
public class MatchmakingAdminSnapshotCandidate
{
/// Whether me and the other user can be matched.
public readonly bool CanMatch;
/// My matching threshold.
public readonly double MyTotalScore;
/// The other user's matching threshold.
public readonly double TheirCurrentThreshold;
public MatchmakingAdminSnapshotCandidate(IntPtr o)
{
CanMatch = CLIB.ppf_MatchmakingAdminSnapshotCandidate_GetCanMatch(o);
MyTotalScore = CLIB.ppf_MatchmakingAdminSnapshotCandidate_GetMyTotalScore(o);
TheirCurrentThreshold = CLIB.ppf_MatchmakingAdminSnapshotCandidate_GetTheirCurrentThreshold(o);
}
}
/// <summary>
/// Each element is \ref MatchmakingAdminSnapshotCandidate.
/// </summary>
public class MatchmakingAdminSnapshotCandidateList : MessageArray<MatchmakingAdminSnapshotCandidate>
{
/// The total number of MatchmakingAdminSnapshotCandidate in the list.
public readonly ulong TotalCount;
public MatchmakingAdminSnapshotCandidateList(IntPtr a)
{
var count = (int) CLIB.ppf_MatchmakingAdminSnapshotCandidateArray_GetSize(a);
this.Capacity = count;
TotalCount = (ulong)CLIB.ppf_MatchmakingAdminSnapshotCandidateArray_GetTotalCount(a);
for (int i = 0; i < count; i++)
{
this.Add(new MatchmakingAdminSnapshotCandidate(CLIB.ppf_MatchmakingAdminSnapshotCandidateArray_GetElement(a, (UIntPtr) i)));
}
}
}
/// <summary>Matchmaking browse result. You will receive the result after calling \ref MatchmakingService.Browse2. </summary>
public class MatchmakingBrowseResult
{
/// Matchmaking enqueue result.
public readonly MatchmakingEnqueueResult EnqueueResult;
/// The list of matchmaking rooms.
public readonly MatchmakingRoomList MatchmakingRooms;
public MatchmakingBrowseResult(IntPtr o)
{
EnqueueResult = new MatchmakingEnqueueResult(CLIB.ppf_MatchmakingBrowseResult_GetEnqueueResult(o));
MatchmakingRooms = new MatchmakingRoomList(CLIB.ppf_MatchmakingBrowseResult_GetRooms(o));
}
}
/// <summary>Matchmaking enqueue result.</summary>
public class MatchmakingEnqueueResult
{
/// Matchmaking snapshot options. Used for debugging only.
public readonly MatchmakingAdminSnapshot AdminSnapshotOptional;
/// The average waiting time.
public readonly uint AverageWait;
/// The number of matches made in the last hour.
public readonly uint MatchesInLastHourCount;
/// The expected longest waiting time.
public readonly uint MaxExpectedWait;
/// Matchmaking pool name.
public readonly string Pool;
/// Match rate.
public readonly uint RecentMatchPercentage;
public MatchmakingEnqueueResult(IntPtr o)
{
{
var pointer = CLIB.ppf_MatchmakingEnqueueResult_GetAdminSnapshot(o);
if (pointer == IntPtr.Zero)
{
AdminSnapshotOptional = null;
}
else
{
AdminSnapshotOptional = new MatchmakingAdminSnapshot(pointer);
}
}
AverageWait = CLIB.ppf_MatchmakingEnqueueResult_GetAverageWait(o);
MatchesInLastHourCount = CLIB.ppf_MatchmakingEnqueueResult_GetMatchesInLastHourCount(o);
MaxExpectedWait = CLIB.ppf_MatchmakingEnqueueResult_GetMaxExpectedWait(o);
Pool = CLIB.ppf_MatchmakingEnqueueResult_GetPool(o);
RecentMatchPercentage = CLIB.ppf_MatchmakingEnqueueResult_GetRecentMatchPercentage(o);
}
}
/// <summary>Matchmaking enqueue result and room info. You will receive this after calling \ref MatchmakingService.CreateAndEnqueueRoom2.</summary>
public class MatchmakingEnqueueResultAndRoom
{
/// Matchmaking enqueue result.
public readonly MatchmakingEnqueueResult MatchmakingEnqueueResult;
/// Matchmaking room info.
public readonly Room Room;
public MatchmakingEnqueueResultAndRoom(IntPtr o)
{
MatchmakingEnqueueResult = new MatchmakingEnqueueResult(CLIB.ppf_MatchmakingEnqueueResultAndRoom_GetMatchmakingEnqueueResult(o));
Room = new Room(CLIB.ppf_MatchmakingEnqueueResultAndRoom_GetRoom(o));
}
}
/// <summary>Matchmaking room.</summary>
public class MatchmakingRoom
{
/// Room info.
public readonly Models.Room Room;
/// Currently, always `0`.
public readonly uint PingTime;
/// Currently, always `false`.
public readonly bool HasPingTime;
public MatchmakingRoom(IntPtr o)
{
this.PingTime = CLIB.ppf_MatchmakingRoom_GetPingTime(o);
this.Room = new Models.Room(CLIB.ppf_MatchmakingRoom_GetRoom(o));
this.HasPingTime = CLIB.ppf_MatchmakingRoom_HasPingTime(o);
}
}
/**
* Each element is \ref MatchmakingRoom
*/
public class MatchmakingRoomList : MessageArray<MatchmakingRoom>
{
/// The total number.
public readonly int TotalCount;
public MatchmakingRoomList(IntPtr a)
{
TotalCount = CLIB.ppf_MatchmakingRoomArray_GetTotalCount(a);
int count = (int) CLIB.ppf_MatchmakingRoomArray_GetSize(a);
this.Capacity = count;
for (uint i = 0; i < count; i++)
{
this.Add(new MatchmakingRoom(CLIB.ppf_MatchmakingRoomArray_GetElement(a, (UIntPtr) i)));
}
}
}
/// <summary>Matchmaking statistics. Will receive this after calling \ref MatchmakingService.GetStats.</summary>
public class MatchmakingStats
{
/// The current user's number of draws.
public readonly uint DrawCount;
/// The current user's number of losses.
public readonly uint LossCount;
/// The current user's skill level for the current matchmaking pool.
public readonly uint SkillLevel;
/// The average of all skill levels for the current matchmaking pool.
public readonly double SkillMean;
/// The standard deviation of all skill levels for the current matchmaking pool
public readonly double SkillStandardDeviation;
/// The current user's number of wins.
public readonly uint WinCount;
public MatchmakingStats(IntPtr o)
{
DrawCount = CLIB.ppf_MatchmakingStats_GetDrawCount(o);
LossCount = CLIB.ppf_MatchmakingStats_GetLossCount(o);
SkillLevel = CLIB.ppf_MatchmakingStats_GetSkillLevel(o);
SkillMean = CLIB.ppf_MatchmakingStats_GetSkillMean(o);
SkillStandardDeviation = CLIB.ppf_MatchmakingStats_GetSkillStandardDeviation(o);
WinCount = CLIB.ppf_MatchmakingStats_GetWinCount(o);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ad76d09e01dbdf749a00f0dfd0ed3c1a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,69 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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 UnityEngine;
namespace Pico.Platform.Models
{
/// <summary>
/// Invitation notificiation.
/// </summary>
public class RoomInviteNotification
{
/// Invitation ID.
public readonly UInt64 ID;
/// Room ID.
public readonly UInt64 RoomID;
/// Inviter's user ID.
public readonly string SenderID;
/// The time when the invitation is sent.
public readonly DateTime SentTime;
public RoomInviteNotification(IntPtr o)
{
ID = CLIB.ppf_RoomInviteNotification_GetID(o);
RoomID = CLIB.ppf_RoomInviteNotification_GetRoomID(o);
SenderID = CLIB.ppf_RoomInviteNotification_GetSenderID(o);
SentTime = new DateTime();
try
{
SentTime = TimeUtil.SecondsToDateTime((long) CLIB.ppf_RoomInviteNotification_GetSentTime(o));
}
catch (UnityException ex)
{
Debug.LogWarning($"RoomInviteNotification get SentTime fail {ex}");
throw;
}
}
}
/// <summary>
/// Each element is \ref RoomInviteNotification
/// </summary>
public class RoomInviteNotificationList : MessageArray<RoomInviteNotification>
{
/// The total number.
public readonly int TotalCount;
public RoomInviteNotificationList(IntPtr a)
{
TotalCount = CLIB.ppf_RoomInviteNotificationArray_GetTotalCount(a);
NextPageParam = CLIB.ppf_RoomInviteNotificationArray_HasNextPage(a) ? "true" : string.Empty;
int count = (int) CLIB.ppf_RoomInviteNotificationArray_GetSize(a);
this.Capacity = count;
for (uint i = 0; i < count; i++)
{
this.Add(new RoomInviteNotification(CLIB.ppf_RoomInviteNotificationArray_GetElement(a, (UIntPtr)i)));
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0945c228a6a840e0b4046d70ed08ea25
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,91 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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.Models
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// The information about the message packet.
/// </summary>
public sealed class Packet : IDisposable
{
/// The size of the message packet.
private readonly ulong size;
/// The handler of the message packet.
private readonly IntPtr handler;
public Packet(IntPtr handler)
{
this.handler = handler;
this.size = (ulong) CLIB.ppf_Packet_GetSize(handler);
}
/// <summary>Get message content.</summary>
public ulong GetBytes(byte[] dest)
{
if ((ulong) dest.LongLength >= size)
{
Marshal.Copy(CLIB.ppf_Packet_GetBytes(handler), dest, 0, (int) size);
return size;
}
else
{
throw new ArgumentException($"Dest array can't hold {size} bytes");
}
}
/// <summary>Get message content.</summary>
public string GetBytes()
{
if (size > 0)
{
byte[] bytes = new byte[size];
Marshal.Copy(CLIB.ppf_Packet_GetBytes(handler), bytes, 0, (int) size);
return System.Text.Encoding.UTF8.GetString(bytes);
}
else
{
return string.Empty;
}
}
/// <summary>Get the ID of the message sender.</summary>
public string SenderId
{
get { return CLIB.ppf_Packet_GetSenderID(handler); }
}
/// <summary>Get message size.</summary>
public ulong Size
{
get { return size; }
}
#region IDisposable
~Packet()
{
Dispose();
}
public void Dispose()
{
CLIB.ppf_Packet_Free(handler);
GC.SuppressFinalize(this);
}
#endregion
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 351ba01c3b9b64a2f99b84ec5e4202b1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,156 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
/// <summary>
/// Destination is a location in the app.
/// You can configure destinations for your app on the PICO Developer Platform.
/// </summary>
public class Destination
{
/// The destination's API name.
public readonly string ApiName;
/// The destination's deeplink message.
public readonly string DeeplinkMessage;
/// The destination's display name.
public readonly string DisplayName;
public Destination(IntPtr o)
{
ApiName = CLIB.ppf_Destination_GetApiName(o);
DeeplinkMessage = CLIB.ppf_Destination_GetDeeplinkMessage(o);
DisplayName = CLIB.ppf_Destination_GetDisplayName(o);
}
}
/// <summary>
/// Each element is \ref Destination
/// </summary>
public class DestinationList : MessageArray<Destination>
{
public DestinationList(IntPtr a)
{
var count = (int) CLIB.ppf_DestinationArray_GetSize(a);
this.Capacity = count;
for (int i = 0; i < count; i++)
{
this.Add(new Destination(CLIB.ppf_DestinationArray_GetElement(a, (UIntPtr) i)));
}
NextPageParam = CLIB.ppf_DestinationArray_GetNextPageParam(a);
}
}
/// <summary>
/// App's invitation info.
/// </summary>
public class ApplicationInvite
{
/// The destination where the user is directed to after accepting the invitation.
public readonly Destination Destination;
/// Invited users.
public readonly User Recipient;
/// Invitation ID.
public readonly UInt64 ID;
/// If the user clicks the invitation message, this field will be `true`.
public readonly bool IsActive;
/// The lobby session ID that identifies a group or team.
public readonly string LobbySessionId;
/// The match session ID that identifies a competition.
public readonly string MatchSessionId;
public ApplicationInvite(IntPtr o)
{
Destination = new Destination(CLIB.ppf_ApplicationInvite_GetDestination(o));
Recipient = new User(CLIB.ppf_ApplicationInvite_GetRecipient(o));
ID = CLIB.ppf_ApplicationInvite_GetID(o);
IsActive = CLIB.ppf_ApplicationInvite_GetIsActive(o);
LobbySessionId = CLIB.ppf_ApplicationInvite_GetLobbySessionId(o);
MatchSessionId = CLIB.ppf_ApplicationInvite_GetMatchSessionId(o);
}
}
/// <summary>
/// Each element is \ref ApplicationInvite.
/// </summary>
public class ApplicationInviteList : MessageArray<ApplicationInvite>
{
public ApplicationInviteList(IntPtr a)
{
var count = (int) CLIB.ppf_ApplicationInviteArray_GetSize(a);
this.Capacity = count;
for (int i = 0; i < count; i++)
{
this.Add(new ApplicationInvite(CLIB.ppf_ApplicationInviteArray_GetElement(a, (UIntPtr) i)));
}
NextPageParam = CLIB.ppf_ApplicationInviteArray_GetNextPageParam(a);
}
}
/// <summary>
/// The result returned after calling \ref PresenceService.SendInvites.
/// </summary>
public class SendInvitesResult
{
public readonly ApplicationInviteList Invites;
public SendInvitesResult(IntPtr o)
{
Invites = new ApplicationInviteList(CLIB.ppf_SendInvitesResult_GetInvites(o));
}
}
/// <summary>
/// When user click the invitation message, the app will be launched and you will receive a message with presence info.
/// </summary>
public class PresenceJoinIntent
{
/// The deeplink message of the destination.
public readonly string DeeplinkMessage;
/// The destination api name of the destination.
public readonly string DestinationApiName;
/// The lobby session id which is configured by the sender.
public readonly string LobbySessionId;
/// The match session id which is configured by the sender.
public readonly string MatchSessionId;
/// The extra info of the presence.
public readonly string Extra;
public PresenceJoinIntent(IntPtr o)
{
DeeplinkMessage = CLIB.ppf_PresenceJoinIntent_GetDeeplinkMessage(o);
DestinationApiName = CLIB.ppf_PresenceJoinIntent_GetDestinationApiName(o);
LobbySessionId = CLIB.ppf_PresenceJoinIntent_GetLobbySessionId(o);
MatchSessionId = CLIB.ppf_PresenceJoinIntent_GetMatchSessionId(o);
Extra = CLIB.ppf_PresenceJoinIntent_GetExtra(o);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cefd599deefe0d44294c1b825693cdff
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,557 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
/// <summary>
/// The binary message received in a RTC room.
/// </summary>
public class RtcBinaryMessageReceived
{
/// The message sender's user ID.
public readonly string UserId;
/// The binary data of the message.
public readonly byte[] Data;
/// The ID of the room that the message is sent to.
public readonly string RoomId;
public RtcBinaryMessageReceived(IntPtr o)
{
UserId = CLIB.ppf_RtcBinaryMessageReceived_GetUserId(o);
var ptr = CLIB.ppf_RtcBinaryMessageReceived_GetData(o);
var sz = CLIB.ppf_RtcBinaryMessageReceived_GetLength(o);
Data = MarshalUtil.ByteArrayFromNative(ptr, (uint) sz);
RoomId = CLIB.ppf_RtcBinaryMessageReceived_GetRoomId(o);
}
}
/// <summary>
/// The audio frame is several frames of RTC recorded audio.
/// </summary>
public class RtcAudioFrame
{
/// The type of the audio channel for this audio frame.
public readonly RtcAudioChannel Channel;
/// The data pointer of the audio frame.
public readonly IntPtr Data;
/// The size of the data.
public readonly long DataSize;
/// The sample rate of the data.
public readonly RtcAudioSampleRate SampleRate;
/// The timestamp.Its value is always 0. So don't use it.
public readonly long TimeStampInUs;
public RtcAudioFrame(IntPtr o)
{
Channel = CLIB.ppf_RtcAudioFrame_GetChannel(o);
DataSize = CLIB.ppf_RtcAudioFrame_GetDataSize(o);
SampleRate = CLIB.ppf_RtcAudioFrame_GetSampleRate(o);
TimeStampInUs = CLIB.ppf_RtcAudioFrame_GetTimeStampInUs(o);
Data = CLIB.ppf_RtcAudioFrame_GetData(o);
}
public byte[] GetData()
{
return MarshalUtil.ByteArrayFromNative(this.Data, (uint) this.DataSize);
}
public void SetData(byte[] data)
{
Marshal.Copy(data, 0, this.Data, (int) this.DataSize);
}
}
/// <summary>
/// The message sending result that indicates whether the message is successfully sent.
/// </summary>
public class RtcMessageSendResult
{
/// The message ID.
public readonly long MessageId;
/// The error code returned in the result. `200` means success.
public readonly int Error;
/// The ID of the room that the message is sent to.
public readonly string RoomId;
public RtcMessageSendResult(IntPtr o)
{
MessageId = CLIB.ppf_RtcMessageSendResult_GetMessageId(o);
Error = CLIB.ppf_RtcMessageSendResult_GetError(o);
RoomId = CLIB.ppf_RtcMessageSendResult_GetRoomId(o);
}
}
/// <summary>
/// When the remote user canceled publshing stream to the room, you will receive a notification.
/// </summary>
public class RtcUserUnPublishInfo
{
/// The ID of the remote user.
public readonly string UserId;
/// The stream type.
public readonly RtcMediaStreamType MediaStreamType;
/// The reason why the remote user canceled publishing stream.
public readonly RtcStreamRemoveReason Reason;
/// The ID of the room that the remote user is in.
public readonly string RoomId;
public RtcUserUnPublishInfo(IntPtr o)
{
UserId = CLIB.ppf_RtcUserUnPublishInfo_GetUserId(o);
MediaStreamType = CLIB.ppf_RtcUserUnPublishInfo_GetMediaStreamType(o);
Reason = CLIB.ppf_RtcUserUnPublishInfo_GetReason(o);
RoomId = CLIB.ppf_RtcUserUnPublishInfo_GetRoomId(o);
}
}
/// <summary>
/// The publish stream info.
/// If the remote user publishes stream, you will receive a notification.
/// </summary>
public class RtcUserPublishInfo
{
/// The ID of the remote user.
public readonly string UserId;
/// The stream type.
public readonly RtcMediaStreamType MediaStreamType;
/// The ID of the room that the remote user is in.
public readonly string RoomId;
public RtcUserPublishInfo(IntPtr o)
{
UserId = CLIB.ppf_RtcUserPublishInfo_GetUserId(o);
MediaStreamType = CLIB.ppf_RtcUserPublishInfo_GetMediaStreamType(o);
RoomId = CLIB.ppf_RtcUserPublishInfo_GetRoomId(o);
}
}
/// <summary>
/// The message received by a certain room.
/// The remote users can send messages to the room and you will receive this message.
/// </summary>
public class RtcRoomMessageReceived
{
/// The ID of the message sender.
public readonly string UserId;
/// The message.
public readonly string Message;
/// The ID of the room that the message was sent to.
public readonly string RoomId;
public RtcRoomMessageReceived(IntPtr o)
{
UserId = CLIB.ppf_RtcRoomMessageReceived_GetUserId(o);
Message = CLIB.ppf_RtcRoomMessageReceived_GetMessage(o);
RoomId = CLIB.ppf_RtcRoomMessageReceived_GetRoomId(o);
}
}
/// <summary>
/// The message sent to you by a certain user. You will receive a notification.
/// </summary>
public class RtcUserMessageReceived
{
/// The ID of the message sender.
public readonly string UserId;
/// The message.
public readonly string Message;
/// The ID of the room that the message sender and recipient are in.
public readonly string RoomId;
public RtcUserMessageReceived(IntPtr o)
{
UserId = CLIB.ppf_RtcUserMessageReceived_GetUserId(o);
Message = CLIB.ppf_RtcUserMessageReceived_GetMessage(o);
RoomId = CLIB.ppf_RtcUserMessageReceived_GetRoomId(o);
}
}
/// <summary>
/// The stream sync info sent to your room. You will receive a notification,
/// </summary>
public class RtcStreamSyncInfo
{
/// The key of the stream.
public readonly RtcRemoteStreamKey StreamKey;
/// The type of the stream.
public readonly RtcSyncInfoStreamType StreamType;
/// The stream sync info
public readonly byte[] Data;
public RtcStreamSyncInfo(IntPtr o)
{
StreamKey = new RtcRemoteStreamKey(CLIB.ppf_RtcStreamSyncInfo_GetStreamKey(o));
StreamType = CLIB.ppf_RtcStreamSyncInfo_GetStreamType(o);
var ptr = CLIB.ppf_RtcStreamSyncInfo_GetData(o);
var sz = CLIB.ppf_RtcStreamSyncInfo_GetLength(o);
Data = MarshalUtil.ByteArrayFromNative(ptr, (uint) sz);
}
}
/// <summary>
/// If you enable audio properties report, you will periodically receive audio property info.
/// </summary>
public class RtcAudioPropertyInfo
{
/// The volume detected. It's a value between `0` and `255`.
public readonly int Volume;
public RtcAudioPropertyInfo(IntPtr o)
{
Volume = CLIB.ppf_RtcAudioPropertyInfo_GetVolume(o);
}
}
/// <summary>
/// You will receive this message after you call \ref RtcService.JoinRoom.
/// </summary>
public class RtcJoinRoomResult
{
/// The ID of the room that the user joined.
public readonly string RoomId;
/// The ID of the user.
public readonly string UserId;
/// The error code. `0` indicates success.
public readonly int ErrorCode;
/// The time from calling \ref RtcService.JoinRoom to receiving the result.
public readonly int Elapsed;
/// Whether it is the first time that the user has joined the room or if the user is reconnected to the room.
public readonly RtcJoinRoomType JoinType;
public RtcJoinRoomResult(IntPtr o)
{
RoomId = CLIB.ppf_RtcJoinRoomResult_GetRoomId(o);
UserId = CLIB.ppf_RtcJoinRoomResult_GetUserId(o);
ErrorCode = CLIB.ppf_RtcJoinRoomResult_GetErrorCode(o);
Elapsed = CLIB.ppf_RtcJoinRoomResult_GetElapsed(o);
JoinType = CLIB.ppf_RtcJoinRoomResult_GetJoinType(o);
}
}
/// <summary>
/// You will receive this message after you call \ref RtcService.LeaveRoom.
/// </summary>
public class RtcLeaveRoomResult
{
/// The ID of the room that the user left.
public readonly string RoomId;
public RtcLeaveRoomResult(IntPtr o)
{
RoomId = CLIB.ppf_RtcLeaveRoomResult_GetRoomId(o);
}
}
/// <summary>
/// The local audio properties info.
/// You will periodically receive this message after you
/// call \ref RtcService.EnableAudioPropertiesReport.
/// </summary>
public class RtcLocalAudioPropertiesInfo
{
/// The stream index info.
public readonly RtcStreamIndex StreamIndex;
/// The audio property details.
public readonly RtcAudioPropertyInfo AudioPropertyInfo;
public RtcLocalAudioPropertiesInfo(IntPtr o)
{
StreamIndex = CLIB.ppf_RtcLocalAudioPropertiesInfo_GetStreamIndex(o);
AudioPropertyInfo = new RtcAudioPropertyInfo(CLIB.ppf_RtcLocalAudioPropertiesInfo_GetAudioPropertyInfo(o));
}
}
/// <summary>
/// The local audio properties report.
/// You will periodically receive this message after you
/// call \ref RtcService.EnableAudioPropertiesReport.
/// </summary>
public class RtcLocalAudioPropertiesReport
{
public readonly RtcLocalAudioPropertiesInfo[] AudioPropertiesInfos;
public RtcLocalAudioPropertiesReport(IntPtr o)
{
ulong total = (ulong) CLIB.ppf_RtcLocalAudioPropertiesReport_GetAudioPropertiesInfosSize(o);
AudioPropertiesInfos = new RtcLocalAudioPropertiesInfo[total];
for (uint i = 0; i < total; i++)
{
AudioPropertiesInfos[i] = new RtcLocalAudioPropertiesInfo(CLIB.ppf_RtcLocalAudioPropertiesReport_GetAudioPropertiesInfos(o, (UIntPtr) i));
}
}
}
/// <summary>
/// The media device change info.
/// RTC engine will send this message if media device change is detected.
/// </summary>
public class RtcMediaDeviceChangeInfo
{
/// <summary>
/// Device ID.
/// </summary>
public readonly string DeviceId;
/// <summary>
/// Device type.
/// </summary>
public readonly RtcMediaDeviceType DeviceType;
/// <summary>
/// Device state.
/// </summary>
public readonly RtcMediaDeviceState DeviceState;
/// <summary>
/// Device error.
/// </summary>
public readonly RtcMediaDeviceError DeviceError;
public RtcMediaDeviceChangeInfo(IntPtr o)
{
DeviceId = CLIB.ppf_RtcMediaDeviceChangeInfo_GetDeviceId(o);
DeviceType = CLIB.ppf_RtcMediaDeviceChangeInfo_GetDeviceType(o);
DeviceState = CLIB.ppf_RtcMediaDeviceChangeInfo_GetDeviceState(o);
DeviceError = CLIB.ppf_RtcMediaDeviceChangeInfo_GetDeviceError(o);
}
}
/// <summary>
/// You will receive this notification if the remote user call \ref RtcService.MuteLocalAudio.
/// </summary>
public class RtcMuteInfo
{
/// The ID of the remote user who muted audio.
public readonly string UserId;
/// The state of audio muting: muted or canceled.
public readonly RtcMuteState MuteState;
public RtcMuteInfo(IntPtr o)
{
UserId = CLIB.ppf_RtcMuteInfo_GetUserId(o);
MuteState = CLIB.ppf_RtcMuteInfo_GetMuteState(o);
}
}
/// <summary>
/// The remote audio properties info.
/// You can check who is speaking by this method.
/// </summary>
public class RtcRemoteAudioPropertiesInfo
{
public readonly RtcRemoteStreamKey StreamKey;
public readonly RtcAudioPropertyInfo AudioPropertiesInfo;
public RtcRemoteAudioPropertiesInfo(IntPtr o)
{
StreamKey = new RtcRemoteStreamKey(CLIB.ppf_RtcRemoteAudioPropertiesInfo_GetStreamKey(o));
AudioPropertiesInfo = new RtcAudioPropertyInfo(CLIB.ppf_RtcRemoteAudioPropertiesInfo_GetAudioPropertiesInfo(o));
}
}
/// <summary>
/// You will receive remote user's audio info if you call \ref RtcService.EnableAudioPropertiesReport.
/// </summary>
public class RtcRemoteAudioPropertiesReport
{
public readonly RtcRemoteAudioPropertiesInfo[] AudioPropertiesInfos;
/// The total volume of remote users in the room.
public readonly int TotalRemoteVolume;
public RtcRemoteAudioPropertiesReport(IntPtr o)
{
AudioPropertiesInfos = new RtcRemoteAudioPropertiesInfo[(int) CLIB.ppf_RtcRemoteAudioPropertiesReport_GetAudioPropertiesInfosSize(o)];
for (uint i = 0; i < AudioPropertiesInfos.Length; i++)
{
AudioPropertiesInfos[i] = new RtcRemoteAudioPropertiesInfo(CLIB.ppf_RtcRemoteAudioPropertiesReport_GetAudioPropertiesInfos(o, (UIntPtr) i));
}
TotalRemoteVolume = CLIB.ppf_RtcRemoteAudioPropertiesReport_GetTotalRemoteVolume(o);
}
}
/// <summary>
/// RtcRemoteStreamKey indicates the stream index of a remote user.
/// </summary>
public class RtcRemoteStreamKey
{
/// The ID of the room that the remote user is in.
public readonly string RoomId;
/// The ID of the remote user.
public readonly string UserId;
/// Indicates whether the stream is main stream or screen stream.
public readonly RtcStreamIndex RtcStreamIndex;
public RtcRemoteStreamKey(IntPtr o)
{
RoomId = CLIB.ppf_RtcRemoteStreamKey_GetRoomId(o);
UserId = CLIB.ppf_RtcRemoteStreamKey_GetUserId(o);
RtcStreamIndex = CLIB.ppf_RtcRemoteStreamKey_GetStreamIndex(o);
}
}
/// <summary>
/// You will receive an error code when an error occurred in the room.
/// </summary>
public class RtcRoomError
{
/// The error code.
public readonly int Code;
/// The ID of the room where the error occurred.
public readonly string RoomId;
public RtcRoomError(IntPtr o)
{
Code = CLIB.ppf_RtcRoomError_GetCode(o);
RoomId = CLIB.ppf_RtcRoomError_GetRoomId(o);
}
}
/// <summary>
/// You will periodically receive this message after you successfully join a room.
/// </summary>
public class RtcRoomStats
{
/// The time elapsed since you joined the room .
public readonly int TotalDuration;
/// The number of users in the room.
public readonly int UserCount;
/// The ID of the room you joined.
public readonly string RoomId;
public RtcRoomStats(IntPtr o)
{
TotalDuration = CLIB.ppf_RtcRoomStats_GetTotalDuration(o);
UserCount = CLIB.ppf_RtcRoomStats_GetUserCount(o);
RoomId = CLIB.ppf_RtcRoomStats_GetRoomId(o);
}
}
/// <summary>
/// The warning info of the room.
/// </summary>
public class RtcRoomWarn
{
/// The error code.
public readonly int Code;
/// The ID of the room that the warning info comes from.
public readonly string RoomId;
public RtcRoomWarn(IntPtr o)
{
Code = CLIB.ppf_RtcRoomWarn_GetCode(o);
RoomId = CLIB.ppf_RtcRoomWarn_GetRoomId(o);
}
}
/// <summary>
/// You will receive this message after a remote user joins the room.
/// </summary>
public class RtcUserJoinInfo
{
/// The ID of the user.
public readonly string UserId;
/// If the remote user set the `UserExtra` field when calling \ref RtcService.JoinRoom with extra info.
public readonly string UserExtra;
/// The time used for the remote user to join the room.
public readonly int Elapsed;
/// The ID of the room that the remote user joined.
public readonly string RoomId;
public RtcUserJoinInfo(IntPtr o)
{
UserId = CLIB.ppf_RtcUserJoinInfo_GetUserId(o);
UserExtra = CLIB.ppf_RtcUserJoinInfo_GetUserExtra(o);
Elapsed = CLIB.ppf_RtcUserJoinInfo_GetElapsed(o);
RoomId = CLIB.ppf_RtcUserJoinInfo_GetRoomId(o);
}
}
/// <summary>
/// You will receive this message when the remote user leaves the room.
/// </summary>
public class RtcUserLeaveInfo
{
/// The ID of the user.
public readonly string UserId;
/// The reason why the user left the room, which can be network error or proactive quit.
public readonly RtcUserLeaveReasonType OfflineReason;
/// The ID of the room that the user left.
public readonly string RoomId;
public RtcUserLeaveInfo(IntPtr o)
{
UserId = CLIB.ppf_RtcUserLeaveInfo_GetUserId(o);
OfflineReason = CLIB.ppf_RtcUserLeaveInfo_GetOfflineReason(o);
RoomId = CLIB.ppf_RtcUserLeaveInfo_GetRoomId(o);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: df80498d870b6584980cc5a5d3bb404f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,111 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
/// <summary>
/// Room info.
/// </summary>
public class Room
{
/// The datastore that stores a room's metadata. The maximum datastore key length is 32 bytes and the maximum datastore value length is 64 bytes.
public readonly Dictionary<string, string> DataStore;
/// Room description. The maximum length is 128 bytes.
public readonly string Description;
/// Room ID.
public readonly UInt64 RoomId;
/// Whether the room is locked.
public readonly bool IsMembershipLocked;
/// Room's join policy.
public readonly RoomJoinPolicy RoomJoinPolicy;
/// Room's joinability.
public readonly RoomJoinability RoomJoinability;
/// The maximum number of users allowed to join a room, which is `100`.
public readonly uint MaxUsers;
/// Room owner. This field can be null. Need to check whether it is null before use.
public readonly User OwnerOptional;
/// Room type.
public readonly RoomType RoomType;
/// Room members. This field can be null. Need to check whether it is null before use.
public readonly UserList UsersOptional;
/// Room name.
public readonly string Name;
/// The Num of the users in room.
public readonly uint PlayerNumber;
public Room(IntPtr o)
{
PlayerNumber = CLIB.ppf_Room_GetPlayerNumber(o);
DataStore = CLIB.DataStoreFromNative(CLIB.ppf_Room_GetDataStore(o));
Description = CLIB.ppf_Room_GetDescription(o);
RoomId = CLIB.ppf_Room_GetID(o);
IsMembershipLocked = CLIB.ppf_Room_GetIsMembershipLocked(o);
RoomJoinPolicy = (RoomJoinPolicy) CLIB.ppf_Room_GetJoinPolicy(o);
RoomJoinability = (RoomJoinability) CLIB.ppf_Room_GetJoinability(o);
MaxUsers = CLIB.ppf_Room_GetMaxUsers(o);
Name = CLIB.ppf_Room_GetName(o);
RoomType = (RoomType) CLIB.ppf_Room_GetType(o);
{
var ptr = CLIB.ppf_Room_GetOwner(o);
if (ptr == IntPtr.Zero)
{
OwnerOptional = null;
}
else
{
OwnerOptional = new User(ptr);
}
}
{
var ptr = CLIB.ppf_Room_GetUsers(o);
if (ptr == IntPtr.Zero)
{
UsersOptional = null;
}
else
{
UsersOptional = new UserList(ptr);
}
}
}
}
/// <summary>Room list info. Each element is \ref Room.</summary>
public class RoomList : MessageArray<Room>
{
/// The total number of rooms.
public readonly int TotalCount;
/// The current page idex from which the list begins.
public int CurIndex;
/// The number of rooms given on each page.
public int PageSize;
public RoomList(IntPtr a)
{
TotalCount = CLIB.ppf_RoomArray_GetTotalCount(a);
CurIndex = CLIB.ppf_RoomArray_GetPageIndex(a);
PageSize = CLIB.ppf_RoomArray_GetPageSize(a);
NextPageParam = CLIB.ppf_RoomArray_HasNextPage(a) ? "true" : string.Empty;
int count = (int) CLIB.ppf_RoomArray_GetSize(a);
this.Capacity = count;
for (uint i = 0; i < count; i++)
{
this.Add(new Room(CLIB.ppf_RoomArray_GetElement(a, (UIntPtr)i)));
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b3b9396dfcf9db14a896b58160a9954f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,65 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
/// <summary>
/// The automatic speech recognition result.
/// </summary>
public class AsrResult
{
/// <summary>
/// The text recognized.
/// </summary>
public readonly string Text;
/// <summary>
/// Whether this is the final result:
/// * `true`: yes
/// * `false`: no
/// </summary>
public readonly bool IsFinalResult;
public AsrResult(IntPtr o)
{
Text = CLIB.ppf_AsrResult_GetText(o);
IsFinalResult = CLIB.ppf_AsrResult_GetIsFinalResult(o);
}
}
/// <summary>
/// Information about the automatic speech recognition error.
/// </summary>
public class SpeechError
{
/// <summary>
/// Error message.
/// </summary>
public readonly string Message;
/// <summary>
/// The ID of the session where the error occurred.
/// </summary>
public readonly string SessionId;
/// <summary>
/// Error code.
/// </summary>
public readonly int Code;
public SpeechError(IntPtr o)
{
Message = CLIB.ppf_SpeechError_GetMessage(o);
Code = CLIB.ppf_SpeechError_GetCode(o);
SessionId = CLIB.ppf_SpeechError_GetSessionId(o);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 869552f8209743b5af9b39415c131ee7
timeCreated: 1679484910

View File

@ -0,0 +1,134 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
/// <summary>
/// The summary of daily sport info.
/// Users' daily sports info is recorded in the local database. This structure indicates the sports info generated someday.
/// </summary>
public class SportDailySummary
{
/// The ID of the summary.
public readonly long Id;
/// The date when the summary was generated.
public readonly DateTime Date;
/// The sport duration (in seconds).
public readonly int DurationInSeconds;
/// The planned sport duration (in seconds).
public readonly int PlanDurationInMinutes;
/// The actual calorie burnt (in kilo calorie).
public readonly double Calorie;
/// The planned calorie to burn.
public readonly double PlanCalorie;
public SportDailySummary(IntPtr o)
{
Id = CLIB.ppf_SportDailySummary_GetId(o);
Date = TimeUtil.MilliSecondsToDateTime(CLIB.ppf_SportDailySummary_GetDate(o));
DurationInSeconds = CLIB.ppf_SportDailySummary_GetDurationInSeconds(o);
PlanDurationInMinutes = CLIB.ppf_SportDailySummary_GetPlanDurationInMinutes(o);
Calorie = CLIB.ppf_SportDailySummary_GetCalorie(o);
PlanCalorie = CLIB.ppf_SportDailySummary_GetPlanCalorie(o);
}
}
/// <summary>
/// Each element is \ref SportDailySummary
/// </summary>
public class SportDailySummaryList : MessageArray<SportDailySummary>
{
public SportDailySummaryList(IntPtr a)
{
var count = (int) CLIB.ppf_SportDailySummaryArray_GetSize(a);
this.Capacity = count;
for (int i = 0; i < count; i++)
{
this.Add(new SportDailySummary(CLIB.ppf_SportDailySummaryArray_GetElement(a, (UIntPtr) i)));
}
}
}
/// <summary>
/// User's sport summary of today.
/// </summary>
public class SportSummary
{
/// The sport duration (in seconds).
public readonly int DurationInSeconds;
/// The calorie burnt (in kilo calorie).
public readonly double Calorie;
/// The time when the user started playing sport.
public readonly DateTime StartTime;
/// The time when the user stopped playing sport.
public readonly DateTime EndTime;
public SportSummary(IntPtr o)
{
DurationInSeconds = (int) CLIB.ppf_SportSummary_GetDurationInSeconds(o);
Calorie = CLIB.ppf_SportSummary_GetCalorie(o);
StartTime = TimeUtil.MilliSecondsToDateTime(CLIB.ppf_SportSummary_GetStartTime(o));
EndTime = TimeUtil.MilliSecondsToDateTime(CLIB.ppf_SportSummary_GetEndTime(o));
}
}
/// <summary>
/// The user's sport info.
/// User can set sport goal in the Sport Center app.
/// </summary>
public class SportUserInfo
{
public readonly Gender Gender;
public readonly DateTime Birthday;
/// The height of the user (in cm).
public readonly int Stature;
/// The weight of the user (in kg).
public readonly int Weight;
/// The sport level that indicates the intensity of the sport.
public readonly int SportLevel;
/// The planned daily sport duration (in minutes).
public readonly int DailyDurationInMinutes;
/// The planned weekly sport days.
public readonly int DaysPerWeek;
/// The sport purpose, such as `keep fit` and `lose weight`.
public readonly SportTarget SportTarget;
public SportUserInfo(IntPtr o)
{
Gender = CLIB.ppf_SportUserInfo_GetGender(o);
Birthday = TimeUtil.MilliSecondsToDateTime(CLIB.ppf_SportUserInfo_GetBirthday(o));
Stature = CLIB.ppf_SportUserInfo_GetStature(o);
Weight = CLIB.ppf_SportUserInfo_GetWeight(o);
SportLevel = CLIB.ppf_SportUserInfo_GetSportLevel(o);
DailyDurationInMinutes = CLIB.ppf_SportUserInfo_GetDailyDurationInMinutes(o);
DaysPerWeek = CLIB.ppf_SportUserInfo_GetDaysPerWeek(o);
SportTarget = CLIB.ppf_SportUserInfo_GetSportTarget(o);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fb62290b60b54d6297318c9a437b7269
timeCreated: 1657617406

View File

@ -0,0 +1,286 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
namespace Pico.Platform.Models
{
/// <summary>
/// The User info structure.
/// Basic fields, such as `DisplayName` and `ImageUrl`, are always valid.
/// Some fields, such as presence-related fields, are valid only when you call presence-related APIs.
/// See also: \ref UserService.GetLoggedInUser
/// </summary>
public class User
{
/// User's display name.
public readonly string DisplayName;
///The URL of user's profile photo. The image size is 300x300.
public readonly string ImageUrl;
/// The URL of the user's small profile photo. The image size is 128x128.
public readonly string SmallImageUrl;
/// User's openID. The same user has different openIDs in different apps.
public readonly string ID;
/// User's presence status which indicates whether the user is online.
public readonly UserPresenceStatus PresenceStatus;
/// User's gender.
public readonly Gender Gender;
/// User's presence information.
public readonly string Presence;
/// The deeplink message.
public readonly string PresenceDeeplinkMessage;
/// The destination's API name.
public readonly string PresenceDestinationApiName;
/// The lobby session ID which identifies a group or team.
public readonly string PresenceLobbySessionId;
/// The match session ID which identifies a competition.
public readonly string PresenceMatchSessionId;
/// User's extra presence information.
public readonly string PresenceExtra;
/// Whether the user can be joined by others.
public readonly bool PresenceIsJoinable;
/// The user's invite token.
public readonly string InviteToken;
/// The user's registration country/region. Returns a country/region code.
public readonly string StoreRegion;
public User(IntPtr obj)
{
DisplayName = CLIB.ppf_User_GetDisplayName(obj);
ImageUrl = CLIB.ppf_User_GetImageUrl(obj);
ID = CLIB.ppf_User_GetID(obj);
InviteToken = CLIB.ppf_User_GetInviteToken(obj);
PresenceStatus = CLIB.ppf_User_GetPresenceStatus(obj);
Gender = CLIB.ppf_User_GetGender(obj);
Presence = CLIB.ppf_User_GetPresence(obj);
PresenceDeeplinkMessage = CLIB.ppf_User_GetPresenceDeeplinkMessage(obj);
PresenceDestinationApiName = CLIB.ppf_User_GetPresenceDestinationApiName(obj);
PresenceLobbySessionId = CLIB.ppf_User_GetPresenceLobbySessionId(obj);
PresenceMatchSessionId = CLIB.ppf_User_GetPresenceMatchSessionId(obj);
PresenceExtra = CLIB.ppf_User_GetPresenceExtra(obj);
PresenceIsJoinable = CLIB.ppf_User_GetPresenceIsJoinable(obj);
SmallImageUrl = CLIB.ppf_User_GetSmallImageUrl(obj);
InviteToken = CLIB.ppf_User_GetInviteToken(obj);
StoreRegion = CLIB.ppf_User_GetStoreRegion(obj);
}
}
/// <summary>
/// Each element is \ref User.
/// </summary>
public class UserList : MessageArray<User>
{
public UserList(IntPtr a)
{
var count = (int) CLIB.ppf_UserArray_GetSize(a);
this.Capacity = count;
for (int i = 0; i < count; i++)
{
this.Add(new User(CLIB.ppf_UserArray_GetElement(a, (UIntPtr) i)));
}
NextPageParam = CLIB.ppf_UserArray_GetNextPageParam(a);
}
}
/// <summary>
/// The user's organization ID.
/// </summary>
public class OrgScopedID
{
/// <summary>
/// The organization ID.
/// </summary>
public readonly string ID;
public OrgScopedID(IntPtr o)
{
ID = CLIB.ppf_OrgScopedID_GetID(o);
}
}
/// <summary>
/// Indicates whether the friend request is canceled or successfully sent.
/// </summary>
public class LaunchFriendResult
{
/// Whether the request is canceled by the user.
public readonly bool DidCancel;
/// Whether the request is successfully sent.
public readonly bool DidSendRequest;
public LaunchFriendResult(IntPtr obj)
{
DidCancel = CLIB.ppf_LaunchFriendRequestFlowResult_GetDidCancel(obj);
DidSendRequest = CLIB.ppf_LaunchFriendRequestFlowResult_GetDidSendRequest(obj);
}
}
/// <summary>
/// The info returned after calling \ref UserService.GetFriendsAndRooms.
/// </summary>
public class UserRoom
{
public readonly User User;
public readonly Room Room;
public UserRoom(IntPtr o)
{
User = new User(CLIB.ppf_UserAndRoom_GetUser(o));
var ptr = CLIB.ppf_UserAndRoom_GetRoom(o);
if (ptr != IntPtr.Zero)
{
Room = new Room(ptr);
}
}
}
/// <summary>
/// Each element is \ref UserRoom.
/// </summary>
public class UserRoomList : MessageArray<UserRoom>
{
public UserRoomList(IntPtr a)
{
var count = (int) CLIB.ppf_UserAndRoomArray_GetSize(a);
this.Capacity = count;
for (int i = 0; i < count; i++)
{
this.Add(new UserRoom(CLIB.ppf_UserAndRoomArray_GetElement(a, (UIntPtr) i)));
}
NextPageParam = CLIB.ppf_UserAndRoomArray_GetNextPageParam(a);
}
}
/// <summary>
/// User permissions list.
/// </summary>
public static class Permissions
{
/// <summary>
/// The permission to get the user's registration information, including the user's nickname, gender, profile photo, and more.
/// </summary>
public const string UserInfo = "user_info";
/// <summary>
/// The permission to get users' friend relations.
/// </summary>
public const string FriendRelation = "friend_relation";
/// <summary>
/// The permission to get the user's information, including the user's gender, birthday, stature, weight, and more, on the PICO Fitness app.
/// </summary>
public const string SportsUserInfo = "sports_userinfo";
/// <summary>
/// The permission to get users' exercise data from the PICO Fitness app.
/// </summary>
public const string SportsSummaryData = "sports_summarydata";
/// <summary>
/// The permission to capture or record the screen, which is required when using the highlight service.
/// </summary>
public const string RecordHighlight = "record_highlight";
}
/// <summary>
/// The result returned after calling \ref UserService.RequestUserPermissions or \ref UserService.GetAuthorizedPermissions.
/// </summary>
public class PermissionResult
{
/// The authorized permissions.
public readonly string[] AuthorizedPermissions;
/// The access token. It has a value only after you call \ref UserService.RequestUserPermissions.
public readonly string AccessToken;
/// The current user's ID.
public readonly string UserID;
public PermissionResult(IntPtr o)
{
{
int sz = (int) CLIB.ppf_PermissionResult_GetAuthorizedPermissionsSize(o);
AuthorizedPermissions = new string[sz];
for (int i = 0; i < sz; i++)
{
AuthorizedPermissions[i] = CLIB.ppf_PermissionResult_GetAuthorizedPermissions(o, (UIntPtr) i);
}
}
AccessToken = CLIB.ppf_PermissionResult_GetAccessToken(o);
UserID = CLIB.ppf_PermissionResult_GetUserID(o);
}
}
/// <summary>
/// The result returned after calling \ref UserService.GetUserRelations.
///
/// This class derives from Dictionary. The key is userId and value is
/// \ref UserRelationType.
/// </summary>
public class UserRelationResult : Dictionary<string, UserRelationType>
{
public UserRelationResult(IntPtr o)
{
{
int sz = (int) CLIB.ppf_UserRelationResult_GetRelationsSize(o);
for (int i = 0; i < sz; i++)
{
string userId = CLIB.ppf_UserRelationResult_GetRelationsKey(o, i);
UserRelationType relation = CLIB.ppf_UserRelationResult_GetRelationsValue(o, i);
Add(userId, relation);
}
}
}
}
/// <summary>
/// The result returned after calling \ref UserService.EntitlementCheck
/// </summary>
public class EntitlementCheckResult
{
/// Whether the user is entitled to use the current app.
public readonly bool HasEntitlement;
/// The status code for entitlement check.
public readonly int StatusCode;
/// The status message for entitlement check. You can show this message to user if the user does not pass the entitlement check.
public readonly string StatusMessage;
public EntitlementCheckResult(IntPtr o)
{
HasEntitlement = CLIB.ppf_EntitlementCheckResult_GetHasEntitlement(o);
StatusCode = CLIB.ppf_EntitlementCheckResult_GetStatusCode(o);
StatusMessage = CLIB.ppf_EntitlementCheckResult_GetStatusMessage(o);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4aae686bf05693c4db87bb0d2875cb40
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f129e135c079ff744a1c426c0798e843
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,339 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cc57c56aed09492bb5ddfa820fcd982c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,209 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d95f2760768458048bb7e3ea645369ef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,251 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1b713a81e59d43a3a50d0dc59b3fda40
timeCreated: 1661772509

View File

@ -0,0 +1,232 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 31e084e3699a42aab6084064d4789f2d
timeCreated: 1664349933

View File

@ -0,0 +1,26 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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());
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ca8e54478ee44174dac9eb355d755c7f
timeCreated: 1679484591

View File

@ -0,0 +1,47 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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));
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 18f2fcae6c334637ae67cdb01c26dab2
timeCreated: 1679567015

View File

@ -0,0 +1,256 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 496980589199efc479aff90a62629be7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,139 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 49c5348fb263404a8d2d84556f274a40
timeCreated: 1686138735

View File

@ -0,0 +1,208 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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));
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e074c6a46e5d441b80ada0813183cb79
timeCreated: 1655278625

View File

@ -0,0 +1,275 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: afa08af6e76749e1b2ccad3292287c4f
timeCreated: 1655221139

View File

@ -0,0 +1,482 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 51d1402fc42ddf141ba5d9bb9e470a26
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,194 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8590c499f74c2f346a273d23e44feadd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,64 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b4c79e1681394a0292f762df49b5cdd4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,502 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ec5d2740554cc9147b92daecb097798d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,978 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5156f6aeca9c5bd4caf2a75e964824db
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,736 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 288ca2a98b45b4d47957eae7a66fc97c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,120 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c640c57562fe4afd8f49c65022cc336b
timeCreated: 1679484591

View File

@ -0,0 +1,108 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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)));
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9138eed51e124e57aac6c3c6a2198ce9
timeCreated: 1657617033

View File

@ -0,0 +1,290 @@
/*******************************************************************************
Copyright © 2015-2022 PICO Technology Co., Ltd.All rights reserved.
NOTICEAll 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());
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d99829583dd409e439ddfb0930207154
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: