using 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 BepInEx;
using Configgy;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ParryImages")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ParryImages")]
[assembly: AssemblyCopyright("Copyright © Nobody 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d6025689-10a2-4e6f-b98a-6e2aa6442186")]
[assembly: AssemblyFileVersion("1.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.1.0.0")]
[BepInPlugin("com.harryzawg.UltraKill.ParryImages", "ParryImages", "2.1.0")]
public class ParryImages : BaseUnityPlugin
{
public class DebugCheck : ConfigToggle
{
public DebugCheck(bool Val)
: base(Val)
{
}
protected override void BuildElementCore(RectTransform rect)
{
if (ConsoleEnabled())
{
((ConfigToggle)this).BuildElementCore(rect);
}
}
}
[HarmonyPatch(typeof(Punch), "Parry")]
private static class ParryPatch
{
private static void Postfix(Punch __instance)
{
if (((ConfigValueElement<bool>)(object)DebugToggle).Value)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Got parry, showing image");
}
ShowImage((MonoBehaviour)(object)__instance);
}
}
[HarmonyPatch(typeof(Punch), "ParryProjectile")]
private static class ProjectileParryPatch
{
private static void Postfix(Punch __instance, Projectile proj)
{
if (((ConfigValueElement<bool>)(object)DebugToggle).Value)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"Got projectile parry, is player bullet? {proj.playerBullet}");
}
if (proj.playerBullet)
{
ShowImage((MonoBehaviour)(object)__instance);
}
}
}
[CompilerGenerated]
private sealed class <FadeOutImage>d__37 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
private float <StartOpacity>5__2;
private float <FadeDir>5__3;
private float <Timer>5__4;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <FadeOutImage>d__37(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;
<StartOpacity>5__2 = ImgOpacity;
<FadeDir>5__3 = ((ConfigValueElement<float>)(object)FadeDurSlider).Value;
<Timer>5__4 = 0f;
break;
case 1:
<>1__state = -1;
break;
}
if (<Timer>5__4 < <FadeDir>5__3)
{
<Timer>5__4 += Time.unscaledDeltaTime;
ImgOpacity = Mathf.Lerp(<StartOpacity>5__2, 0f, <Timer>5__4 / <FadeDir>5__3);
<>2__current = null;
<>1__state = 1;
return true;
}
ImgOpacity = 0f;
Show = false;
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();
}
}
[CompilerGenerated]
private sealed class <HideImage>d__36 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public float duration;
private float <Timer>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <HideImage>d__36(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;
<Timer>5__2 = 0f;
break;
case 1:
<>1__state = -1;
break;
}
if (<Timer>5__2 < duration)
{
<Timer>5__2 += Time.unscaledDeltaTime;
<>2__current = null;
<>1__state = 1;
return true;
}
Show = false;
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();
}
}
[CompilerGenerated]
private sealed class <LoadAudioFiles>d__29 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public string[] files;
private string[] <>7__wrap1;
private int <>7__wrap2;
private string <file>5__4;
private WWW <www>5__5;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <LoadAudioFiles>d__29(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || num == 1)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<>7__wrap1 = null;
<file>5__4 = null;
<www>5__5 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Expected O, but got Unknown
try
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>7__wrap1 = files;
<>7__wrap2 = 0;
break;
case 1:
<>1__state = -3;
if (!string.IsNullOrEmpty(<www>5__5.error))
{
((BaseUnityPlugin)Instance).Logger.LogWarning((object)("Failed to load audio " + <file>5__4 + ": " + <www>5__5.error));
<>m__Finally1();
}
else
{
AudioClip audioClip = <www>5__5.GetAudioClip(false, false);
if ((Object)(object)audioClip != (Object)null)
{
LoadedAudios.Add(audioClip);
if (((ConfigValueElement<bool>)(object)DebugToggle).Value)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)("Loaded audio " + Path.GetFileName(<file>5__4)));
}
}
else
{
((BaseUnityPlugin)Instance).Logger.LogWarning((object)("Invalid audio clip: " + <file>5__4));
}
<>m__Finally1();
<www>5__5 = null;
<file>5__4 = null;
}
<>7__wrap2++;
break;
}
if (<>7__wrap2 < <>7__wrap1.Length)
{
<file>5__4 = <>7__wrap1[<>7__wrap2];
string text = "file:///" + <file>5__4.Replace("\\", "/");
<www>5__5 = new WWW(text);
<>1__state = -3;
<>2__current = <www>5__5;
<>1__state = 1;
return true;
}
<>7__wrap1 = null;
if (LoadedAudios.Count == 0)
{
((BaseUnityPlugin)Instance).Logger.LogWarning((object)"No audio files loaded!");
}
return false;
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
if (<www>5__5 != null)
{
((IDisposable)<www>5__5).Dispose();
}
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <StopAudio>d__34 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public float duration;
private float <timer>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <StopAudio>d__34(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;
<timer>5__2 = 0f;
break;
case 1:
<>1__state = -1;
break;
}
if (<timer>5__2 < duration && AudioPlayer.isPlaying)
{
<timer>5__2 += Time.unscaledDeltaTime;
<>2__current = null;
<>1__state = 1;
return true;
}
AudioPlayer.Stop();
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 static List<Texture2D> LoadedImages = new List<Texture2D>();
private static Texture2D CurrentImg;
private static bool Show = false;
private static float ImgOpacity = 0.8f;
private static List<AudioClip> LoadedAudios = new List<AudioClip>();
private static AudioSource AudioPlayer;
[Configgable("Images", "Enabled", 0, null)]
private static ConfigToggle EnabledToggle = new ConfigToggle(true);
[Configgable("Images", "Reload Images", 0, null)]
public static ConfigButton ReloadButton = new ConfigButton((Action)ReloadImages, (string)null);
[Configgable("Images", "Open ParryImages Folder", 0, null)]
public static ConfigButton OpenImagesFolder = new ConfigButton((Action)delegate
{
string text2 = Path.Combine(Paths.PluginPath, "ParryImages");
if (!Directory.Exists(text2))
{
Directory.CreateDirectory(text2);
string path = Path.Combine(text2, "Read-Me.txt");
string contents = "Place any .jpg, .jpeg, .png, or .bmp in this folder, and when you parry it will flash your image on the screen\nOnce your images are in the folder, go into the Configgy settings and press Reload Images inside of Images to load your images into the game";
File.WriteAllText(path, contents);
}
Application.OpenURL(text2);
((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[ParryImages] Opening " + text2));
}, (string)null);
[Configgable("Images", "Effect", 0, null)]
private static ConfigDropdown<string> ParryDisplayMode = new ConfigDropdown<string>(new string[2] { "Flash", "Fade Out" }, "Flash", (string[])null);
[Configgable("Images", "Fade Out Duration", 0, null)]
private static FloatSlider FadeDurSlider = new FloatSlider(1.2f, 0.3f, 10f);
[Configgable("Images", "Opacity", 0, null)]
private static FloatSlider OpacitySlider = new FloatSlider(0.8f, 0f, 1f);
[Configgable("", "Debug", 0, null)]
private static DebugCheck DebugToggle = new DebugCheck(Val: false);
[Configgable("Sound", "Enabled", 0, null)]
private static ConfigToggle AudioToggle = new ConfigToggle(true);
[Configgable("Sound", "Open ParryAudios Folder", 0, null)]
public static ConfigButton OpenAudioFolder = new ConfigButton((Action)delegate
{
string text = Path.Combine(Paths.PluginPath, "ParryAudios");
if (!Directory.Exists(text))
{
Directory.CreateDirectory(text);
File.WriteAllText(Path.Combine(text, "Read-Me.txt"), "Place .mp3, .ogg, or .wav files here and a random audio will play when you parry.");
}
Application.OpenURL(text);
((BaseUnityPlugin)Instance).Logger.LogInfo((object)("[ParryImages] Opening " + text));
}, (string)null);
[Configgable("Sound", "Reload Audios", 0, null)]
public static ConfigButton ReloadAudioBtn = new ConfigButton((Action)ReloadAudios, (string)null);
[Configgable("Sound", "Audio Volume", 0, null)]
private static FloatSlider AudioVolSlider = new FloatSlider(0.7f, 0f, 1f);
[Configgable("Sound", "Max Audio Duration", 0, null)]
private static FloatSlider AudioDurSlider = new FloatSlider(5f, 0.1f, 15f);
public static ParryImages Instance { get; private set; }
private void Awake()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: 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
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
GameObject val = new GameObject("ParryImages_Audio")
{
hideFlags = (HideFlags)61
};
Object.DontDestroyOnLoad((Object)val);
AudioPlayer = val.AddComponent<AudioSource>();
AudioPlayer.playOnAwake = false;
AudioPlayer.spatialBlend = 0f;
AudioPlayer.rolloffMode = (AudioRolloffMode)1;
AudioPlayer.minDistance = 1f;
AudioPlayer.maxDistance = 500f;
AudioPlayer.dopplerLevel = 0f;
AudioPlayer.priority = 0;
LoadImages();
LoadAudios();
new Harmony("com.harryzawg.UltraKill.ParryImages").PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin ParryImages was loaded!");
new ConfigBuilder("ParryImages", (string)null).BuildAll();
}
public static bool ConsoleEnabled()
{
string path = Path.Combine(Paths.ConfigPath, "BepInEx.cfg");
if (!File.Exists(path))
{
return false;
}
bool flag = false;
string[] array = File.ReadAllLines(path);
for (int i = 0; i < array.Length; i++)
{
string text = array[i].Trim();
if (string.IsNullOrWhiteSpace(text) || text.StartsWith("#") || text.StartsWith(";"))
{
continue;
}
if (text.StartsWith("[") && text.EndsWith("]"))
{
flag = text.Equals("[Logging.Console]", StringComparison.OrdinalIgnoreCase);
}
else if (flag && text.StartsWith("Enabled", StringComparison.OrdinalIgnoreCase))
{
string[] array2 = text.Split(new char[1] { '=' });
bool result;
if (array2.Length == 2)
{
return bool.TryParse(array2[1].Trim(), out result) && result;
}
}
}
return false;
}
private void OnGUI()
{
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
if (((ConfigValueElement<bool>)(object)EnabledToggle).Value && Show && (Object)(object)CurrentImg != (Object)null)
{
if (((ConfigValueElement<string>)(object)ParryDisplayMode).Value == "Flash")
{
ImgOpacity = ((ConfigValueElement<float>)(object)OpacitySlider).Value;
}
GUI.color = new Color(1f, 1f, 1f, ImgOpacity);
GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)CurrentImg);
GUI.color = Color.white;
}
}
private static void LoadImages()
{
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Expected O, but got Unknown
LoadedImages.Clear();
string text = Path.Combine(Paths.PluginPath, "ParryImages");
if (!Directory.Exists(text))
{
((BaseUnityPlugin)Instance).Logger.LogWarning((object)"Could not find ParryImages Directory! Will create...");
Directory.CreateDirectory(text);
string path = Path.Combine(text, "Read-Me.txt");
string contents = "Place any .jpg, .jpeg, .png, or .bmp in this folder, and when you parry it will flash your image on the screen\nOnce your images are in the folder, go into the Configgy settings and press Reload Images inside of Images to load your images into the game";
File.WriteAllText(path, contents);
}
string[] array = (from f in Directory.GetFiles(text)
where f.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".jpeg", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".png", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".bmp", StringComparison.OrdinalIgnoreCase)
select f).ToArray();
foreach (string text2 in array)
{
try
{
byte[] array2 = File.ReadAllBytes(text2);
Texture2D val = new Texture2D(2, 2);
if (ImageConversion.LoadImage(val, array2))
{
LoadedImages.Add(val);
if (((ConfigValueElement<bool>)(object)DebugToggle).Value)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)("Loaded " + Path.GetFileName(text2)));
}
}
}
catch (Exception ex)
{
((BaseUnityPlugin)Instance).Logger.LogWarning((object)("Couldn't load image " + text2 + ": " + ex.Message));
}
}
if (LoadedImages.Count == 0)
{
((BaseUnityPlugin)Instance).Logger.LogWarning((object)"No images were found in the ParryImages folder!");
}
}
private static void ReloadImages()
{
if (((ConfigValueElement<bool>)(object)DebugToggle).Value)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Reloading images...");
}
LoadImages();
}
private static void LoadAudios()
{
LoadedAudios.Clear();
string text = Path.Combine(Paths.PluginPath, "ParryAudios");
if (!Directory.Exists(text))
{
((BaseUnityPlugin)Instance).Logger.LogWarning((object)"Could not find ParryAudios Directory! Will create...");
Directory.CreateDirectory(text);
File.WriteAllText(Path.Combine(text, "Read-Me.txt"), "Place .mp3, .ogg, or .wav files here and a random audio will play when you parry.");
}
else
{
string[] files = (from f in Directory.GetFiles(text)
where f.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".ogg", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".wav", StringComparison.OrdinalIgnoreCase)
select f).ToArray();
((MonoBehaviour)Instance).StartCoroutine(LoadAudioFiles(files));
}
}
[IteratorStateMachine(typeof(<LoadAudioFiles>d__29))]
private static IEnumerator LoadAudioFiles(string[] files)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <LoadAudioFiles>d__29(0)
{
files = files
};
}
private static void ReloadAudios()
{
if (((ConfigValueElement<bool>)(object)DebugToggle).Value)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Reloading audios...");
}
LoadAudios();
}
private static void PlayAudio(MonoBehaviour source)
{
if (((ConfigValueElement<bool>)(object)AudioToggle).Value && LoadedAudios.Count != 0)
{
AudioClip clip = LoadedAudios[Random.Range(0, LoadedAudios.Count)];
AudioPlayer.Stop();
AudioPlayer.clip = clip;
AudioPlayer.volume = Mathf.Clamp01(((ConfigValueElement<float>)(object)AudioVolSlider).Value * 2.5f);
AudioPlayer.pitch = Random.Range(0.97f, 1.03f);
AudioPlayer.Play();
source.StartCoroutine(StopAudio(((ConfigValueElement<float>)(object)AudioDurSlider).Value));
}
}
[IteratorStateMachine(typeof(<StopAudio>d__34))]
private static IEnumerator StopAudio(float duration)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <StopAudio>d__34(0)
{
duration = duration
};
}
private static void ShowImage(MonoBehaviour source)
{
if (((ConfigValueElement<bool>)(object)EnabledToggle).Value)
{
if (LoadedImages.Count > 0)
{
CurrentImg = LoadedImages[Random.Range(0, LoadedImages.Count)];
}
else
{
CurrentImg = null;
}
if (((ConfigValueElement<bool>)(object)AudioToggle).Value)
{
PlayAudio(source);
}
Show = true;
ImgOpacity = ((ConfigValueElement<float>)(object)OpacitySlider).Value;
string value = ((ConfigValueElement<string>)(object)ParryDisplayMode).Value;
if (value == "Flash")
{
source.StartCoroutine(HideImage(0.25f));
}
else if (value == "Fade Out")
{
source.StartCoroutine(FadeOutImage());
}
}
}
[IteratorStateMachine(typeof(<HideImage>d__36))]
private static IEnumerator HideImage(float duration)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <HideImage>d__36(0)
{
duration = duration
};
}
[IteratorStateMachine(typeof(<FadeOutImage>d__37))]
private static IEnumerator FadeOutImage()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <FadeOutImage>d__37(0);
}
}
namespace ParryImagesInfo;
public class HarmonyPatches
{
private static Harmony instance;
public const string InstanceId = "com.harryzawg.UltraKill.ParryImages";
public static bool IsPatched { get; private set; }
internal static void ApplyHarmonyPatches()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
if (!IsPatched)
{
if (instance == null)
{
instance = new Harmony("com.harryzawg.UltraKill.ParryImages");
}
instance.PatchAll(Assembly.GetExecutingAssembly());
IsPatched = true;
}
}
internal static void RemoveHarmonyPatches()
{
if (instance != null && IsPatched)
{
instance.UnpatchSelf();
IsPatched = false;
}
}
}
internal class PluginInfo
{
public const string GUID = "com.harryzawg.UltraKill.ParryImages";
public const string Name = "ParryImages";
public const string Version = "2.1.0";
}