Decompiled source of Cleaverang v1.0.6

plugins/Cleaverang.dll

Decompiled 4 days ago
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.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dolso;
using EntityStates;
using HG;
using HG.Reflection;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.ContentManagement;
using RoR2.Projectile;
using RoR2.Skills;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Cleaverang")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Cleaverang")]
[assembly: AssemblyTitle("Cleaverang")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Dolso
{
	internal static class log
	{
		private static readonly ManualLogSource logger = Logger.CreateLogSource(Assembly.GetExecutingAssembly().GetName().Name);

		[Conditional("DEBUG")]
		internal static void debug(object data)
		{
			logger.LogDebug(data);
		}

		internal static void info(object data)
		{
			logger.LogInfo(data);
		}

		internal static void message(object data)
		{
			logger.LogMessage(data);
		}

		internal static void warning(object data)
		{
			logger.LogWarning(data);
		}

		internal static void error(object data)
		{
			logger.LogError(data);
		}

		internal static void fatal(object data)
		{
			logger.LogFatal(data);
		}

		internal static void LogError(this ILCursor c, object data)
		{
			logger.LogError((object)$"ILCursor failure, skipping: {data}\n{c}");
		}

		internal static void LogErrorCaller(this ILCursor c, object data)
		{
			logger.LogError((object)$"ILCursor failed in {new StackFrame(1).GetMethod().Name}, skipping: {data}\n{c}");
		}
	}
	internal static class HookManager
	{
		internal delegate bool ConfigEnabled<T>(T configValue);

		internal class HookedConfig<T>
		{
			private readonly ConfigEnabled<T> enabled;

			private readonly IDetour detour;

			internal HookedConfig(ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, IDetour detour)
			{
				this.enabled = enabled;
				this.detour = detour;
				if (configEntry != null)
				{
					configEntry.SettingChanged += ConfigChanged;
					ConfigChanged(configEntry, null);
				}
				else
				{
					detour.Apply();
				}
			}

			private void ConfigChanged(object sender, EventArgs args)
			{
				if (!detour.IsValid)
				{
					return;
				}
				if (enabled(((ConfigEntry<T>)sender).Value))
				{
					if (!detour.IsApplied)
					{
						detour.Apply();
					}
				}
				else if (detour.IsApplied)
				{
					detour.Undo();
				}
			}
		}

		internal const BindingFlags allFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly List<IDisposable> detours = new List<IDisposable>();

		private static readonly ConfigEnabled<bool> boolConfigEnabled = BoolEnabled;

		private static ILHookConfig ilHookConfig = new ILHookConfig
		{
			ManualApply = true
		};

		private static HookConfig onHookConfig = new HookConfig
		{
			ManualApply = true
		};

		internal static int Hook(Type typeFrom, string fromMethod, Manipulator ilHook)
		{
			return Hook(GetMethod(typeFrom, fromMethod), ilHook);
		}

		internal static int Hook(Delegate fromMethod, Manipulator ilHook)
		{
			return Hook(fromMethod.Method, ilHook);
		}

		internal static int Hook(MethodBase fromMethod, Manipulator ilHook)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			try
			{
				ILHook val = new ILHook(fromMethod, ilHook, ref ilHookConfig);
				detours.Add((IDisposable)val);
				val.Apply();
			}
			catch (Exception e)
			{
				e.LogHookError(fromMethod, ((Delegate)(object)ilHook).Method);
				return 8;
			}
			return 0;
		}

		internal static int Hook(Type typeFrom, string fromMethod, Delegate onHook)
		{
			return Hook(GetMethod(typeFrom, fromMethod), onHook.Method, onHook.Target);
		}

		internal static int Hook(Delegate fromMethod, Delegate onHook)
		{
			return Hook(fromMethod.Method, onHook.Method, onHook.Target);
		}

		internal static int Hook(MethodBase fromMethod, Delegate onHook)
		{
			return Hook(fromMethod, onHook.Method, onHook.Target);
		}

		internal static int Hook(MethodBase fromMethod, MethodInfo onHook, object target = null)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			try
			{
				Hook val = new Hook(fromMethod, onHook, target, ref onHookConfig);
				detours.Add((IDisposable)val);
				val.Apply();
			}
			catch (Exception e)
			{
				e.LogHookError(fromMethod, onHook);
				return 8;
			}
			return 0;
		}

		internal static int HookConfig(this ConfigEntry<bool> configEntry, Type typeFrom, string fromMethod, Delegate hook)
		{
			return configEntry.HookConfig(boolConfigEnabled, GetMethod(typeFrom, fromMethod), hook.Method, hook.Target);
		}

		internal static int HookConfig(this ConfigEntry<bool> configEntry, MethodBase fromMethod, Delegate hook)
		{
			return configEntry.HookConfig(boolConfigEnabled, fromMethod, hook.Method, hook.Target);
		}

		internal static int HookConfig(this ConfigEntry<bool> configEntry, MethodBase fromMethod, MethodInfo hook)
		{
			return configEntry.HookConfig(boolConfigEnabled, fromMethod, hook);
		}

		internal static int HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, Type typeFrom, string fromMethod, Delegate hook)
		{
			return configEntry.HookConfig(enabled, GetMethod(typeFrom, fromMethod), hook.Method, hook.Target);
		}

		internal static int HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase fromMethod, Delegate hook)
		{
			return configEntry.HookConfig(enabled, fromMethod, hook.Method, hook.Target);
		}

		internal static int HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase fromMethod, MethodInfo hook, object target = null)
		{
			try
			{
				IDetour val = ManualDetour(fromMethod, hook, target);
				if (val == null)
				{
					return 8;
				}
				new HookedConfig<T>(configEntry, enabled, val);
				return 0;
			}
			catch (Exception e)
			{
				e.LogHookError(fromMethod, hook);
				return 8;
			}
		}

		internal static IDetour ManualDetour(Type typeFrom, string fromMethod, Delegate hook)
		{
			return ManualDetour(GetMethod(typeFrom, fromMethod), hook.Method, hook.Target);
		}

		internal static IDetour ManualDetour(MethodBase fromMethod, Delegate hook)
		{
			return ManualDetour(fromMethod, hook.Method, hook.Target);
		}

		internal static IDetour ManualDetour(MethodBase fromMethod, MethodInfo hook, object target = null)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			try
			{
				ParameterInfo[] parameters = hook.GetParameters();
				if (parameters.Length == 1 && parameters[0].ParameterType == typeof(ILContext))
				{
					return (IDetour)new ILHook(fromMethod, (Manipulator)hook.CreateDelegate(typeof(Manipulator)), ref ilHookConfig);
				}
				return (IDetour)new Hook(fromMethod, hook, target, ref onHookConfig);
			}
			catch (Exception e)
			{
				e.LogHookError(fromMethod, hook);
				return null;
			}
		}

		internal static MethodInfo GetMethod(Type typeFrom, string methodName)
		{
			if (typeFrom == null || methodName == null)
			{
				log.error($"Null argument in GetMethod: type={typeFrom}, name={methodName}");
				return null;
			}
			MethodInfo[] array = (from a in typeFrom.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
				where a.Name == methodName
				select a).ToArray();
			switch (array.Length)
			{
			case 1:
				return array[0];
			case 0:
				log.error($"Failed to find method: {typeFrom}::{methodName}");
				return null;
			default:
			{
				string text = $"{array.Length} ambiguous matches found for {typeFrom}::{methodName}, may be incorrect";
				MethodInfo[] array2 = array;
				for (int num = 0; num < array2.Length; num++)
				{
					text = text + "\n" + array2[num];
				}
				log.warning(text);
				return array[0];
			}
			}
		}

		internal static MethodInfo GetMethod(Type typeFrom, string methodName, params Type[] parameters)
		{
			if (typeFrom == null || methodName == null)
			{
				log.error($"Null argument in GetMethod: type={typeFrom}, name={methodName}");
				return null;
			}
			MethodInfo? method = typeFrom.GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameters, null);
			if (method == null)
			{
				log.error($"Failed to find method: {typeFrom}::{methodName}_{parameters.Length}");
			}
			return method;
		}

		internal static void SetPriority(string[] before_il = null, string[] before_on = null, string[] after_il = null, string[] after_on = null)
		{
			ilHookConfig.Before = before_il;
			onHookConfig.Before = before_on;
			ilHookConfig.After = after_il;
			onHookConfig.After = after_on;
		}

		internal static void DisposeAll()
		{
			for (int num = detours.Count - 1; num >= 0; num--)
			{
				try
				{
					IDisposable disposable = detours[num];
					detours.RemoveAt(num);
					disposable.Dispose();
				}
				catch (Exception)
				{
				}
			}
		}

		internal static void LogHookError(this Exception e, MethodBase fromMethod, MethodInfo hook)
		{
			log.error((fromMethod == null) ? $"null from-method for hook: {hook.Name}\n{e}" : $"Failed to hook: {fromMethod.DeclaringType}::{fromMethod.Name} - {hook.Name}\n{e}");
		}

		private static bool BoolEnabled(bool configValue)
		{
			return configValue;
		}
	}
	internal static class Utilities
	{
		private static GameObject _prefabParent;

		internal static GameObject CreatePrefab(GameObject gameObject, string name = null)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)_prefabParent))
			{
				_prefabParent = new GameObject("DolsoPrefabs");
				Object.DontDestroyOnLoad((Object)(object)_prefabParent);
				((Object)_prefabParent).hideFlags = (HideFlags)61;
				_prefabParent.SetActive(false);
			}
			GameObject val = Object.Instantiate<GameObject>(gameObject, _prefabParent.transform);
			if (name != null)
			{
				((Object)val).name = name;
			}
			return val;
		}
	}
	internal static class RiskofOptions
	{
		internal const string RooGuid = "com.rune580.riskofoptions";

		internal static bool enabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void SetSprite(Sprite sprite)
		{
			ModSettingsManager.SetModIcon(sprite);
		}

		internal static void SetSpriteDefaultIcon()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string fullName = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)).FullName;
				Texture2D val = new Texture2D(256, 256);
				if (ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(fullName, "icon.png"))))
				{
					ModSettingsManager.SetModIcon(Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)));
				}
				else
				{
					log.error("Failed to load icon.png");
				}
			}
			catch (Exception ex)
			{
				log.error("Failed to load icon.png\n" + ex);
			}
		}

		internal static void AddOption(ConfigEntryBase entry)
		{
			AddOption(entry, string.Empty, string.Empty);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void AddOption(ConfigEntryBase entry, string categoryName = "", string name = "", bool restartRequired = false)
		{
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Expected O, but got Unknown
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Expected O, but got Unknown
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00a5: 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)
			//IL_0095: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			Type settingType = entry.SettingType;
			object obj;
			if (!(settingType == typeof(float)))
			{
				obj = ((!(settingType == typeof(string))) ? ((!(settingType == typeof(bool))) ? ((!(settingType == typeof(int))) ? ((!(settingType == typeof(Color))) ? ((!(settingType == typeof(KeyboardShortcut))) ? ((object)((!settingType.IsEnum) ? ((ChoiceOption)null) : new ChoiceOption(entry, new ChoiceConfig()))) : ((object)new KeyBindOption((ConfigEntry<KeyboardShortcut>)(object)entry, new KeyBindConfig()))) : ((object)new ColorOption((ConfigEntry<Color>)(object)entry, new ColorOptionConfig()))) : ((object)new IntFieldOption((ConfigEntry<int>)(object)entry, new IntFieldConfig()))) : ((object)new CheckBoxOption((ConfigEntry<bool>)(object)entry, new CheckBoxConfig()))) : ((object)new StringInputFieldOption((ConfigEntry<string>)(object)entry, new InputFieldConfig
				{
					submitOn = (SubmitEnum)6,
					lineType = (LineType)0
				})));
			}
			else if (entry.Description.AcceptableValues is AcceptableValueRange<float>)
			{
				obj = (object)new SliderOption((ConfigEntry<float>)(object)entry, new SliderConfig
				{
					min = ((AcceptableValueRange<float>)(object)entry.Description.AcceptableValues).MinValue,
					max = ((AcceptableValueRange<float>)(object)entry.Description.AcceptableValues).MaxValue,
					FormatString = "{0:f2}",
					description = entry.DescWithDefault("{0:f2}")
				});
			}
			else
			{
				ConfigEntry<float> obj2 = (ConfigEntry<float>)(object)entry;
				FloatFieldConfig val = new FloatFieldConfig();
				((NumericFieldConfig<float>)val).FormatString = "{0:f2}";
				((BaseOptionConfig)val).description = entry.DescWithDefault("{0:f2}");
				obj = (object)new FloatFieldOption(obj2, val);
			}
			BaseOption val2 = (BaseOption)obj;
			if (val2 == null)
			{
				return;
			}
			BaseOptionConfig config = val2.GetConfig();
			config.category = categoryName;
			config.name = name;
			config.restartRequired = restartRequired;
			if (config.description == "")
			{
				config.description = entry.DescWithDefault();
			}
			try
			{
				ModSettingsManager.AddOption(val2);
			}
			catch (Exception arg)
			{
				log.error($"AddOption {entry.Definition} failed\n{arg}");
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void AddOption(ConfigEntry<float> entry, float min, float max, string format = "{0:f2}", string categoryName = "")
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new SliderOption(entry, new SliderConfig
			{
				min = min,
				max = max,
				FormatString = format,
				category = categoryName,
				description = ((ConfigEntryBase)(object)entry).DescWithDefault(format)
			}));
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void AddIntSlider(ConfigEntry<int> entry, int min, int max, string categoryName = "")
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(entry, new IntSliderConfig
			{
				min = min,
				max = max,
				category = categoryName,
				description = ((ConfigEntryBase)(object)entry).DescWithDefault()
			}));
		}

		private static string DescWithDefault(this ConfigEntryBase entry, string format = "{0}")
		{
			return string.Format("{1}\n[Default: " + format + "]", entry.DefaultValue, entry.Description.Description);
		}
	}
}
namespace Cleaverang
{
	internal class Config
	{
		private static ConfigFile configFile;

