Code review
This commit is contained in:
@@ -5,38 +5,26 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
#if false
|
||||
using BeatLeader.Utils;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
#endif
|
||||
using IPALogger = IPA.Logging.Logger;
|
||||
|
||||
namespace Setlist
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses BeatLeader sync URLs and checks ownership via GET /user/playlists.
|
||||
/// Reuses BeatLeader's sign-in by piggy-backing on Unity's process-wide
|
||||
/// <see cref="UnityWebRequest"/> cookie cache (the shipped 0.9.x BeatLeader
|
||||
/// signs in with <see cref="UnityWebRequest"/>; cookies are global per host).
|
||||
/// We block on BeatLeader's <c>Authentication._signedIn</c> via reflection so
|
||||
/// we don't fire the request before the cookie is in the cache.
|
||||
/// Parses BeatLeader-style sync URLs for logging. Ownership is determined in
|
||||
/// <see cref="Plugin.FormatPlaylistLogLine"/> from playlist JSON only (no network).
|
||||
/// </summary>
|
||||
internal static class BeatLeaderPlaylistOwnership
|
||||
{
|
||||
private const string AuthenticationTypeName = "BeatLeader.API.Authentication";
|
||||
private const string SignedInFieldName = "_signedIn";
|
||||
private const float LoginWaitTimeoutSeconds = 90f;
|
||||
private const float PlatformUserPollStepSeconds = 0.5f;
|
||||
/// <summary>How long to wait for <see cref="PlatformLeaderboardsModel"/> to appear and populate <c>playerId</c> (plugin runs before menu init).</summary>
|
||||
private const float PlatformUserWaitTimeoutSeconds = 30f;
|
||||
private const float PlatformUserGetUserInfoRetrySeconds = 3f;
|
||||
private const int RequestTimeoutSeconds = 30;
|
||||
|
||||
private sealed class UserPlaylistSummary
|
||||
{
|
||||
[JsonProperty("guid")]
|
||||
public string Guid { get; set; }
|
||||
}
|
||||
|
||||
internal static bool TryExtractBeatLeaderPlaylistGuid(string syncUrl, out string guid)
|
||||
{
|
||||
@@ -79,9 +67,8 @@ namespace Setlist
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Spawns a hidden coroutine runner that waits for BeatLeader sign-in,
|
||||
/// fetches <c>/user/playlists</c>, then logs the per-playlist ownership.
|
||||
/// Must be called from the Unity main thread (BSIPA's <c>OnApplicationStart</c> is fine).
|
||||
/// 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).
|
||||
/// </summary>
|
||||
internal static void ScheduleVerifyAndLog(
|
||||
List<(string Title, bool HasSyncUrl, string BeatLeaderGuid, string OwnerId)> entries,
|
||||
@@ -95,7 +82,7 @@ namespace Setlist
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Component that drives the verification coroutine; self-destroys when finished.
|
||||
/// Component that drives the logging coroutine; self-destroys when finished.
|
||||
/// </summary>
|
||||
private sealed class OwnershipRunner : MonoBehaviour
|
||||
{
|
||||
@@ -119,54 +106,6 @@ namespace Setlist
|
||||
? "platformUserId=(unknown)"
|
||||
: $"platformUserId={platformUserId}");
|
||||
|
||||
HashSet<string> owned = null;
|
||||
string failure = null;
|
||||
|
||||
if (_entries.Any(e => e.BeatLeaderGuid != null))
|
||||
{
|
||||
FieldInfo signedInField;
|
||||
try
|
||||
{
|
||||
signedInField = ResolveSignedInField(_log);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
signedInField = null;
|
||||
failure = "reflecting BeatLeader Authentication failed: " + ex.Message;
|
||||
}
|
||||
|
||||
if (signedInField != null)
|
||||
{
|
||||
var waitedSeconds = 0f;
|
||||
while (!IsSignedIn(signedInField))
|
||||
{
|
||||
if (waitedSeconds >= LoginWaitTimeoutSeconds)
|
||||
{
|
||||
failure = $"BeatLeader login did not complete within {LoginWaitTimeoutSeconds:F0}s; "
|
||||
+ "is the BeatLeader mod actually signing in (check BeatLeader log lines)?";
|
||||
break;
|
||||
}
|
||||
yield return new WaitForSeconds(1f);
|
||||
waitedSeconds += 1f;
|
||||
}
|
||||
|
||||
if (failure == null)
|
||||
{
|
||||
var fetchEnumerator = FetchOwnedGuids(result =>
|
||||
{
|
||||
owned = result.OwnedGuids;
|
||||
failure = result.Failure;
|
||||
});
|
||||
yield return StartCoroutine(fetchEnumerator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (owned == null && failure != null)
|
||||
{
|
||||
_log.Info("BeatLeader /user/playlists: " + failure);
|
||||
}
|
||||
|
||||
foreach (var e in _entries)
|
||||
{
|
||||
_log.Info(Plugin.FormatPlaylistLogLine(
|
||||
@@ -174,8 +113,7 @@ namespace Setlist
|
||||
e.HasSyncUrl,
|
||||
e.BeatLeaderGuid,
|
||||
e.OwnerId,
|
||||
platformUserId,
|
||||
owned));
|
||||
platformUserId));
|
||||
}
|
||||
|
||||
Destroy(gameObject);
|
||||
@@ -287,6 +225,21 @@ namespace Setlist
|
||||
return last;
|
||||
}
|
||||
|
||||
// SETLIST: Remove the entire #if false region below once we no longer need the old
|
||||
// BeatLeader GET /user/playlists + login-wait verification path for reference.
|
||||
|
||||
#if false
|
||||
private const string AuthenticationTypeName = "BeatLeader.API.Authentication";
|
||||
private const string SignedInFieldName = "_signedIn";
|
||||
private const float LoginWaitTimeoutSeconds = 90f;
|
||||
private const int RequestTimeoutSeconds = 30;
|
||||
|
||||
private sealed class UserPlaylistSummary
|
||||
{
|
||||
[JsonProperty("guid")]
|
||||
public string Guid { get; set; }
|
||||
}
|
||||
|
||||
private struct FetchResult
|
||||
{
|
||||
public HashSet<string> OwnedGuids;
|
||||
@@ -384,6 +337,7 @@ namespace Setlist
|
||||
var asm = typeof(BeatLeaderPlaylistOwnership).Assembly;
|
||||
return asm.GetName().Version?.ToString() ?? "0.0.0";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user