MVP completed: Hook into Playlistmanager to post updates to beatleader maps owned by the user
This commit is contained in:
@@ -62,6 +62,37 @@ namespace Setlist
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>Reads sync URL, BeatLeader guid, and owner from playlist customData (same rules as startup scan).</summary>
|
||||
internal static void TryReadBeatLeaderMetadata(
|
||||
IPlaylist playlist,
|
||||
out bool hasSyncUrl,
|
||||
out string beatLeaderGuid,
|
||||
out string ownerId)
|
||||
{
|
||||
hasSyncUrl = false;
|
||||
beatLeaderGuid = null;
|
||||
ownerId = null;
|
||||
|
||||
if (!playlist.TryGetCustomData("syncURL", out var syncObj) || !(syncObj is string syncUrl)
|
||||
|| string.IsNullOrWhiteSpace(syncUrl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hasSyncUrl = true;
|
||||
|
||||
if (playlist.TryGetCustomData("owner", out var ownerObj) && ownerObj is string o
|
||||
&& !string.IsNullOrWhiteSpace(o))
|
||||
{
|
||||
ownerId = o.Trim();
|
||||
}
|
||||
|
||||
if (TryExtractBeatLeaderPlaylistGuid(syncUrl, out var g))
|
||||
{
|
||||
beatLeaderGuid = g;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Spawns a hidden coroutine runner that resolves the platform user id, then logs per-playlist
|
||||
/// ownership from playlist JSON. Must be called from the Unity main thread (BSIPA <c>OnApplicationStart</c> is fine).
|
||||
@@ -77,6 +108,108 @@ namespace Setlist
|
||||
runner.Initialize(entries, log);
|
||||
}
|
||||
|
||||
internal static IEnumerator FetchPlatformUserIdCoroutine(Action<string> onDone)
|
||||
{
|
||||
var waited = 0f;
|
||||
var lastGetUserInfoAttempt = -PlatformUserGetUserInfoRetrySeconds;
|
||||
while (waited < PlatformUserWaitTimeoutSeconds)
|
||||
{
|
||||
foreach (var plm in EnumerateLeaderboardModels())
|
||||
{
|
||||
var pid = plm.playerId;
|
||||
if (!string.IsNullOrEmpty(pid))
|
||||
{
|
||||
onDone(pid.Trim());
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
|
||||
if (waited - lastGetUserInfoAttempt >= PlatformUserGetUserInfoRetrySeconds)
|
||||
{
|
||||
lastGetUserInfoAttempt = waited;
|
||||
var model = ResolvePlatformUserModel();
|
||||
if (model != null)
|
||||
{
|
||||
Task<UserInfo> task;
|
||||
try
|
||||
{
|
||||
task = model.GetUserInfo(CancellationToken.None);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
task = null;
|
||||
}
|
||||
|
||||
if (task != null)
|
||||
{
|
||||
while (!task.IsCompleted)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
if (!task.IsFaulted)
|
||||
{
|
||||
var uid = task.Result?.platformUserId;
|
||||
if (!string.IsNullOrEmpty(uid))
|
||||
{
|
||||
onDone(uid.Trim());
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
waited += PlatformUserPollStepSeconds;
|
||||
yield return new WaitForSeconds(PlatformUserPollStepSeconds);
|
||||
}
|
||||
|
||||
onDone(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Resources.FindObjectsOfTypeAll{T}"/> can miss very early; <see cref="Object.FindObjectOfType{T}()"/> sometimes finds the scene instance sooner.
|
||||
/// </summary>
|
||||
private static IEnumerable<PlatformLeaderboardsModel> EnumerateLeaderboardModels()
|
||||
{
|
||||
var seen = new HashSet<PlatformLeaderboardsModel>();
|
||||
foreach (var plm in Resources.FindObjectsOfTypeAll<PlatformLeaderboardsModel>())
|
||||
{
|
||||
if (plm != null && seen.Add(plm))
|
||||
{
|
||||
yield return plm;
|
||||
}
|
||||
}
|
||||
|
||||
var active = UnityEngine.Object.FindObjectOfType<PlatformLeaderboardsModel>();
|
||||
if (active != null && seen.Add(active))
|
||||
{
|
||||
yield return active;
|
||||
}
|
||||
}
|
||||
|
||||
private static IPlatformUserModel ResolvePlatformUserModel()
|
||||
{
|
||||
var field = typeof(PlatformLeaderboardsModel).GetField(
|
||||
"_platformUserModel",
|
||||
BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
if (field == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
IPlatformUserModel last = null;
|
||||
foreach (var plm in EnumerateLeaderboardModels())
|
||||
{
|
||||
if (field.GetValue(plm) is IPlatformUserModel m)
|
||||
{
|
||||
last = m;
|
||||
}
|
||||
}
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Component that drives the logging coroutine; self-destroys when finished.
|
||||
/// </summary>
|
||||
@@ -97,7 +230,8 @@ namespace Setlist
|
||||
private IEnumerator Run()
|
||||
{
|
||||
string platformUserId = null;
|
||||
yield return StartCoroutine(FetchPlatformUserId(id => { platformUserId = id; }));
|
||||
yield return StartCoroutine(FetchPlatformUserIdCoroutine(id => { platformUserId = id; }));
|
||||
Plugin.CachedPlatformUserId = platformUserId;
|
||||
_log.Info(string.IsNullOrEmpty(platformUserId)
|
||||
? "platformUserId=(unknown)"
|
||||
: $"platformUserId={platformUserId}");
|
||||
@@ -112,131 +246,8 @@ namespace Setlist
|
||||
platformUserId));
|
||||
}
|
||||
|
||||
foreach (var e in _entries)
|
||||
{
|
||||
if (!string.Equals(e.Title, BeatLeaderPlaylistUpdateTest.TargetPlaylistTitle, StringComparison.Ordinal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return BeatLeaderPlaylistUpdateTest.RunIfTargetOwned(
|
||||
e.Playlist,
|
||||
e.HasSyncUrl,
|
||||
e.BeatLeaderGuid,
|
||||
e.OwnerId,
|
||||
platformUserId,
|
||||
_log);
|
||||
break;
|
||||
}
|
||||
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BSIPA runs us very early; <see cref="PlatformLeaderboardsModel"/> may not exist yet and its
|
||||
/// async init may not have set <see cref="PlatformLeaderboardsModel.playerId"/>. Poll until ready.
|
||||
/// </summary>
|
||||
private static IEnumerator FetchPlatformUserId(Action<string> onDone)
|
||||
{
|
||||
var waited = 0f;
|
||||
var lastGetUserInfoAttempt = -PlatformUserGetUserInfoRetrySeconds;
|
||||
while (waited < PlatformUserWaitTimeoutSeconds)
|
||||
{
|
||||
foreach (var plm in EnumerateLeaderboardModels())
|
||||
{
|
||||
var pid = plm.playerId;
|
||||
if (!string.IsNullOrEmpty(pid))
|
||||
{
|
||||
onDone(pid.Trim());
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
|
||||
if (waited - lastGetUserInfoAttempt >= PlatformUserGetUserInfoRetrySeconds)
|
||||
{
|
||||
lastGetUserInfoAttempt = waited;
|
||||
var model = ResolvePlatformUserModel();
|
||||
if (model != null)
|
||||
{
|
||||
Task<UserInfo> task;
|
||||
try
|
||||
{
|
||||
task = model.GetUserInfo(CancellationToken.None);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
task = null;
|
||||
}
|
||||
|
||||
if (task != null)
|
||||
{
|
||||
while (!task.IsCompleted)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
if (!task.IsFaulted)
|
||||
{
|
||||
var uid = task.Result?.platformUserId;
|
||||
if (!string.IsNullOrEmpty(uid))
|
||||
{
|
||||
onDone(uid.Trim());
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
waited += PlatformUserPollStepSeconds;
|
||||
yield return new WaitForSeconds(PlatformUserPollStepSeconds);
|
||||
}
|
||||
|
||||
onDone(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Resources.FindObjectsOfTypeAll{T}"/> can miss very early; <see cref="Object.FindObjectOfType{T}()"/> sometimes finds the scene instance sooner.
|
||||
/// </summary>
|
||||
private static IEnumerable<PlatformLeaderboardsModel> EnumerateLeaderboardModels()
|
||||
{
|
||||
var seen = new HashSet<PlatformLeaderboardsModel>();
|
||||
foreach (var plm in Resources.FindObjectsOfTypeAll<PlatformLeaderboardsModel>())
|
||||
{
|
||||
if (plm != null && seen.Add(plm))
|
||||
{
|
||||
yield return plm;
|
||||
}
|
||||
}
|
||||
|
||||
var active = UnityEngine.Object.FindObjectOfType<PlatformLeaderboardsModel>();
|
||||
if (active != null && seen.Add(active))
|
||||
{
|
||||
yield return active;
|
||||
}
|
||||
}
|
||||
|
||||
private static IPlatformUserModel ResolvePlatformUserModel()
|
||||
{
|
||||
var field = typeof(PlatformLeaderboardsModel).GetField(
|
||||
"_platformUserModel",
|
||||
BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
if (field == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
IPlatformUserModel last = null;
|
||||
foreach (var plm in EnumerateLeaderboardModels())
|
||||
{
|
||||
if (field.GetValue(plm) is IPlatformUserModel m)
|
||||
{
|
||||
last = m;
|
||||
}
|
||||
}
|
||||
|
||||
return last;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user