Update
This commit is contained in:
parent
8ce38e51db
commit
e90a67a8d5
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.2.4.0")]
|
||||
[assembly: AssemblyFileVersion("1.2.4.0")]
|
||||
[assembly: AssemblyVersion("1.2.5.0")]
|
||||
[assembly: AssemblyFileVersion("1.2.5.0")]
|
||||
|
@ -82,6 +82,7 @@
|
||||
<Compile Include="Patches\PlayerModelViewPatch.cs" />
|
||||
<Compile Include="SkinHidePlugin.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Utils\RefHelp.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="kmyuhkyuk.pfx" />
|
||||
|
@ -1,26 +1,28 @@
|
||||
using BepInEx;
|
||||
using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using EFT;
|
||||
using EFT.Visual;
|
||||
using SkinHide.Patches;
|
||||
using SkinHide.Utils;
|
||||
|
||||
namespace SkinHide
|
||||
{
|
||||
[BepInPlugin("com.kmyuhkyuk.SkinHide", "kmyuhkyuk-SkinHide", "1.2.4")]
|
||||
[BepInPlugin("com.kmyuhkyuk.SkinHide", "kmyuhkyuk-SkinHide", "1.2.5")]
|
||||
public class SkinHidePlugin : BaseUnityPlugin
|
||||
{
|
||||
public static PlayerBody Player;
|
||||
internal static PlayerBody Player;
|
||||
|
||||
public static PlayerBody PlayerModelView;
|
||||
internal static PlayerBody PlayerModelView;
|
||||
|
||||
public static List <PlayerBody> Bot = new List<PlayerBody>();
|
||||
internal static List<PlayerBody> Bot = new List<PlayerBody>();
|
||||
|
||||
private SettingsData settingsdata = new SettingsData();
|
||||
|
||||
private ReflectionData reflectiondata = new ReflectionData();
|
||||
|
||||
public enum Part
|
||||
{
|
||||
All,
|
||||
@ -47,6 +49,10 @@ namespace SkinHide
|
||||
|
||||
new PlayerModelViewPatch().Enable();
|
||||
new PlayerPatch().Enable();
|
||||
|
||||
reflectiondata.RefSlotViews = RefHelp.FieldRef<PlayerBody, object>.Create("SlotViews");
|
||||
reflectiondata.RefSlotList = RefHelp.FieldRef<object, IEnumerable<object>>.Create(reflectiondata.RefSlotViews.FieldType, "list_0");
|
||||
reflectiondata.RefDresses = RefHelp.FieldRef<object, Dress[]>.Create(reflectiondata.RefSlotList.FieldType.GetGenericArguments()[0], "Dresses");
|
||||
}
|
||||
|
||||
void Update()
|
||||
@ -88,11 +94,11 @@ namespace SkinHide
|
||||
|
||||
void Hide(PlayerBody playerbody, Part part, bool hide)
|
||||
{
|
||||
object slotviews = Traverse.Create(playerbody).Field("SlotViews").GetValue<object>();
|
||||
object slotviews = reflectiondata.RefSlotViews.GetValue(playerbody);
|
||||
|
||||
IEnumerable<object> slotlist = (IEnumerable<object>)Traverse.Create(slotviews).Field("list_0").GetValue<object>();
|
||||
IEnumerable<object> slotlist = reflectiondata.RefSlotList.GetValue(slotviews);
|
||||
|
||||
Dress[] dresses = slotlist.Where(x => Traverse.Create(x).Field("Dresses").GetValue<Dress[]>() != null).SelectMany(x => Traverse.Create(x).Field("Dresses").GetValue<Dress[]>()).ToArray();
|
||||
Dress[] dresses = slotlist.Where(x => reflectiondata.RefDresses.GetValue(x) != null).SelectMany(x => reflectiondata.RefDresses.GetValue(x)).ToArray();
|
||||
|
||||
GameObject[] dress = dresses.Where(x => x.GetType() == typeof(Dress)).Select(x => x.gameObject).ToArray();
|
||||
|
||||
@ -139,5 +145,12 @@ namespace SkinHide
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
309
SkinHide/Utils/RefHelp.cs
Normal file
309
SkinHide/Utils/RefHelp.cs
Normal file
@ -0,0 +1,309 @@
|
||||
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 is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(method));
|
||||
}
|
||||
|
||||
var delegateType = typeof(DelegateType);
|
||||
|
||||
var declaringType = method.DeclaringType;
|
||||
|
||||
var DelegateParameters = delegateType.GetMethod("Invoke").GetParameters();
|
||||
var DelegateparameterTypes = DelegateParameters.Select(x => x.ParameterType).ToArray();
|
||||
|
||||
var dmd = new DynamicMethod("OpenInstanceDelegate_" + method.Name, method.ReturnType, DelegateparameterTypes);
|
||||
|
||||
var ilGen = dmd.GetILGenerator();
|
||||
|
||||
if (!method.IsStatic)
|
||||
{
|
||||
var parameters = method.GetParameters();
|
||||
var numParameters = parameters.Length;
|
||||
var parameterTypes = new Type[numParameters + 1];
|
||||
parameterTypes[0] = typeof(object);
|
||||
for (var 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);
|
||||
|
||||
for (var i = 1; i < parameterTypes.Length; i++)
|
||||
{
|
||||
ilGen.Emit(OpCodes.Ldarg, i);
|
||||
ilGen.Emit(OpCodes.Castclass, parameterTypes[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var parameterTypes = method.GetParameters().Select(x => x.ParameterType).ToArray();
|
||||
|
||||
for (var i = 0; i < parameterTypes.Length; i++)
|
||||
{
|
||||
ilGen.Emit(OpCodes.Ldarg, i);
|
||||
ilGen.Emit(OpCodes.Castclass, parameterTypes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (method.IsStatic || !virtualCall)
|
||||
{
|
||||
ilGen.Emit(OpCodes.Call, method);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilGen.Emit(OpCodes.Callvirt, method);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
public Type ReturnType;
|
||||
|
||||
public PropertyRef(PropertyInfo propertyinfo, object instance = null)
|
||||
{
|
||||
Init(propertyinfo, instance);
|
||||
}
|
||||
|
||||
public PropertyRef(Type type, string propertyname, object instance = null)
|
||||
{
|
||||
Init(type.GetProperty(propertyname, AccessTools.all), instance);
|
||||
}
|
||||
|
||||
private void Init(PropertyInfo propertyinfo, object instance)
|
||||
{
|
||||
PropertyInfo = propertyinfo;
|
||||
|
||||
TType = PropertyInfo.DeclaringType;
|
||||
|
||||
Instance = (T)instance;
|
||||
|
||||
GetMethodInfo = PropertyInfo.GetGetMethod(true);
|
||||
|
||||
if (GetMethodInfo != null)
|
||||
{
|
||||
RefGetValue = ObjectMethodDelegate<Func<T, F>>(GetMethodInfo);
|
||||
}
|
||||
|
||||
SetMethodInfo = PropertyInfo.GetSetMethod(true);
|
||||
|
||||
if (SetMethodInfo != null)
|
||||
{
|
||||
RefSetValue = ObjectMethodDelegate<Action<T, F>>(SetMethodInfo);
|
||||
}
|
||||
|
||||
if (GetMethodInfo != null && SetMethodInfo != null)
|
||||
{
|
||||
ReturnType = GetMethodInfo.ReturnType;
|
||||
}
|
||||
else if (GetMethodInfo != null || SetMethodInfo != null)
|
||||
{
|
||||
ReturnType = GetMethodInfo != null ? GetMethodInfo.ReturnType : SetMethodInfo.ReturnType;
|
||||
}
|
||||
}
|
||||
|
||||
public static PropertyRef<T, F> Create(PropertyInfo propertyinfo, object instance = null)
|
||||
{
|
||||
return new PropertyRef<T, F>(propertyinfo, instance);
|
||||
}
|
||||
|
||||
public static PropertyRef<T, F> Create(string propertyname, object instance = null)
|
||||
{
|
||||
return new PropertyRef<T, F>(typeof(T), propertyname, instance);
|
||||
}
|
||||
|
||||
public static PropertyRef<T, F> Create(Type type, string propertyname, object instance = null)
|
||||
{
|
||||
return new PropertyRef<T, F>(type, propertyname, 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(F);
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
{
|
||||
private AccessTools.FieldRef<T, F> HarmonyFieldRef;
|
||||
|
||||
private FieldInfo FieldInfo;
|
||||
|
||||
private Type TType;
|
||||
|
||||
private T Instance;
|
||||
|
||||
public Type InType;
|
||||
|
||||
public Type FieldType;
|
||||
|
||||
public FieldRef(FieldInfo fieldinfo, object instance = null)
|
||||
{
|
||||
Init(fieldinfo, instance);
|
||||
}
|
||||
|
||||
public FieldRef(Type type, string fieldname, object instance = null)
|
||||
{
|
||||
Init(type.GetField(fieldname, AccessTools.all), 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, object instance = null)
|
||||
{
|
||||
return new FieldRef<T, F>(typeof(T), fieldname, instance);
|
||||
}
|
||||
|
||||
public static FieldRef<T, F> Create(Type type, string fieldname, object instance = null)
|
||||
{
|
||||
return new FieldRef<T, F>(type, fieldname, instance);
|
||||
}
|
||||
|
||||
private void Init(FieldInfo fieldinfo, object instance = null)
|
||||
{
|
||||
FieldInfo = fieldinfo;
|
||||
|
||||
TType = FieldInfo.DeclaringType;
|
||||
|
||||
InType = TType;
|
||||
|
||||
FieldType = FieldInfo.FieldType;
|
||||
|
||||
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(F);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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