Skip to content

Commit

Permalink
Fetch Campaign Progress from the leaderboards
Browse files Browse the repository at this point in the history
  • Loading branch information
PulseLane committed Feb 25, 2024
1 parent 6b24517 commit b149653
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 21 deletions.
2 changes: 1 addition & 1 deletion CustomCampaigns/Managers/CustomCampaignUIManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ public void LoadErrors(List<GameplayModifierParamsSO> modifierParams)

private void AddCustomTab()
{
_gameplaySetupManager.Setup(CustomCampaignFlowCoordinator.CustomCampaignManager.Campaign);
_gameplaySetupManager.Setup(CustomCampaignFlowCoordinator.CustomCampaignManager.Campaign, _currentCampaignNodes);
}

private void OnViewActivated()
Expand Down
4 changes: 2 additions & 2 deletions CustomCampaigns/Managers/GameplaySetupManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public GameplaySetupManager(GameplaySetupViewController gameplaySetupViewControl
_toolsHandler = toolsHandler;
}

public void Setup(Campaign.Campaign campaign)
public void Setup(Campaign.Campaign campaign, MissionNode[] campaignNodes)
{
if (_mainTab == null)
{
Expand All @@ -54,7 +54,7 @@ public void Setup(Campaign.Campaign campaign)
_mainTab.gameObject.SetActive(false);
_mainTab.IsVisible = true;

_toolsHandler.SetCampaign(campaign);
_toolsHandler.SetCampaign(campaign, campaignNodes);
}

public void CampaignExit()
Expand Down
127 changes: 122 additions & 5 deletions CustomCampaigns/UI/GameplaySetupUI/ToolsHandler.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
using BeatSaberMarkupLanguage;
using BeatSaberMarkupLanguage.Attributes;
using CustomCampaignLeaderboardLibrary;
using CustomCampaigns.Campaign;
using CustomCampaigns.Campaign.Missions;
using CustomCampaigns.Managers;
using CustomCampaigns.UI.FlowCoordinators;
using CustomCampaigns.Utils;
using HarmonyLib;
using IPA.Utilities;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;

namespace CustomCampaigns.UI.GameplaySetupUI
Expand All @@ -22,6 +31,12 @@ public class ToolsHandler : INotifyPropertyChanged

private Campaign.Campaign _campaign;

private CampaignProgressModel _campaignProgressModel;
private List<MissionNode> _campaignNodes;
private MissionMapAnimationController _missionMapAnimationController;

private HashSet<MissionNode> _checkedMissions = new HashSet<MissionNode>();

private int songsDownloaded;
private int downloadsFailed;

Expand All @@ -34,25 +49,32 @@ public class ToolsHandler : INotifyPropertyChanged
[UIValue("playlists-visible")]
public bool PlaylistsVisible { get; private set; }

[UIComponent("fetch-progress-button")]
Button fetchProgressButton;

[UIComponent("download-button")]
Button downloadButton;

[UIComponent("playlist-button")]
Button playlistButton;

public ToolsHandler(MenuTransitionsHelper menuTransitionsHelper, CreditsManager creditsManager, DownloadManager downloadManager, Config config)
public ToolsHandler(MenuTransitionsHelper menuTransitionsHelper, CreditsManager creditsManager, DownloadManager downloadManager, CampaignFlowCoordinator campaignFlowCoordinator, MissionSelectionMapViewController missionSelectionMapViewController, Config config)
{
_menuTransitionsHelper = menuTransitionsHelper;
_creditsManager = creditsManager;
_downloadManager = downloadManager;
_config = config;

_campaignProgressModel = campaignFlowCoordinator.GetField<CampaignProgressModel, CampaignFlowCoordinator>("_campaignProgressModel");
_missionMapAnimationController = missionSelectionMapViewController.GetField<MissionMapAnimationController, MissionSelectionMapViewController>("_missionMapAnimationController");

PlaylistsVisible = Plugin.isPlaylistLibInstalled;
}

internal void SetCampaign(Campaign.Campaign campaign)
internal void SetCampaign(Campaign.Campaign campaign, MissionNode[] campaignNodes)
{
_campaign = campaign;
_campaignNodes = campaignNodes.ToList();

var creditsVisible = File.Exists(campaign.campaignPath + "/" + "credits.json");
CreditsVisibleUnViewed = creditsVisible && !_config.creditsViewed.Contains(_campaign.info.name);
Expand All @@ -61,14 +83,109 @@ internal void SetCampaign(Campaign.Campaign campaign)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CreditsVisibleUnViewed)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CreditsVisibleViewed)));

downloadButton.interactable = true;
downloadButton.SetButtonText("Download Missing Songs");
if (_campaign.missions.Count > 0)
{
fetchProgressButton.interactable = true;
fetchProgressButton.SetButtonText("Fetch Campaign Progress");

playlistButton.interactable = true;
downloadButton.interactable = true;
downloadButton.SetButtonText("Download Missing Songs");
}

playlistButton.interactable = true;
playlistButton.SetButtonText(GetDoesPlaylistExist(_campaign) ? "Update Playlist" : "Create Playlist");
}

#region Progress Button
private Mission GetMatchingMissionFromMissionNode(MissionNode node)
{
foreach (var mission in _campaign.missions)
{
MissionDataSO missionDataSO = mission.TryGetMissionData();
if (missionDataSO != null && missionDataSO == node.missionData)
{
return mission;
}
}

return null;
}

