using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using HarmonyLib;
using JetBrains.Annotations;
using LitJson2;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: Guid("497EB368-9410-49A7-A098-9E3905D0DA35")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyProduct("DualWield")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("DualWield")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
[Microsoft.CodeAnalysis.Embedded]
[CompilerGenerated]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace BalrondDualWield
{
public class BalrondTranslator
{
public static Dictionary<string, Dictionary<string, string>> translations = new Dictionary<string, Dictionary<string, string>>();
public static Dictionary<string, string> getLanguage(string language)
{
Dictionary<string, string> result = null;
try
{
result = translations[language];
}
catch (Exception)
{
}
return result;
}
}
internal static class DualWieldMath
{
private const float PrimaryAnimationRightWeight = 0.6f;
private const float PrimaryAnimationLeftWeight = 0.4f;
private static readonly HashSet<Player> SecondaryAttackPlayers = new HashSet<Player>();
internal static float GetDualSkillFactor(Player player)
{
return ((Object)(object)player != (Object)null) ? ((Character)player).GetSkillFactor((SkillType)874298) : 0f;
}
internal static float GetPrimaryOffhandDamageScale(Player player)
{
return 0.5f + 0.25f * GetDualSkillFactor(player);
}
internal static float GetSecondaryOffhandDamageScale(Player player)
{
return GetPrimaryOffhandDamageScale(player) + 0.5f;
}
internal static void SetSecondaryAttackState(Player player, bool active)
{
if (!((Object)(object)player == (Object)null))
{
if (active)
{
SecondaryAttackPlayers.Add(player);
}
else
{
SecondaryAttackPlayers.Remove(player);
}
}
}
internal static bool IsMarkedSecondary(Player player)
{
return (Object)(object)player != (Object)null && SecondaryAttackPlayers.Contains(player);
}
internal static bool TryGetAttackIndexFromAnimator(Player player, out int attackIndex)
{
attackIndex = 1;
if ((Object)(object)player == (Object)null || (Object)(object)((Character)player).m_animator == (Object)null)
{
return false;
}
AnimatorClipInfo[] currentAnimatorClipInfo = ((Character)player).m_animator.GetCurrentAnimatorClipInfo(0);
if (currentAnimatorClipInfo == null || currentAnimatorClipInfo.Length == 0 || (Object)(object)((AnimatorClipInfo)(ref currentAnimatorClipInfo[0])).clip == (Object)null)
{
return false;
}
if (!Launch.AttackMap.TryGetValue(((Object)((AnimatorClipInfo)(ref currentAnimatorClipInfo[0])).clip).name, out var value))
{
return false;
}
attackIndex = ClampAttackIndex(value);
return true;
}
internal static int GetAttackIndexFromAttackState(Attack attack)
{
if (attack == null)
{
return 1;
}
return ClampAttackIndex(attack.m_currentAttackCainLevel + 1);
}
internal static bool IsSecondaryAttack(Player player, Attack attack)
{
if ((Object)(object)player == (Object)null || attack == null)
{
return false;
}
if (IsMarkedSecondary(player))
{
return true;
}
if (TryGetAttackIndexFromAnimator(player, out var attackIndex) && attackIndex == 0)
{
return true;
}
if (((Humanoid)player).m_currentAttack == attack && !string.IsNullOrEmpty(attack.m_attackAnimation))
{
string attackAnimation = attack.m_attackAnimation;
if (Launch.AttackMap.TryGetValue(attackAnimation, out var value) && value == 0)
{
return true;
}
if (attackAnimation.IndexOf("secondary", StringComparison.OrdinalIgnoreCase) >= 0 || attackAnimation.IndexOf("jumpattack", StringComparison.OrdinalIgnoreCase) >= 0 || attackAnimation.IndexOf("alt", StringComparison.OrdinalIgnoreCase) >= 0)
{
return true;
}
}
return false;
}
internal static float GetPrimaryCombinedSpeedFactor(Player player, int attackIndex)
{
ItemData item = (((Object)(object)player != (Object)null) ? ((Humanoid)player).m_rightItem : null);
ItemData item2 = (((Object)(object)player != (Object)null) ? ((Humanoid)player).m_leftItem : null);
float speed = GetBalancing(item, attackIndex).Speed;
float speed2 = GetBalancing(item2, attackIndex).Speed;
return speed * 0.6f + speed2 * 0.4f;
}
internal static float GetSecondaryCombinedSpeedFactor(Player player, int attackIndex)
{
return GetPrimaryCombinedSpeedFactor(player, attackIndex);
}
internal static float GetPrimaryStaminaCost(Player player, Attack attack)
{
return GetCombinedResourceCost(player, secondary: false, GetAttackStaminaCost, applySkillReduction: true);
}
internal static float GetSecondaryStaminaCost(Player player)
{
return GetCombinedResourceCost(player, secondary: true, GetAttackStaminaCost, applySkillReduction: true);
}
internal static float GetPrimaryHealthCost(Player player)
{
return GetCombinedResourceCost(player, secondary: false, GetAttackHealthCost, applySkillReduction: false);
}
internal static float GetSecondaryHealthCost(Player player)
{
return GetCombinedResourceCost(player, secondary: true, GetAttackHealthCost, applySkillReduction: false);
}
internal static float GetPrimaryEitrCost(Player player)
{
return GetCombinedResourceCost(player, secondary: false, GetAttackEitrCost, applySkillReduction: false);
}
internal static float GetSecondaryEitrCost(Player player)
{
return GetCombinedResourceCost(player, secondary: true, GetAttackEitrCost, applySkillReduction: false);
}
internal static float GetAttackStaminaCost(ItemData item, bool secondary)
{
Attack relevantAttack = GetRelevantAttack(item, secondary);
if (relevantAttack == null)
{
return 0f;
}
return Mathf.Max(0f, relevantAttack.m_attackStamina);
}
internal static float GetAttackHealthCost(ItemData item, bool secondary)
{
Attack relevantAttack = GetRelevantAttack(item, secondary);
if (relevantAttack == null)
{
return 0f;
}
return Mathf.Max(0f, relevantAttack.m_attackHealth);
}
internal static float GetAttackEitrCost(ItemData item, bool secondary)
{
Attack relevantAttack = GetRelevantAttack(item, secondary);
if (relevantAttack == null)
{
return 0f;
}
return Mathf.Max(0f, relevantAttack.m_attackEitr);
}
internal static float SafeInverse(float value)
{
return (Math.Abs(value) <= 0.0001f) ? 1f : (1f / value);
}
internal static Launch.AnimationBalancing GetBalancingForItem(ItemData item, int attackIndex)
{
return GetBalancing(item, attackIndex);
}
private static float GetCombinedResourceCost(Player player, bool secondary, Func<ItemData, bool, float> getter, bool applySkillReduction)
{
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)player == (Object)null || ((Humanoid)player).m_rightItem == null || ((Humanoid)player).m_leftItem == null)
{
return 0f;
}
ItemData rightItem = ((Humanoid)player).m_rightItem;
ItemData leftItem = ((Humanoid)player).m_leftItem;
float num = getter(rightItem, arg2: false);
float num2 = getter(leftItem, arg2: false);
float num3 = (secondary ? GetSecondaryOffhandDamageScale(player) : GetPrimaryOffhandDamageScale(player));
bool flag = num > 0f;
bool flag2 = num2 > 0f;
if (applySkillReduction)
{
if (flag)
{
num = ApplyWeaponSkillReduction(num, player, rightItem.m_shared.m_skillType);
}
if (flag2)
{
num2 = ApplyWeaponSkillReduction(num2, player, leftItem.m_shared.m_skillType);
}
}
float num4 = ((flag && flag2) ? (num + num2 * num3) : (flag ? num : ((!flag2) ? 0f : (num2 * num3))));
if (applySkillReduction)
{
num4 = ApplyDualSkillReduction(num4, player);
}
if (secondary)
{
num4 += 5f;
}
return Mathf.Max(0f, num4);
}
private static Attack GetRelevantAttack(ItemData item, bool secondary)
{
if (item == null || item.m_shared == null)
{
return null;
}
if (secondary)
{
return item.m_shared.m_attack;
}
return item.m_shared.m_attack;
}
private static float ApplyWeaponSkillReduction(float cost, Player player, SkillType skillType)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)player == (Object)null)
{
return cost;
}
return cost - cost / 6f * ((Character)player).GetSkillFactor(skillType);
}
private static float ApplyDualSkillReduction(float cost, Player player)
{
if ((Object)(object)player == (Object)null)
{
return cost;
}
return cost - cost / 6f * ((Character)player).GetSkillFactor((SkillType)874298);
}
private static Launch.AnimationBalancing GetBalancing(ItemData item, int attackIndex)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
if (item == null || item.m_shared == null)
{
return GetFallbackBalancing(attackIndex);
}
if (Launch.BalancingMap.TryGetValue(item.m_shared.m_skillType, out Launch.AnimationBalancing[] value) && value != null && value.Length != 0)
{
return value[ClampAttackIndex(attackIndex)];
}
return GetFallbackBalancing(attackIndex);
}
private static Launch.AnimationBalancing GetFallbackBalancing(int attackIndex)
{
int num = ClampAttackIndex(attackIndex);
return new Launch.AnimationBalancing(1f, (num == 0) ? 20f : 15f);
}
private static int ClampAttackIndex(int attackIndex)
{
if (attackIndex < 0)
{
return 0;
}
if (attackIndex > 3)
{
return 3;
}
return attackIndex;
}
}
[BepInPlugin("balrond.astafaraios.BalrondDualMastery", "BalrondDualMastery", "0.2.1")]
public class Launch : BaseUnityPlugin
{
internal enum DualSkill
{
DualWield = 874298
}
internal struct AnimationBalancing
{
public float Speed;
public float Stamina;
public AnimationBalancing(float speed, float stamina)
{
Speed = speed;
Stamina = stamina;
}
}
public const string PluginGUID = "balrond.astafaraios.BalrondDualMastery";
public const string PluginName = "BalrondDualMastery";
public const string PluginVersion = "0.2.1";
public static JsonLoader jsonLoader = new JsonLoader();
private Harmony harmony;
internal const SkillType DualWieldSkillType = 874298;
internal static AssetBundle AssetBundle;
internal static readonly Dictionary<string, RuntimeAnimatorController> CustomRuntimeControllers = new Dictionary<string, RuntimeAnimatorController>();
internal static readonly Dictionary<string, AnimationClip> ExternalAnimations = new Dictionary<string, AnimationClip>();
internal static readonly Dictionary<string, Dictionary<string, string>> ReplacementMap = new Dictionary<string, Dictionary<string, string>>();
internal static readonly Dictionary<string, int> AttackMap = new Dictionary<string, int>();
public static readonly float skillFactor = 0.2f;
private static readonly string skillName = "Dual Wield";
private static readonly string skillTooltip = "$tag_dualwield_bal_tooltip";
internal static readonly Dictionary<SkillType, AnimationBalancing[]> DefaultBalancing = new Dictionary<SkillType, AnimationBalancing[]>
{
{
(SkillType)7,
new AnimationBalancing[4]
{
new AnimationBalancing(0.6f, 40f),
new AnimationBalancing(0.8f, 20f),
new AnimationBalancing(0.7f, 20f),
new AnimationBalancing(0.6f, 30f)
}
},
{
(SkillType)3,
new AnimationBalancing[4]
{
new AnimationBalancing(0.8f, 35f),
new AnimationBalancing(1.2f, 14f),
new AnimationBalancing(1.3f, 15f),
new AnimationBalancing(1.5f, 15f)
}
},
{
(SkillType)2,
new AnimationBalancing[4]
{
new AnimationBalancing(1.4f, 32f),
new AnimationBalancing(1.4f, 9f),
new AnimationBalancing(1.4f, 9f),
new AnimationBalancing(2f, 27f)
}
},
{
(SkillType)1,
new AnimationBalancing[4]
{
new AnimationBalancing(1f, 40f),
new AnimationBalancing(1f, 15f),
new AnimationBalancing(1f, 15f),
new AnimationBalancing(1.2f, 20f)
}
}
};
internal static readonly Dictionary<SkillType, AnimationBalancing[]> BalancingMap = new Dictionary<SkillType, AnimationBalancing[]>();
private void Awake()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Expected O, but got Unknown
jsonLoader.loadJson();
InitializeAssets();
InitializeAttackMap();
InitializeReplacementMaps();
InitializeSkills();
InitializeBalancing();
harmony = new Harmony("balrond.astafaraios.BalrondDualMastery");
harmony.PatchAll();
}
private static void InitializeAssets()
{
ExternalAnimations.Clear();
AssetBundle = GetAssetBundle("dwanimations");
LoadAnimation("Attack1External", "Attack1");
LoadAnimation("Attack2External", "Attack2");
LoadAnimation("Attack3External", "Attack3");
LoadAnimation("BlockExternal", "DWblock");
LoadAnimation("DualSpecial", "DWspecial");
}
private static void LoadAnimation(string key, string asset)
{
AnimationClip val = AssetBundle.LoadAsset<AnimationClip>(asset);
if ((Object)(object)val == (Object)null)
{
throw new Exception("Missing animation " + asset);
}
ExternalAnimations[key] = val;
}
private static void InitializeAttackMap()
{
AttackMap.Clear();
AttackMap["Attack1"] = 1;
AttackMap["Attack2"] = 2;
AttackMap["Attack3"] = 3;
AttackMap["Sword-Attack-R4"] = 0;
AttackMap["AxeAltAttack"] = 0;
AttackMap["MaceAltAttack"] = 0;
AttackMap["Knife JumpAttack"] = 0;
AttackMap["axe_secondary"] = 0;
AttackMap["AxeSecondaryAttack"] = 0;
AttackMap["BattleAxeAltAttack"] = 0;
}
private static void InitializeReplacementMaps()
{
ReplacementMap.Clear();
ReplacementMap["Dual"] = BuildReplacementMap();
}
private static Dictionary<string, string> BuildReplacementMap()
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary["fight idle"] = "BlockExternal";
dictionary["Block idle"] = "BlockExternal";
foreach (KeyValuePair<string, int> item in AttackMap)
{
dictionary[item.Key] = ((item.Value == 0) ? "DualSpecial" : ("Attack" + item.Value + "External"));
}
return dictionary;
}
private static void InitializeSkills()
{
DualWieldSkills.AddNewSkill(DualSkill.DualWield, skillName, skillTooltip, skillFactor, DualWieldSkills.loadSprite("dualswords.png", 64, 64));
}
private static void InitializeBalancing()
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
BalancingMap.Clear();
foreach (KeyValuePair<SkillType, AnimationBalancing[]> item in DefaultBalancing)
{
AnimationBalancing[] array = new AnimationBalancing[item.Value.Length];
Array.Copy(item.Value, array, item.Value.Length);
BalancingMap[item.Key] = array;
}
}
internal static RuntimeAnimatorController MakeAnimatorOverrideController(Dictionary<string, string> replacement, RuntimeAnimatorController original)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
AnimatorOverrideController val = new AnimatorOverrideController(original);
List<KeyValuePair<AnimationClip, AnimationClip>> list = new List<KeyValuePair<AnimationClip, AnimationClip>>();
AnimationClip[] animationClips = ((RuntimeAnimatorController)val).animationClips;
foreach (AnimationClip val2 in animationClips)
{
if (replacement.TryGetValue(((Object)val2).name, out string value) && ExternalAnimations.TryGetValue(value, out AnimationClip value2) && (Object)(object)value2 != (Object)null)
{
AnimationClip val3 = Object.Instantiate<AnimationClip>(value2);
((Object)val3).name = ((Object)val2).name;
list.Add(new KeyValuePair<AnimationClip, AnimationClip>(val2, val3));
}
else
{
list.Add(new KeyValuePair<AnimationClip, AnimationClip>(val2, val2));
}
}
val.ApplyOverrides((IList<KeyValuePair<AnimationClip, AnimationClip>>)list);
return (RuntimeAnimatorController)(object)val;
}
internal static void FastReplaceRuntimeAnimatorController(Player player, RuntimeAnimatorController replacement)
{
if (!((Object)(object)player == (Object)null) && !((Object)(object)((Character)player).m_animator == (Object)null) && !((Object)(object)replacement == (Object)null) && !((Object)(object)((Character)player).m_animator.runtimeAnimatorController == (Object)(object)replacement))
{
((Character)player).m_animator.runtimeAnimatorController = replacement;
((Character)player).m_animator.Update(Time.deltaTime);
}
}
private static AssetBundle GetAssetBundle(string filename)
{
string filename2 = filename;
Assembly executingAssembly = Assembly.GetExecutingAssembly();
string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string n) => n.EndsWith(filename2, StringComparison.OrdinalIgnoreCase));
if (text == null)
{
throw new Exception("Missing embedded asset bundle");
}
using Stream stream = executingAssembly.GetManifestResourceStream(text);
if (stream == null)
{
throw new Exception("Could not open embedded asset bundle stream");
}
AssetBundle val = AssetBundle.LoadFromStream(stream);
if ((Object)(object)val == (Object)null)
{
throw new Exception("Could not load asset bundle from stream");
}
return val;
}
internal static bool IsOneHandedWeapon(ItemData item)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
return item != null && item.m_shared != null && (int)item.m_shared.m_itemType == 3;
}
internal static bool IsDualWieldingOneHandedWeapons(Player player)
{
return (Object)(object)player != (Object)null && IsOneHandedWeapon(((Humanoid)player).m_rightItem) && IsOneHandedWeapon(((Humanoid)player).m_leftItem);
}
internal static SharedData GetSharedDataFromHash(int hash)
{
if (hash == 0 || (Object)(object)ObjectDB.instance == (Object)null)
{
return null;
}
GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(hash);
if ((Object)(object)itemPrefab == (Object)null)
{
return null;
}
ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
if ((Object)(object)component == (Object)null || component.m_itemData == null)
{
return null;
}
return component.m_itemData.m_shared;
}
}
public class JsonLoader
{
public string defaultPath = string.Empty;
public void loadJson()
{
LoadTranslations();
justDefaultPath();
}
public void justDefaultPath()
{
string configPath = Paths.ConfigPath;
string text = Path.Combine(configPath, "BalrondDualMastery-translation/");
defaultPath = text;
}
public void createDefaultPath()
{
string configPath = Paths.ConfigPath;
string text = Path.Combine(configPath, "BalrondDualMastery-translation/");
if (!Directory.Exists(text))
{
CreateFolder(text);
}
else
{
Debug.Log((object)("BalrondDualMastery: Folder already exists: " + text));
}
defaultPath = text;
}
private string[] jsonFilePath(string folderName, string extension)
{
string configPath = Paths.ConfigPath;
string text = Path.Combine(configPath, "BalrondDualMastery-translation/");
if (!Directory.Exists(text))
{
CreateFolder(text);
}
else
{
Debug.Log((object)("BalrondDualMastery: Folder already exists: " + text));
}
string[] files = Directory.GetFiles(text, extension);
Debug.Log((object)("BalrondDualMastery:" + folderName + " Json Files Found: " + files.Length));
return files;
}
private static void CreateFolder(string path)
{
try
{
Directory.CreateDirectory(path);
Debug.Log((object)"BalrondDualMastery: Folder created successfully.");
}
catch (Exception ex)
{
Debug.Log((object)("BalrondDualMastery: Error creating folder: " + ex.Message));
}
}
private void LoadTranslations()
{
int num = 0;
string[] array = jsonFilePath("Translation", "*.json");
foreach (string text in array)
{
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text);
string json = File.ReadAllText(text);
JsonData jsonData = JsonMapper.ToObject(json);
Dictionary<string, string> dictionary = new Dictionary<string, string>();
foreach (string key in jsonData.Keys)
{
dictionary[key] = jsonData[key].ToString();
}
if (dictionary != null)
{
BalrondTranslator.translations.Add(fileNameWithoutExtension, dictionary);
Debug.Log((object)("BalrondDualMastery: Json Files Language: " + fileNameWithoutExtension));
num++;
}
else
{
Debug.LogError((object)("BalrondDualMastery: Loading FAILED file: " + text));
}
}
Debug.Log((object)("BalrondDualMastery: Translation JsonFiles Loaded: " + num));
}
}
[HarmonyPatch(typeof(Attack), "OnAttackTrigger")]
internal static class Patch_Attack_OnAttackTrigger
{
private struct StartAttackState
{
public Player Player;
public ItemData RightItem;
public Attack OriginalPrimaryAttack;
public Attack OriginalSecondaryAttack;
public bool ReplacedPrimaryAttack;
public bool ReplacedSecondaryAttack;
public bool IsSecondary;
public float PendingHealthCost;
public float PendingEitrCost;
}
[HarmonyPatch(typeof(Player), "RaiseSkill")]
internal static class Patch_Player_RaiseSkill_DualWield
{
private static bool _raisingDualSkill;
private static void Postfix(Player __instance, SkillType skill, float value)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Invalid comparison between Unknown and I4
//IL_009c: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
if (_raisingDualSkill || (Object)(object)__instance == (Object)null || (int)skill == 874298 || value <= 0f || !Launch.IsDualWieldingOneHandedWeapons(__instance))
{
return;
}
ItemData rightItem = ((Humanoid)__instance).m_rightItem;
ItemData leftItem = ((Humanoid)__instance).m_leftItem;
if (rightItem == null || leftItem == null || rightItem.m_shared == null || leftItem.m_shared == null)
{
return;
}
SkillType skillType = rightItem.m_shared.m_skillType;
SkillType skillType2 = leftItem.m_shared.m_skillType;
if (skill != skillType && skill != skillType2)
{
return;
}
try
{
_raisingDualSkill = true;
((Character)__instance).RaiseSkill((SkillType)874298, value * Launch.skillFactor);
}
finally
{
_raisingDualSkill = false;
}
}
}
[HarmonyPatch(typeof(Player), "GetRandomSkillFactor")]
internal static class Patch_Player_GetRandomSkillFactor
{
private static bool Prefix(Player __instance, SkillType skill, ref float __result)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
if ((int)skill == 874298)
{
__result = 0.03f + ((Character)__instance).GetSkillFactor(skill) * 1.5f;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Attack), "GetAttackStamina")]
internal static class Patch_Attack_GetAttackStamina
{
private static bool Prefix(Attack __instance, ref float __result)
{
Humanoid character = __instance.m_character;
Player val = (Player)(object)((character is Player) ? character : null);
if ((Object)(object)val == (Object)null || !Launch.IsDualWieldingOneHandedWeapons(val))
{
return true;
}
bool flag = DualWieldMath.IsSecondaryAttack(val, __instance);
__result = (flag ? DualWieldMath.GetSecondaryStaminaCost(val) : DualWieldMath.GetPrimaryStaminaCost(val, __instance));
return false;
}
}
[HarmonyPatch(typeof(Attack), "DoMeleeAttack")]
internal static class Patch_Attack_DoMeleeAttack
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
MethodInfo quaternionEuler = AccessTools.DeclaredMethod(typeof(Quaternion), "Euler", new Type[3]
{
typeof(float),
typeof(float),
typeof(float)
}, (Type[])null);
FieldInfo attackAngleField = AccessTools.DeclaredField(typeof(Attack), "m_attackAngle");
List<CodeInstruction> instrs = new List<CodeInstruction>(instructions);
int i = 0;
while (i < instrs.Count)
{
if (i + 2 < instrs.Count && instrs[i].opcode == OpCodes.Neg && instrs[i + 2].opcode == OpCodes.Call && CodeInstructionExtensions.OperandIs(instrs[i + 2], (MemberInfo)quaternionEuler))
{
Label label = generator.DefineLabel();
yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null);
yield return new CodeInstruction(OpCodes.Ldfld, (object)attackAngleField);
yield return new CodeInstruction(OpCodes.Ldc_R4, (object)0f);
yield return new CodeInstruction(OpCodes.Ble, (object)label);
yield return new CodeInstruction(OpCodes.Neg, (object)null);
instrs[i + 1].labels.Add(label);
}
else
{
yield return instrs[i];
}
if (instrs[i].opcode == OpCodes.Ldfld && CodeInstructionExtensions.OperandIs(instrs[i], (MemberInfo)attackAngleField))
{
yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(Mathf), "Abs", new Type[1] { typeof(float) }, (Type[])null));
}
int num = i + 1;
i = num;
}
}
}
[HarmonyPatch(typeof(Humanoid), "StartAttack")]
internal static class Patch_Humanoid_StartAttack
{
private static bool Prefix(Humanoid __instance, bool secondaryAttack, ref bool __result, out StartAttackState __state)
{
__state = default(StartAttackState);
Player val = (Player)(object)((__instance is Player) ? __instance : null);
if ((Object)(object)val == (Object)null || !Launch.IsDualWieldingOneHandedWeapons(val))
{
return true;
}
ItemData rightItem = ((Humanoid)val).m_rightItem;
if (rightItem == null || rightItem.m_shared == null)
{
return true;
}
float num = (secondaryAttack ? DualWieldMath.GetSecondaryHealthCost(val) : DualWieldMath.GetPrimaryHealthCost(val));
float num2 = (secondaryAttack ? DualWieldMath.GetSecondaryEitrCost(val) : DualWieldMath.GetPrimaryEitrCost(val));
if (((Character)val).GetHealth() <= num + 0.0001f)
{
__result = false;
return false;
}
if (GetPlayerEitr(val) + 0.0001f < num2)
{
__result = false;
return false;
}
__state.Player = val;
__state.RightItem = rightItem;
__state.PendingHealthCost = num;
__state.PendingEitrCost = num2;
__state.IsSecondary = secondaryAttack;
if (secondaryAttack)
{
DualWieldMath.SetSecondaryAttackState(val, active: true);
__state.OriginalSecondaryAttack = rightItem.m_shared.m_secondaryAttack;
Attack attack = rightItem.m_shared.m_attack;
if (attack != null)
{
Attack val2 = attack.Clone();
val2.m_attackHealth = 0f;
val2.m_attackEitr = 0f;
rightItem.m_shared.m_secondaryAttack = val2;
__state.ReplacedSecondaryAttack = true;
}
}
else
{
__state.OriginalPrimaryAttack = rightItem.m_shared.m_attack;
if (__state.OriginalPrimaryAttack != null)
{
Attack val3 = __state.OriginalPrimaryAttack.Clone();
val3.m_attackHealth = 0f;
val3.m_attackEitr = 0f;
rightItem.m_shared.m_attack = val3;
__state.ReplacedPrimaryAttack = true;
}
}
return true;
}
private static void Postfix(Humanoid __instance, StartAttackState __state, bool __result)
{
if (__state.RightItem != null && __state.RightItem.m_shared != null)
{
if (__state.ReplacedPrimaryAttack)
{
__state.RightItem.m_shared.m_attack = __state.OriginalPrimaryAttack;
}
if (__state.ReplacedSecondaryAttack)
{
__state.RightItem.m_shared.m_secondaryAttack = __state.OriginalSecondaryAttack;
}
}
if (!__result && (Object)(object)__state.Player != (Object)null)
{
DualWieldMath.SetSecondaryAttackState(__state.Player, active: false);
}
else if (__result && (Object)(object)__state.Player != (Object)null)
{
if (__state.PendingHealthCost > 0f)
{
UsePlayerHealth(__state.Player, __state.PendingHealthCost);
}
if (__state.PendingEitrCost > 0f)
{
UsePlayerEitr(__state.Player, __state.PendingEitrCost);
}
}
}
}
private static float _rightSharedScale = 1f;
private static float _leftSharedScale = 1f;
private static SharedData _rightScaledShared;
private static SharedData _leftScaledShared;
private static readonly string[] SwappedAttackFields = new string[13]
{
"m_hitTerrain", "m_specialHitType", "m_specialHitSkill", "m_attackRange", "m_attackHeight", "m_attackRayWidth", "m_attackOffset", "m_damageMultiplier", "m_forceMultiplier", "m_staggerMultiplier",
"m_lowerDamagePerHit", "m_resetChainIfHit", "m_hitPointtype"
};
private static Dictionary<FieldInfo, object> SnapshotAttackFields(Attack attack)
{
Dictionary<FieldInfo, object> dictionary = new Dictionary<FieldInfo, object>();
string[] swappedAttackFields = SwappedAttackFields;
foreach (string text in swappedAttackFields)
{
FieldInfo fieldInfo = AccessTools.Field(typeof(Attack), text);
if (fieldInfo != null)
{
dictionary[fieldInfo] = fieldInfo.GetValue(attack);
}
}
return dictionary;
}
private static void CopyAttackFields(Attack source, Attack destination)
{
string[] swappedAttackFields = SwappedAttackFields;
foreach (string text in swappedAttackFields)
{
FieldInfo fieldInfo = AccessTools.Field(typeof(Attack), text);
if (fieldInfo != null)
{
fieldInfo.SetValue(destination, fieldInfo.GetValue(source));
}
}
}
private static void RestoreAttackFields(Attack attack, Dictionary<FieldInfo, object> backup)
{
foreach (KeyValuePair<FieldInfo, object> item in backup)
{
item.Key.SetValue(attack, item.Value);
}
}
private static void ApplySharedScale(SharedData shared, float factor)
{
if (shared != null && !(Math.Abs(factor - 1f) <= 0.0001f))
{
((DamageTypes)(ref shared.m_damages)).Modify(factor);
shared.m_attackForce *= factor;
shared.m_backstabBonus *= factor;
}
}
private static float GetPlayerEitr(Player player)
{
if ((Object)(object)player == (Object)null)
{
return 0f;
}
MethodInfo methodInfo = AccessTools.Method(((object)player).GetType(), "GetEitr", (Type[])null, (Type[])null);
if (methodInfo == null)
{
return 0f;
}
object obj = methodInfo.Invoke(player, null);
return (obj is float) ? ((float)obj) : 0f;
}
private static void UsePlayerEitr(Player player, float amount)
{
if (!((Object)(object)player == (Object)null) && !(amount <= 0f))
{
MethodInfo methodInfo = AccessTools.Method(((object)player).GetType(), "UseEitr", new Type[1] { typeof(float) }, (Type[])null);
if (methodInfo != null)
{
methodInfo.Invoke(player, new object[1] { amount });
}
}
}
private static void UsePlayerHealth(Player player, float amount)
{
if (!((Object)(object)player == (Object)null) && !(amount <= 0f))
{
MethodInfo methodInfo = AccessTools.Method(typeof(Character), "GetHealth", (Type[])null, (Type[])null);
MethodInfo methodInfo2 = AccessTools.Method(typeof(Character), "SetHealth", new Type[1] { typeof(float) }, (Type[])null);
if (!(methodInfo == null) && !(methodInfo2 == null))
{
object obj = methodInfo.Invoke(player, null);
float num = ((obj is float) ? ((float)obj) : 0f);
float num2 = Mathf.Max(1f, num - amount);
methodInfo2.Invoke(player, new object[1] { num2 });
}
}
}
private static void Prefix(Attack __instance)
{
_rightSharedScale = 1f;
_leftSharedScale = 1f;
_rightScaledShared = null;
_leftScaledShared = null;
Humanoid character = __instance.m_character;
Player val = (Player)(object)((character is Player) ? character : null);
if ((Object)(object)val == (Object)null || !Launch.IsDualWieldingOneHandedWeapons(val))
{
return;
}
ItemData rightItem = ((Humanoid)val).m_rightItem;
ItemData leftItem = ((Humanoid)val).m_leftItem;
if (rightItem == null || leftItem == null)
{
return;
}
float leftSharedScale = (DualWieldMath.IsSecondaryAttack(val, __instance) ? DualWieldMath.GetSecondaryOffhandDamageScale(val) : DualWieldMath.GetPrimaryOffhandDamageScale(val));
_rightScaledShared = rightItem.m_shared;
_leftScaledShared = leftItem.m_shared;
_rightSharedScale = 1f;
_leftSharedScale = leftSharedScale;
Dictionary<FieldInfo, object> dictionary = null;
Attack attack = leftItem.m_shared.m_attack;
if (attack != null)
{
dictionary = SnapshotAttackFields(__instance);
}
ItemData weapon = __instance.m_weapon;
float attackAngle = __instance.m_attackAngle;
try
{
if (attack != null)
{
CopyAttackFields(attack, __instance);
}
__instance.m_attackAngle = 0f - __instance.m_attackAngle;
__instance.m_weapon = leftItem;
ApplySharedScale(leftItem.m_shared, _leftSharedScale);
__instance.DoMeleeAttack();
}
finally
{
ApplySharedScale(leftItem.m_shared, DualWieldMath.SafeInverse(_leftSharedScale));
if (dictionary != null)
{
RestoreAttackFields(__instance, dictionary);
}
__instance.m_weapon = weapon;
__instance.m_attackAngle = attackAngle;
}
}
private static void Postfix(Attack __instance)
{
Humanoid character = __instance.m_character;
Player val = (Player)(object)((character is Player) ? character : null);
if ((Object)(object)val != (Object)null)
{
DualWieldMath.SetSecondaryAttackState(val, active: false);
}
_rightScaledShared = null;
_leftScaledShared = null;
_rightSharedScale = 1f;
_leftSharedScale = 1f;
}
}
[HarmonyPatch(typeof(Player), "Start")]
internal static class Patch_Player_Start
{
private static void Postfix(Player __instance)
{
if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((Character)__instance).m_animator == (Object)null) && Launch.CustomRuntimeControllers.Count <= 0)
{
RuntimeAnimatorController runtimeAnimatorController = ((Character)__instance).m_animator.runtimeAnimatorController;
if (!((Object)(object)runtimeAnimatorController == (Object)null))
{
Launch.CustomRuntimeControllers["Original"] = Launch.MakeAnimatorOverrideController(new Dictionary<string, string>(), runtimeAnimatorController);
Launch.CustomRuntimeControllers["Dual"] = Launch.MakeAnimatorOverrideController(Launch.ReplacementMap["Dual"], runtimeAnimatorController);
}
}
}
}
[HarmonyPatch(typeof(Humanoid), "EquipItem")]
internal static class Patch_Humanoid_EquipItem
{
private static bool CheckDualOneHandedWeaponEquip(Humanoid humanoid, ItemData item, bool triggerEquipEffects)
{
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Invalid comparison between Unknown and I4
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Invalid comparison between Unknown and I4
Player val = (Player)(object)((humanoid is Player) ? humanoid : null);
if ((Object)(object)val == (Object)null || item == null || item.m_shared == null)
{
return false;
}
if (((Humanoid)val).m_rightItem != null && ((Humanoid)val).m_rightItem.m_shared != null && (int)((Humanoid)val).m_rightItem.m_shared.m_itemType == 3 && (int)item.m_shared.m_skillType != 5)
{
if (((Humanoid)val).m_leftItem != null)
{
((Humanoid)val).UnequipItem(((Humanoid)val).m_leftItem, triggerEquipEffects);
}
((Humanoid)val).m_leftItem = item;
return true;
}
return false;
}
private static void Prefix()
{
Patch_Humanoid_SetupEquipment.ManipulatingEquipment = true;
}
private static void Postfix()
{
Patch_Humanoid_SetupEquipment.ManipulatingEquipment = false;
}
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> instrs = instructions.ToList();
int i = 0;
while (i < instrs.Count)
{
yield return instrs[i];
if (i >= 4 && instrs[i - 4].opcode == OpCodes.Ldarg_1 && instrs[i - 1].opcode == OpCodes.Ldc_I4_3 && instrs[i].opcode == OpCodes.Bne_Un)
{
yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null);
yield return new CodeInstruction(OpCodes.Ldarg_1, (object)null);
yield return new CodeInstruction(OpCodes.Ldarg_2, (object)null);
yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(Patch_Humanoid_EquipItem), "CheckDualOneHandedWeaponEquip", (Type[])null, (Type[])null));
yield return new CodeInstruction(OpCodes.Brtrue, instrs[i].operand);
}
int num = i + 1;
i = num;
}
}
}
[HarmonyPatch(typeof(Humanoid), "UnequipAllItems")]
internal static class Patch_Humanoid_UnequipAllItems
{
private static void Prefix()
{
Patch_Humanoid_SetupEquipment.ManipulatingEquipment = true;
}
private static void Postfix()
{
Patch_Humanoid_SetupEquipment.ManipulatingEquipment = false;
}
}
[HarmonyPatch(typeof(Humanoid), "SetupEquipment")]
internal static class Patch_Humanoid_SetupEquipment
{
internal static bool ManipulatingEquipment;
private static void Prefix(Humanoid __instance)
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Invalid comparison between Unknown and I4
Player val = (Player)(object)((__instance is Player) ? __instance : null);
if (!((Object)(object)val == (Object)null) && !ManipulatingEquipment && ((Humanoid)val).m_rightItem == null && ((Humanoid)val).m_leftItem != null && ((Humanoid)val).m_leftItem.m_shared != null && (int)((Humanoid)val).m_leftItem.m_shared.m_itemType == 3)
{
ItemData leftItem = ((Humanoid)val).m_leftItem;
((Humanoid)val).UnequipItem(((Humanoid)val).m_leftItem, false);
((Humanoid)val).m_rightItem = leftItem;
((Humanoid)val).m_rightItem.m_equipped = true;
((Humanoid)val).m_leftItem = null;
}
}
}
[HarmonyPatch(typeof(VisEquipment), "SetWeaponTrails")]
internal static class Patch_VisEquipment_SetWeaponTrails
{
private static void Postfix(VisEquipment __instance, bool enabled)
{
if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.m_leftItemInstance == (Object)null)
{
return;
}
MeleeWeaponTrail[] componentsInChildren = __instance.m_leftItemInstance.GetComponentsInChildren<MeleeWeaponTrail>();
MeleeWeaponTrail[] array = componentsInChildren;
foreach (MeleeWeaponTrail val in array)
{
if ((Object)(object)val != (Object)null)
{
val.Emit = enabled;
}
}
}
}
[HarmonyPatch(typeof(VisEquipment), "AttachItem")]
internal static class Patch_VisEquipment_AttachItem
{
private static void Postfix(VisEquipment __instance, Transform joint)
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)__instance == (Object)null) && !((Object)(object)joint == (Object)null))
{
if ((Object)(object)joint == (Object)(object)__instance.m_backMelee && joint.childCount > 1)
{
joint.GetChild(1).localPosition = new Vector3(-0.003f, 0f, 0.003f);
joint.GetChild(1).localEulerAngles = new Vector3(0f, 80f, 0f);
}
if ((Object)(object)joint == (Object)(object)__instance.m_backTool && joint.childCount > 1)
{
joint.GetChild(1).localPosition = new Vector3(-0.0008f, -0.0052f, 0f);
joint.GetChild(1).localEulerAngles = new Vector3(20f, 0f, 0f);
}
}
}
}
[HarmonyPatch(typeof(ZSyncAnimation), "RPC_SetTrigger")]
internal static class Patch_ZSyncAnimation_RPC_SetTrigger
{
private static void Prefix(ZSyncAnimation __instance, string name)
{
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Invalid comparison between Unknown and I4
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Invalid comparison between Unknown and I4
string name2 = name;
if ((Object)(object)__instance == (Object)null || string.IsNullOrEmpty(name2))
{
return;
}
Player component = ((Component)__instance).GetComponent<Player>();
if ((Object)(object)component == (Object)null || (Object)(object)((Humanoid)component).m_visEquipment == (Object)null)
{
return;
}
SharedData sharedDataFromHash = Launch.GetSharedDataFromHash(((Humanoid)component).m_visEquipment.m_currentRightItemHash);
SharedData sharedDataFromHash2 = Launch.GetSharedDataFromHash(((Humanoid)component).m_visEquipment.m_currentLeftItemHash);
if (HasAttack(sharedDataFromHash2) || HasAttack(sharedDataFromHash) || IsMappedDualAttackTrigger())
{
string key = "Original";
if (sharedDataFromHash2 != null && sharedDataFromHash != null && (int)sharedDataFromHash2.m_itemType == 3 && (int)sharedDataFromHash.m_itemType == 3)
{
key = "Dual";
}
if (Launch.CustomRuntimeControllers.TryGetValue(key, out RuntimeAnimatorController value))
{
Launch.FastReplaceRuntimeAnimatorController(component, value);
}
}
bool HasAttack(SharedData data)
{
if (data == null)
{
return false;
}
string animName2 = ((data.m_attack != null) ? data.m_attack.m_attackAnimation : null);
string animName3 = ((data.m_secondaryAttack != null) ? data.m_secondaryAttack.m_attackAnimation : null);
return HasAttackName(animName2) || HasAttackName(animName3);
}
bool HasAttackName(string animName)
{
return !string.IsNullOrEmpty(animName) && (name2 == animName || name2.StartsWith(animName));
}
bool IsMappedDualAttackTrigger()
{
foreach (KeyValuePair<string, int> item in Launch.AttackMap)
{
if (name2 == item.Key || name2.StartsWith(item.Key))
{
return true;
}
}
return false;
}
}
}
[HarmonyPatch(typeof(CharacterAnimEvent), "CustomFixedUpdate")]
internal static class Patch_CharacterAnimEvent_CustomFixedUpdate
{
[HarmonyPriority(300)]
[UsedImplicitly]
private static void Prefix(Character ___m_character, ref Animator ___m_animator)
{
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Expected O, but got Unknown
if ((Object)(object)___m_character == (Object)null || (Object)(object)___m_animator == (Object)null || !___m_character.IsPlayer() || !___m_character.InAttack() || (___m_animator.speed * 10000f % 10f >= 1f && ___m_animator.speed * 10000f % 10f <= 3f) || ___m_animator.speed <= 0.001f)
{
return;
}
Player val = (Player)___m_character;
Attack currentAttack = ((Humanoid)val).m_currentAttack;
if (currentAttack != null && Launch.IsDualWieldingOneHandedWeapons(val))
{
if (!DualWieldMath.TryGetAttackIndexFromAnimator(val, out var attackIndex))
{
attackIndex = DualWieldMath.GetAttackIndexFromAttackState(currentAttack);
}
float num = (DualWieldMath.IsSecondaryAttack(val, currentAttack) ? DualWieldMath.GetSecondaryCombinedSpeedFactor(val, attackIndex) : DualWieldMath.GetPrimaryCombinedSpeedFactor(val, attackIndex));
___m_animator.speed = (float)Math.Round(___m_animator.speed * num, 3) + ___m_animator.speed % 0.0001f + 0.0002f;
}
}
}
public static class DualWieldSkills
{
private sealed class SkillDetails
{
public string SkillName;
public string InternalSkillName;
public SkillDef SkillDef;
}
[HarmonyPatch(typeof(Skills), "GetSkillDef")]
private static class Patch_Skills_GetSkillDef
{
private static void Postfix(ref SkillDef __result, List<SkillDef> ___m_skills, SkillType type)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
if (__result != null)
{
return;
}
SkillDef skillDef = GetSkillDef(type);
if (skillDef != null)
{
if (___m_skills != null && !___m_skills.Contains(skillDef))
{
___m_skills.Add(skillDef);
}
__result = skillDef;
}
}
}
[HarmonyPatch(typeof(Skills), "CheatRaiseSkill")]
private static class Patch_Skills_CheatRaiseSkill
{
[HarmonyPrefix]
private static bool Prefix(Skills __instance, string name, float value, Player ___m_player)
{
if (!TryGetSkillDetails(name, out int skillId, out SkillDetails details))
{
return true;
}
Skill skill = __instance.GetSkill((SkillType)skillId);
skill.m_level += value;
skill.m_level = Mathf.Clamp(skill.m_level, 0f, 100f);
if ((Object)(object)___m_player != (Object)null && skill.m_info != null)
{
((Character)___m_player).Message((MessageType)1, "Skill increased " + details.SkillName + ": " + (int)skill.m_level, 0, skill.m_info.m_icon);
}
if ((Object)(object)Console.instance != (Object)null)
{
Console.instance.Print("Skill " + details.SkillName + " = " + skill.m_level);
}
return false;
}
}
[HarmonyPatch(typeof(Skills), "CheatResetSkill")]
private static class Patch_Skills_CheatResetSkill
{
[HarmonyPrefix]
private static bool Prefix(Skills __instance, string name)
{
if (!TryGetSkillDetails(name, out int skillId, out SkillDetails details))
{
return true;
}
__instance.ResetSkill((SkillType)skillId);
if ((Object)(object)Console.instance != (Object)null)
{
Console.instance.Print("Skill " + details.SkillName + " reset");
}
return false;
}
}
[HarmonyPatch(typeof(Skills), "IsSkillValid")]
private static class Patch_Skills_IsSkillValid
{
private static void Postfix(SkillType type, ref bool __result)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected I4, but got Unknown
if (!__result)
{
__result = SkillsById.ContainsKey((int)type);
}
}
}
private static readonly Dictionary<int, SkillDetails> SkillsById = new Dictionary<int, SkillDetails>();
private static readonly Dictionary<string, int> SkillIdsByInternalName = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
private static MethodInfo _loadImageMethod;
private static bool _searchedLoadImageMethod;
public static void AddNewSkill<T>(T skill, string skillName, string skillDescription, float skillIncreaseStep, Sprite skillIcon) where T : struct, IConvertible
{
//IL_001a: 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_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Expected O, but got Unknown
int num = skill.ToInt32(CultureInfo.InvariantCulture);
SkillType skill2 = (SkillType)(object)skill;
SkillDetails skillDetails = new SkillDetails
{
SkillName = skillName,
InternalSkillName = skill.ToString(),
SkillDef = new SkillDef
{
m_description = skillDescription,
m_icon = skillIcon,
m_increseStep = skillIncreaseStep,
m_skill = skill2
}
};
SkillsById[num] = skillDetails;
SkillIdsByInternalName[skillDetails.InternalSkillName] = num;
}
private static bool TryGetSkillDetails(SkillType skillType, out SkillDetails details)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Expected I4, but got Unknown
return SkillsById.TryGetValue((int)skillType, out details);
}
private static bool TryGetSkillDetails(string internalName, out int skillId, out SkillDetails details)
{
skillId = 0;
details = null;
if (string.IsNullOrEmpty(internalName))
{
return false;
}
if (!SkillIdsByInternalName.TryGetValue(internalName, out skillId))
{
return false;
}
return SkillsById.TryGetValue(skillId, out details);
}
private static SkillDef GetSkillDef(SkillType skillType)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected I4, but got Unknown
if (!TryGetSkillDetails(skillType, out SkillDetails details))
{
return null;
}
if (Localization.instance != null)
{
Localization.instance.AddWord("skill_" + (int)skillType, details.SkillName);
}
return details.SkillDef;
}
private static byte[] ReadEmbeddedFileBytes(string resourceName)
{
Assembly executingAssembly = Assembly.GetExecutingAssembly();
string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
string text = null;
for (int i = 0; i < manifestResourceNames.Length; i++)
{
if (manifestResourceNames[i].EndsWith(resourceName, StringComparison.OrdinalIgnoreCase))
{
text = manifestResourceNames[i];
break;
}
}
if (string.IsNullOrEmpty(text))
{
throw new FileNotFoundException("Embedded resource not found: " + resourceName + "\nAvailable resources:\n" + string.Join("\n", manifestResourceNames));
}
Stream manifestResourceStream = executingAssembly.GetManifestResourceStream(text);
if (manifestResourceStream == null)
{
throw new FileNotFoundException("Embedded resource stream not found: " + text);
}
try
{
MemoryStream memoryStream = new MemoryStream();
try
{
manifestResourceStream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
finally
{
memoryStream.Dispose();
}
}
finally
{
manifestResourceStream.Dispose();
}
}
private static MethodInfo GetLoadImageMethod()
{
if (_searchedLoadImageMethod)
{
return _loadImageMethod;
}
_searchedLoadImageMethod = true;
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
Type type = assemblies[i].GetType("UnityEngine.ImageConversion");
if (!(type == null))
{
MethodInfo method = type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[2]
{
typeof(Texture2D),
typeof(byte[])
}, null);
if (method != null)
{
_loadImageMethod = method;
return _loadImageMethod;
}
method = type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3]
{
typeof(Texture2D),
typeof(byte[]),
typeof(bool)
}, null);
if (method != null)
{
_loadImageMethod = method;
return _loadImageMethod;
}
}
}
return null;
}
private static bool TryLoadImage(Texture2D texture, byte[] data)
{
MethodInfo loadImageMethod = GetLoadImageMethod();
if (loadImageMethod == null)
{
throw new MissingMethodException("Could not find UnityEngine.ImageConversion.LoadImage at runtime.");
}
ParameterInfo[] parameters = loadImageMethod.GetParameters();
object obj = ((parameters.Length != 2) ? loadImageMethod.Invoke(null, new object[3] { texture, data, false }) : loadImageMethod.Invoke(null, new object[2] { texture, data }));
return obj is bool && (bool)obj;
}
private static Texture2D LoadTexture(string name)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Expected O, but got Unknown
byte[] data = ReadEmbeddedFileBytes("icons." + name);
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
bool flag;
try
{
flag = TryLoadImage(val, data);
}
catch
{
Object.Destroy((Object)(object)val);
throw;
}
if (!flag)
{
Object.Destroy((Object)(object)val);
throw new Exception("Failed to load texture from embedded resource: " + name);
}
return val;
}
public static Sprite LoadSprite(string name, int width, int height)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
Texture2D val = LoadTexture(name);
return Sprite.Create(val, new Rect(0f, 0f, (float)width, (float)height), Vector2.zero);
}
public static Sprite loadSprite(string name, int width, int height)
{
return LoadSprite(name, width, height);
}
}
[HarmonyPatch]
internal static class TranslationPatches
{
[HarmonyPatch(typeof(FejdStartup), "SetupGui")]
private class FejdStartup_SetupGUI
{
private static void Postfix()
{
string selectedLanguage = Localization.instance.GetSelectedLanguage();
Dictionary<string, string> translations = GetTranslations(selectedLanguage);
AddTranslations(translations);
}
}
[HarmonyPriority(800)]
[HarmonyPatch(typeof(Localization), "SetupLanguage")]
private class Translation_SetupLanguage
{
private static void Prefix(Localization __instance, string language)
{
Dictionary<string, string> translations = GetTranslations(language);
AddTranslations(translations, __instance);
}
}
[HarmonyPriority(800)]
[HarmonyPatch(typeof(Localization), "LoadCSV")]
private class Translation_LoadCSV
{
private static void Prefix(Localization __instance, string language)
{
Dictionary<string, string> translations = GetTranslations(language);
AddTranslations(translations, __instance);
}
}
private static Dictionary<string, string> GetTranslations(string language)
{
Dictionary<string, string> result = BalrondTranslator.getLanguage("English");
if (!string.Equals(language, "English", StringComparison.OrdinalIgnoreCase))
{
Dictionary<string, string> language2 = BalrondTranslator.getLanguage(language);
if (language2 != null)
{
result = language2;
}
else
{
Debug.Log((object)("BalrondDualMastery: Did not find translation file for '" + language + "', loading English"));
}
}
return result;
}
private static void AddTranslations(Dictionary<string, string> translations, Localization localizationInstance = null)
{
if (translations == null)
{
Debug.LogWarning((object)"BalrondDualMastery: No translation file found!");
return;
}
if (localizationInstance != null)
{
foreach (KeyValuePair<string, string> translation in translations)
{
localizationInstance.AddWord(translation.Key, translation.Value);
}
return;
}
foreach (KeyValuePair<string, string> translation2 in translations)
{
Localization.instance.AddWord(translation2.Key, translation2.Value);
}
}
}
}
namespace LitJson2
{
internal enum JsonType
{
None,
Object,
Array,
String,
Int,
Long,
Double,
Boolean
}
internal interface IJsonWrapper : IList, IOrderedDictionary, IDictionary, ICollection, IEnumerable
{
bool IsArray { get; }
bool IsBoolean { get; }
bool IsDouble { get; }
bool IsInt { get; }
bool IsLong { get; }
bool IsObject { get; }
bool IsString { get; }
bool GetBoolean();
double GetDouble();
int GetInt();
JsonType GetJsonType();
long GetLong();
string GetString();
void SetBoolean(bool val);
void SetDouble(double val);
void SetInt(int val);
void SetJsonType(JsonType type);
void SetLong(long val);
void SetString(string val);
string ToJson();
void ToJson(JsonWriter writer);
}
internal class JsonData : IJsonWrapper, IList, IOrderedDictionary, IDictionary, ICollection, IEnumerable, IEquatable<JsonData>
{
private IList<JsonData> inst_array;
private bool inst_boolean;
private double inst_double;
private int inst_int;
private long inst_long;
private IDictionary<string, JsonData> inst_object;
private string inst_string;
private string json;
private JsonType type;
private IList<KeyValuePair<string, JsonData>> object_list;
public int Count => EnsureCollection().Count;
public bool IsArray => type == JsonType.Array;
public bool IsBoolean => type == JsonType.Boolean;
public bool IsDouble => type == JsonType.Double;
public bool IsInt => type == JsonType.Int;
public bool IsLong => type == JsonType.Long;
public bool IsObject => type == JsonType.Object;
public bool IsString => type == JsonType.String;
public ICollection<string> Keys
{
get
{
EnsureDictionary();
return inst_object.Keys;
}
}
int ICollection.Count => Count;
bool ICollection.IsSynchronized => EnsureCollection().IsSynchronized;
object ICollection.SyncRoot => EnsureCollection().SyncRoot;
bool IDictionary.IsFixedSize => EnsureDictionary().IsFixedSize;
bool IDictionary.IsReadOnly => EnsureDictionary().IsReadOnly;
ICollection IDictionary.Keys
{
get
{
EnsureDictionary();
IList<string> list = new List<string>();
foreach (KeyValuePair<string, JsonData> item in object_list)
{
list.Add(item.Key);
}
return (ICollection)list;
}
}
ICollection IDictionary.Values
{
get
{
EnsureDictionary();
IList<JsonData> list = new List<JsonData>();
foreach (KeyValuePair<string, JsonData> item in object_list)
{
list.Add(item.Value);
}
return (ICollection)list;
}
}
bool IJsonWrapper.IsArray => IsArray;
bool IJsonWrapper.IsBoolean => IsBoolean;
bool IJsonWrapper.IsDouble => IsDouble;
bool IJsonWrapper.IsInt => IsInt;
bool IJsonWrapper.IsLong => IsLong;
bool IJsonWrapper.IsObject => IsObject;
bool IJsonWrapper.IsString => IsString;
bool IList.IsFixedSize => EnsureList().IsFixedSize;
bool IList.IsReadOnly => EnsureList().IsReadOnly;
object IDictionary.this[object key]
{
get
{
return EnsureDictionary()[key];
}
set
{
if (!(key is string))
{
throw new ArgumentException("The key has to be a string");
}
JsonData value2 = ToJsonData(value);
this[(string)key] = value2;
}
}
object IOrderedDictionary.this[int idx]
{
get
{
EnsureDictionary();
return object_list[idx].Value;
}
set
{
EnsureDictionary();
JsonData value2 = ToJsonData(value);
KeyValuePair<string, JsonData> keyValuePair = object_list[idx];
inst_object[keyValuePair.Key] = value2;
KeyValuePair<string, JsonData> value3 = new KeyValuePair<string, JsonData>(keyValuePair.Key, value2);
object_list[idx] = value3;
}
}
object IList.this[int index]
{
get
{
return EnsureList()[index];
}
set
{
EnsureList();
JsonData value2 = ToJsonData(value);
this[index] = value2;
}
}
public JsonData this[string prop_name]
{
get
{
EnsureDictionary();
return inst_object[prop_name];
}
set
{
EnsureDictionary();
KeyValuePair<string, JsonData> keyValuePair = new KeyValuePair<string, JsonData>(prop_name, value);
if (inst_object.ContainsKey(prop_name))
{
for (int i = 0; i < object_list.Count; i++)
{
if (object_list[i].Key == prop_name)
{
object_list[i] = keyValuePair;
break;
}
}
}
else
{
object_list.Add(keyValuePair);
}
inst_object[prop_name] = value;
json = null;
}
}
public JsonData this[int index]
{
get
{
EnsureCollection();
if (type == JsonType.Array)
{
return inst_array[index];
}
return object_list[index].Value;
}
set
{
EnsureCollection();
if (type == JsonType.Array)
{
inst_array[index] = value;
}
else
{
KeyValuePair<string, JsonData> keyValuePair = object_list[index];
KeyValuePair<string, JsonData> value2 = new KeyValuePair<string, JsonData>(keyValuePair.Key, value);
object_list[index] = value2;
inst_object[keyValuePair.Key] = value;
}
json = null;
}
}
public JsonData()
{
}
public JsonData(bool boolean)
{
type = JsonType.Boolean;
inst_boolean = boolean;
}
public JsonData(double number)
{
type = JsonType.Double;
inst_double = number;
}
public JsonData(int number)
{
type = JsonType.Int;
inst_int = number;
}
public JsonData(long number)
{
type = JsonType.Long;
inst_long = number;
}
public JsonData(object obj)
{
if (obj is bool)
{
type = JsonType.Boolean;
inst_boolean = (bool)obj;
return;
}
if (obj is double)
{
type = JsonType.Double;
inst_double = (double)obj;
return;
}
if (obj is int)
{
type = JsonType.Int;
inst_int = (int)obj;
return;
}
if (obj is long)
{
type = JsonType.Long;
inst_long = (long)obj;
return;
}
if (obj is string)
{
type = JsonType.String;
inst_string = (string)obj;
return;
}
throw new ArgumentException("Unable to wrap the given object with JsonData");
}
public JsonData(string str)
{
type = JsonType.String;
inst_string = str;
}
public static implicit operator JsonData(bool data)
{
return new JsonData(data);
}
public static implicit operator JsonData(double data)
{
return new JsonData(data);
}
public static implicit operator JsonData(int data)
{
return new JsonData(data);
}
public static implicit operator JsonData(long data)
{
return new JsonData(data);
}
public static implicit operator JsonData(string data)
{
return new JsonData(data);
}
public static explicit operator bool(JsonData data)
{
if (data.type != JsonType.Boolean)
{
throw new InvalidCastException("Instance of JsonData doesn't hold a double");
}
return data.inst_boolean;
}
public static explicit operator double(JsonData data)
{
if (data.type != JsonType.Double)
{
throw new InvalidCastException("Instance of JsonData doesn't hold a double");
}
return data.inst_double;
}
public static explicit operator int(JsonData data)
{
if (data.type != JsonType.Int)
{
throw new InvalidCastException("Instance of JsonData doesn't hold an int");
}
return data.inst_int;
}
public static explicit operator long(JsonData data)
{
if (data.type != JsonType.Long)
{
throw new InvalidCastException("Instance of JsonData doesn't hold an int");
}
return data.inst_long;
}
public static explicit operator string(JsonData data)
{
if (data.type != JsonType.String)
{
throw new InvalidCastException("Instance of JsonData doesn't hold a string");
}
return data.inst_string;
}
void ICollection.CopyTo(Array array, int index)
{
EnsureCollection().CopyTo(array, index);
}
void IDictionary.Add(object key, object value)
{
JsonData value2 = ToJsonData(value);
EnsureDictionary().Add(key, value2);
KeyValuePair<string, JsonData> item = new KeyValuePair<string, JsonData>((string)key, value2);
object_list.Add(item);
json = null;
}
void IDictionary.Clear()
{
EnsureDictionary().Clear();
object_list.Clear();
json = null;
}
bool IDictionary.Contains(object key)
{
return EnsureDictionary().Contains(key);
}
IDictionaryEnumerator IDictionary.GetEnumerator()
{
return ((IOrderedDictionary)this).GetEnumerator();
}
void IDictionary.Remove(object key)
{
EnsureDictionary().Remove(key);
for (int i = 0; i < object_list.Count; i++)
{
if (object_list[i].Key == (string)key)
{
object_list.RemoveAt(i);
break;
}
}
json = null;
}
IEnumerator IEnumerable.GetEnumerator()
{
return EnsureCollection().GetEnumerator();
}
bool IJsonWrapper.GetBoolean()
{
if (type != JsonType.Boolean)
{
throw new InvalidOperationException("JsonData instance doesn't hold a boolean");
}
return inst_boolean;
}
double IJsonWrapper.GetDouble()
{
if (type != JsonType.Double)
{
throw new InvalidOperationException("JsonData instance doesn't hold a double");
}
return inst_double;
}
int IJsonWrapper.GetInt()
{
if (type != JsonType.Int)
{
throw new InvalidOperationException("JsonData instance doesn't hold an int");
}
return inst_int;
}
long IJsonWrapper.GetLong()
{
if (type != JsonType.Long)
{
throw new InvalidOperationException("JsonData instance doesn't hold a long");
}
return inst_long;
}
string IJsonWrapper.GetString()
{
if (type != JsonType.String)
{
throw new InvalidOperationException("JsonData instance doesn't hold a string");
}
return inst_string;
}
void IJsonWrapper.SetBoolean(bool val)
{
type = JsonType.Boolean;
inst_boolean = val;
json = null;
}
void IJsonWrapper.SetDouble(double val)
{
type = JsonType.Double;
inst_double = val;
json = null;
}
void IJsonWrapper.SetInt(int val)
{
type = JsonType.Int;
inst_int = val;
json = null;
}
void IJsonWrapper.SetLong(long val)
{
type = JsonType.Long;
inst_long = val;
json = null;
}
void IJsonWrapper.SetString(string val)
{
type = JsonType.String;
inst_string = val;
json = null;
}
string IJsonWrapper.ToJson()
{
return ToJson();
}
void IJsonWrapper.ToJson(JsonWriter writer)
{
ToJson(writer);
}
int IList.Add(object value)
{
return Add(value);
}
void IList.Clear()
{
EnsureList().Clear();
json = null;
}
bool IList.Contains(object value)
{
return EnsureList().Contains(value);
}
int IList.IndexOf(object value)
{
return EnsureList().IndexOf(value);
}
void IList.Insert(int index, object value)
{
EnsureList().Insert(index, value);
json = null;
}
void IList.Remove(object value)
{
EnsureList().Remove(value);
json = null;
}
void IList.RemoveAt(int index)
{
EnsureList().RemoveAt(index);
json = null;
}
IDictionaryEnumerator IOrderedDictionary.GetEnumerator()
{
EnsureDictionary();
return new OrderedDictionaryEnumerator(object_list.GetEnumerator());
}
void IOrderedDictionary.Insert(int idx, object key, object value)
{
string text = (string)key;
JsonData value2 = (this[text] = ToJsonData(value));
KeyValuePair<string, JsonData> item = new KeyValuePair<string, JsonData>(text, value2);
object_list.Insert(idx, item);
}
void IOrderedDictionary.RemoveAt(int idx)
{
EnsureDictionary();
inst_object.Remove(object_list[idx].Key);
object_list.RemoveAt(idx);
}
private ICollection EnsureCollection()
{
if (type == JsonType.Array)
{
return (ICollection)inst_array;
}
if (type == JsonType.Object)
{
return (ICollection)inst_object;
}
throw new InvalidOperationException("The JsonData instance has to be initialized first");
}
private IDictionary EnsureDictionary()
{
if (type == JsonType.Object)
{
return (IDictionary)inst_object;
}
if (type != 0)
{
throw new InvalidOperationException("Instance of JsonData is not a dictionary");
}
type = JsonType.Object;
inst_object = new Dictionary<string, JsonData>();
object_list = new List<KeyValuePair<string, JsonData>>();
return (IDictionary)inst_object;
}
private IList EnsureList()
{
if (type == JsonType.Array)
{
return (IList)inst_array;
}
if (type != 0)
{
throw new InvalidOperationException("Instance of JsonData is not a list");
}
type = JsonType.Array;
inst_array = new List<JsonData>();
return (IList)inst_array;
}
private JsonData ToJsonData(object obj)
{
if (obj == null)
{
return null;
}
if (obj is JsonData)
{
return (JsonData)obj;
}
return new JsonData(obj);
}
private static void WriteJson(IJsonWrapper obj, JsonWriter writer)
{
if (obj == null)
{
writer.Write(null);
}
else if (obj.IsString)
{
writer.Write(obj.GetString());
}
else if (obj.IsBoolean)
{
writer.Write(obj.GetBoolean());
}
else if (obj.IsDouble)
{
writer.Write(obj.GetDouble());
}
else if (obj.IsInt)
{
writer.Write(obj.GetInt());
}
else if (obj.IsLong)
{
writer.Write(obj.GetLong());
}
else if (obj.IsArray)
{
writer.WriteArrayStart();
foreach (object item in (IEnumerable)obj)
{
WriteJson((JsonData)item, writer);
}
writer.WriteArrayEnd();
}
else
{
if (!obj.IsObject)
{
return;
}
writer.WriteObjectStart();
foreach (DictionaryEntry item2 in (IDictionary)obj)
{
writer.WritePropertyName((string)item2.Key);
WriteJson((JsonData)item2.Value, writer);
}
writer.WriteObjectEnd();
}
}
public int Add(object value)
{
JsonData value2 = ToJsonData(value);
json = null;
return EnsureList().Add(value2);
}
public void Clear()
{
if (IsObject)
{
((IDictionary)this).Clear();
}
else if (IsArray)
{
((IList)this).Clear();
}
}
public bool Equals(JsonData x)
{
if (x == null)
{
return false;
}
if (x.type != type)
{
return false;
}
return type switch
{
JsonType.None => true,
JsonType.Object => inst_object.Equals(x.inst_object),
JsonType.Array => inst_array.Equals(x.inst_array),
JsonType.String => inst_string.Equals(x.inst_string),
JsonType.Int => inst_int.Equals(x.inst_int),
JsonType.Long => inst_long.Equals(x.inst_long),
JsonType.Double => inst_double.Equals(x.inst_double),
JsonType.Boolean => inst_boolean.Equals(x.inst_boolean),
_ => false,
};
}
public JsonType GetJsonType()
{
return type;
}
public void SetJsonType(JsonType type)
{
if (this.type != type)
{
switch (type)
{
case JsonType.Object:
inst_object = new Dictionary<string, JsonData>();
object_list = new List<KeyValuePair<string, JsonData>>();
break;
case JsonType.Array:
inst_array = new List<JsonData>();
break;
case JsonType.String:
inst_string = null;
break;
case JsonType.Int:
inst_int = 0;
break;
case JsonType.Long:
inst_long = 0L;
break;
case JsonType.Double:
inst_double = 0.0;
break;
case JsonType.Boolean:
inst_boolean = false;
break;
}
this.type = type;
}
}
public string ToJson()
{
if (json != null)
{
return json;
}
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.Validate = false;
WriteJson(this, jsonWriter);
json = stringWriter.ToString();
return json;
}
public void ToJson(JsonWriter writer)
{
bool validate = writer.Validate;
writer.Validate = false;
WriteJson(this, writer);
writer.Validate = validate;
}
public override string ToString()
{
return type switch
{
JsonType.Array => "JsonData array",
JsonType.Boolean => inst_boolean.ToString(),
JsonType.Double => inst_double.ToString(),
JsonType.Int => inst_int.ToString(),
JsonType.Long => inst_long.ToString(),
JsonType.Object => "JsonData object",
JsonType.String => inst_string,
_ => "Uninitialized JsonData",
};
}
}
internal class OrderedDictionaryEnumerator : IDictionaryEnumerator, IEnumerator
{
private IEnumerator<KeyValuePair<string, JsonData>> list_enumerator;
public object Current => Entry;
public DictionaryEntry Entry
{
get
{
KeyValuePair<string, JsonData> current = list_enumerator.Current;
return new DictionaryEntry(current.Key, current.Value);
}
}
public object Key => list_enumerator.Current.Key;
public object Value => list_enumerator.Current.Value;
public OrderedDictionaryEnumerator(IEnumerator<KeyValuePair<string, JsonData>> enumerator)
{
list_enumerator = enumerator;
}
public bool MoveNext()
{
return list_enumerator.MoveNext();
}
public void Reset()
{
list_enumerator.Reset();
}
}
internal class JsonException : ApplicationException
{
public JsonException()
{
}
internal JsonException(ParserToken token)
: base($"Invalid token '{token}' in input string")
{
}
internal JsonException(ParserToken token, Exception inner_exception)
: base($"Invalid token '{token}' in input string", inner_exception)
{
}
internal JsonException(int c)
: base($"Invalid character '{(char)c}' in input string")
{
}
internal JsonException(int c, Exception inner_exception)
: base($"Invalid character '{(char)c}' in input string", inner_exception)
{
}
public JsonException(string message)
: base(message)
{
}
public JsonException(string message, Exception inner_exception)
: base(message, inner_exception)
{
}
}
internal struct PropertyMetadata
{
public MemberInfo Info;
public bool IsField;
public Type Type;
}
internal struct ArrayMetadata
{
private Type element_type;
private bool is_array;
private bool is_list;
public Type ElementType
{
get
{
if (element_type == null)
{
return typeof(JsonData);
}
return element_type;
}
set
{
element_type = value;
}
}
public bool IsArray
{
get
{
return is_array;
}
set
{
is_array = value;
}
}
public bool IsList
{
get
{
return is_list;
}
set
{
is_list = value;
}
}
}
internal struct ObjectMetadata
{
private Type element_type;
private bool is_dictionary;
private IDictionary<string, PropertyMetadata> properties;
public Type ElementType
{
get
{
if (element_type == null)
{
return typeof(JsonData);
}
return element_type;
}
set
{
element_type = value;
}
}
public bool IsDictionary
{
get
{
return is_dictionary;
}
set
{
is_dictionary = value;
}
}
public IDictionary<string, PropertyMetadata> Properties
{
get
{
return properties;
}
set
{
properties = value;
}
}
}
internal delegate void ExporterFunc(object obj, JsonWriter writer);
internal delegate void ExporterFunc<T>(T obj, JsonWriter writer);
internal delegate object ImporterFunc(object input);
internal delegate TValue ImporterFunc<TJson, TValue>(TJson input);
internal delegate IJsonWrapper WrapperFactory();
internal class JsonMapper
{
private static int max_nesting_depth;
private static IFormatProvider datetime_format;
private static IDictionary<Type, ExporterFunc> base_exporters_table;
private static IDictionary<Type, ExporterFunc> custom_exporters_table;
private static IDictionary<Type, IDictionary<Type, ImporterFunc>> base_importers_table;
private static IDictionary<Type, IDictionary<Type, ImporterFunc>> custom_importers_table;
private static IDictionary<Type, ArrayMetadata> array_metadata;
private static readonly object array_metadata_lock;
private static IDictionary<Type, IDictionary<Type, MethodInfo>> conv_ops;
private static readonly object conv_ops_lock;
private static IDictionary<Type, ObjectMetadata> object_metadata;
private static readonly object object_metadata_lock;
private static IDictionary<Type, IList<PropertyMetadata>> type_properties;
private static readonly object type_properties_lock;
private static JsonWriter static_writer;
private static readonly object static_writer_lock;
static JsonMapper()
{
array_metadata_lock = new object();
conv_ops_lock = new object();
object_metadata_lock = new object();
type_properties_lock = new object();
static_writer_lock = new object();
max_nesting_depth = 100;
array_metadata = new Dictionary<Type, ArrayMetadata>();
conv_ops = new Dictionary<Type, IDictionary<Type, MethodInfo>>();
object_metadata = new Dictionary<Type, ObjectMetadata>();
type_properties = new Dictionary<Type, IList<PropertyMetadata>>();
static_writer = new JsonWriter();
datetime_format = DateTimeFormatInfo.InvariantInfo;
base_exporters_table = new Dictionary<Type, ExporterFunc>();
custom_exporters_table = new Dictionary<Type, ExporterFunc>();
base_importers_table = new Dictionary<Type, IDictionary<Type, ImporterFunc>>();
custom_importers_table = new Dictionary<Type, IDictionary<Type, ImporterFunc>>();
RegisterBaseExporters();
RegisterBaseImporters();
}
private static void AddArrayMetadata(Type type)
{
if (array_metadata.ContainsKey(type))
{
return;
}
ArrayMetadata value = default(ArrayMetadata);
value.IsArray = type.IsArray;
if (type.GetInterface("System.Collections.IList") != null)
{
value.IsList = true;
}
PropertyInfo[] properties = type.GetProperties();
foreach (PropertyInfo propertyInfo in properties)
{
if (!(propertyInfo.Name != "Item"))
{
ParameterInfo[] indexParameters = propertyInfo.GetIndexParameters();
if (indexParameters.Length == 1 && indexParameters[0].ParameterType == typeof(int))
{
value.ElementType = propertyInfo.PropertyType;
}
}
}
lock (array_metadata_lock)
{
try
{
array_metadata.Add(type, value);
}
catch (ArgumentException)
{
}
}
}
private static void AddObjectMetadata(Type type)
{
if (object_metadata.ContainsKey(type))
{
return;
}
ObjectMetadata value = default(ObjectMetadata);
if (type.GetInterface("System.Collections.IDictionary") != null)
{
value.IsDictionary = true;
}
value.Properties = new Dictionary<string, PropertyMetadata>();
PropertyInfo[] properties = type.GetProperties();
foreach (PropertyInfo propertyInfo in properties)
{
if (propertyInfo.Name == "Item")
{
ParameterInfo[] indexParameters = propertyInfo.GetIndexParameters();
if (indexParameters.Length == 1 && indexParameters[0].ParameterType == typeof(string))
{
value.ElementType = propertyInfo.PropertyType;
}
}
else
{
PropertyMetadata value2 = default(PropertyMetadata);
value2.Info = propertyInfo;
value2.Type = propertyInfo.PropertyType;
value.Properties.Add(propertyInfo.Name, value2);
}
}
FieldInfo[] fields = type.GetFields();
foreach (FieldInfo fieldInfo in fields)
{
PropertyMetadata value3 = default(PropertyMetadata);
value3.Info = fieldInfo;
value3.IsField = true;
value3.Type = fieldInfo.FieldType;
value.Properties.Add(fieldInfo.Name, value3);
}
lock (object_metadata_lock)
{
try
{
object_metadata.Add(type, value);
}
catch (ArgumentException)
{
}
}
}
private static void AddTypeProperties(Type type)
{
if (type_properties.ContainsKey(type))
{
return;
}
IList<PropertyMetadata> list = new List<PropertyMetadata>();
PropertyInfo[] properties = type.GetProperties();
foreach (PropertyInfo propertyInfo in properties)
{
if (!(propertyInfo.Name == "Item"))
{
PropertyMetadata item = default(PropertyMetadata);
item.Info = propertyInfo;
item.IsField = false;
list.Add(item);
}
}
FieldInfo[] fields = type.GetFields();
foreach (FieldInfo info in fields)
{
PropertyMetadata item2 = default(PropertyMetadata);
item2.Info = info;
item2.IsField = true;
list.Add(item2);
}
lock (type_properties_lock)
{
try
{
type_properties.Add(type, list);
}
catch (ArgumentException)
{
}
}
}
private static MethodInfo GetConvOp(Type t1, Type t2)
{
lock (conv_ops_lock)
{
if (!conv_ops.ContainsKey(t1))
{
conv_ops.Add(t1, new Dictionary<Type, MethodInfo>());
}
}
if (conv_ops[t1].ContainsKey(t2))
{
return conv_ops[t1][t2];
}
MethodInfo method = t1.GetMethod("op_Implicit", new Type[1] { t2 });
lock (conv_ops_lock)
{
try
{
conv_ops[t1].Add(t2, method);
return method;
}
catch (ArgumentException)
{
return conv_ops[t1][t2];
}
}
}
private static object ReadValue(Type inst_type, JsonReader reader)
{
reader.Read();
if (reader.Token == JsonToken.ArrayEnd)
{
return null;
}
Type underlyingType = Nullable.GetUnderlyingType(inst_type);
Type type = underlyingType ?? inst_type;
if (reader.Token == JsonToken.Null)
{
if (inst_type.IsClass || underlyingType != null)
{
return null;
}
throw new JsonException($"Can't assign null to an instance of type {inst_type}");
}
if (reader.Token == JsonToken.Double || reader.Token == JsonToken.Int || reader.Token == JsonToken.Long || reader.Token == JsonToken.String || reader.Token == JsonToken.Boolean)
{
Type type2 = reader.Value.GetType();
if (type.IsAssignableFrom(type2))
{
return reader.Value;
}
if (custom_importers_table.ContainsKey(type2) && custom_importers_table[type2].ContainsKey(type))
{
ImporterFunc importerFunc = custom_importers_table[type2][type];
return importerFunc(reader.Value);
}
if (base_importers_table.ContainsKey(type2) && base_importers_table[type2].ContainsKey(type))
{
ImporterFunc importerFunc2 = base_importers_table[type2][type];
return importerFunc2(reader.Value);
}
if (type.IsEnum)
{
return Enum.ToObject(type, reader.Value);
}
MethodInfo convOp = GetConvOp(type, type2);
if (convOp != null)
{
return convOp.Invoke(null, new object[1] { reader.Value });
}
throw new JsonException($"Can't assign value '{reader.Value}' (type {type2}) to type {inst_type}");
}
object obj = null;
if (reader.Token == JsonToken.ArrayStart)
{
AddArrayMetadata(inst_type);
ArrayMetadata arrayMetadata = array_metadata[inst_type];
if (!arrayMetadata.IsArray && !arrayMetadata.IsList)
{
throw new JsonException($"Type {inst_type} can't act as an array");
}
IList list;
Type elementType;
if (!arrayMetadata.IsArray)
{
list = (IList)Activator.CreateInstance(inst_type);
elementType = arrayMetadata.ElementType;
}
else
{
list = new ArrayList();
elementType = inst_type.GetElementType();
}
while (true)
{
object obj2 = ReadValue(elementType, reader);
if (obj2 == null && reader.Token == JsonToken.ArrayEnd)
{
break;
}
list.Add(obj2);
}
if (arrayMetadata.IsArray)
{
int count = list.Count;
obj = Array.CreateInstance(elementType, count);
for (int i = 0; i < count; i++)
{
((Array)obj).SetValue(list[i], i);
}
}
else
{
obj = list;
}
}
else if (reader.Token == JsonToken.ObjectStart)
{
AddObjectMetadata(type);
ObjectMetadata objectMetadata = object_metadata[type];
obj = Activator.CreateInstance(type);
while (true)
{
reader.Read();
if (reader.Token == JsonToken.ObjectEnd)
{
break;
}
string text = (string)reader.Value;
if (objectMetadata.Properties.ContainsKey(text))
{
PropertyMetadata propertyMetadata = objectMetadata.Properties[text];
if (propertyMetadata.IsField)
{
((FieldInfo)propertyMetadata.Info).SetValue(obj, ReadValue(propertyMetadata.Type, reader));
continue;
}
PropertyInfo propertyInfo = (PropertyInfo)propertyMetadata.Info;
if (propertyInfo.CanWrite)
{
propertyInfo.SetValue(obj, ReadValue(propertyMetadata.Type, reader), null);
}
else
{
ReadValue(propertyMetadata.Type, reader);
}
}
else if (!objectMetadata.IsDictionary)
{
if (!reader.SkipNonMembers)
{
throw new JsonException($"The type {inst_type} doesn't have the property '{text}'");
}
ReadSkip(reader);
}
else
{
((IDictionary)obj).Add(text, ReadValue(objectMetadata.ElementType, reader));
}
}
}
return obj;
}
private static IJsonWrapper ReadValue(WrapperFactory factory, JsonReader reader)
{
reader.Read();
if (reader.Token == JsonToken.ArrayEnd || reader.Token == JsonToken.Null)
{
return null;
}
IJsonWrapper jsonWrapper = factory();
if (reader.Token == JsonToken.String)
{
jsonWrapper.SetString((string)reader.Value);
return jsonWrapper;
}
if (reader.Token == JsonToken.Double)
{
jsonWrapper.SetDouble((double)reader.Value);
return jsonWrapper;
}
if (reader.Token == JsonToken.Int)
{
jsonWrapper.SetInt((int)reader.Value);
return jsonWrapper;
}
if (reader.Token == JsonToken.Long)
{
jsonWrapper.SetLong((long)reader.Value);
return jsonWrapper;
}
if (reader.Token == JsonToken.Boolean)
{
jsonWrapper.SetBoolean((bool)reader.Value);
return jsonWrapper;
}
if (reader.Token == JsonToken.ArrayStart)
{
jsonWrapper.SetJsonType(JsonType.Array);
while (true)
{
IJsonWrapper jsonWrapper2 = ReadValue(factory, reader);
if (jsonWrapper2 == null && reader.Token == JsonToken.ArrayEnd)
{
break;
}
jsonWrapper.Add(jsonWrapper2);
}
}
else if (reader.Token == JsonToken.ObjectStart)
{
jsonWrapper.SetJsonType(JsonType.Object);
while (true)
{
reader.Read();
if (reader.Token == JsonToken.ObjectEnd)
{
break;
}
string key = (string)reader.Value;
jsonWrapper[key] = ReadValue(factory, reader);
}
}
return jsonWrapper;
}
private static void ReadSkip(JsonReader reader)
{
ToWrapper(() => new JsonMockWrapper(), reader);
}
private static void RegisterBaseExporters()
{
base_exporters_table[typeof(byte)] = delegate(object obj, JsonWriter writer)
{
writer.Write(Convert.ToInt32((byte)obj));
};
base_exporters_table[typeof(char)] = delegate(object obj, JsonWriter writer)
{
writer.Write(Convert.ToString((char)obj));
};
base_exporters_table[typeof(DateTime)] = delegate(object obj, JsonWriter writer)
{
writer.Write(Convert.ToString((DateTime)obj, datetime_format));
};
base_exporters_table[typeof(decimal)] = delegate(object obj, JsonWriter writer)
{
writer.Write((decimal)obj);
};
base_exporters_table[typeof(sbyte)] = delegate(object obj, JsonWriter writer)
{
writer.Write(Convert.ToInt32((sbyte)obj));
};
base_exporters_table[typeof(short)] = delegate(object obj, JsonWriter writer)
{
writer.Write(Convert.ToInt32((short)obj));
};
base_exporters_table[typeof(ushort)] = delegate(object obj, JsonWriter writer)
{
writer.Write(Convert.ToInt32((ushort)obj));
};
base_exporters_table[typeof(uint)] = delegate(object obj, JsonWriter writer)
{
writer.Write(Convert.ToUInt64((uint)obj));
};
base_exporters_table[typeof(ulong)] = delegate(object obj, JsonWriter writer)
{
writer.Write((ulong)obj);
};
}
private static void RegisterBaseImporters()
{
ImporterFunc importer = (object input) => Convert.ToByte((int)input);
RegisterImporter(base_importers_table, typeof(int), typeof(byte), importer);
importer = (object input) => Convert.ToUInt64((int)input);
RegisterImporter(base_importers_table, typeof(int), typeof(ulong), importer);
importer = (object input) => Convert.ToSByte((int)input);
RegisterImporter(base_importers_table, typeof(int), typeof(sbyte), importer);
importer = (object input) => Convert.ToInt16((int)input);
RegisterImporter(base_importers_table, typeof(int), typeof(short), importer);
importer = (object input) => Convert.ToUInt16((int)input);
RegisterImporter(base_importers_table, typeof(int), typeof(ushort), importer);
importer = (object input) => Convert.ToUInt32((int)input);
RegisterImporter(base_importers_table, typeof(int), typeof(uint), importer);
importer = (object input) => Convert.ToSingle((int)input);
RegisterImporter(base_importers_table, typeof(int), typeof(float), importer);
importer = (object input) => Convert.ToDouble((int)input);
RegisterImporter(base_importers_table, typeof(int), typeof(double), importer);
importer = (object input) => Convert.ToDecimal((double)input);
RegisterImporter(base_importers_table, typeof(double), typeof(decimal), importer);
importer = (object input) => Convert.ToUInt32((long)input);
RegisterImporter(base_importers_table, typeof(long), typeof(uint), importer);
importer = (object input) => Convert.ToChar((string)input);
RegisterImporter(base_importers_table, typeof(string), typeof(char), importer);
importer = (object input) => Convert.ToDateTime((string)input, datetime_format);
RegisterImporter(base_importers_table, typeof(string), typeof(DateTime), importer);
}
private static void RegisterImporter(IDictionary<Type, IDictionary<Type, ImporterFunc>> table, Type json_type, Type value_type, ImporterFunc importer)
{
if (!table.ContainsKey(json_type))
{
table.Add(json_type, new Dictionary<Type, ImporterFunc>());
}
table[json_type][value_type] = importer;
}
private static void WriteValue(object obj, JsonWriter writer, bool writer_is_private, int depth)
{
if (depth > max_nesting_depth)
{
throw new JsonException($"Max allowed object depth reached while trying to export from type {obj.GetType()}");
}
if (obj == null)
{
writer.Write(null);
return;
}
if (obj is IJsonWrapper)
{
if (writer_is_private)
{
writer.TextWriter.Write(((IJsonWrapper)obj).ToJson());
}
else
{
((IJsonWrapper)obj).ToJson(writer);
}
return;
}
if (obj is string)
{
writer.Write((string)obj);
return;
}
if (obj is double)
{
writer.Write((double)obj);
return;
}
if (obj is int)
{
writer.Write((int)obj);
return;
}
if (obj is bool)
{
writer.Write((bool)obj);
return;
}
if (obj is long)
{
writer.Write((long)obj);
return;
}
if (obj is Array)
{
writer.WriteArrayStart();
foreach (object item in (Array)obj)
{
WriteValue(item, writer, writer_is_private, depth + 1);
}
writer.WriteArrayEnd();
return;
}
if (obj is IList)
{
writer.WriteArrayStart();
foreach (object item2 in (IList)obj)
{
WriteValue(item2, writer, writer_is_private, depth + 1);
}
writer.WriteArrayEnd();
return;
}
if (obj is IDictionary)
{
writer.WriteObjectStart();
foreach (DictionaryEntry item3 in (IDictionary)obj)
{
writer.WritePropertyName((string)item3.Key);
WriteValue(item3.Value, writer, writer_is_private, depth + 1);
}
writer.WriteObjectEnd();
return;
}
Type type = obj.GetType();
if (custom_exporters_table.ContainsKey(type))
{
ExporterFunc exporterFunc = custom_exporters_table[type];
exporterFunc(obj, writer);
return;
}
if (base_exporters_table.ContainsKey(type))
{
ExporterFunc exporterFunc2 = base_exporters_table[type];
exporterFunc2(obj, writer);
return;
}
if (obj is Enum)
{
Type underlyingType = Enum.GetUnderlyingType(type);
if (underlyingType == typeof(long) || underlyingType == typeof(uint) || underlyingType == typeof(ulong))
{
writer.Write((ulong)obj);
}
else
{
writer.Write((int)obj);
}
return;
}
AddTypeProperties(type);
IList<PropertyMetadata> list = type_properties[type];
writer.WriteObjectStart();
foreach (PropertyMetadata item4 in list)
{
if (item4.IsField)
{
writer.WritePropertyName(item4.Info.Name);
WriteValue(((FieldInfo)item4.Info).GetValue(obj), writer, writer_is_private, depth + 1);
continue;
}
PropertyInfo propertyInfo = (PropertyInfo)item4.Info;
if (propertyInfo.CanRead)
{
writer.WritePropertyName(item4.Info.Name);
WriteValue(propertyInfo.GetValue(obj, null), writer, writer_is_private, depth + 1);
}
}
writer.WriteObjectEnd();
}
public static string ToJson(object obj)
{
lock (static_writer_lock)
{
static_writer.Reset();
WriteValue(obj, static_writer, writer_is_private: true, 0);
return static_writer.ToString();
}
}
public static void ToJson(object obj, JsonWriter writer)
{
WriteValue(obj, writer, writer_is_private: false, 0);
}
public static JsonData ToObject(JsonReader reader)
{
return (JsonData)ToWrapper(() => new JsonData(), reader);
}
public static JsonData ToObject(TextReader reader)
{
JsonReader reader2 = new JsonReader(reader);
return (JsonData)ToWrapper(() => new JsonData(), reader2);
}
public static JsonData ToObject(string json)
{
return (JsonData)ToWrapper(() => new JsonData(), json);
}
public static T ToObject<T>(JsonReader reader)
{
return (T)ReadValue(typeof(T), reader);
}
public static T ToObject<T>(TextReader reader)
{
JsonReader reader2 = new JsonReader(reader);
return (T)ReadValue(typeof(T), reader2);
}
public static T ToObject<T>(string json)
{
JsonReader reader = new JsonReader(json);
return (T)ReadValue(typeof(T), reader);
}
public static IJsonWrapper ToWrapper(WrapperFactory factory, JsonReader reader)
{
return ReadValue(factory, reader);
}
public static IJsonWrapper ToWrapper(WrapperFactory factory, string json)
{
JsonReader reader = new JsonReader(json);
return ReadValue(factory, reader);
}
public static void RegisterExporter<T>(ExporterFunc<T> exporter)
{
ExporterFunc value = delegate(object obj, JsonWriter writer)
{
exporter((T)obj, writer);
};
custom_exporters_table[typeof(T)] = value;
}
public static void RegisterImporter<TJson, TValue>(ImporterFunc<TJson, TValue> importer)
{
ImporterFunc importer2 = (object input) => importer((TJson)input);
RegisterImporter(custom_importers_table, typeof(TJson), typeof(TValue), importer2);
}
public static void UnregisterExporters()
{
custom_exporters_table.Clear();
}
public static void UnregisterImporters()
{
custom_importers_table.Clear();
}
}
internal class JsonMockWrapper : IJsonWrapper, IList, IOrderedDictionary, IDictionary, ICollection, IEnumerable
{
public bool IsArray => false;
public bool IsBoolean => false;
public bool IsDouble => false;
public bool IsInt => false;
public bool IsLong => false;
public bool IsObject => false;
public bool IsString => false;
bool IList.IsFixedSize => true;
bool IList.IsReadOnly => true;
object IList.this[int index]
{
get
{
return null;
}
set
{
}
}
int ICollection.Count => 0;
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => null;
bool IDictionary.IsFixedSize => true;
bool IDictionary.IsReadOnly => true;
ICollection IDictionary.Keys => null;
ICollection IDictionary.Values => null;
object IDictionary.this[object key]
{
get
{
return null;
}
set
{
}
}
object IOrderedDictionary.this[int idx]
{
get
{
return null;
}
set
{
}
}
public bool GetBoolean()
{
return false;
}
public double GetDouble()
{
return 0.0;
}
public int GetInt()
{
return 0;
}
public JsonType GetJsonType()
{
return JsonType.None;
}
public long GetLong()
{
return 0L;
}
public string GetString()
{
return "";
}
public void SetBoolean(bool val)
{
}
public void SetDouble(double val)
{
}
public void SetInt(int val)
{
}
public void SetJsonType(JsonType type)
{
}
public void SetLong(long val)
{
}
public void SetString(string val)
{
}
public string ToJson()
{
return "";
}
public void ToJson(JsonWriter writer)
{
}
int IList.Add(object value)
{
return 0;
}
void IList.Clear()
{
}
bool IList.Contains(object value)
{
return false;
}
int IList.IndexOf(object value)
{
return -1;
}
void IList.Insert(int i, object v)
{
}
void IList.Remove(object value)
{
}
void IList.RemoveAt(int index)
{
}
void ICollection.CopyTo(Array array, int index)
{
}
IEnumerator IEnumerable.GetEnumerator()
{
return null;
}
void IDictionary.Add(object k, object v)
{
}
void IDictionary.Clear()
{
}
bool IDictionary.Contains(object key)
{
return false;
}
void IDictionary.Remove(object key)
{
}
IDictionaryEnumerator IDictionary.GetEnumerator()
{
return null;
}
IDictionaryEnumerator IOrderedDictionary.GetEnumerator()
{
return null;
}
void IOrderedDictionary.Insert(int i, object k, object v)
{
}
void IOrderedDictionary.RemoveAt(int i)
{
}
}
internal enum JsonToken
{
None,
ObjectStart,
PropertyName,
ObjectEnd,
ArrayStart,
ArrayEnd,
Int,
Long,
Double,
String,
Boolean,
Null
}
internal class JsonReader
{
private static IDictionary<int, IDictionary<int, int[]>> parse_table;
private Stack<int> automaton_stack;
private int current_input;
private int current_symbol;
private bool end_of_json;
private bool end_of_input;
private Lexer lexer;
private bool parser_in_string;
private bool parser_return;
private bool read_started;
private TextReader reader;
private bool reader_is_owned;
private bool skip_non_members;
private object token_value;
private JsonToken token;
public bool AllowComments
{
get
{
return lexer.AllowComments;
}
set
{
lexer.AllowComments = value;
}
}
public bool AllowSingleQuotedStrings
{
get
{
return lexer.AllowSingleQuotedStrings;
}
set
{
lexer.AllowSingleQuotedStrings = value;
}
}
public bool SkipNonMembers
{
get
{
return skip_non_members;
}
set
{
skip_non_members = value;
}
}
public bool EndOfInput => end_of_input;
public bool EndOfJson => end_of_json;
public JsonToken Token => token;
public object Value => token_value;
static JsonReader()
{
PopulateParseTable();
}
public JsonReader(string json_text)
: this(new StringReader(json_text), owned: true)
{
}
public JsonReader(TextReader reader)
: this(reader, owned: false)
{
}
private JsonReader(TextReader reader, bool owned)
{
if (reader == null)
{
throw new ArgumentNullException("reader");
}
parser_in_string = false;
parser_return = false;
read_started = false;
automaton_stack = new Stack<int>();
automaton_stack.Push(65553);
automaton_stack.Push(65543);
lexer = new Lexer(reader);
end_of_input = false;
end_of_json = false;
skip_non_members = true;