using System;
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 System.Text;
using BepInEx;
using BepInEx.Logging;
using EntityStates;
using Microsoft.CodeAnalysis;
using On.RoR2;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.Skills;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("VoidStance")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+71d41ee0805864580ef5297067384fa6cd5f7753")]
[assembly: AssemblyProduct("VoidStance")]
[assembly: AssemblyTitle("VoidStance")]
[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 VoidStanceMod
{
[BepInPlugin("com.MyName.VoidStance", "VoidStance", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
public class VoidStanceToggle : BaseSkillState
{
public override void OnEnter()
{
((BaseState)this).OnEnter();
CharacterBody characterBody = ((EntityState)this).characterBody;
if (characterBody != null)
{
characterBody.SetAimTimer(0.2f);
}
((EntityState)this).PlayCrossfade("Gesture, Additive", "BufferEmpty", "BufferEmpty.playbackRate", 0.1f, 0.05f);
if (!Object.op_Implicit((Object)(object)((EntityState)this).characterBody))
{
return;
}
VoidStanceController voidStanceController = ((Component)((EntityState)this).characterBody).GetComponent<VoidStanceController>();
if (!Object.op_Implicit((Object)(object)voidStanceController))
{
voidStanceController = ((Component)((EntityState)this).characterBody).gameObject.AddComponent<VoidStanceController>();
}
if (!NetworkServer.active)
{
VoidStanceNet component = ((Component)((EntityState)this).characterBody).GetComponent<VoidStanceNet>();
if ((Object)(object)component != (Object)null)
{
component.RequestToggle();
return;
}
ManualLogSource log = Log;
if (log != null)
{
log.LogWarning((object)"[VoidStance] Net component missing on client.");
}
}
else
{
ServerToggleNow(voidStanceController);
}
}
private void ServerToggleNow(VoidStanceController ctrl)
{
ctrl.ResolveAndBindController();
if (ctrl.LockedIsHigh())
{
ctrl.GoControlledNow();
}
else
{
ctrl.GoCorruptedNow();
}
}
public override void FixedUpdate()
{
((EntityState)this).FixedUpdate();
if (((EntityState)this).fixedAge >= 0.2f)
{
((EntityState)this).outer.SetNextStateToMain();
}
}
public override InterruptPriority GetMinimumInterruptPriority()
{
return (InterruptPriority)1;
}
}
public const string PluginGUID = "com.MyName.VoidStance";
public const string PluginName = "VoidStance";
public const string PluginVer = "1.0.0";
internal static ManualLogSource Log;
internal static SkillDef StanceSkillDef;
private string _pluginDir;
private Sprite _modIcon;
private Sprite _specialIcon;
private void Awake()
{
//IL_0046: 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_00bd: 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_01bd: Unknown result type (might be due to invalid IL or missing references)
//IL_01c7: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
_pluginDir = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
_modIcon = LoadSprite("icon.png");
_specialIcon = LoadSprite("icon_special.png");
bool flag = default(bool);
ContentAddition.AddEntityState<VoidStanceToggle>(ref flag);
StanceSkillDef = ScriptableObject.CreateInstance<SkillDef>();
StanceSkillDef.skillName = "VOIDSTANCE_TOGGLE";
StanceSkillDef.skillNameToken = "VOIDSTANCE_TOGGLE_NAME";
StanceSkillDef.skillDescriptionToken = "VOIDSTANCE_TOGGLE_DESC";
StanceSkillDef.icon = (((Object)(object)_specialIcon != (Object)null) ? _specialIcon : _modIcon);
StanceSkillDef.activationState = new SerializableEntityStateType(typeof(VoidStanceToggle));
StanceSkillDef.activationStateMachineName = "Weapon";
StanceSkillDef.baseMaxStock = 1;
StanceSkillDef.rechargeStock = 1;
StanceSkillDef.baseRechargeInterval = 2f;
StanceSkillDef.beginSkillCooldownOnSkillEnd = true;
StanceSkillDef.canceledFromSprinting = false;
StanceSkillDef.cancelSprintingOnActivation = false;
StanceSkillDef.fullRestockOnAssign = true;
StanceSkillDef.isCombatSkill = true;
StanceSkillDef.interruptPriority = (InterruptPriority)0;
StanceSkillDef.mustKeyPress = true;
StanceSkillDef.requiredStock = 1;
StanceSkillDef.resetCooldownTimerOnUse = false;
ContentAddition.AddSkillDef(StanceSkillDef);
LanguageAPI.Add("VOIDSTANCE_TOGGLE_NAME", "Void Stance");
LanguageAPI.Add("VOIDSTANCE_TOGGLE_DESC", "Toggle between Controlled and Corrupted at will. Prevents passive corruption drift and auto-transforms.");
RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(InjectIntoVoidFiend));
CharacterBody.onBodyStartGlobal += TryAttachControllers;
CharacterBody.Start += new hook_Start(HookBodyStartAttach);
Log.LogInfo((object)"[VoidStance] Loaded 1.3.3");
}
private Sprite LoadSprite(string fileName)
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Expected O, but got Unknown
//IL_008c: 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)
try
{
if (string.IsNullOrEmpty(_pluginDir))
{
return null;
}
string path = Path.Combine(_pluginDir, fileName);
if (!File.Exists(path))
{
return null;
}
byte[] array = File.ReadAllBytes(path);
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
if (!ImageConversion.LoadImage(val, array))
{
return null;
}
((Texture)val).wrapMode = (TextureWrapMode)1;
((Texture)val).filterMode = (FilterMode)1;
return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
}
catch (Exception ex)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogWarning((object)("[VoidStance] LoadSprite failed for '" + fileName + "': " + ex.Message));
}
return null;
}
}
private void InjectIntoVoidFiend()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Expected O, but got Unknown
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
try
{
GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/DLC1/VoidSurvivor/VoidSurvivorBody.prefab").WaitForCompletion();
if (!Object.op_Implicit((Object)(object)val))
{
Log.LogError((object)"[VoidStance] Could not load VoidSurvivorBody.");
return;
}
SkillLocator component = val.GetComponent<SkillLocator>();
if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.special) || !Object.op_Implicit((Object)(object)component.special.skillFamily))
{
Log.LogError((object)"[VoidStance] Void Fiend special family not found.");
return;
}
SkillFamily skillFamily = component.special.skillFamily;
if (!skillFamily.variants.Any((Variant v) => (Object)(object)v.skillDef == (Object)(object)StanceSkillDef))
{
Array.Resize(ref skillFamily.variants, skillFamily.variants.Length + 1);
Variant[] variants = skillFamily.variants;
int num = variants.Length - 1;
Variant val2 = new Variant
{
skillDef = StanceSkillDef,
unlockableDef = null
};
((Variant)(ref val2)).viewableNode = new Node(StanceSkillDef.skillNameToken, false, (Node)null);
variants[num] = val2;
}
Log.LogInfo((object)"[VoidStance] Added 'Void Stance' to Void Fiend Special.");
}
catch (Exception ex)
{
Log.LogError((object)("[VoidStance] Injection failed: " + ex));
}
}
private void HookBodyStartAttach(orig_Start orig, CharacterBody self)
{
orig.Invoke(self);
TryAttachControllers(self);
}
private void TryAttachControllers(CharacterBody body)
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)body))
{
return;
}
if ((!Object.op_Implicit((Object)(object)((Component)body).gameObject) || ((Object)((Component)body).gameObject).name.IndexOf("VoidSurvivor", StringComparison.OrdinalIgnoreCase) < 0) && (string.IsNullOrEmpty(body.baseNameToken) || body.baseNameToken.IndexOf("VOID_SURVIVOR", StringComparison.OrdinalIgnoreCase) < 0))
{
string bodyName = BodyCatalog.GetBodyName(body.bodyIndex);
if (bodyName == null || bodyName.IndexOf("VoidSurvivor", StringComparison.OrdinalIgnoreCase) < 0)
{
return;
}
}
if (!Object.op_Implicit((Object)(object)((Component)body).GetComponent<VoidStanceController>()))
{
((Component)body).gameObject.AddComponent<VoidStanceController>();
}
if (!Object.op_Implicit((Object)(object)((Component)body).GetComponent<VoidStanceNet>()))
{
((Component)body).gameObject.AddComponent<VoidStanceNet>();
}
}
}
public class VoidStanceNet : NetworkBehaviour
{
private CharacterBody body;
private VoidStanceController ctrl;
private void Awake()
{
body = ((Component)this).GetComponent<CharacterBody>();
ctrl = ((Component)this).GetComponent<VoidStanceController>();
}
public void RequestToggle()
{
if (!((NetworkBehaviour)this).isServer)
{
CmdToggle();
}
else
{
ServerToggle();
}
}
[Command]
private void CmdToggle()
{
ServerToggle();
}
private void ServerToggle()
{
if (!Object.op_Implicit((Object)(object)ctrl))
{
ctrl = ((Component)this).GetComponent<VoidStanceController>();
}
if (Object.op_Implicit((Object)(object)ctrl))
{
ctrl.ResolveAndBindController();
if (ctrl.LockedIsHigh())
{
ctrl.GoControlledNow();
}
else
{
ctrl.GoCorruptedNow();
}
TargetOnToggled(((NetworkBehaviour)this).connectionToClient, ctrl.LockedIsHigh());
}
}
[TargetRpc]
private void TargetOnToggled(NetworkConnection target, bool isCorrupted)
{
}
}
public class VoidStanceController : MonoBehaviour
{
private CharacterBody body;
private GenericSkill special;
private Component vfController;
private Transform boundTransform;
private FieldInfo fldCorruption;
private PropertyInfo propCorruption;
private FieldInfo fldIsCorrupted;
private FieldInfo fldCorruptionActive;
private FieldInfo fldMinThreshold;
private FieldInfo fldMaxThreshold;
private FieldInfo[] corruptionRelatedFloats;
private MethodInfo mEnterCorruption;
private MethodInfo mExitCorruption;
private MethodInfo mSetCorruptionActiveBool;
private MethodInfo mTryTransformToCorrupted;
private MethodInfo mTryTransformToBase;
private MethodInfo mRequestTransformationBool;
private float lockedCorruption = float.NaN;
private bool corruptionIsPercent = true;
private bool userChoseStance;
private bool overrideApplied;
private float rebindTick;
private bool dumped;
private void Start()
{
body = ((Component)this).GetComponent<CharacterBody>();
CharacterBody obj = body;
special = ((obj == null) ? null : obj.skillLocator?.special);
userChoseStance = HasVoidStanceSelected();
ResolveAndBindController();
SnapLockValue();
}
private void OnDestroy()
{
TryUnsetOverride();
}
private bool HasVoidStanceSelected()
{
if (!Object.op_Implicit((Object)(object)special) || (Object)(object)Plugin.StanceSkillDef == (Object)null)
{
return false;
}
return (Object)(object)special.skillDef == (Object)(object)Plugin.StanceSkillDef;
}
private bool FamilyContainsOurDef()
{
if (!Object.op_Implicit((Object)(object)special) || (Object)(object)special.skillFamily == (Object)null || (Object)(object)Plugin.StanceSkillDef == (Object)null)
{
return false;
}
SkillFamily skillFamily = special.skillFamily;
for (int i = 0; i < skillFamily.variants.Length; i++)
{
if ((Object)(object)skillFamily.variants[i].skillDef == (Object)(object)Plugin.StanceSkillDef)
{
return true;
}
}
return false;
}
private void TryApplyOverride()
{
if (!overrideApplied && Object.op_Implicit((Object)(object)special) && !((Object)(object)Plugin.StanceSkillDef == (Object)null) && FamilyContainsOurDef())
{
special.SetSkillOverride((object)body, Plugin.StanceSkillDef, (SkillOverridePriority)4);
overrideApplied = true;
}
}
private void TryUnsetOverride()
{
if (overrideApplied)
{
if (!Object.op_Implicit((Object)(object)special) || (Object)(object)Plugin.StanceSkillDef == (Object)null)
{
overrideApplied = false;
return;
}
special.UnsetSkillOverride((object)body, Plugin.StanceSkillDef, (SkillOverridePriority)4);
overrideApplied = false;
}
}
public void ForceDump()
{
DumpAllComponents();
}
private void FixedUpdate()
{
rebindTick -= Time.fixedDeltaTime;
if (rebindTick <= 0f)
{
rebindTick = 0.1f;
if (!Object.op_Implicit((Object)(object)vfController))
{
ResolveAndBindController();
}
}
if (HasVoidStanceSelected())
{
userChoseStance = true;
}
if (userChoseStance)
{
TryApplyOverride();
}
else
{
TryUnsetOverride();
}
if (NetworkServer.active && Object.op_Implicit((Object)(object)vfController) && userChoseStance)
{
StrongLockCorruption();
}
}
private void Update()
{
if (NetworkServer.active && Object.op_Implicit((Object)(object)vfController) && userChoseStance)
{
StrongLockCorruption();
}
}
public bool LockedIsHigh()
{
if (float.IsNaN(lockedCorruption))
{
lockedCorruption = ReadCorruption();
}
float num = (float.IsNaN(lockedCorruption) ? 0f : lockedCorruption);
return num > (corruptionIsPercent ? 50f : 0.5f);
}
public void GoCorruptedNow()
{
ResolveAndBindController();
if (HasVoidStanceSelected())
{
userChoseStance = true;
}
if (userChoseStance)
{
TryApplyOverride();
}
SafeInvoke(mSetCorruptionActiveBool, vfController, new object[1] { false });
SafeInvoke(mEnterCorruption, vfController, null);
SafeInvoke(mTryTransformToCorrupted, vfController, null);
SafeInvoke(mRequestTransformationBool, vfController, new object[1] { true });
SafeWriteBool(fldIsCorrupted, vfController, v: true);
SafeWriteBool(fldCorruptionActive, vfController, v: false);
lockedCorruption = (corruptionIsPercent ? 100f : 1f);
WriteCorruption(lockedCorruption);
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[VoidStance] -> Corrupted");
}
}
public void GoControlledNow()
{
ResolveAndBindController();
if (HasVoidStanceSelected())
{
userChoseStance = true;
}
if (userChoseStance)
{
TryApplyOverride();
}
SafeInvoke(mSetCorruptionActiveBool, vfController, new object[1] { false });
SafeInvoke(mExitCorruption, vfController, null);
SafeInvoke(mTryTransformToBase, vfController, null);
SafeInvoke(mRequestTransformationBool, vfController, new object[1] { false });
SafeWriteBool(fldIsCorrupted, vfController, v: false);
SafeWriteBool(fldCorruptionActive, vfController, v: false);
lockedCorruption = 0f;
WriteCorruption(lockedCorruption);
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[VoidStance] -> Controlled");
}
}
public void ResolveAndBindController()
{
vfController = null;
boundTransform = null;
fldCorruption = null;
propCorruption = null;
fldIsCorrupted = null;
fldCorruptionActive = null;
fldMinThreshold = null;
fldMaxThreshold = null;
corruptionRelatedFloats = null;
mEnterCorruption = null;
mExitCorruption = null;
mSetCorruptionActiveBool = null;
mTryTransformToCorrupted = null;
mTryTransformToBase = null;
mRequestTransformationBool = null;
if (!Object.op_Implicit((Object)(object)body))
{
return;
}
List<Transform> list = new List<Transform> { body.transform };
ModelLocator modelLocator = body.modelLocator;
if (Object.op_Implicit((Object)(object)modelLocator) && Object.op_Implicit((Object)(object)modelLocator.modelTransform))
{
list.Add(modelLocator.modelTransform);
}
if (Object.op_Implicit((Object)(object)modelLocator) && Object.op_Implicit((Object)(object)modelLocator.modelBaseTransform))
{
list.Add(modelLocator.modelBaseTransform);
}
if (Object.op_Implicit((Object)(object)body.masterObject))
{
list.Add(body.masterObject.transform);
}
foreach (Transform item in list.Where((Transform x) => Object.op_Implicit((Object)(object)x)))
{
Component[] componentsInChildren = ((Component)item).GetComponentsInChildren<Component>(true);
foreach (Component val in componentsInChildren)
{
if (Object.op_Implicit((Object)(object)val) && ((object)val).GetType().Name.Equals("VoidSurvivorController", StringComparison.OrdinalIgnoreCase) && BindFromComponent(val))
{
return;
}
}
}
foreach (Transform item2 in list.Where((Transform x) => Object.op_Implicit((Object)(object)x)))
{
Component[] componentsInChildren2 = ((Component)item2).GetComponentsInChildren<Component>(true);
foreach (Component val2 in componentsInChildren2)
{
if (Object.op_Implicit((Object)(object)val2))
{
Type type = ((object)val2).GetType();
if (HasAnyMethod(type, new string[10] { "EnterCorruption", "EnterCorrupted", "StartCorruption", "ExitCorruption", "ExitCorrupted", "StopCorruption", "SetCorruptionActive", "TryTransformToCorrupted", "TryTransformToBase", "RequestTransformation" }) && BindFromComponent(val2))
{
return;
}
}
}
}
foreach (Transform item3 in list.Where((Transform x) => Object.op_Implicit((Object)(object)x)))
{
Component[] componentsInChildren3 = ((Component)item3).GetComponentsInChildren<Component>(true);
foreach (Component val3 in componentsInChildren3)
{
if (Object.op_Implicit((Object)(object)val3) && HasPlausibleCorruptionValue(val3, out var _, out var _) && BindFromComponent(val3))
{
return;
}
}
}
if (!dumped)
{
dumped = true;
DumpAllComponents();
}
}
private bool BindFromComponent(Component c)
{
vfController = c;
boundTransform = c.transform;
Type type = ((object)c).GetType();
fldCorruption = FirstField(type, typeof(float), new string[5] { "corruption", "corruptionFrac", "corruptionFraction", "corruptionPercent", "corruptionValue" }) ?? GuessCorruptionFloatField(type, c);
if (fldCorruption == null)
{
propCorruption = FirstProperty(type, typeof(float), new string[4] { "Corruption", "CorruptionFraction", "CorruptionPercent", "Value" });
}
fldIsCorrupted = FirstField(type, typeof(bool), new string[4] { "isCorrupted", "isCorruption", "corrupted", "isInCorruptedMode" });
fldCorruptionActive = FirstField(type, typeof(bool), new string[3] { "corruptionActive", "isCorruptionActive", "isCorruptionOn" });
fldMinThreshold = FirstField(type, typeof(float), new string[3] { "minCorruptionToTransform", "minCorruptionToActivate", "minCorruption" });
fldMaxThreshold = FirstField(type, typeof(float), new string[3] { "maxCorruptionToRevert", "maxCorruptionToDeactivate", "maxCorruption" });
FieldInfo[] array = (from f in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
where f.FieldType == typeof(float)
select f).ToArray();
List<FieldInfo> list = new List<FieldInfo>();
FieldInfo[] array2 = array;
foreach (FieldInfo fieldInfo in array2)
{
string text = fieldInfo.Name.ToLowerInvariant();
if (text.Contains("corrupt") && ShouldZero(fieldInfo))
{
list.Add(fieldInfo);
}
}
corruptionRelatedFloats = list.ToArray();
mEnterCorruption = FirstMethod(type, new string[3] { "EnterCorruption", "EnterCorrupted", "StartCorruption" }, Type.EmptyTypes);
mExitCorruption = FirstMethod(type, new string[3] { "ExitCorruption", "ExitCorrupted", "StopCorruption" }, Type.EmptyTypes);
mSetCorruptionActiveBool = FirstMethod(type, new string[2] { "SetCorruptionActive", "SetCorrupted" }, new Type[1] { typeof(bool) });
mTryTransformToCorrupted = FirstMethod(type, new string[2] { "TryTransformToCorrupted", "TryEnterCorruption" }, Type.EmptyTypes);
mTryTransformToBase = FirstMethod(type, new string[2] { "TryTransformToBase", "TryExitCorruption" }, Type.EmptyTypes);
mRequestTransformationBool = FirstMethod(type, new string[2] { "RequestTransformation", "RequestCorruption" }, new Type[1] { typeof(bool) });
float num = ReadCorruption();
if (!float.IsNaN(num))
{
corruptionIsPercent = num > 1.0001f && num <= 100f;
}
else
{
corruptionIsPercent = false;
}
ManualLogSource log = Plugin.Log;
if (log != null)
{
object[] obj = new object[4]
{
type.FullName,
PathOf(boundTransform),
fldCorruption?.Name ?? propCorruption?.Name ?? "<?>",
null
};
FieldInfo[] array3 = corruptionRelatedFloats;
obj[3] = ((array3 != null) ? array3.Length : 0);
log.LogInfo((object)string.Format("[VoidStance] Bound: {0} @ {1} | value={2} | floatsToZero={3}", obj));
}
return true;
bool ShouldZero(FieldInfo f)
{
string text2 = f.Name.ToLowerInvariant();
if (fldCorruption != null && f == fldCorruption)
{
return false;
}
if (text2.Contains("min") || text2.Contains("max") || text2.Contains("threshold") || text2.Contains("limit") || text2.Contains("bound"))
{
return false;
}
if (text2.Contains("toactivate") || text2.Contains("totransform"))
{
return false;
}
if (text2.EndsWith("percent") || text2.EndsWith("fraction") || text2.EndsWith("value"))
{
return false;
}
return text2.Contains("rate") || text2.Contains("drift") || text2.Contains("delta") || text2.Contains("speed") || text2.Contains("gain") || text2.Contains("loss") || text2.Contains("regen") || text2.Contains("persecond");
}
}
private void StrongLockCorruption()
{
if (float.IsNaN(lockedCorruption))
{
lockedCorruption = ReadCorruption();
}
if (float.IsNaN(lockedCorruption))
{
lockedCorruption = 0f;
}
if (corruptionIsPercent)
{
lockedCorruption = Mathf.Clamp(lockedCorruption, 0f, 100f);
}
else
{
lockedCorruption = Mathf.Clamp01(lockedCorruption);
}
WriteCorruption(lockedCorruption);
SafeInvoke(mSetCorruptionActiveBool, vfController, new object[1] { false });
if (corruptionRelatedFloats != null)
{
for (int i = 0; i < corruptionRelatedFloats.Length; i++)
{
SafeWriteFloat(corruptionRelatedFloats[i], vfController, 0f);
}
}
}
private void DumpAllComponents()
{
try
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("=== VoidStance Component Dump ===");
CharacterBody obj = body;
ModelLocator val = ((obj != null) ? obj.modelLocator : null);
List<Transform> list = new List<Transform>();
if (Object.op_Implicit((Object)(object)body))
{
list.Add(body.transform);
}
if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.modelTransform))
{
list.Add(val.modelTransform);
}
if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.modelBaseTransform))
{
list.Add(val.modelBaseTransform);
}
if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.masterObject))
{
list.Add(body.masterObject.transform);
}
foreach (Transform item in list.Where((Transform x) => Object.op_Implicit((Object)(object)x)))
{
stringBuilder.AppendLine("-- ROOT: " + PathOf(item));
Component[] componentsInChildren = ((Component)item).GetComponentsInChildren<Component>(true);
foreach (Component val2 in componentsInChildren)
{
if (Object.op_Implicit((Object)(object)val2))
{
Type type = ((object)val2).GetType();
stringBuilder.AppendLine(" " + PathOf(val2.transform) + " :: " + type.FullName);
if (HasAnyMethod(type, new string[6] { "EnterCorruption", "ExitCorruption", "SetCorruptionActive", "TryTransformToCorrupted", "TryTransformToBase", "RequestTransformation" }))
{
stringBuilder.AppendLine(" [*] has corruption methods");
}
if (HasPlausibleCorruptionValue(val2, out var fOut, out var pOut))
{
stringBuilder.AppendLine(" [*] has corruption value via " + ((fOut != null) ? ("field:" + fOut.Name) : ("prop:" + pOut.Name)));
}
}
}
}
string text = Path.Combine(Paths.BepInExRootPath, "LogOutput");
Directory.CreateDirectory(text);
string text2 = Path.Combine(text, "VoidStance.dump.txt");
File.WriteAllText(text2, stringBuilder.ToString());
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("[VoidStance] Dump written: " + text2));
}
}
catch (Exception ex)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogWarning((object)("[VoidStance] Dump failed: " + ex.Message));
}
}
}
private static bool HasAnyMethod(Type t, IEnumerable<string> names)
{
foreach (string name in names)
{
if (t.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null)
{
return true;
}
}
return false;
}
private static bool HasPlausibleCorruptionValue(Component c, out FieldInfo fOut, out PropertyInfo pOut)
{
fOut = null;
pOut = null;
Type type = ((object)c).GetType();
FieldInfo fieldInfo = FirstField(type, typeof(float), new string[5] { "corruption", "corruptionFraction", "corruptionFrac", "corruptionPercent", "corruptionValue" }) ?? GuessCorruptionFloatField(type, c);
PropertyInfo propertyInfo = null;
if (fieldInfo == null)
{
propertyInfo = FirstProperty(type, typeof(float), new string[4] { "Corruption", "CorruptionFraction", "CorruptionPercent", "Value" });
}
float num = float.NaN;
try
{
if (fieldInfo != null)
{
num = (float)fieldInfo.GetValue(c);
}
else if (propertyInfo != null)
{
num = (float)propertyInfo.GetValue(c, null);
}
}
catch
{
}
if (!float.IsNaN(num) && ((num >= 0f && num <= 1f) || (num >= 0f && num <= 100f)))
{
fOut = fieldInfo;
pOut = propertyInfo;
return true;
}
return false;
}
private static FieldInfo FirstField(Type t, Type ft, IEnumerable<string> names)
{
foreach (string name in names)
{
FieldInfo field = t.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null && field.FieldType == ft)
{
return field;
}
}
return null;
}
private static PropertyInfo FirstProperty(Type t, Type pt, IEnumerable<string> names)
{
foreach (string name in names)
{
PropertyInfo property = t.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null && property.PropertyType == pt && property.CanRead && property.CanWrite)
{
return property;
}
}
return null;
}
private static MethodInfo FirstMethod(Type t, IEnumerable<string> names, Type[] sig)
{
foreach (string name in names)
{
MethodInfo method = t.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, sig, null);
if (method != null)
{
return method;
}
}
return null;
}
private static MethodInfo FirstMethod(Type t, IEnumerable<string> names, Type emptySig)
{
return FirstMethod(t, names, Type.EmptyTypes);
}
private static FieldInfo GuessCorruptionFloatField(Type t, object inst)
{
try
{
FieldInfo[] array = (from f in t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
where f.FieldType == typeof(float)
select f).ToArray();
FieldInfo[] array2 = array.Where((FieldInfo f) => f.Name.IndexOf("corrupt", StringComparison.OrdinalIgnoreCase) >= 0).ToArray();
FieldInfo[] array3 = ((array2.Length != 0) ? array2 : array);
FieldInfo[] array4 = array3;
foreach (FieldInfo fieldInfo in array4)
{
try
{
float num = (float)fieldInfo.GetValue(inst);
if ((num >= 0f && num <= 1f) || (num >= 0f && num <= 100f))
{
return fieldInfo;
}
}
catch
{
}
}
}
catch
{
}
return null;
}
private float ReadCorruption()
{
try
{
if (fldCorruption != null)
{
return (float)fldCorruption.GetValue(vfController);
}
if (propCorruption != null)
{
return (float)propCorruption.GetValue(vfController, null);
}
}
catch
{
}
return float.NaN;
}
private void WriteCorruption(float value)
{
try
{
if (fldCorruption != null)
{
fldCorruption.SetValue(vfController, value);
}
else if (propCorruption != null)
{
propCorruption.SetValue(vfController, value, null);
}
}
catch
{
}
}
private void SafeWriteFloat(FieldInfo f, object o, float v)
{
if (f == null)
{
return;
}
try
{
f.SetValue(o, v);
}
catch
{
}
}
private void SafeWriteBool(FieldInfo f, object o, bool v)
{
if (f == null)
{
return;
}
try
{
f.SetValue(o, v);
}
catch
{
}
}
private bool? ReadBool(FieldInfo f, object o)
{
if (f == null)
{
return null;
}
try
{
return (bool)f.GetValue(o);
}
catch
{
return null;
}
}
private bool SafeInvoke(MethodInfo m, object o, object[] args)
{
if (m == null)
{
return false;
}
try
{
m.Invoke(o, args);
return true;
}
catch
{
return false;
}
}
private static string PathOf(Transform t)
{
if (!Object.op_Implicit((Object)(object)t))
{
return "<null>";
}
List<string> list = new List<string>();
while (Object.op_Implicit((Object)(object)t))
{
list.Add(((Object)t).name);
t = t.parent;
}
list.Reverse();
return string.Join("/", list);
}
private void SnapLockValue()
{
bool? flag = ReadBool(fldIsCorrupted, vfController);
if (flag.HasValue)
{
lockedCorruption = ((!flag.Value) ? 0f : (corruptionIsPercent ? 100f : 1f));
WriteCorruption(lockedCorruption);
return;
}
float num = ReadCorruption();
if (float.IsNaN(num))
{
num = 0f;
}
if (num < 0f)
{
num = 0f;
}
if (num > 100f)
{
num = 100f;
}
if (num <= 1.0001f)
{
corruptionIsPercent = false;
}
else if (num <= 100f)
{
corruptionIsPercent = true;
}
lockedCorruption = num;
}
}
}
namespace VoidStance
{
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);
}
}
}