		private static ConfigEntry<string> version;

		internal static ConfigEntry<float> damage;

		internal static ConfigEntry<float> bleedChance;

		internal static ConfigEntry<float> procCoef;

		internal static ConfigEntry<float> cooldown;

		internal static ConfigEntry<float> interval;

		internal static void DoConfig(ConfigFile bepConfigFile)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			configFile = bepConfigFile;
			damage = configFile.Bind<float>("Stats", "Damage", 0.8f, "Damage multiplier of hits");
			bleedChance = configFile.Bind<float>("Stats", "Bleed Chance", 40f, new ConfigDescription("Bleed chance of boosted (from Yes Chef) Cleaverangs", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			procCoef = configFile.Bind<float>("Stats", "Proc Coefficient", 1f, "Proc coefficient of the repeated hits");
			cooldown = configFile.Bind<float>("Stats", "Cooldown", 2.25f, "Cooldown of Cleaverang. For reference vanilla Dice cooldown is 1.75s");
			interval = configFile.Bind<float>("Stats", "Attack Interval", 0.5f, "Interval between attacks");
			version = configFile.Bind<string>("", "Config Version", "1.0.6", "Config version, if this is different from current version, resets config");
			if (version.Value != "1.0.6")
			{
				configFile.Clear();
				DoConfig(configFile);
			}
			else if (RiskofOptions.enabled)
			{
				DoRiskOfOptions();
			}
		}

		internal static void DoRiskOfOptions()
		{
			RiskofOptions.AddOption(damage, 0f, 1.5f);
			RiskofOptions.AddOption(bleedChance, 0f, 100f, "{0:f0}");
			RiskofOptions.AddOption(procCoef, 0f, 2f);
			RiskofOptions.AddOption(cooldown, 0.5f, 6f);
			RiskofOptions.AddOption(interval, 0f, 1.5f);
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void ReloadConfig(ConCommandArgs args)
		{
			configFile.Reload();
			Debug.Log((object)"Cleaverang config reloaded");
		}
	}
	internal class Content : IContentPackProvider
	{
		private static AssetBundle assetBundle;

		internal static ContentPack contentPack;

		internal static GameObject cleaverangPrefab;

		internal static GameObject cleaverangBoostedPrefab;

		internal static SkillDef cSkillDef;

		internal static SkillDef cBoostedSkillDef;

		public string identifier => "dolso.Cleaverang";

		private static string directory => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args)
		{
			AssetBundleCreateRequest assetBundleRequest = AssetBundle.LoadFromFileAsync(Path.Combine(directory, "cleaverang"));
			yield return LoadAsync((AsyncOperation)(object)assetBundleRequest, args);
			assetBundle = assetBundleRequest.assetBundle;
			AssetBundleRequest serializableContentPack = assetBundle.LoadAssetAsync<SerializableContentPack>("Cleaverang ContentPack");
			yield return LoadAsync((AsyncOperation)(object)serializableContentPack, args);
			Object asset = serializableContentPack.asset;
			contentPack = ((SerializableContentPack)((asset is SerializableContentPack) ? asset : null)).CreateContentPack();
			yield return DoProjectiles();
			yield return DoSkills();
			if (RiskofOptions.enabled)
			{
				yield return DoRiskOfOptions();
			}
			static IEnumerator LoadAsync(AsyncOperation request, LoadStaticContentAsyncArgs val)
			{
				while (!request.isDone)
				{
					val.ReportProgress(request.progress);
					yield return null;
				}
			}
		}

		public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args)
		{
			ContentPack.Copy(contentPack, args.output);
			yield break;
		}

