setlist/Setlist/Plugin.cs

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}";
}
}
}