using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("SoulcatcherTickBlobFix")]
[assembly: AssemblyConfiguration("release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SoulcatcherTickBlobFix")]
[assembly: AssemblyTitle("SoulcatcherTickBlobFix")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 SoulcatcherTickBlobFix
{
[BepInPlugin("ru.gerbesh.soulcatcher.tickblobfix", "Soulcatcher Tick + Blob Fix", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class Plugin : BaseUnityPlugin
{
public const string PluginGuid = "ru.gerbesh.soulcatcher.tickblobfix";
public const string PluginName = "Soulcatcher Tick + Blob Fix";
public const string PluginVersion = "1.0.0";
internal static ManualLogSource Log;
private Harmony _harmony;
private bool _jumpTranspilerUnpatched;
private void Awake()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
UnpatchSoulcatcherJumpTranspiler();
_harmony = new Harmony("ru.gerbesh.soulcatcher.tickblobfix");
_harmony.PatchAll(Assembly.GetExecutingAssembly());
}
private void UnpatchSoulcatcherJumpTranspiler()
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
if (_jumpTranspilerUnpatched)
{
return;
}
try
{
MethodInfo methodInfo = AccessTools.Method(typeof(Character), "Jump", (Type[])null, (Type[])null);
if (methodInfo != null)
{
new Harmony("Soulcatcher").Unpatch((MethodBase)methodInfo, (HarmonyPatchType)3, "Soulcatcher");
_jumpTranspilerUnpatched = true;
}
}
catch
{
}
}
private void Start()
{
UnpatchSoulcatcherJumpTranspiler();
}
private void OnDestroy()
{
try
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
catch
{
}
}
}
internal static class ReflectionExtensions
{
internal static Type[] GetTypesSafe(this Assembly asm)
{
try
{
return asm.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
return ex.Types.Where((Type t) => t != null).ToArray();
}
catch
{
return Array.Empty<Type>();
}
}
}
internal static class EffectConfigTypeCache
{
private static readonly object LockObj = new object();
private static readonly Dictionary<string, Type> Cache = new Dictionary<string, Type>(StringComparer.Ordinal);
internal static Type GetConfigType(string declaringTypeName)
{
lock (LockObj)
{
if (Cache.TryGetValue(declaringTypeName, out var value))
{
return value;
}
value = FindConfigType(declaringTypeName);
Cache[declaringTypeName] = value;
return value;
}
}
private static Type FindConfigType(string declaringTypeName)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
Type[] typesSafe = assemblies[i].GetTypesSafe();
foreach (Type type in typesSafe)
{
if (!(type == null) && !(type.Name != "Config") && type.IsNested && type.DeclaringType?.Name == declaringTypeName)
{
return type;
}
}
}
return null;
}
}
internal static class JewelcraftingApi
{
private static readonly object LockObj = new object();
private static MethodInfo _getEffectPowerGeneric;
private static Type _defaultPowerType;
private static void EnsureApi()
{
if (_getEffectPowerGeneric != null && _defaultPowerType != null)
{
return;
}
lock (LockObj)
{
if (_getEffectPowerGeneric != null && _defaultPowerType != null)
{
return;
}
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
Type[] typesSafe = assemblies[i].GetTypesSafe();
foreach (Type type in typesSafe)
{
if (type == null || !type.IsAbstract || !type.IsSealed)
{
continue;
}
MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo methodInfo in methods)
{
if (!(methodInfo.Name == "GetEffectPower") || !methodInfo.IsGenericMethodDefinition)
{
continue;
}
ParameterInfo[] parameters = methodInfo.GetParameters();
if (parameters.Length != 2 || !(parameters[1].ParameterType == typeof(string)))
{
continue;
}
_getEffectPowerGeneric = methodInfo;
if (!(_defaultPowerType == null))
{
return;
}
Assembly assembly = methodInfo.DeclaringType?.Assembly;
if (assembly != null)
{
_defaultPowerType = assembly.GetTypesSafe().FirstOrDefault((Type x) => x != null && x.Name == "DefaultPower" && x.IsValueType);
}
return;
}
}
}
}
}
internal static float GetEffectValue(Player player, string effectName, string declaringTypeName)
{
if ((Object)(object)player == (Object)null)
{
return 0f;
}
EnsureApi();
if (_getEffectPowerGeneric == null)
{
return 0f;
}
Type configType = EffectConfigTypeCache.GetConfigType(declaringTypeName);
if (configType != null)
{
float num = TryGetEffectValue(player, effectName, configType);
if (num != 0f)
{
return num;
}
}
if (_defaultPowerType != null)
{
float num2 = TryGetEffectValue(player, effectName, _defaultPowerType);
if (num2 != 0f)
{
return num2;
}
}
return 0f;
}
private static float TryGetEffectValue(Player player, string effectName, Type cfgType)
{
if (cfgType == null)
{
return 0f;
}
try
{
object obj = _getEffectPowerGeneric.MakeGenericMethod(cfgType).Invoke(null, new object[2] { player, effectName });
if (obj == null)
{
return 0f;
}
FieldInfo fieldInfo = cfgType.GetField("Value", BindingFlags.Instance | BindingFlags.Public) ?? cfgType.GetField("Power", BindingFlags.Instance | BindingFlags.Public);
if (fieldInfo != null)
{
return Convert.ToSingle(fieldInfo.GetValue(obj));
}
PropertyInfo propertyInfo = cfgType.GetProperty("Value", BindingFlags.Instance | BindingFlags.Public) ?? cfgType.GetProperty("Power", BindingFlags.Instance | BindingFlags.Public);
if (propertyInfo != null)
{
return Convert.ToSingle(propertyInfo.GetValue(obj, null));
}
}
catch
{
}
return 0f;
}
}
[HarmonyPatch(typeof(Player), "GetEquipmentEitrRegenModifier")]
internal static class TickGemEitrRegenPatch
{
private const string EffectName = "Tick Soul Power";
private const string DeclaringTypeName = "Tick_Soul_Power";
private static void Postfix(Player __instance, ref float __result)
{
if (!((Object)(object)__instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
{
float effectValue = JewelcraftingApi.GetEffectValue(__instance, "Tick Soul Power", "Tick_Soul_Power");
if (effectValue > 0f)
{
__result += effectValue / 100f;
}
}
}
}
internal static class BlobVfxCache
{
private static bool _searched;
private static GameObject _vfx;
internal static GameObject GetVfx()
{
if (_searched)
{
return _vfx;
}
_searched = true;
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
Type[] typesSafe = assemblies[i].GetTypesSafe();
foreach (Type type in typesSafe)
{
if (!(type?.Name != "Blob_Soul_Power"))
{
FieldInfo field = type.GetField("VFX", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null && typeof(GameObject).IsAssignableFrom(field.FieldType))
{
object? value = field.GetValue(null);
return _vfx = (GameObject)((value is GameObject) ? value : null);
}
}
}
}
return null;
}
}
[HarmonyPatch(typeof(Character), "Jump")]
internal static class BlobGemJumpPatch
{
private const string EffectName = "Blob Soul Power";
private const string DeclaringTypeName = "Blob_Soul_Power";
private static readonly FieldRef<Character, ZNetView> NViewRef = AccessTools.FieldRefAccess<Character, ZNetView>("m_nview");
private static readonly FieldRef<Character, Rigidbody> BodyRef = AccessTools.FieldRefAccess<Character, Rigidbody>("m_body");
private static void Prefix(Character __instance, ref bool __state)
{
__state = (Object)(object)__instance != (Object)null && __instance.IsOnGround();
}
private static void Postfix(Character __instance, bool __state)
{
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
Player val = (Player)(object)((__instance is Player) ? __instance : null);
if ((Object)(object)val == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || !__state)
{
return;
}
ZNetView val2 = NViewRef.Invoke((Character)(object)val);
if ((Object)(object)val2 == (Object)null || !val2.IsOwner())
{
return;
}
Rigidbody val3 = BodyRef.Invoke((Character)(object)val);
if ((Object)(object)val3 == (Object)null)
{
return;
}
float effectValue = JewelcraftingApi.GetEffectValue(val, "Blob Soul Power", "Blob_Soul_Power");
if (!(effectValue <= 0f))
{
Vector3 val4 = Vector3.up * effectValue * 0.5f + ((Component)val).transform.forward * effectValue * 6f;
val3.AddForce(val4, (ForceMode)2);
GameObject vfx = BlobVfxCache.GetVfx();
if ((Object)(object)vfx != (Object)null)
{
Object.Instantiate<GameObject>(vfx, ((Component)val).transform.position, Quaternion.identity);
}
}
}
}
[HarmonyPatch(typeof(SEMan), "ModifySkillLevel")]
internal static class DvergerBloodMageSkillPatch
{
private const string EffectName = "Dverger Blood Mage Soul Power";
private const string DeclaringTypeName = "Dverger_BloodMage_Soul_Power";
private static readonly FieldRef<SEMan, Character> CharacterRef = AccessTools.FieldRefAccess<SEMan, Character>("m_character");
private static void Postfix(SEMan __instance, SkillType skill, ref float level)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Invalid comparison between Unknown and I4
if ((int)skill != 10 || __instance == null)
{
return;
}
Character obj = CharacterRef.Invoke(__instance);
Player val = (Player)(object)((obj is Player) ? obj : null);
if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer))
{
float effectValue = JewelcraftingApi.GetEffectValue(val, "Dverger Blood Mage Soul Power", "Dverger_BloodMage_Soul_Power");
if (effectValue > 0f)
{
level += effectValue;
}
}
}
}
[HarmonyPatch]
internal static class DvergerBloodMageCompendiumPatch
{
private const string EffectNameKey = "$jc_effect_dverger_blood_mage_soul_power";
private const string SkillNameKey = "$skill_bloodmagic";
private const string EffectName = "Dverger Blood Mage Soul Power";
private const string DeclaringTypeName = "Dverger_BloodMage_Soul_Power";
private static readonly FieldInfo TextAreaField = AccessTools.Field(typeof(TextsDialog), "m_textArea");
private static MethodBase TargetMethod()
{
Type type = AccessTools.TypeByName("Jewelcrafting.CompendiumDisplay+DisplayGemEffectOverview");
if (!(type == null))
{
return AccessTools.Method(type, "Render", (Type[])null, (Type[])null);
}
return null;
}
private static void Postfix(TextsDialog compendium)
{
if ((Object)(object)compendium == (Object)null)
{
return;
}
Player localPlayer = Player.m_localPlayer;
if ((Object)(object)localPlayer == (Object)null || JewelcraftingApi.GetEffectValue(localPlayer, "Dverger Blood Mage Soul Power", "Dverger_BloodMage_Soul_Power") <= 0f)
{
return;
}
string value = LocalizationHelper.Localize("$jc_effect_dverger_blood_mage_soul_power");
string text = LocalizationHelper.Localize("$skill_bloodmagic");
string text2 = "\n<color=yellow>" + text + "</color>: " + Mathf.FloorToInt(((Character)localPlayer).GetSkillLevel((SkillType)10));
object? obj = TextAreaField?.GetValue(compendium);
Component val = (Component)((obj is Component) ? obj : null);
Transform val2 = (((Object)(object)val != (Object)null) ? val.transform.parent : null);
if ((Object)(object)val2 == (Object)null)
{
return;
}
Component[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Component>(true);
foreach (Component target in componentsInChildren)
{
string text3 = TextComponentAccess.GetText(target);
if (!string.IsNullOrEmpty(text3) && text3.Contains(value) && !text3.Contains(text))
{
TextComponentAccess.SetText(target, text3 + text2);
}
}
}
}
[HarmonyPatch(typeof(TextsDialog), "AddActiveEffects")]
internal static class DvergerBloodMageActiveEffectsPatch
{
private const string EffectName = "Dverger Blood Mage Soul Power";
private const string DeclaringTypeName = "Dverger_BloodMage_Soul_Power";
private const string SkillNameKey = "$skill_bloodmagic";
private static readonly FieldInfo TextsField = AccessTools.Field(typeof(TextsDialog), "m_texts");
private static void Postfix(TextsDialog __instance)
{
if ((Object)(object)__instance == (Object)null || !(TextsField?.GetValue(__instance) is IList list) || list.Count == 0)
{
return;
}
Player localPlayer = Player.m_localPlayer;
if ((Object)(object)localPlayer == (Object)null || JewelcraftingApi.GetEffectValue(localPlayer, "Dverger Blood Mage Soul Power", "Dverger_BloodMage_Soul_Power") <= 0f)
{
return;
}
string text = LocalizationHelper.Localize("$skill_bloodmagic");
int num = Mathf.FloorToInt(((Character)localPlayer).GetSkillLevel((SkillType)10));
string value = "\n" + text + ":";
string text2 = "\n" + text + ": " + num;
object target = list[0];
string text3 = TextComponentAccess.GetText(target);
if (string.IsNullOrEmpty(text3))
{
return;
}
int num2 = text3.IndexOf(value, StringComparison.Ordinal);
if (num2 >= 0)
{
int num3 = text3.IndexOf('\n', num2 + 1);
if (num3 < 0)
{
num3 = text3.Length;
}
text3 = text3.Remove(num2, num3 - num2);
}
text3 += text2;
TextComponentAccess.SetText(target, text3);
}
}
internal static class LocalizationHelper
{
private static Type _type;
private static PropertyInfo _instanceProp;
private static MethodInfo _localizeMethod;
internal static string Localize(string key)
{
if (string.IsNullOrEmpty(key))
{
return key;
}
Ensure();
if (_instanceProp == null || _localizeMethod == null)
{
return key;
}
try
{
object value = _instanceProp.GetValue(null, null);
if (value == null)
{
return key;
}
return (_localizeMethod.Invoke(value, new object[1] { key }) as string) ?? key;
}
catch
{
return key;
}
}
private static void Ensure()
{
if (!(_localizeMethod != null))
{
_type = typeof(Player).Assembly.GetTypesSafe().FirstOrDefault((Type t) => t != null && t.Name == "Localization");
if (!(_type == null))
{
_instanceProp = _type.GetProperty("instance", BindingFlags.Static | BindingFlags.Public);
_localizeMethod = _type.GetMethod("Localize", new Type[1] { typeof(string) });
}
}
}
}
internal static class TextComponentAccess
{
internal static string GetText(object target)
{
if (target == null)
{
return null;
}
PropertyInfo property = target.GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
if (property != null && property.PropertyType == typeof(string))
{
return property.GetValue(target, null) as string;
}
FieldInfo field = target.GetType().GetField("m_text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null && field.FieldType == typeof(string))
{
return field.GetValue(target) as string;
}
return null;
}
internal static void SetText(object target, string value)
{
if (target == null)
{
return;
}
PropertyInfo property = target.GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
if (property != null && property.PropertyType == typeof(string))
{
property.SetValue(target, value, null);
return;
}
FieldInfo field = target.GetType().GetField("m_text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null && field.FieldType == typeof(string))
{
field.SetValue(target, value);
}
}
}
}