153 lines
3.3 KiB
C#
153 lines
3.3 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using GTA;
|
|||
|
using GTA.Native;
|
|||
|
using GTA.Math;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
using LemonUI.Elements;
|
|||
|
using System.Drawing;
|
|||
|
|
|||
|
namespace RageCoop.Client
|
|||
|
{
|
|||
|
[StructLayout(LayoutKind.Explicit, Size = 80)]
|
|||
|
public struct HeadBlendData
|
|||
|
{
|
|||
|
[FieldOffset(0)]
|
|||
|
public int ShapeFirst;
|
|||
|
|
|||
|
[FieldOffset(8)]
|
|||
|
public int ShapeSecond;
|
|||
|
|
|||
|
[FieldOffset(16)]
|
|||
|
public int ShapeThird;
|
|||
|
|
|||
|
[FieldOffset(24)]
|
|||
|
public int SkinFirst;
|
|||
|
|
|||
|
[FieldOffset(32)]
|
|||
|
public int SkinSecond;
|
|||
|
|
|||
|
[FieldOffset(40)]
|
|||
|
public int SkinThird;
|
|||
|
|
|||
|
[FieldOffset(48)]
|
|||
|
public float ShapeMix;
|
|||
|
|
|||
|
[FieldOffset(56)]
|
|||
|
public float SkinMix;
|
|||
|
|
|||
|
[FieldOffset(64)]
|
|||
|
public float ThirdMix;
|
|||
|
}
|
|||
|
|
|||
|
[StructLayout(LayoutKind.Explicit, Size = 24)]
|
|||
|
public struct NativeVector3
|
|||
|
{
|
|||
|
[FieldOffset(0)]
|
|||
|
public float X;
|
|||
|
|
|||
|
[FieldOffset(8)]
|
|||
|
public float Y;
|
|||
|
|
|||
|
[FieldOffset(16)]
|
|||
|
public float Z;
|
|||
|
|
|||
|
public static implicit operator Vector3(NativeVector3 vec)
|
|||
|
{
|
|||
|
return new Vector3() { X=vec.X, Y=vec.Y, Z=vec.Z };
|
|||
|
}
|
|||
|
public static implicit operator NativeVector3(Vector3 vec)
|
|||
|
{
|
|||
|
return new NativeVector3() { X=vec.X, Y=vec.Y, Z=vec.Z };
|
|||
|
}
|
|||
|
}
|
|||
|
public static class NativeCaller
|
|||
|
{
|
|||
|
// These are borrowed from ScriptHookVDotNet's
|
|||
|
[DllImport("ScriptHookV.dll", ExactSpelling = true, EntryPoint = "?nativeInit@@YAX_K@Z")]
|
|||
|
static extern void NativeInit(ulong hash);
|
|||
|
|
|||
|
[DllImport("ScriptHookV.dll", ExactSpelling = true, EntryPoint = "?nativePush64@@YAX_K@Z")]
|
|||
|
static extern void NativePush64(ulong val);
|
|||
|
|
|||
|
[DllImport("ScriptHookV.dll", ExactSpelling = true, EntryPoint = "?nativeCall@@YAPEA_KXZ")]
|
|||
|
static extern unsafe ulong* NativeCall();
|
|||
|
|
|||
|
// These are from ScriptHookV's nativeCaller.h
|
|||
|
static unsafe void NativePush<T>(T val) where T : unmanaged
|
|||
|
{
|
|||
|
ulong val64 = 0;
|
|||
|
*(T*)(&val64) = val;
|
|||
|
NativePush64(val64);
|
|||
|
}
|
|||
|
|
|||
|
public static unsafe R Invoke<R>(ulong hash) where R : unmanaged
|
|||
|
{
|
|||
|
NativeInit(hash);
|
|||
|
return *(R*)(NativeCall());
|
|||
|
}
|
|||
|
public static unsafe R Invoke<R>(Hash hash, params object[] args)
|
|||
|
where R : unmanaged
|
|||
|
{
|
|||
|
NativeInit((ulong)hash);
|
|||
|
var arguments=ConvertPrimitiveArguments(args);
|
|||
|
foreach (var arg in arguments)
|
|||
|
NativePush(arg);
|
|||
|
|
|||
|
return *(R*)(NativeCall());
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Helper function that converts an array of primitive values to a native stack.
|
|||
|
/// </summary>
|
|||
|
/// <param name="args"></param>
|
|||
|
/// <returns></returns>
|
|||
|
static unsafe ulong[] ConvertPrimitiveArguments(object[] args)
|
|||
|
{
|
|||
|
var result = new ulong[args.Length];
|
|||
|
for (int i = 0; i < args.Length; ++i)
|
|||
|
{
|
|||
|
if (args[i] is bool valueBool)
|
|||
|
{
|
|||
|
result[i] = valueBool ? 1ul : 0ul;
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (args[i] is byte valueByte)
|
|||
|
{
|
|||
|
result[i] = (ulong)valueByte;
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (args[i] is int valueInt32)
|
|||
|
{
|
|||
|
result[i] = (ulong)valueInt32;
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (args[i] is ulong valueUInt64)
|
|||
|
{
|
|||
|
result[i] = valueUInt64;
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (args[i] is float valueFloat)
|
|||
|
{
|
|||
|
result[i] = *(ulong*)&valueFloat;
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (args[i] is IntPtr valueIntPtr)
|
|||
|
{
|
|||
|
result[i] = (ulong)valueIntPtr.ToInt64();
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
throw new ArgumentException("Unknown primitive type in native argument list", nameof(args));
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|