using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Unity.IL2CPP;
using CellMenu;
using GTFO.API.Utilities;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Localization;
using MTFO.API;
using MTFO.Ext.PartialData;
using MTFO.Ext.PartialData.JsonConverters;
using Microsoft.CodeAnalysis;
using Player;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using WeaponStatShower.Dependencies;
using WeaponStatShower.ExtraDescription;
using WeaponStatShower.ExtraDescription.Data;
using WeaponStatShower.Json;
using WeaponStatShower.Json.Converters.Utils;
using WeaponStatShower.Patches;
using WeaponStatShower.Utils;
using WeaponStatShower.Utils.Extensions;
using WeaponStatShower.Utils.Language;
using WeaponStatShower.Utils.Language.Models;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("WeaponStatShower")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+75aa869cf995234f6c582c07759bee1e5af89b9a")]
[assembly: AssemblyProduct("WeaponStatShower")]
[assembly: AssemblyTitle("WeaponStatShower")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace WeaponStatShower
{
public static class BIEExtensions
{
public static ConfigEntry<T> GetConfigEntry<T>(this ConfigFile configFile, ConfigDefinition definition)
{
ConfigEntry<T> result = default(ConfigEntry<T>);
if (!configFile.TryGetEntry<T>(definition, ref result))
{
throw new InvalidOperationException("Config entry has not been added yet.");
}
return result;
}
}
[BepInPlugin("WeaponStatShower", "Weapon Stat Shower", "2.0.1")]
[BepInProcess("GTFO.exe")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class WeaponStatShowerPlugin : BasePlugin
{
private enum ShowStatSetting
{
False,
True,
Force
}
public enum StatsPosition
{
Last,
First,
Combined
}
internal const string ModName = "Weapon Stat Shower";
internal const string GUID = "WeaponStatShower";
private const string SectionMain = "Config";
private static readonly ConfigDefinition ConfigDefinition = new ConfigDefinition("Config", "Version");
private static readonly ConfigDefinition ConfigGameVersion = new ConfigDefinition("Config", "GameVersion");
private static Harmony? HarmonyInstance;
private static readonly Dictionary<Type, Patch> RegisteredPatches = new Dictionary<Type, Patch>();
private static ConfigEntry<LanguageEnum> _configLanguage = null;
private static ConfigEntry<string> _sleepersShown = null;
private static ConfigEntry<ShowStatSetting> _showStats = null;
private static ConfigEntry<StatsPosition> _statsPosition = null;
public static WeaponStatShowerPlugin Instance { get; private set; }
internal static bool ShowStats
{
get
{
if (_showStats.Value != ShowStatSetting.Force)
{
if (_showStats.Value == ShowStatSetting.True)
{
return !DescriptionDataManager.Current.GlobalSettings.PreferHideStats;
}
return false;
}
return true;
}
}
internal static string SleepersShown => _sleepersShown.Value.Trim().ToUpper();
internal static LanguageEnum ConfigLanguage => _configLanguage.Value;
internal static StatsPosition StatsLocation => _statsPosition.Value;
public override void Load()
{
Instance = this;
((BasePlugin)this).Config.SaveOnConfigSet = true;
LogInfo("STARTED");
DescriptionDataManager.Current.Init();
RegisterPatch<DescriptionToggle>();
BuildConfig(((BasePlugin)this).Config);
}
public static void RegisterPatch<T>() where T : Patch, new()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
if (HarmonyInstance == null)
{
HarmonyInstance = new Harmony("WeaponStatShower");
}
if (RegisteredPatches.TryGetValue(typeof(T), out Patch _))
{
LogDebug("Ignoring duplicate patch: " + typeof(T).Name);
return;
}
T val = new T
{
Harmony = HarmonyInstance
};
val.Initialize();
if (val.Enabled)
{
LogInfo("Applying patch: " + val.Name);
val.Execute();
}
RegisteredPatches[typeof(T)] = val;
}
public static void LogDebug(object data)
{
((BasePlugin)Instance).Log.LogDebug(data);
}
public static void LogError(object data)
{
((BasePlugin)Instance).Log.LogError(data);
}
public static void LogFatal(object data)
{
((BasePlugin)Instance).Log.LogFatal(data);
}
public static void LogInfo(object data)
{
((BasePlugin)Instance).Log.LogInfo(data);
}
public static void LogMessage(object data)
{
((BasePlugin)Instance).Log.LogMessage(data);
}
public static void LogWarning(object data)
{
((BasePlugin)Instance).Log.LogWarning(data);
}
private static void BuildConfig(ConfigFile file)
{
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Expected O, but got Unknown
string text = "ShowStat";
_configLanguage = file.Bind<LanguageEnum>(text, "Language", LanguageEnum.English, "Select the mod language.");
_sleepersShown = file.Bind<string>(text, "SleepersShown", "NONE", "Select which Sleepers are shown, seperated by a comma.\nAcceptable values: ALL, NONE, STRIKER, SHOOTER, SCOUT, BIG_STRIKER, BIG_SHOOTER, CHARGER, CHARGER_SCOUT");
_showStats = file.Bind<ShowStatSetting>(text, "ShowStats", ShowStatSetting.True, "Add a description tab with auto-generated weapon stats.\nForce will always create a tab, even if the rundown developer disables it.");
_statsPosition = file.Bind<StatsPosition>(text, "StatsPosition", StatsPosition.Last, "Which tab to place the auto-generated weapon stats.\nCombined will combine it with the normal description, similar to older versions.");
string? directoryName = Path.GetDirectoryName(file.ConfigFilePath);
string fileName = Path.GetFileName(file.ConfigFilePath);
LiveEdit.CreateListener(directoryName, fileName, false).FileChanged += (LiveEditEventHandler)delegate
{
file.Reload();
};
}
}
}
namespace WeaponStatShower.Utils
{
internal static class ArchetypeUtil
{
internal static ArchetypeDataBlock? GetArchetypeDataBlock(GearIDRange idRange, uint categoryID, GearCategoryDataBlock gearCatBlock)
{
//IL_0007: 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)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
eWeaponFireMode val = (eWeaponFireMode)idRange.GetCompID((eGearComponent)1);
if (categoryID != 12)
{
return GameDataBlockBase<ArchetypeDataBlock>.GetBlock(GearBuilder.GetArchetypeID(gearCatBlock, val));
}
return SentryGunInstance_Firing_Bullets.GetArchetypeDataForFireMode(val);
}
internal static ArchetypeDataBlock? GetMappedArchetypeDataBlock(GearIDRange idRange, uint categoryID, GearCategoryDataBlock gearCatBlock)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected I4, but got Unknown
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
eWeaponFireMode val = (eWeaponFireMode)idRange.GetCompID((eGearComponent)1);
bool flag = categoryID == 12;
if (!flag)
{
val = (eWeaponFireMode)((val - 10) switch
{
0 => 0,
1 => 2,
2 => 1,
3 => 0,
_ => val,
});
}
if (!flag)
{
return GameDataBlockBase<ArchetypeDataBlock>.GetBlock(GearBuilder.GetArchetypeID(gearCatBlock, val));
}
return SentryGunInstance_Firing_Bullets.GetArchetypeDataForFireMode(val);
}
}
[JsonConverter(typeof(LocaleTextConverter))]
public struct LocaleText : IEquatable<LocaleText>
{
public uint ID;
public string RawText;
public static readonly LocaleText Empty = new LocaleText(string.Empty);
private readonly string TextFallback
{
get
{
if (ID != 0)
{
return Text.Get(ID);
}
return RawText;
}
}
public LocaleText(LocalizedText baseText)
{
ID = 0u;
RawText = string.Empty;
RawText = LocalizedToText(baseText);
ID = baseText.Id;
}
public LocaleText(string text)
{
ID = 0u;
RawText = string.Empty;
if (PartialData.TryGetGUID(text, out var guid))
{
RawText = string.Empty;
ID = guid;
}
else
{
RawText = text;
ID = 0u;
}
}
public LocaleText(uint id)
{
ID = 0u;
RawText = string.Empty;
RawText = string.Empty;
ID = id;
}
public readonly LocalizedText ToLocalizedText()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Expected O, but got Unknown
return new LocalizedText
{
Id = ID,
UntranslatedText = TextFallback
};
}
public override readonly string ToString()
{
return TextFallback;
}
public static string LocalizedToText(LocalizedText text)
{
if (!text.HasTranslation)
{
return text.UntranslatedText;
}
return Text.Get(text.Id);
}
public static explicit operator LocaleText(LocalizedText localizedText)
{
return new LocaleText(localizedText);
}
public static explicit operator LocaleText(string text)
{
return new LocaleText(text);
}
public static implicit operator LocalizedText(LocaleText localeText)
{
return localeText.ToLocalizedText();
}
public static implicit operator string(LocaleText localeText)
{
return localeText.ToString();
}
public readonly bool Equals(LocaleText other)
{
if (ID == other.ID)
{
return string.Equals(RawText, other.RawText, StringComparison.Ordinal);
}
return false;
}
public override readonly bool Equals(object? obj)
{
if (obj is LocaleText other)
{
return Equals(other);
}
return false;
}
public override readonly int GetHashCode()
{
return HashCode.Combine(ID, RawText);
}
public static bool operator ==(LocaleText left, LocaleText right)
{
return left.Equals(right);
}
public static bool operator !=(LocaleText left, LocaleText right)
{
return !(left == right);
}
}
internal class SleepersDatas
{
private readonly struct EnemyData
{
public readonly float Health;
public readonly float HeadMultiplier;
public readonly float BackMultiplier;
public readonly bool IsArmored;
public EnemyData(float health, float headMultiplier, float backMultiplier, bool isArmored)
{
Health = health;
HeadMultiplier = headMultiplier;
BackMultiplier = backMultiplier;
IsArmored = isArmored;
}
}
private readonly Dictionary<string, EnemyData> _enemyDatas = new Dictionary<string, EnemyData>();
private readonly SleepersLanguageModel sleepersLanguageDatas;
public SleepersDatas(string[] activatedSleepers, SleepersLanguageModel sleepersLanguageDatas)
{
this.sleepersLanguageDatas = sleepersLanguageDatas;
for (int i = 0; i < activatedSleepers.Length; i++)
{
string text = activatedSleepers[i].Trim();
switch (text)
{
case "DETAILS_ONLY":
case "DESCRIPTION_ONLY":
case "NONE":
_enemyDatas.Clear();
return;
case "ALL":
_enemyDatas.Clear();
_enemyDatas.TryAdd(sleepersLanguageDatas.striker, new EnemyData(20f, 3f, 2f, isArmored: false));
_enemyDatas.TryAdd(sleepersLanguageDatas.shooter, new EnemyData(30f, 5f, 2f, isArmored: false));
_enemyDatas.TryAdd(sleepersLanguageDatas.scout, new EnemyData(42f, 3f, 2f, isArmored: false));
_enemyDatas.TryAdd(sleepersLanguageDatas.bigStriker, new EnemyData(120f, 1.5f, 2f, isArmored: false));
_enemyDatas.TryAdd(sleepersLanguageDatas.bigShooter, new EnemyData(150f, 2f, 2f, isArmored: false));
_enemyDatas.TryAdd(sleepersLanguageDatas.charger, new EnemyData(30f, 1f, 2f, isArmored: true));
_enemyDatas.TryAdd(sleepersLanguageDatas.chargerScout, new EnemyData(60f, 1f, 2f, isArmored: true));
return;
case "STRIKER":
_enemyDatas.TryAdd(sleepersLanguageDatas.striker, new EnemyData(20f, 3f, 2f, isArmored: false));
break;
case "SHOOTER":
_enemyDatas.TryAdd(sleepersLanguageDatas.shooter, new EnemyData(30f, 5f, 2f, isArmored: false));
break;
case "SCOUT":
_enemyDatas.TryAdd(sleepersLanguageDatas.scout, new EnemyData(42f, 3f, 2f, isArmored: false));
break;
case "BIG_STRIKER":
_enemyDatas.TryAdd(sleepersLanguageDatas.bigStriker, new EnemyData(120f, 1.5f, 2f, isArmored: false));
break;
case "BIG_SHOOTER":
_enemyDatas.TryAdd(sleepersLanguageDatas.bigShooter, new EnemyData(150f, 2f, 2f, isArmored: false));
break;
case "CHARGER":
_enemyDatas.TryAdd(sleepersLanguageDatas.charger, new EnemyData(30f, 1f, 2f, isArmored: true));
break;
case "CHARGER_SCOUT":
_enemyDatas.TryAdd(sleepersLanguageDatas.chargerScout, new EnemyData(60f, 1f, 2f, isArmored: true));
break;
default:
WeaponStatShowerPlugin.LogWarning("You inserted an incorrect value in the config: " + text);
break;
}
}
}
public string VerboseKill(ArchetypeDataBlock archetypeDB)
{
float damage = archetypeDB.Damage * (float)((archetypeDB.ShotgunBulletCount <= 0) ? 1 : archetypeDB.ShotgunBulletCount);
float precisionDamageMulti = archetypeDB.PrecisionDamageMulti;
return BuildKillString(precisionDamageMulti, (string _, EnemyData __) => damage);
}
internal string? VerboseKill(MeleeArchetypeDataBlock meleeArchetypeDB)
{
float baseDamage = meleeArchetypeDB.ChargedAttackDamage * meleeArchetypeDB.ChargedSleeperMulti;
float chargedPrecisionMulti = meleeArchetypeDB.ChargedPrecisionMulti;
return BuildKillString(chargedPrecisionMulti, delegate(string enemyName, EnemyData _)
{
float num = baseDamage;
if (enemyName.Contains("SCOUT") || enemyName.Contains("哨兵") || enemyName.Contains("黑触"))
{
num /= meleeArchetypeDB.ChargedSleeperMulti;
}
return num;
});
}
private string BuildKillString(float prcnMult, Func<string, EnemyData, float> getDamage)
{
StringBuilder stringBuilder = new StringBuilder();
int num = 0;
int num2 = 0;
int num3 = _enemyDatas.Count - 1;
foreach (KeyValuePair<string, EnemyData> enemyData2 in _enemyDatas)
{
enemyData2.Deconstruct(out var key, out var value);
string text = key;
EnemyData enemyData = value;
float damage = getDamage(text, enemyData);
List<string> list = new List<string>(4);
if (canKillOnOccipit(damage, prcnMult, enemyData))
{
list.Add(sleepersLanguageDatas.occipit);
}
if (canKillOnHead(damage, prcnMult, enemyData))
{
list.Add(sleepersLanguageDatas.head);
}
if (canKillOnBack(damage, enemyData))
{
list.Add(sleepersLanguageDatas.back);
}
if (canKillOnChest(damage, enemyData))
{
list.Add(sleepersLanguageDatas.chest);
}
if (list.Count > 0)
{
if (num % 2 == 1)
{
stringBuilder.Append(" | ");
}
list.Reverse();
stringBuilder.Append(text + ": [" + string.Join(",", list) + "]");
if (num++ % 2 == 1 && num2 != num3)
{
stringBuilder.AppendLine();
}
}
num2++;
}
if (num > 1 && stringBuilder.Length > 0)
{
if (stringBuilder[stringBuilder.Length - 1] != '\n')
{
stringBuilder.AppendLine();
}
}
return stringBuilder.ToString();
}
private bool canKillOnChest(float damage, EnemyData data)
{
return damage >= data.Health;
}
private bool canKillOnBack(float damage, EnemyData data)
{
return damage * data.BackMultiplier >= data.Health;
}
private bool canKillOnHead(float damage, float prcnMultiplier, EnemyData data)
{
if (isArmored(data))
{
return damage * data.HeadMultiplier >= data.Health;
}
return damage * prcnMultiplier * data.HeadMultiplier >= data.Health;
}
private bool canKillOnOccipit(float damage, float prcnMultiplier, EnemyData data)
{
if (isArmored(data))
{
return damage * data.BackMultiplier * data.HeadMultiplier >= data.Health;
}
return damage * prcnMultiplier * data.BackMultiplier * data.HeadMultiplier >= data.Health;
}
private bool isArmored(EnemyData data)
{
return data.IsArmored;
}
}
internal class WeaponDescriptionBuilder
{
private PlayerDataBlock _playerDB;
private GearIDRange _idRange;
private uint _categoryID;
private GearCategoryDataBlock _gearCategoryDB;
private ItemDataBlock _itemDB;
private LanguageDatas _languageDatas;
private LanguageEnum _language;
private SleepersDatas _sleepersDatas;
private string _lastSleepersDatas;
private readonly StringBuilder _strBuilder = new StringBuilder();
private const string DIVIDER = " | ";
private const string CLOSE_COLOR_TAG = "</color>";
private const string SHOTGUN_PREFAB = "Assets/AssetPrefabs/Items/Weapons/GearSetup/ShotgunWeaponFirstPerson.prefab";
internal void Inizialize(GearIDRange idRange, PlayerDataBlock playerDB, LanguageEnum language)
{
_idRange = idRange;
_playerDB = playerDB;
_categoryID = idRange.GetCompID((eGearComponent)2);
_gearCategoryDB = GameDataBlockBase<GearCategoryDataBlock>.GetBlock(_categoryID);
_itemDB = GameDataBlockBase<ItemDataBlock>.GetBlock(_gearCategoryDB.BaseItem);
bool sleepersDatas = DeserializeLanguageJson(language);
SetSleepersDatas(sleepersDatas);
}
private bool DeserializeLanguageJson(LanguageEnum language)
{
if (_language == language && _languageDatas != null)
{
return false;
}
LanguageDatasClass languageDatasClass = JsonSerializer.Deserialize<LanguageDatasClass>(LocalizedString.JsonString);
_languageDatas = (language.Equals(LanguageEnum.English) ? languageDatasClass.english : languageDatasClass.chinese);
_language = language;
return true;
}
private void SetSleepersDatas(bool force)
{
if (!(_lastSleepersDatas == WeaponStatShowerPlugin.SleepersShown) || force)
{
_lastSleepersDatas = WeaponStatShowerPlugin.SleepersShown;
string[] array = _lastSleepersDatas.Split(',');
if (array[0].Trim().Length == 0)
{
WeaponStatShowerPlugin.LogWarning("Empty String in the config file, applying Default values");
array = new string[1] { "ALL" };
}
_sleepersDatas = new SleepersDatas(array, _languageDatas.sleepers);
}
}
public string DescriptionFormatter()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Invalid comparison between Unknown and I4
if ((int)_itemDB.inventorySlot == 10)
{
MeleeArchetypeDataBlock block = GameDataBlockBase<MeleeArchetypeDataBlock>.GetBlock(GearBuilder.GetMeleeArchetypeID(_gearCategoryDB));
return VerboseDescriptionFormatter(block) + GetFormatedWeaponStats(block, _itemDB);
}
var (val, flag) = GetRangedArchetype();
if (val == null)
{
return string.Empty;
}
return string.Concat(str1: GetFormatedWeaponStats(val, (!flag) ? (_itemDB.FirstPersonPrefabs != null && _itemDB.FirstPersonPrefabs.Contains("Assets/AssetPrefabs/Items/Weapons/GearSetup/ShotgunWeaponFirstPerson.prefab")) : (_idRange.GetCompID((eGearComponent)1) == 13), flag), str0: VerboseDescriptionFormatter(val, flag));
}
internal string FireRateFormatter(string gearPublicName)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Invalid comparison between Unknown and I4
if ((int)_itemDB.inventorySlot == 10)
{
MeleeArchetypeDataBlock block = GameDataBlockBase<MeleeArchetypeDataBlock>.GetBlock(GearBuilder.GetMeleeArchetypeID(_gearCategoryDB));
MeleeLanguageModel melee = _languageDatas.melee;
return ((GameDataBlockBase<MeleeArchetypeDataBlock>)(object)block).persistentID switch
{
1u => melee.hammer,
2u => melee.knife,
3u => melee.spear,
4u => melee.bat,
_ => gearPublicName,
};
}
ArchetypeDataBlock item = GetRangedArchetype().Item1;
if (item == null)
{
return gearPublicName;
}
return VerbosePublicNameFireMode(item);
}
private (ArchetypeDataBlock?, bool) GetRangedArchetype()
{
bool item = _categoryID == 12;
return (ArchetypeUtil.GetMappedArchetypeDataBlock(_idRange, _categoryID, _gearCategoryDB), item);
}
private string VerbosePublicNameFireMode(ArchetypeDataBlock archetypeDB)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: 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_005d: Expected I4, but got Unknown
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_035b: Unknown result type (might be due to invalid IL or missing references)
//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
FiremodeLanguageModel firemode = _languageDatas.firemode;
eWeaponFireMode fireMode = archetypeDB.FireMode;
_strBuilder.Clear();
switch ((int)fireMode)
{
case 2:
case 11:
{
StringBuilder strBuilder = _strBuilder;
StringBuilder stringBuilder6 = strBuilder;
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(13, 4, strBuilder);
handler.AppendFormatted(firemode.fullA);
handler.AppendLiteral(" (<#12FF50>");
handler.AppendFormatted(_languageDatas.rateOfFire);
handler.AppendLiteral(" ");
handler.AppendFormatted(GetRateOfFire(archetypeDB, fireMode));
handler.AppendFormatted("</color>");
handler.AppendLiteral(")");
stringBuilder6.Append(ref handler);
break;
}
case 0:
case 10:
{
StringBuilder strBuilder = _strBuilder;
StringBuilder stringBuilder5 = strBuilder;
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(13, 4, strBuilder);
handler.AppendFormatted(firemode.semiA);
handler.AppendLiteral(" (<#12FF50>");
handler.AppendFormatted(_languageDatas.rateOfFire);
handler.AppendLiteral(" ");
handler.AppendFormatted(GetRateOfFire(archetypeDB, fireMode));
handler.AppendFormatted("</color>");
handler.AppendLiteral(")");
stringBuilder5.Append(ref handler);
break;
}
case 1:
case 12:
if (archetypeDB.BurstShotCount != 1)
{
StringBuilder strBuilder = _strBuilder;
StringBuilder stringBuilder3 = strBuilder;
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(23, 7, strBuilder);
handler.AppendFormatted(firemode.burst);
handler.AppendLiteral(" (<#704dfa>#");
handler.AppendFormatted(archetypeDB.BurstShotCount);
handler.AppendFormatted("</color>");
handler.AppendFormatted(" | ");
handler.AppendLiteral("<#12FF50>");
handler.AppendFormatted(_languageDatas.rateOfFire);
handler.AppendLiteral(" ");
handler.AppendFormatted(GetRateOfFire(archetypeDB, fireMode));
handler.AppendFormatted("</color>");
handler.AppendLiteral(")");
stringBuilder3.Append(ref handler);
}
else
{
StringBuilder strBuilder = _strBuilder;
StringBuilder stringBuilder4 = strBuilder;
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(13, 4, strBuilder);
handler.AppendFormatted(firemode.burst);
handler.AppendLiteral(" (<#12FF50>");
handler.AppendFormatted(_languageDatas.rateOfFire);
handler.AppendLiteral(" ");
handler.AppendFormatted(GetRateOfFire(archetypeDB, (eWeaponFireMode)0));
handler.AppendFormatted("</color>");
handler.AppendLiteral(")");
stringBuilder4.Append(ref handler);
}
break;
case 3:
{
StringBuilder strBuilder = _strBuilder;
StringBuilder stringBuilder2 = strBuilder;
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(28, 3, strBuilder);
handler.AppendLiteral("S-Burst (<#12FF50>#");
handler.AppendFormatted(archetypeDB.BurstShotCount);
handler.AppendLiteral(" every ");
handler.AppendFormatted(archetypeDB.SpecialSemiBurstCountTimeout);
handler.AppendLiteral("'");
handler.AppendFormatted("</color>");
handler.AppendLiteral(")");
stringBuilder2.Append(ref handler);
break;
}
case 13:
{
StringBuilder strBuilder = _strBuilder;
StringBuilder stringBuilder = strBuilder;
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(13, 4, strBuilder);
handler.AppendFormatted(firemode.shotgunSentry);
handler.AppendLiteral(" (<#12FF50>");
handler.AppendFormatted(_languageDatas.rateOfFire);
handler.AppendLiteral(" ");
handler.AppendFormatted(GetRateOfFire(archetypeDB, fireMode));
handler.AppendFormatted("</color>");
handler.AppendLiteral(")");
stringBuilder.Append(ref handler);
break;
}
default:
WeaponStatShowerPlugin.LogError("FireMode not found");
break;
}
return _strBuilder.ToString();
}
private string VerboseDescriptionFormatter(ArchetypeDataBlock archetypeDB, bool isSentry)
{
_strBuilder.Clear();
float specialChargetupTime = archetypeDB.SpecialChargetupTime;
if (specialChargetupTime > 0f)
{
string value = (((double)specialChargetupTime > 0.4) ? _languageDatas.longChargeUp : _languageDatas.shortChargeUp);
StringBuilder strBuilder = _strBuilder;
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 2, strBuilder);
handler.AppendFormatted(value);
handler.AppendLiteral(" (");
handler.AppendFormatted(FormatFloat(specialChargetupTime, 2));
handler.AppendLiteral(")");
strBuilder.AppendLine(ref handler);
}
if (_strBuilder.Length != 0)
{
return _strBuilder.ToString() + "\n";
}
return string.Empty;
}
private string VerboseDescriptionFormatter(MeleeArchetypeDataBlock meleeArchetypeDB)
{
_strBuilder.Clear();
if ((double)meleeArchetypeDB.CameraDamageRayLength < 1.76)
{
_strBuilder.AppendLine(_languageDatas.melee.shortRange);
}
else if ((double)meleeArchetypeDB.CameraDamageRayLength < 2.5)
{
_strBuilder.AppendLine(_languageDatas.melee.mediumRange);
}
else
{
_strBuilder.AppendLine(_languageDatas.melee.longRange);
}
_strBuilder.Append(meleeArchetypeDB.CanHitMultipleEnemies ? (_languageDatas.melee.canPierce + "\n") : string.Empty);
if (_strBuilder.Length != 0)
{
return _strBuilder.ToString();
}
return string.Empty;
}
private string GetFormatedWeaponStats(ArchetypeDataBlock archetypeDB, bool isShotgun, bool isSentry = false)
{
//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
if (archetypeDB == null)
{
return string.Empty;
}
int count = 0;
int dividerThreshold = ((_language != LanguageEnum.English) ? 3 : 4);
_strBuilder.Clear();
string value = FormatFloat(archetypeDB.Damage, 2) + (isShotgun ? $"(x{archetypeDB.ShotgunBulletCount})" : "");
AppendStat(ref count, "<#9D2929>", _languageDatas.damage, value);
AppendStatIf(ref count, Divider, !isSentry, "<color=orange>", _languageDatas.clip, archetypeDB.DefaultClipSize.ToString());
Divider();
AppendStat(ref count, "<#FFD306>", _languageDatas.maxAmmo, GetTotalAmmo(archetypeDB, _itemDB, isSentry).ToString());
AppendStatIf(ref count, Divider, !isSentry, "<#C0FF00>", _languageDatas.reload, FormatFloat(archetypeDB.DefaultReloadTime, 2).ToString());
AppendStatIf(ref count, Divider, archetypeDB.PrecisionDamageMulti != 1f, "<#18A4A9>", _languageDatas.precision, FormatFloat(archetypeDB.PrecisionDamageMulti, 2).ToString());
Divider();
AppendStat(ref count, "<#6764de>", _languageDatas.falloff, (int)archetypeDB.DamageFalloff.x + "m");
AppendStatIf(ref count, Divider, archetypeDB.StaggerDamageMulti != 1f, "<color=green>", _languageDatas.stagger, FormatFloat(archetypeDB.StaggerDamageMulti, 2).ToString());
AppendStatIf(ref count, Divider, archetypeDB.HipFireSpread != 0f && !isShotgun, "<#cc9347>", _languageDatas.hipSpread, FormatFloat(archetypeDB.HipFireSpread, 2).ToString());
AppendStatIf(ref count, Divider, archetypeDB.AimSpread != 0f && !isShotgun, "<#e6583c>", _languageDatas.aimDSpread, FormatFloat(archetypeDB.AimSpread, 2).ToString());
AppendStatIf(ref count, Divider, (float)(archetypeDB.ShotgunBulletSpread + archetypeDB.ShotgunConeSize) != 0f && isShotgun, "<#e6583c>", _languageDatas.spread, FormatFloat(archetypeDB.ShotgunBulletSpread + archetypeDB.ShotgunConeSize, 2).ToString());
AppendStatIf(ref count, Divider, archetypeDB.PiercingBullets, "<#097345>", _languageDatas.pierceCount, archetypeDB.PiercingDamageCountLimit.ToString());
_strBuilder.AppendLine();
_strBuilder.Append(_sleepersDatas.VerboseKill(archetypeDB));
return _strBuilder.ToString();
void Divider()
{
if (count >= dividerThreshold)
{
_strBuilder.AppendLine();
count = 0;
}
else if (count > 0)
{
_strBuilder.Append(" | ");
}
}
}
private string GetFormatedWeaponStats(MeleeArchetypeDataBlock meleeArchetypeDB, ItemDataBlock itemDB)
{
if (meleeArchetypeDB == null)
{
return string.Empty;
}
int count = 0;
MeleeLanguageModel melee = _languageDatas.melee;
_strBuilder.Clear();
_strBuilder.AppendLine();
AppendStat(ref count, "<#9D2929>", _languageDatas.damage + "." + melee.light, meleeArchetypeDB.LightAttackDamage.ToString());
Divider();
AppendStat(ref count, "<color=orange>", _languageDatas.damage + "." + melee.heavy, meleeArchetypeDB.ChargedAttackDamage.ToString());
AppendStatIf(ref count, Divider, !meleeArchetypeDB.AllowRunningWhenCharging, "<#FFD306>", melee.canRunWhileCharging);
AppendStatIf(ref count, Divider, meleeArchetypeDB.LightStaggerMulti != 1f, "<#C0FF00>", _languageDatas.stagger + "." + melee.light, meleeArchetypeDB.LightStaggerMulti.ToString());
AppendStatIf(ref count, Divider, meleeArchetypeDB.ChargedStaggerMulti != 1f, "<color=green>", _languageDatas.stagger + "." + melee.heavy, meleeArchetypeDB.ChargedStaggerMulti.ToString());
AppendStatIf(ref count, Divider, meleeArchetypeDB.LightPrecisionMulti != 1f, "<#004E2C>", _languageDatas.precision + "." + melee.light, meleeArchetypeDB.LightPrecisionMulti.ToString());
AppendStatIf(ref count, Divider, meleeArchetypeDB.ChargedPrecisionMulti != 1f, "<#55022B>", _languageDatas.precision + "." + melee.heavy, meleeArchetypeDB.ChargedPrecisionMulti.ToString());
AppendStatIf(ref count, Divider, meleeArchetypeDB.LightSleeperMulti != 1f, "<#A918A7>", melee.sleepingEnemiesMultiplier + "." + melee.light, meleeArchetypeDB.LightSleeperMulti.ToString());
AppendStatIf(ref count, Divider, meleeArchetypeDB.ChargedSleeperMulti != 1f, "<#025531>", melee.sleepingEnemiesMultiplier + "." + melee.heavy, meleeArchetypeDB.ChargedSleeperMulti.ToString());
AppendStatIf(ref count, Divider, meleeArchetypeDB.LightBackstabberMulti != 1f, "<#18A4A9>", melee.backstabMultiplier + "." + melee.light, meleeArchetypeDB.LightBackstabberMulti.ToString());
AppendStatIf(ref count, Divider, meleeArchetypeDB.ChargedBackstabberMulti != 1f, "<#75A2AA>", melee.backstabMultiplier + "." + melee.heavy, meleeArchetypeDB.ChargedBackstabberMulti.ToString());
AppendStatIf(ref count, Divider, meleeArchetypeDB.LightEnvironmentMulti != 1f, "<#18A4A9>", melee.environmentMultiplier + "." + melee.light, meleeArchetypeDB.LightEnvironmentMulti.ToString());
AppendStatIf(ref count, Divider, meleeArchetypeDB.ChargedEnvironmentMulti != 1f, "<#75A2AA>", melee.environmentMultiplier + "." + melee.heavy, meleeArchetypeDB.ChargedEnvironmentMulti.ToString());
_strBuilder.AppendLine();
_strBuilder.Append(_sleepersDatas.VerboseKill(meleeArchetypeDB) ?? string.Empty);
return _strBuilder.ToString();
void Divider()
{
if (count >= 3)
{
_strBuilder.AppendLine();
count = 0;
}
else if (count > 0)
{
_strBuilder.Append(" | ");
}
}
}
private void AppendStatIf(ref int count, Action divider, bool condition, string color, string label, string value = "")
{
if (condition)
{
divider();
AppendStat(ref count, color, label, value);
}
}
private void AppendStat(ref int count, string color, string label, string value = "")
{
_strBuilder.Append(color);
_strBuilder.Append(label);
if (!string.IsNullOrEmpty(value))
{
_strBuilder.Append(' ');
_strBuilder.Append(value);
}
_strBuilder.Append("</color>");
count++;
}
private static float FormatFloat(float value, int v)
{
return (float)Math.Round((decimal)value, v);
}
private int GetAmmoMax(ItemDataBlock itemDataBlock)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: 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_002a: Expected I4, but got Unknown
AmmoType ammoTypeFromSlot = PlayerAmmoStorage.GetAmmoTypeFromSlot(itemDataBlock.inventorySlot);
return (int)ammoTypeFromSlot switch
{
0 => _playerDB.AmmoStandardMaxCap,
1 => _playerDB.AmmoSpecialMaxCap,
2 => _playerDB.AmmoClassMaxCap,
5 => itemDataBlock.ConsumableAmmoMax,
_ => -1,
};
}
private int GetTotalAmmo(ArchetypeDataBlock archetypeDB, ItemDataBlock itemDB, bool isSentry = false)
{
int ammoMax = GetAmmoMax(itemDB);
float num = archetypeDB.CostOfBullet;
if (isSentry)
{
num *= itemDB.ClassAmmoCostFactor;
if ((float)archetypeDB.ShotgunBulletCount > 0f)
{
num *= (float)archetypeDB.ShotgunBulletCount;
}
}
int num2 = (int)((float)ammoMax / num);
if (!isSentry)
{
return num2 + archetypeDB.DefaultClipSize;
}
return num2;
}
private string GetRateOfFire(ArchetypeDataBlock archetypeDB, eWeaponFireMode fireMode)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected I4, but got Unknown
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Expected I4, but got Unknown
float value = -1f;
switch ((int)fireMode)
{
default:
switch (fireMode - 11)
{
case 0:
break;
case 2:
goto IL_003e;
case 1:
goto IL_0054;
default:
goto end_IL_0007;
}
goto case 2;
case 2:
value = 1f / archetypeDB.ShotDelay;
break;
case 0:
goto IL_003e;
case 1:
goto IL_0054;
IL_0054:
value = 1f / (archetypeDB.BurstDelay + archetypeDB.SpecialChargetupTime + archetypeDB.ShotDelay * (float)(archetypeDB.BurstShotCount - 1)) * (float)archetypeDB.BurstShotCount;
break;
IL_003e:
value = 1f / (archetypeDB.ShotDelay + archetypeDB.SpecialChargetupTime);
break;
end_IL_0007:
break;
}
return FormatFloat(value, 1).ToString();
}
}
}
namespace WeaponStatShower.Utils.Language
{
public class LanguageDatas
{
public FiremodeLanguageModel firemode { get; set; } = new FiremodeLanguageModel();
public MeleeLanguageModel melee { get; set; } = new MeleeLanguageModel();
public SleepersLanguageModel sleepers { get; set; } = new SleepersLanguageModel();
public string damage { get; set; } = string.Empty;
public string clip { get; set; } = string.Empty;
public string maxAmmo { get; set; } = string.Empty;
public string falloff { get; set; } = string.Empty;
public string reload { get; set; } = string.Empty;
public string stagger { get; set; } = string.Empty;
public string precision { get; set; } = string.Empty;
public string pierceCount { get; set; } = string.Empty;
public string rateOfFire { get; set; } = string.Empty;
public string aimDSpread { get; set; } = string.Empty;
public string hipSpread { get; set; } = string.Empty;
public string spread { get; set; } = string.Empty;
public string deployable { get; set; } = string.Empty;
public string longChargeUp { get; set; } = string.Empty;
public string shortChargeUp { get; set; } = string.Empty;
}
internal class LanguageDatasClass
{
public LanguageDatas english { get; set; } = new LanguageDatas();
public LanguageDatas chinese { get; set; } = new LanguageDatas();
}
internal enum LanguageEnum
{
English,
Chinese
}
internal class LocalizedString
{
public static readonly string JsonString = "{\r\n\t\t\t\"english\": {\r\n\t\t\t\t\"firemode\": {\r\n\t\t\t\t\t\"fullA\": \"Full-A\",\r\n\t\t\t\t\t\"semiA\": \"Semi-A\",\r\n\t\t\t\t\t\"burst\": \"Burst\",\r\n\t\t\t\t\t\"shotgunSentry\": \"Shotgun-S\"\r\n\t\t\t\t},\r\n\t\t\t\t\"melee\": {\r\n\t\t\t\t\t\"light\": \"Lgt\",\r\n\t\t\t\t\t\"heavy\": \"Hvy\",\r\n\t\t\t\t\t\"canRunWhileCharging\": \"Can't run\",\r\n\t\t\t\t\t\"sleepingEnemiesMultiplier\": \"Slp\",\r\n\t\t\t\t\t\"backstabMultiplier\": \"Bak\",\r\n\t\t\t\t\t\"environmentMultiplier\": \"Env\",\r\n\t\t\t\t\t\"canPierce\": \"Piercing\",\r\n\t\t\t\t\t\"shortRange\": \"Short Range\",\r\n\t\t\t\t\t\"mediumRange\": \"Medium Range\",\r\n\t\t\t\t\t\"longRange\": \"Long Range\",\r\n\t\t\t\t\t\"hammer\": \"Hammer - Balanced\",\r\n\t\t\t\t\t\"knife\": \"Knife - Fast\",\r\n\t\t\t\t\t\"bat\": \"Bat - Fast\",\r\n\t\t\t\t\t\"spear\": \"Spear - Slow\"\r\n\t\t\t\t},\r\n\t\t\t\t\"sleepers\": {\r\n\t\t\t\t\t\"striker\": \"STRK\",\r\n\t\t\t\t\t\"shooter\": \"SHTR\",\r\n\t\t\t\t\t\"scout\": \"SCOUT\",\r\n\t\t\t\t\t\"bigStriker\": \"B-STRK\",\r\n\t\t\t\t\t\"bigShooter\": \"B-SHTR\",\r\n\t\t\t\t\t\"charger\": \"CHRG\",\r\n\t\t\t\t\t\"chargerScout\": \"C-SCOUT\",\r\n\t\t\t\t\t\"occipit\": \"o\",\r\n\t\t\t\t\t\"head\": \"h\",\r\n\t\t\t\t\t\"back\": \"b\",\r\n\t\t\t\t\t\"chest\": \"c\"\r\n\t\t\t\t},\r\n\t\t\t\t\"damage\": \"Dmg\",\r\n\t\t\t\t\"clip\": \"Clp\",\r\n\t\t\t\t\"maxAmmo\": \"Max\",\r\n\t\t\t\t\"falloff\": \"Dist\",\r\n\t\t\t\t\"reload\": \"Rld\",\r\n\t\t\t\t\"stagger\": \"Stgr\",\r\n\t\t\t\t\"precision\": \"Prcn\",\r\n\t\t\t\t\"pierceCount\": \"Pierc\",\r\n\t\t\t\t\"rateOfFire\": \"RoF\",\r\n\t\t\t\t\"aimDSpread\": \"ADS\",\r\n\t\t\t\t\"hipSpread\": \"HIP\",\r\n\t\t\t\t\"spread\": \"SPRD\",\r\n\t\t\t\t\"deployable\": \"Deployable\",\r\n\t\t\t\t\"longChargeUp\": \"Long Charge-up\",\r\n\t\t\t\t\"shortChargeUp\": \"short Charge-up\"\r\n\t\t\t},\r\n\r\n\t\t\t\"chinese\": {\r\n\t\t\t\t\"firemode\": {\r\n\t\t\t\t\t\"fullA\": \"全自动\",\r\n\t\t\t\t\t\"semiA\": \"半自动\",\r\n\t\t\t\t\t\"burst\": \"连发\",\r\n\t\t\t\t\t\"shotgunSentry\": \"半自动霰弹射击\"\r\n\t\t\t\t},\r\n\t\t\t\t\"melee\": {\r\n\t\t\t\t\t\"light\": \"轻击\",\r\n\t\t\t\t\t\"heavy\": \"重击\",\r\n\t\t\t\t\t\"canRunWhileCharging\": \"不能冲刺\",\r\n\t\t\t\t\t\"sleepingEnemiesMultiplier\": \"沉睡倍率\",\r\n\t\t\t\t\t\"backstabMultiplier\": \"背后捅刀\",\r\n\t\t\t\t\t\"environmentMultiplier\": \"环境倍率\",\r\n\t\t\t\t\t\"canPierce\": \"穿刺\",\r\n\t\t\t\t\t\"shortRange\": \"短距离\",\r\n\t\t\t\t\t\"mediumRange\": \"中距离\",\r\n\t\t\t\t\t\"longRange\": \"长距离\",\r\n\t\t\t\t\t\"hammer\": \"大锤 - 均衡\",\r\n\t\t\t\t\t\"knife\": \"刀 - 快速\",\r\n\t\t\t\t\t\"bat\": \"棍棒 - 快速\",\r\n\t\t\t\t\t\"spear\": \"矛 - 慢速\"\r\n\t\t\t\t},\r\n\t\t\t\t\"sleepers\": {\r\n\t\t\t\t\t\"striker\": \"前锋\",\r\n\t\t\t\t\t\"shooter\": \"射手\",\r\n\t\t\t\t\t\"scout\": \"哨兵\",\r\n\t\t\t\t\t\"bigStriker\": \"大壮\",\r\n\t\t\t\t\t\"bigShooter\": \"大姐\",\r\n\t\t\t\t\t\"charger\": \"黑刺\",\r\n\t\t\t\t\t\"chargerScout\": \"黑触\",\r\n\t\t\t\t\t\"occipit\": \"后脑\",\r\n\t\t\t\t\t\"head\": \"头\",\r\n\t\t\t\t\t\"back\": \"背\",\r\n\t\t\t\t\t\"chest\": \"胸\"\r\n\t\t\t\t},\r\n\r\n\t\t\t\t\"damage\": \"伤害\",\r\n\t\t\t\t\"clip\": \"弹容量\",\r\n\t\t\t\t\"maxAmmo\": \"总弹量\",\r\n\t\t\t\t\"falloff\": \"衰减距离\",\r\n\t\t\t\t\"reload\": \"换弹时间\",\r\n\t\t\t\t\"stagger\": \"硬直倍率\",\r\n\t\t\t\t\"precision\": \"精准倍率\",\r\n\t\t\t\t\"pierceCount\": \"穿透\",\r\n\t\t\t\t\"rateOfFire\": \"射速\",\r\n\t\t\t\t\"aimDSpread\": \"倍镜\",\r\n\t\t\t\t\"hipSpread\": \"后坐力\",\r\n\t\t\t\t\"spread\": \"点差\",\r\n\t\t\t\t\"deployable\": \"可部署\",\r\n\t\t\t\t\"longChargeUp\": \"长蓄力\",\r\n\t\t\t\t\"shortChargeUp\": \"短蓄力\"\r\n\t\t\t}\r\n\t\t}";
}
}
namespace WeaponStatShower.Utils.Language.Models
{
public class FiremodeLanguageModel
{
public string fullA { get; set; } = string.Empty;
public string semiA { get; set; } = string.Empty;
public string burst { get; set; } = string.Empty;
public string shotgunSentry { get; set; } = string.Empty;
}
public class MeleeLanguageModel
{
public string light { get; set; } = string.Empty;
public string heavy { get; set; } = string.Empty;
public string canRunWhileCharging { get; set; } = string.Empty;
public string sleepingEnemiesMultiplier { get; set; } = string.Empty;
public string backstabMultiplier { get; set; } = string.Empty;
public string environmentMultiplier { get; set; } = string.Empty;
public string canPierce { get; set; } = string.Empty;
public string shortRange { get; set; } = string.Empty;
public string mediumRange { get; set; } = string.Empty;
public string longRange { get; set; } = string.Empty;
public string hammer { get; set; } = string.Empty;
public string knife { get; set; } = string.Empty;
public string bat { get; set; } = string.Empty;
public string spear { get; set; } = string.Empty;
}
public class SleepersLanguageModel
{
public string striker { get; set; } = string.Empty;
public string shooter { get; set; } = string.Empty;
public string scout { get; set; } = string.Empty;
public string bigStriker { get; set; } = string.Empty;
public string bigShooter { get; set; } = string.Empty;
public string charger { get; set; } = string.Empty;
public string chargerScout { get; set; } = string.Empty;
public string occipit { get; set; } = string.Empty;
public string head { get; set; } = string.Empty;
public string back { get; set; } = string.Empty;
public string chest { get; set; } = string.Empty;
}
}
namespace WeaponStatShower.Utils.Extensions
{
public static class CollectionExtensions
{
public static void ExpandToSize<T>(this List<T> list, int count, T defaultValue)
{
list.EnsureCapacity(count);
while (list.Count < count)
{
list.Add(defaultValue);
}
}
}
}
namespace WeaponStatShower.Patches
{
internal class DescriptionToggle : Patch
{
private const string PatchName = "DescriptionToggle";
private static DescriptionButtonHandler _button;
public override string Name => "DescriptionToggle";
public static Patch Instance { get; private set; }
public override void Initialize()
{
Instance = this;
}
public override void Execute()
{
PatchMethod<CM_PlayerLobbyBar>("ShowWeaponSelectionPopup", PatchType.Postfix);
PatchMethod<CM_PlayerLobbyBar>("OnWeaponSlotItemSelected", PatchType.Postfix);
}
public static void CM_PlayerLobbyBar__ShowWeaponSelectionPopup__Postfix(CM_PlayerLobbyBar __instance)
{
_button = new DescriptionButtonHandler(__instance);
if ((Object)(object)__instance.selectedWeaponSlotItem != (Object)null)
{
CM_PlayerLobbyBar__OnWeaponSlotItemSelected__Postfix(__instance.selectedWeaponSlotItem);
}
}
public static void CM_PlayerLobbyBar__OnWeaponSlotItemSelected__Postfix(CM_InventorySlotItem slotItem)
{
if (_button != null)
{
_button.SetData(slotItem.m_gearID);
}
}
}
public abstract class Patch
{
protected internal Harmony? Harmony { get; set; }
public virtual string Name { get; }
public virtual bool Enabled => true;
public virtual void Initialize()
{
}
public abstract void Execute();
public void PatchConstructor<TClass>(PatchType patchType, string? prefixMethodName = null, string? postfixMethodName = null) where TClass : class
{
PatchConstructor<TClass>(null, patchType, prefixMethodName, postfixMethodName);
}
public void PatchConstructor<TClass>(Type[]? parameters, PatchType patchType, string? prefixMethodName = null, string? postfixMethodName = null) where TClass : class
{
ConstructorInfo methodBase = AccessTools.Constructor(typeof(TClass), parameters, false);
PatchMethod<TClass>(methodBase, patchType, prefixMethodName, postfixMethodName);
}
public void PatchMethod<TClass>(string methodName, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null) where TClass : class
{
PatchMethod<TClass>(methodName, null, patchType, generics, prefixMethodName, postfixMethodName);
}
public void PatchMethod<TClass>(string methodName, Type[] parameters, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null) where TClass : class
{
MethodInfo methodBase = AccessTools.Method(typeof(TClass), methodName, parameters, generics);
PatchMethod<TClass>(methodBase, patchType, prefixMethodName, postfixMethodName);
}
public void PatchMethod<TClass>(MethodBase methodBase, PatchType patchType, string prefixMethodName = null, string postfixMethodName = null) where TClass : class
{
PatchMethod(typeof(TClass), methodBase, patchType, prefixMethodName, postfixMethodName);
}
public void PatchMethod(Type classType, string methodName, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null)
{
PatchMethod(classType, methodName, null, patchType, generics, prefixMethodName, postfixMethodName);
}
public void PatchMethod(Type classType, string methodName, Type[] parameters, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null)
{
MethodInfo methodBase = AccessTools.Method(classType, methodName, parameters, generics);
PatchMethod(classType, methodBase, patchType, prefixMethodName, postfixMethodName);
}
public void PatchMethod(Type classType, MethodBase methodBase, PatchType patchType, string? prefixMethodName = null, string? postfixMethodName = null)
{
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Expected O, but got Unknown
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Expected O, but got Unknown
//IL_0147: Expected O, but got Unknown
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
//IL_0190: Expected O, but got Unknown
string text = classType.Name.Replace("`", "__");
string value = methodBase.ToString();
string text2 = (methodBase.IsConstructor ? "ctor" : methodBase.Name);
MethodInfo methodInfo = null;
MethodInfo methodInfo2 = null;
if ((patchType & PatchType.Prefix) != 0)
{
try
{
methodInfo2 = AccessTools.Method(GetType(), prefixMethodName ?? (text + "__" + text2 + "__Prefix"), (Type[])null, (Type[])null);
}
catch (Exception value2)
{
WeaponStatShowerPlugin.LogFatal($"Failed to obtain the prefix patch method for {value}): {value2}");
}
}
if ((patchType & PatchType.Postfix) != 0)
{
try
{
methodInfo = AccessTools.Method(GetType(), postfixMethodName ?? (text + "__" + text2 + "__Postfix"), (Type[])null, (Type[])null);
}
catch (Exception value3)
{
WeaponStatShowerPlugin.LogFatal($"Failed to obtain the postfix patch method for {value}): {value3}");
}
}
try
{
if (methodInfo2 != null && methodInfo != null)
{
Harmony.Patch(methodBase, new HarmonyMethod(methodInfo2), new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
else if (methodInfo2 != null)
{
Harmony.Patch(methodBase, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
else if (methodInfo != null)
{
Harmony.Patch(methodBase, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
}
catch (Exception value4)
{
WeaponStatShowerPlugin.LogError($"Failed to patch method {value}: {value4}");
}
}
}
[Flags]
public enum PatchType : byte
{
Prefix = 1,
Postfix = 2,
Both = 3
}
}
namespace WeaponStatShower.Json
{
public static class JSON
{
private static readonly JsonSerializerOptions _setting;
static JSON()
{
_setting = new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip,
IncludeFields = true,
PropertyNameCaseInsensitive = true,
WriteIndented = true,
IgnoreReadOnlyProperties = true
};
_setting.Converters.Add(new JsonStringEnumConverter());
if (PartialData.HasPData)
{
_setting.Converters.Add(PartialData.PDataIDConverter);
}
}
public static T? Deserialize<T>(string json)
{
return JsonSerializer.Deserialize<T>(json, _setting);
}
public static T? Deserialize<T>(ref Utf8JsonReader reader)
{
return JsonSerializer.Deserialize<T>(ref reader, _setting);
}
public static bool TryDeserializeSafe<T>(string json, [MaybeNullWhen(false)] out T value)
{
try
{
value = JsonSerializer.Deserialize<T>(json, _setting);
return value != null;
}
catch (JsonException ex)
{
WeaponStatShowerPlugin.LogError("Caught exception while reading json: " + ex.Message + "\n" + ex.StackTrace);
value = default(T);
return false;
}
}
public static bool TryDeserialize<T>(string json, [MaybeNullWhen(false)] out T value)
{
value = JsonSerializer.Deserialize<T>(json, _setting);
return value != null;
}
public static bool TryDeserialize<T>(ref Utf8JsonReader reader, [MaybeNullWhen(false)] out T value)
{
value = JsonSerializer.Deserialize<T>(ref reader, _setting);
return value != null;
}
public static object? Deserialize(Type type, string json)
{
return JsonSerializer.Deserialize(json, type, _setting);
}
public static string Serialize<T>(T value)
{
return JsonSerializer.Serialize(value, _setting);
}
public static void Serialize<T>(Utf8JsonWriter writer, T value)
{
JsonSerializer.Serialize(writer, value, _setting);
}
public static void Serialize<T>(Utf8JsonWriter writer, string name, T value)
{
writer.WritePropertyName(name);
JsonSerializer.Serialize(writer, value, _setting);
}
}
}
namespace WeaponStatShower.Json.Converters.Utils
{
public class LocaleTextConverter : JsonConverter<LocaleText>
{
public override bool HandleNull => true;
public override LocaleText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.TokenType switch
{
JsonTokenType.String => new LocaleText(reader.GetString()),
JsonTokenType.Number => new LocaleText(reader.GetUInt32()),
JsonTokenType.Null => LocaleText.Empty,
_ => throw new JsonException($"LocaleTextJson type: {reader.TokenType} is not implemented!"),
};
}
public override void Write(Utf8JsonWriter writer, LocaleText value, JsonSerializerOptions options)
{
if (value.ID != 0)
{
writer.WriteNumberValue(value.ID);
}
else
{
writer.WriteStringValue(value.RawText);
}
}
}
}
namespace WeaponStatShower.ExtraDescription
{
public class DescriptionButtonHandler
{
private static readonly Vector2 Size = new Vector2(600f, 320f);
private static readonly WeaponDescriptionBuilder DescriptionBuilder = new WeaponDescriptionBuilder();
private readonly GameObject _gameObject;
private readonly CM_Item _item;
private readonly TextMeshPro _text;
private readonly RectTransform _rectTrans;
private readonly CM_ScrollWindowInfoBox _infoBox;
private readonly CM_PageLoadout _pageLoadout;
private LocaleText[] _headers;
private LocaleText[] _descriptions;
private int _index;
private GearIDRange? _lastRange;
public event Action<LocaleText>? OnDescriptionChanged;
public DescriptionButtonHandler(CM_PlayerLobbyBar lobbyBar)
{
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Expected O, but got Unknown
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
//IL_021f: Unknown result type (might be due to invalid IL or missing references)
//IL_0234: Unknown result type (might be due to invalid IL or missing references)
//IL_024a: Unknown result type (might be due to invalid IL or missing references)
//IL_025c: Unknown result type (might be due to invalid IL or missing references)
_pageLoadout = ((Il2CppObjectBase)lobbyBar.m_parentPage).Cast<CM_PageLoadout>();
_infoBox = lobbyBar.m_popupScrollWindow.InfoBox;
_gameObject = Object.Instantiate<GameObject>(((Component)CM_PageLoadout.Current.m_copyLobbyIdButton).gameObject, ((Component)_infoBox).transform);
_item = _gameObject.GetComponent<CM_Item>();
_item.m_clickBlink = false;
Transform child = ((Component)_item).transform.GetChild(0);
_rectTrans = ((Component)child).GetComponent<RectTransform>();
((Component)child).gameObject.SetActive(false);
_item.OnBtnPressCallback = null;
_item.OnBtnPressCallback += Action<int>.op_Implicit((Action<int>)OnBtnPress);
GameObject val = new GameObject("PageNumber");
val.transform.SetParent(_gameObject.transform, false);
val.transform.localPosition = new Vector3(0f, -110f, 0f);
val.layer = LayerManager.LAYER_UI;
Color val2 = default(Color);
((Color)(ref val2))..ctor(1f, 1f, 1f, 0.2f);
TextMeshPro val3 = ((Il2CppArrayBase<TextMeshPro>)(object)_item.m_texts)[0];
_text = val.AddComponent<TextMeshPro>();
((TMP_Text)_text).font = ((TMP_Text)val3).font;
((TMP_Text)_text).fontSize = 48f;
((Graphic)_text).color = val2;
((TMP_Text)_text).alignment = (TextAlignmentOptions)1026;
((Graphic)_text).raycastTarget = ((Graphic)val3).raycastTarget;
_text.sortingLayerID = val3.sortingLayerID;
((TMP_Text)_text).enableWordWrapping = false;
((TMP_Text)_text).isOrthographic = true;
((TMP_Text)_text).rectTransform.sizeDelta = new Vector2(100f, 50f);
((Il2CppArrayBase<TextMeshPro>)(object)_item.m_texts)[0] = _text;
Object.Destroy((Object)(object)val3);
((Component)_item).transform.localPosition = new Vector3(-300f, -50f - Size.y / 2f, -1f);
_item.m_collider.size = Size;
((Il2CppArrayBase<Color>)(object)_item.m_textColorOut)[0] = val2;
((Il2CppArrayBase<Color>)(object)_item.m_textColorOver)[0] = Color.white;
_item.m_alphaSpriteOnHover = true;
}
public void SetData(GearIDRange idRange)
{
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Invalid comparison between Unknown and I4
if (_lastRange == idRange)
{
return;
}
_lastRange = idRange;
uint compID = idRange.GetCompID((eGearComponent)2);
GearCategoryDataBlock block = GameDataBlockBase<GearCategoryDataBlock>.GetBlock(compID);
ArchetypeDataBlock mappedArchetypeDataBlock = ArchetypeUtil.GetMappedArchetypeDataBlock(idRange, compID, block);
bool flag = WeaponStatShowerPlugin.ShowStats;
LocaleText localeText;
bool flag2;
ExtraDescriptionData data;
if (mappedArchetypeDataBlock != null)
{
localeText = new LocaleText(mappedArchetypeDataBlock.Description);
flag2 = DescriptionDataManager.TryGetArchData(((GameDataBlockBase<ArchetypeDataBlock>)(object)mappedArchetypeDataBlock).persistentID, out data);
}
else
{
ItemDataBlock block2 = GameDataBlockBase<ItemDataBlock>.GetBlock(idRange.GetCompID((eGearComponent)3));
flag = flag && (int)block2.inventorySlot == 10;
flag2 = DescriptionDataManager.TryGetGearData(compID, out data);
localeText = new LocaleText(block.Description);
}
if (!flag && (!flag2 || data.Descriptions.Length == 0))
{
_gameObject.SetActive(false);
return;
}
List<LocaleText> list = new List<LocaleText>();
List<LocaleText> list2 = new List<LocaleText>();
int num = DescriptionDataManager.Current.GlobalSettings.DefaultDescriptionIndex;
if (flag2)
{
if (data.DescriptionIndexOverride >= 0)
{
num = data.DescriptionIndexOverride;
}
list2.AddRange(data.Descriptions);
list.AddRange(data.Headers);
list.ExpandToSize(list2.Count, LocaleText.Empty);
}
LocaleText item = LocaleText.Empty;
LocaleText item2 = new LocaleText((LocalizedText)localeText);
if (flag)
{
var (localeText2, item3) = CreateGeneratedStats(idRange);
switch (WeaponStatShowerPlugin.StatsLocation)
{
case WeaponStatShowerPlugin.StatsPosition.Last:
list.Add(localeText2);
list2.Add(item3);
break;
case WeaponStatShowerPlugin.StatsPosition.First:
list.Insert(0, localeText2);
list2.Insert(0, item3);
if (num < list2.Count)
{
num++;
}
break;
case WeaponStatShowerPlugin.StatsPosition.Combined:
item = localeText2;
item2 = new LocaleText(item3.ToString() + "\n" + item2);
break;
}
}
num = Math.Min(num, list2.Count);
list2.Insert(num, item2);
list.Insert(num, item);
_descriptions = list2.ToArray();
_headers = list.ToArray();
LocaleText localeText3 = new LocaleText(idRange.PublicGearName);
for (int i = 0; i < _headers.Length; i++)
{
if (_headers[i] == LocaleText.Empty)
{
_headers[i] = localeText3;
}
}
_index = 0;
if (num != 0 || WeaponStatShowerPlugin.StatsLocation == WeaponStatShowerPlugin.StatsPosition.Combined)
{
((TMP_Text)_infoBox.m_infoMainTitleText).SetText((string)_headers[0], true);
((TMP_Text)_infoBox.m_infoDescriptionText).SetText((string)_descriptions[0], true);
}
if (_descriptions.Length == 1)
{
_gameObject.SetActive(false);
return;
}
_gameObject.SetActive(true);
((TMP_Text)_text).SetText("<< 1 >>", true);
}
private void OnBtnPress(int _)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
Vector2 val = RectTransformUtility.WorldToScreenPoint(CM_Camera.Current.Camera, ((CM_PageBase)_pageLoadout).CursorWorldPosition);
Vector2 val2 = default(Vector2);
RectTransformUtility.ScreenPointToLocalPointInRectangle(_rectTrans, val, CM_Camera.Current.Camera, ref val2);
if (val2.x > 0f)
{
_index = (_index + 1) % _descriptions.Length;
}
else if (_index > 0)
{
_index--;
}
else
{
_index = _descriptions.Length - 1;
}
((TMP_Text)_infoBox.m_infoMainTitleText).SetText((string)_headers[_index], true);
((TMP_Text)_infoBox.m_infoDescriptionText).SetText((string)_descriptions[_index], true);
((TMP_Text)_text).SetText($"<< {_index + 1} >>", true);
}
private static (LocaleText header, LocaleText desc) CreateGeneratedStats(GearIDRange idRange)
{
DescriptionBuilder.Inizialize(idRange, GameDataBlockBase<PlayerDataBlock>.GetBlock(1u), WeaponStatShowerPlugin.ConfigLanguage);
return (header: new LocaleText(DescriptionBuilder.FireRateFormatter(idRange.PublicGearName)), desc: new LocaleText(DescriptionBuilder.DescriptionFormatter()));
}
}
public class DescriptionDataManager
{
public static readonly DescriptionDataManager Current = new DescriptionDataManager();
private const string GlobalFile = "Global.json";
private const string DataDir = "ExtraDescriptions";
private readonly Dictionary<string, List<ExtraDescriptionData>> _fileData = new Dictionary<string, List<ExtraDescriptionData>>();
private readonly Dictionary<uint, ExtraDescriptionData> _archIdDataMap = new Dictionary<uint, ExtraDescriptionData>();
private readonly Dictionary<uint, ExtraDescriptionData> _gearIdDataMap = new Dictionary<uint, ExtraDescriptionData>();
public GlobalData GlobalSettings { get; private set; } = new GlobalData();
private void GlobalFileChanged(LiveEditEventArgs e)
{
WeaponStatShowerPlugin.LogWarning("LiveEdit Global File Changed");
LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
{
ReadGlobalContent(content);
});
}
private void ReadGlobalContent(string content)
{
if (JSON.TryDeserializeSafe<GlobalData>(content, out var value))
{
GlobalSettings = value;
}
}
private void DataFileChanged(LiveEditEventArgs e)
{
WeaponStatShowerPlugin.LogWarning("LiveEdit File Changed: " + e.FileName);
LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
{
ReadDataContent(e.FullPath, content);
});
}
private void DataFileDeleted(LiveEditEventArgs e)
{
WeaponStatShowerPlugin.LogWarning("LiveEdit File Removed: " + e.FileName);
if (!_fileData.Remove(e.FullPath, out List<ExtraDescriptionData> value))
{
return;
}
foreach (ExtraDescriptionData item in value)
{
if (item.ArchetypeID != 0)
{
_archIdDataMap.Remove(item.ArchetypeID);
}
if (item.GearCategoryID != 0)
{
_gearIdDataMap.Remove(item.GearCategoryID);
}
}
}
private void DataFileCreated(LiveEditEventArgs e)
{
WeaponStatShowerPlugin.LogWarning("LiveEdit File Created: " + e.FileName);
LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
{
ReadDataContent(e.FullPath, content);
});
}
private void ReadDataContent(string filepath, string content)
{
if (_fileData.TryGetValue(filepath, out List<ExtraDescriptionData> value))
{
foreach (ExtraDescriptionData item in value)
{
if (item.ArchetypeID != 0)
{
_archIdDataMap.Remove(item.ArchetypeID);
}
if (item.GearCategoryID != 0)
{
_gearIdDataMap.Remove(item.GearCategoryID);
}
}
value.Clear();
}
else
{
_fileData.Add(filepath, value = new List<ExtraDescriptionData>());
}
if (!JSON.TryDeserializeSafe<List<ExtraDescriptionData>>(content, out var value2))
{
return;
}
value.EnsureCapacity(value2.Count);
foreach (ExtraDescriptionData item2 in value2)
{
if (item2.ArchetypeID != 0 || item2.GearCategoryID != 0)
{
if (item2.ArchetypeID != 0 && !_archIdDataMap.TryAdd(item2.ArchetypeID, item2))
{
WeaponStatShowerPlugin.LogWarning($"Duplicate archetype ID {item2.ArchetypeID} found. Name: {_archIdDataMap[item2.ArchetypeID].Name}, duplicate name: {item2.Name}");
}
if (item2.GearCategoryID != 0 && !_gearIdDataMap.TryAdd(item2.GearCategoryID, item2))
{
WeaponStatShowerPlugin.LogWarning($"Duplicate gear category ID {item2.GearCategoryID} found. Name: {_gearIdDataMap[item2.GearCategoryID].Name}, duplicate name: {item2.Name}");
}
value.Add(item2);
}
}
value.TrimExcess();
}
public DescriptionDataManager()
{
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_0171: Expected O, but got Unknown
//IL_0185: Unknown result type (might be due to invalid IL or missing references)
//IL_018f: Expected O, but got Unknown
//IL_0197: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Expected O, but got Unknown
//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
//IL_01b2: Expected O, but got Unknown
if (!MTFOWrapper.HasMTFO)
{
return;
}
string text = Path.Combine(MTFOWrapper.CustomPath, "WeaponStatShower");
string path = Path.Combine(text, "Global.json");
string text2 = Path.Combine(text, "ExtraDescriptions");
if (!Directory.Exists(text))
{
WeaponStatShowerPlugin.LogInfo("No Weapon Stat Shower directory detected. Creating templates.");
Directory.CreateDirectory(text2);
StreamWriter streamWriter;
using (streamWriter = File.CreateText(path))
{
streamWriter.WriteLine(JSON.Serialize(new GlobalData()));
}
using (streamWriter = File.CreateText(Path.Combine(text2, "Template.json")))
{
streamWriter.WriteLine(JSON.Serialize(ExtraDescriptionData.Template));
}
}
else if (!File.Exists(path))
{
using StreamWriter streamWriter2 = File.CreateText(path);
streamWriter2.WriteLine(JSON.Serialize(new GlobalData()));
}
ReadGlobalContent(File.ReadAllText(path));
foreach (string item in Directory.EnumerateFiles(text2, "*.json", SearchOption.AllDirectories))
{
ReadDataContent(item, File.ReadAllText(item));
}
LiveEdit.CreateListener(text, "Global.json", false).FileChanged += new LiveEditEventHandler(GlobalFileChanged);
LiveEditListener obj = LiveEdit.CreateListener(text2, "*.json", true);
obj.FileCreated += new LiveEditEventHandler(DataFileCreated);
obj.FileChanged += new LiveEditEventHandler(DataFileChanged);
obj.FileDeleted += new LiveEditEventHandler(DataFileDeleted);
}
internal void Init()
{
}
public static bool TryGetArchData(uint archetypeID, [MaybeNullWhen(false)] out ExtraDescriptionData data)
{
return Current._archIdDataMap.TryGetValue(archetypeID, out data);
}
public static bool TryGetGearData(uint gearCategoryID, [MaybeNullWhen(false)] out ExtraDescriptionData data)
{
return Current._gearIdDataMap.TryGetValue(gearCategoryID, out data);
}
}
}
namespace WeaponStatShower.ExtraDescription.Data
{
public class ExtraDescriptionData
{
public static readonly ExtraDescriptionData[] Template = new ExtraDescriptionData[2]
{
new ExtraDescriptionData(),
new ExtraDescriptionData
{
Headers = new LocaleText[2]
{
LocaleText.Empty,
new LocaleText("Third Tab")
},
Descriptions = new LocaleText[2]
{
new LocaleText("Custom tab for testing"),
new LocaleText("Another custom tab under the third tab")
},
Name = "Filled Example"
}
};
public uint ArchetypeID { get; set; }
public uint GearCategoryID { get; set; }
public LocaleText[] Headers { get; set; } = Array.Empty<LocaleText>();
public LocaleText[] Descriptions { get; set; } = Array.Empty<LocaleText>();
public int DescriptionIndexOverride { get; set; } = -1;
public string Name { get; set; } = string.Empty;
}
public class GlobalData
{
public bool PreferHideStats { get; set; }
public int DefaultDescriptionIndex { get; set; }
}
}
namespace WeaponStatShower.Dependencies
{
internal static class MTFOWrapper
{
public const string PLUGIN_GUID = "com.dak.MTFO";
public static readonly bool HasMTFO;
public static string GameDataPath => MTFOPathAPI.RundownPath;
public static string CustomPath => MTFOPathAPI.CustomPath;
public static bool HasCustomDatablocks
{
get
{
if (HasMTFO)
{
return UnsafeHasCustomDatablocks();
}
return false;
}
}
static MTFOWrapper()
{
HasMTFO = ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("com.dak.MTFO");
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool UnsafeHasCustomDatablocks()
{
return MTFOPathAPI.HasRundownPath;
}
public static void AddOnHotReload(Action action)
{
if (HasMTFO)
{
AddOnHotReload_Unsafe(action);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void AddOnHotReload_Unsafe(Action action)
{
MTFOHotReloadAPI.OnHotReload += action;
}
}
internal static class PartialData
{
public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks";
public static readonly bool HasPData;
public static JsonConverter PDataIDConverter;
static PartialData()
{
HasPData = ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("MTFO.Extension.PartialBlocks");
if (HasPData)
{
SetConverter();
}
}
public static bool TryGetGUID(string text, out uint guid)
{
if (!HasPData)
{
guid = 0u;
return false;
}
return TryGetGUID_Internal(text, out guid);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool TryGetGUID_Internal(string text, out uint guid)
{
return PersistentIDManager.TryGetId(text, ref guid);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void SetConverter()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Expected O, but got Unknown
PDataIDConverter = (JsonConverter)new PersistentIDConverter();
}
}
}