		public IEnumerator FinalizeAsync(FinalizeAsyncArgs args)
		{
			yield break;
		}

		private static IEnumerator DoProjectiles()
		{
			AsyncOperationHandle<GameObject> sawAsync = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Saw/Sawmerang.prefab");
			AsyncOperationHandle<GameObject> muzzleFlashAsync = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/DLC2/Chef/MuzzleflashChefDiceReturn.prefab");
			AsyncOperationHandle<BuffDef> chefBuffAsync = Addressables.LoadAssetAsync<BuffDef>((object)"RoR2/DLC2/Chef/Buffs/bdCookingChopped.asset");
			AssetBundleRequest redMatAsync = assetBundle.LoadAssetAsync<Texture>("texSawmerangRedDiffuse");
			yield return sawAsync;
			yield return muzzleFlashAsync;
			yield return chefBuffAsync;
			yield return redMatAsync;
			ThrowCleaverang.muzzleFlashPrefab = muzzleFlashAsync.Result;
			GameObject result = sawAsync.Result;
			GameObject obj = (cleaverangPrefab = contentPack.projectilePrefabs.Find("CleaverangProjectile"));
			GameObject val = (cleaverangBoostedPrefab = contentPack.projectilePrefabs.Find("CleaverangBoostedProjectile"));
			ProjectileController component = result.GetComponent<ProjectileController>();
			ProjectileController component2 = obj.GetComponent<ProjectileController>();
			ProjectileController component3 = val.GetComponent<ProjectileController>();
			component2.ghostPrefabAddress = component.ghostPrefabAddress;
			component2.flightSoundLoop = (component3.flightSoundLoop = component.flightSoundLoop);
			component3.ghostPrefab = Utilities.CreatePrefab(component.ghostPrefabAddress.LoadAssetAsync().WaitForCompletion(), "CleaverangBoostedGhost");
			MeshRenderer componentInChildren = component3.ghostPrefab.GetComponentInChildren<MeshRenderer>();
			((Renderer)componentInChildren).material = new Material(((Renderer)componentInChildren).material)
			{
				name = "matSawmerangRed",
				mainTexture = (Texture)/*isinst with value type is only supported in some contexts*/
			};
			BoomerangProjectile component4 = result.GetComponent<BoomerangProjectile>();
			BoomerangProjectile component5 = obj.GetComponent<BoomerangProjectile>();
			BoomerangProjectile component6 = val.GetComponent<BoomerangProjectile>();
			component5.impactSpark = (component6.impactSpark = component4.impactSpark);
			ProjectileDotZone component7 = result.GetComponent<ProjectileDotZone>();
			ProjectileDotZone component8 = obj.GetComponent<ProjectileDotZone>();
			ProjectileDotZone component9 = val.GetComponent<ProjectileDotZone>();
			component8.impactEffect = (component9.impactEffect = component7.impactEffect);
			component8.overlapProcCoefficient = (component9.overlapProcCoefficient = Config.procCoef.Value);
			ProjectileOverlapAttack component10 = result.GetComponent<ProjectileOverlapAttack>();
			ProjectileOverlapAttack component11 = obj.GetComponent<ProjectileOverlapAttack>();
			ProjectileOverlapAttack component12 = val.GetComponent<ProjectileOverlapAttack>();
			component11.impactEffect = (component12.impactEffect = component10.impactEffect);
			ProjectileInflictTimedBuff component13 = obj.GetComponent<ProjectileInflictTimedBuff>();
			ProjectileInflictTimedBuff component14 = val.GetComponent<ProjectileInflictTimedBuff>();
			component13.buffDef = (component14.buffDef = chefBuffAsync.Result);
			sawAsync.Release();
		}

