136 lines
4.8 KiB
C#
136 lines
4.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using BeatSaberPlaylistsLib.Types;
|
|
using IPA;
|
|
using PlaylistManager.Utilities;
|
|
using IPALogger = IPA.Logging.Logger;
|
|
|
|
namespace Setlist
|
|
{
|
|
[Plugin(RuntimeOptions.SingleStartInit)]
|
|
public class Plugin
|
|
{
|
|
internal static Plugin Instance { get; private set; }
|
|
|
|
/// <summary>
|
|
/// BSIPA logger (shows in BSIPA console / game logs when verbose).
|
|
/// </summary>
|
|
internal static IPALogger Log { get; private set; }
|
|
|
|
/// <summary>Set after the ownership scan resolves the platform user id; used when syncing after PlaylistManager adds a song.</summary>
|
|
internal static string CachedPlatformUserId { get; set; }
|
|
|
|
[Init]
|
|
public Plugin(IPALogger logger)
|
|
{
|
|
Instance = this;
|
|
Log = logger;
|
|
}
|
|
|
|
[OnStart]
|
|
public void OnApplicationStart()
|
|
{
|
|
try
|
|
{
|
|
SetlistSyncHost.Ensure();
|
|
|
|
Events.playlistSongAdded += OnPlaylistSongAdded;
|
|
|
|
var playlists = BeatSaberPlaylistsLib.PlaylistManager.DefaultManager.GetAllPlaylists(
|
|
includeChildren: true,
|
|
out AggregateException loadErrors);
|
|
|
|
if (loadErrors != null)
|
|
{
|
|
Log.Error(loadErrors.Message);
|
|
foreach (var inner in loadErrors.InnerExceptions)
|
|
{
|
|
Log.Error(inner.ToString());
|
|
}
|
|
}
|
|
|
|
if (playlists == null || playlists.Length == 0)
|
|
{
|
|
Log.Info("No playlists loaded (or playlist library not initialized yet).");
|
|
return;
|
|
}
|
|
|
|
var entries = new List<(IPlaylist Playlist, string Title, bool HasSyncUrl, string BeatLeaderGuid, string OwnerId)>();
|
|
foreach (var playlist in playlists)
|
|
{
|
|
BeatLeaderPlaylistOwnership.TryReadBeatLeaderMetadata(
|
|
playlist,
|
|
out var hasSyncUrl,
|
|
out var blGuid,
|
|
out var ownerId);
|
|
|
|
entries.Add((playlist, playlist.Title, hasSyncUrl, blGuid, ownerId));
|
|
}
|
|
|
|
BeatLeaderPlaylistOwnership.ScheduleVerifyAndLog(entries, Log);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error(ex.ToString());
|
|
}
|
|
}
|
|
|
|
[OnExit]
|
|
public void OnApplicationQuit()
|
|
{
|
|
Events.playlistSongAdded -= OnPlaylistSongAdded;
|
|
}
|
|
|
|
private void OnPlaylistSongAdded(IPlaylistSong song, IPlaylist playlist)
|
|
{
|
|
SetlistSyncHost.Instance?.StartPostOwnedBeatLeaderPlaylist(playlist, Log);
|
|
}
|
|
|
|
/// <summary>
|
|
/// One-line log for a playlist. Ownership is inferred only from playlist JSON customData
|
|
/// (<c>owner</c> vs the game's platform user id). No network verification.
|
|
/// </summary>
|
|
internal static string FormatPlaylistLogLine(
|
|
string title,
|
|
bool hasSyncUrl,
|
|
string beatLeaderPlaylistGuid,
|
|
string ownerId,
|
|
string platformUserId)
|
|
{
|
|
var ownerToken = string.IsNullOrEmpty(ownerId) ? "owner=n/a" : $"owner={ownerId}";
|
|
|
|
string ownerMatchesPlatformPart;
|
|
if (!hasSyncUrl)
|
|
{
|
|
ownerMatchesPlatformPart = "ownerMatchesPlatform=n/a (no sync URL)";
|
|
}
|
|
else if (string.IsNullOrEmpty(beatLeaderPlaylistGuid))
|
|
{
|
|
ownerMatchesPlatformPart =
|
|
"ownerMatchesPlatform=n/a (sync URL is not an api.beatleader.com /playlist/guid/… URL)";
|
|
}
|
|
else if (string.IsNullOrEmpty(platformUserId))
|
|
{
|
|
ownerMatchesPlatformPart =
|
|
"ownerMatchesPlatform=unknown (platform user id not available yet; cannot compare to owner)";
|
|
}
|
|
else if (string.IsNullOrEmpty(ownerId))
|
|
{
|
|
ownerMatchesPlatformPart =
|
|
"ownerMatchesPlatform=false (BeatLeader playlist URL but no owner field in playlist JSON)";
|
|
}
|
|
else if (string.Equals(ownerId, platformUserId, StringComparison.Ordinal))
|
|
{
|
|
ownerMatchesPlatformPart = "ownerMatchesPlatform=true (playlist owner field equals platform user id)";
|
|
}
|
|
else
|
|
{
|
|
ownerMatchesPlatformPart =
|
|
"ownerMatchesPlatform=false (playlist owner field differs from platform user id)";
|
|
}
|
|
|
|
return $"Playlist \"{title}\": hasSyncUrl={hasSyncUrl}, {ownerToken}, {ownerMatchesPlatformPart}";
|
|
}
|
|
}
|
|
}
|