using System;
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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using IL.RoR2;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2;
using R2API;
using RiskOfOptions;
using RiskOfOptions.Options;
using RoR2;
using UnityEngine;
[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("FinFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b8c234ee6c51608bcdf1ea408d4d03d05d492f0e")]
[assembly: AssemblyProduct("FinFix")]
[assembly: AssemblyTitle("FinFix")]
[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 FinFix
{
public class FinFixConfig
{
public static ConfigEntry<bool> FixDoubleDip;
public static ConfigEntry<bool> FixDeathMark;
public static ConfigEntry<bool> DelayJuggleStacks;
public static void Init(ConfigFile config)
{
FixDoubleDip = config.Bind<bool>("Fixes", "Fix Double Dip", true, "Breaching Fin's damage multiplier is applied multiple times during proc chains.\n\nEnabling this setting ensures it's only applied once.");
FixDeathMark = config.Bind<bool>("Fixes", "Fix Death Mark", true, "Breaching Fin applies 2 debuffs to keep track of knock ups, both of which counts for Death Mark.\n\nEnabling this setting ensure only one of those 2 debuffs counts for Death Mark.");
DelayJuggleStacks = config.Bind<bool>("Fixes", "Delay Juggle Stacks", false, "Breaching Fin's juggle stacks are applied before calculating the damage multiplier. This causes the very first attack to also have its damage multiplied, despite the enemy being on the ground.\n\nEnabling this setting changes that behaviour and calculate the mutiplier based on stacks before the hit.\nWarning: With this enabled, an extra attack is required to get the full multiplier after the last knockup.");
if (RiskOfOptionsCompatibility.Enabled)
{
RiskOfOptionsCompatibility.AddConfig();
}
}
}
[BepInPlugin("Judgy.FinFix", "FinFix", "1.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class FinFixPlugin : BaseUnityPlugin
{
public const string PluginGUID = "Judgy.FinFix";
public const string PluginAuthor = "Judgy";
public const string PluginName = "FinFix";
public const string PluginVersion = "1.1.0";
private ModdedProcType _customJuggleProcType;
private int _juggleStacksBefore;
public static string PluginDirectory { get; private set; }
public void Awake()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected O, but got Unknown
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Expected O, but got Unknown
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Expected O, but got Unknown
PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
Log.Init(((BaseUnityPlugin)this).Logger);
FinFixConfig.Init(((BaseUnityPlugin)this).Config);
_customJuggleProcType = ProcTypeAPI.ReserveProcType();
HealthComponent.TakeDamageProcess += new hook_TakeDamageProcess(RememberStacksBeforeDamageCalc);
KnockbackFinUtil.ModifyDamageInfo += new hook_ModifyDamageInfo(On_KnockbackFinUtil_ModifyDamageInfo);
GlobalEventManager.ProcessHitEnemy += new Manipulator(IL_GlobalEventManager_ProcessHitEnemy);
}
private void RememberStacksBeforeDamageCalc(orig_TakeDamageProcess orig, HealthComponent self, DamageInfo damageInfo)
{
_juggleStacksBefore = self.body.GetBuffCount(Buffs.KnockUpHitEnemiesJuggleCount);
orig.Invoke(self, damageInfo);
}
private void On_KnockbackFinUtil_ModifyDamageInfo(orig_ModifyDamageInfo orig, ref DamageInfo damageInfo, CharacterBody attacker, CharacterBody victim)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
int num = victim.GetBuffCount(Buffs.KnockUpHitEnemiesJuggleCount);
if (FinFixConfig.DelayJuggleStacks.Value)
{
num = _juggleStacksBefore;
}
if (num > 0)
{
if (!damageInfo.crit)
{
damageInfo.damageColorIndex = (DamageColorIndex)14;
}
if (!FinFixConfig.FixDoubleDip.Value || !ProcTypeAPI.HasModdedProc(damageInfo.procChainMask, _customJuggleProcType))
{
float num2 = (float)num * 0.2f * damageInfo.damage;
DamageInfo obj = damageInfo;
obj.damage += num2;
ProcTypeAPI.AddModdedProc(ref damageInfo.procChainMask, _customJuggleProcType);
}
}
}
private void IL_GlobalEventManager_ProcessHitEnemy(ILContext il)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Expected O, but got Unknown
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
ILCursor val = new ILCursor(il);
if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
{
(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(BuffCatalog).GetField("debuffBuffIndices", BindingFlags.Static | BindingFlags.Public))
}))
{
Log.Error("GlobalEventManager_ProcessHitEnemy IL Hook failed while searching for BuffCatalog.debuffBuffIndices " + val.Index);
return;
}
int buffIndex = -1;
if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
{
(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref buffIndex),
(Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, (MethodBase)typeof(CharacterBody).GetMethod("HasBuff", new Type[1] { typeof(BuffIndex) }))
}) || buffIndex == -1)
{
Log.Error("GlobalEventManager_ProcessHitEnemy IL Hook failed while searching for characterBody.HasBuff(buffType)");
return;
}
val.Emit(OpCodes.Ldloc, buffIndex);
val.EmitDelegate<Func<BuffIndex, bool>>((Func<BuffIndex, bool>)IsValidDebuffForDeathmark);
val.Emit(OpCodes.And);
Log.Info("GlobalEventManager_ProcessHitEnemy IL Hook successfull");
}
private bool IsValidDebuffForDeathmark(BuffIndex buffIndex)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
if (!FinFixConfig.FixDeathMark.Value)
{
return true;
}
return (Object)(object)BuffCatalog.GetBuffDef(buffIndex) != (Object)(object)Buffs.KnockUpHitEnemies;
}
}
internal static class Log
{
private static ManualLogSource _logSource;
internal static void Init(ManualLogSource logSource)
{
_logSource = logSource;
}
internal static void Debug(object data)
{
_logSource.LogDebug(data);
}
internal static void Error(object data)
{
_logSource.LogError(data);
}
internal static void Fatal(object data)
{
_logSource.LogFatal(data);
}
internal static void Info(object data)
{
_logSource.LogInfo(data);
}
internal static void Message(object data)
{
_logSource.LogMessage(data);
}
internal static void Warning(object data)
{
_logSource.LogWarning(data);
}
}
internal class RiskOfOptionsCompatibility
{
private static bool? _enabled;
public static bool Enabled
{
get
{
bool valueOrDefault = _enabled.GetValueOrDefault();
if (!_enabled.HasValue)
{
valueOrDefault = Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");
_enabled = valueOrDefault;
}
return _enabled.Value;
}
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static void AddConfig()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Expected O, but got Unknown
ModSettingsManager.SetModIcon(LoadIcon());
ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(FinFixConfig.FixDoubleDip));
ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(FinFixConfig.FixDeathMark));
ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(FinFixConfig.DelayJuggleStacks));
}
private static Sprite LoadIcon()
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Expected O, but got Unknown
string text = FindIconFilePath();
if (text == null)
{
return null;
}
Texture2D val = new Texture2D(256, 256);
ImageConversion.LoadImage(val, File.ReadAllBytes(text));
return Sprite.Create(val, new Rect(0f, 0f, 256f, 256f), new Vector2(0f, 0f));
}
private static string FindIconFilePath()
{
DirectoryInfo directoryInfo = new DirectoryInfo(FinFixPlugin.PluginDirectory);
do
{
FileInfo[] files = directoryInfo.GetFiles("icon.png", SearchOption.TopDirectoryOnly);
if (files != null && files.Length != 0)
{
return files[0].FullName;
}
directoryInfo = directoryInfo.Parent;
}
while (directoryInfo != null && !string.Equals(directoryInfo.Name, "plugins", StringComparison.OrdinalIgnoreCase));
return null;
}
}
}