		private static IEnumerator DoSkills()
		{
			AsyncOperationHandle<GameObject> chefBodyAsync = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/DLC2/Chef/ChefBody.prefab");
			yield return chefBodyAsync;
			cSkillDef = contentPack.skillDefs.Find("CleaverangSkillDef");
			cBoostedSkillDef = contentPack.skillDefs.Find("CleaverangBoostedSkillDef");
			cSkillDef.baseRechargeInterval = (cBoostedSkillDef.baseRechargeInterval = Config.cooldown.Value);
			cSkillDef.activationState = (cBoostedSkillDef.activationState = new SerializableEntityStateType(typeof(ThrowCleaverang)));
			contentPack.entityStateTypes.Add(new Type[1] { typeof(ThrowCleaverang) });
			ref Variant[] variants = ref chefBodyAsync.Result.GetComponent<SkillLocator>().primary.skillFamily.variants;
			Variant val = new Variant
			{
				skillDef = cSkillDef
			};
			((Variant)(ref val)).viewableNode = new Node(cSkillDef.skillNameToken, false, (Node)null);
			ArrayUtils.ArrayAppend<Variant>(ref variants, ref val);
		}

		private static IEnumerator DoRiskOfOptions()
		{
			AssetBundleRequest sprite = assetBundle.LoadAssetAsync<Sprite>("CleaverangIcon");
			yield return sprite;
			Object asset = sprite.asset;
			RiskofOptions.SetSprite((Sprite)(object)((asset is Sprite) ? asset : null));
		}
	}
	internal static class Hooks
	{
		private static int cleaverangIndex;

