239 lines
7.2 KiB
C#
239 lines
7.2 KiB
C#
using Net.Helper;
|
|
using Net.Share;
|
|
using System;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Net.Common
|
|
{
|
|
/// <summary>
|
|
/// 属性观察接口
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public interface IPropertyObserver<T>
|
|
{
|
|
/// <summary>
|
|
/// 属性值
|
|
/// </summary>
|
|
T Value { get; set; }
|
|
/// <summary>
|
|
/// 当属性被修改事件
|
|
/// </summary>
|
|
Action<T> OnValueChanged { get; set; }
|
|
/// <summary>
|
|
/// 获取属性值
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
T GetValue();
|
|
/// <summary>
|
|
/// 设置属性值
|
|
/// </summary>
|
|
/// <param name="value">新的属性值</param>
|
|
/// <param name="isNotify">是否通知事件</param>
|
|
void SetValue(T value, bool isNotify = true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 属性观察类
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public class PropertyObserver<T> : IPropertyObserver<T>
|
|
{
|
|
protected T value;
|
|
public T Value { get => GetValue(); set => SetValue(value); }
|
|
public Action<T> OnValueChanged { get; set; }
|
|
public PropertyObserver() { }
|
|
public PropertyObserver(T value) : this(value, null) { }
|
|
public PropertyObserver(T value, Action<T> onValueChanged)
|
|
{
|
|
this.value = value;
|
|
OnValueChanged = onValueChanged;
|
|
}
|
|
|
|
public virtual T GetValue()
|
|
{
|
|
return value;
|
|
}
|
|
|
|
public virtual void SetValue(T value, bool isNotify = true)
|
|
{
|
|
if (Equals(this.value, value))
|
|
return;
|
|
this.value = value;
|
|
if (isNotify) OnValueChanged?.Invoke(value);
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"{Value}";
|
|
}
|
|
|
|
public static implicit operator PropertyObserver<T>(T value)
|
|
{
|
|
return new PropertyObserver<T>(value, null);
|
|
}
|
|
|
|
public static implicit operator T(PropertyObserver<T> value)
|
|
{
|
|
return value.Value;
|
|
}
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (obj is PropertyObserver<T> value)
|
|
return Equals(value);
|
|
return false;
|
|
}
|
|
|
|
public bool Equals(PropertyObserver<T> obj)
|
|
{
|
|
return Value.Equals(obj.Value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 模糊属性观察类, 此类只支持byte, sbyte, short, ushort, char, int, uint, float, long, ulong, double
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public class ObscuredPropertyObserver<T> : IPropertyObserver<T>
|
|
{
|
|
private string name;
|
|
private long valueAtk;
|
|
private long valueAtkKey;
|
|
private byte crcValue;
|
|
public T Value { get => GetValue(); set => SetValue(value); }
|
|
public Action<T> OnValueChanged { get; set; }
|
|
|
|
public ObscuredPropertyObserver(T value) : this(null, value) { }
|
|
public ObscuredPropertyObserver(string name, T value) : this(name, value, null) { }
|
|
public ObscuredPropertyObserver(string name, T value, Action<T> onValueChanged)
|
|
{
|
|
this.name = name;
|
|
valueAtkKey = RandomHelper.Range(0, int.MaxValue);
|
|
SetValue(value);
|
|
OnValueChanged = onValueChanged;
|
|
}
|
|
|
|
public unsafe T GetValue()
|
|
{
|
|
var value = valueAtk ^ valueAtkKey;
|
|
var ptr = (byte*)&value;
|
|
var crcIndex = (byte)(valueAtk % 247);
|
|
crcValue = Net.Helper.CRCHelper.CRC8(ptr, 0, 8, crcIndex);
|
|
if (this.crcValue != crcValue)
|
|
{
|
|
AntiCheatHelper.OnDetected?.Invoke(name, value, value);
|
|
return default;
|
|
}
|
|
var value1 = Unsafe.As<long, T>(ref value);
|
|
return value1;
|
|
}
|
|
|
|
public unsafe void SetValue(T value, bool isNotify = true)
|
|
{
|
|
var value1 = Unsafe.As<T, long>(ref value);
|
|
valueAtk = value1 ^ valueAtkKey;
|
|
var ptr = (byte*)&value1;
|
|
var crcIndex = (byte)(valueAtk % 247);
|
|
crcValue = Net.Helper.CRCHelper.CRC8(ptr, 0, 8, crcIndex);
|
|
if (isNotify) OnValueChanged?.Invoke(value);
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"{Value}";
|
|
}
|
|
|
|
public static implicit operator ObscuredPropertyObserver<T>(T value)
|
|
{
|
|
return new ObscuredPropertyObserver<T>(string.Empty, value, null);
|
|
}
|
|
|
|
public static implicit operator T(ObscuredPropertyObserver<T> value)
|
|
{
|
|
return value.Value;
|
|
}
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (obj is ObscuredPropertyObserver<T> value)
|
|
return Equals(value);
|
|
return false;
|
|
}
|
|
|
|
public bool Equals(ObscuredPropertyObserver<T> obj)
|
|
{
|
|
return Value.Equals(obj.Value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 属性观察自动类, 可模糊,不模糊
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public class PropertyObserverAuto<T> : IPropertyObserver<T>
|
|
{
|
|
private readonly bool available;
|
|
private IPropertyObserver<T> binding;
|
|
public T Value { get => GetValue(); set => SetValue(value); }
|
|
public Action<T> OnValueChanged { get => binding.OnValueChanged; set => binding.OnValueChanged = value; }
|
|
|
|
public PropertyObserverAuto() { }
|
|
/// <summary>
|
|
/// 属性观察自动类构造
|
|
/// </summary>
|
|
/// <param name="name">当属性被发现修改时提示名称</param>
|
|
/// <param name="available">使用模糊属性?</param>
|
|
/// <param name="onValueChanged">当属性被修改事件</param>
|
|
public PropertyObserverAuto(string name, bool available, Action<T> onValueChanged) : this(name, available, default, onValueChanged)
|
|
{
|
|
}
|
|
|
|
public PropertyObserverAuto(string name, bool available, T value, Action<T> onValueChanged)
|
|
{
|
|
this.available = available;
|
|
if (!AntiCheatHelper.IsActive | !available)
|
|
binding = new PropertyObserver<T>(value, onValueChanged);
|
|
else
|
|
binding = new ObscuredPropertyObserver<T>(name, value, onValueChanged);
|
|
}
|
|
|
|
public T GetValue()
|
|
{
|
|
return binding.GetValue();
|
|
}
|
|
|
|
public void SetValue(T value, bool isNotify = true)
|
|
{
|
|
binding.SetValue(value, isNotify);
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"{Value}";
|
|
}
|
|
|
|
public static implicit operator PropertyObserverAuto<T>(T value)
|
|
{
|
|
return new PropertyObserverAuto<T>(string.Empty, true, value, null);
|
|
}
|
|
|
|
public static implicit operator T(PropertyObserverAuto<T> value)
|
|
{
|
|
return value.Value;
|
|
}
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (obj is PropertyObserverAuto<T> value)
|
|
return Equals(value);
|
|
return false;
|
|
}
|
|
|
|
public bool Equals(PropertyObserverAuto<T> obj)
|
|
{
|
|
return Value.Equals(obj.Value);
|
|
}
|
|
}
|
|
}
|