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
|
||||
VisualStudioVersion = 17.1.32407.343
|
||||
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
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
@ -7,8 +7,8 @@
|
||||
<ProjectGuid>{E5DD6484-115E-4104-AADF-E5610EE4F397}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SkinHide</RootNamespace>
|
||||
<AssemblyName>SkinHide</AssemblyName>
|
||||
<RootNamespace>HideDress</RootNamespace>
|
||||
<AssemblyName>HideDress</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
@ -55,6 +55,12 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>R:\Battlestate Games\Client.0.12.12.15.17349\EscapeFromTarkov_Data\Managed\Comfort.dll</HintPath>
|
||||
</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="System" />
|
||||
<Reference Include="System.Core" />
|
||||
@ -78,11 +84,12 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Patches\PlayerPatch.cs" />
|
||||
<Compile Include="Patches\PlayerModelViewPatch.cs" />
|
||||
<Compile Include="SkinHidePlugin.cs" />
|
||||
<Compile Include="Models\ReflectionModel.cs" />
|
||||
<Compile Include="Models\SettingsModel.cs" />
|
||||
<Compile Include="Models\HideDressModel.cs" />
|
||||
<Compile Include="HideDressPlugin.cs" />
|
||||
<Compile Include="Patches\PlayerModelViewShow.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Utils\RefHelp.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<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.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("kmyuhkyuk-SkinHide")]
|
||||
[assembly: AssemblyTitle("kmyuhkyuk-HideDress")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("https://hub.sp-tarkov.com/files/file/583-skin-hide")]
|
||||
[assembly: AssemblyProduct("SkinHide")]
|
||||
[assembly: AssemblyProduct("HideDress")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2022")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
@ -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