		private static int cleaverangBoostedIndex;

		internal static void DoHooks()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			HookManager.Hook(typeof(ChefController), "OverrideYesChefSkillBySlot", (Delegate)new Func<Func<ChefController, SkillSlot, SkillStateOverrideData, bool>, ChefController, SkillSlot, SkillStateOverrideData, bool>(AddOverride_On_ChefController_OverrideYesChefSkillBySlot));
			HookManager.Hook(typeof(GlobalEventManager), "ProcessHitEnemy", new Manipulator(SetBleed_IL_GlobalEventManager_OnHitEnemy));
			HookManager.Hook(typeof(BoomerangProjectile), "Start", (Delegate)new Action<Action<BoomerangProjectile>, BoomerangProjectile>(SetVelocity_On_BoomerangProjectile_Start));
			HookManager.Hook(typeof(BoomerangProjectile), "FixedUpdate", new Manipulator(ChangeFlightPath_IL_BoomerangProjectile_FixedUpdate));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(OnRoR2Loaded));
		}

		private static void OnRoR2Loaded()
		{
			cleaverangIndex = ProjectileCatalog.FindProjectileIndex("CleaverangProjectile");
			cleaverangBoostedIndex = ProjectileCatalog.FindProjectileIndex("CleaverangBoostedProjectile");
		}

		private static bool AddOverride_On_ChefController_OverrideYesChefSkillBySlot(Func<ChefController, SkillSlot, SkillStateOverrideData, bool> orig, ChefController self, SkillSlot slot, SkillStateOverrideData skillOverrideData)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if ((int)slot == 0 && (Object)(object)self.skillLocator.primary.skillDef == (Object)(object)Content.cSkillDef)
			{
				skillOverrideData.primarySkillOverride = Content.cBoostedSkillDef;
				return true;
			}
			return orig(self, slot, skillOverrideData);
		}

		private static void SetBleed_IL_GlobalEventManager_OnHitEnemy(ILContext il)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			VariableDefinition val2 = ((IEnumerable<VariableDefinition>)val.Body.Variables).First((VariableDefinition a) => ((MemberReference)((VariableReference)a).VariableType).Name == typeof(CharacterMaster).Name);
			VariableDefinition val3 = ((IEnumerable<VariableDefinition>)val.Body.Variables).First((VariableDefinition a) => ((MemberReference)((VariableReference)a).VariableType).Name == typeof(BoomerangProjectile).Name);
			ILLabel branchFalse = null;
			int sawBleedIndex = -1;
			if (val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction a) => ILPatternMatchingExt.MatchLdsfld(a, typeof(Equipment), "Saw")
			}) && val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction a) => ILPatternMatchingExt.MatchBneUn(a, ref branchFalse)
			}) && val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction a) => ILPatternMatchingExt.MatchStloc(a, ref sawBleedIndex)
			}))
			{
				val.GotoLabel(branchFalse, (MoveType)1, false);
				val.Emit(OpCodes.Ldloc, val2);
				val.Emit(OpCodes.Ldloc, val3);
				val.Emit(OpCodes.Ldloca, sawBleedIndex);
				val.EmitDelegate<<>A{00000040}<CharacterMaster, BoomerangProjectile, int>>((<>A{00000040}<CharacterMaster, BoomerangProjectile, int>)delegate(CharacterMaster master, BoomerangProjectile boomerang, ref int sawBleed)
				{
					if (boomerang.projectileController != null)
					{
						int catalogIndex = boomerang.projectileController.catalogIndex;
						if (catalogIndex == cleaverangIndex)
						{
							sawBleed = 0;
						}
						else if (catalogIndex == cleaverangBoostedIndex)
						{
							sawBleed = (Util.CheckRoll(Config.bleedChance.Value, master) ? 1 : 0);
						}
					}
				});
			}
			else
			{
				val.LogErrorCaller("saw bleed");
			}
		}

		private static void SetVelocity_On_BoomerangProjectile_Start(Action<BoomerangProjectile> orig, BoomerangProjectile self)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			orig(self);
			if (self.projectileController.catalogIndex == cleaverangBoostedIndex)
			{
				self.rigidbody.velocity = self.travelSpeed * ((Component)self).transform.forward;
			}
		}

		private static void ChangeFlightPath_IL_BoomerangProjectile_FixedUpdate(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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 a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, typeof(Rigidbody), "set_velocity")
			}))
			{
				ILLabel val2 = val.MarkLabel();
				if (val.TryGotoPrev(new Func<Instruction, bool>[1]
				{
					(Instruction a) => ILPatternMatchingExt.MatchLdfld(a, typeof(BoomerangProjectile), "rigidbody")
				}))
				{
					val.EmitDelegate<Func<BoomerangProjectile, bool>>((Func<BoomerangProjectile, bool>)((BoomerangProjectile self) => self.projectileController.catalogIndex == cleaverangBoostedIndex));
					val.Emit(OpCodes.Brtrue, (object)val2);
					val.Emit(OpCodes.Ldarg_0);
					return;
				}
			}
			val.LogErrorCaller("");
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("dolso.Cleaverang", "Cleaverang", "1.0.6")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "dolso.Cleaverang";

		internal const string Version = "1.0.6";

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Config.DoConfig(((BaseUnityPlugin)this).Config);
			ConfigEvents();
			Hooks.DoHooks();
			ContentManager.collectContentPackProviders += new CollectContentPackProvidersDelegate(CollectContentPack);
			Language.collectLanguageRootFolders += CollectLanguageFolder;
		}

		private static void CollectContentPack(AddContentPackProviderDelegate addContentPackProvider)
		{
			addContentPackProvider.Invoke((IContentPackProvider)(object)new Content());
		}

		private void CollectLanguageFolder(List<string> list)
		{
			list.Add(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Language"));
		}

		private static void ConfigEvents()
		{
			Config.cooldown.SettingChanged += delegate
			{
				Content.cSkillDef.baseRechargeInterval = Config.cooldown.Value;
				Content.cBoostedSkillDef.baseRechargeInterval = Config.cooldown.Value;
			};
			Config.procCoef.SettingChanged += delegate
			{
				Content.cleaverangPrefab.GetComponent<ProjectileDotZone>().overlapProcCoefficient = Config.procCoef.Value;
				Content.cleaverangBoostedPrefab.GetComponent<ProjectileDotZone>().overlapProcCoefficient = Config.procCoef.Value;
			};
		}
	}
	internal class ThrowCleaverang : BaseState
	{
		internal static GameObject muzzleFlashPrefab;

		private float baseDuration;

		private bool boosted;

		public override void OnEnter()
		{
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			((BaseState)this).OnEnter();
			boosted = ((EntityState)this).characterBody.HasBuff(Buffs.Boosted);
			if (boosted && NetworkServer.active)
			{
				((EntityState)this).characterBody.RemoveBuff(Buffs.Boosted);
			}
			baseDuration = Config.interval.Value;
			float num = baseDuration / base.attackSpeedStat;
			((BaseState)this).StartAimMode(num + 2f, false);
			if (boosted)
			{
				((EntityState)this).PlayAnimation("Gesture, Override", "FireSliceAndDice", "FireSliceAndDice.playbackRate", num, 0f);
				((EntityState)this).PlayAnimation("Gesture, Additive", "FireSliceAndDice", "FireSliceAndDice.playbackRate", num, 0f);
				Util.PlaySound("Play_chef_skill1_boosted_shoot", ((EntityState)this).gameObject);
			}
			else
			{
				((EntityState)this).PlayAnimation("Gesture, Override", "FireDice", "FireDice.playbackRate", num, 0f);
				((EntityState)this).PlayAnimation("Gesture, Additive", "FireDice", "FireDice.playbackRate", num, 0f);
				Util.PlaySound("Play_chef_skill1_shoot", ((EntityState)this).gameObject);
			}
			EffectManager.SimpleMuzzleFlash(muzzleFlashPrefab, ((Component)((EntityState)this).characterBody.aimOriginTransform).gameObject, "MouthMuzzle", false);
			if (((EntityState)this).isAuthority)
			{
				Ray aimRay = ((BaseState)this).GetAimRay();
				Quaternion val = Util.QuaternionSafeLookRotation(((Ray)(ref aimRay)).direction);
				if (boosted)
				{
					GameObject cleaverangBoostedPrefab = Content.cleaverangBoostedPrefab;
					Quaternion val2 = Quaternion.AngleAxis(90f, ((Ray)(ref aimRay)).direction);
					Quaternion val3 = val * Quaternion.Euler(0f, 15f, 0f);
					FireSingleProjectile(cleaverangBoostedPrefab, ((Ray)(ref aimRay)).origin, val);
					FireSingleProjectile(cleaverangBoostedPrefab, ((Ray)(ref aimRay)).origin, val3);
					val3 = val2 * val3;
					FireSingleProjectile(cleaverangBoostedPrefab, ((Ray)(ref aimRay)).origin, val3);
					val3 = val2 * val3;
					FireSingleProjectile(cleaverangBoostedPrefab, ((Ray)(ref aimRay)).origin, val3);
					val3 = val2 * val3;
					FireSingleProjectile(cleaverangBoostedPrefab, ((Ray)(ref aimRay)).origin, val3);
				}
				else
				{
					FireSingleProjectile(Content.cleaverangPrefab, ((Ray)(ref aimRay)).origin, val);
				}
			}
		}

		private void FireSingleProjectile(GameObject prefab, Vector3 origin, Quaternion rotation)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			ProjectileManager.instance.FireProjectile(new FireProjectileInfo
			{
				projectilePrefab = prefab,
				position = origin,
				rotation = rotation,
				owner = ((EntityState)this).gameObject,
				damage = base.damageStat * Config.damage.Value,
				crit = Util.CheckRoll(base.critStat, ((EntityState)this).characterBody.master),
				force = 0f
			});
		}

		public override void FixedUpdate()
		{
			((EntityState)this).FixedUpdate();
			if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= baseDuration / ((EntityState)this).characterBody.attackSpeed)
			{
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		public override void OnExit()
		{
			ChefController component = ((EntityState)this).GetComponent<ChefController>();
			component.SetYesChefState(false);
			if (((EntityState)this).isAuthority)
			{
				component.ClearSkillOverrides();
			}
			if (NetworkServer.active)
			{
				((EntityState)this).characterBody.RemoveBuff(Buffs.boostedFireEffect);
			}
			((EntityState)this).OnExit();
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			return (InterruptPriority)1;
		}
	}
}