From 7b4857617821da8ed96a93a6e23a579650f5ff34 Mon Sep 17 00:00:00 2001 From: ci-gitlab Date: Fri, 17 Feb 2023 18:34:22 +0800 Subject: [PATCH] feat:update upm --- CHANGELOG.md | 260 ++++++++++++++++++++++++ CHANGELOG.md.meta | 3 + Documentation.meta | 8 + Documentation/README.md | 257 +++++++++++++++++++++++ Documentation/README.md.meta | 7 + Plugins.meta | 8 + Plugins/TapTap.Bootstrap.deps.json | 233 +++++++++++++++++++++ Plugins/TapTap.Bootstrap.deps.json.meta | 7 + Plugins/TapTap.Bootstrap.dll | Bin 0 -> 35328 bytes Plugins/TapTap.Bootstrap.dll.meta | 33 +++ Plugins/TapTap.Bootstrap.pdb | Bin 0 -> 16252 bytes Plugins/TapTap.Bootstrap.pdb.meta | 7 + README.md | 254 +++++++++++++++++++++++ README.md.meta | 3 + VERSIONNOTE.md | 0 VERSIONNOTE.md.meta | 7 + package.json | 14 ++ package.json.meta | 7 + 18 files changed, 1108 insertions(+) create mode 100644 CHANGELOG.md create mode 100644 CHANGELOG.md.meta create mode 100644 Documentation.meta create mode 100644 Documentation/README.md create mode 100644 Documentation/README.md.meta create mode 100644 Plugins.meta create mode 100644 Plugins/TapTap.Bootstrap.deps.json create mode 100644 Plugins/TapTap.Bootstrap.deps.json.meta create mode 100644 Plugins/TapTap.Bootstrap.dll create mode 100644 Plugins/TapTap.Bootstrap.dll.meta create mode 100644 Plugins/TapTap.Bootstrap.pdb create mode 100644 Plugins/TapTap.Bootstrap.pdb.meta create mode 100644 README.md create mode 100644 README.md.meta create mode 100644 VERSIONNOTE.md create mode 100644 VERSIONNOTE.md.meta create mode 100644 package.json create mode 100644 package.json.meta diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..9fea556 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,260 @@ +# ChangeLog +## 3.11.1 +- TapTap.Login v3.11.1 +- TapTap.Common v3.11.1 +- LeanCloud.Realtime v0.10.11 +- LeanCloud.Storage v0.10.11 + +## 3.11.0 + +### Dependencies + +- TapTap.Login v3.11.0 +- TapTap.Common v3.11.0 +- LeanCloud.Realtime v0.10.11 +- LeanCloud.Storage v0.10.11 + +## 3.10.0 + +### New Feature +- 支持排行榜 + +### Dependencies + +- TapTap.Login v3.10.0 +- TapTap.Common v3.10.0 +- LeanCloud.Realtime v0.10.11 +- LeanCloud.Storage v0.10.11 + +## 3.9.0 + +### Dependencies + +- TapTap.Login v3.9.0 +- TapTap.Common v3.9.0 +- LeanCloud.Realtime v0.10.11 +- LeanCloud.Storage v0.10.11 + +## 3.8.0 + +### Dependencies + +- TapTap.Login v3.8.0 +- TapTap.Common v3.8.0 +- LeanCloud.Realtime v0.10.10 +- LeanCloud.Storage v0.10.10 + +## 3.7.1 + +### Dependencies + +- TapTap.Login v3.7.1 +- TapTap.Common v3.7.1 +- LeanCloud.Realtime v0.10.0 +- LeanCloud.Storage v0.10.0 + +## 3.7.0 + +### Dependencies + +- TapTap.Login v3.7.0 +- TapTap.Common v3.7.0 +- LeanCloud.Realtime v0.10.0 +- LeanCloud.Storage v0.10.0 + + +## 3.6.3 + +### Dependencies + +- TapTap.Login v3.6.3 +- TapTap.Common v3.6.3 +- LeanCloud.Realtime v0.10.0 +- LeanCloud.Storage v0.10.0 + +## 3.6.1 + +### Dependencies + +- TapTap.Login v3.6.1 +- TapTap.Common v3.6.1 +- LeanCloud.Realtime v0.10.0 +- LeanCloud.Storage v0.10.0 + +## 3.6.0 + +### Dependencies + +- TapTap.Login v3.6.0 +- TapTap.Common v3.6.0 +- LeanCloud.Realtime v0.10.0 +- LeanCloud.Storage v0.10.0 + +## 3.5.0 + +### Dependencies + +- TapTap.Login v3.5.0 +- TapTap.Common v3.5.0 +- LeanCloud.Realtime v0.10.0 +- LeanCloud.Storage v0.10.0 + +## 3.4.0 + +### Dependencies + +- TapTap.Login v3.4.0 +- TapTap.Common v3.4.0 +- LeanCloud.Realtime v0.10.0 +- LeanCloud.Storage v0.10.0 + +## 3.3.0 + +### Dependencies + +- TapTap.Login v3.3.0 +- TapTap.Common v3.3.0 +- LeanCloud.Realtime v0.9.11 +- LeanCloud.Storage v0.9.11 + +## 3.2.0 + +### New Feature + +- 支持云存档 + +### Dependencies + +- TapTap.Login v3.2.0 +- TapTap.Common v3.2.0 +- LeanCloud.Storage v0.9.5 +- LeanCloud.Realtime v0.9.5 + +## 3.1.0 + +### New Feature + +- `TDSUser` 新增好友系统操作 + +### Dependencies + +- TapTap.Login v3.1.0 +- TapTap.Common v3.1.0 +- LeanCloud.Storage v0.9.2 +- LeanCloud.Realtime v0.9.2 + +## 3.0.0 + +TapSDK 3.0 开始,我们在单纯的 TapTap 登录之外,还提供了一个内建账户系统供游戏使用:开发者可以直接用 TapTap OAuth +授权的结果生成一个游戏内的账号(TDSUser),然后用该账号保存更多玩家数据。同时,我们也支持将更多第三方认证登录的结果绑定到这一账号上来(以及后续的解绑操作)。 + +### New Feature + +- 新增 `TDSUser` 用于内建账户系统操作 + +### BreakingChange + +- `TapBootstrap` 接口仅保留 `TapBootstrap.Init(tapConfig)` 接口 + +### Dependencies + +- LeanCloud.Storage v0.8.2 +- TapTap.Login v3.0.0 +- TapTap.Common v3.0.0 + +## 2.1.7 + +### Dependencies + +- TapTap.Common v2.1.7 + +## 2.1.6 + +### Dependencies + +- TapTap.Common v2.1.6 + +## 2.1.5 + +### Dependencies + +- TapTap.Common v2.1.5 + +## 2.1.4 + +### Optimization and fixed bugs + +- 优化多语言相关 + +### Dependencies + +- TapTap.Common v2.1.4 + +## 2.1.3 + +### Feature + +* 新增繁中、日文、韩文、泰文和印尼语多语言配置 + +## 2.1.2 + +### BreakingChange + +* 废弃 OpenUserCenter 接口 + +### Dependencies + +* TapTap.Common v2.1.2 + +## 2.1.1 + +### Feature + +* 新增篝火测试资格校验 + ``` + TapBootstrap.GetTestQualification((bool, error)=>{ }): + ``` +* 通过 TapConfig 进行初始化配置 + * 新增 TapDBConfig 用于 TapDB 初始化配置 + * 新增 ClientSecret 用于 TapSDK 初始化 + ```c# + //建议使用以下 TapConfig 构造方法进行初始化 + var config = new TapConfig.Builder() + .ClientID("client_id") + .ClientSecret("client_secret") + .RegionType(RegionType.CN) + .TapDBConfig(true, "gameChannel", "gameVersion", true) + .ConfigBuilder(); + TapBootstrap.Init(config); + ``` + +### Breaking changes + +* LoginType 删除 Apple、Guest 登陆方式 +* TDS-Info.plist 删除 Apple_SignIn_Enable 配置 +* 废弃 Bind 接口 +* TapConfig 构造方法参数修改 + +### Dependencies + +* TapTap.Common v2.1.1 + +## 2.1.0 + +### Feature + +* 支持性改动用于 TapTap.Friends + +### Dependencies + +* TapTap.Common v2.1.0 + +## 2.0.0 + +### Feature + +* TapTap Bootstrap + +### Dependencies + +* TapTap.Common v2.0.0 \ No newline at end of file diff --git a/CHANGELOG.md.meta b/CHANGELOG.md.meta new file mode 100644 index 0000000..419383c --- /dev/null +++ b/CHANGELOG.md.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7388165be5344a9682382768c5fce466 +timeCreated: 1616755935 \ No newline at end of file diff --git a/Documentation.meta b/Documentation.meta new file mode 100644 index 0000000..1130a03 --- /dev/null +++ b/Documentation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bd03b50332353477c899419b5b455fb0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Documentation/README.md b/Documentation/README.md new file mode 100644 index 0000000..2564c0c --- /dev/null +++ b/Documentation/README.md @@ -0,0 +1,257 @@ +# 使用 TapTap.Bootstrap + +## 使用前提 + +使用 TapTap.Bootstrap 前提是必须依赖以下库: +* [TapTap.Common](https://github.com/TapTap/TapCommon-Unity.git) +* [TapTap.Login](https://github.com/TapTap/TapLogin-Unity.git) +* [LeanCloud.Storage](https://github.com/leancloud/csharp-sdk) +* [LeanCloud.RealTime](https://github.com/leancloud/csharp-sdk) + +## 命名空间 + +```c# +using TapTap.Bootstrap; +``` + +## 接口描述 + +## 1.初始化 + +TapBootstrap 会根据 TapConfig 中的 TapDBConfig 配置来进行 TapDB 的自动初始化。 + +### 开启 TapDB +```c# +var config = new TapConfig.Builder() + .ClientID("client_id") + .ClientToken("client_token") + .ServerURL("https://ikggdre2.lc-cn-n1-shared.com") + .RegionType(RegionType.CN) + .TapDBConfig(true,"channel","gameVersion",true) + .Builder(); +``` +### 关闭 TapDB +```c# +var config = new TapConfig.Builder() + .ClientID("client_id") + .ClientToken("client_token") + .ServerURL("https://ikggdre2.lc-cn-n1-shared.com") + .RegionType(RegionType.CN) +//# .TapDBConfig(false,null,null,false) + .EnableTapDB(false) + .Builder(); +``` +### 初始化 +```c# +TapBootstrap.Init(config); +``` + +## 2.账户系统 + +> 登陆成功之后,都会得到一个 `TDSUser` 实例 + +### 使用 TapTap OAuth 授权结果直接登陆/注册账户系统 + +```c# +var tdsUser = await TDSUser.LoginWithTapTap(); +``` + +### 游客登陆 + +```c# +var tdsUser = await TDSUser.LoginAnonymously(); +``` + +### 使用第三方平台授权登录/注册账户 + +```c# +var tdsUser = await TDSUser.LoginWithAuthData(Dictionary authData, string platform, +LCUserAuthDataLoginOption option = null); +``` + +### 绑定第三方平台授权 + +```c# +await TDSUser.AssociateAuthData(Dictionary authData, string platform); +``` + +### 退出登陆 + +```c# +TDSUser.Logout(); +``` + +## 3.好友系统 + +### 申请成为好友 + +```c# +TDSUser tom, jerry; +await tom.ApplyFriendship(jerry); +``` +申请成功的回调中,我们会得到一个 LCFriendshipRequest 的实例,这个实例中包含了两个用户: +- sourceUser,指请求的发起方,上面的例子中就是 `tom`。 +- friend,指请求的目的方,上面的例子中就是 `jerry`。 + +tom 也可以在申请好友的时候,添加更多的属性,例如 tom 希望加 jerry 为好友的时候,也设定一个名为 cat 的圈子,可以这样操作: + +```cs +Dictionary attrs = new Dictionary { + { "group", "cat" } +}; +await tom.ApplyFriendship(jerry, attrs); +``` + +### 获取好友申请列表 +好友申请有三种状态: + +- `pending`,对方没有回应,还处于等待中。 +- `accepted`,对方已经接受,现在双方成为好友。 +- `declined`,对方已经拒绝。 + +好友请求创建之后默认是 `pending` 状态。 + +jerry 这里可以通过 `friendshipRequestQuery` 来查找不同状态的请求。例如 jerry 想看看新的好友请求,可以这样操作: + +```cs +LCQuery query = jerry.GetFriendshipRequestQuery(LCFriendshipRequest.STATUS_PENDING, false, true); +ReadOnlyCollection reqs = await query.Find(); +foreach (LCFriendshipRequest req in reqs) { + Console.WriteLine(req); +} +``` + +### 处理好友申请 + +jerry 对于新的好友请求,可以同意或者拒绝,也可以什么都不做,无视这些请求,甚至直接删除。这些操作我们都是支持的,请看下面的示例: + +```cs +LCFriendshipRequest tomRequest, tuffyRequest, otherRequest; +await jerry.AcceptFriendshipRequest(tomRequest); +await jerry.DeclineFriendshipRequest(tuffyRequest); +await jerry.DeleteFriendshipRequest(otherRequest); +``` + +注意: +* 在 jerry 拒绝了 tom 的好友请求之后,如果 tom 再次请求成为 jerry 的好友,tom 在执行 applyFriendshipInBackground 时会直接得到错误的应答,表明 jerry 不想和 ta 成为好友。 +* jerry 同意了 tuffy 的好友请求之后,它们就成为了好友,之后两个人中任何一人再次调用 applyFriendshipInBackground 申请横位好友时,也会直接得到错误的应答,表明它们已经是好友无需再次申请。 +* jerry 删除陌生人的好友请求后,对方还可以再次发起请求。 + +### 响应好友变化通知 + +TDS 好友模块支持客户端监听好友状态变化,在游戏中实时给玩家提示。好友状态变化的接口包括 + +```cs +public class FriendshipNotification { + public Action OnNewRequestComing { get; set; } + public Action OnRequestAccepted { get; set; } + public Action OnRequestDeclined { get; set; } +} +``` + +其中: +- onNewRequestComing 表示有其他人申请成为当前用户的好友,通过调用 `LCFriendshipRequest#getSourceUser()` 方法可以获得发起方用户信息。 +- onRequestAccepted 表示当前用户的好友申请被对方通过,通过调用 `LCFriendshipRequest#getFriend()` 方法可以获得对方用户信息。 +- onRequestDeclined 表示当前用户的好友申请被对方拒绝,通过调用 `LCFriendshipRequest#getFriend()` 方法可以获得对方用户信息。 + +开发者可以通过 `TDSUser#registerFriendshipNotification` 来注册通知接收器,通过调用 `TDSUser#unregisterFriendshipNotification` 来取消通知接收器。 + +### 获取好友列表 + +调用 `TDSUser#friendshipQuery()` 可以得到查询好友的 `LCQuery` 实例,之后调用 `LCQuery#findInBackground()` 方法就可以得到好友列表。示例如下: + +```cs +LCQuery query = jerry.GetFirendshipQuery(); +``` + +LCFriendship 里面会包含两个用户: + +- `LCFriendship#getLCUser(LCFriendship.ATTR_USER)` 得到的是 jerry 自己; +- `LCFriendship#getLCUser(LCFriendship.ATTR_FOLLOWEE)` 得到的就是另一方的用户信息。 + +### 删除好友 + +成为好友关系的两个用户,之后也可以单方面删除好友。例如 jerry 不想再和 tom 成为好友,那只需要在自己的好友列表中删除包含 tom 的那条 LCFriendship 记录即可: + +```cs +await friendship.Delete(); +``` + +### 查询好友关系 + +我们使用 LCQuery 可以单独查询两个用户是否为好友关系。 + +```cs +LCQuery query = jerry.GetFirendshipQuery(); +query.whereEqualTo("followee", tom); +int count = await query.Count(); +if (count > 0) { + // tom is a friend of jerry. +} else { + // tom isn't a friend of jerry. +} +``` + +这一查询是通过网络发送到服务端执行的,一般情况下,我们推荐开发者在游戏启动时拉取一次当前登录用户的好友列表,然后缓存在本地,以后需要检查另外玩家是否为当前用户的好友时,直接从缓存中查询即可。如果担心好友数据变化,缓存没有得到及时更新,可以调用前面「响应好友变化通知」的方法,对好友数据更新进行监听,这样在绝大部分时候数据同步都是可以保证的。 + +## 4.云存档 + +### 构建云存档元数据 + +```c# +var gameSave = new TapGameSave +{ + Name = "GameSave_Name",// 存档名称 + Summary = "GameSave_Description", // 该字段会作为展示给用户的实际存档名 + ModifiedAt = DateTime.Now.ToLocalTime(), // 原文件修改时间 + PlayedTime = 1000L, // 游戏时长,单位 ms (非必填) + ProgressValue = 100, // 游戏进度 ,单位 int (非必填) + CoverFilePath = pic, // 游戏封面,可以传入一个本地文件路径,SDK 限制为 png/jpeg 格式 + GameFilePath = dll // 存档源文件,可以传入一个本地文件路径 +}; + +``` +### 保存存档 + +保存存档时,会去检查当前`TDSUser`是否已经登录以及元数据。 + +同时 SDK 在上传时会去限制存档本身以及相关联的两个文件( Cover 以及 GameFile )的权限为当前用户本身。 +```c# +await gameSave.Save(); +``` + +### 查询当前用户的所有存档 + +```c# +var collection = await TapGameSave.GetCurrentUserGameSaves(); + +foreach(var gameSave in collection){ + // 存档概览 + var name = gameSave.Summary; + // 原文件修改时间 + var modifiedAt = gameSave.ModifiedAt; + // 游戏时长 + var playedTime = gameSave.PlayedTime; + // 游戏进度 + var progressValue = gameSave.ProgressValue; + // 游戏封面 + var coverFile = gameSave.CoverFile; + // 存档源文件 + var gameFile = gameSave.GameFile; + // 源文件下载地址 + var gameFileUrl = gameFile.Url; +} +``` + +### 查询当前用户存档 + +我们使用 `LCQuery` 来查询当前用户的云存档。 + +SDK 查询封装了一个限定方法用于查询当前`TDSUser`的云存档。 +```c# +TDSUser user = await TDSUser.GetCurrent(); +LCQuery gameSaveQuery = TapGameSave.GetQueryWithUser(user); +// 查询 Name 为 TDSUser_GameSave_Name 的云存档 +gameSaveQuery.WhereEqualTo("name","TDSUser_GameSave_Name"); +var collection = await gameSaveQuery.Find(); +``` \ No newline at end of file diff --git a/Documentation/README.md.meta b/Documentation/README.md.meta new file mode 100644 index 0000000..125a6de --- /dev/null +++ b/Documentation/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 17ed6166c017a4fcda77ff618f2703db +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins.meta b/Plugins.meta new file mode 100644 index 0000000..bbcf194 --- /dev/null +++ b/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dc389bcfbbddc4d35a997cbc06799975 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/TapTap.Bootstrap.deps.json b/Plugins/TapTap.Bootstrap.deps.json new file mode 100644 index 0000000..1229ab6 --- /dev/null +++ b/Plugins/TapTap.Bootstrap.deps.json @@ -0,0 +1,233 @@ +{ + "runtimeTarget": { + "name": ".NETStandard,Version=v2.0/", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETStandard,Version=v2.0": {}, + ".NETStandard,Version=v2.0/": { + "TapTap.Bootstrap/1.0.0": { + "dependencies": { + "NETStandard.Library": "2.0.3", + "TapTap.Common": "1.0.0", + "TapTap.Login": "1.0.0", + "Common": "1.0.0.0", + "LiveQuery": "1.0.0.0", + "Storage": "1.0.0.0", + "Storage.Unity": "1.0.0.0", + "UnityEngine": "0.0.0.0" + }, + "runtime": { + "TapTap.Bootstrap.dll": {} + } + }, + "Microsoft.NETCore.Platforms/1.1.0": {}, + "NETStandard.Library/2.0.3": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "TapTap.Common/1.0.0": { + "runtime": { + "TapTap.Common.dll": {} + } + }, + "TapTap.Login/1.0.0": { + "dependencies": { + "TapTap.Common": "1.0.0" + }, + "runtime": { + "TapTap.Login.dll": {} + } + }, + "Common/1.0.0.0": { + "runtime": { + "Common.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + }, + "LiveQuery/1.0.0.0": { + "runtime": { + "LiveQuery.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + }, + "Storage/1.0.0.0": { + "runtime": { + "Storage.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + }, + "Storage.Unity/1.0.0.0": { + "runtime": { + "Storage.Unity.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + }, + "UnityEngine/0.0.0.0": { + "runtime": { + "UnityEngine.dll": { + "assemblyVersion": "0.0.0.0", + "fileVersion": "0.0.0.0" + } + } + }, + "LC.Newtonsoft.Json/11.0.0.0": { + "runtime": { + "LC.Newtonsoft.Json.dll": { + "assemblyVersion": "11.0.0.0", + "fileVersion": "11.0.1.0" + } + } + }, + "Realtime/1.0.0.0": { + "runtime": { + "Realtime.dll": { + "assemblyVersion": "1.0.0.0", + "fileVersion": "1.0.0.0" + } + } + }, + "LC.Google.Protobuf/3.14.0.0": { + "runtime": { + "LC.Google.Protobuf.dll": { + "assemblyVersion": "3.14.0.0", + "fileVersion": "3.14.0.0" + } + } + }, + "System.Memory/4.0.1.1": { + "runtime": { + "System.Memory.dll": { + "assemblyVersion": "4.0.1.1", + "fileVersion": "4.6.27617.2" + } + } + }, + "System.Runtime.CompilerServices.Unsafe/4.0.4.1": { + "runtime": { + "System.Runtime.CompilerServices.Unsafe.dll": { + "assemblyVersion": "4.0.4.1", + "fileVersion": "4.0.0.0" + } + } + }, + "System.Buffers/4.0.2.0": { + "runtime": { + "System.Buffers.dll": { + "assemblyVersion": "4.0.2.0", + "fileVersion": "4.6.25519.3" + } + } + }, + "System.Numerics.Vectors/4.1.3.0": { + "runtime": { + "System.Numerics.Vectors.dll": { + "assemblyVersion": "4.1.3.0", + "fileVersion": "4.6.25519.3" + } + } + } + } + }, + "libraries": { + "TapTap.Bootstrap/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.NETCore.Platforms/1.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==", + "path": "microsoft.netcore.platforms/1.1.0", + "hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512" + }, + "NETStandard.Library/2.0.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "path": "netstandard.library/2.0.3", + "hashPath": "netstandard.library.2.0.3.nupkg.sha512" + }, + "TapTap.Common/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "TapTap.Login/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Common/1.0.0.0": { + "type": "reference", + "serviceable": false, + "sha512": "" + }, + "LiveQuery/1.0.0.0": { + "type": "reference", + "serviceable": false, + "sha512": "" + }, + "Storage/1.0.0.0": { + "type": "reference", + "serviceable": false, + "sha512": "" + }, + "Storage.Unity/1.0.0.0": { + "type": "reference", + "serviceable": false, + "sha512": "" + }, + "UnityEngine/0.0.0.0": { + "type": "reference", + "serviceable": false, + "sha512": "" + }, + "LC.Newtonsoft.Json/11.0.0.0": { + "type": "reference", + "serviceable": false, + "sha512": "" + }, + "Realtime/1.0.0.0": { + "type": "reference", + "serviceable": false, + "sha512": "" + }, + "LC.Google.Protobuf/3.14.0.0": { + "type": "reference", + "serviceable": false, + "sha512": "" + }, + "System.Memory/4.0.1.1": { + "type": "reference", + "serviceable": false, + "sha512": "" + }, + "System.Runtime.CompilerServices.Unsafe/4.0.4.1": { + "type": "reference", + "serviceable": false, + "sha512": "" + }, + "System.Buffers/4.0.2.0": { + "type": "reference", + "serviceable": false, + "sha512": "" + }, + "System.Numerics.Vectors/4.1.3.0": { + "type": "reference", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Plugins/TapTap.Bootstrap.deps.json.meta b/Plugins/TapTap.Bootstrap.deps.json.meta new file mode 100644 index 0000000..92c4277 --- /dev/null +++ b/Plugins/TapTap.Bootstrap.deps.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 31cab863b627d4a509bd0f259bcf6a31 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/TapTap.Bootstrap.dll b/Plugins/TapTap.Bootstrap.dll new file mode 100644 index 0000000000000000000000000000000000000000..13cc1f0fa248a539d712e23295cde38d8e4fd723 GIT binary patch literal 35328 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

