The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of BalloonMochi v1.0.1
plugins/com.github.MuttFromMars.BalloonMochi.dll
Decompiled 5 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using PEAKLib.Core; using Photon.Pun; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("com.github.MuttFromMars.BalloonMochi")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("com.github.MuttFromMars.BalloonMochi")] [assembly: AssemblyTitle("BalloonMochi")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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; } } } internal sealed class FreezeUntilFirstPickup : MonoBehaviour { private bool _everPickedUp; private Rigidbody[] _rbs = Array.Empty<Rigidbody>(); private Transform? _spawnParent; private void Awake() { _spawnParent = ((Component)this).transform.parent; Cache(); Freeze(on: true); } private void Start() { EvaluateParent(); } private void OnTransformParentChanged() { EvaluateParent(); } private void EvaluateParent() { if (!_everPickedUp && (Object)(object)((Component)this).transform.parent != (Object)(object)_spawnParent) { _everPickedUp = true; Freeze(on: false); Object.Destroy((Object)(object)this); } } private void Freeze(bool on) { Rigidbody[] rbs = _rbs; foreach (Rigidbody val in rbs) { if (!((Object)(object)val == (Object)null)) { val.isKinematic = on; val.detectCollisions = true; if (on) { val.Sleep(); } } } } private void Cache() { _rbs = ((Component)this).GetComponentsInChildren<Rigidbody>(true); } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BalloonMochi { [BepInPlugin("com.github.MuttFromMars.BalloonMochi", "Balloon Mochi", "1.0.1")] public class PrefabRedirector : BaseUnityPlugin { private sealed class BoxUShort { public ushort V; public BoxUShort(ushort v) { V = v; } } private sealed class RedirectingPool : IPunPrefabPool { private readonly IPunPrefabPool _inner; public RedirectingPool(IPunPrefabPool inner) { _inner = inner; } public GameObject Instantiate(string prefabId, Vector3 pos, Quaternion rot) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) TryMap(ref prefabId); GameObject val = ((_inner != null) ? _inner.Instantiate(prefabId, pos, rot) : null); if ((Object)(object)val == (Object)null) { GameObject val2 = Resources.Load<GameObject>(prefabId) ?? Resources.Load<GameObject>(prefabId + ".prefab"); if ((Object)(object)val2 != (Object)null) { val = Object.Instantiate<GameObject>(val2, pos, rot); } } if ((Object)(object)val != (Object)null && prefabId.Equals("balloonmochi", StringComparison.OrdinalIgnoreCase)) { try { val.AddComponent<FreezeUntilFirstPickup>(); } catch { } } return val; } public void Destroy(GameObject go) { if (_inner != null) { _inner.Destroy(go); } else if ((Object)(object)go != (Object)null) { Object.Destroy((Object)(object)go); } } } [CompilerGenerated] private sealed class <EnsureWrappedPool>d__23 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private int <i>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EnsureWrappedPool>d__23(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <i>5__2 = 0; break; case 1: <>1__state = -1; <i>5__2++; break; } if (<i>5__2 < 120) { IPunPrefabPool prefabPool = PhotonNetwork.PrefabPool; if (prefabPool is RedirectingPool) { return false; } if (prefabPool != null) { PhotonNetwork.PrefabPool = (IPunPrefabPool)(object)new RedirectingPool(prefabPool); return false; } <>2__current = null; <>1__state = 1; return true; } 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(); } } private const ushort TARGET_ITEM_ID = 13; private const string DISPLAY_NAME = "MOCHI"; private const string BUNDLE_FILE = "balloonmochi"; private const string PREFAB_NAME = "BalloonMochi.prefab"; private const string MAT_NAME = "M_BalloonMochi.mat"; private const string ICON_NAME = "balloonmochi_icon"; private const string SHADER_NAME = "W/Character"; private const string MATCH_ICON_NAME = "BingBong"; private static readonly Dictionary<string, string> s_NameRedirectMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "bingbong", "balloonmochi" } }; private AssetBundle? _bundle; private Material? _mat; private Harmony _harmony; internal static ManualLogSource? s_Log; private UnityAction<Scene, Scene>? _sceneChangedHandler; private static Texture2D? s_IconTex; private static int? s_PrefabCarryWeight; private static FieldInfo? s_Field_carryWeight; private static readonly ConditionalWeakTable<ItemUIData, BoxUShort> s_UIToId = new ConditionalWeakTable<ItemUIData, BoxUShort>(); private void Awake() { s_Log = ((BaseUnityPlugin)this).Logger; TryLoadBundleAndRegister(); ((MonoBehaviour)this).StartCoroutine(EnsureWrappedPool()); _sceneChangedHandler = delegate { ((MonoBehaviour)this).StartCoroutine(EnsureWrappedPool()); }; SceneManager.activeSceneChanged += _sceneChangedHandler; Patch(); } private void OnDestroy() { if (_sceneChangedHandler != null) { SceneManager.activeSceneChanged -= _sceneChangedHandler; } s_Log = null; } private void TryLoadBundleAndRegister() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) try { string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); string text = Path.Combine(directoryName, "balloonmochi"); _bundle = (File.Exists(text) ? AssetBundle.LoadFromFile(text) : null); GameObject val = (((Object)(object)_bundle != (Object)null) ? _bundle.LoadAsset<GameObject>("BalloonMochi.prefab") : null); if ((Object)(object)val != (Object)null) { RebindShaders(val); Material val2 = (((Object)(object)_bundle != (Object)null) ? _bundle.LoadAsset<Material>("M_BalloonMochi.mat") : null); Shader val3 = Shader.Find("W/Character"); object obj = this; obj = (object)((!((Object)(object)val3 != (Object)null)) ? ((Material)null) : new Material(val3)); ((PrefabRedirector)obj)._mat = (Material?)obj; if ((Object)(object)_mat != (Object)null && (Object)(object)val2 != (Object)null) { _mat.CopyPropertiesFromMaterial(val2); } if ((Object)(object)_mat != (Object)null) { ApplyMaterial(val, _mat, "HeadTorso", "TongueMouth"); } try { Item component = val.GetComponent<Item>(); if ((Object)(object)component != (Object)null) { if ((object)s_Field_carryWeight == null) { s_Field_carryWeight = AccessTools.Field(typeof(Item), "carryWeight"); } if (s_Field_carryWeight != null && s_Field_carryWeight.FieldType == typeof(int)) { s_PrefabCarryWeight = (int)s_Field_carryWeight.GetValue(component); ManualLogSource? obj2 = s_Log; if (obj2 != null) { obj2.LogInfo((object)$"[BalloonMochi] prefab carryWeight = {s_PrefabCarryWeight}"); } } } } catch (Exception arg) { ManualLogSource? obj3 = s_Log; if (obj3 != null) { obj3.LogWarning((object)$"[BalloonMochi] Failed to capture carryWeight: {arg}"); } } NetworkPrefabManager.RegisterNetworkPrefab("balloonmochi", val); } if ((Object)(object)_bundle != (Object)null) { s_IconTex = _bundle.LoadAsset<Texture2D>("balloonmochi_icon"); _bundle.Unload(false); _bundle = null; } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); } } [IteratorStateMachine(typeof(<EnsureWrappedPool>d__23))] private IEnumerator EnsureWrappedPool() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EnsureWrappedPool>d__23(0); } private static bool TryMap(ref string id) { if (string.IsNullOrEmpty(id)) { return false; } string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(id); if (string.IsNullOrEmpty(fileNameWithoutExtension)) { return false; } if (s_NameRedirectMap.TryGetValue(fileNameWithoutExtension, out string value)) { id = value; return true; } return false; } private void Patch() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Expected O, but got Unknown _harmony = new Harmony("com.github.MuttFromMars.BalloonMochi"); TryPostfix(typeof(Item), "GetName", "Postfix_Item_GetName"); MethodInfo methodInfo = AccessTools.Property(typeof(Item), "CarryWeight")?.GetGetMethod(); if (methodInfo != null) { try { _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(PrefabRedirector), "Postfix_Item_get_CarryWeight", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception arg) { ManualLogSource? obj = s_Log; if (obj != null) { obj.LogWarning((object)$"[BalloonMochi] Failed to patch Item.get_CarryWeight: {arg}"); } } } TryPostfix(typeof(Item), "Awake", "Postfix_Item_Awake"); Type typeFromHandle = typeof(ItemUIData); MethodInfo methodInfo2 = AccessTools.Method(typeFromHandle, "GetIcon", Type.EmptyTypes, (Type[])null); if (methodInfo2 != null) { try { _harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(PrefabRedirector), "Postfix_UIData_GetIcon_Tex", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception arg2) { ManualLogSource? obj2 = s_Log; if (obj2 != null) { obj2.LogWarning((object)$"[BalloonMochi] Failed to patch ItemUIData.GetIcon: {arg2}"); } } } Type type = AccessTools.TypeByName("ItemUI"); MethodInfo methodInfo3 = ((type != null) ? AccessTools.Method(type, "GetIcon", Type.EmptyTypes, (Type[])null) : null); if (!(methodInfo3 != null)) { return; } try { _harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(PrefabRedirector), "Postfix_UI_Fallback_GetIcon_Tex", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception arg3) { ManualLogSource? obj3 = s_Log; if (obj3 != null) { obj3.LogWarning((object)$"[BalloonMochi] Failed to patch ItemUI.GetIcon: {arg3}"); } } } private void TryPostfix(Type t, string name, string postfix) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(t, name, Type.EmptyTypes, (Type[])null); if (methodInfo != null) { try { _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(PrefabRedirector), postfix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); return; } catch (Exception arg) { ManualLogSource? obj = s_Log; if (obj != null) { obj.LogWarning((object)$"[BalloonMochi] Failed to patch {t.FullName}.{name}(): {arg}"); } return; } } ManualLogSource? obj2 = s_Log; if (obj2 != null) { obj2.LogWarning((object)("[BalloonMochi] Method not found: " + t.FullName + "." + name + "()")); } } private static void RebindShaders(GameObject root) { if ((Object)(object)root == (Object)null) { return; } Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if ((Object)(object)val == (Object)null) { continue; } try { Material[] sharedMaterials = val.sharedMaterials; foreach (Material val2 in sharedMaterials) { if (!((Object)(object)val2 == (Object)null)) { Shader val3 = Shader.Find(((Object)(object)val2.shader != (Object)null) ? ((Object)val2.shader).name : "W/Character"); if ((Object)(object)val3 != (Object)null && (Object)(object)val2.shader != (Object)(object)val3) { val2.shader = val3; } } } } catch { } } } private static void ApplyMaterial(GameObject root, Material mat, params string[] targets) { if ((Object)(object)root == (Object)null || (Object)(object)mat == (Object)null || targets == null || targets.Length == 0) { return; } Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if ((Object)(object)val == (Object)null) { continue; } bool flag = false; string text = ((Object)((Component)val).gameObject).name ?? string.Empty; foreach (string value in targets) { if (text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; break; } } if (!flag) { continue; } try { Material[] sharedMaterials = val.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { val.sharedMaterial = mat; continue; } for (int k = 0; k < sharedMaterials.Length; k++) { sharedMaterials[k] = mat; } val.sharedMaterials = sharedMaterials; } catch { } } } public static void Postfix_Item_GetName(Item __instance, ref string __result) { try { if (__instance.itemID == 13) { __result = "MOCHI"; } } catch { } } public static void Postfix_Item_get_CarryWeight(Item __instance, ref int __result) { try { if (s_PrefabCarryWeight.HasValue && __instance.itemID == 13) { int num = 0; try { num = Ascents.itemWeightModifier; } catch { } __result = s_PrefabCarryWeight.Value + num; } } catch { } } public static void Postfix_Item_Awake(Item __instance) { try { if (__instance?.UIData == null) { return; } try { s_UIToId.Remove(__instance.UIData); } catch { } try { s_UIToId.Add(__instance.UIData, new BoxUShort(__instance.itemID)); } catch { } } catch { } } public static void Postfix_UIData_GetIcon_Tex(ItemUIData __instance, ref Texture2D __result) { try { if (!((Object)(object)s_IconTex == (Object)null)) { if (s_UIToId.TryGetValue(__instance, out BoxUShort value) && value != null && value.V == 13) { __result = s_IconTex; } else if ((Object)(object)__result != (Object)null && TextureNameLooksLikeStock(((Object)__result).name)) { __result = s_IconTex; } } } catch { } } private static bool TextureNameLooksLikeStock(string name) { if (string.IsNullOrEmpty(name)) { return false; } if (!name.Equals("BingBong", StringComparison.OrdinalIgnoreCase)) { return name.IndexOf("BingBong", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } public static void Postfix_UI_Fallback_GetIcon_Tex(object __instance, ref Texture2D __result) { try { if (!((Object)(object)s_IconTex == (Object)null) && (Object)(object)__result != (Object)null && TextureNameLooksLikeStock(((Object)__result).name)) { __result = s_IconTex; } } catch { } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }