You've already forked CC-Framework.BriskGameServer
923 lines
30 KiB
C#
923 lines
30 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using UnityEngine;
|
|
|
|
public sealed class BriskQuickStartSample : MonoBehaviour
|
|
{
|
|
[Header("初始化")]
|
|
public string BaseUrl = "https://brisk.lightyears.ltd";
|
|
public string GameKey = "demo-game";
|
|
public string ClientVersion = "1.0.0";
|
|
public string DeviceId = "editor-device";
|
|
public bool ValidateSessionOnInitialize = true;
|
|
|
|
[Header("登录")]
|
|
public string LoginProvider = "tap";
|
|
public string LoginUserId = "tap_user_10001";
|
|
public string LoginCode = string.Empty;
|
|
public string Nickname = "Unity示例玩家";
|
|
public string AvatarUrl = string.Empty;
|
|
|
|
[Header("排行榜")]
|
|
public string RankKey = "season-score";
|
|
public string SubmitScoreValue = "128";
|
|
public string LeaderboardLimit = "10";
|
|
public string AroundMeRange = "5";
|
|
public string SeasonId = string.Empty;
|
|
public string SeasonHistoryLimit = "20";
|
|
|
|
[Header("云存档")]
|
|
public string ArchiveSlotNo = "1";
|
|
public string ArchiveBaseVersion = string.Empty;
|
|
[TextArea(3, 6)]
|
|
public string ArchiveContent = "{\n \"save\": 1,\n \"coins\": 128,\n \"hero\": \"mage\",\n \"title\": \"中文测试存档\"\n}";
|
|
|
|
[Header("公告")]
|
|
public string AnnouncementId = string.Empty;
|
|
|
|
[Header("玩家空间")]
|
|
public string SpacePlayerId = string.Empty;
|
|
public string SpaceLoginProvider = "tap";
|
|
public string SpaceLoginUserId = "tap_user_10001";
|
|
[TextArea(3, 6)]
|
|
public string SpacePayloadText = "{\n \"mood\": \"ready\",\n \"title\": \"你好 Brisk\",\n \"desc\": \"这是中文测试空间数据\"\n}";
|
|
|
|
[Header("演示")]
|
|
public bool AutoRunOnStart;
|
|
|
|
private readonly List<string> _eventLogs = new List<string>();
|
|
|
|
private Vector2 _pageScroll;
|
|
private Vector2 _resultScroll;
|
|
private Vector2 _logScroll;
|
|
private bool _isBusy;
|
|
private string _busyAction = string.Empty;
|
|
private string _statusText = "就绪";
|
|
private string _resultText = "尚未执行请求。";
|
|
private string _lastErrorText = string.Empty;
|
|
private IReadOnlyList<BriskAnnouncementItem> _announcementCache = Array.Empty<BriskAnnouncementItem>();
|
|
private IReadOnlyList<BriskRankSeasonInfo> _seasonHistoryCache = Array.Empty<BriskRankSeasonInfo>();
|
|
|
|
private void OnEnable()
|
|
{
|
|
Brisk.OnInitialized += HandleInitialized;
|
|
Brisk.OnLoggedIn += HandleLoggedIn;
|
|
Brisk.OnLoggedOut += HandleLoggedOut;
|
|
Brisk.OnAuthExpired += HandleAuthExpired;
|
|
Brisk.OnBlockingError += HandleBlockingError;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
Brisk.OnInitialized -= HandleInitialized;
|
|
Brisk.OnLoggedIn -= HandleLoggedIn;
|
|
Brisk.OnLoggedOut -= HandleLoggedOut;
|
|
Brisk.OnAuthExpired -= HandleAuthExpired;
|
|
Brisk.OnBlockingError -= HandleBlockingError;
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
if (AutoRunOnStart)
|
|
{
|
|
RunAction("自动冒烟流程", RunSmokeFlowAsync);
|
|
}
|
|
}
|
|
|
|
[ContextMenu("运行 Brisk 示例")]
|
|
public void RunFromContextMenu()
|
|
{
|
|
RunAction("右键菜单冒烟流程", RunSmokeFlowAsync);
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
var area = new Rect(12f, 12f, Screen.width - 24f, Screen.height - 24f);
|
|
GUILayout.BeginArea(area, GUI.skin.box);
|
|
_pageScroll = GUILayout.BeginScrollView(_pageScroll);
|
|
|
|
DrawHeader();
|
|
DrawStatusPanel();
|
|
DrawInitSection();
|
|
DrawLoginSection();
|
|
DrawPlayerAndConfigSection();
|
|
DrawAnnouncementsSection();
|
|
DrawLeaderboardSection();
|
|
DrawArchiveSection();
|
|
DrawSpaceSection();
|
|
DrawOutputSection();
|
|
|
|
GUILayout.EndScrollView();
|
|
GUILayout.EndArea();
|
|
}
|
|
|
|
private void DrawHeader()
|
|
{
|
|
GUILayout.Label("Brisk IMGUI 测试面板", GUI.skin.box);
|
|
GUILayout.Label("这个场景用于在一个页面内测试 SDK 的完整流程。", GUI.skin.label);
|
|
}
|
|
|
|
private void DrawStatusPanel()
|
|
{
|
|
BeginSection("运行状态");
|
|
DrawReadOnlyRow("已初始化", Brisk.IsInitialized ? "是" : "否");
|
|
DrawReadOnlyRow("已登录", Brisk.IsLoggedIn ? "是" : "否");
|
|
DrawReadOnlyRow("PlayerId", Brisk.PlayerId);
|
|
DrawReadOnlyRow("当前身份", Brisk.Identity == null ? string.Empty : Brisk.Identity.LoginProvider + " / " + Brisk.Identity.LoginUserId);
|
|
DrawReadOnlyRow("当前动作", _isBusy ? _busyAction : "空闲");
|
|
DrawReadOnlyRow("状态", _statusText);
|
|
|
|
GUILayout.BeginHorizontal();
|
|
DrawButton("执行冒烟流程", RunSmokeFlowAsync);
|
|
DrawButton("查看 Bootstrap 缓存", () =>
|
|
{
|
|
SetResult("Bootstrap 缓存", Brisk.Bootstrap);
|
|
return Task.CompletedTask;
|
|
}, Brisk.IsInitialized);
|
|
DrawButton("关闭 SDK", () =>
|
|
{
|
|
Brisk.Shutdown();
|
|
Log("SDK 已关闭。");
|
|
_statusText = "SDK 已关闭";
|
|
return Task.CompletedTask;
|
|
});
|
|
DrawButton("清空输出", () =>
|
|
{
|
|
_resultText = "输出已清空。";
|
|
_lastErrorText = string.Empty;
|
|
_eventLogs.Clear();
|
|
_statusText = "输出已清空";
|
|
return Task.CompletedTask;
|
|
});
|
|
GUILayout.EndHorizontal();
|
|
EndSection();
|
|
}
|
|
|
|
private void DrawInitSection()
|
|
{
|
|
BeginSection("初始化");
|
|
BaseUrl = DrawEditableRow("服务地址", BaseUrl);
|
|
GameKey = DrawEditableRow("游戏 Key", GameKey);
|
|
ClientVersion = DrawEditableRow("客户端版本", ClientVersion);
|
|
DeviceId = DrawEditableRow("设备标识", DeviceId);
|
|
ValidateSessionOnInitialize = DrawToggleRow("初始化时校验旧会话", ValidateSessionOnInitialize);
|
|
|
|
GUILayout.BeginHorizontal();
|
|
DrawButton("初始化", InitializeAsync);
|
|
DrawButton("重新初始化", ReinitializeAsync);
|
|
GUILayout.EndHorizontal();
|
|
EndSection();
|
|
}
|
|
|
|
private void DrawLoginSection()
|
|
{
|
|
BeginSection("登录");
|
|
LoginProvider = DrawEditableRow("登录提供方", LoginProvider);
|
|
LoginUserId = DrawEditableRow("登录用户 ID", LoginUserId);
|
|
LoginCode = DrawEditableRow("登录 Code", LoginCode);
|
|
Nickname = DrawEditableRow("昵称", Nickname);
|
|
AvatarUrl = DrawEditableRow("头像地址", AvatarUrl);
|
|
|
|
GUILayout.BeginHorizontal();
|
|
DrawButton("按用户 ID 登录", LoginWithUserIdAsync, Brisk.IsInitialized);
|
|
DrawButton("按 Code 登录", LoginWithCodeAsync, Brisk.IsInitialized);
|
|
DrawButton("登出", LogoutAsync, Brisk.IsInitialized);
|
|
GUILayout.EndHorizontal();
|
|
EndSection();
|
|
}
|
|
|
|
private void DrawPlayerAndConfigSection()
|
|
{
|
|
BeginSection("玩家与配置");
|
|
GUILayout.BeginHorizontal();
|
|
DrawButton("获取当前玩家", GetMeAsync, Brisk.IsLoggedIn);
|
|
DrawButton("获取当前配置", GetConfigAsync, Brisk.IsInitialized);
|
|
DrawButton("同步当前身份到空间查询", () =>
|
|
{
|
|
ApplyCurrentIdentityToSpace();
|
|
SetResult("空间查询身份", new Dictionary<string, object>
|
|
{
|
|
{ "space_player_id", SpacePlayerId },
|
|
{ "space_login_provider", SpaceLoginProvider },
|
|
{ "space_login_user_id", SpaceLoginUserId }
|
|
});
|
|
return Task.CompletedTask;
|
|
}, Brisk.IsInitialized);
|
|
GUILayout.EndHorizontal();
|
|
EndSection();
|
|
}
|
|
|
|
private void DrawAnnouncementsSection()
|
|
{
|
|
BeginSection("公告");
|
|
AnnouncementId = DrawEditableRow("公告 ID", AnnouncementId);
|
|
|
|
GUILayout.BeginHorizontal();
|
|
DrawButton("获取公告列表", GetAnnouncementsAsync, Brisk.IsLoggedIn);
|
|
DrawButton("标记已读", MarkAnnouncementAsync, Brisk.IsLoggedIn);
|
|
DrawButton("标记首条缓存公告已读", MarkFirstCachedAnnouncementAsync, Brisk.IsLoggedIn && _announcementCache.Count > 0);
|
|
GUILayout.EndHorizontal();
|
|
EndSection();
|
|
}
|
|
|
|
private void DrawLeaderboardSection()
|
|
{
|
|
BeginSection("排行榜");
|
|
RankKey = DrawEditableRow("排行榜 Key", RankKey);
|
|
SubmitScoreValue = DrawEditableRow("提交分数", SubmitScoreValue);
|
|
LeaderboardLimit = DrawEditableRow("Top 数量", LeaderboardLimit);
|
|
AroundMeRange = DrawEditableRow("附近范围", AroundMeRange);
|
|
SeasonId = DrawEditableRow("赛季 ID", SeasonId);
|
|
SeasonHistoryLimit = DrawEditableRow("历史条数", SeasonHistoryLimit);
|
|
|
|
GUILayout.BeginHorizontal();
|
|
DrawButton("获取 Top", GetTopAsync, Brisk.IsLoggedIn);
|
|
DrawButton("获取我的排名", GetMyRankAsync, Brisk.IsLoggedIn);
|
|
DrawButton("获取我附近的排名", GetAroundMeAsync, Brisk.IsLoggedIn);
|
|
GUILayout.EndHorizontal();
|
|
|
|
GUILayout.BeginHorizontal();
|
|
DrawButton("提交分数", SubmitScoreAsync, Brisk.IsLoggedIn);
|
|
DrawButton("获取当前赛季", GetCurrentSeasonAsync, Brisk.IsLoggedIn);
|
|
DrawButton("获取赛季历史", GetSeasonHistoryAsync, Brisk.IsLoggedIn);
|
|
DrawButton("获取赛季详情", GetSeasonDetailAsync, Brisk.IsLoggedIn);
|
|
GUILayout.EndHorizontal();
|
|
EndSection();
|
|
}
|
|
|
|
private void DrawArchiveSection()
|
|
{
|
|
BeginSection("云存档");
|
|
ArchiveSlotNo = DrawEditableRow("槽位号", ArchiveSlotNo);
|
|
ArchiveBaseVersion = DrawEditableRow("基准版本", ArchiveBaseVersion);
|
|
ArchiveContent = DrawTextAreaRow("存档内容", ArchiveContent, 90f);
|
|
|
|
GUILayout.BeginHorizontal();
|
|
DrawButton("获取槽位列表", GetArchiveSlotsAsync, Brisk.IsLoggedIn);
|
|
DrawButton("获取存档元信息", GetArchiveMetaAsync, Brisk.IsLoggedIn);
|
|
DrawButton("上传文本存档", UploadArchiveAsync, Brisk.IsLoggedIn);
|
|
DrawButton("下载存档", DownloadArchiveAsync, Brisk.IsLoggedIn);
|
|
GUILayout.EndHorizontal();
|
|
EndSection();
|
|
}
|
|
|
|
private void DrawSpaceSection()
|
|
{
|
|
BeginSection("玩家空间");
|
|
SpacePlayerId = DrawEditableRow("空间 PlayerId", SpacePlayerId);
|
|
SpaceLoginProvider = DrawEditableRow("空间登录提供方", SpaceLoginProvider);
|
|
SpaceLoginUserId = DrawEditableRow("空间登录用户 ID", SpaceLoginUserId);
|
|
SpacePayloadText = DrawTextAreaRow("空间 Payload 文本", SpacePayloadText, 90f);
|
|
|
|
GUILayout.BeginHorizontal();
|
|
DrawButton("按 PlayerId 获取空间", GetSpaceByPlayerIdAsync, Brisk.IsLoggedIn);
|
|
DrawButton("按登录身份获取空间", GetSpaceByLoginAsync, Brisk.IsLoggedIn);
|
|
DrawButton("按 PlayerId 获取统计", GetSpaceStatsByPlayerIdAsync, Brisk.IsLoggedIn);
|
|
DrawButton("按登录身份获取统计", GetSpaceStatsByLoginAsync, Brisk.IsLoggedIn);
|
|
GUILayout.EndHorizontal();
|
|
|
|
GUILayout.BeginHorizontal();
|
|
DrawButton("按 PlayerId 点赞", LikeByPlayerIdAsync, Brisk.IsLoggedIn);
|
|
DrawButton("按 PlayerId 取消点赞", UnlikeByPlayerIdAsync, Brisk.IsLoggedIn);
|
|
DrawButton("按登录身份点赞", LikeByLoginAsync, Brisk.IsLoggedIn);
|
|
DrawButton("按登录身份取消点赞", UnlikeByLoginAsync, Brisk.IsLoggedIn);
|
|
GUILayout.EndHorizontal();
|
|
|
|
GUILayout.BeginHorizontal();
|
|
DrawButton("更新我的空间", UpdateMySpaceAsync, Brisk.IsLoggedIn);
|
|
DrawButton("获取我的访客", GetMyVisitsAsync, Brisk.IsLoggedIn);
|
|
GUILayout.EndHorizontal();
|
|
EndSection();
|
|
}
|
|
|
|
private void DrawOutputSection()
|
|
{
|
|
BeginSection("输出");
|
|
GUILayout.Label("最近一次结果", GUI.skin.label);
|
|
_resultScroll = GUILayout.BeginScrollView(_resultScroll, GUILayout.Height(240f));
|
|
GUILayout.TextArea(_resultText, GUILayout.ExpandHeight(true));
|
|
GUILayout.EndScrollView();
|
|
|
|
GUILayout.Space(8f);
|
|
GUILayout.Label("最近一次错误", GUI.skin.label);
|
|
GUILayout.TextArea(string.IsNullOrWhiteSpace(_lastErrorText) ? "暂无错误。" : _lastErrorText, GUILayout.Height(90f));
|
|
|
|
GUILayout.Space(8f);
|
|
GUILayout.Label("事件日志", GUI.skin.label);
|
|
_logScroll = GUILayout.BeginScrollView(_logScroll, GUILayout.Height(220f));
|
|
GUILayout.TextArea(_eventLogs.Count == 0 ? "暂无事件。" : string.Join("\n", _eventLogs.ToArray()), GUILayout.ExpandHeight(true));
|
|
GUILayout.EndScrollView();
|
|
EndSection();
|
|
}
|
|
|
|
private async Task InitializeAsync()
|
|
{
|
|
await Brisk.InitializeAsync(new BriskOptions
|
|
{
|
|
BaseUrl = BaseUrl,
|
|
GameKey = GameKey,
|
|
ClientVersion = ClientVersion,
|
|
DeviceId = DeviceId,
|
|
ValidateSessionOnInitialize = ValidateSessionOnInitialize,
|
|
ExitHandler = HandleExitRequested
|
|
});
|
|
|
|
SetResult("初始化结果", Brisk.Bootstrap);
|
|
}
|
|
|
|
private async Task ReinitializeAsync()
|
|
{
|
|
if (Brisk.IsInitialized)
|
|
{
|
|
Brisk.Shutdown();
|
|
Log("重新初始化前已先关闭 SDK。");
|
|
}
|
|
|
|
await InitializeAsync();
|
|
}
|
|
|
|
private async Task LoginWithUserIdAsync()
|
|
{
|
|
var result = await Brisk.Auth.LoginWithUserIdAsync(LoginProvider, LoginUserId, CreateProfile());
|
|
ApplyIdentity(result.PlayerId, result.LoginProvider, result.LoginUserId);
|
|
SetResult("按用户 ID 登录结果", result);
|
|
}
|
|
|
|
private async Task LoginWithCodeAsync()
|
|
{
|
|
var result = await Brisk.Auth.LoginWithCodeAsync(LoginProvider, LoginCode, CreateProfile());
|
|
ApplyIdentity(result.PlayerId, result.LoginProvider, result.LoginUserId);
|
|
SetResult("按 Code 登录结果", result);
|
|
}
|
|
|
|
private async Task LogoutAsync()
|
|
{
|
|
await Brisk.Auth.LogoutAsync();
|
|
SetResult("登出结果", new Dictionary<string, object>
|
|
{
|
|
{ "logged_in", Brisk.IsLoggedIn },
|
|
{ "player_id", Brisk.PlayerId }
|
|
});
|
|
}
|
|
|
|
private async Task GetMeAsync()
|
|
{
|
|
var me = await Brisk.Player.GetMeAsync();
|
|
ApplyIdentity(me.PlayerId, me.LoginProvider, me.LoginUserId);
|
|
SetResult("当前玩家信息", me);
|
|
}
|
|
|
|
private async Task GetConfigAsync()
|
|
{
|
|
var config = await Brisk.Config.GetCurrentAsync();
|
|
SetResult("当前配置", config);
|
|
}
|
|
|
|
private async Task GetAnnouncementsAsync()
|
|
{
|
|
_announcementCache = await Brisk.Announcements.GetListAsync();
|
|
if (_announcementCache.Count > 0 && string.IsNullOrWhiteSpace(AnnouncementId))
|
|
{
|
|
AnnouncementId = _announcementCache[0].Id.ToString();
|
|
}
|
|
|
|
SetResult("公告列表", _announcementCache);
|
|
}
|
|
|
|
private async Task MarkAnnouncementAsync()
|
|
{
|
|
var id = ParseRequiredLong(AnnouncementId, nameof(AnnouncementId));
|
|
await Brisk.Announcements.MarkReadAsync(id);
|
|
SetResult("公告已标记已读", new Dictionary<string, object> { { "announcement_id", id } });
|
|
}
|
|
|
|
private async Task MarkFirstCachedAnnouncementAsync()
|
|
{
|
|
if (_announcementCache.Count == 0)
|
|
{
|
|
throw new InvalidOperationException("公告缓存为空,请先执行“获取公告列表”。");
|
|
}
|
|
|
|
var id = _announcementCache[0].Id;
|
|
AnnouncementId = id.ToString();
|
|
await Brisk.Announcements.MarkReadAsync(id);
|
|
SetResult("首条缓存公告已标记已读", _announcementCache[0]);
|
|
}
|
|
|
|
private async Task GetTopAsync()
|
|
{
|
|
var result = await Brisk.Leaderboard.GetTopAsync(RankKey, ParseOptionalInt(LeaderboardLimit, 10));
|
|
SetResult("排行榜 Top", result);
|
|
}
|
|
|
|
private async Task GetMyRankAsync()
|
|
{
|
|
var result = await Brisk.Leaderboard.GetMeAsync(RankKey);
|
|
SetResult("我的排行榜信息", result);
|
|
}
|
|
|
|
private async Task GetAroundMeAsync()
|
|
{
|
|
var result = await Brisk.Leaderboard.GetAroundMeAsync(RankKey, ParseOptionalInt(AroundMeRange, 5));
|
|
SetResult("我附近的排行榜", result);
|
|
}
|
|
|
|
private async Task SubmitScoreAsync()
|
|
{
|
|
var score = ParseRequiredLong(SubmitScoreValue, nameof(SubmitScoreValue));
|
|
await Brisk.Leaderboard.SubmitScoreAsync(RankKey, score);
|
|
SetResult("分数提交结果", new Dictionary<string, object>
|
|
{
|
|
{ "rank_key", RankKey },
|
|
{ "score", score }
|
|
});
|
|
}
|
|
|
|
private async Task GetCurrentSeasonAsync()
|
|
{
|
|
var result = await Brisk.Leaderboard.GetCurrentSeasonAsync(RankKey);
|
|
SeasonId = result == null ? SeasonId : result.SeasonId;
|
|
SetResult("当前赛季", result);
|
|
}
|
|
|
|
private async Task GetSeasonHistoryAsync()
|
|
{
|
|
_seasonHistoryCache = await Brisk.Leaderboard.GetSeasonHistoryAsync(RankKey, ParseOptionalInt(SeasonHistoryLimit, 20));
|
|
if (_seasonHistoryCache.Count > 0 && string.IsNullOrWhiteSpace(SeasonId))
|
|
{
|
|
SeasonId = _seasonHistoryCache[0].SeasonId;
|
|
}
|
|
|
|
SetResult("赛季历史", _seasonHistoryCache);
|
|
}
|
|
|
|
private async Task GetSeasonDetailAsync()
|
|
{
|
|
var result = await Brisk.Leaderboard.GetSeasonHistoryDetailAsync(RankKey, SeasonId, ParseOptionalInt(SeasonHistoryLimit, 20));
|
|
SetResult("赛季详情", result);
|
|
}
|
|
|
|
private async Task GetArchiveSlotsAsync()
|
|
{
|
|
var result = await Brisk.Archive.GetSlotsAsync();
|
|
SetResult("存档槽位列表", result);
|
|
}
|
|
|
|
private async Task GetArchiveMetaAsync()
|
|
{
|
|
var result = await Brisk.Archive.GetMetaAsync(ParseRequiredInt(ArchiveSlotNo, nameof(ArchiveSlotNo)));
|
|
ArchiveBaseVersion = result == null ? ArchiveBaseVersion : result.Version.ToString();
|
|
SetResult("存档元信息", result);
|
|
}
|
|
|
|
private async Task UploadArchiveAsync()
|
|
{
|
|
var slotNo = ParseRequiredInt(ArchiveSlotNo, nameof(ArchiveSlotNo));
|
|
var baseVersion = ParseNullableInt(ArchiveBaseVersion);
|
|
var bytes = Encoding.UTF8.GetBytes(ArchiveContent ?? string.Empty);
|
|
var result = await Brisk.Archive.UploadAsync(slotNo, bytes, baseVersion);
|
|
ArchiveBaseVersion = result == null ? ArchiveBaseVersion : result.Version.ToString();
|
|
SetResult("存档上传结果", result);
|
|
}
|
|
|
|
private async Task DownloadArchiveAsync()
|
|
{
|
|
var result = await Brisk.Archive.DownloadAsync(ParseRequiredInt(ArchiveSlotNo, nameof(ArchiveSlotNo)));
|
|
ArchiveBaseVersion = result == null ? ArchiveBaseVersion : result.Version.ToString();
|
|
|
|
var output = new Dictionary<string, object>
|
|
{
|
|
{ "version", result.Version },
|
|
{ "checksum", result.Checksum },
|
|
{ "byte_length", result.Bytes == null ? 0 : result.Bytes.Length },
|
|
{ "text_preview", result.Bytes == null ? string.Empty : Encoding.UTF8.GetString(result.Bytes) }
|
|
};
|
|
|
|
SetResult("存档下载结果", output);
|
|
}
|
|
|
|
private async Task GetSpaceByPlayerIdAsync()
|
|
{
|
|
var result = await Brisk.Space.GetByPlayerIdAsync(SpacePlayerId);
|
|
SetResult("按 PlayerId 获取空间", result);
|
|
}
|
|
|
|
private async Task GetSpaceByLoginAsync()
|
|
{
|
|
var result = await Brisk.Space.GetByLoginIdentityAsync(SpaceLoginProvider, SpaceLoginUserId);
|
|
SetResult("按登录身份获取空间", result);
|
|
}
|
|
|
|
private async Task GetSpaceStatsByPlayerIdAsync()
|
|
{
|
|
var result = await Brisk.Space.GetStatsByPlayerIdAsync(SpacePlayerId);
|
|
SetResult("按 PlayerId 获取空间统计", result);
|
|
}
|
|
|
|
private async Task GetSpaceStatsByLoginAsync()
|
|
{
|
|
var result = await Brisk.Space.GetStatsByLoginIdentityAsync(SpaceLoginProvider, SpaceLoginUserId);
|
|
SetResult("按登录身份获取空间统计", result);
|
|
}
|
|
|
|
private async Task LikeByPlayerIdAsync()
|
|
{
|
|
await Brisk.Space.LikeByPlayerIdAsync(SpacePlayerId);
|
|
SetResult("按 PlayerId 点赞结果", new Dictionary<string, object> { { "player_id", SpacePlayerId } });
|
|
}
|
|
|
|
private async Task UnlikeByPlayerIdAsync()
|
|
{
|
|
await Brisk.Space.UnlikeByPlayerIdAsync(SpacePlayerId);
|
|
SetResult("按 PlayerId 取消点赞结果", new Dictionary<string, object> { { "player_id", SpacePlayerId } });
|
|
}
|
|
|
|
private async Task LikeByLoginAsync()
|
|
{
|
|
await Brisk.Space.LikeByLoginIdentityAsync(SpaceLoginProvider, SpaceLoginUserId);
|
|
SetResult("按登录身份点赞结果", new Dictionary<string, object>
|
|
{
|
|
{ "login_provider", SpaceLoginProvider },
|
|
{ "login_user_id", SpaceLoginUserId }
|
|
});
|
|
}
|
|
|
|
private async Task UnlikeByLoginAsync()
|
|
{
|
|
await Brisk.Space.UnlikeByLoginIdentityAsync(SpaceLoginProvider, SpaceLoginUserId);
|
|
SetResult("按登录身份取消点赞结果", new Dictionary<string, object>
|
|
{
|
|
{ "login_provider", SpaceLoginProvider },
|
|
{ "login_user_id", SpaceLoginUserId }
|
|
});
|
|
}
|
|
|
|
private async Task UpdateMySpaceAsync()
|
|
{
|
|
var payload = new Dictionary<string, object>
|
|
{
|
|
{ "sample_text", SpacePayloadText },
|
|
{ "updated_at", DateTimeOffset.UtcNow.ToString("O") },
|
|
{ "player_id", Brisk.PlayerId },
|
|
{ "rank_key", RankKey }
|
|
};
|
|
|
|
await Brisk.Space.UpdateMyAsync(payload);
|
|
SetResult("更新我的空间结果", payload);
|
|
}
|
|
|
|
private async Task GetMyVisitsAsync()
|
|
{
|
|
var result = await Brisk.Space.GetMyVisitsAsync();
|
|
SetResult("我的访客列表", result);
|
|
}
|
|
|
|
private async Task RunSmokeFlowAsync()
|
|
{
|
|
await InitializeAsync();
|
|
|
|
if (!Brisk.IsLoggedIn)
|
|
{
|
|
await LoginWithUserIdAsync();
|
|
}
|
|
|
|
await GetMeAsync();
|
|
await GetConfigAsync();
|
|
await GetTopAsync();
|
|
await GetAnnouncementsAsync();
|
|
await GetArchiveSlotsAsync();
|
|
await GetMyVisitsAsync();
|
|
}
|
|
|
|
private void DrawButton(string label, Func<Task> action, bool enabled = true)
|
|
{
|
|
var previous = GUI.enabled;
|
|
GUI.enabled = previous && !_isBusy && enabled;
|
|
if (GUILayout.Button(label, GUILayout.Height(30f)))
|
|
{
|
|
RunAction(label, action);
|
|
}
|
|
|
|
GUI.enabled = previous;
|
|
}
|
|
|
|
private void RunAction(string actionName, Func<Task> action)
|
|
{
|
|
if (_isBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
RunActionAsync(actionName, action);
|
|
}
|
|
|
|
private async void RunActionAsync(string actionName, Func<Task> action)
|
|
{
|
|
_isBusy = true;
|
|
_busyAction = actionName;
|
|
_statusText = "执行中: " + actionName;
|
|
_lastErrorText = string.Empty;
|
|
Log("开始执行: " + actionName);
|
|
|
|
try
|
|
{
|
|
await action();
|
|
_statusText = "执行成功: " + actionName;
|
|
Log("执行成功: " + actionName);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
_statusText = "执行失败: " + actionName;
|
|
_lastErrorText = FormatException(exception);
|
|
Log("执行失败: " + actionName + " | " + exception.GetType().Name + " | " + exception.Message);
|
|
Debug.LogException(exception, this);
|
|
}
|
|
finally
|
|
{
|
|
_busyAction = string.Empty;
|
|
_isBusy = false;
|
|
}
|
|
}
|
|
|
|
private void SetResult(string title, object value)
|
|
{
|
|
_resultText = title + "\n" + new string('=', title.Length) + "\n" + FormatValue(value);
|
|
}
|
|
|
|
private void ApplyIdentity(string playerId, string loginProvider, string loginUserId)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(playerId))
|
|
{
|
|
SpacePlayerId = playerId;
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(loginProvider))
|
|
{
|
|
SpaceLoginProvider = loginProvider;
|
|
LoginProvider = loginProvider;
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(loginUserId))
|
|
{
|
|
SpaceLoginUserId = loginUserId;
|
|
LoginUserId = loginUserId;
|
|
}
|
|
}
|
|
|
|
private void ApplyCurrentIdentityToSpace()
|
|
{
|
|
if (Brisk.Identity != null)
|
|
{
|
|
ApplyIdentity(Brisk.Identity.PlayerId, Brisk.Identity.LoginProvider, Brisk.Identity.LoginUserId);
|
|
return;
|
|
}
|
|
|
|
if (Brisk.IsInitialized)
|
|
{
|
|
ApplyIdentity(Brisk.PlayerId, LoginProvider, LoginUserId);
|
|
}
|
|
}
|
|
|
|
private BriskProfile CreateProfile()
|
|
{
|
|
return new BriskProfile
|
|
{
|
|
Nickname = Nickname,
|
|
AvatarUrl = AvatarUrl
|
|
};
|
|
}
|
|
|
|
private void HandleInitialized()
|
|
{
|
|
Log("事件: 初始化完成");
|
|
}
|
|
|
|
private void HandleLoggedIn()
|
|
{
|
|
Log("事件: 登录完成");
|
|
ApplyCurrentIdentityToSpace();
|
|
}
|
|
|
|
private void HandleLoggedOut()
|
|
{
|
|
Log("事件: 登出完成");
|
|
}
|
|
|
|
private void HandleAuthExpired(BriskAuthExpiredException exception)
|
|
{
|
|
Log("事件: 登录态失效 | " + exception.Message);
|
|
}
|
|
|
|
private void HandleBlockingError(BriskBlockingException exception)
|
|
{
|
|
Log("事件: 严重阻断错误 | " + exception.Message);
|
|
}
|
|
|
|
private void HandleExitRequested()
|
|
{
|
|
Log("Brisk 阻断流程请求退出。");
|
|
}
|
|
|
|
private void Log(string message)
|
|
{
|
|
var line = "[" + DateTime.Now.ToString("HH:mm:ss") + "] " + message;
|
|
_eventLogs.Add(line);
|
|
if (_eventLogs.Count > 120)
|
|
{
|
|
_eventLogs.RemoveAt(0);
|
|
}
|
|
|
|
_logScroll.y = float.MaxValue;
|
|
}
|
|
|
|
private static int ParseRequiredInt(string value, string fieldName)
|
|
{
|
|
if (!int.TryParse(value, out var result))
|
|
{
|
|
throw new InvalidOperationException(fieldName + " 必须是合法整数。");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private static long ParseRequiredLong(string value, string fieldName)
|
|
{
|
|
if (!long.TryParse(value, out var result))
|
|
{
|
|
throw new InvalidOperationException(fieldName + " 必须是合法整数。");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private static int ParseOptionalInt(string value, int fallback)
|
|
{
|
|
return int.TryParse(value, out var result) ? result : fallback;
|
|
}
|
|
|
|
private static int? ParseNullableInt(string value)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return int.TryParse(value, out var result) ? result : (int?)null;
|
|
}
|
|
|
|
private static string FormatException(Exception exception)
|
|
{
|
|
if (exception == null)
|
|
{
|
|
return "未知错误。";
|
|
}
|
|
|
|
var builder = new StringBuilder();
|
|
var current = exception;
|
|
while (current != null)
|
|
{
|
|
builder.AppendLine(current.GetType().Name + ": " + current.Message);
|
|
current = current.InnerException;
|
|
}
|
|
|
|
return builder.ToString().TrimEnd();
|
|
}
|
|
|
|
private static string FormatValue(object value)
|
|
{
|
|
var builder = new StringBuilder();
|
|
AppendValue(builder, value, 0, 0);
|
|
return builder.ToString().TrimEnd();
|
|
}
|
|
|
|
private static void AppendValue(StringBuilder builder, object value, int indent, int depth)
|
|
{
|
|
if (depth > 5)
|
|
{
|
|
builder.AppendLine(Indent(indent) + "...");
|
|
return;
|
|
}
|
|
|
|
if (value == null)
|
|
{
|
|
builder.AppendLine(Indent(indent) + "null");
|
|
return;
|
|
}
|
|
|
|
if (value is string stringValue)
|
|
{
|
|
builder.AppendLine(Indent(indent) + stringValue);
|
|
return;
|
|
}
|
|
|
|
if (value is byte[] bytes)
|
|
{
|
|
builder.AppendLine(Indent(indent) + "byte[" + bytes.Length + "]");
|
|
return;
|
|
}
|
|
|
|
var type = value.GetType();
|
|
if (type.IsPrimitive || value is decimal)
|
|
{
|
|
builder.AppendLine(Indent(indent) + value);
|
|
return;
|
|
}
|
|
|
|
if (value is IDictionary dictionary)
|
|
{
|
|
foreach (DictionaryEntry entry in dictionary)
|
|
{
|
|
builder.AppendLine(Indent(indent) + entry.Key + ":");
|
|
AppendValue(builder, entry.Value, indent + 2, depth + 1);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (value is IEnumerable enumerable)
|
|
{
|
|
var index = 0;
|
|
foreach (var item in enumerable)
|
|
{
|
|
builder.AppendLine(Indent(indent) + "[" + index + "]");
|
|
AppendValue(builder, item, indent + 2, depth + 1);
|
|
index++;
|
|
}
|
|
|
|
if (index == 0)
|
|
{
|
|
builder.AppendLine(Indent(indent) + "(empty)");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
|
|
if (fields.Length == 0)
|
|
{
|
|
builder.AppendLine(Indent(indent) + value);
|
|
return;
|
|
}
|
|
|
|
foreach (var field in fields)
|
|
{
|
|
builder.AppendLine(Indent(indent) + field.Name + ":");
|
|
AppendValue(builder, field.GetValue(value), indent + 2, depth + 1);
|
|
}
|
|
}
|
|
|
|
private static string Indent(int indent)
|
|
{
|
|
return new string(' ', indent);
|
|
}
|
|
|
|
private static void BeginSection(string title)
|
|
{
|
|
GUILayout.Space(10f);
|
|
GUILayout.BeginVertical(GUI.skin.box);
|
|
GUILayout.Label(title, GUI.skin.label);
|
|
GUILayout.Space(4f);
|
|
}
|
|
|
|
private static void EndSection()
|
|
{
|
|
GUILayout.EndVertical();
|
|
}
|
|
|
|
private static string DrawEditableRow(string label, string value)
|
|
{
|
|
GUILayout.BeginHorizontal();
|
|
GUILayout.Label(label, GUILayout.Width(180f));
|
|
var next = GUILayout.TextField(value ?? string.Empty);
|
|
GUILayout.EndHorizontal();
|
|
return next;
|
|
}
|
|
|
|
private static string DrawTextAreaRow(string label, string value, float height)
|
|
{
|
|
GUILayout.Label(label, GUILayout.Width(180f));
|
|
return GUILayout.TextArea(value ?? string.Empty, GUILayout.Height(height));
|
|
}
|
|
|
|
private static bool DrawToggleRow(string label, bool value)
|
|
{
|
|
GUILayout.BeginHorizontal();
|
|
GUILayout.Label(label, GUILayout.Width(180f));
|
|
var next = GUILayout.Toggle(value, value ? "Enabled" : "Disabled");
|
|
GUILayout.EndHorizontal();
|
|
return next;
|
|
}
|
|
|
|
private static void DrawReadOnlyRow(string label, string value)
|
|
{
|
|
GUILayout.BeginHorizontal();
|
|
GUILayout.Label(label, GUILayout.Width(180f));
|
|
GUILayout.Label(string.IsNullOrWhiteSpace(value) ? "-" : value, GUI.skin.box);
|
|
GUILayout.EndHorizontal();
|
|
}
|
|
}
|