private async Task<bool> GetIsMissionNodeOnLeaderboard(MissionNode node)
{
Mission mission = GetMatchingMissionFromMissionNode(node);
if (mission == null)
{
Plugin.logger.Debug($"Could not find matching mission - {node.name}");
return false;
}

LeaderboardResponse response;
if (_campaign.info.customMissionLeaderboard == "")
{
var hash = CustomCampaignLeaderboardLibraryUtils.GetHash(mission);
response = await CustomCampaignLeaderboard.LoadLeaderboards(UserInfoManager.UserInfo.platformUserId, hash);
}

else
{
string url = CustomCampaignLeaderboardLibraryUtils.GetURL(mission, _campaign.info.customMissionLeaderboard);
response = await CustomCampaignLeaderboard.LoadLeaderboards(url);
}

return response != null && response.you.position > 0;
}

[UIAction("fetch-progress-click")]
public async void FetchCampaignProgress()
{
fetchProgressButton.interactable = false;
fetchProgressButton.SetButtonText("Fetching Progress...");

Queue<MissionNode> missions = new Queue<MissionNode>();
missions.Enqueue(_campaignNodes[0]);
int i = 0;
while (missions.Count > 0)
{
MissionNode node = missions.Dequeue();
if (_checkedMissions.Contains(node))
{
continue;
}

i++;
fetchProgressButton.SetButtonText($"Fetching {i} / {_campaignNodes.Count}...");
_checkedMissions.Add(node);

bool isCleared = false;

if (_campaignProgressModel.IsMissionCleared(node.missionId))
{
isCleared = true;
}
else if (await GetIsMissionNodeOnLeaderboard(node))
{
_campaignProgressModel.SetMissionCleared(node.missionId);
isCleared = true;
}

if (isCleared)
{
foreach (var child in node.childNodes)
{
if (!_checkedMissions.Contains(child))
{
missions.Enqueue(child);
}
}
}
}

_missionMapAnimationController.UpdateMissionMapAfterMissionWasCleared(false, null);
fetchProgressButton.SetButtonText("Campaign Progress Fetched");
}
#endregion

#region Download Buton
[UIAction("download-click")]
public void DownloadMissingSongs()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,13 @@ private IEnumerator UpdateLeaderboardsCoroutine()
Task<LeaderboardResponse> task;
if (customURL == "")
{
Plugin.logger.Debug("normal leaderboard");
var hash = CustomCampaignLeaderboardLibraryUtils.GetHash(mission);
task = CustomCampaignLeaderboard.LoadLeaderboards(UserInfoManager.UserInfo.platformUserId, hash);
}

else
{
Plugin.logger.Debug("custom leaderboard");
string url = GetURL(mission, customURL);
string url = CustomCampaignLeaderboardLibraryUtils.GetURL(mission, customURL);
task = CustomCampaignLeaderboard.LoadLeaderboards(url);
}

Expand All @@ -99,16 +97,6 @@ private IEnumerator UpdateLeaderboardsCoroutine()
}
}

private string GetURL(Mission mission, string customURL)
{
string url = customURL.Replace("{missionHash}", CustomCampaignLeaderboardLibraryUtils.GetHash(mission))
.Replace("{mapHash}", mission.hash)
.Replace("{characteristic}", mission.characteristic)
.Replace("{difficulty}", ((int) mission.difficulty).ToString())
.Replace("{userID}", UserInfoManager.UserInfo.platformUserId);
return url;
}

private async void UpdateScores(LeaderboardResponse response)
{
List<ScoreData> scores = new List<ScoreData>();
Expand Down
1 change: 1 addition & 0 deletions CustomCampaigns/UI/Views/tools.bsml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<vertical spacing="5" vertical-fit="PreferredSize" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='https://monkeymanboy.github.io/BSML-Docs/ https://raw.githubusercontent.com/monkeymanboy/BSML-Docs/gh-pages/BSMLSchema.xsd'>
<button id='fetch-progress-button' text='Fetch Campaign Progress' hover-hint='Automatically unlocks any locked levels where you have a score on the custom campaigns leaderboard.' on-click='fetch-progress-click' pref-height='7.5'/>
<button id='download-button' text='Download Missing Songs' on-click='download-click' pref-height='7.5'/>
<button id='playlist-button' text='Export to Playlist' on-click='playlist-click' active='~playlists-visible' pref-height='7.5'/>
<action-button text="View Campaign Credits" on-click='credits-click' id='credits-button' active='~credits-visible-unviewed' pref-height='7.5'/>
Expand Down
10 changes: 10 additions & 0 deletions CustomCampaigns/Utils/CustomCampaignLeaderboardLibraryUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ public static string GetHash(string s)
return sb.ToString();
}

public static string GetURL(Mission mission, string customURL)
{
string url = customURL.Replace("{missionHash}", CustomCampaignLeaderboardLibraryUtils.GetHash(mission))
.Replace("{mapHash}", mission.hash)
.Replace("{characteristic}", mission.characteristic)
.Replace("{difficulty}", ((int) mission.difficulty).ToString())
.Replace("{userID}", UserInfoManager.UserInfo.platformUserId);
return url;
}

public static string GetSpecialName(string id, string name)
{
if (IsRainbowName(id))
Expand Down

0 comments on commit b149653

Please sign in to comment.