11pfZHoZ06$o94De*dOMpMGpwcd? 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 literal 0 HcmV?d00001 diff --git a/Plugins/TapTap.Bootstrap.pdb.meta b/Plugins/TapTap.Bootstrap.pdb.meta new file mode 100644 index 0000000..1456e1e --- /dev/null +++ b/Plugins/TapTap.Bootstrap.pdb.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b3d6c5154fb9d4319a2a32e6fde07f63 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/README.md b/README.md new file mode 100644 index 0000000..ac2eea9 --- /dev/null +++ b/README.md @@ -0,0 +1,254 @@ +# [使用 TapTap.Bootstrap ](./Documentation/README.md) + +## 使用前提 + +使用 TapTap.Bootstrap 前提是必须依赖以下库: +* [TapTap.Common](https://github.com/TapTap/TapCommon-Unity.git) +* [TapTap.Login](https://github.com/TapTap/TapLogin-Unity.git) +* [LeanCloud.Storage](https://github.com/leancloud/csharp-sdk) +* [LeanCloud.RealTime](https://github.com/leancloud/csharp-sdk) + +## 命名空间 + +```c# +using TapTap.Bootstrap; +``` + +## 接口描述 + +## 1.初始化 + +TapBootstrap 会根据 TapConfig 中的 TapDBConfig 配置来进行 TapDB 的自动初始化。 + +### 开启 TapDB +```c# +var config = new TapConfig.Builder() + .ClientID("client_id") + .ClientToken("client_token") + .ServerURL("https://ikggdre2.lc-cn-n1-shared.com") + .RegionType(RegionType.CN) + .TapDBConfig(true,"channel","gameVersion",true) + .Builder(); +``` +### 关闭 TapDB +```c# +var config = new TapConfig.Builder() + .ClientID("client_id") + .ClientToken("client_token") + .ServerURL("https://ikggdre2.lc-cn-n1-shared.com") + .RegionType(RegionType.CN) +//# .TapDBConfig(false,null,null,false) + .EnableTapDB(false) + .Builder(); +``` +### 初始化 +```c# +TapBootstrap.Init(config); +``` + +## 2.账户系统 + +> 登陆成功之后,都会得到一个 `TDSUser` 实例 + +### 使用 TapTap OAuth 授权结果直接登陆/注册账户系统 + +```c# +var tdsUser = await TDSUser.LoginWithTapTap(); +``` + +### 游客登陆 + +```c# +var tdsUser = await TDSUser.LoginAnonymously(); +``` + +### 使用第三方平台授权登录/注册账户 + +```c# +var tdsUser = await TDSUser.LoginWithAuthData(Dictionary authData, string platform, +LCUserAuthDataLoginOption option = null); +``` + +### 绑定第三方平台授权 + +```c# +await TDSUser.AssociateAuthData(Dictionary authData, string platform); +``` + +### 退出登陆 + +```c# +TDSUser.Logout(); +``` + +## 3.好友系统 + +### 申请成为好友 + +```c# +TDSUser tom, jerry; +await tom.ApplyFriendship(jerry); +``` +申请成功的回调中,我们会得到一个 LCFriendshipRequest 的实例,这个实例中包含了两个用户: +- sourceUser,指请求的发起方,上面的例子中就是 `tom`。 +- friend,指请求的目的方,上面的例子中就是 `jerry`。 + +tom 也可以在申请好友的时候,添加更多的属性,例如 tom 希望加 jerry 为好友的时候,也设定一个名为 cat 的圈子,可以这样操作: + +```cs +Dictionary attrs = new Dictionary { + { "group", "cat" } +}; +await tom.ApplyFriendship(jerry, attrs); +``` + +### 获取好友申请列表 +好友申请有三种状态: + +- `pending`,对方没有回应,还处于等待中。 +- `accepted`,对方已经接受,现在双方成为好友。 +- `declined`,对方已经拒绝。 + +好友请求创建之后默认是 `pending` 状态。 + +jerry 这里可以通过 `friendshipRequestQuery` 来查找不同状态的请求。例如 jerry 想看看新的好友请求,可以这样操作: + +```cs +LCQuery query = jerry.GetFriendshipRequestQuery(LCFriendshipRequest.STATUS_PENDING, false, true); +ReadOnlyCollection reqs = await query.Find(); +foreach (LCFriendshipRequest req in reqs) { + Console.WriteLine(req); +} +``` + +### 处理好友申请 + +jerry 对于新的好友请求,可以同意或者拒绝,也可以什么都不做,无视这些请求,甚至直接删除。这些操作我们都是支持的,请看下面的示例: + +```cs +LCFriendshipRequest tomRequest, tuffyRequest, otherRequest; +await jerry.AcceptFriendshipRequest(tomRequest); +await jerry.DeclineFriendshipRequest(tuffyRequest); +await jerry.DeleteFriendshipRequest(otherRequest); +``` + +注意: +* 在 jerry 拒绝了 tom 的好友请求之后,如果 tom 再次请求成为 jerry 的好友,tom 在执行 applyFriendshipInBackground 时会直接得到错误的应答,表明 jerry 不想和 ta 成为好友。 +* jerry 同意了 tuffy 的好友请求之后,它们就成为了好友,之后两个人中任何一人再次调用 applyFriendshipInBackground 申请横位好友时,也会直接得到错误的应答,表明它们已经是好友无需再次申请。 +* jerry 删除陌生人的好友请求后,对方还可以再次发起请求。 + +### 响应好友变化通知 + +TDS 好友模块支持客户端监听好友状态变化,在游戏中实时给玩家提示。好友状态变化的接口包括 + +```cs +public class FriendshipNotification { + public Action OnNewRequestComing { get; set; } + public Action OnRequestAccepted { get; set; } + public Action OnRequestDeclined { get; set; } +} +``` + +其中: +- onNewRequestComing 表示有其他人申请成为当前用户的好友,通过调用 `LCFriendshipRequest#getSourceUser()` 方法可以获得发起方用户信息。 +- onRequestAccepted 表示当前用户的好友申请被对方通过,通过调用 `LCFriendshipRequest#getFriend()` 方法可以获得对方用户信息。 +- onRequestDeclined 表示当前用户的好友申请被对方拒绝,通过调用 `LCFriendshipRequest#getFriend()` 方法可以获得对方用户信息。 + +开发者可以通过 `TDSUser#registerFriendshipNotification` 来注册通知接收器,通过调用 `TDSUser#unregisterFriendshipNotification` 来取消通知接收器。 + +### 获取好友列表 + +调用 `TDSUser#friendshipQuery()` 可以得到查询好友的 `LCQuery` 实例,之后调用 `LCQuery#findInBackground()` 方法就可以得到好友列表。示例如下: + +```cs +LCQuery query = jerry.GetFirendshipQuery(); +``` + +LCFriendship 里面会包含两个用户: + +- `LCFriendship#getLCUser(LCFriendship.ATTR_USER)` 得到的是 jerry 自己; +- `LCFriendship#getLCUser(LCFriendship.ATTR_FOLLOWEE)` 得到的就是另一方的用户信息。 + +### 删除好友 + +成为好友关系的两个用户,之后也可以单方面删除好友。例如 jerry 不想再和 tom 成为好友,那只需要在自己的好友列表中删除包含 tom 的那条 LCFriendship 记录即可: + +```cs +await friendship.Delete(); +``` + +### 查询好友关系 + +我们使用 LCQuery 可以单独查询两个用户是否为好友关系。 + +```cs +LCQuery query = jerry.GetFirendshipQuery(); +query.whereEqualTo("followee", tom); +int count = await query.Count(); +if (count > 0) { + // tom is a friend of jerry. +} else { + // tom isn't a friend of jerry. +} +``` + +这一查询是通过网络发送到服务端执行的,一般情况下,我们推荐开发者在游戏启动时拉取一次当前登录用户的好友列表,然后缓存在本地,以后需要检查另外玩家是否为当前用户的好友时,直接从缓存中查询即可。如果担心好友数据变化,缓存没有得到及时更新,可以调用前面「响应好友变化通知」的方法,对好友数据更新进行监听,这样在绝大部分时候数据同步都是可以保证的。 + +## 4.云存档 + +### 构建云存档元数据 + +```c# +var gameSave = new TapGameSave +{ + Name = "GameSave_Name",// 存档名称 + Summary = "GameSave_Description", // 该字段会作为展示给用户的实际存档名 + ModifiedAt = DateTime.Now.ToLocalTime(), // 原文件修改时间 + PlayedTime = 1000L, // 游戏时长,单位 ms (非必填) + ProgressValue = 100, // 游戏进度 ,单位 int (非必填) + CoverFilePath = pic, // 游戏封面,可以传入一个本地文件路径,SDK 限制为 png/jpeg 格式 + GameFilePath = dll // 存档源文件,可以传入一个本地文件路径 +}; + +``` +### 保存存档 + +保存存档时,会去检查当前`TDSUser`是否已经登录以及元数据。 + +同时 SDK 在上传时会去限制存档本身以及相关联的两个文件( Cover 以及 GameFile )的权限为当前用户本身。 +```c# +await gameSave.Save(); +``` + +### 查询当前用户的所有存档 + +```c# +var collection = await TapGameSave.GetCurrentUserGameSaves(); + +foreach(var gameSave in collection){ + // 存档概览 + var name = gameSave.Summary; + // 原文件修改时间 + var modifiedAt = gameSave.ModifiedAt; + // 游戏时长 + var playedTime = gameSave.PlayedTime; + // 游戏进度 + var progressValue = gameSave.ProgressValue; + // 游戏封面 + var coverFile = gameSave.CoverFile; + // 存档源文件 + var gameFile = gameSave.GameFile; + // 源文件下载地址 + var gameFileUrl = gameFile.Url; +} +``` + +### 查询云存档 +云存档只能查询当前用户的所有存档,需要查询该用户的特定存档时,可以增加相应过滤,可参考 [查询条件](https://developer.taptap.com/docs/sdk/storage/guide/objc/#%E6%9F%A5%E8%AF%A2%E6%9D%A1%E4%BB%B6) +```c# +TDSUser user = await TDSUser.GetCurrent(); +LCQuery gameSaveQuery = TapGameSave.GetQueryWithUser(user); +// 查询 Name 为 TDSUser_GameSave_Name 的云存档 +gameSaveQuery.WhereEqualTo("name","TDSUser_GameSave_Name"); +var collection = await gameSaveQuery.Find(); +``` diff --git a/README.md.meta b/README.md.meta new file mode 100644 index 0000000..74191cc --- /dev/null +++ b/README.md.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c5330aab2c6a41699a1601f1af6b27d9 +timeCreated: 1616755935 \ No newline at end of file diff --git a/VERSIONNOTE.md b/VERSIONNOTE.md new file mode 100644 index 0000000..e69de29 diff --git a/VERSIONNOTE.md.meta b/VERSIONNOTE.md.meta new file mode 100644 index 0000000..4bb7039 --- /dev/null +++ b/VERSIONNOTE.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d5391b17003874fb2afc3e309a3f63ef +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/package.json b/package.json new file mode 100644 index 0000000..28203d2 --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "com.taptap.tds.bootstrap", + "displayName": "TapTap Bootstrap", + "description": "TapTap Develop Service", + "version": "3.17.0", + "unity": "2018.3", + "license": "MIT", + "dependencies": { + "com.taptap.tds.common": "https://github.com/TapTap/TapCommon-Unity.git#3.17.0", + "com.taptap.tds.login": "https://github.com/TapTap/TapLogin-Unity.git#3.17.0", + "com.leancloud.realtime": "https://github.com/leancloud/csharp-sdk-upm.git#realtime-0.10.14", + "com.leancloud.storage": "https://github.com/leancloud/csharp-sdk-upm.git#storage-0.10.14" + } +} diff --git a/package.json.meta b/package.json.meta new file mode 100644 index 0000000..a42bf59 --- /dev/null +++ b/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e618b9375caf846708cffea428908521 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: