using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BaboonAPI.Hooks.Tracks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.FSharp.Collections;
using Microsoft.FSharp.Core;
using Newtonsoft.Json;
using SongOrganizer.Data;
using SongOrganizer.Utils;
using TMPro;
using TrombLoader.CustomTracks;
using TrombLoader.Helpers;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Localization.Components;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("SongOrganizer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Trombone Champ: Searching, Filtering, and Sorting")]
[assembly: AssemblyFileVersion("1.3.10.0")]
[assembly: AssemblyInformationalVersion("1.3.10")]
[assembly: AssemblyProduct("SongOrganizer")]
[assembly: AssemblyTitle("SongOrganizer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.10.0")]
[module: UnverifiableCode]
namespace SongOrganizer
{
[BepInPlugin("SongOrganizer", "SongOrganizer", "1.3.10")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
public static Plugin Instance;
public static ManualLogSource Log;
public static Options Options;
public static TrackLoaded TrackLoaded;
public static Toggle Toggle;
public static Button Button;
public static TMP_InputField InputFieldPrefab;
public static TMP_InputField SearchInput;
public static Image Star;
public static Dictionary<string, Track> TrackDict = new Dictionary<string, Track>();
public const int TRACK_SCORE_LENGTH = 5;
private const string FILTER_SECTION = "Filter";
private const string SORT_SECTION = "Sort";
private const string INDEX_SECTION = "Index";
private const string SEARCH_SECTION = "Search";
private void Awake()
{
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
Options = new Options
{
ShowDefault = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowDefault", true, (ConfigDescription)null),
ShowCustom = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowCustom", true, (ConfigDescription)null),
ShowUnplayed = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowUnplayed", true, (ConfigDescription)null),
ShowPlayed = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowPlayed", true, (ConfigDescription)null),
ShowNotSRank = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowNotSRank", true, (ConfigDescription)null),
ShowSRank = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowSRank", true, (ConfigDescription)null),
ShowUnrated = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowUnrated", true, (ConfigDescription)null),
ShowRated = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowRated", true, (ConfigDescription)null),
SortMode = ((BaseUnityPlugin)this).Config.Bind<string>("Sort", "SortMode", "default", (ConfigDescription)null),
LastIndex = ((BaseUnityPlugin)this).Config.Bind<int>("Index", "LastIndex", 0, (ConfigDescription)null),
SearchValue = ((BaseUnityPlugin)this).Config.Bind<string>("Search", "SearchValue", "", (ConfigDescription)null)
};
((MonoBehaviour)this).StartCoroutine((IEnumerator)TootTally.GetRatedTracks());
SceneManager.sceneUnloaded += UnloadModule;
new Harmony("SongOrganizer").PatchAll();
}
public static void UnloadModule(Scene scene)
{
UnloadModule();
}
public static void UnloadModule()
{
if (TrackLoaded != null)
{
TracksLoadedEvent.EVENT.Unregister((Listener)(object)TrackLoaded);
TrackLoaded = null;
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "SongOrganizer";
public const string PLUGIN_NAME = "SongOrganizer";
public const string PLUGIN_VERSION = "1.3.10";
}
}
namespace SongOrganizer.Utils
{
public class TrackLoaded : Listener
{
private LevelSelectController __instance;
private IEnumerable<TootTally.SearchTrackResult> ratedTracks;
public TrackLoaded(LevelSelectController instance, IEnumerable<TootTally.SearchTrackResult> ratedTracks)
{
__instance = instance;
this.ratedTracks = ratedTracks;
}
public void OnTracksLoaded(FSharpList<TromboneTrack> tracks)
{
AddTracks(ratedTracks, __instance);
FilterTracks(__instance);
}
public static void AddTracks(IEnumerable<TootTally.SearchTrackResult> ratedTracks, LevelSelectController __instance)
{
DateTime now = DateTime.Now;
Plugin.Log.LogDebug((object)$"Loading tracks: {__instance.alltrackslist.Count} total");
Dictionary<string, TootTally.SearchTrackResult> dictionary = ratedTracks.ToDictionary((TootTally.SearchTrackResult i) => i.file_hash);
HashSet<string> hashSet = new HashSet<string>(ratedTracks.Select((TootTally.SearchTrackResult i) => i.track_ref));
HashSet<string> foundRatedTrackNoteHashes = new HashSet<string>();
Plugin.TrackDict.Clear();
foreach (SingleTrackData item in __instance.alltrackslist)
{
bool flag = false;
if (hashSet.Contains(item.trackref))
{
if (Globals.IsCustomTrack(item.trackref))
{
TromboneTrack obj = TrackLookup.lookup(item.trackref);
CustomTrack val = (CustomTrack)(object)((obj is CustomTrack) ? obj : null);
string fileLocation = Path.Combine(val.folderPath, Globals.defaultChartName);
string key = CalcFileHash(fileLocation);
flag = dictionary.ContainsKey(key);
if (flag)
{
foundRatedTrackNoteHashes.Add(dictionary[key].note_hash);
}
}
else
{
flag = true;
}
}
Track track2 = new Track(item)
{
custom = Globals.IsCustomTrack(item.trackref),
rated = flag
};
FSharpOption<SavedTrackScore> val2 = TrackLookup.lookupScore(item.trackref);
track2.letterScore = ((val2 != null) ? val2.Value.highestRank : "-");
track2.scores = ((val2 != null) ? ((IEnumerable<int>)val2.Value.highScores).ToArray() : new int[5]);
Plugin.TrackDict.TryAdd(item.trackref, track2);
}
List<TootTally.SearchTrackResult> list = ratedTracks.Where((TootTally.SearchTrackResult track) => !foundRatedTrackNoteHashes.Contains(track.note_hash) && !track.is_official).ToList();
Plugin.Log.LogInfo((object)$"Rated tracks: {ratedTracks.Count()} total. {list.Count} missing");
foreach (TootTally.SearchTrackResult item2 in list.OrderBy((TootTally.SearchTrackResult i) => i.short_name))
{
Plugin.Log.LogDebug((object)(item2.short_name + " - " + ((item2.mirror == null) ? item2.download : item2.mirror)));
}
Plugin.Log.LogDebug((object)$"Elapsed {DateTime.Now - now}");
}
public static string CalcFileHash(string fileLocation)
{
byte[] bytes = Encoding.UTF8.GetBytes(File.ReadAllText(fileLocation));
using SHA256 sHA = SHA256.Create();
StringBuilder stringBuilder = new StringBuilder();
byte[] array = sHA.ComputeHash(bytes);
byte[] array2 = array;
foreach (byte b in array2)
{
stringBuilder.Append(b.ToString("x2"));
}
return stringBuilder.ToString();
}
public static void FilterTracks(LevelSelectController __instance)
{
List<string[]> list = new List<string[]>();
List<SingleTrackData> list2 = new List<SingleTrackData>();
int num = 0;
foreach (Track value in Plugin.TrackDict.Values)
{
if (ShowTrack(value))
{
((SingleTrackData)value).trackindex = num;
list.Add(new string[10]
{
((SingleTrackData)value).trackname_long,
((SingleTrackData)value).trackname_short,
((SingleTrackData)value).trackref,
((SingleTrackData)value).year,
((SingleTrackData)value).artist,
((SingleTrackData)value).genre,
((SingleTrackData)value).desc,
((SingleTrackData)value).difficulty.ToString(),
((SingleTrackData)value).length.ToString(),
((SingleTrackData)value).tempo.ToString()
});
list2.Add((SingleTrackData)(object)value);
num++;
}
}
if (list.Count > 0)
{
GlobalVariables.data_tracktitles = list.ToArray();
__instance.alltrackslist.Clear();
__instance.alltrackslist.AddRange(list2);
}
if (GlobalVariables.levelselect_index >= GlobalVariables.data_tracktitles.Length)
{
GlobalVariables.levelselect_index = 0;
}
Plugin.Log.LogDebug((object)$"Filter result: {__instance.alltrackslist.Count} found of {Plugin.TrackDict.Count}");
__instance.sortTracks(Plugin.Options.SortMode.Value.ToLower(), false);
}
private static bool ShowTrack(Track track)
{
return ShowTrack(Plugin.Options.ShowCustom.Value, Plugin.Options.ShowDefault.Value, track.custom) && ShowTrack(Plugin.Options.ShowPlayed.Value, Plugin.Options.ShowUnplayed.Value, track.letterScore != "-") && ShowTrack(Plugin.Options.ShowSRank.Value, Plugin.Options.ShowNotSRank.Value, track.letterScore == "S") && ShowTrack(Plugin.Options.ShowRated.Value, Plugin.Options.ShowUnrated.Value, track.rated) && ShowTrack(Plugin.Options.SearchValue.Value, track);
}
private static bool ShowTrack(bool optionToggle, bool oppositeOptionToggle, bool option)
{
return optionToggle == oppositeOptionToggle || optionToggle == option;
}
private static bool ShowTrack(string searchVal, Track track)
{
if (Utility.IsNullOrWhiteSpace(searchVal))
{
return true;
}
string value = searchVal.ToLower().Trim();
return ((SingleTrackData)track).trackname_long.ToLower().Contains(value) || ((SingleTrackData)track).trackname_short.ToLower().Contains(value) || ((SingleTrackData)track).artist.ToLower().Contains(value) || ((SingleTrackData)track).genre.ToLower().Contains(value) || ((SingleTrackData)track).desc.ToLower().Contains(value);
}
}
}
namespace SongOrganizer.Patches
{
[HarmonyPatch(typeof(HomeController), "Start")]
public class HomeControllerStartPatch : MonoBehaviour
{
private static void Postfix(HomeController __instance)
{
Plugin.Toggle = Object.Instantiate<Toggle>(__instance.set_tog_vsync);
Object.DontDestroyOnLoad((Object)(object)Plugin.Toggle);
Plugin.Button = Object.Instantiate<Button>(__instance.graphicspanel.GetComponentInChildren<Button>());
((UnityEventBase)Plugin.Button.onClick).RemoveAllListeners();
Object.DontDestroyOnLoad((Object)(object)Plugin.Button);
SetInputFieldPrefab();
}
private static void SetInputFieldPrefab()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
float num = 250f;
GameObject val = new GameObject("InputFieldHolderSongOrganizer");
RectTransform val2 = val.AddComponent<RectTransform>();
val2.anchoredPosition = Vector2.zero;
val2.sizeDelta = new Vector2(num, 50f);
GameObject val3 = Object.Instantiate<GameObject>(val, val.transform);
GameObject val4 = Object.Instantiate<GameObject>(val3, val.transform);
((Object)val3).name = "Image";
((Object)val4).name = "Text";
Plugin.InputFieldPrefab = val.AddComponent<TMP_InputField>();
Vector2 anchorMax = (val2.anchorMin = Vector2.zero);
val2.anchorMax = anchorMax;
((Selectable)Plugin.InputFieldPrefab).image = val3.AddComponent<Image>();
RectTransform component = val3.GetComponent<RectTransform>();
Vector2 val5 = (component.pivot = Vector2.zero);
anchorMax = (component.anchorMax = val5);
component.anchorMin = anchorMax;
component.anchoredPosition = new Vector2(0f, 2f);
component.sizeDelta = new Vector2(num, 2f);
RectTransform component2 = val4.GetComponent<RectTransform>();
Vector2 val7 = (component2.anchorMin = Vector2.zero);
val5 = (component2.anchoredPosition = val7);
anchorMax = (component2.anchorMax = val5);
component2.pivot = anchorMax;
component2.sizeDelta = new Vector2(num, 50f);
Plugin.InputFieldPrefab.textComponent = CreateSingleText(val4.transform, "TextLabel", "", Color.white);
Plugin.InputFieldPrefab.textComponent.rectTransform.pivot = new Vector2(0f, 0.7f);
Plugin.InputFieldPrefab.textComponent.alignment = (TextAlignmentOptions)513;
Plugin.InputFieldPrefab.textComponent.margin = new Vector4(2f, 0f, 0f, 0f);
Plugin.InputFieldPrefab.textComponent.enableWordWrapping = true;
Plugin.InputFieldPrefab.textViewport = Plugin.InputFieldPrefab.textComponent.rectTransform;
Object.DontDestroyOnLoad((Object)(object)Plugin.InputFieldPrefab);
}
public static TMP_Text CreateSingleText(Transform canvasTransform, string name, string text, Color color)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
return CreateSingleText(canvasTransform, name, text, new Vector2(0f, 1f), ((Component)canvasTransform).GetComponent<RectTransform>().sizeDelta, color);
}
public static TMP_Text CreateSingleText(Transform canvasTransform, string name, string text, Vector2 pivot, Vector2 size, Color color)
{
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
GameObject gameObject = GameObject.Find("MainCanvas").gameObject;
GameObject gameObject2 = ((Component)gameObject.transform.Find("AdvancedInfoPanel/primary-content/intro/copy")).gameObject;
GameObject val = Object.Instantiate<GameObject>(gameObject2);
((Object)val).name = "ComfortaaTextPrefab";
val.SetActive(true);
Object.DestroyImmediate((Object)(object)val.GetComponent<Text>());
TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
((TMP_Text)val2).fontSize = 13f;
((TMP_Text)val2).text = "DefaultText";
((TMP_Text)val2).font = TMP_FontAsset.CreateFontAsset(gameObject2.GetComponent<Text>().font);
((TMP_Text)val2).fontMaterial.SetFloat(ShaderUtilities.ID_FaceDilate, 0.25f);
((TMP_Text)val2).fontMaterial.EnableKeyword(ShaderUtilities.Keyword_Outline);
((TMP_Text)val2).fontMaterial.SetFloat(ShaderUtilities.ID_OutlineWidth, 0.25f);
((TMP_Text)val2).fontMaterial.SetColor(ShaderUtilities.ID_OutlineColor, Color.black);
((TMP_Text)val2).alignment = (TextAlignmentOptions)514;
((Component)val2).GetComponent<RectTransform>().sizeDelta = val.GetComponent<RectTransform>().sizeDelta;
((Component)val2).GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
((TMP_Text)val2).richText = true;
((TMP_Text)val2).enableWordWrapping = false;
Object.DontDestroyOnLoad((Object)(object)val2);
TMP_Text val3 = (TMP_Text)(object)Object.Instantiate<TextMeshProUGUI>(val2, canvasTransform);
((Object)val3).name = name;
val3.text = text;
((Graphic)val3).color = color;
((Component)val3).gameObject.GetComponent<RectTransform>().pivot = pivot;
((Component)val3).gameObject.GetComponent<RectTransform>().sizeDelta = size;
val3.enableWordWrapping = true;
((Component)val3).gameObject.SetActive(true);
return val3;
}
}
[HarmonyPatch(typeof(LevelSelectController), "sortTracks")]
public class LevelSelectControllerSortTracksPatch : MonoBehaviour
{
private static bool Prefix(LevelSelectController __instance, string sortcriteria, bool anim)
{
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
Plugin.Options.SortMode.Value = sortcriteria;
GlobalVariables.sortmode = sortcriteria;
__instance.sortlabel.text = "Sort: " + sortcriteria;
if (anim)
{
__instance.clipPlayer.cancelCrossfades();
__instance.doSfx(__instance.sfx_click);
__instance.closeSortDropdown();
__instance.btnspanel.transform.localScale = new Vector3(0.001f, 1f, 1f);
LeanTween.scaleX(__instance.btnspanel, 1f, 0.2f).setEaseOutQuart();
}
switch (sortcriteria)
{
case "default":
__instance.alltrackslist.Sort((SingleTrackData t1, SingleTrackData t2) => t1.trackindex.CompareTo(t2.trackindex));
break;
case "difficulty":
__instance.alltrackslist.Sort((SingleTrackData t1, SingleTrackData t2) => t1.difficulty.CompareTo(t2.difficulty));
break;
case "alpha":
__instance.alltrackslist.Sort((SingleTrackData t1, SingleTrackData t2) => (t1.trackname_short == null) ? (-1) : t1.trackname_short.Trim().CompareTo(t2.trackname_short.Trim()));
break;
case "long name":
__instance.alltrackslist.Sort((SingleTrackData t1, SingleTrackData t2) => (t1.trackname_long == null) ? (-1) : t1.trackname_long.Trim().CompareTo(t2.trackname_long.Trim()));
break;
case "length":
__instance.alltrackslist.Sort((SingleTrackData t1, SingleTrackData t2) => t1.length.CompareTo(t2.length));
break;
case "artist":
__instance.alltrackslist.Sort((SingleTrackData t1, SingleTrackData t2) => (t1.artist == null) ? (-1) : t1.artist.Trim().CompareTo(t2.artist.Trim()));
break;
}
__instance.songindex = ((!anim) ? GlobalVariables.levelselect_index : 0);
__instance.populateSongNames(true);
return false;
}
}
[HarmonyPatch(typeof(LevelSelectController), "updateGraph")]
public class LevelSelectControllerUpdateGraphPatch : MonoBehaviour
{
private static bool Prefix(LevelSelectController __instance)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < 5; i++)
{
__instance.graphline.SetPosition(i, __instance.getGraphVector(i, (float)Mathf.FloorToInt(Random.value * 100f)));
}
return false;
}
}
[HarmonyPatch(typeof(LevelSelectController), "populateSongNames")]
public class LevelSelectControllerPopulateSongNamesPatch : MonoBehaviour
{
private static void Prefix(ref int ___songindex)
{
GlobalVariables.levelselect_index = ___songindex;
Plugin.Options.LastIndex.Value = ___songindex;
}
}
[HarmonyPatch(typeof(LevelSelectController), "searchForSongName")]
public class LevelSelectControllerSearchFirstLetterPatch : MonoBehaviour
{
private static bool Prefix(string startingletter)
{
return false;
}
}
[HarmonyPatch(typeof(LevelSelectController), "Update")]
public class LevelSelectControllerUpdatePatch : MonoBehaviour
{
private static void Postfix(LevelSelectController __instance, ref int ___songindex, ref List<SingleTrackData> ___alltrackslist)
{
if ((Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) && Input.GetKeyDown((KeyCode)102))
{
((Selectable)Plugin.SearchInput).Select();
}
else
{
if (Plugin.SearchInput.isFocused || !Input.anyKeyDown || Input.inputString.Length <= 0)
{
return;
}
char c = Input.inputString.ToLower()[0];
int num = 1;
int num2 = ___songindex + 1;
while (num2 < ___alltrackslist.Count)
{
if (___alltrackslist[num2].trackname_short.ToLower().Trim()[0] == c)
{
__instance.advanceSongs(num, true);
return;
}
num2++;
num++;
}
int num3 = 0;
while (num3 < ___songindex)
{
if (___alltrackslist[num3].trackname_short.ToLower().Trim()[0] == c)
{
__instance.advanceSongs(num, true);
break;
}
num3++;
num++;
}
}
}
}
[HarmonyPatch(typeof(LevelSelectController), "clickBack")]
public class LevelSelectControllerBackPatch : MonoBehaviour
{
private static void Postfix()
{
Plugin.UnloadModule();
}
}
[HarmonyPatch(typeof(LevelSelectController), "clickPlay")]
public class LevelSelectControllerPlayPatch : MonoBehaviour
{
private static void Postfix()
{
Plugin.UnloadModule();
}
}
[HarmonyPatch(typeof(LevelSelectController), "Start")]
public class LevelSelectControllerStartPatch : MonoBehaviour
{
private const string FULLSCREENPANEL = "MainCanvas/FullScreenPanel";
private const string LEADERBOARD_PATH = "MainCanvas/FullScreenPanel/Leaderboard";
private const string SORT_DROPDOWN_PATH = "MainCanvas/FullScreenPanel/sort-dropdown";
private const string SORT_DROPDROPDOWN_FACE_PATH = "MainCanvas/FullScreenPanel/sort-dropdown/face";
private const string SORT_BUTTON_PATH = "MainCanvas/FullScreenPanel/sort-dropdown/face/btn_sort_length";
private const string COMPOSER_NAME_PATH = "MainCanvas/FullScreenPanel/capsules/composername";
private const string TITLE_BAR = "MainCanvas/FullScreenPanel/title bar";
private static void Prefix()
{
GlobalVariables.sortmode = Plugin.Options.SortMode.Value;
GlobalVariables.levelselect_index = Plugin.Options.LastIndex.Value;
if (GlobalVariables.levelselect_index >= GlobalVariables.data_tracktitles.Length)
{
GlobalVariables.levelselect_index = 0;
}
}
private static void Postfix(LevelSelectController __instance)
{
IEnumerable<TootTally.SearchTrackResult> ratedTracks = TootTally.ReadRatedTracks();
if (Plugin.TrackLoaded == null)
{
Plugin.TrackLoaded = new TrackLoaded(__instance, ratedTracks);
TracksLoadedEvent.EVENT.Register((Listener)(object)Plugin.TrackLoaded);
Plugin.TrackLoaded.OnTracksLoaded(null);
}
AddOptions(__instance);
AddSearchBar(__instance);
}
private static void AddOptions(LevelSelectController __instance)
{
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
//IL_0200: Unknown result type (might be due to invalid IL or missing references)
//IL_0210: Unknown result type (might be due to invalid IL or missing references)
GameObject val = GameObject.Find("MainCanvas/FullScreenPanel/sort-dropdown");
val.transform.SetAsLastSibling();
GameObject val2 = GameObject.Find("MainCanvas/FullScreenPanel/sort-dropdown/face");
RectTransform component = __instance.sortdrop.GetComponent<RectTransform>();
RectTransform component2 = val2.GetComponent<RectTransform>();
CreateSortOption(__instance, val2, "artist", -75f);
CreateSortOption(__instance, val2, "long name", -105f);
int num = 430;
component2.sizeDelta = new Vector2(180f, (float)num);
component.sizeDelta = new Vector2(180f, (float)num);
Button[] componentsInChildren = val2.GetComponentsInChildren<Button>();
foreach (Button val3 in componentsInChildren)
{
RectTransform component3 = ((Component)val3).GetComponent<RectTransform>();
component3.anchoredPosition = new Vector2(component3.anchoredPosition.x, component3.anchoredPosition.y + 90f);
}
int num2 = -180;
foreach (FilterOption value in Enum.GetValues(typeof(FilterOption)))
{
Toggle val4 = CreateFilterOption(val2, value, new Vector2(242f, (float)(num2 -= 30)));
ConfigEntry<bool> configEntry = GetConfigEntry(value);
if (configEntry != null)
{
val4.isOn = configEntry.Value;
((UnityEvent<bool>)(object)val4.onValueChanged).AddListener((UnityAction<bool>)delegate(bool b)
{
ToggleListener(configEntry, b, __instance);
});
}
}
Button[] componentsInChildren2 = val2.GetComponentsInChildren<Button>();
foreach (Button val5 in componentsInChildren2)
{
RectTransform component4 = ((Component)val5).GetComponent<RectTransform>();
component4.anchoredPosition = new Vector2(component4.anchoredPosition.x, component4.anchoredPosition.y + 60f);
}
}
private static void ToggleListener(ConfigEntry<bool> configEntry, bool b, LevelSelectController __instance)
{
configEntry.Value = b;
TrackLoaded.FilterTracks(__instance);
}
private static ConfigEntry<bool> GetConfigEntry(FilterOption filterOption)
{
if (1 == 0)
{
}
ConfigEntry<bool> result = (ConfigEntry<bool>)(filterOption switch
{
FilterOption.DEFAULT => Plugin.Options.ShowDefault,
FilterOption.CUSTOM => Plugin.Options.ShowCustom,
FilterOption.PLAYED => Plugin.Options.ShowPlayed,
FilterOption.UNPLAYED => Plugin.Options.ShowUnplayed,
FilterOption.NOT_S_RANK => Plugin.Options.ShowNotSRank,
FilterOption.S_RANK => Plugin.Options.ShowSRank,
FilterOption.UNRATED => Plugin.Options.ShowUnrated,
FilterOption.RATED => Plugin.Options.ShowRated,
_ => null,
});
if (1 == 0)
{
}
return result;
}
private static void CreateSortOption(LevelSelectController __instance, GameObject face, string sortOption, float y)
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Expected O, but got Unknown
GameObject val = GameObject.Find("MainCanvas/FullScreenPanel/sort-dropdown/face/btn_sort_length");
Button val2 = Object.Instantiate<Button>(val.GetComponent<Button>(), ((Component)face.transform).transform);
Object.Destroy((Object)(object)((Component)val2).GetComponentInChildren<LocalizeStringEvent>());
((Object)val2).name = sortOption;
RectTransform component = ((Component)val2).GetComponent<RectTransform>();
component.anchoredPosition = new Vector2(0f, y);
Text componentInChildren = ((Component)val2).GetComponentInChildren<Text>();
componentInChildren.text = sortOption;
Button component2 = ((Component)val2).GetComponent<Button>();
((UnityEventBase)component2.onClick).RemoveAllListeners();
((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
{
__instance.sortTracks(sortOption, true);
});
}
private static Toggle CreateFilterOption(GameObject face, FilterOption filter, Vector2 position)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_0185: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
Toggle val = Object.Instantiate<Toggle>(Plugin.Toggle, ((Component)face.transform).transform);
string text = (((Object)val).name = Enums.GetDescription(filter));
RectTransform component = ((Component)val).GetComponent<RectTransform>();
component.anchoredPosition = position;
component.sizeDelta = new Vector2(180f, 30f);
Text componentInChildren = ((Component)val).GetComponentInChildren<Text>();
componentInChildren.text = text + " tracks";
componentInChildren.fontSize = 13;
((Graphic)componentInChildren).color = new Color(0.024f, 0.294f, 0.302f);
Image[] componentsInChildren = ((Component)val).GetComponentsInChildren<Image>();
Image[] array = componentsInChildren;
foreach (Image val2 in array)
{
if (((Object)val2).name == "Background")
{
((Graphic)val2).rectTransform.sizeDelta = new Vector2(0f, 30f);
((Graphic)val2).color = new Color(13f / 85f, 1f, 1f);
}
else if (((Object)val2).name == "Checkmark")
{
((Graphic)val2).rectTransform.anchoredPosition = new Vector2(-70f, 20f);
((Graphic)val2).rectTransform.sizeDelta = new Vector2(20f, 20f);
}
}
Text componentInChildren2 = ((Component)val).GetComponentInChildren<Text>();
((Graphic)componentInChildren2).rectTransform.sizeDelta = new Vector2(180f, ((Graphic)componentInChildren2).rectTransform.sizeDelta.y);
return val;
}
private static void AddSearchBar(LevelSelectController __instance)
{
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Expected O, but got Unknown
GameObject val = GameObject.Find("MainCanvas/FullScreenPanel");
Object.Destroy((Object)(object)__instance.scenetitle);
Plugin.SearchInput = Object.Instantiate<TMP_InputField>(Plugin.InputFieldPrefab, val.transform);
((Object)Plugin.SearchInput).name = "SearchInput";
((Component)Plugin.SearchInput).GetComponent<RectTransform>().anchoredPosition = new Vector2(190f, 420f);
((Component)Plugin.SearchInput).GetComponent<RectTransform>().sizeDelta = new Vector2(80f, 14f);
Plugin.SearchInput.text = Plugin.Options.SearchValue.Value;
((UnityEvent<string>)(object)Plugin.SearchInput.onEndEdit).AddListener((UnityAction<string>)delegate(string text)
{
Plugin.SearchInput.text = text;
});
((UnityEvent<string>)(object)Plugin.SearchInput.onValueChanged).AddListener((UnityAction<string>)delegate(string text)
{
Plugin.Options.SearchValue.Value = text;
TrackLoaded.FilterTracks(__instance);
});
Button val2 = AddDeleteButton(Plugin.SearchInput.textComponent);
((Object)val2).name = "clear search";
((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
{
Plugin.SearchInput.text = "";
Plugin.SearchInput.textComponent.text = "";
Plugin.Options.SearchValue.Value = "";
TrackLoaded.FilterTracks(__instance);
});
RectTransform component = ((Component)val2).GetComponent<RectTransform>();
}
private static Button AddDeleteButton(TMP_Text scoreText)
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
RectTransform component = ((Component)scoreText).GetComponent<RectTransform>();
Button val = Object.Instantiate<Button>(Plugin.Button, (Transform)(object)component);
RectTransform component2 = ((Component)val).GetComponent<RectTransform>();
((UnityEventBase)val.onClick).RemoveAllListeners();
component2.sizeDelta = new Vector2(15f, 15f);
((Transform)component2).position = ((Transform)component).position;
component2.anchoredPosition = new Vector2(-20f, 15f);
Text componentInChildren = ((Component)val).GetComponentInChildren<Text>();
componentInChildren.text = "X";
componentInChildren.fontSize = 12;
return val;
}
}
}
namespace SongOrganizer.Data
{
public class Enums
{
public static string GetDescription(Enum value)
{
FieldInfo field = value.GetType().GetField(value.ToString());
return (field.GetCustomAttributes(typeof(DescriptionAttribute), inherit: false) is DescriptionAttribute[] source && source.Any()) ? source.First().Description : value.ToString();
}
}
public enum FilterOption
{
DEFAULT,
CUSTOM,
UNPLAYED,
PLAYED,
[Description("Non S rank")]
NOT_S_RANK,
[Description("S rank")]
S_RANK,
UNRATED,
RATED
}
public class Options
{
public ConfigEntry<bool> ShowDefault { get; set; }
public ConfigEntry<bool> ShowCustom { get; set; }
public ConfigEntry<bool> ShowUnplayed { get; set; }
public ConfigEntry<bool> ShowPlayed { get; set; }
public ConfigEntry<bool> ShowNotSRank { get; set; }
public ConfigEntry<bool> ShowSRank { get; set; }
public ConfigEntry<bool> ShowUnrated { get; set; }
public ConfigEntry<bool> ShowRated { get; set; }
public ConfigEntry<string> SortMode { get; set; }
public ConfigEntry<int> LastIndex { get; set; }
public ConfigEntry<string> SearchValue { get; set; }
}
public class TootTally
{
[Serializable]
public class SearchResponse
{
public List<SearchTrackResult> results;
}
[Serializable]
public class SearchTrackResult
{
public string track_ref;
public string short_name;
public string name;
public string note_hash;
public string file_hash;
public decimal difficulty;
public string author;
public string download;
public string mirror;
public bool is_official;
public bool is_rated;
}
public static string RatedTracksPath = Paths.ConfigPath + "/rated.json";
public const string API_URL = "https://toottally.com";
public const string RATED_ENDPOINT = "/api/search/?rated=1&page=1&page_size=100000&fields=track_ref,short_name,name,note_hash,file_hash,difficulty,author,download,mirror,is_official,is_rated";
public static IEnumerator<UnityWebRequestAsyncOperation> GetRatedTracks()
{
string apiLink = "https://toottally.com/api/search/?rated=1&page=1&page_size=100000&fields=track_ref,short_name,name,note_hash,file_hash,difficulty,author,download,mirror,is_official,is_rated";
Plugin.Log.LogDebug((object)("Getting rated tracks " + apiLink));
UnityWebRequest webRequest = UnityWebRequest.Get(apiLink);
yield return webRequest.SendWebRequest();
if (!webRequest.isNetworkError && !webRequest.isHttpError)
{
File.WriteAllText(RatedTracksPath, webRequest.downloadHandler.GetText());
Plugin.Log.LogDebug((object)("Finished writing rated tracks to " + RatedTracksPath));
}
else
{
Plugin.Log.LogError((object)("ERROR: " + webRequest.error));
}
}
public static IEnumerable<SearchTrackResult> ReadRatedTracks()
{
try
{
string text = File.ReadAllText(RatedTracksPath);
SearchResponse searchResponse = JsonConvert.DeserializeObject<SearchResponse>(text);
return searchResponse.results.Where((SearchTrackResult i) => i.is_rated);
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Error reading rated.json\n" + ex.Message));
}
return new List<SearchTrackResult>();
}
}
public class Track : SingleTrackData
{
public bool custom { get; set; }
public bool rated { get; set; }
public string letterScore { get; set; }
public int[] scores { get; set; }
public Track()
{
}
public Track(SingleTrackData other)
{
base.trackname_long = other.trackname_long;
base.trackname_short = other.trackname_short;
base.year = other.year;
base.artist = other.artist;
base.desc = other.desc;
base.genre = other.genre;
base.difficulty = other.difficulty;
base.tempo = other.tempo;
base.length = other.length;
base.trackindex = other.trackindex;
base.trackref = other.trackref;
}
}
}