Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Nobody Telephone Detka v1.0.0
plugins/nobody-telephone-detka.dll
Decompiled 2 months 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.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; 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: AssemblyTitle("телефон детка")] [assembly: AssemblyDescription("Мод для замены звука и текстуры в игре")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCompany("ItsRauga")] [assembly: AssemblyProduct("Телефон детка")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("539FD5FA-E6F8-4644-8538-204B60D9A70C")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("2.0.1")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("2.0.1.0")] namespace smert_v_nishite; public class AudioSourceData { public AudioClip OriginalClip { get; set; } public AudioSource Source { get; private set; } public AudioClip RealClip { get { using (new SpoofBypass()) { return Source.clip; } } set { using (new SpoofBypass()) { Source.clip = value; } } } private AudioSourceData(AudioSource source) { Source = source; } public static AudioSourceData GetOrCreate(AudioSource source) { if (Plugin.audioSourceData.TryGetValue(source, out var value)) { return value; } value = new AudioSourceData(source) { OriginalClip = source.clip }; Plugin.audioSourceData[source] = value; return value; } } [HarmonyPatch(typeof(AudioSource))] public class AudioSourcePatch { [ThreadStatic] internal static bool bypassSpoofing; [HarmonyPrefix] [HarmonyPatch("Play", new Type[] { })] [HarmonyPatch("Play", new Type[] { typeof(ulong) })] [HarmonyPatch("Play", new Type[] { typeof(double) })] private static bool Play(AudioSource __instance) { AudioSourceData orCreate = AudioSourceData.GetOrCreate(__instance); string text = (((Object)(object)orCreate.OriginalClip != (Object)null) ? ((Object)orCreate.OriginalClip).name : ""); AudioClip replacedSound = Plugin.GetReplacedSound(text ?? ""); if ((Object)(object)replacedSound == (Object)null) { return true; } orCreate.RealClip = replacedSound; using (new SpoofBypass()) { __instance.clip = replacedSound; } return true; } [HarmonyPrefix] [HarmonyPatch("PlayOneShot", new Type[] { typeof(AudioClip), typeof(float) })] private static bool PlayOneShot(ref AudioClip clip, float volumeScale) { string text = (((Object)(object)clip != (Object)null) ? ((Object)clip).name : ""); AudioClip replacedSound = Plugin.GetReplacedSound(text ?? ""); if ((Object)(object)replacedSound != (Object)null) { clip = replacedSound; } return true; } [HarmonyPrefix] [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static bool ClipSetter(AudioSource __instance, AudioClip value) { if (bypassSpoofing) { return true; } if (Plugin.audioSourceData.TryGetValue(__instance, out var value2) && (Object)(object)value2.OriginalClip == (Object)(object)value) { return false; } AudioSourceData.GetOrCreate(__instance).OriginalClip = value; return true; } [HarmonyPostfix] [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static void ClipGetter(AudioSource __instance, ref AudioClip __result) { if (!bypassSpoofing && Plugin.audioSourceData.TryGetValue(__instance, out var value) && (Object)(object)value.OriginalClip != (Object)null) { __result = value.OriginalClip; } } } public class SpoofBypass : IDisposable { public SpoofBypass() { AudioSourcePatch.bypassSpoofing = true; } public void Dispose() { AudioSourcePatch.bypassSpoofing = false; } } [BepInPlugin("smert-v-nishite", "Smert v Nishite", "2.0.1")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; internal static AudioClip replacementAudio; internal static Texture2D replacementTexture; internal static Dictionary<AudioSource, AudioSourceData> audioSourceData = new Dictionary<AudioSource, AudioSourceData>(); private static bool textureReplacerInitialized; private void Awake() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) Logger = ((BaseUnityPlugin)this).Logger; LoadEmbeddedResources(); if ((!((Object)(object)replacementAudio == (Object)null) && !((Object)(object)replacementTexture == (Object)null)) || LoadAssetBundle()) { new Harmony("smert-v-nishite").PatchAll(); SceneManager.sceneLoaded += OnSceneLoaded; Logger.LogInfo((object)"Plugin loaded with custom resources!"); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!textureReplacerInitialized) { textureReplacerInitialized = true; GameObject val = new GameObject("TextureReplacer"); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent<TextureReplacer>(); } } private void LoadEmbeddedResources() { //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); string[] array = manifestResourceNames; foreach (string text in array) { if (text.EndsWith(".ogg")) { using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream != null) { byte[] array2 = new byte[stream.Length]; stream.Read(array2, 0, array2.Length); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text); replacementAudio = CreateAudioClipFromBytes(array2, fileNameWithoutExtension); Logger.LogInfo((object)("Loaded sound: " + text)); } } else { if (!text.EndsWith(".png") && !text.EndsWith(".jpg")) { continue; } using Stream stream2 = executingAssembly.GetManifestResourceStream(text); if (stream2 != null) { byte[] array3 = new byte[stream2.Length]; stream2.Read(array3, 0, array3.Length); Texture2D val = new Texture2D(50, 89, (TextureFormat)4, false); ImageConversion.LoadImage(val, array3); replacementTexture = val; Logger.LogInfo((object)("Loaded texture: " + text)); } } } if ((Object)(object)replacementAudio == (Object)null) { Logger.LogWarning((object)"No sound file found in resources"); } if ((Object)(object)replacementTexture == (Object)null) { Logger.LogWarning((object)"No texture file found in resources"); } } catch (Exception ex) { Logger.LogError((object)("Failed to load embedded resources: " + ex.Message)); } } private AudioClip CreateAudioClipFromBytes(byte[] audioData, string name) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown try { string text = Path.Combine(Application.temporaryCachePath, name + ".ogg"); File.WriteAllBytes(text, audioData); AudioClip val = null; WWW val2 = new WWW("file:///" + text); try { while (!val2.isDone) { } if (string.IsNullOrEmpty(val2.error)) { val = val2.GetAudioClip(false, true); } } finally { ((IDisposable)val2)?.Dispose(); } File.Delete(text); if ((Object)(object)val != (Object)null) { ((Object)val).name = name; } return val; } catch (Exception ex) { Logger.LogError((object)("Failed to create audio clip: " + ex.Message)); return null; } } private bool LoadAssetBundle() { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("smert_v_nishite.smert_v_nishite"); if (stream == null) { Logger.LogError((object)"Embedded asset bundle not found."); return false; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); AssetBundle val = AssetBundle.LoadFromMemory(array); if ((Object)(object)val == (Object)null) { Logger.LogError((object)"Failed to load asset bundle."); return false; } string[] allAssetNames = val.GetAllAssetNames(); foreach (string text in allAssetNames) { if (text.EndsWith(".ogg")) { replacementAudio = val.LoadAsset<AudioClip>(text); Logger.LogDebug((object)("Ringtone loaded: " + text)); } else if (text.EndsWith(".png")) { replacementTexture = val.LoadAsset<Texture2D>(text); Logger.LogDebug((object)("Screen loaded: " + text)); } } return true; } public static AudioClip GetReplacedSound(string originalName) { return (originalName.ToLowerInvariant() == "phone ringtone") ? replacementAudio : null; } } public class TextureReplacer : MonoBehaviour { [CompilerGenerated] private sealed class <InitialScan>d__8 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public TextureReplacer <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <InitialScan>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this.ScanRenderers(); 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 string ATLAS_NAME = "arctic small valuables_defaultmaterial_emissive"; private const int OVERLAY_X = 241; private const int OVERLAY_Y_FROM_TOP = 107; private static readonly HashSet<int> processedMaterials = new HashSet<int>(); private static readonly Dictionary<int, Texture2D> modifiedAtlasCache = new Dictionary<int, Texture2D>(); private static readonly int EmissionMapId = Shader.PropertyToID("_EmissionMap"); private float lastScanTime; private void Start() { ((MonoBehaviour)this).StartCoroutine(InitialScan()); } [IteratorStateMachine(typeof(<InitialScan>d__8))] private IEnumerator InitialScan() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <InitialScan>d__8(0) { <>4__this = this }; } private void Update() { if (!(Time.time - lastScanTime < 2f)) { lastScanTime = Time.time; ScanRenderers(); } } private void ScanRenderers() { Renderer[] array = Object.FindObjectsOfType<Renderer>(); Renderer[] array2 = array; foreach (Renderer val in array2) { if (!((Object)(object)val == (Object)null)) { TryReplacePropertyBlock(val); TryReplaceMaterials(val); } } } private void TryReplacePropertyBlock(Renderer renderer) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown MaterialPropertyBlock val = new MaterialPropertyBlock(); renderer.GetPropertyBlock(val); Texture texture = val.GetTexture(EmissionMapId); Texture2D val2 = (Texture2D)(object)((texture is Texture2D) ? texture : null); if (!((Object)(object)val2 == (Object)null) && !(((Object)val2).name?.ToLowerInvariant() != "arctic small valuables_defaultmaterial_emissive")) { Texture2D orCreateModifiedAtlas = GetOrCreateModifiedAtlas(val2); if (!((Object)(object)orCreateModifiedAtlas == (Object)null)) { val.SetTexture(EmissionMapId, (Texture)(object)orCreateModifiedAtlas); renderer.SetPropertyBlock(val); } } } private void TryReplaceMaterials(Renderer renderer) { Material[] sharedMaterials = renderer.sharedMaterials; if (sharedMaterials == null) { return; } Material[] array = sharedMaterials; foreach (Material val in array) { if ((Object)(object)val == (Object)null) { continue; } int instanceID = ((Object)val).GetInstanceID(); if (!processedMaterials.Contains(instanceID)) { processedMaterials.Add(instanceID); if (!TryReplaceMaterialTexture(val, "_EmissionMap") && !TryReplaceMaterialTexture(val, "_MainTex")) { TryReplaceMaterialTexture(val, "_BaseMap"); } } } } private bool TryReplaceMaterialTexture(Material mat, string prop) { if (!mat.HasProperty(prop)) { return false; } Texture texture = mat.GetTexture(prop); Texture2D val = (Texture2D)(object)((texture is Texture2D) ? texture : null); if ((Object)(object)val == (Object)null) { return false; } if (((Object)val).name?.ToLowerInvariant() != "arctic small valuables_defaultmaterial_emissive") { return false; } Texture2D orCreateModifiedAtlas = GetOrCreateModifiedAtlas(val); if ((Object)(object)orCreateModifiedAtlas == (Object)null) { return false; } mat.SetTexture(prop, (Texture)(object)orCreateModifiedAtlas); if (prop == "_EmissionMap") { try { mat.EnableKeyword("_EMISSION"); } catch { } } return true; } private Texture2D GetOrCreateModifiedAtlas(Texture2D original) { int instanceID = ((Object)original).GetInstanceID(); if (modifiedAtlasCache.TryGetValue(instanceID, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = CreateModifiedAtlas(original); if ((Object)(object)val != (Object)null) { modifiedAtlasCache[instanceID] = val; } return val; } private Texture2D CreateModifiedAtlas(Texture2D original) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)original == (Object)null || (Object)(object)Plugin.replacementTexture == (Object)null) { return null; } Texture2D replacementTexture = Plugin.replacementTexture; int num = ((Texture)original).height - 107 - ((Texture)replacementTexture).height; RenderTexture temporary = RenderTexture.GetTemporary(((Texture)original).width, ((Texture)original).height, 0, (RenderTextureFormat)0); Graphics.Blit((Texture)(object)original, temporary); Texture2D val = new Texture2D(((Texture)original).width, ((Texture)original).height, (TextureFormat)4, false, true); RenderTexture active = RenderTexture.active; RenderTexture.active = temporary; val.ReadPixels(new Rect(0f, 0f, (float)((Texture)original).width, (float)((Texture)original).height), 0, 0); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); Color[] array = ReadPixels(replacementTexture); if (array == null) { return null; } val.SetPixels(241, num, ((Texture)replacementTexture).width, ((Texture)replacementTexture).height, array); val.Apply(false); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)2; return val; } private Color[] ReadPixels(Texture2D tex) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tex == (Object)null) { return null; } RenderTexture temporary = RenderTexture.GetTemporary(((Texture)tex).width, ((Texture)tex).height, 0, (RenderTextureFormat)0); Graphics.Blit((Texture)(object)tex, temporary); Texture2D val = new Texture2D(((Texture)tex).width, ((Texture)tex).height, (TextureFormat)4, false); RenderTexture active = RenderTexture.active; RenderTexture.active = temporary; val.ReadPixels(new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), 0, 0); val.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); Color[] pixels = val.GetPixels(); Object.Destroy((Object)(object)val); return pixels; } private void OnDestroy() { processedMaterials.Clear(); foreach (Texture2D value in modifiedAtlasCache.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } modifiedAtlasCache.Clear(); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "smert-v-nishite"; public const string PLUGIN_NAME = "smert-v-nishite"; public const string PLUGIN_VERSION = "2.0.1"; }