using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BaboonAPI.Hooks.Initializer; using BaboonAPI.Hooks.Tracks; using BaboonAPI.Hooks.Tracks.Collections; using BaboonAPI.Utility; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Cinemachine; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using Microsoft.FSharp.Core; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using TMPro; using TrombLoader.CustomTracks; using TrombLoader.CustomTracks.Backgrounds; using TrombLoader.Data; using TrombLoader.Helpers; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.Playables; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.Video; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("TromboneChamps")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Trombone Champ Custom Chart Loader")] [assembly: AssemblyFileVersion("2.4.5.0")] [assembly: AssemblyInformationalVersion("2.4.5+d20a9aada3e5d15c15ba35d46b9239e8773d533a")] [assembly: AssemblyProduct("TrombLoader")] [assembly: AssemblyTitle("TrombLoader")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/tc-mods/TrombLoader")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.4.5.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace TrombLoader { [BepInPlugin("TrombLoader", "TrombLoader", "2.4.5")] [BepInDependency("ch.offbeatwit.baboonapi.plugin", "2.10.0")] public class Plugin : BaseUnityPlugin { public static Plugin Instance; public ShaderHelper ShaderHelper; public ConfigEntry beatsToShow; public ConfigEntry DeveloperMode; public ConfigEntry DefaultBackground; public ConfigEntry turboBackgroundFallback; private Harmony _harmony = new Harmony("TrombLoader"); private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown ConfigFile val = new ConfigFile(Path.Combine(Paths.ConfigPath, "TrombLoader.cfg"), true); beatsToShow = val.Bind("General", "Note Display Limit", 64, "The maximum amount of notes displayed on screen at once."); List list = new List { "freeplay", "freeplay-static", "grey", "black" }; DefaultBackground = val.Bind("General", "Default Background", "freeplay", "The default background to show when a chart does not include one. Can be one of the following:\n" + string.Join(", ", list)); DefaultBackground.Value = DefaultBackground.Value.ToLower().Trim(); if (!list.Contains(DefaultBackground.Value)) { LogWarning("Default Background is not set to a valid option!"); } turboBackgroundFallback = val.Bind("General", "Turbo Mode Background Fallback", false, "When enabled, TrombLoader will load an image or default background instead of a video background when Turbo Mode is on."); DeveloperMode = val.Bind("Charting", "Developer Mode", false, "When enabled, TrombLoader will re-read chart data from disk each time a track is loaded."); Instance = this; LogInfo("Plugin TrombLoader is loaded!"); GameInitializationEvent.Register(((BaseUnityPlugin)this).Info, (Action)TryInitialize); TrackLoader trackLoader = new TrackLoader(); TrackRegistrationEvent.EVENT.Register((Listener)(object)trackLoader); CustomTrackLoaderEvent.EVENT.Register((CustomTrackLoader)(object)trackLoader); TrackCollectionRegistrationEvent.EVENT.Register((Listener)(object)new TrombLoaderCollection.CollectionLoader(this)); ShaderHelper = new ShaderHelper(); QualitySettings.pixelLightCount = 16; } private void TryInitialize() { _harmony.PatchAll(); } public IEnumerator GetAudioClipSync(string path, Action callback = null) { Uri uri = new UriBuilder(Uri.UriSchemeFile, string.Empty) { Path = path }.Uri; UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(uri, (AudioType)14); ((DownloadHandlerAudioClip)www.downloadHandler).streamAudio = true; yield return www.SendWebRequest(); while (!www.isDone) { yield return null; } if (www.isNetworkError || www.isHttpError) { yield return www.error; yield break; } callback?.Invoke(); yield return DownloadHandlerAudioClip.GetContent(www); } public void LoadGameplayScene() { SceneManager.LoadSceneAsync("gameplay", (LoadSceneMode)0); } internal static void LogDebug(string message) { Instance.Log(message, (LogLevel)32); } internal static void LogInfo(string message) { Instance.Log(message, (LogLevel)16); } internal static void LogWarning(string message) { Instance.Log(message, (LogLevel)4); } internal static void LogError(string message) { Instance.Log(message, (LogLevel)2); } private void Log(string message, LogLevel logLevel) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) ((BaseUnityPlugin)this).Logger.Log(logLevel, (object)message); } } public static class PluginInfo { public const string PLUGIN_GUID = "TrombLoader"; public const string PLUGIN_NAME = "TrombLoader"; public const string PLUGIN_VERSION = "2.4.5"; } } namespace TrombLoader.Patch { [HarmonyPatch] public class BeatsToShowPatch { [HarmonyPatch(typeof(GameController), "Start")] [HarmonyPrefix] private static void PatchBeatsToShow(out int ___beatstoshow) { ___beatstoshow = Plugin.Instance.beatsToShow?.Value ?? 64; } } [HarmonyPatch(typeof(GameController))] [HarmonyPatch("startDance")] public class GameControllerStartDancePatch { private static void DoStartDance(GameController controller, float num) { BackgroundPuppetController component = controller.bgcontroller.fullbgobject.GetComponent(); if ((Object)(object)component != (Object)null) { component.StartPuppetBob(num); } } private static IEnumerable Transpiler(IEnumerable instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).End().InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldloc_0, (object)null), CodeInstruction.Call(typeof(GameControllerStartDancePatch), "DoStartDance", (Type[])null, (Type[])null) }).InstructionEnumeration(); } } [HarmonyPatch(typeof(GameController))] [HarmonyPatch("Update")] public class GameControllerPuppetUpdatePatch { private static MethodInfo doPuppetControl_m = AccessTools.Method(typeof(HumanPuppetController), "doPuppetControl", (Type[])null, (Type[])null); private static void DoPuppetControl(GameController controller, float vp, float vibratoAmount) { BackgroundPuppetController component = controller.bgcontroller.fullbgobject.GetComponent(); if ((Object)(object)component != (Object)null) { component.DoPuppetControl(vp * 2f, vibratoAmount); } } private static void Postfix(GameController __instance) { BackgroundPuppetController component = __instance.bgcontroller.fullbgobject.GetComponent(); if ((Object)(object)component != (Object)null) { if (GlobalVariables.localsettings.mousecontrolmode <= 1) { component.DoManualDance(Input.GetAxis("Mouse X") * 1.25f * GlobalVariables.localsettings.sensitivity); } else { component.DoManualDance(Input.GetAxis("Mouse Y") * -1.25f * GlobalVariables.localsettings.sensitivity); } } } private static IEnumerable Transpiler(IEnumerable instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown CodeMatcher obj = new CodeMatcher(instructions, (ILGenerator)null).SearchForward((Func)((CodeInstruction instruction) => CodeInstructionExtensions.Calls(instruction, doPuppetControl_m))).ThrowIfInvalid("Failed to find injection point in GameController#Update"); CodeInstruction val = obj.InstructionAt(-3); if (!CodeInstructionExtensions.IsLdloc(val, (LocalBuilder)null)) { throw new InvalidOperationException("Failed to find ldloc in GameController#Update"); } return obj.Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[5] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldloc_S, val.operand), new CodeInstruction(OpCodes.Ldarg_0, (object)null), CodeInstruction.LoadField(typeof(GameController), "vibratoamt", false), CodeInstruction.Call(typeof(GameControllerPuppetUpdatePatch), "DoPuppetControl", (Type[])null, (Type[])null) }).InstructionEnumeration(); } } [HarmonyPatch(typeof(GameController))] [HarmonyPatch("setPuppetBreath")] public class GameControllerPuppetBreathPatch { private static void Postfix(GameController __instance, bool hasbreath) { BackgroundPuppetController component = __instance.bgcontroller.fullbgobject.GetComponent(); if ((Object)(object)component != (Object)null) { component.SetPuppetBreath(hasbreath); } } } [HarmonyPatch(typeof(GameController))] [HarmonyPatch("setPuppetShake")] public class GameControllerPuppetShakePatch { private static void Postfix(GameController __instance, bool shake) { BackgroundPuppetController component = __instance.bgcontroller.fullbgobject.GetComponent(); if ((Object)(object)component != (Object)null) { component.SetPuppetShake(shake); } } } [HarmonyPatch(typeof(HumanPuppetController))] [HarmonyPatch("startPuppetBob")] public class HumanPuppetControllerPuppetBobPatch { private static bool Prefix(HumanPuppetController __instance) { return !__instance.just_testing; } } [HarmonyPatch(typeof(HumanPuppetController))] [HarmonyPatch("testMovement")] public class HumanPuppetControllerTestMovementPatch { private static bool Prefix() { return false; } } [HarmonyPatch(typeof(HumanPuppetController))] [HarmonyPatch("Start")] public class HumanPuppetControllerStartPatch { private static bool Prefix(HumanPuppetController __instance) { return !((Object)(object)((Component)__instance).gameObject.GetComponent() != (Object)null); } private static void Postfix(HumanPuppetController __instance, bool __runOriginal) { if (!__runOriginal) { ((MonoBehaviour)__instance).Invoke("setTextures", 0.5f); __instance.applyFaceTex(); } } } [HarmonyPatch(typeof(GameController))] public class TrackEndPatch { [HarmonyPatch("Start")] [HarmonyPostfix] public static void FixTrackEnd(GameController __instance) { if (!((Object)(object)__instance.musictrack == (Object)null) && !((Object)(object)__instance.musictrack.clip == (Object)null)) { float length = __instance.musictrack.clip.length; if (__instance.levelendtime >= length) { __instance.levelendtime = length - 0.001f; } } } } } namespace TrombLoader.Helpers { public class BeatCounter : MonoBehaviour { public List targetBeats; public float currentBeat; public UnityEvent actionToExecute; private bool isInitialized; public float bpm; public bool runOnZeroBeat; public void IncrementBeat() { if (!isInitialized) { isInitialized = true; if (!runOnZeroBeat) { return; } } if (targetBeats.Count == 0) { return; } float num = 0.125f; CheckNote(currentBeat); for (int i = 1; i < 8; i++) { float newTime = num * (float)i; float num2 = newTime * 60f / bpm; LeanTween.value(0f, 1f, num2).setOnComplete((Action)delegate { CheckNote(currentBeat + newTime); }); } currentBeat += 1f; } private void CheckNote(float target) { if (targetBeats.Count != 0 && target >= targetBeats[0]) { UnityEvent obj = actionToExecute; if (obj != null) { obj.Invoke(); } targetBeats.RemoveAt(0); } } [ContextMenu("Parse String")] public void ParseFromString() { string systemCopyBuffer = GUIUtility.systemCopyBuffer; targetBeats = new List(); string[] array = systemCopyBuffer.Replace("[", "").Replace("]", "").Split(new char[1] { ',' }); foreach (string s in array) { targetBeats.Add(float.Parse(s, CultureInfo.InvariantCulture)); } } } public static class Globals { public static readonly string defaultChartName = "song.tmb"; public static readonly string defaultAudioName = "song.ogg"; public static readonly string defaultPreviewName = "preview.ogg"; [Obsolete("No longer populated, use BaboonAPI to look up the track and cast to CustomTrack instead")] public static Dictionary ChartFolders = new Dictionary(); [Obsolete("No longer controlled by TrombLoader")] public static bool SaveCreationEnabled = true; public static string GetCustomSongsPath() { return Path.Combine(Paths.BepInExRootPath, "CustomSongs/"); } public static bool IsCustomTrack(string trackReference) { return TrackLookup.lookup(trackReference) is CustomTrack; } } public static class ImageHelper { public static Texture2D LoadTextureRaw(byte[] bytes) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown if (bytes.Count() > 0) { Texture2D val = new Texture2D(2, 2); if (ImageConversion.LoadImage(val, bytes)) { return val; } } return null; } public static Texture2D LoadTextureFromFile(string path) { if (File.Exists(path)) { return LoadTextureRaw(File.ReadAllBytes(path)); } return null; } public static Texture2D LoadTextureFromResources(string resourcePath) { return LoadTextureRaw(GetResource(Assembly.GetCallingAssembly(), resourcePath)); } public static Sprite LoadSpriteRaw(byte[] image, float pixelsPerUnit = 100f) { return LoadSpriteFromTexture(LoadTextureRaw(image), pixelsPerUnit); } public static Sprite LoadSpriteFromTexture(Texture2D texture, float pixelsPerUnit = 100f) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)texture)) { return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f), pixelsPerUnit); } return null; } public static Sprite LoadSpriteFromFile(string path, float pixelsPerUnit = 100f) { return LoadSpriteFromTexture(LoadTextureFromFile(path), pixelsPerUnit); } public static Sprite LoadSpriteFromResources(string resourcePath, float pixelsPerUnit = 100f) { return LoadSpriteRaw(GetResource(Assembly.GetCallingAssembly(), resourcePath), pixelsPerUnit); } private static byte[] GetResource(Assembly asm, string resourcePath) { Stream manifestResourceStream = asm.GetManifestResourceStream(resourcePath); byte[] array = new byte[manifestResourceStream.Length]; manifestResourceStream.Read(array, 0, (int)manifestResourceStream.Length); return array; } } public class SceneLightingHelper : MonoBehaviour { public Color ambientSkyColor = Color.black; public Color ambientEquatorColor = Color.black; public float ambientIntensity; public float reflectionIntensity; public Material skybox; public Light sun; public void Start() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) RenderSettings.ambientSkyColor = ambientSkyColor; RenderSettings.ambientEquatorColor = ambientEquatorColor; RenderSettings.ambientIntensity = ambientIntensity; RenderSettings.reflectionIntensity = reflectionIntensity; RenderSettings.skybox = skybox; RenderSettings.sun = sun; } } public class ShaderHelper { public List BaseGameShaderNames = new List { "Custom/WavySpriteLit", "Custom/WavySpriteUnlit", "FX/Flare", "FX/Gem", "GUI/Text Shader", "Hidden/BlitCopy", "Hidden/BlitCopyDepth", "Hidden/BlitCopyWithDepth", "Hidden/BlitToDepth", "Hidden/BlitToDepth/MSAA", "Hidden/Compositing", "Hidden/ConvertTexture", "Hidden/CubeBlend", "Hidden/CubeBlur", "Hidden/CubeCopy", "Hidden/FrameDebuggerRenderTargetDisplay", "Hidden/Internal-Colored", "Hidden/Internal-CombineDepthNormals", "Hidden/Internal-CubemapToEquirect", "Hidden/Internal-DeferredReflections", "Hidden/Internal-DeferredShading", "Hidden/Internal-DepthNormalsTexture", "Hidden/Internal-Flare", "Hidden/Internal-GUIRoundedRect", "Hidden/Internal-GUIRoundedRectWithColorPerBorder", "Hidden/Internal-GUITexture", "Hidden/Internal-GUITextureBlit", "Hidden/Internal-GUITextureClip", "Hidden/Internal-GUITextureClipText", "Hidden/Internal-Halo", "Hidden/Internal-MotionVectors", "Hidden/Internal-ODSWorldTexture", "Hidden/Internal-PrePassLighting", "Hidden/Internal-ScreenSpaceShadows", "Hidden/Internal-StencilWrite", "Hidden/Internal-UIRAtlasBlitCopy", "Hidden/Internal-UIRDefault", "Hidden/InternalClear", "Hidden/InternalErrorShader", "Hidden/Post FX/Ambient Occlusion", "Hidden/Post FX/Blit", "Hidden/Post FX/Bloom", "Hidden/Post FX/Builtin Debug Views", "Hidden/Post FX/Depth Of Field", "Hidden/Post FX/Eye Adaptation", "Hidden/Post FX/Fog", "Hidden/Post FX/FXAA", "Hidden/Post FX/Grain Generator", "Hidden/Post FX/Lut Generator", "Hidden/Post FX/Motion Blur", "Hidden/Post FX/Screen Space Reflection", "Hidden/Post FX/Temporal Anti-aliasing", "hidden/SuperSystems/Wireframe-Global", "hidden/SuperSystems/Wireframe-Shaded-Unlit-Global", "hidden/SuperSystems/Wireframe-Transparent-Culled-Global", "hidden/SuperSystems/Wireframe-Transparent-Global", "Hidden/TextCore/Distance Field SSD", "Hidden/VideoComposite", "Hidden/VideoDecode", "Hidden/VideoDecodeOSX", "Hidden/VR/BlitFromTex2DToTexArraySlice", "Hidden/VR/BlitTexArraySlice", "Legacy Shaders/Diffuse", "Legacy Shaders/Particles/Additive", "Legacy Shaders/Particles/Alpha Blended Premultiply", "Legacy Shaders/Particles/Alpha Blended", "Legacy Shaders/Transparent/VertexLit", "Legacy Shaders/VertexLit", "Mobile/Unlit (Supports Lightmap)", "Particles/Standard Unlit", "Skybox/Procedural", "Spaventacorvi/Glitter/Glitter F - Bumped Specular", "Spaventacorvi/Holographic/Holo D - Specular Textured", "Sprites/Default", "Sprites/Diffuse", "Sprites/Mask", "Standard (Specular setup)", "Standard", "SuperSystems/Wireframe-Transparent-Culled", "TextMeshPro/Bitmap Custom Atlas", "TextMeshPro/Bitmap", "TextMeshPro/Distance Field (Surface)", "TextMeshPro/Distance Field Overlay", "TextMeshPro/Distance Field", "TextMeshPro/Mobile/Bitmap", "TextMeshPro/Mobile/Distance Field (Surface)", "TextMeshPro/Mobile/Distance Field - Masking", "TextMeshPro/Mobile/Distance Field Overlay", "TextMeshPro/Mobile/Distance Field", "TextMeshPro/Sprite", "UI/Default", "Hidden/Post FX/Uber" }; public List BaseGameShadersFamiliesToNotLoad = new List { "Hidden", "TextMeshPro" }; public Dictionary ShaderCache { get; } public Dictionary BaseGameShaderCache { get; } = new Dictionary(); public ShaderHelper() { //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Invalid comparison between Unknown and I4 //IL_0450: Unknown result type (might be due to invalid IL or missing references) if ((int)Application.platform == 1) { LoadBaseGameShaders(); ShaderCache = LoadShaderBundleFromPath(((BaseUnityPlugin)Plugin.Instance).Info.Location, Application.platform); } else { ShaderCache = new Dictionary(); } } private void LoadBaseGameShaders() { int num = 0; foreach (string baseGameShaderName in BaseGameShaderNames) { if (!BaseGameShadersFamiliesToNotLoad.Any((string e) => baseGameShaderName.ToLower().StartsWith(e.ToLower()))) { Shader val = Shader.Find(baseGameShaderName); if ((Object)(object)val == (Object)null) { Plugin.LogInfo("Failed to cache " + baseGameShaderName); num++; } else { BaseGameShaderCache.Add(((Object)val).name, val); } } } Plugin.LogInfo($"{BaseGameShaderCache.Count} Base game shaders loaded. {num} failed to load."); } public Dictionary LoadShaderBundleFromPath(string path, RuntimePlatform? platform = null) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 Dictionary dictionary = new Dictionary(); List list = new List { "*.DONOTDELETE", "*.shaderbundle", "*.shaders" }; List list2 = new List(); if ((int)platform.GetValueOrDefault() == 1) { foreach (string item2 in list) { string[] files = Directory.GetFiles(Path.GetDirectoryName(path), item2, SearchOption.TopDirectoryOnly); foreach (string text in files) { if ((text.ToLower().Contains("macos") || text.ToLower().Contains("osx")) && !list2.Contains(text)) { list2.Add(text); } } } } else if (!platform.HasValue) { foreach (string item3 in list) { string[] files = Directory.GetFiles(Path.GetDirectoryName(path), item3, SearchOption.TopDirectoryOnly); foreach (string item in files) { if (!list2.Contains(item)) { list2.Add(item); } } } } foreach (string item4 in list2) { if (!File.Exists(item4)) { continue; } AssetBundle val = AssetBundle.LoadFromFile(item4); Object obj = val.LoadAsset("Assets/_Shaders.prefab"); GameObject val2 = (GameObject)(object)((obj is GameObject) ? obj : null); if ((Object)(object)val2 != (Object)null) { Renderer[] componentsInChildren = val2.GetComponentsInChildren(); foreach (Renderer val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3.sharedMaterial == (Object)null)) { Shader shader = val3.sharedMaterial.shader; if (!((Object)(object)shader == (Object)null) && !dictionary.ContainsKey(((Object)shader).name) && !BaseGameShaderCache.ContainsKey(((Object)shader).name)) { dictionary.Add(((Object)shader).name, shader); } } } } else { Plugin.LogWarning("Missing _Shaders.prefab file in bundle " + item4 + "!"); } val.Unload(false); } return dictionary; } } } namespace TrombLoader.Data { [Serializable] [RequireComponent(typeof(TromboneEventManager))] public class BackgroundEvent : MonoBehaviour { [SerializeField] public int BackgroundEventID; public UnityEvent UnityEvent; } public class BackgroundPuppetController : MonoBehaviour { public List Tromboners { get; } public BackgroundPuppetController() { Tromboners = new List(); } public void StartPuppetBob(float bob) { foreach (Tromboner tromboner in Tromboners) { tromboner.controller.startPuppetBob(bob); } } public void DoPuppetControl(float vp, float vibrato) { foreach (Tromboner tromboner in Tromboners) { tromboner.controller.doPuppetControl(vp); tromboner.controller.vibrato = vibrato; } } public void DoManualDance(float amount) { foreach (Tromboner tromboner in Tromboners) { if (tromboner.placeholder.DanceMode == TrombonerDanceMode.ManualDance) { tromboner.controller.doManualDance(amount); } } } public void SetPuppetBreath(bool hasBreath) { foreach (Tromboner tromboner in Tromboners) { tromboner.controller.outofbreath = hasBreath; tromboner.controller.applyFaceTex(); } } public void SetPuppetShake(bool shaking) { foreach (Tromboner tromboner in Tromboners) { tromboner.controller.shaking = shaking; tromboner.controller.applyFaceTex(); } } } public class CustomPuppetController : MonoBehaviour { public Tromboner Tromboner { get; set; } public void Start() { HumanPuppetController controller = Tromboner.controller; int movementType = GetMovementType(); LeanTween.value((movementType == 0) ? 10f : (-38f), -48f, 7f).setLoopPingPong().setEaseInOutQuart() .setOnUpdate((Action)delegate(float val) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) controller.p_parent.transform.localEulerAngles = new Vector3(0f, val, 0f); }); controller.estudious = movementType == 1; } private int GetMovementType() { if (Tromboner.placeholder.MovementType == TrombonerMovementType.DoNotOverride) { return GlobalVariables.chosen_vibe; } return (int)Tromboner.placeholder.MovementType; } } [Serializable] public class LeanTweenHelper : MonoBehaviour { public enum LeanTweenHelperType { MOVELOCAL, MOVEGLOBAL, ROTATELOCAL, ROTATEGLOBAL, MOVEX, MOVEY, MOVEZ, MOVELOCALX, MOVELOCALY, MOVELOCALZ, SCALE } public LeanTweenHelperType tweenType; public Vector3 vector3Value; public float floatValue; public float time; public LeanTweenType easeType = (LeanTweenType)1; public LeanTweenType loopType = (LeanTweenType)36; public int loopCount; public bool runOnStart; public LeanTweenHelper invokeOnComplete; public Action tweenAction; public void SetTweenType() { switch (tweenType) { case LeanTweenHelperType.MOVELOCAL: tweenAction = delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) LeanTween.moveLocal(((Component)this).gameObject, vector3Value, time).setEase(easeType).setLoopCount(loopCount) .setLoopType(loopType) .setOnComplete((Action)delegate { invokeOnComplete?.DoTween(); }); }; break; case LeanTweenHelperType.MOVEGLOBAL: tweenAction = delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) LeanTween.move(((Component)this).gameObject, vector3Value, time).setEase(easeType).setLoopCount(loopCount) .setLoopType(loopType) .setOnComplete((Action)delegate { invokeOnComplete?.DoTween(); }); }; break; case LeanTweenHelperType.ROTATELOCAL: tweenAction = delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) LeanTween.rotateLocal(((Component)this).gameObject, vector3Value, time).setEase(easeType).setLoopCount(loopCount) .setLoopType(loopType) .setOnComplete((Action)delegate { invokeOnComplete?.DoTween(); }); }; break; case LeanTweenHelperType.ROTATEGLOBAL: tweenAction = delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) LeanTween.rotate(((Component)this).gameObject, vector3Value, time).setEase(easeType).setLoopCount(loopCount) .setLoopType(loopType) .setOnComplete((Action)delegate { invokeOnComplete?.DoTween(); }); }; break; case LeanTweenHelperType.SCALE: tweenAction = delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) LeanTween.scale(((Component)this).gameObject, vector3Value, time).setEase(easeType).setLoopCount(loopCount) .setLoopType(loopType) .setOnComplete((Action)delegate { invokeOnComplete?.DoTween(); }); }; break; case LeanTweenHelperType.MOVEX: tweenAction = delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) LeanTween.moveX(((Component)this).gameObject, floatValue, time).setEase(easeType).setLoopCount(loopCount) .setLoopType(loopType) .setOnComplete((Action)delegate { invokeOnComplete?.DoTween(); }); }; break; case LeanTweenHelperType.MOVEY: tweenAction = delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) LeanTween.moveY(((Component)this).gameObject, floatValue, time).setEase(easeType).setLoopCount(loopCount) .setLoopType(loopType) .setOnComplete((Action)delegate { invokeOnComplete?.DoTween(); }); }; break; case LeanTweenHelperType.MOVEZ: tweenAction = delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) LeanTween.moveZ(((Component)this).gameObject, floatValue, time).setEase(easeType).setLoopCount(loopCount) .setLoopType(loopType) .setOnComplete((Action)delegate { invokeOnComplete?.DoTween(); }); }; break; case LeanTweenHelperType.MOVELOCALX: tweenAction = delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) LeanTween.moveLocalX(((Component)this).gameObject, floatValue, time).setEase(easeType).setLoopCount(loopCount) .setLoopType(loopType) .setOnComplete((Action)delegate { invokeOnComplete?.DoTween(); }); }; break; case LeanTweenHelperType.MOVELOCALY: tweenAction = delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) LeanTween.moveLocalY(((Component)this).gameObject, floatValue, time).setEase(easeType).setLoopCount(loopCount) .setLoopType(loopType) .setOnComplete((Action)delegate { invokeOnComplete?.DoTween(); }); }; break; case LeanTweenHelperType.MOVELOCALZ: tweenAction = delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) LeanTween.moveLocalZ(((Component)this).gameObject, floatValue, time).setEase(easeType).setLoopCount(loopCount) .setLoopType(loopType) .setOnComplete((Action)delegate { invokeOnComplete?.DoTween(); }); }; break; } } public void Start() { SetTweenType(); if (runOnStart) { DoTween(); } } public void DoTween() { tweenAction(); } } [RequireComponent(typeof(Text))] public class TextEventHandler : MonoBehaviour { public string StringToReplaceWithEventData = "{int}"; private Text _text; private string _originalText; private int _cachedInt; public void ConvertIntToText(int inputInt) { _cachedInt = inputInt; UpdateText(); } private void UpdateText() { if ((Object)(object)_text != (Object)null) { if (_originalText == null) { _originalText = _text.text; } _text.text = _originalText.Replace(StringToReplaceWithEventData, _cachedInt.ToString()); } } public void Start() { _text = ((Component)this).GetComponent(); UpdateText(); } } public class TromboneEventInvoker : MonoBehaviour { [SerializeField] private GameController _controller; [SerializeField] private TromboneEventManager[] _eventManagers; [SerializeField] private BackgroundEvent[] _backgroundEvents; private bool previousNoteActiveValue; private bool waitingForNextTimeSigJump = true; private int barCount; private int previousCombo; private int previousBGDataIndex; private bool currentInputState; private bool currentChampState; private bool outOfBreath; public void InitializeInvoker(GameController controller, TromboneEventManager[] eventManagers) { _controller = controller; _eventManagers = eventManagers; } public void LateUpdate() { if (_controller == null) { return; } TromboneEventManager[] eventManagers; if (_controller.bgindex != previousBGDataIndex) { int num = (int)_controller.bgdata[previousBGDataIndex][1]; previousBGDataIndex = _controller.bgindex; eventManagers = _eventManagers; for (int i = 0; i < eventManagers.Length; i++) { BackgroundEvent[] events = eventManagers[i].Events; foreach (BackgroundEvent backgroundEvent in events) { if (backgroundEvent.BackgroundEventID == num) { backgroundEvent.UnityEvent.Invoke(); } } } } if (_controller.timesigcount == 1) { if (waitingForNextTimeSigJump) { waitingForNextTimeSigJump = false; eventManagers = _eventManagers; foreach (TromboneEventManager tromboneEventManager in eventManagers) { UnityEvent onBeat = tromboneEventManager.OnBeat; if (onBeat != null) { onBeat.Invoke(); } if (barCount % _controller.beatspermeasure == 0) { UnityEvent onBar = tromboneEventManager.OnBar; if (onBar != null) { onBar.Invoke(); } } } barCount++; } } else { waitingForNextTimeSigJump = true; } if (previousNoteActiveValue != _controller.noteactive) { previousNoteActiveValue = _controller.noteactive; eventManagers = _eventManagers; foreach (TromboneEventManager tromboneEventManager2 in eventManagers) { if (previousNoteActiveValue) { UnityEvent noteStart = tromboneEventManager2.NoteStart; if (noteStart != null) { noteStart.Invoke(); } } else { UnityEvent noteEnd = tromboneEventManager2.NoteEnd; if (noteEnd != null) { noteEnd.Invoke(); } } } } if (_controller.highestcombocounter != previousCombo) { previousCombo = _controller.highestcombocounter; eventManagers = _eventManagers; for (int i = 0; i < eventManagers.Length; i++) { ((UnityEvent)eventManagers[i].ComboUpdated)?.Invoke(previousCombo); } } if (_controller.notebuttonpressed) { if (!currentInputState) { currentInputState = true; eventManagers = _eventManagers; for (int i = 0; i < eventManagers.Length; i++) { UnityEvent playerTootInputStart = eventManagers[i].PlayerTootInputStart; if (playerTootInputStart != null) { playerTootInputStart.Invoke(); } } } } else if (currentInputState) { currentInputState = false; eventManagers = _eventManagers; for (int i = 0; i < eventManagers.Length; i++) { UnityEvent playerTootInputEnd = eventManagers[i].PlayerTootInputEnd; if (playerTootInputEnd != null) { playerTootInputEnd.Invoke(); } } } if (_controller.rainbowcontroller.champmode != currentChampState) { currentChampState = _controller.rainbowcontroller.champmode; eventManagers = _eventManagers; foreach (TromboneEventManager tromboneEventManager3 in eventManagers) { if (currentChampState) { UnityEvent champModeActivated = tromboneEventManager3.ChampModeActivated; if (champModeActivated != null) { champModeActivated.Invoke(); } } else { UnityEvent champModeDeactivated = tromboneEventManager3.ChampModeDeactivated; if (champModeDeactivated != null) { champModeDeactivated.Invoke(); } } } } if (_controller.outofbreath == outOfBreath) { return; } outOfBreath = _controller.outofbreath; eventManagers = _eventManagers; foreach (TromboneEventManager tromboneEventManager4 in eventManagers) { if (outOfBreath) { UnityEvent obj = tromboneEventManager4.OutOfBreath; if (obj != null) { obj.Invoke(); } } } } } [Serializable] public class Vector3Event : UnityEvent { } [Serializable] public class IntEvent : UnityEvent { } [Serializable] [DisallowMultipleComponent] public class TromboneEventManager : MonoBehaviour { [NonSerialized] public BackgroundEvent[] Events; public UnityEvent OnBeat; public UnityEvent OnBar; public UnityEvent NoteStart; public UnityEvent NoteEnd; public UnityEvent PlayerTootInputStart; public UnityEvent PlayerTootInputEnd; public UnityEvent ChampModeActivated; public UnityEvent ChampModeDeactivated; public UnityEvent OutOfBreath; public IntEvent ComboUpdated; public Vector3Event MousePositionUpdated; private Vector3 mousePosition; [SerializeField] [HideInInspector] private string serializedMousePositionJson; [SerializeField] [HideInInspector] private Object[] serializedMousePositionTargets; [SerializeField] [HideInInspector] private string serializedComboJson; [SerializeField] [HideInInspector] private Object[] serializedComboTargets; public void SerializeAllGenericEvents() { serializedMousePositionJson = JsonUtility.ToJson((object)MousePositionUpdated); serializedComboJson = JsonUtility.ToJson((object)ComboUpdated); } public void DeserializeAllGenericEvents() { if (Events == null) { Events = ((Component)this).GetComponents(); } if (!string.IsNullOrEmpty(serializedMousePositionJson)) { MousePositionUpdated = JsonUtility.FromJson(serializedMousePositionJson); AssignTargets((UnityEventBase)(object)MousePositionUpdated, serializedMousePositionTargets); } if (!string.IsNullOrEmpty(serializedComboJson)) { ComboUpdated = JsonUtility.FromJson(serializedComboJson); AssignTargets((UnityEventBase)(object)ComboUpdated, serializedComboTargets); } } public static void AssignTargets(UnityEventBase unityEvent, Object[] objects) { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; Type? type = typeof(UnityEventBase).Assembly.GetType("UnityEngine.Events.PersistentCall"); FieldInfo field = typeof(UnityEventBase).GetField("m_PersistentCalls", bindingAttr); FieldInfo? field2 = field.FieldType.GetField("m_Calls", bindingAttr); FieldInfo field3 = field2.FieldType.GetField("_items", bindingAttr); object value = field.GetValue(unityEvent); object value2 = field2.GetValue(value); object[] array = (object[])field3.GetValue(value2); FieldInfo field4 = type.GetField("m_Target", bindingAttr); for (int i = 0; i < array.Length; i++) { field4.SetValue(array[i], objects[i]); } } public void Update() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(serializedMousePositionJson) && MousePositionUpdated == null) { DeserializeAllGenericEvents(); } else if (!string.IsNullOrEmpty(serializedComboJson) && ComboUpdated == null) { DeserializeAllGenericEvents(); } if (MousePositionUpdated != null && Input.mousePosition != mousePosition) { mousePosition = Input.mousePosition; ((UnityEvent)MousePositionUpdated).Invoke(new Vector3(mousePosition.x / (float)Screen.width, mousePosition.y / (float)Screen.height, 0f)); } } } public class Tromboner { public GameObject gameObject; public Transform transform; public HumanPuppetController controller; public TrombonerPlaceholder placeholder; public Tromboner(GameObject _gameObject, TrombonerPlaceholder _placeholder) { gameObject = _gameObject; transform = _gameObject.transform; controller = _gameObject.GetComponent(); placeholder = _placeholder; } } public class TrombonerPlaceholder : MonoBehaviour { public TrombonerType TrombonerType = TrombonerType.DoNotOverride; public TrombonerOutfit TrombonerOutfit = TrombonerOutfit.DoNotOverride; public TromboneSkin TromboneSkin = TromboneSkin.DoNotOverride; public TromboneLength TromboneLength = TromboneLength.DoNotOverride; public TromboneHat TromboneHat = TromboneHat.DoNotOverride; public TrombonerMovementType MovementType = TrombonerMovementType.DoNotOverride; public TrombonerDanceMode DanceMode = TrombonerDanceMode.DoNotOverride; [HideInInspector] [SerializeField] public int InstanceID; } [Serializable] public enum TrombonerType { [InspectorName("Do Not Override (Default)")] DoNotOverride = -1, [InspectorName("Appaloosa")] Female1, [InspectorName("Beezerly")] Female2, [InspectorName("Kaizyle II")] Female3, [InspectorName("Trixiebell")] Female4, [InspectorName("Meldor")] Male1, [InspectorName("Jermajesty")] Male2, [InspectorName("Horn Lord")] Male3, [InspectorName("Soda")] Male4, [InspectorName("Polygon")] Female5, [InspectorName("Servant Of Babi")] Male5 } [Serializable] public enum TrombonerOutfit { [InspectorName("Do Not Override (Default)")] DoNotOverride = -1, [InspectorName("Default")] Default, [InspectorName("Christmas")] Christmas } [Serializable] public enum TromboneSkin { [InspectorName("Do Not Override (Default)")] DoNotOverride = -1, [InspectorName("Brass")] Brass, [InspectorName("Silver")] Silver, [InspectorName("Red")] Red, [InspectorName("Blue")] Blue, [InspectorName("Green")] Green, [InspectorName("Pink")] Pink, [InspectorName("Polygon")] Polygon, [InspectorName("Champ")] Champ } [Serializable] public enum TromboneLength { [InspectorName("Do Not Override (Default)")] DoNotOverride = -1, [InspectorName("Short")] Short, [InspectorName("Long")] Long } [Serializable] public enum TromboneHat { [InspectorName("Do Not Override (Default)")] DoNotOverride = -1, [InspectorName("Disabled")] Disabled, [InspectorName("Enabled")] Enabled } [Serializable] public enum TrombonerMovementType { [InspectorName("Do Not Override (Default)")] DoNotOverride = -1, [InspectorName("Jubilant")] Jubilant, [InspectorName("Estudious")] Estudious } [Serializable] public enum TrombonerDanceMode { [InspectorName("Do Not Override (Default)")] DoNotOverride = -1, [InspectorName("Auto Dance")] AutoDance, [InspectorName("Manual Dance")] ManualDance } } namespace TrombLoader.CustomTracks { public class ChartCompatibility { public class IntOrFloatConverter : JsonConverter { private readonly string _fieldName; public IntOrFloatConverter(string fieldName) { _fieldName = fieldName; } public override void WriteJson(JsonWriter writer, int value, JsonSerializer serializer) { throw new NotImplementedException(); } public override int ReadJson(JsonReader reader, Type objectType, int existingValue, bool hasExistingValue, JsonSerializer serializer) { //IL_0014: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Invalid comparison between Unknown and I4 //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (reader.Value == null) { throw new JsonException("Expected number, got null"); } JsonToken tokenType = reader.TokenType; if (tokenType - 8 <= 1) { if ((int)reader.TokenType == 8) { string text = (string)serializer.Context.Context; _logger.LogWarning((object)("Chart '" + text + "' has invalid type " + ((object)reader.TokenType/*cast due to .constrained prefix*/).ToString() + " on field " + _fieldName + " (expected an integer)")); } return (int)Convert.ToDouble(reader.Value); } if ((int)reader.TokenType != 7) { throw new JsonException("Expected number, got " + ((object)reader.TokenType/*cast due to .constrained prefix*/).ToString()); } return Convert.ToInt32(reader.Value); } } private static ManualLogSource _logger = Logger.CreateLogSource("TrombLoader.Compatibility"); } public class ChartData { [JsonConverter(typeof(ChartCompatibility.IntOrFloatConverter), new object[] { "savednotespacing" })] [JsonRequired] public int savednotespacing; [JsonConverter(typeof(ChartCompatibility.IntOrFloatConverter), new object[] { "timesig" })] [JsonRequired] public int timesig; [JsonRequired] public float[][] notes; public List lyrics = new List(); public float[] note_color_start = new float[3] { 1f, 0.21f, 0f }; public float[] note_color_end = new float[3] { 1f, 0.8f, 0.3f }; public float[][] improv_zones = new float[0][]; public float[][] bgdata = new float[0][]; public SavedLevel ToSavedLevel(CustomTrackData data) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown return new SavedLevel { savedleveldata = new List(notes), bgdata = new List(bgdata), improv_zones = new List(improv_zones), endpoint = data.endpoint, lyricspos = lyrics.Select((Lyric lyric) => new float[2] { lyric.bar, 0f }).ToList(), lyricstxt = lyrics.Select((Lyric lyric) => lyric.text).ToList(), note_color_start = note_color_start, note_color_end = note_color_end, savednotespacing = savednotespacing, tempo = data.tempo, timesig = timesig }; } } public class CustomTrack : TromboneTrack, Previewable, FilesystemTrack { public class LoadedCustomTrack : LoadedTromboneTrack, IDisposable, AsyncAudioAware, PauseAware { private readonly CustomTrack _parent; private readonly AbstractBackground _background; public bool CanResume => _background.CanResume; public string trackref => _parent.trackref; public LoadedCustomTrack(CustomTrack parent, AbstractBackground background) { _parent = parent; _background = background; } public TrackAudio LoadAudio() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown string path = Path.Combine(_parent.folderPath, Globals.defaultAudioName); IEnumerator audioClipSync = Plugin.Instance.GetAudioClipSync(path); while (audioClipSync.MoveNext()) { object current = audioClipSync.Current; AudioClip val = (AudioClip)((current is AudioClip) ? current : null); if (val == null) { if (!(current is string message)) { continue; } Plugin.LogError(message); return null; } return new TrackAudio(val, 1f); } Plugin.LogError("Failed to load audio"); return null; } YieldTask> AsyncAudioAware.LoadAudio() { YieldTask> val = Unity.loadAudioClip(Path.Combine(_parent.folderPath, Globals.defaultAudioName), (AudioType)14); return Coroutines.map, FSharpResult>(FuncConvert.FromFunc, FSharpResult>((Func, FSharpResult>)((FSharpResult res) => ResultModule.Map(FuncConvert.FromFunc((Func)((AudioClip clip) => new TrackAudio(clip, 1f))), res))), val); } public GameObject LoadBackground(BackgroundContext ctx) { return _background.Load(ctx); } public void SetUpBackgroundDelayed(BGController controller, GameObject bg) { GameObject obj = GameObject.Find("3dModelCamera"); Camera val = ((obj != null) ? obj.GetComponent() : null); if ((Object)(object)val != (Object)null) { val.clearFlags = (CameraClearFlags)3; } _background.SetUpBackground(controller, bg); controller.tickontempo = false; controller.doBGEffect(_parent._data.backgroundMovement); } public void OnPause(PauseContext ctx) { _background.OnPause(ctx); } public void OnResume(PauseContext ctx) { _background.OnResume(ctx); } public void Dispose() { _background.Dispose(); } } private readonly CustomTrackData _data; private readonly TrackLoader _loader; public string folderPath { get; } public TrackSource source { get; } public string trackref => _data.trackRef; public string trackname_long => _data.name; public string trackname_short => _data.shortName; public string year => _data.year.ToString(); public string artist => _data.author; public string desc => _data.description; public string genre => _data.genre; public int difficulty => _data.difficulty; public int tempo => (int)_data.tempo; public int length => Mathf.FloorToInt(_data.endpoint / (_data.tempo / 60f)); public CustomTrack(string folderPath, CustomTrackData data, TrackLoader loader, TrackSource source) { this.folderPath = folderPath; this.source = source; _data = data; _loader = loader; } [CanBeNull] public ExtraData GetCustomData(Identifier identifier) { if (!_data.custom_data.TryGetValue(identifier, out var value)) { return null; } return new ExtraData(identifier, value); } public SavedLevel LoadChart() { return _loader.LoadChartData(folderPath, _data); } public LoadedTromboneTrack LoadTrack() { return (LoadedTromboneTrack)(object)new LoadedCustomTrack(this, LoadBackground()); } public YieldTask> LoadClip() { string text = Path.Combine(folderPath, Globals.defaultPreviewName); if (!File.Exists(text)) { text = Path.Combine(folderPath, Globals.defaultAudioName); } YieldTask> val = Unity.loadAudioClip(text, (AudioType)14); return Coroutines.map, FSharpResult>(FuncConvert.FromFunc, FSharpResult>((Func, FSharpResult>)((FSharpResult res) => ResultModule.Map(FuncConvert.FromFunc((Func)((AudioClip clip) => new TrackAudio(clip, 0.9f))), res))), val); } private AbstractBackground LoadBackground() { if (File.Exists(Path.Combine(folderPath, "bg.trombackground"))) { return new CustomBackground(AssetBundle.LoadFromFile(Path.Combine(folderPath, "bg.trombackground")), folderPath); } string text = Path.Combine(folderPath, "bg.mp4"); if (File.Exists(text) && (!GlobalVariables.turbomode || !Plugin.Instance.turboBackgroundFallback.Value)) { return new VideoBackground(text); } string text2 = Path.Combine(folderPath, "bg.png"); if (File.Exists(text2)) { return new ImageBackground(text2); } Plugin.LogWarning("No background for track " + trackref); return new EmptyBackground(); } public bool IsVisible() { return true; } } [JsonObject] public class CustomTrackData { [JsonRequired] public string trackRef; [JsonRequired] public string name; [JsonRequired] public string shortName; [JsonRequired] public string author; [JsonRequired] public string description; [JsonRequired] public float endpoint; [JsonRequired] public int year; [JsonRequired] public string genre; [JsonRequired] public int difficulty; [JsonRequired] public float tempo; public string backgroundMovement = "none"; public Dictionary custom_data = new Dictionary(); } public class ExtraData { private Identifier _identifier; private JObject _contents; public Identifier Identifier => _identifier; public JToken this[string key] => _contents[key]; public ExtraData(Identifier identifier, JObject contents) { _identifier = identifier; _contents = contents; } public JObject GetJsonObject() { return _contents; } } [TypeConverter(typeof(IdentifierTypeConverter))] public class Identifier { private sealed class IdentifierTypeConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(string); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { return new Identifier((string)value); } } private static readonly Regex IdentifierRegex = new Regex("^([a-zA-Z_-]+):([a-zA-Z0-9_-]+)$"); public string Namespace { get; } public string Path { get; } public Identifier(string @namespace, string path) { Namespace = @namespace; Path = path; } [JsonConstructor] public Identifier(string identifier) { Match match = IdentifierRegex.Match(identifier); if (!match.Success) { throw new ArgumentException("Invalid identifier string: " + identifier); } Namespace = match.Groups[1].Value; Path = match.Groups[2].Value; } public override string ToString() { return Namespace + ":" + Path; } public override int GetHashCode() { return (Namespace.GetHashCode() * 397) ^ Path.GetHashCode(); } protected bool Equals(Identifier other) { if (Namespace == other.Namespace) { return Path == other.Path; } return false; } public override bool Equals(object obj) { if (obj == null) { return false; } if (this == obj) { return true; } if (obj.GetType() != GetType()) { return false; } return Equals((Identifier)obj); } public static Identifier Parse(string identifier) { return new Identifier(identifier); } } [JsonObject] public class Lyric { public string text { get; } public float bar { get; } [JsonConstructor] public Lyric(string text, float bar) { this.text = text; this.bar = bar; } } public class TrackLoader : Listener, CustomTrackLoader { private JsonSerializer _serializer = new JsonSerializer(); public LoadingPriority Priority => (LoadingPriority)1; public IEnumerable OnRegisterTracks() { CreateMissingDirectories(); IEnumerable enumerable = GetSearchPaths().SelectMany((string searchPath) => Directory.EnumerateFiles(searchPath, Globals.defaultChartName, SearchOption.AllDirectories)).Select(Path.GetDirectoryName); Stopwatch sw = Stopwatch.StartNew(); foreach (string item in enumerable) { TromboneTrack val = LoadCustomTrack(item, TrackSource.TrombLoader); if (val != null) { yield return val; } } sw.Stop(); Plugin.LogInfo($"Loaded tracks in {sw.Elapsed.TotalSeconds} seconds"); } private TromboneTrack LoadCustomTrack(string songFolder, TrackSource source) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown string text = Path.Combine(songFolder, Globals.defaultChartName); string fileName = Path.GetFileName(songFolder.TrimEnd(new char[1] { '/' })); if (!File.Exists(text)) { return null; } using StreamReader streamReader = File.OpenText(text); JsonTextReader val = new JsonTextReader((TextReader)streamReader); try { CustomTrackData data; try { _serializer.Context = new StreamingContext(StreamingContextStates.File, fileName); data = _serializer.Deserialize((JsonReader)(object)val); } catch (Exception ex) { Plugin.LogWarning("Unable to deserialize JSON of custom chart: " + text); Plugin.LogWarning(ex.Message); return null; } return (TromboneTrack)(object)new CustomTrack(songFolder, data, this, source); } finally { ((IDisposable)val)?.Dispose(); } } public SavedLevel LoadChartData(string folderPath, CustomTrackData data) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown using StreamReader streamReader = File.OpenText(Path.Combine(folderPath, Globals.defaultChartName)); JsonTextReader val = new JsonTextReader((TextReader)streamReader); try { _serializer.Context = new StreamingContext(StreamingContextStates.File, data.trackRef); return _serializer.Deserialize((JsonReader)(object)val)?.ToSavedLevel(data); } finally { ((IDisposable)val)?.Dispose(); } } private string[] GetSearchPaths() { return new string[2] { Globals.GetCustomSongsPath(), Paths.PluginPath }; } private static void CreateMissingDirectories() { if (!Directory.Exists(Globals.GetCustomSongsPath())) { Directory.CreateDirectory(Globals.GetCustomSongsPath()); } } public FSharpOption LoadTrack(string folderPath) { return OptionModule.OfObj(LoadCustomTrack(folderPath, TrackSource.Other)); } } public enum TrackSource { TrombLoader, Other } public class TrombLoaderCollection : BaseTromboneCollection { internal class CollectionLoader(Plugin plugin) : Listener { public IEnumerable OnRegisterCollections() { yield return (TromboneCollection)(object)new TrombLoaderCollection(plugin); } } private readonly Plugin _plugin; public override string folder => "BepInEx/CustomSongs"; public TrombLoaderCollection(Plugin plugin) : base("TrombLoader", "TrombLoader Tracks", "Custom tracks loaded by TrombLoader") { _plugin = plugin; } public override IEnumerable BuildTrackList() { return ((IEnumerable)TrackLookup.allTracks()).Where((TromboneTrack track) => track is CustomTrack customTrack && customTrack.source == TrackSource.TrombLoader); } public override YieldTask> LoadSprite() { return Unity.loadTexture(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)_plugin).Info.Location), "Assets", "collection.png")).Select>((Func, FSharpResult>)((FSharpResult result) => ResultModule.Map(FuncConvert.FromFunc((Func)((Texture2D tex) => Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), Vector2.zero))), result))); } } } namespace TrombLoader.CustomTracks.Backgrounds { public abstract class AbstractBackground : IDisposable, PauseAware { protected AssetBundle Bundle; public abstract bool CanResume { get; } protected AbstractBackground(AssetBundle bundle) { Bundle = bundle; } public abstract GameObject Load(BackgroundContext ctx); public abstract void SetUpBackground(BGController controller, GameObject bg); public abstract void OnPause(PauseContext ctx); public abstract void OnResume(PauseContext ctx); public virtual void Dispose() { if ((Object)(object)Bundle != (Object)null) { Bundle.Unload(false); } } } public class CustomBackground : AbstractBackground { private string _songPath; private List _pausedVideoPlayers = new List(); private List _pausedParticleSystems = new List(); public override bool CanResume => true; public CustomBackground(AssetBundle bundle, string songPath) : base(bundle) { _songPath = songPath; } public override GameObject Load(BackgroundContext ctx) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_0146: Unknown result type (might be due to invalid IL or missing references) GameObject val = Bundle.LoadAsset("assets/_background.prefab"); if ((int)Application.platform == 1) { LoadShaderBundle(val); } TromboneEventManager[] componentsInChildren = val.GetComponentsInChildren(); TromboneEventManager[] array = componentsInChildren; for (int i = 0; i < array.Length; i++) { array[i].DeserializeAllGenericEvents(); } val.AddComponent().InitializeInvoker(ctx.controller, componentsInChildren); VideoPlayer[] componentsInChildren2 = val.GetComponentsInChildren(); foreach (VideoPlayer val2 in componentsInChildren2) { if (val2.url != null && val2.url.Contains("SERIALIZED_OUTSIDE_BUNDLE")) { string path = val2.url.Replace("SERIALIZED_OUTSIDE_BUNDLE/", ""); string url = Path.Combine(_songPath, path); val2.url = url; } } Transform child = val.transform.GetChild(1); while (child.childCount < 8) { new GameObject("Filler").transform.SetParent(child); } while (((Component)val.transform.GetChild(0)).GetComponentsInChildren().Length < 2) { GameObject val3 = new GameObject("Filler"); val3.AddComponent(); val3.transform.SetParent(val.transform.GetChild(0)); } if (val.transform.childCount < 3) { new GameObject("ConfettiHolder").transform.SetParent(val.transform); } Canvas component = ((Component)ctx.controller.bottombreath.transform.parent.parent).GetComponent(); if ((Object)(object)component != (Object)null) { component.planeDistance = 2f; } GameObject obj = GameObject.Find("GameplayCam"); Camera val4 = ((obj != null) ? obj.GetComponent() : null); if ((Object)(object)val4 != (Object)null) { val4.depth = 99f; } Transform val5 = val.transform.Find("RemoveDefaultLights"); if (Object.op_Implicit((Object)(object)val5)) { Light[] array2 = Object.FindObjectsOfType(); for (int i = 0; i < array2.Length; i++) { ((Behaviour)array2[i]).enabled = false; } ((Component)val5).gameObject.AddComponent(); } if (Object.op_Implicit((Object)(object)val.transform.Find("AddShadows"))) { QualitySettings.shadows = (ShadowQuality)2; QualitySettings.shadowDistance = 100f; } return val; } public override void SetUpBackground(BGController controller, GameObject bg) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) GameController gamecontroller = controller.gamecontroller; VideoPlayer[] componentsInChildren = bg.GetComponentsInChildren(); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].Prepare(); } BackgroundPuppetController backgroundPuppetController = bg.AddComponent(); TrombonerPlaceholder[] componentsInChildren2 = bg.GetComponentsInChildren(); foreach (TrombonerPlaceholder trombonerPlaceholder in componentsInChildren2) { int num = ((trombonerPlaceholder.TrombonerType == TrombonerType.DoNotOverride) ? gamecontroller.puppetnum : ((int)trombonerPlaceholder.TrombonerType)); foreach (Transform item in ((Component)trombonerPlaceholder).transform) { Transform val = item; if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(false); } } GameObject val2 = new GameObject("RealizedTromboner"); val2.transform.SetParent(((Component)trombonerPlaceholder).transform); val2.transform.SetSiblingIndex(0); val2.transform.localPosition = new Vector3(-0.7f, 0.45f, -1.25f); val2.transform.localEulerAngles = new Vector3(0f, 0f, 0f); ((Component)trombonerPlaceholder).transform.Rotate(new Vector3(0f, 19f, 0f)); val2.transform.localScale = Vector3.one; if (num > 3 && num != 8) { val2.transform.localPosition = new Vector3(-0.7f, 0.35f, -1.25f); } GameObject val3 = new GameObject("TromboneTextureRefs"); val3.transform.SetParent(val2.transform); val3.transform.SetSiblingIndex(0); val3.AddComponent().trombmaterials = ((Component)gamecontroller.modelparent.transform.GetChild(0)).GetComponent().trombmaterials; GameObject obj = Object.Instantiate(gamecontroller.playermodels[num], val2.transform, true); obj.transform.localScale = Vector3.one; Tromboner tromboner = new Tromboner(obj, trombonerPlaceholder); obj.AddComponent().Tromboner = tromboner; backgroundPuppetController.Tromboners.Add(tromboner); tromboner.controller.setTromboneTex((trombonerPlaceholder.TromboneSkin == TromboneSkin.DoNotOverride) ? gamecontroller.textureindex : ((int)trombonerPlaceholder.TromboneSkin)); if (trombonerPlaceholder.TrombonerOutfit == TrombonerOutfit.Christmas) { Material[] materials = ((Renderer)tromboner.controller.bodymesh).materials; materials[0] = tromboner.controller.costume_alt; ((Renderer)tromboner.controller.bodymesh).materials = materials; } int num2 = ((trombonerPlaceholder.TromboneHat == TromboneHat.DoNotOverride) ? GlobalVariables.chosen_hat : ((int)trombonerPlaceholder.TromboneHat)); if (num2 > 0) { GameObject obj2 = Object.Instantiate(gamecontroller.hats[num2 - 1], ((Component)tromboner.controller.bellmesh).transform, false); obj2.transform.localPosition = new Vector3(0.189f, 0.332f, 0.309f); obj2.transform.localEulerAngles = new Vector3(0f, 0f, 45f); obj2.transform.localScale = new Vector3(0.12f, 0.12f, 0.2f); } if (GlobalVariables.show_long_trombone && trombonerPlaceholder.TromboneLength == TromboneLength.DoNotOverride) { trombonerPlaceholder.TromboneLength = TromboneLength.Long; } switch (trombonerPlaceholder.TromboneLength) { case TromboneLength.Short: tromboner.controller.tube_distance = 1.1f; tromboner.controller.p_tube.transform.localScale = new Vector3(1f, 1f, 1f); break; case TromboneLength.Long: tromboner.controller.tube_distance = 3.57f; tromboner.controller.p_tube.transform.localScale = new Vector3(1f, 1f, 2.25f); break; } if (GlobalVariables.show_toot_rainbow && (GlobalVariables.localsave.cardcollectionstatus[36] >= 10 || GlobalVariables.localsave.cardcollectionstatus_gold[36] > 0)) { tromboner.controller.show_rainbow = true; } if (tromboner.placeholder.DanceMode == TrombonerDanceMode.DoNotOverride && GlobalVariables.localsave.manual_dance) { tromboner.placeholder.DanceMode = TrombonerDanceMode.ManualDance; } } } private IEnumerable GetPauseableBehaviours(PauseContext ctx) { Animator[] componentsInChildren = ctx.backgroundObj.GetComponentsInChildren(); for (int i = 0; i < componentsInChildren.Length; i++) { yield return (Behaviour)(object)componentsInChildren[i]; } Animation[] componentsInChildren2 = ctx.backgroundObj.GetComponentsInChildren(); for (int i = 0; i < componentsInChildren2.Length; i++) { yield return (Behaviour)(object)componentsInChildren2[i]; } PlayableDirector[] componentsInChildren3 = ctx.backgroundObj.GetComponentsInChildren(); for (int i = 0; i < componentsInChildren3.Length; i++) { yield return (Behaviour)(object)componentsInChildren3[i]; } CinemachineDollyCart[] componentsInChildren4 = ctx.backgroundObj.GetComponentsInChildren(); for (int i = 0; i < componentsInChildren4.Length; i++) { yield return (Behaviour)(object)componentsInChildren4[i]; } } public override void OnPause(PauseContext ctx) { foreach (Behaviour pauseableBehaviour in GetPauseableBehaviours(ctx)) { pauseableBehaviour.enabled = false; } VideoPlayer[] componentsInChildren = ctx.backgroundObj.GetComponentsInChildren(); foreach (VideoPlayer val in componentsInChildren) { if (val.isPlaying) { val.Pause(); _pausedVideoPlayers.Add(val); } } ParticleSystem[] componentsInChildren2 = ctx.backgroundObj.GetComponentsInChildren(); foreach (ParticleSystem val2 in componentsInChildren2) { if (val2.isPlaying) { val2.Pause(); _pausedParticleSystems.Add(val2); } } } public override void OnResume(PauseContext ctx) { foreach (Behaviour pauseableBehaviour in GetPauseableBehaviours(ctx)) { pauseableBehaviour.enabled = true; } foreach (VideoPlayer pausedVideoPlayer in _pausedVideoPlayers) { pausedVideoPlayer.Play(); } foreach (ParticleSystem pausedParticleSystem in _pausedParticleSystems) { pausedParticleSystem.Play(); } _pausedVideoPlayers.Clear(); _pausedParticleSystems.Clear(); } public override void Dispose() { _pausedVideoPlayers.Clear(); base.Dispose(); } private void LoadShaderBundle(GameObject bg) { Dictionary dictionary = new Dictionary(Plugin.Instance.ShaderHelper.BaseGameShaderCache); foreach (KeyValuePair item in Plugin.Instance.ShaderHelper.ShaderCache) { if (!dictionary.ContainsKey(item.Key)) { dictionary.Add(item.Key, item.Value); } } foreach (KeyValuePair item2 in Plugin.Instance.ShaderHelper.LoadShaderBundleFromPath(_songPath + "/")) { dictionary[item2.Key] = item2.Value; } foreach (Material item3 in new IEnumerable[3] { bg.GetComponentsInChildren(true).SelectMany((Renderer renderer) => renderer.materials), from textMesh in bg.GetComponentsInChildren(true) select textMesh.fontSharedMaterial, from graphics in bg.GetComponentsInChildren(true) select graphics.material }.SelectMany((IEnumerable x) => x)) { if (!((Object)(object)item3 == (Object)null) && !((Object)(object)item3.shader == (Object)null) && !(((Object)item3.shader).name == "Standard")) { if (dictionary.TryGetValue(((Object)item3.shader).name, out var value)) { item3.shader = value; Plugin.LogDebug("Replacing shader on " + ((Object)item3).name + " (" + ((Object)value).name + ")"); } else { Plugin.LogDebug("Could not find shader on " + ((Object)item3).name + " (" + ((Object)item3.shader).name + ")"); } } } } } public class EmptyBackground : HijackedBackground { public override bool CanResume => true; public override void SetUpBackground(BGController controller, GameObject bg) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) switch (Plugin.Instance.DefaultBackground.Value) { case "grey": DisableParts(bg); break; case "black": bg.GetComponent().backgroundColor = Color.black; DisableParts(bg); break; default: controller.songname = "freeplay"; break; case "freeplay-static": break; } } public override void OnPause(PauseContext ctx) { } public override void OnResume(PauseContext ctx) { } } public abstract class HijackedBackground : AbstractBackground { protected HijackedBackground() : base(AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/trackassets/freeplay/contentbundle")) { } public override GameObject Load(BackgroundContext ctx) { return Bundle.LoadAsset("BGCam_freeplay"); } protected void DisableParts(GameObject bg) { GameObject gameObject = ((Component)bg.transform.GetChild(0)).gameObject; GameObject gameObject2 = ((Component)bg.transform.GetChild(0).GetChild(1)).gameObject; GameObject gameObject3 = ((Component)bg.transform.GetChild(0).GetChild(0)).gameObject; GameObject gameObject4 = ((Component)bg.transform.GetChild(1)).gameObject; gameObject.SetActive(false); gameObject2.SetActive(false); gameObject3.SetActive(false); gameObject4.SetActive(false); } } public class ImageBackground : HijackedBackground { private readonly string _imagePath; public override bool CanResume => true; public ImageBackground(string imagePath) { _imagePath = imagePath; } public override void SetUpBackground(BGController controller, GameObject bg) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) DisableParts(bg); Camera component = bg.GetComponent(); Transform child = bg.transform.GetChild(0); SpriteRenderer component2 = ((Component)child.GetChild(1)).GetComponent(); component2.color = Color.white; component2.sprite = ImageHelper.LoadSpriteFromFile(_imagePath); Rect rect = component2.sprite.rect; float width = ((Rect)(ref rect)).width; rect = component2.sprite.rect; float num = width / ((Rect)(ref rect)).height; float num3; if (num > 1.7778f) { rect = component2.sprite.rect; float num2 = ((Rect)(ref rect)).width / component2.sprite.pixelsPerUnit; num3 = 17.778f / num2; } else { rect = component2.sprite.rect; float num4 = ((Rect)(ref rect)).height / component2.sprite.pixelsPerUnit; num3 = 10f / num4; } ((Component)component2).transform.localScale = Vector3.one * num3; if (num >= 1.7f && num <= 1.78f) { component.backgroundColor = Color.black; } else { Color[] pixels = component2.sprite.texture.GetPixels(); int num5 = pixels.Length; float num6 = 0f; float num7 = 0f; float num8 = 0f; int num9 = ((num5 >= 200) ? ((int)((float)num5 * 0.005f)) : num5); for (int i = 0; i < num5; i += num9) { Color val = pixels[i]; num6 += val.r; num7 += val.g; num8 += val.b; } component.backgroundColor = new Color(num6 / 200f, num7 / 200f, num8 / 200f); } ((Component)child).gameObject.SetActive(true); ((Component)component2).gameObject.SetActive(true); } public override void OnPause(PauseContext ctx) { } public override void OnResume(PauseContext ctx) { } } public class VideoBackground : HijackedBackground { private readonly string _videoPath; private VideoPlayer _videoPlayer; public override bool CanResume => true; public VideoBackground(string videoPath) { _videoPath = videoPath; } public override void SetUpBackground(BGController controller, GameObject bg) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) DisableParts(bg); Transform child = bg.transform.GetChild(0); Transform child2 = child.GetChild(0); ((Component)child).gameObject.SetActive(true); ((Component)child2).gameObject.SetActive(true); ((Component)child2).GetComponent().color = Color.black; _videoPlayer = ((Component)child2).GetComponent() ?? ((Component)child2).gameObject.AddComponent(); _videoPlayer.url = _videoPath; _videoPlayer.isLooping = true; _videoPlayer.playOnAwake = false; _videoPlayer.skipOnDrop = true; _videoPlayer.renderMode = (VideoRenderMode)1; _videoPlayer.targetCamera = ((Component)bg.transform).GetComponent(); ((Behaviour)_videoPlayer).enabled = true; _videoPlayer.Pause(); if (GlobalVariables.practicemode != 1f) { _videoPlayer.playbackSpeed = GlobalVariables.practicemode; } else if (GlobalVariables.turbomode) { _videoPlayer.playbackSpeed = 2f; } ((MonoBehaviour)controller).StartCoroutine((IEnumerator)PlayVideoDelayed(_videoPlayer).GetEnumerator()); } public override void OnPause(PauseContext ctx) { _videoPlayer.Pause(); } public override void OnResume(PauseContext ctx) { _videoPlayer.Play(); } public static IEnumerable PlayVideoDelayed(VideoPlayer videoPlayer) { yield return (YieldInstruction)new WaitForSeconds(2.4f); if ((Object)(object)videoPlayer != (Object)null) { videoPlayer.Play(); } } } }