using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using DonkeyCastrator; using Il2Cpp; using Il2CppInterop.Runtime.InteropTypes.Arrays; using MelonLoader; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(Core), "DonkeyCastrator", "1.0.0", "Caleb Orchard", null)] [assembly: MelonGame("DefaultCompany", "BabySteps")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("DonkeyCastrator")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+bc364cca4ff5e2260188c9314b0086602acdd915")] [assembly: AssemblyProduct("DonkeyCastrator")] [assembly: AssemblyTitle("DonkeyCastrator")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace DonkeyCastrator { public class Core : MelonMod { private readonly HashSet reportedInstanceIds = new HashSet(); private readonly HashSet scannedIds = new HashSet(); private readonly Dictionary childCountCache = new Dictionary(); private readonly HashSet discoveredNodeIds = new HashSet(); private readonly Dictionary discoveryChildCountCache = new Dictionary(); private readonly Queue discoveryQueue = new Queue(); private readonly HashSet queuedDiscoveryIds = new HashSet(); private readonly List censorRoots = new List(); private readonly HashSet censorRootIds = new HashSet(); private readonly List censoredTargets = new List(); private readonly HashSet censoredTargetIds = new HashSet(); private float nextScanTime; private float nextDiscoveryTime; private float nextWarningTime; private const float ScanInterval = 1f; private const float DiscoveryInterval = 5f; private const float WarningCooldown = 2f; private const float DiscoveryFrameBudgetMs = 1f; private const int MaxDiscoveryNodesPerFrame = 200; public override void OnInitializeMelon() { ((MelonBase)this).LoggerInstance.Msg("Initialized."); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { DiscoverCensorRoots(force: true); } public override void OnSceneWasUnloaded(int buildIndex, string sceneName) { reportedInstanceIds.Clear(); scannedIds.Clear(); childCountCache.Clear(); discoveredNodeIds.Clear(); discoveryChildCountCache.Clear(); discoveryQueue.Clear(); queuedDiscoveryIds.Clear(); censorRoots.Clear(); censorRootIds.Clear(); censoredTargets.Clear(); censoredTargetIds.Clear(); } public override void OnUpdate() { EnforceCensoredTargets(); float unscaledTime = Time.unscaledTime; if (unscaledTime >= nextDiscoveryTime) { nextDiscoveryTime = unscaledTime + 5f; DiscoverCensorRoots(force: false); } ProcessDiscoveryQueue(); if (!(unscaledTime < nextScanTime)) { nextScanTime = unscaledTime + 1f; ScanKnownRoots(); } } public override void OnLateUpdate() { EnforceCensoredTargets(); } private void ScanKnownRoots() { try { List found = new List(); for (int num = censorRoots.Count - 1; num >= 0; num--) { Transform t = censorRoots[num]; if (!IsLoaded(t)) { censorRoots.RemoveAt(num); } else { CheckObjectRecursive(t, found); } } } catch (Exception ex) { if (Time.unscaledTime >= nextWarningTime) { MelonLogger.Warning("DonkeyCastrator scan error: " + ex.Message); nextWarningTime = Time.unscaledTime + 2f; } } } private void DiscoverCensorRoots(bool force) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (force) { discoveredNodeIds.Clear(); discoveryChildCountCache.Clear(); discoveryQueue.Clear(); queuedDiscoveryIds.Clear(); censorRoots.Clear(); censorRootIds.Clear(); } for (int i = 0; i < SceneManager.sceneCount; i++) { Scene sceneAt = SceneManager.GetSceneAt(i); if (!((Scene)(ref sceneAt)).isLoaded) { continue; } foreach (GameObject item in (Il2CppArrayBase)(object)((Scene)(ref sceneAt)).GetRootGameObjects()) { if (!((Object)(object)item == (Object)null)) { EnqueueForDiscovery(item.transform); } } } } private void ProcessDiscoveryQueue() { if (discoveryQueue.Count == 0) { return; } float realtimeSinceStartup = Time.realtimeSinceStartup; int num = 0; while (discoveryQueue.Count > 0 && num < 200 && !((Time.realtimeSinceStartup - realtimeSinceStartup) * 1000f >= 1f)) { Transform val = discoveryQueue.Dequeue(); if ((Object)(object)val != (Object)null) { queuedDiscoveryIds.Remove(((Object)val).GetInstanceID()); } num++; DiscoverCensorRootsStep(val); } } private void DiscoverCensorRootsStep(Transform t) { if ((Object)(object)t == (Object)null) { return; } int instanceID = ((Object)t).GetInstanceID(); int childCount = t.childCount; if (!discoveredNodeIds.Contains(instanceID) || !discoveryChildCountCache.TryGetValue(instanceID, out var value) || value != childCount) { if ((Object)(object)((Component)t).GetComponent() != (Object)null && censorRootIds.Add(instanceID)) { censorRoots.Add(t); } for (int i = 0; i < childCount; i++) { EnqueueForDiscovery(t.GetChild(i)); } discoveredNodeIds.Add(instanceID); discoveryChildCountCache[instanceID] = childCount; } } private void EnqueueForDiscovery(Transform t) { if (!((Object)(object)t == (Object)null)) { int instanceID = ((Object)t).GetInstanceID(); if (queuedDiscoveryIds.Add(instanceID)) { discoveryQueue.Enqueue(t); } } } private void CheckObjectRecursive(Transform t, List found) { if ((Object)(object)t == (Object)null) { return; } int instanceID = ((Object)t).GetInstanceID(); int childCount = t.childCount; if (reportedInstanceIds.Contains(instanceID)) { EnsureZeroScale(t); CacheScanState(instanceID, childCount); } else { if (scannedIds.Contains(instanceID) && childCountCache.TryGetValue(instanceID, out var value) && value == childCount) { return; } string name = ((Object)((Component)t).gameObject).name; if (name.IndexOf("penis", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("testes", StringComparison.OrdinalIgnoreCase) >= 0) { if (name.IndexOf("Boing", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("Censor", StringComparison.OrdinalIgnoreCase) < 0) { reportedInstanceIds.Add(instanceID); found.Add(name); if (censoredTargetIds.Add(instanceID)) { censoredTargets.Add(t); } EnsureZeroScale(t); } CacheScanState(instanceID, childCount); } else { for (int i = 0; i < childCount; i++) { CheckObjectRecursive(t.GetChild(i), found); } CacheScanState(instanceID, childCount); } } } private void EnforceCensoredTargets() { for (int num = censoredTargets.Count - 1; num >= 0; num--) { Transform t = censoredTargets[num]; if (!IsLoaded(t)) { censoredTargets.RemoveAt(num); } else { EnsureZeroScale(t); } } } private bool IsLoaded(Transform t) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) int result; if ((Object)(object)t != (Object)null) { Scene scene = ((Component)t).gameObject.scene; result = (((Scene)(ref scene)).isLoaded ? 1 : 0); } else { result = 0; } return (byte)result != 0; } private void EnsureZeroScale(Transform t) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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) if (t.localScale != Vector3.zero) { t.localScale = Vector3.zero; } } private void CacheScanState(int id, int childCount) { scannedIds.Add(id); childCountCache[id] = childCount; } } }