using 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 UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("kossnikita")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("smert-v-nishite")]
[assembly: AssemblyTitle("smert-v-nishite")]
[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 smert_v_nishite
{
public class AudioSourceData
{
public AudioClip OriginalClip { get; set; }
public AudioClip RealClip
{
get
{
using (new SpoofBypass())
{
return Source.clip;
}
}
set
{
using (new SpoofBypass())
{
Source.clip = value;
}
}
}
public AudioSource Source { get; }
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);
AudioClip originalClip = orCreate.OriginalClip;
AudioClip replacedSound = Plugin.GetReplacedSound(((originalClip != null) ? ((Object)originalClip).name : null) ?? "");
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)
{
AudioClip obj = clip;
AudioClip replacedSound = Plugin.GetReplacedSound(((obj != null) ? ((Object)obj).name : null) ?? "");
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", "JohnPorkMod", "1.0.0")]
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_0019: Unknown result type (might be due to invalid IL or missing references)
Logger = ((BaseUnityPlugin)this).Logger;
if (LoadAssetBundle())
{
new Harmony("smert-v-nishite").PatchAll();
SceneManager.sceneLoaded += OnSceneLoaded;
Logger.LogInfo((object)"Plugin loaded!");
}
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
//IL_0013: 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_001e: Expected O, but got Unknown
if (!textureReplacerInitialized)
{
textureReplacerInitialized = true;
GameObject val = new GameObject("TextureReplacer");
Object.DontDestroyOnLoad((Object)val);
val.AddComponent<TextureReplacer>();
}
}
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 loadded: " + text));
}
}
return true;
}
public static AudioClip GetReplacedSound(string originalName)
{
if (!(originalName.ToLowerInvariant() == "phone ringtone"))
{
return null;
}
return replacementAudio;
}
}
public class TextureReplacer : MonoBehaviour
{
[CompilerGenerated]
private sealed class <InitialScan>d__8 : IEnumerator<object>, IEnumerator, IDisposable
{
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_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
int num = <>1__state;
TextureReplacer textureReplacer = <>4__this;
switch (num)
{
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;
textureReplacer.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>();
foreach (Renderer val in array)
{
if (!((Object)(object)val == (Object)null))
{
TryReplacePropertyBlock(val);
TryReplaceMaterials(val);
}
}
}
private void TryReplacePropertyBlock(Renderer renderer)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: 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 (val2 != 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 (val == 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_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Expected O, but got Unknown
//IL_0085: 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_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: 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_005f: 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)
//IL_007d: Expected O, but got Unknown
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)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 = "1.0.0";
}
}