RUMBLE does not support other mod managers. If you want to use a manager, you must use the RUMBLE Mod Manager, a manager specifically designed for this game.
Decompiled source of SketchbookPlus v1.1.3
Mods/SketchbookPlus.dll
Decompiled a month agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppRUMBLE.Managers; using Il2CppRUMBLE.Players; using Il2CppRUMBLE.Utilities; using MelonLoader; using RumbleModUI; using RumbleModdingAPI; using SketchbookPlus; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(main), "SketchbookPlus", "1.1.3", "UlvakSkillz", null)] [assembly: MelonGame("Buckethead Entertainment", "RUMBLE")] [assembly: MelonColor(255, 195, 0, 255)] [assembly: MelonAuthorColor(255, 195, 0, 255)] [assembly: VerifyLoaderVersion(0, 6, 6, true)] [assembly: AssemblyDescription("")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("3b03f008-9dbb-4382-a110-b59ee8b632ca")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("SketchbookPlus")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+e85fbc15b6d79f896c25c2452e9a356c4f0a149f")] [assembly: AssemblyProduct("SketchbookPlus")] [assembly: AssemblyTitle("SketchbookPlus")] [assembly: AssemblyVersion("1.0.0.0")] namespace SketchbookPlus; public static class BuildInfo { public const string ModName = "SketchbookPlus"; public const string ModVersion = "1.1.3"; public const string Author = "UlvakSkillz"; } public class main : MelonMod { [CompilerGenerated] private sealed class <Wait>d__29 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public main <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Wait>d__29(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (Mods.findOwnMod("CloneBending", "1.0.0", false)) { <>2__current = (object)new WaitForSeconds(11f); <>1__state = 1; return true; } break; case 1: <>1__state = -1; break; } if (<>4__this.currentScene == "Gym") { if (!<>4__this.randomizerInit) { <>4__this.setupRandomizer(); } <>4__this.Save(); } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static Mod SketchbookPlus = new Mod(); private string currentScene = "Loader"; private Random random = new Random(DateTime.Now.Millisecond * DateTime.Now.Second * DateTime.Now.Minute); private List<string> acceptedFiles = new List<string>(); private List<string> failedFiles = new List<string>(); private List<string> pendingFiles = new List<string>(); private List<string> acceptedFilesTexts = new List<string>(); private List<string> pendingFilesTexts = new List<string>(); private List<List<int>> acceptedItems = new List<List<int>>(); private bool randomizerInit = false; private int lastOutfit = -1; private bool debug = false; private void Log(string msg) { MelonLogger.Msg(msg); } private void debugLog(string msg) { if (debug) { MelonLogger.Msg("-" + msg); } } public override void OnLateInitializeMelon() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Expected O, but got Unknown //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Expected O, but got Unknown //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Expected O, but got Unknown //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown if (!Directory.Exists("UserData\\SketchbookPlus")) { Directory.CreateDirectory("UserData\\SketchbookPlus"); } if (!File.Exists("UserData\\SketchbookPlus\\BlackListedItems.txt")) { saveFile("", "UserData\\SketchbookPlus\\BlackListedItems.txt", addAcceptedFile: false); } SketchbookPlus.ModName = "SketchbookPlus"; SketchbookPlus.ModVersion = "1.1.3"; SketchbookPlus.SetFolder("SketchbookPlus"); SketchbookPlus.AddToList("Save Outfit", false, 0, "Set to True and Save to Store the Equipped Outfit", new Tags { DoNotSave = true }); SketchbookPlus.AddToList("Saved Outfit Name", "DefaultName", "File Name To Save Under", new Tags()); SketchbookPlus.AddToList("Load Outfit", false, 1, "(Sets in Gym) Set to True and Save to Load the Selected Outfit", new Tags()); SketchbookPlus.AddToList("Outfit Name to Load", "DefaultName", "Outfit to Load from File", new Tags()); SketchbookPlus.AddToList("Random Outfit from Files", false, 1, "(Sets in Gym) Selects a Random Outfit from Saved Outfit Files", new Tags()); SketchbookPlus.AddToList("Randomizer: Identity", false, 0, "On/Off Toggle for Randomizing Identity", new Tags()); SketchbookPlus.AddToList("Randomizer: Armor Colors", true, 0, "On/Off Toggle for Randomizing Armor Colors", new Tags()); SketchbookPlus.AddToList("Randomizer: Armor Items", false, 0, "On/Off Toggle for Randomizing Armor Items", new Tags()); SketchbookPlus.AddToList("Randomizer: Markings", false, 0, "On/Off Toggle for Randomizing Markings", new Tags()); SketchbookPlus.AddToList("Set Random Outfit", false, 1, "(Sets in Gym) Sets the Player to a Randomized Outfit from the Randomizer Selections", new Tags()); SketchbookPlus.AddToList("Update Files Texts", false, 0, "Set to True to refresh the Mod's Data from Files", new Tags { DoNotSave = true }); SketchbookPlus.GetFromFile(); UI.instance.UI_Initialized += UIInit; SketchbookPlus.ModSaved += Save; Calls.onMapInitialized += mapInit; pendingFiles.Clear(); acceptedFiles.Clear(); failedFiles.Clear(); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { currentScene = sceneName; debugLog("Loading Scene: " + currentScene); } private void UIInit() { UI.instance.AddMod(SketchbookPlus); } private void Save() { //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown debugLog("Main Method Running"); bool flag = (bool)SketchbookPlus.Settings[0].SavedValue; string text = (string)SketchbookPlus.Settings[1].SavedValue; bool flag2 = (bool)SketchbookPlus.Settings[2].SavedValue; string text2 = (string)SketchbookPlus.Settings[3].SavedValue; bool flag3 = (bool)SketchbookPlus.Settings[4].SavedValue; bool flag4 = (bool)SketchbookPlus.Settings[5].SavedValue; bool flag5 = (bool)SketchbookPlus.Settings[6].SavedValue; bool flag6 = (bool)SketchbookPlus.Settings[7].SavedValue; bool flag7 = (bool)SketchbookPlus.Settings[8].SavedValue; bool flag8 = (bool)SketchbookPlus.Settings[9].SavedValue; PlayerVisualData visualData = Singleton<PlayerManager>.instance.localPlayer.Data.VisualData; PlayerVisualData val = new PlayerVisualData(visualData); int[] array = new int[acceptedItems.Count]; SketchbookPlus.Settings[0].Value = false; SketchbookPlus.Settings[0].SavedValue = false; if ((bool)SketchbookPlus.Settings[10].SavedValue) { debugLog("Clearing Known Files"); SketchbookPlus.Settings[10].Value = false; SketchbookPlus.Settings[10].SavedValue = false; pendingFiles.Clear(); acceptedFiles.Clear(); failedFiles.Clear(); } debugLog("Rechecking Files"); recheckFiles(); debugLog("Done Rechecking Files"); if (!text.ToLower().EndsWith(".txt")) { text += ".txt"; } if (!text2.ToLower().EndsWith(".txt")) { text2 += ".txt"; } if (flag8) { debugLog("Starting Randomizer"); string[] array2 = getOutfitString(visualData).Split(","); debugLog("Got Original Outfit"); string[] array3 = new string[array2.Length]; int[] array4 = new int[20] { 0, 1, 2, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 58, 59, 60, 61, 62, 63, 64 }; int[] array5 = new int[6] { 3, 4, 5, 6, 7, 8 }; int[] array6 = new int[30] { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57 }; int[] array7 = new int[9] { 19, 20, 21, 22, 23, 24, 25, 26, 27 }; for (int i = 0; i < array2.Length; i++) { array3[i] = array2[i]; } for (int j = 0; j < array4.Length + array5.Length + array6.Length + array7.Length; j++) { if ((flag4 && array4.Contains(j)) || (flag5 && array5.Contains(j)) || (flag6 && array7.Contains(j)) || (flag7 && array6.Contains(j))) { array3[j] = acceptedItems[j][random.Next(0, acceptedItems[j].Count)].ToString(); } } setPVD(visualData, array3); Log("Randomizer Outfit Set: " + getOutfitString(visualData)); } else if (flag) { debugLog("Saving Outfit: UserData\\SketchbookPlus\\" + text); string outfitString = getOutfitString(Singleton<PlayerManager>.instance.localPlayer.Data.VisualData); debugLog("File Text: " + outfitString); saveFile(outfitString, "UserData\\SketchbookPlus\\" + text); } else { if (!(currentScene == "Gym")) { return; } if (flag3 && acceptedFiles.Count > 0) { int num = random.Next(0, acceptedFiles.Count); while (num == lastOutfit && acceptedFiles.Count > 1) { num = random.Next(0, acceptedFiles.Count); } debugLog("Loading Random: " + acceptedFiles[num]); loadOutfit(acceptedFiles[num]); lastOutfit = num; } else if (flag2) { debugLog("Loading Selected: " + text2); loadOutfit("UserData\\SketchbookPlus\\" + text2); } } } private void recheckFiles() { string[] files = Directory.GetFiles("UserData\\SketchbookPlus"); string[] array = files; foreach (string text in array) { if (!(text == "UserData\\SketchbookPlus\\Settings.txt") && !(text == "UserData\\SketchbookPlus\\BlackListedItems.txt") && !failedFiles.Contains(text) && !acceptedFiles.Contains(text)) { debugLog("Pending File: " + text); pendingFiles.Add(text); } } loadFileTexts(); while (pendingFiles.Count > 0) { if (!CheckFileValidity(pendingFiles[0])) { Log("Removing Bad File: " + pendingFiles[0]); Log("Removing Bad File's Text: " + pendingFilesTexts[0]); failedFiles.Add(pendingFiles[0]); pendingFiles.Remove(pendingFiles[0]); pendingFilesTexts.RemoveAt(0); } else { debugLog("Accepting file: " + pendingFiles[0]); acceptedFiles.Add(pendingFiles[0]); acceptedFilesTexts.Add(pendingFilesTexts[0]); pendingFiles.Remove(pendingFiles[0]); pendingFilesTexts.RemoveAt(0); } } } private void saveFile(string textToSave, string file, bool addAcceptedFile = true) { if (!File.Exists(file)) { acceptedFiles.Add(file); } FileStream fileStream = File.Create(file); byte[] bytes = Encoding.UTF8.GetBytes(textToSave); fileStream.Write(bytes); fileStream.Close(); fileStream.Dispose(); Log("Saving " + file + " Complete"); } private void setupRandomizer() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown debugLog("Setting Up Randomizer"); PlayerVisualData visualData = Singleton<PlayerManager>.instance.localPlayer.Data.VisualData; PlayerVisualData val = new PlayerVisualData(visualData); setPVD(val, visualData); string outfitString = getOutfitString(visualData); string[] array = outfitString.Split(","); int[] array2 = new int[65] { 21, 23, 19, 23, 13, 17, 23, 15, 23, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 3, 8, 2, 2, 4, 4, 4, 3, 3, 7, 5, 6, 3, 3, 3, 3, 6, 78, 0, 29, 29, 29, 29, 29, 24, 24, 24, 24, 24, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 5, 3, 4, 3, 4 }; int[] array3 = new int[array2.Length]; for (int i = 0; i < array2.Length; i++) { array3[i] = int.Parse(array[i]); } for (int j = 0; j < array2.Length; j++) { List<int> list = new List<int>(); string text = "Spot " + j + ": "; for (int k = 0; k <= array2[j]; k++) { array3[j] = k; string[] array4 = new string[array3.Length]; for (int l = 0; l < array4.Length; l++) { array4[l] = array3[l].ToString(); } setPVD(val, array4); if (checkItems(val.ToPlayfabDataString(), isSilent: true)) { list.Add(k); text = text + k + ", "; } } acceptedItems.Add(list); debugLog(text); for (int m = 0; m < array2.Length; m++) { array3[m] = int.Parse(array[m]); } } setupBlackList(); debugLog("Randomizer Setup"); randomizerInit = true; } private void setupBlackList() { string[] array = File.ReadAllLines("UserData\\SketchbookPlus\\BlackListedItems.txt"); try { string[] array2 = array; foreach (string text in array2) { string[] array3 = text.Split(","); if (acceptedItems[int.Parse(array3[0])].Remove(int.Parse(array3[1]))) { Log("Removed Item: " + text); } } } catch { MelonLogger.Error("Error Reading BlackList File"); } } private string getOutfitString(PlayerVisualData pvd) { string text = ""; for (int i = 0; i < ((Il2CppArrayBase<short>)(object)pvd.ColorationIndexes).Count; i++) { text = text + ((Il2CppArrayBase<short>)(object)pvd.ColorationIndexes)[i] + ","; } for (int j = 0; j < ((Il2CppArrayBase<short>)(object)pvd.CustomizationPartIndexes).Count; j++) { text = text + ((Il2CppArrayBase<short>)(object)pvd.CustomizationPartIndexes)[j] + ","; } for (int k = 0; k < ((Il2CppArrayBase<short>)(object)pvd.OtherCustomizationIndexes).Count; k++) { text = text + ((Il2CppArrayBase<short>)(object)pvd.OtherCustomizationIndexes)[k] + ","; } for (int l = 0; l < ((Il2CppArrayBase<short>)(object)pvd.TextureCustomizationIndexes).Count; l++) { text = text + ((Il2CppArrayBase<short>)(object)pvd.TextureCustomizationIndexes)[l] + ","; } for (int m = 0; m < ((Il2CppArrayBase<short>)(object)pvd.TextureOpacityIndexes).Count; m++) { text = text + ((Il2CppArrayBase<short>)(object)pvd.TextureOpacityIndexes)[m] + ","; } for (int n = 0; n < ((Il2CppArrayBase<short>)(object)pvd.WeightAdjustementIndexes).Count; n++) { text += ((Il2CppArrayBase<short>)(object)pvd.WeightAdjustementIndexes)[n]; if (n != ((Il2CppArrayBase<short>)(object)pvd.WeightAdjustementIndexes).Count - 1) { text += ","; } } return text; } private void loadOutfit(string fileName) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown if (acceptedFiles.IndexOf(fileName) == -1) { MelonLogger.Error("Not An Accepted File: " + fileName); return; } Log("Text: " + acceptedFilesTexts[acceptedFiles.IndexOf(fileName)]); string[] data = acceptedFilesTexts[acceptedFiles.IndexOf(fileName)].Split(','); PlayerVisualData visualData = Singleton<PlayerManager>.instance.localPlayer.Data.VisualData; PlayerVisualData val = new PlayerVisualData(visualData); setPVD(val, data); if (checkItems(val.ToPlayfabDataString())) { debugLog("Setting PVD Now"); setPVD(visualData, val); Log("Loaded Outfit for Next Scene: " + fileName); } } private bool CheckFileValidity(string fileName) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown string[] data = pendingFilesTexts[pendingFiles.IndexOf(fileName)].Split(','); PlayerVisualData val = new PlayerVisualData(Singleton<PlayerManager>.instance.localPlayer.Data.VisualData); try { setPVD(val, data); } catch { Log("Invalid File Text"); return false; } return checkItems(val.ToPlayfabDataString()); } private void setPVD(PlayerVisualData pvd, string[] data) { int num = 0; for (int i = 0; i < ((Il2CppArrayBase<short>)(object)pvd.ColorationIndexes).Count; i++) { ((Il2CppArrayBase<short>)(object)pvd.ColorationIndexes)[i] = short.Parse(data[num]); num++; } for (int j = 0; j < ((Il2CppArrayBase<short>)(object)pvd.CustomizationPartIndexes).Count; j++) { ((Il2CppArrayBase<short>)(object)pvd.CustomizationPartIndexes)[j] = short.Parse(data[num]); num++; } for (int k = 0; k < ((Il2CppArrayBase<short>)(object)pvd.OtherCustomizationIndexes).Count; k++) { ((Il2CppArrayBase<short>)(object)pvd.OtherCustomizationIndexes)[k] = short.Parse(data[num]); num++; } for (int l = 0; l < ((Il2CppArrayBase<short>)(object)pvd.TextureCustomizationIndexes).Count; l++) { ((Il2CppArrayBase<short>)(object)pvd.TextureCustomizationIndexes)[l] = short.Parse(data[num]); num++; } for (int m = 0; m < ((Il2CppArrayBase<short>)(object)pvd.TextureOpacityIndexes).Count; m++) { ((Il2CppArrayBase<short>)(object)pvd.TextureOpacityIndexes)[m] = short.Parse(data[num]); num++; } for (int n = 0; n < ((Il2CppArrayBase<short>)(object)pvd.WeightAdjustementIndexes).Count; n++) { ((Il2CppArrayBase<short>)(object)pvd.WeightAdjustementIndexes)[n] = short.Parse(data[num]); num++; } } private void setPVD(PlayerVisualData pvdTo, PlayerVisualData pvdFrom) { for (int i = 0; i < ((Il2CppArrayBase<short>)(object)pvdTo.ColorationIndexes).Count; i++) { ((Il2CppArrayBase<short>)(object)pvdTo.ColorationIndexes)[i] = ((Il2CppArrayBase<short>)(object)pvdFrom.ColorationIndexes)[i]; } for (int j = 0; j < ((Il2CppArrayBase<short>)(object)pvdTo.CustomizationPartIndexes).Count; j++) { ((Il2CppArrayBase<short>)(object)pvdTo.CustomizationPartIndexes)[j] = ((Il2CppArrayBase<short>)(object)pvdFrom.CustomizationPartIndexes)[j]; } for (int k = 0; k < ((Il2CppArrayBase<short>)(object)pvdTo.OtherCustomizationIndexes).Count; k++) { ((Il2CppArrayBase<short>)(object)pvdTo.OtherCustomizationIndexes)[k] = ((Il2CppArrayBase<short>)(object)pvdFrom.OtherCustomizationIndexes)[k]; } for (int l = 0; l < ((Il2CppArrayBase<short>)(object)pvdTo.TextureCustomizationIndexes).Count; l++) { ((Il2CppArrayBase<short>)(object)pvdTo.TextureCustomizationIndexes)[l] = ((Il2CppArrayBase<short>)(object)pvdFrom.TextureCustomizationIndexes)[l]; } for (int m = 0; m < ((Il2CppArrayBase<short>)(object)pvdTo.TextureOpacityIndexes).Count; m++) { ((Il2CppArrayBase<short>)(object)pvdTo.TextureOpacityIndexes)[m] = ((Il2CppArrayBase<short>)(object)pvdFrom.TextureOpacityIndexes)[m]; } for (int n = 0; n < ((Il2CppArrayBase<short>)(object)pvdTo.WeightAdjustementIndexes).Count; n++) { ((Il2CppArrayBase<short>)(object)pvdTo.WeightAdjustementIndexes)[n] = ((Il2CppArrayBase<short>)(object)pvdFrom.WeightAdjustementIndexes)[n]; } } private bool checkItems(string tempPVDEconomyDataString, bool isSilent = false) { string[] array = tempPVDEconomyDataString.Split(':'); bool flag = true; for (int i = 0; i < array.Length; i++) { if (i == 0 || i == 5) { continue; } string[] array2 = array[i].Split(","); string[] array3 = array2; foreach (string text in array3) { if (!Singleton<PlayerManager>.instance.localPlayer.Data.EconomyData.ReceivedItems.Contains(text)) { flag = false; if (!isSilent) { Log("Item Not Redeemed"); } break; } } if (!flag) { break; } } if (flag) { return true; } return false; } private void mapInit() { MelonCoroutines.Start(Wait()); } [IteratorStateMachine(typeof(<Wait>d__29))] private IEnumerator Wait() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Wait>d__29(0) { <>4__this = this }; } private void loadFileTexts() { foreach (string pendingFile in pendingFiles) { string item = File.ReadAllText(pendingFile); pendingFilesTexts.Add(item); } } }