Depend on EFTApi and refactor code
This commit is contained in:
parent
d75de1aa04
commit
f7caaaadaf
@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.1.32407.343
|
VisualStudioVersion = 17.1.32407.343
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkinHide", "SkinHide\SkinHide.csproj", "{E5DD6484-115E-4104-AADF-E5610EE4F397}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HideDress", "HideDress\HideDress.csproj", "{E5DD6484-115E-4104-AADF-E5610EE4F397}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
@ -7,8 +7,8 @@
|
|||||||
<ProjectGuid>{E5DD6484-115E-4104-AADF-E5610EE4F397}</ProjectGuid>
|
<ProjectGuid>{E5DD6484-115E-4104-AADF-E5610EE4F397}</ProjectGuid>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>SkinHide</RootNamespace>
|
<RootNamespace>HideDress</RootNamespace>
|
||||||
<AssemblyName>SkinHide</AssemblyName>
|
<AssemblyName>HideDress</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<Deterministic>true</Deterministic>
|
<Deterministic>true</Deterministic>
|
||||||
@ -55,6 +55,12 @@
|
|||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>R:\Battlestate Games\Client.0.12.12.15.17349\EscapeFromTarkov_Data\Managed\Comfort.dll</HintPath>
|
<HintPath>R:\Battlestate Games\Client.0.12.12.15.17349\EscapeFromTarkov_Data\Managed\Comfort.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="EFTApi">
|
||||||
|
<HintPath>..\..\EFTApi\Build\bin\Current\EFTApi.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="EFTReflection">
|
||||||
|
<HintPath>..\..\EFTApi\Build\bin\Current\EFTReflection.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Sirenix.Serialization, Version=3.0.4.0, Culture=neutral, PublicKeyToken=null" />
|
<Reference Include="Sirenix.Serialization, Version=3.0.4.0, Culture=neutral, PublicKeyToken=null" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
@ -78,11 +84,12 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Patches\PlayerPatch.cs" />
|
<Compile Include="Models\ReflectionModel.cs" />
|
||||||
<Compile Include="Patches\PlayerModelViewPatch.cs" />
|
<Compile Include="Models\SettingsModel.cs" />
|
||||||
<Compile Include="SkinHidePlugin.cs" />
|
<Compile Include="Models\HideDressModel.cs" />
|
||||||
|
<Compile Include="HideDressPlugin.cs" />
|
||||||
|
<Compile Include="Patches\PlayerModelViewShow.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Utils\RefHelp.cs" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="kmyuhkyuk.pfx" />
|
<None Include="kmyuhkyuk.pfx" />
|
2
HideDress/HideDress.csproj.DotSettings
Normal file
2
HideDress/HideDress.csproj.DotSettings
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=patches/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
107
HideDress/HideDressPlugin.cs
Normal file
107
HideDress/HideDressPlugin.cs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using BepInEx;
|
||||||
|
using EFT;
|
||||||
|
using EFT.Visual;
|
||||||
|
using HideDress.Models;
|
||||||
|
using static EFTApi.EFTHelpers;
|
||||||
|
|
||||||
|
namespace HideDress
|
||||||
|
{
|
||||||
|
[BepInPlugin("com.kmyuhkyuk.HideDress", "kmyuhkyuk-HideDress", "1.2.7")]
|
||||||
|
[BepInDependency("com.kmyuhkyuk.EFTApi", "1.2.0")]
|
||||||
|
public partial class HideDressPlugin : BaseUnityPlugin
|
||||||
|
{
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
SettingsModel.Create(Config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
ReflectionModel.Instance.PlayerModelViewShow.Add(this, nameof(PlayerModelViewShow));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
var player = _PlayerHelper.Player;
|
||||||
|
var world = _GameWorldHelper.GameWorld;
|
||||||
|
var settingsModel = SettingsModel.Instance;
|
||||||
|
var hideDressModel = HideDressModel.Instance;
|
||||||
|
|
||||||
|
if (settingsModel.KeyPlayerHideDressShortcut.Value.IsDown())
|
||||||
|
{
|
||||||
|
settingsModel.KeyPlayerHideDress.Value = !settingsModel.KeyPlayerHideDress.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsModel.KeyOtherPlayerHideDressShortcut.Value.IsDown())
|
||||||
|
{
|
||||||
|
settingsModel.KeyOtherPlayerHideDress.Value = !settingsModel.KeyOtherPlayerHideDress.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hideDressModel.PlayerModelViewBody != null)
|
||||||
|
{
|
||||||
|
EnabledPartDress(hideDressModel.PlayerModelViewBody, settingsModel.KeyPlayerHideDressPart.Value, !settingsModel.KeyPlayerHideDress.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player != null)
|
||||||
|
{
|
||||||
|
EnabledPartDress(player.PlayerBody, settingsModel.KeyPlayerHideDressPart.Value, !settingsModel.KeyPlayerHideDress.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (world != null)
|
||||||
|
{
|
||||||
|
foreach (var otherPlayer in _GameWorldHelper.AllOtherPlayer)
|
||||||
|
{
|
||||||
|
EnabledPartDress(otherPlayer.PlayerBody, settingsModel.KeyOtherPlayerHideDressPart.Value, !settingsModel.KeyOtherPlayerHideDress.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnabledPartDress(PlayerBody playerBody, HideDressModel.DressPart part, bool enabled)
|
||||||
|
{
|
||||||
|
var reflectionModel = ReflectionModel.Instance;
|
||||||
|
|
||||||
|
var slotViews = reflectionModel.RefSlotViews.GetValue(playerBody);
|
||||||
|
|
||||||
|
var slotList = reflectionModel.RefSlotList.GetValue(slotViews);
|
||||||
|
|
||||||
|
var dressList = new List<Dress>();
|
||||||
|
|
||||||
|
foreach (var slot in slotList)
|
||||||
|
{
|
||||||
|
var dresses = reflectionModel.RefDresses.GetValue(slot);
|
||||||
|
|
||||||
|
if (dresses == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (var dress in dresses)
|
||||||
|
{
|
||||||
|
dressList.Add(dress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EnabledDress(dressList.Where(x => x.GetType() == typeof(Dress)), part == HideDressModel.DressPart.SkinDress || enabled);
|
||||||
|
EnabledSkinDress(dressList.Where(x => x is SkinDress || x is ArmBandView), part == HideDressModel.DressPart.Dress || enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnabledDress(IEnumerable<Dress> dressEnumerable, bool enabled)
|
||||||
|
{
|
||||||
|
foreach (var dress in dressEnumerable)
|
||||||
|
{
|
||||||
|
foreach (var renderer in ReflectionModel.Instance.RefRenderers.GetValue(dress))
|
||||||
|
{
|
||||||
|
renderer.enabled = enabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnabledSkinDress(IEnumerable<Dress> skinDressEnumerable, bool enabled)
|
||||||
|
{
|
||||||
|
foreach (var skinDress in skinDressEnumerable)
|
||||||
|
{
|
||||||
|
skinDress.gameObject.SetActive(enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
HideDress/Models/HideDressModel.cs
Normal file
25
HideDress/Models/HideDressModel.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using EFT;
|
||||||
|
|
||||||
|
namespace HideDress.Models
|
||||||
|
{
|
||||||
|
internal class HideDressModel
|
||||||
|
{
|
||||||
|
private static readonly Lazy<HideDressModel> Lazy = new Lazy<HideDressModel>(() => new HideDressModel());
|
||||||
|
|
||||||
|
public static HideDressModel Instance => Lazy.Value;
|
||||||
|
|
||||||
|
public PlayerBody PlayerModelViewBody;
|
||||||
|
|
||||||
|
public enum DressPart
|
||||||
|
{
|
||||||
|
Both,
|
||||||
|
Dress,
|
||||||
|
SkinDress
|
||||||
|
}
|
||||||
|
|
||||||
|
private HideDressModel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
38
HideDress/Models/ReflectionModel.cs
Normal file
38
HideDress/Models/ReflectionModel.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using EFT;
|
||||||
|
using EFT.UI;
|
||||||
|
using EFT.Visual;
|
||||||
|
using EFTReflection;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace HideDress.Models
|
||||||
|
{
|
||||||
|
internal class ReflectionModel
|
||||||
|
{
|
||||||
|
private static readonly Lazy<ReflectionModel> Lazy = new Lazy<ReflectionModel>(() => new ReflectionModel());
|
||||||
|
|
||||||
|
public static ReflectionModel Instance => Lazy.Value;
|
||||||
|
|
||||||
|
public readonly RefHelper.FieldRef<PlayerBody, object> RefSlotViews;
|
||||||
|
|
||||||
|
public readonly RefHelper.FieldRef<object, IEnumerable<object>> RefSlotList;
|
||||||
|
|
||||||
|
public readonly RefHelper.FieldRef<object, Dress[]> RefDresses;
|
||||||
|
|
||||||
|
public readonly RefHelper.FieldRef<Dress, Renderer[]> RefRenderers;
|
||||||
|
|
||||||
|
public readonly RefHelper.HookRef PlayerModelViewShow;
|
||||||
|
|
||||||
|
private ReflectionModel()
|
||||||
|
{
|
||||||
|
RefSlotViews = RefHelper.FieldRef<PlayerBody, object>.Create("SlotViews");
|
||||||
|
RefSlotList = RefHelper.FieldRef<object, IEnumerable<object>>.Create(RefSlotViews.FieldType, "list_0");
|
||||||
|
RefDresses =
|
||||||
|
RefHelper.FieldRef<object, Dress[]>.Create(RefSlotList.FieldType.GetGenericArguments()[0], "Dresses");
|
||||||
|
RefRenderers = RefHelper.FieldRef<Dress, Renderer[]>.Create("Renderers");
|
||||||
|
|
||||||
|
PlayerModelViewShow = RefHelper.HookRef.Create(typeof(PlayerModelView), x => x.Name == "Show" && x.GetParameters()[0].ParameterType == typeof(PlayerVisualRepresentation));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
HideDress/Models/SettingsModel.cs
Normal file
50
HideDress/Models/SettingsModel.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
|
||||||
|
namespace HideDress.Models
|
||||||
|
{
|
||||||
|
internal class SettingsModel
|
||||||
|
{
|
||||||
|
public static SettingsModel Instance { get; private set; }
|
||||||
|
|
||||||
|
public readonly ConfigEntry<bool> KeyPlayerHideDress;
|
||||||
|
public readonly ConfigEntry<bool> KeyOtherPlayerHideDress;
|
||||||
|
|
||||||
|
public readonly ConfigEntry<HideDressModel.DressPart> KeyPlayerHideDressPart;
|
||||||
|
public readonly ConfigEntry<HideDressModel.DressPart> KeyOtherPlayerHideDressPart;
|
||||||
|
|
||||||
|
public readonly ConfigEntry<KeyboardShortcut> KeyPlayerHideDressShortcut;
|
||||||
|
public readonly ConfigEntry<KeyboardShortcut> KeyOtherPlayerHideDressShortcut;
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "RedundantTypeArgumentsOfMethod")]
|
||||||
|
private SettingsModel(ConfigFile configFile)
|
||||||
|
{
|
||||||
|
const string hideDressSettings = "Hide Dress Settings";
|
||||||
|
const string hideDressPartSettings = "Hide Dress Part Settings";
|
||||||
|
const string shortcutSettings = "Keyboard Shortcut Settings";
|
||||||
|
|
||||||
|
KeyPlayerHideDress = configFile.Bind<bool>(hideDressSettings, "Hide Player Dress", false);
|
||||||
|
KeyOtherPlayerHideDress = configFile.Bind<bool>(hideDressSettings, "Hide Other Player Dress", false);
|
||||||
|
|
||||||
|
KeyPlayerHideDressPart =
|
||||||
|
configFile.Bind<HideDressModel.DressPart>(hideDressPartSettings, "Player", HideDressModel.DressPart.Both);
|
||||||
|
KeyOtherPlayerHideDressPart =
|
||||||
|
configFile.Bind<HideDressModel.DressPart>(hideDressPartSettings, "Other Player", HideDressModel.DressPart.Both);
|
||||||
|
|
||||||
|
KeyPlayerHideDressShortcut =
|
||||||
|
configFile.Bind<KeyboardShortcut>(shortcutSettings, "Hide Player Dress",
|
||||||
|
KeyboardShortcut.Empty);
|
||||||
|
KeyOtherPlayerHideDressShortcut =
|
||||||
|
configFile.Bind<KeyboardShortcut>(shortcutSettings, "Hide Other Player Dress", KeyboardShortcut.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReSharper disable once UnusedMethodReturnValue.Global
|
||||||
|
public static SettingsModel Create(ConfigFile configFile)
|
||||||
|
{
|
||||||
|
if (Instance != null)
|
||||||
|
return Instance;
|
||||||
|
|
||||||
|
return Instance = new SettingsModel(configFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
HideDress/Patches/PlayerModelViewShow.cs
Normal file
16
HideDress/Patches/PlayerModelViewShow.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using EFT.UI;
|
||||||
|
using HideDress.Models;
|
||||||
|
|
||||||
|
namespace HideDress
|
||||||
|
{
|
||||||
|
public partial class HideDressPlugin
|
||||||
|
{
|
||||||
|
private static async void PlayerModelViewShow(Task __result, PlayerModelView __instance)
|
||||||
|
{
|
||||||
|
await __result;
|
||||||
|
|
||||||
|
HideDressModel.Instance.PlayerModelViewBody = __instance.PlayerBody;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,14 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// 有关程序集的一般信息由以下
|
// 有关程序集的一般信息由以下
|
||||||
// 控制。更改这些特性值可修改
|
// 控制。更改这些特性值可修改
|
||||||
// 与程序集关联的信息。
|
// 与程序集关联的信息。
|
||||||
[assembly: AssemblyTitle("kmyuhkyuk-SkinHide")]
|
[assembly: AssemblyTitle("kmyuhkyuk-HideDress")]
|
||||||
[assembly: AssemblyDescription("")]
|
[assembly: AssemblyDescription("")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("https://hub.sp-tarkov.com/files/file/583-skin-hide")]
|
[assembly: AssemblyCompany("https://hub.sp-tarkov.com/files/file/583-skin-hide")]
|
||||||
[assembly: AssemblyProduct("SkinHide")]
|
[assembly: AssemblyProduct("HideDress")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 2022")]
|
[assembly: AssemblyCopyright("Copyright © 2022")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
@ -33,4 +32,4 @@ using System.Runtime.InteropServices;
|
|||||||
//通过使用 "*",如下所示:
|
//通过使用 "*",如下所示:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.2.7.0")]
|
[assembly: AssemblyVersion("1.2.7.0")]
|
||||||
[assembly: AssemblyFileVersion("1.2.7.0")]
|
[assembly: AssemblyFileVersion("1.2.7.0")]
|
@ -1,24 +0,0 @@
|
|||||||
using Aki.Reflection.Patching;
|
|
||||||
using Aki.Reflection.Utils;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using EFT.UI;
|
|
||||||
|
|
||||||
namespace SkinHide.Patches
|
|
||||||
{
|
|
||||||
public class PlayerModelViewPatch : ModulePatch
|
|
||||||
{
|
|
||||||
protected override MethodBase GetTargetMethod()
|
|
||||||
{
|
|
||||||
return typeof(PlayerModelView).GetMethod("method_0", PatchConstants.PrivateFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
[PatchPostfix]
|
|
||||||
private static async void PatchPostfix(Task __result, PlayerModelView __instance)
|
|
||||||
{
|
|
||||||
await __result;
|
|
||||||
|
|
||||||
SkinHidePlugin.PlayerModelView = __instance.PlayerBody;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
using Aki.Reflection.Patching;
|
|
||||||
using Aki.Reflection.Utils;
|
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using EFT;
|
|
||||||
|
|
||||||
namespace SkinHide.Patches
|
|
||||||
{
|
|
||||||
public class PlayerInitPatch : ModulePatch
|
|
||||||
{
|
|
||||||
private static readonly bool Is231Up = SkinHidePlugin.GameVersion > new Version("0.12.12.17349");
|
|
||||||
|
|
||||||
protected override MethodBase GetTargetMethod()
|
|
||||||
{
|
|
||||||
return typeof(Player).GetMethod("Init", PatchConstants.PrivateFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
[PatchPostfix]
|
|
||||||
private async static void PatchPostfix(Task __result, Player __instance)
|
|
||||||
{
|
|
||||||
await __result;
|
|
||||||
|
|
||||||
bool isYouPlayer;
|
|
||||||
|
|
||||||
if (Is231Up)
|
|
||||||
{
|
|
||||||
isYouPlayer = __instance.IsYourPlayer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
isYouPlayer = __instance.Id == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isYouPlayer)
|
|
||||||
{
|
|
||||||
SkinHidePlugin.Player = __instance.PlayerBody;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SkinHidePlugin.BotList.Add(__instance.PlayerBody);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PlayerEndPatch : ModulePatch
|
|
||||||
{
|
|
||||||
private static readonly bool Is231Up = SkinHidePlugin.GameVersion > new Version("0.12.12.17349");
|
|
||||||
|
|
||||||
protected override MethodBase GetTargetMethod()
|
|
||||||
{
|
|
||||||
return typeof(Player).GetMethod("OnGameSessionEnd", BindingFlags.Public | BindingFlags.Instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
[PatchPostfix]
|
|
||||||
private static void PatchPostfix(Player __instance)
|
|
||||||
{
|
|
||||||
bool isYouPlayer;
|
|
||||||
|
|
||||||
if (Is231Up)
|
|
||||||
{
|
|
||||||
isYouPlayer = __instance.IsYourPlayer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
isYouPlayer = __instance.Id == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isYouPlayer)
|
|
||||||
{
|
|
||||||
SkinHidePlugin.BotList.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,206 +0,0 @@
|
|||||||
using BepInEx;
|
|
||||||
using BepInEx.Configuration;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
using EFT;
|
|
||||||
using EFT.Visual;
|
|
||||||
using SkinHide.Patches;
|
|
||||||
using SkinHide.Utils;
|
|
||||||
using EFT.InventoryLogic;
|
|
||||||
|
|
||||||
namespace SkinHide
|
|
||||||
{
|
|
||||||
[BepInPlugin("com.kmyuhkyuk.SkinHide", "kmyuhkyuk-SkinHide", "1.2.7")]
|
|
||||||
public class SkinHidePlugin : BaseUnityPlugin
|
|
||||||
{
|
|
||||||
internal static PlayerBody Player;
|
|
||||||
|
|
||||||
internal static PlayerBody PlayerModelView;
|
|
||||||
|
|
||||||
internal static List<PlayerBody> BotList = new List<PlayerBody>();
|
|
||||||
|
|
||||||
private readonly SettingsData SettingsDatas = new SettingsData();
|
|
||||||
|
|
||||||
private readonly ReflectionData ReflectionDatas = new ReflectionData();
|
|
||||||
|
|
||||||
private bool PMVHideCache;
|
|
||||||
|
|
||||||
private bool PlayerHideCache;
|
|
||||||
|
|
||||||
private bool BotHideCache;
|
|
||||||
|
|
||||||
internal static Version GameVersion { get; private set; }
|
|
||||||
|
|
||||||
public enum Part
|
|
||||||
{
|
|
||||||
All,
|
|
||||||
Dress,
|
|
||||||
SkinDress
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Start()
|
|
||||||
{
|
|
||||||
Logger.LogInfo("Loaded: kmyuhkyuk-SkinHide");
|
|
||||||
|
|
||||||
FileVersionInfo exeInfo = Process.GetCurrentProcess().MainModule.FileVersionInfo;
|
|
||||||
|
|
||||||
GameVersion = new Version(exeInfo.FileMajorPart, exeInfo.ProductMinorPart, exeInfo.ProductBuildPart, exeInfo.FilePrivatePart);
|
|
||||||
|
|
||||||
const string skinHideSettings = "Skin Hide Settings";
|
|
||||||
const string skinHidePartSettings = "隐藏部分设置 Skin Hide Part Settings";
|
|
||||||
const string kbsSettings = "快捷键设置 Keyboard Shortcut Settings";
|
|
||||||
|
|
||||||
SettingsDatas.KeyPlayerSkinHide = Config.Bind<bool>(skinHideSettings, "玩家服装隐藏 Player Skin Hide", false);
|
|
||||||
SettingsDatas.KeyBotSkinHide = Config.Bind<bool>(skinHideSettings, "Bot服装隐藏 Bot Skin Hide", false);
|
|
||||||
|
|
||||||
SettingsDatas.KeyPlayerSkinHidePart = Config.Bind<Part>(skinHidePartSettings, "Player", Part.All);
|
|
||||||
SettingsDatas.KeyBotSkinHidePart = Config.Bind<Part>(skinHidePartSettings, "Bot", Part.All);
|
|
||||||
|
|
||||||
SettingsDatas.KBSPlayerSkinHide = Config.Bind<KeyboardShortcut>(kbsSettings, "玩家服装隐藏快捷键 Player Skin Hide", KeyboardShortcut.Empty);
|
|
||||||
SettingsDatas.KBSBotSkinHide = Config.Bind<KeyboardShortcut>(kbsSettings, "Bot服装隐藏快捷键 Bot Skin Hide", KeyboardShortcut.Empty);
|
|
||||||
|
|
||||||
new PlayerModelViewPatch().Enable();
|
|
||||||
new PlayerInitPatch().Enable();
|
|
||||||
new PlayerEndPatch().Enable();
|
|
||||||
|
|
||||||
ReflectionDatas.RefSlotViews = RefHelp.FieldRef<PlayerBody, object>.Create("SlotViews");
|
|
||||||
ReflectionDatas.RefSlotList = RefHelp.FieldRef<object, IEnumerable<object>>.Create(ReflectionDatas.RefSlotViews.FieldType, "list_0");
|
|
||||||
ReflectionDatas.RefDresses = RefHelp.FieldRef<object, Dress[]>.Create(ReflectionDatas.RefSlotList.FieldType.GetGenericArguments()[0], "Dresses");
|
|
||||||
ReflectionDatas.RefRenderers = RefHelp.FieldRef<Dress, Renderer[]>.Create("Renderers");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
if (SettingsDatas.KBSPlayerSkinHide.Value.IsDown())
|
|
||||||
{
|
|
||||||
SettingsDatas.KeyPlayerSkinHide.Value = !SettingsDatas.KeyPlayerSkinHide.Value;
|
|
||||||
}
|
|
||||||
if (SettingsDatas.KBSBotSkinHide.Value.IsDown())
|
|
||||||
{
|
|
||||||
SettingsDatas.KeyBotSkinHide.Value = !SettingsDatas.KeyBotSkinHide.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
//PlayerModelView Skin Hide
|
|
||||||
if (PlayerModelView != null)
|
|
||||||
{
|
|
||||||
if (SettingsDatas.KeyPlayerSkinHide.Value)
|
|
||||||
{
|
|
||||||
Hide(PlayerModelView, SettingsDatas.KeyPlayerSkinHidePart.Value, true);
|
|
||||||
|
|
||||||
PMVHideCache = true;
|
|
||||||
}
|
|
||||||
else if (!SettingsDatas.KeyPlayerSkinHide.Value && PMVHideCache)
|
|
||||||
{
|
|
||||||
Hide(PlayerModelView, Part.All, false);
|
|
||||||
|
|
||||||
PMVHideCache = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Player Skin Hide
|
|
||||||
if (Player != null)
|
|
||||||
{
|
|
||||||
if (SettingsDatas.KeyPlayerSkinHide.Value)
|
|
||||||
{
|
|
||||||
Hide(Player, SettingsDatas.KeyPlayerSkinHidePart.Value, true);
|
|
||||||
|
|
||||||
PlayerHideCache = true;
|
|
||||||
}
|
|
||||||
else if (!SettingsDatas.KeyPlayerSkinHide.Value && PlayerHideCache)
|
|
||||||
{
|
|
||||||
Hide(Player, Part.All, false);
|
|
||||||
|
|
||||||
PlayerHideCache = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Bot Skin Hide
|
|
||||||
if (BotList.Count > 0)
|
|
||||||
{
|
|
||||||
if (SettingsDatas.KeyBotSkinHide.Value)
|
|
||||||
{
|
|
||||||
foreach (PlayerBody bot in BotList)
|
|
||||||
{
|
|
||||||
Hide(bot, SettingsDatas.KeyBotSkinHidePart.Value, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
BotHideCache = true;
|
|
||||||
}
|
|
||||||
else if (!SettingsDatas.KeyBotSkinHide.Value && BotHideCache)
|
|
||||||
{
|
|
||||||
foreach (PlayerBody bot in BotList)
|
|
||||||
{
|
|
||||||
Hide(bot, Part.All, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
BotHideCache = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Hide(PlayerBody playerbody, Part part, bool hide)
|
|
||||||
{
|
|
||||||
object slotViews = ReflectionDatas.RefSlotViews.GetValue(playerbody);
|
|
||||||
|
|
||||||
IEnumerable<object> slotList = ReflectionDatas.RefSlotList.GetValue(slotViews);
|
|
||||||
|
|
||||||
IEnumerable<Dress> dresses = slotList.SelectMany(x => ReflectionDatas.RefDresses.GetValue(x)).Where(x => x != null);
|
|
||||||
|
|
||||||
IEnumerable<Dress> dress = dresses.Where(x => x.GetType() == typeof(Dress));
|
|
||||||
|
|
||||||
IEnumerable<Renderer> renDress = dress.SelectMany(x => ReflectionDatas.RefRenderers.GetValue(x));
|
|
||||||
|
|
||||||
IEnumerable<GameObject> skinDress = dresses.Where(x => x.GetType() == typeof(SkinDress) || x.GetType() == typeof(ArmBandView)).Select(x => x.gameObject);
|
|
||||||
|
|
||||||
switch (part)
|
|
||||||
{
|
|
||||||
case Part.All:
|
|
||||||
foreach (GameObject gameobject in skinDress)
|
|
||||||
{
|
|
||||||
gameobject.SetActive(!hide);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (MeshRenderer renderer in renDress)
|
|
||||||
{
|
|
||||||
renderer.enabled = !hide;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Part.Dress:
|
|
||||||
foreach (MeshRenderer renderer in renDress)
|
|
||||||
{
|
|
||||||
renderer.enabled = !hide;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Part.SkinDress:
|
|
||||||
foreach (GameObject gameobject in skinDress)
|
|
||||||
{
|
|
||||||
gameobject.SetActive(!hide);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SettingsData
|
|
||||||
{
|
|
||||||
public ConfigEntry<bool> KeyPlayerSkinHide;
|
|
||||||
public ConfigEntry<bool> KeyBotSkinHide;
|
|
||||||
|
|
||||||
public ConfigEntry<Part> KeyPlayerSkinHidePart;
|
|
||||||
public ConfigEntry<Part> KeyBotSkinHidePart;
|
|
||||||
|
|
||||||
public ConfigEntry<KeyboardShortcut> KBSPlayerSkinHide;
|
|
||||||
public ConfigEntry<KeyboardShortcut> KBSBotSkinHide;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ReflectionData
|
|
||||||
{
|
|
||||||
public RefHelp.FieldRef<PlayerBody, object> RefSlotViews;
|
|
||||||
public RefHelp.FieldRef<object, IEnumerable<object>> RefSlotList;
|
|
||||||
public RefHelp.FieldRef<object, Dress[]> RefDresses;
|
|
||||||
public RefHelp.FieldRef<Dress, Renderer[]> RefRenderers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,431 +0,0 @@
|
|||||||
using Aki.Reflection.Utils;
|
|
||||||
using HarmonyLib;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Reflection.Emit;
|
|
||||||
|
|
||||||
namespace SkinHide.Utils
|
|
||||||
{
|
|
||||||
public class RefHelp
|
|
||||||
{
|
|
||||||
public static DelegateType ObjectMethodDelegate<DelegateType>(MethodInfo method, bool virtualCall = true) where DelegateType : Delegate
|
|
||||||
{
|
|
||||||
if (method == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(method));
|
|
||||||
}
|
|
||||||
|
|
||||||
var delegateType = typeof(DelegateType);
|
|
||||||
|
|
||||||
var declaringType = method.DeclaringType;
|
|
||||||
|
|
||||||
var delegateMethod = delegateType.GetMethod("Invoke");
|
|
||||||
var delegateParameters = delegateMethod.GetParameters();
|
|
||||||
var delegateParameterTypes = delegateParameters.Select(x => x.ParameterType).ToArray();
|
|
||||||
|
|
||||||
Type returnType;
|
|
||||||
bool needBox;
|
|
||||||
|
|
||||||
if (delegateMethod.ReturnType == typeof(object) && method.ReturnType.IsValueType)
|
|
||||||
{
|
|
||||||
returnType = typeof(object);
|
|
||||||
|
|
||||||
needBox = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
returnType = method.ReturnType;
|
|
||||||
|
|
||||||
needBox = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var dmd = new DynamicMethod("OpenInstanceDelegate_" + method.Name, returnType, delegateParameterTypes);
|
|
||||||
|
|
||||||
var ilGen = dmd.GetILGenerator();
|
|
||||||
|
|
||||||
Type[] parameterTypes;
|
|
||||||
int num;
|
|
||||||
|
|
||||||
if (!method.IsStatic)
|
|
||||||
{
|
|
||||||
var parameters = method.GetParameters();
|
|
||||||
var numParameters = parameters.Length;
|
|
||||||
parameterTypes = new Type[numParameters + 1];
|
|
||||||
parameterTypes[0] = typeof(object);
|
|
||||||
|
|
||||||
for (int i = 0; i < numParameters; i++)
|
|
||||||
{
|
|
||||||
parameterTypes[i + 1] = parameters[i].ParameterType;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (declaringType != null && declaringType.IsValueType)
|
|
||||||
{
|
|
||||||
ilGen.Emit(OpCodes.Ldarga_S, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ilGen.Emit(OpCodes.Ldarg_0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ilGen.Emit(OpCodes.Castclass, declaringType);
|
|
||||||
|
|
||||||
num = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
parameterTypes = method.GetParameters().Select(x => x.ParameterType).ToArray();
|
|
||||||
|
|
||||||
num = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = num; i < parameterTypes.Length; i++)
|
|
||||||
{
|
|
||||||
ilGen.Emit(OpCodes.Ldarg, i);
|
|
||||||
|
|
||||||
Type parameterType = parameterTypes[i];
|
|
||||||
|
|
||||||
bool isValueType = parameterType.IsValueType;
|
|
||||||
|
|
||||||
if (!isValueType)
|
|
||||||
{
|
|
||||||
ilGen.Emit(OpCodes.Castclass, parameterType);
|
|
||||||
}
|
|
||||||
//DelegateparameterTypes i == parameterTypes i
|
|
||||||
else if (delegateParameterTypes[i] == typeof(object) && isValueType)
|
|
||||||
{
|
|
||||||
ilGen.Emit(OpCodes.Unbox_Any, parameterType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method.IsStatic || !virtualCall)
|
|
||||||
{
|
|
||||||
ilGen.Emit(OpCodes.Call, method);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ilGen.Emit(OpCodes.Callvirt, method);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needBox)
|
|
||||||
{
|
|
||||||
ilGen.Emit(OpCodes.Box, method.ReturnType);
|
|
||||||
}
|
|
||||||
|
|
||||||
ilGen.Emit(OpCodes.Ret);
|
|
||||||
|
|
||||||
return (DelegateType)dmd.CreateDelegate(delegateType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PropertyRef<T, F> where T : class
|
|
||||||
{
|
|
||||||
private Func<T, F> RefGetValue;
|
|
||||||
|
|
||||||
private Action<T, F> RefSetValue;
|
|
||||||
|
|
||||||
private PropertyInfo PropertyInfo;
|
|
||||||
|
|
||||||
private MethodInfo GetMethodInfo;
|
|
||||||
|
|
||||||
private MethodInfo SetMethodInfo;
|
|
||||||
|
|
||||||
private Type TType;
|
|
||||||
|
|
||||||
private T Instance;
|
|
||||||
|
|
||||||
public Type InType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return TType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type PropertyType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return PropertyInfo.PropertyType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyRef(PropertyInfo propertyinfo, object instance)
|
|
||||||
{
|
|
||||||
if (propertyinfo == null)
|
|
||||||
{
|
|
||||||
throw new Exception("PropertyInfo is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
Init(propertyinfo, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyRef(Type type, string propertyname, bool declaredonly, object instance)
|
|
||||||
{
|
|
||||||
BindingFlags flags = declaredonly ? AccessTools.allDeclared : AccessTools.all;
|
|
||||||
|
|
||||||
PropertyInfo propertyInfo = type.GetProperty(propertyname, flags);
|
|
||||||
|
|
||||||
if (propertyInfo == null)
|
|
||||||
{
|
|
||||||
throw new Exception(propertyname + " is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
Init(propertyInfo, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyRef(Type type, string[] propertynames, bool declaredonly, object instance)
|
|
||||||
{
|
|
||||||
BindingFlags flags = declaredonly ? AccessTools.allDeclared : AccessTools.all;
|
|
||||||
|
|
||||||
PropertyInfo propertyInfo = propertyInfo = propertynames.Select(x => type.GetProperty(x, flags)).FirstOrDefault(x => x != null);
|
|
||||||
|
|
||||||
if (propertyInfo == null)
|
|
||||||
{
|
|
||||||
throw new Exception(propertynames.First() + " is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
Init(propertyInfo, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Init(PropertyInfo propertyinfo, object instance)
|
|
||||||
{
|
|
||||||
PropertyInfo = propertyinfo;
|
|
||||||
|
|
||||||
TType = PropertyInfo.DeclaringType;
|
|
||||||
|
|
||||||
Instance = (T)instance;
|
|
||||||
|
|
||||||
if (PropertyInfo.CanRead)
|
|
||||||
{
|
|
||||||
GetMethodInfo = PropertyInfo.GetGetMethod(true);
|
|
||||||
|
|
||||||
RefGetValue = ObjectMethodDelegate<Func<T, F>>(GetMethodInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PropertyInfo.CanWrite)
|
|
||||||
{
|
|
||||||
SetMethodInfo = PropertyInfo.GetSetMethod(true);
|
|
||||||
|
|
||||||
RefSetValue = ObjectMethodDelegate<Action<T, F>>(SetMethodInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PropertyRef<T, F> Create(PropertyInfo propertyinfo, object instance)
|
|
||||||
{
|
|
||||||
return new PropertyRef<T, F>(propertyinfo, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PropertyRef<T, F> Create(string propertyname, bool declaredonly = false, object instance = null)
|
|
||||||
{
|
|
||||||
return new PropertyRef<T, F>(typeof(T), propertyname, declaredonly, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PropertyRef<T, F> Create(string[] propertynames, bool declaredonly = false, object instance = null)
|
|
||||||
{
|
|
||||||
return new PropertyRef<T, F>(typeof(T), propertynames, declaredonly, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PropertyRef<T, F> Create(Type type, string propertyname, bool declaredonly = false, object instance = null)
|
|
||||||
{
|
|
||||||
return new PropertyRef<T, F>(type, propertyname, declaredonly, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PropertyRef<T, F> Create(Type type, string[] propertynames, bool declaredonly = false, object instance = null)
|
|
||||||
{
|
|
||||||
return new PropertyRef<T, F>(type, propertynames, declaredonly, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public F GetValue(T instance)
|
|
||||||
{
|
|
||||||
if (RefGetValue == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(RefGetValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instance != null && TType.IsAssignableFrom(instance.GetType()))
|
|
||||||
{
|
|
||||||
return RefGetValue(instance);
|
|
||||||
}
|
|
||||||
else if (Instance != null && instance == null)
|
|
||||||
{
|
|
||||||
return RefGetValue(Instance);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetValue(T instance, F value)
|
|
||||||
{
|
|
||||||
if (RefSetValue == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(RefSetValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instance != null && TType.IsAssignableFrom(instance.GetType()))
|
|
||||||
{
|
|
||||||
RefSetValue(instance, value);
|
|
||||||
}
|
|
||||||
else if (Instance != null && instance == null)
|
|
||||||
{
|
|
||||||
RefSetValue(Instance, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FieldRef<T, F> where T : class
|
|
||||||
{
|
|
||||||
private AccessTools.FieldRef<T, F> HarmonyFieldRef;
|
|
||||||
|
|
||||||
private FieldInfo FieldInfo;
|
|
||||||
|
|
||||||
private Type TType;
|
|
||||||
|
|
||||||
private T Instance;
|
|
||||||
|
|
||||||
public Type InType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return TType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type FieldType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return FieldInfo.FieldType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public FieldRef(FieldInfo fieldinfo, object instance)
|
|
||||||
{
|
|
||||||
if (fieldinfo == null)
|
|
||||||
{
|
|
||||||
throw new Exception("FieldInfo is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
Init(fieldinfo, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public FieldRef(Type type, string fieldname, bool declaredonly, object instance)
|
|
||||||
{
|
|
||||||
BindingFlags flags = declaredonly ? AccessTools.allDeclared : AccessTools.all;
|
|
||||||
|
|
||||||
FieldInfo fieldInfo = type.GetField(fieldname, flags);
|
|
||||||
|
|
||||||
if (fieldInfo == null)
|
|
||||||
{
|
|
||||||
throw new Exception(fieldname + " is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
Init(fieldInfo, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public FieldRef(Type type, string[] fieldnames, bool declaredonly, object instance)
|
|
||||||
{
|
|
||||||
BindingFlags flags = declaredonly ? AccessTools.allDeclared : AccessTools.all;
|
|
||||||
|
|
||||||
FieldInfo fieldInfo = fieldnames.Select(x => type.GetField(x, flags)).FirstOrDefault(x => x != null);
|
|
||||||
|
|
||||||
if (fieldInfo == null)
|
|
||||||
{
|
|
||||||
throw new Exception(fieldnames.First() + " is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
Init(fieldInfo, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FieldRef<T, F> Create(FieldInfo fieldinfo, object instance = null)
|
|
||||||
{
|
|
||||||
return new FieldRef<T, F>(fieldinfo, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FieldRef<T, F> Create(string fieldname, bool declaredonly = false, object instance = null)
|
|
||||||
{
|
|
||||||
return new FieldRef<T, F>(typeof(T), fieldname, declaredonly, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FieldRef<T, F> Create(string[] fieldnames, bool declaredonly = false, object instance = null)
|
|
||||||
{
|
|
||||||
return new FieldRef<T, F>(typeof(T), fieldnames, declaredonly, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FieldRef<T, F> Create(Type type, string fieldname, bool declaredonly = false, object instance = null)
|
|
||||||
{
|
|
||||||
return new FieldRef<T, F>(type, fieldname, declaredonly, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FieldRef<T, F> Create(Type type, string[] fieldnames, bool declaredonly = false, object instance = null)
|
|
||||||
{
|
|
||||||
return new FieldRef<T, F>(type, fieldnames, declaredonly, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Init(FieldInfo fieldinfo, object instance = null)
|
|
||||||
{
|
|
||||||
FieldInfo = fieldinfo;
|
|
||||||
|
|
||||||
TType = FieldInfo.DeclaringType;
|
|
||||||
|
|
||||||
Instance = (T)instance;
|
|
||||||
|
|
||||||
HarmonyFieldRef = AccessTools.FieldRefAccess<T, F>(FieldInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
public F GetValue(T instance)
|
|
||||||
{
|
|
||||||
if (HarmonyFieldRef == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(HarmonyFieldRef));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instance != null && TType.IsAssignableFrom(instance.GetType()))
|
|
||||||
{
|
|
||||||
return HarmonyFieldRef(instance);
|
|
||||||
}
|
|
||||||
else if (Instance != null && instance == null)
|
|
||||||
{
|
|
||||||
return HarmonyFieldRef(Instance);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetValue(T instance, F value)
|
|
||||||
{
|
|
||||||
if (HarmonyFieldRef == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(HarmonyFieldRef));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instance != null && TType.IsAssignableFrom(instance.GetType()))
|
|
||||||
{
|
|
||||||
HarmonyFieldRef(instance) = value;
|
|
||||||
}
|
|
||||||
else if (Instance != null && instance == null)
|
|
||||||
{
|
|
||||||
HarmonyFieldRef(Instance) = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Type GetEftType(Func<Type, bool> func)
|
|
||||||
{
|
|
||||||
return PatchConstants.EftTypes.Single(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MethodInfo GetEftMethod(Type type, BindingFlags flags, Func<MethodInfo, bool> func)
|
|
||||||
{
|
|
||||||
return type.GetMethods(flags).Single(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MethodInfo GetEftMethod(Func<Type, bool> func, BindingFlags flags, Func<MethodInfo, bool> func2)
|
|
||||||
{
|
|
||||||
return GetEftMethod(GetEftType(func), flags, func2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user