分类
无聊代码

一些关于deceit有趣的信息

以前看主播玩的一个游戏 自己去玩 总是玩不过 嘿嘿
以下是我19年8月份左右吧 我也忘记了 搞定的一些数据 该游戏是CryEngine引擎上架Steam上的免费游戏 相对来说比较简单
** 这个游戏 是一个狼人杀的游戏 emmm 口才不好 骗不过其他人 只能这样了

**SDK初始化**
BOOL InitDeceitSdk(uintptr_t* ppRenderer, uintptr_t* ppIGameFramework, uintptr_t* ppIPhysicalWorld) {
    BOOL ret = TRUE;
    /*
    //pRenderer sign
    Deceit.exe + FD7B9 - 48 83 3D 6F81A401 00 - cmp qword ptr[Deceit.exe + 1B45930], 00 { (7FFC5BAD0280), 0 }
    Deceit.exe + FD7C1 - 0F84 72040000 - je Deceit.exe + FDC39
    Deceit.exe + FD7C7 - 48 89 B4 24 A8000000 - mov[rsp + 000000A8], rsi
    */
    // 48 83 3D ? ? ? ?  00 0F 84 ? ? ? ? 48 89 B4 24 ? ? ? ?
    uintptr_t pRenderer_sign = (uintptr_t)Utils::PatternScan(GetModuleHandleA(NULL), "48 83 3D ? ? ? ? 00 0F 84 ? ? ? ? 48 89 B4 24 ? ? ? ?");
    if (pRenderer_sign)
    {
        DWORD pRenderer_offset = *(DWORD*)(pRenderer_sign + 3);
        uintptr_t pRenderer = pRenderer_sign + pRenderer_offset + 8;
        *ppRenderer = pRenderer;
    }
    else {
        ret = FALSE;
    }
    /*
    pIGameFramework
Deceit.exe+26A4EC - 48 83 3D DCB38D01 00  - cmp qword ptr [Deceit.exe+1B458D0],00 { (7FF6740B7DE0),0 }
Deceit.exe+26A4F4 - 75 49                 - jne Deceit.exe+26A53F
Deceit.exe+26A4F6 - 4C 8D 44 24 20        - lea r8,[rsp+20]
Deceit.exe+26A4FB - 48 8D 15 16744901     - lea rdx,[Deceit.exe+1701918] { (1409970981) }
    */
    //48 83 3D ? ? ? ? 00 75 ? 4C 8D 44 24 ? 48 8D 15 ? ? ? ?

    uintptr_t pIGameFramework_sign = (uintptr_t)Utils::PatternScan(GetModuleHandleA(NULL), "48 83 3D ? ? ? ? 00 75 ? 4C 8D 44 24 ? 48 8D 15 ? ? ? ?");
    if (pIGameFramework_sign)
    {
        DWORD pIGameFramework_offset = *(DWORD*)(pIGameFramework_sign + 3);
        uintptr_t pIGameFramework = pIGameFramework_sign + pIGameFramework_offset + 8;
        *ppIGameFramework = pIGameFramework;
    }
    else {
        ret = FALSE;
    }
       /**
       IPhysicalWorld
        Deceit.exe + 14DC9C - 48 8B 0D CD7B9F01 - mov rcx, [Deceit.exe + 1B45870]{ (0) }
        Deceit.exe + 14DCA3 - 48 8D 55 88 - lea rdx, [rbp - 78]
        Deceit.exe + 14DCA7 - 48 8B 01 - mov rax, [rcx]
        Deceit.exe + 14DCAA - FF 50 40 - call qword ptr[rax + 40]
        Deceit.exe + 14DCAD - E9 C7060000 - jmp Deceit.exe + 14E379
        */
    //48 8B 0D ? ? ? ? 48 8D 55 88 48 8B 01 FF 50 ? E9 ? ? ? ?
    uintptr_t pIPhysicalWorld_sign = (uintptr_t)Utils::PatternScan(GetModuleHandleA(NULL), "48 8B 0D ? ? ? ? 48 8D 55 88 48 8B 01 FF 50 ? E9 ? ? ? ?");
    if (pIPhysicalWorld_sign)
    {
        DWORD pIPhysicalWorld_offset = *(DWORD*)(pIPhysicalWorld_sign + 3);
        uintptr_t pIPhysicalWorld = pIPhysicalWorld_sign + pIPhysicalWorld_offset + 7;
        *ppIPhysicalWorld = pIPhysicalWorld;
    }
    else {
        ret = FALSE;
    }
    /**
    Deceit.exe + 54096D - 48 8B 0D 844F6001 - mov rcx, [Deceit.exe + 1B458F8]{ (18AF49E1D20) }
        Deceit.exe + 540974 - 0F57 C0 - xorps xmm0, xmm0
        Deceit.exe + 540977 - 0F29 78 B8 - movaps[rax - 48], xmm7
        Deceit.exe + 54097B - 45 33 FF - xor r15d, r15d
        Deceit.exe + 54097E - 44 0F29 40 A8 - movaps[rax - 58], xmm8
        */
    //48 8B 0D ? ? ? ? 0F 57 C0 0F 29 78 B8 45 33 FF

    uintptr_t pCCamera_sign = (uintptr_t)Utils::PatternScan(GetModuleHandleA(NULL), "48 8B 0D ? ? ? ? 0F 57 C0 0F 29 78 B8 45 33 FF");
    if (pCCamera_sign)
    {
        DWORD pCCamera_offset = *(DWORD*)(pCCamera_sign + 3);
        uintptr_t pCCamera = pCCamera_sign + pCCamera_offset + 7;
        g_CCamera = *(CCamera**)pCCamera;
    }
    else {
        ret = FALSE;
    }
    /**
        Deceit.exe + 298C70 - F3 0F10 05 1CF48A01 - movss xmm0, [Deceit.exe + 1B48094]{ (-0.04) }
        Deceit.exe + 298C78 - 89 05 CA469401 - mov[Deceit.exe + 1BDD348], eax{ (0) }
        Deceit.exe + 298C7E - 8B 44 24 74 - mov eax, [rsp + 74]
        Deceit.exe + 298C82 - 89 05 80479401 - mov[Deceit.exe + 1BDD408], eax{ (0) }
        Deceit.exe + 298C88 - 44 89 3D F9429401 - mov[Deceit.exe + 1BDCF88], r15d{ (0) }
        Deceit.exe + 298C8F - 44 89 3D F6429401 - mov[Deceit.exe + 1BDCF8C], r15d{ (0) }
        Deceit.exe + 298C96 - 44 89 3D F7429401 - mov[Deceit.exe + 1BDCF94], r15d{ (0) }
        Deceit.exe + 298C9D - 0F14 C1 - unpcklps xmm0, xmm1
*/
    //  F3 0F 10 05 ? ? ? ? 89 05 ? ? ? ? 8B 44 24 ?
    uintptr_t pGetViewdir_sign = (uintptr_t)Utils::PatternScan(GetModuleHandleA(NULL), "48 8B 0D ? ? ? ? 0F 57 C0 0F 29 78 B8 45 33 FF");
    if (pGetViewdir_sign)
    {
        DWORD pGetViewdir_offset = *(DWORD*)(pCCamera_sign + 3);
        uintptr_t pGetViewdir = pGetViewdir_sign + pGetViewdir_offset + 7;
        g_GetViewdir = (Vec3*)pGetViewdir;
        g_GetFov = (float*)(g_GetViewdir + 0x2C);
    }
    else {
        ret = FALSE;
    }

    return ret;
}
BOOL InitSreachGameOverlay(uintptr_t** pSteamGameOverlay) {
    BOOL ret = TRUE;
    /*gameoverlayrenderer64.dll + 8B79D - FF 15 3D6C0D00 - call qword ptr[gameoverlayrenderer64.dll + 1623E0]{ ->7FFCC6BA03C0 }
    gameoverlayrenderer64.dll + 8B7A3 - 8B F0 - mov esi, eax
    gameoverlayrenderer64.dll + 8B7A5 - 48 85 FF - test rdi, rdi
    gameoverlayrenderer64.dll + 8B7A8 - 74 2A - je gameoverlayrenderer64.dll + 8B7D4
    gameoverlayrenderer64.dll + 8B7AA - 48 8B 97 38010000 - mov rdx, [rdi + 00000138]
    gameoverlayrenderer64.dll+8B7B1 - 48 85 D2              - test rdx,rdx
    */
    // FF 15 ? ? ? ? 8B F0 48 85 FF 74 ? 48 8B 97 ? ? ? ? 48 85 D2  
    uintptr_t gameoverlayrenderer64_sign = (uintptr_t)Utils::PatternScan(GetModuleHandleA("gameoverlayrenderer64.dll"), "FF 15 ? ? ? ? 8B F0 48 85 FF 74 ? 48 8B 97 ? ? ? ? 48 85 D2", 2);
    if (gameoverlayrenderer64_sign)
    {
        DWORD gameoverlayrenderer64_offset = *(DWORD*)(gameoverlayrenderer64_sign + 2);
        uintptr_t* pPresent = (uintptr_t*)(gameoverlayrenderer64_sign + gameoverlayrenderer64_offset + 6);
        *pSteamGameOverlay = pPresent;
    }
    else {
        ret = FALSE;
    }
    return ret;
}
**SDK.HPP**
#include "windows.h"
#include <assert.h> 
#include <math.h>
class IItem;
enum eItemBackAttachment
{
    eIBA_Primary = 0,
    eIBA_Secondary,
    eIBA_Unknown
};

enum eItemHand
{
    eIH_Right = 0, // indicates the right hand of the actor
    eIH_Left,      // indicates the left hand of the actor
    eIH_Last,
};
enum Bone{
    Bip01,
    Bip01_Pelvis,
    u_T_SH_SpineBase01J,
    Bip01_LookTarget,
    Bip01_AimTarget,
    Bip01_IndiHips,
    Bip01_Spine,
    Bip01_RHand2LPocket_IKTarget,
    Bip01_RHand2LPocket_IKBlend,
    Bip01_Spine1,
    Bip01_Neck,
    Bip01_L_Clavicle,
    Bip01_R_Clavicle,
    Bip01_Head,
    u_Jaw_14,
    Bip01_Camera,
    eye_left_bone,
    eye_right_bone,
    u_r_eyebrow_3_jnt,
    u_r_eyebrow_2_jnt,
    u_r_eyebrow_1_jnt,
    u_l_eyebrow_1_jnt,
    u_l_eyebrow_2_jnt,
    u_l_eyebrow_3_jnt,
    u_c_lip_top_mid_root_jnt,
    u_c_lip_bottom_mid_root_jnt,
    u_l_lip_corner_root_jnt,
    u_r_lip_corner_root_jnt,
    u_l_lip_top_slope_root_jnt,
    u_l_lip_bottom_slope_root_jnt,
    u_r_lip_top_slope_root_jnt,
    u_r_lip_bottom_slope_root_jnt,
    u_r_cheek_jnt,
    u_l_cheek_jnt,
    u_r_cheekbone_jnt,
    u_l_cheekbone_jnt,
    u_r_nostril_jnt,
    u_l_nostril_jnt,
    Bip01_Look,
    u_l_eyelid_top_b_jnt,
    u_l_eyelid_top_a_jnt ,
    u_l_eyelid_top_c_jnt ,
    u_l_eyelid_bottom_b_jnt ,
    u_l_eyelid_bottom_a_jnt ,
    u_l_eyelid_bottom_c_jnt ,
    u_r_eyelid_top_c_jnt ,
    u_r_eyelid_top_a_jnt ,
    u_r_eyelid_top_b_jnt ,
    u_r_eyelid_bottom_c_jnt ,
    u_r_eyelid_bottom_a_jnt ,
    u_r_eyelid_bottom_b_jnt ,
    Bip01_HUD,
    u_c_lip_top_mid_jnt ,
    u_c_lip_top_mid_bound_jnt ,
    u_c_lip_bottom_mid_jnt ,
    u_c_lip_bottom_mid_bound_jnt ,
    u_l_lip_corner_jnt, 
    u_l_lip_corner_bound_jnt ,
    u_r_lip_corner_jnt ,
    u_r_lip_corner_bound_jnt ,
    u_l_lip_top_slope_jnt ,
    u_l_lip_top_slope_bound_jnt ,
    u_l_lip_bottom_slope_jnt ,
    u_l_lip_bottom_slope_bound_jnt ,
    u_r_lip_top_slope_jnt ,
    u_r_lip_top_slope_bound_jnt ,
    u_r_lip_bottom_slope_jnt ,
    u_r_lip_bottom_slope_bound_jnt ,
    u_l_eyelid_top_b_end_jnt ,
    u_l_eyelid_top_a_end_jnt ,
    u_l_eyelid_top_c_end_jnt ,
    u_l_eyelid_bottom_b_end_jnt ,
    u_l_eyelid_bottom_a_end_jnt ,
    u_l_eyelid_bottom_c_end_jnt ,
    u_r_eyelid_top_c_end_jnt ,
    u_r_eyelid_top_a_end_jnt ,
    u_r_eyelid_top_b_end_jnt ,
    u_r_eyelid_bottom_c_end_jnt ,
    u_r_eyelid_bottom_a_end_jnt ,
    u_r_eyelid_bottom_b_end_jnt ,
    Bip01_L_UpperArm ,
    Bip01_L_Forearm ,
    Bip01_L_UpperTwist ,
    Bip01_L_UpperTwist1 ,
    Bip01_L_UpperTwist2 ,
    Bip01_L_ForeTwist ,
    Bip01_L_ForeTwist1 ,
    Bip01_L_ForeTwist2 ,
    Bip01_L_Hand ,
    Bip01_L_Finger0 ,
    Bip01_L_Finger1 ,
    Bip01_L_Finger2 ,
    Bip01_L_Finger3 ,
    Bip01_L_Finger4 ,
    Lweapon_bone ,
    Bip01_L_Finger01 ,
    Bip01_L_Finger02 ,
    Bip01_L_Finger11 ,
    Bip01_L_Finger12 ,
    Bip01_L_Finger21 ,
    Bip01_L_Finger22 ,
    Bip01_L_Finger31 ,
    Bip01_L_Finger32 ,
    Bip01_L_Finger41 ,
    Bip01_L_Finger42 ,
    Bip01_R_UpperArm ,
    Bip01_R_Forearm ,
    Bip01_R_UpperTwist ,
    Bip01_R_UpperTwist1 ,
    Bip01_R_UpperTwist2 ,
    Bip01_R_ForeTwist ,
    Bip01_R_ForeTwist1 ,
    Bip01_R_ForeTwist2 ,
    Bip01_R_Hand ,
    Bip01_R_Finger0 ,
    Bip01_R_Finger1 ,
    Bip01_R_Finger2 ,
    Bip01_R_Finger3 ,
    Bip01_R_Finger4 ,
    Rweapon_bone,
    Bip01_R_Finger01,
    Bip01_R_Finger02 ,
    Bip01_R_Finger11 ,
    Bip01_R_Finger12 ,
    Bip01_R_Finger21 ,
    Bip01_R_Finger22 ,
    Bip01_R_Finger31 ,
    Bip01_R_Finger32 ,
    Bip01_R_Finger41 ,
    Bip01_R_Finger42 ,
    Rweapon_IKTarget ,
    Rweapon_IKBlend ,
    Bip01_R_Thigh ,
    Bip01_L_Thigh ,
    Bip01_R_ThighCorrect ,
    Bip01_L_ThighCorrect ,
    Bip01_L_ButtCorrect ,
    Bip01_R_ButtCorrect ,
    Bip01_R_Calf ,
    Bip01_R_Foot ,
    Bip01_planeTargetRight ,
    Bip01_planeWeightRight ,
    Bip01_R_Toe0 ,
    Bip01_R_Heel ,
    Bip01_L_Calf ,
    Bip01_L_Foot ,
    Bip01_planeTargetLeft ,
    Bip01_planeWeightLeft ,
    Bip01_L_Toe0 ,
    Bip01_L_Heel ,
    Bip01_L_ButtCorrectNub ,
    Bip01_R_ButtCorrectNub ,
};

#define min(a,b)            (((a) < (b)) ? (a) : (b))
#define M_PI 3.14159265358979323846
#define M_TPI 6.2831853071795864744
#define M_RADPI 57.295779513082
#define COLLISION_RAY_PIERCABILITY 10
#define RWI_RAY_PIERCABILITY_MASK  0x0F
#define BONE_ATTACH_ENTITY_LINK_PREFIX "@"
#define ENTITY_LINK_NAME_MAX_LENGTH 31
#define Pi 3.1415926535
#define M_PI        3.14159265358979323846  // matches value in gcc v2 math.h
#define M_PI_F      ((float)(M_PI)) // Shouldn't collide with anything.
#define M_PHI       1.61803398874989484820 // golden ratio
#define RAD2DEG( x  )  ( (float)(x) * (float)(180.f / M_PI_F) )
#define DEG2RAD( x  )  ( (float)(x) * (float)(M_PI_F / 180.f) )
typedef unsigned int EntityId;
struct Matrix33;

float clamp(float X, float Min, float Max)
{
    X = (X + Max - fabsf(X - Max))*0.5f;
    X = (X + Min + fabsf(X - Min))*0.5f;

    return X;
}

int FloatU32(const float x)
{
    union { int ui; float f; } cvt;
    cvt.f = x;

    return cvt.ui;
}

#define FloatU32ExpMask (0xFF << 23)

bool NumberValid(const float& x)
{
    int i = FloatU32(x);
    int expmask = FloatU32ExpMask;
    int iexp = i & expmask;
    bool invalid = (iexp == expmask);

    if (invalid)
    {
        int i = 0x7F800001;
        float fpe = *(float*)(&i);
    }

    return !invalid;
}

float isqrt_tpl(float op) { return 1.0f / sqrt(op); }
float fabs_tpl(float op) { return fabs(op); }
void cry_sincos(float angle, float* pSin, float* pCos) { *pSin = (sin(angle));  *pCos = (cos(angle)); }
void sincos(float angle, float* pSin, float* pCos) { cry_sincos(angle, pSin, pCos); }
float isqrt_safe_tpl(float op) { return 1.0f / sqrt(op + (float)DBL_MIN); }

float asin_tpl(float op) { return asin(clamp(op, -1.0f, +1.0f)); }
float g_PI = 3.14159265358979323846264338327950288419716939937510f;
float atan2_tpl(float op1, float op2) { return atan2(op1, op2); }
typedef LRESULT(__fastcall* pfnWndProc)(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
typedef long(__fastcall* pfn_Present)(IDXGISwapChain* p_swapchain, unsigned int syncintreval, unsigned int flags);
#define BIT32(x)       (1u << (x))
struct Vec3
{
    float x;
    float y;
    float z;

    bool IsValid() const
    {
        if (!NumberValid(x)) return false;
        if (!NumberValid(y)) return false;
        if (!NumberValid(z)) return false;

        return true;
    }

    float GetLengthSquared() const { return x * x + y * y + z * z; }

    bool IsUnit(float epsilon = 0.05f) const
    {
        return (fabs_tpl(1 - GetLengthSquared()) <= epsilon);
    }

    Vec3 GetNormalized() const
    {
        float fInvLen = isqrt_safe_tpl(x * x + y * y + z * z);

        Vec3 out = *this;
        out.x *= fInvLen;
        out.y *= fInvLen;
        out.z *= fInvLen;
        return out;
    }

    Vec3 GetNormalizedSafe(const struct Vec3& safe) const
    {
        float fLen2 = x * x + y * y + z * z;

        if (fLen2 > 0.0f)
        {
            float fInvLen = isqrt_tpl(fLen2);
            Vec3 out;
            out.x = safe.x * fInvLen;
            out.y = safe.y * fInvLen;
            out.z = safe.z * fInvLen;
            return out;

        }
        else
        {
            return safe;
        }
    }

    void Normalize()
    {
        assert(this->IsValid());
        float fInvLen = isqrt_safe_tpl(x * x + y * y + z * z);
        x *= fInvLen; y *= fInvLen; z *= fInvLen;
    }

    void Set(float xval, float yval, float zval)
    {
        x = xval;
        y = yval;
        z = zval;
    }

    Vec3& normalize()
    {
        float len2 = x * x + y * y + z * z;
#if defined(XENON) || (defined(PS3) && !defined(__SPU__))
        const F rlen = isqrt_tpl(len2 + 1E-20f);
        x *= rlen; y *= rlen; z *= rlen;
        const F cRev = -len2;
        x = (F)__fsel(cRev, (F)0.f, x);
        y = (F)__fsel(cRev, (F)0.f, y);
        z = (F)__fsel(cRev, (F)1.f, z);
#else
        if (len2 > 1e-20f)
        {
            float rlen = isqrt_tpl(len2);
            x *= rlen; y *= rlen; z *= rlen;
        }
        else
            Set(0, 0, 1);
#endif
        return *this;

    }

    float Dot(const Vec3& vec1, const Vec3& vec2)
    {
        return vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z;
    }

    float Dot(const Vec3& vec) const
    {
        return x * vec.x + y * vec.y + z * vec.z;
    }

    Vec3 operator+(const Vec3& vector) const
    {
        return Vec3{ x + vector.x, y + vector.y, z + vector.z };
    }

    void operator+=(const Vec3& vector)
    {
        x += vector.x;
        y += vector.y;
        z += vector.z;
    }

    Vec3 operator-(const Vec3& vector) const
    {
        return Vec3{ x - vector.x, y - vector.y, z - vector.z };
    }

    void operator-=(const Vec3& vector)
    {
        x -= vector.x;
        y -= vector.y;
        z -= vector.z;
    }

    Vec3 operator*(const Vec3& vector) const
    {
        return Vec3{ x * vector.x, y * vector.y, z * vector.z };
    }

    void operator*=(const float& value)
    {
        x *= value;
        y *= value;
        z *= value;
    }

    Vec3 operator/(const float& value) const
    {
        return Vec3{ x / value, y / value, z / value };
    }

    void operator/=(const float& value)
    {
        x /= value;
        y /= value;
        z /= value;
    }
};

struct Vec3Constants
{
    static const Vec3 fVec3_Zero;
    static const Vec3 fVec3_OneX;
};

struct Matrix33
{
    float m00, m01, m02;
    float m10, m11, m12;
    float m20, m21, m22;

    bool IsValid() const
    {
        if (!NumberValid(m00)) return false;
        if (!NumberValid(m01)) return false;
        if (!NumberValid(m02)) return false;

        if (!NumberValid(m10)) return false;
        if (!NumberValid(m11)) return false;
        if (!NumberValid(m12)) return false;

        if (!NumberValid(m20)) return false;
        if (!NumberValid(m21)) return false;
        if (!NumberValid(m22)) return false;

        return true;
    }

    void SetRotationVDir(const Vec3& vdir)
    {
        m00 = 1;
        m01 = 0;
        m02 = 0;

        m10 = 0;
        m11 = 0;
        m12 = -vdir.z;

        m20 = 0;
        m21 = vdir.z;
        m22 = 0;

        float l = sqrt(vdir.x * vdir.x + vdir.y * vdir.y);

        if (l > 0.0001)
        {
            float xl = -vdir.x / l; float yl = vdir.y / l;

            m00 = (yl);
            m01 = (vdir.x);
            m02 = (xl * vdir.z);

            m10 = (xl);
            m11 = (vdir.y);
            m12 = (-vdir.z * yl);

            m20 = 0;
            m21 = (vdir.z);
            m22 = (l);
        }
    }

    Matrix33(const Vec3& vx, const Vec3& vy, const Vec3& vz)
    {
        m00 = (vx.x);
        m01 = (vy.x);
        m02 = (vz.x);

        m10 = (vx.y);
        m11 = (vy.y);
        m12 = (vz.y);

        m20 = (vx.z);
        m21 = (vy.z);
        m22 = (vz.z);
    }

};
struct Ang3
{
    float x;
    float y;
    float z;

    void Set(float xval, float yval, float zval) { x = xval; y = yval; z = zval; }
    void operator () (float vx, float vy, float vz) { x = vx; y = vy; z = vz; };

    Ang3(const Matrix33& m)
    {
        y = asin_tpl(max(-1.0f, min(1.0f, -m.m20)));
        if (fabs_tpl(fabs_tpl(y) - (g_PI * 0.5f)) < 0.01f)
        {
            x = 0;
            z = atan2_tpl(-m.m01, m.m11);
        }
        else {
            x = atan2_tpl(m.m21, m.m22);
            z = atan2_tpl(m.m10, m.m00);
        }
    }

    bool IsValid() const
    {
        if (!NumberValid(x)) return false;
        if (!NumberValid(y)) return false;
        if (!NumberValid(z)) return false;

        return true;
    }
};

class Quat
{
public:
    Vec3 v;
    float w;

    bool IsValid() const
    {
        if (!NumberValid(v.x)) return false;
        if (!NumberValid(v.y)) return false;
        if (!NumberValid(v.z)) return false;
        if (!NumberValid(w)) return false;

        return true;
    }

    friend float operator | (const Quat& q, const Quat& p)
    {
        assert(q.v.IsValid());
        assert(p.v.IsValid());
        return (q.v.x * p.v.x + q.v.y * p.v.y + q.v.z * p.v.z + q.w * p.w);
    }

    friend Quat operator - (const Quat& q, const Quat& p)
    {
        Quat ret;
        ret.w = q.w - p.w;

        ret.v.x = q.v.x - p.v.x;
        ret.v.y = q.v.y - p.v.y;
        ret.v.z = q.v.z - p.v.z;

        return ret;
    }

    void Normalize(void)
    {
        float d = isqrt_tpl(w * w + v.x * v.x + v.y * v.y + v.z * v.z);

        w *= d;

        v.x *= d;
        v.y *= d;
        v.z *= d;
    }

    void SetNlerp(const Quat& p, const Quat& tq, float t)
    {
        Quat q = tq;

        assert(p.IsValid());
        assert(q.IsValid());

        if ((p | q) < 0)
        {
            float qx = -q.v.x;
            float qy = -q.v.y;
            float qz = -q.v.z;

            q.v.x = qx;
            q.v.y = qy;
            q.v.z = qz;
        }

        v.x = p.v.x * (1.0f - t) + q.v.x * t;
        v.y = p.v.y * (1.0f - t) + q.v.y * t;
        v.z = p.v.z * (1.0f - t) + q.v.z * t;

        w = p.w * (1.0f - t) + q.w * t;

        Normalize();
    }

    void SetSlerp(const Quat& tp, const Quat& tq, float t)
    {
        assert(tp.IsValid());

        Quat p, q;
        p = tp;
        q = tq;
        Quat q2;

        float cosine = (p | q);

        if (cosine < 0.0f)
        {
            float qx = -q.v.x;
            float qy = -q.v.y;
            float qz = -q.v.z;

            cosine = -cosine;

            q.v.x = qx;
            q.v.y = qy;
            q.v.z = qz;
        }

        if (cosine > 0.9999f)
        {
            SetNlerp(p, q, t);
            return;
        }

        q2.w = q.w - p.w * cosine;
        q2.v.x = q.v.x - p.v.x * cosine;
        q2.v.y = q.v.y - p.v.y * cosine;
        q2.v.z = q.v.z - p.v.z * cosine;

        float sine = sqrt(q2 | q2);
        float s, c;

        sincos(atan2(sine, cosine) * t, &s, &c);

        w = (p.w * c + q2.w * s / sine);
        v.x = (p.v.x * c + q2.v.x * s / sine);
        v.y = (p.v.y * c + q2.v.y * s / sine);
        v.z = (p.v.z * c + q2.v.z * s / sine);
    }

    static Quat CreateSlerp(const Quat& p, const Quat& tq, float t)
    {
        Quat d;
        d.SetSlerp(p, tq, t);
        return d;
    }

    Quat(const Matrix33& m)
    {
        float s, p, tr = m.m00 + m.m11 + m.m22;
        w = 1, v.x = 0, v.y = 0, v.z = 0;

        if (tr > 0)
            s = sqrt(tr + 1.0f), p = 0.5f / s, w = s * 0.5f, v.x = (m.m21 - m.m12) * p, v.y = (m.m02 - m.m20) * p, v.z = (m.m10 - m.m01) * p;
        else if ((m.m00 >= m.m11) && (m.m00 >= m.m22))
            s = sqrt(m.m00 - m.m11 - m.m22 + 1.0f), p = 0.5f / s, w = (m.m21 - m.m12) * p, v.x = s * 0.5f, v.y = (m.m10 + m.m01) * p, v.z = (m.m20 + m.m02) * p;
        else if ((m.m11 >= m.m00) && (m.m11 >= m.m22))
            s = sqrt(m.m11 - m.m22 - m.m00 + 1.0f), p = 0.5f / s, w = (m.m02 - m.m20) * p, v.x = (m.m01 + m.m10) * p, v.y = s * 0.5f, v.z = (m.m21 + m.m12) * p;
        else if ((m.m22 >= m.m00) && (m.m22 >= m.m11))
            s = sqrt(m.m22 - m.m00 - m.m11 + 1.0f), p = 0.5f / s, w = (m.m10 - m.m01) * p, v.x = (m.m02 + m.m20) * p, v.y = (m.m12 + m.m21) * p, v.z = s * 0.5f;
    }

    void SetRotationVDir(const Vec3& vdir)
    {
        w = (0.70710676908493042f);
        v.x = (vdir.z * 0.70710676908493042f);
        v.y = (0.0f);
        v.z = (0.0f);

        float l = sqrt(vdir.x * vdir.x + vdir.y * vdir.y);

        if (l > (0.00001))
        {
            Vec3 hv;

            hv.x = vdir.x / l;
            hv.y = vdir.y / l + 1.0f;
            hv.z = l + 1.0f;

            float r = sqrt(hv.x * hv.x + hv.y * hv.y);
            float s = sqrt(hv.z * hv.z + vdir.z * vdir.z);
            float hacos0 = 0.0;
            float hasin0 = -1.0;

            if (r > (0.00001)) { hacos0 = hv.y / r; hasin0 = -hv.x / r; }

            float hacos1 = hv.z / s;
            float hasin1 = vdir.z / s;

            w = (hacos0 * hacos1);
            v.x = (hacos0 * hasin1);
            v.y = (hasin0 * hasin1);
            v.z = (hasin0 * hacos1);
        }
    }

    static Quat CreateRotationVDir(const Vec3& vdir) { Quat q; q.SetRotationVDir(vdir); return q; }
    Quat CreateRotationVDir_(const Vec3& vdir, float roll) { Quat q; q.SetRotationVDir_2(vdir, roll); return q; }

    void SetRotationVDir_2(const Vec3& vdir, float r)
    {
        SetRotationVDir(vdir);
        float sy, cy;  sincos(r * 0.5f, &sy, &cy);
        float vx = v.x, vy = v.y;
        v.x = (vx * cy - v.z * sy); v.y = (w * sy + vy * cy); v.z = (v.z * cy + vx * sy); w = (w * cy - vy * sy);
    }

    Quat CreateRotationXYZ(const Ang3& a)
    {
        assert(a.IsValid());
        Quat q;
        q.SetRotationXYZ(a);

        return q;
    }

    void SetRotationXYZ(const Ang3& a)
    {
        assert(a.IsValid());
        float sx, cx;  sincos((a.x * 0.5f), &sx, &cx);
        float sy, cy;  sincos((a.y * 0.5f), &sy, &cy);
        float sz, cz;  sincos((a.z * 0.5f), &sz, &cz);
        w = cx * cy * cz + sx * sy * sz;
        v.x = cz * cy * sx - sz * sy * cx;
        v.y = cz * sy * cx + sz * cy * sx;
        v.z = sz * cy * cx - cz * sy * sx;
    }

    void SetRotationZ(float r)
    {
        float s, c;
        sincos((r * 0.5f), &s, &c);
        w = c;
        v.x = 0;
        v.y = 0;
        v.z = s;
    }

    Quat CreateRotationZ(float r)
    {
        Quat q;
        q.SetRotationZ(r);
        return q;
    }

    Quat() {}
};

class QuatT
{
public:
    Quat q;
    Vec3 t;

    bool IsValid() const
    {
        if (!t.IsValid()) return false;
        if (!q.IsValid()) return false;
        return true;
    }

    QuatT() {}
};

struct Matrix34
{
    float m00, m01, m02, m03;
    float m10, m11, m12, m13;
    float m20, m21, m22, m23;

    Matrix34() {}

    Vec3 GetTranslation() { Vec3 mf; mf.x = m03; mf.y = m13; mf.z = m23; return Vec3(mf); }

    void SetTranslation(Vec3 Vector) { m03 = Vector.x; m13 = Vector.y; m23 = Vector.z; }

    Matrix34(const QuatT& q)
    {
        assert(q.q.IsValid());

        Vec3 v2 = { 0, 0, 0 };
        v2.x = (q.q.v.x) + (q.q.v.x);

        float xx = 1 - v2.x * q.q.v.x; float yy = v2.y * q.q.v.y; float xw = v2.x * q.q.w;
        float xy = v2.y * q.q.v.x;   float yz = v2.z * q.q.v.y; float  yw = v2.y * q.q.w;
        float xz = v2.z * q.q.v.x;   float zz = v2.z * q.q.v.z; float  zw = v2.z * q.q.w;

        m00 = float(1 - yy - zz);     m01 = float(xy - zw);     m02 = float(xz + yw);   m03 = float(q.t.x);
        m10 = float(xy + zw);      m11 = float(xx - zz);     m12 = float(yz - xw);   m13 = float(q.t.y);
        m20 = float(xz - yw);      m21 = float(yz + xw);     m22 = float(xx - yy);   m23 = float(q.t.z);
    }

    void SetTranslationAndRotation(Vec3 Pos, const Vec3& Rotation)
    {
        float sinX = sin(Rotation.x);
        float cosX = cos(Rotation.x);
        float sinY = sin(Rotation.y);
        float cosY = cos(Rotation.y);
        float sinZ = sin(Rotation.z);
        float cosZ = cos(Rotation.z);

        m00 = cosY * cosZ;
        m01 = sinX * sinY * cosZ - cosX * sinZ;
        m02 = cosX * sinY * cosZ + sinX * sinZ;
        m03 = Pos.x;

        m10 = cosY * sinZ;
        m11 = sinX * sinY * sinZ + cosX * cosZ;
        m12 = cosX * sinY * sinZ - sinX * cosZ;
        m13 = Pos.y;

        m20 = -sinY;
        m21 = sinX * cosY;
        m22 = cosX * cosY;
        m23 = Pos.z;
    }

    void SetRotationXYZ(const Vec3& radian)
    {
        float sinX = sin(radian.x);
        float cosX = cos(radian.x);
        float sinY = sin(radian.y);
        float cosY = cos(radian.y);
        float sinZ = sin(radian.z);
        float cosZ = cos(radian.z);

        m00 = cosY * cosZ;
        m01 = sinX * sinY * cosZ - cosX * sinZ;
        m02 = cosX * sinY * cosZ + sinX * sinZ;
        m03 = 0.f;

        m10 = cosY * sinZ;
        m11 = sinX * sinY * sinZ + cosX * cosZ;
        m12 = cosX * sinY * sinZ - sinX * cosZ;
        m13 = 0.f;

        m20 = -sinY;
        m21 = sinX * cosY;
        m22 = cosX * cosY;
        m23 = 0.f;
    }

    bool GetRotationXYZ(Vec3* radian)
    {
        float yRadian = asin(-m20);
        radian->y = yRadian;

        if (yRadian < (D3DX_PI / 2))
        {
            if (yRadian > -(D3DX_PI / 2))
            {
                radian->x = atan2(m21, m22);
                radian->z = atan2(m10, m00);
                return true;
            }
            else
            {
                radian->x = -atan2(m01, m11);
                radian->z = 0.f;
                return false;
            }
        }
        else
        {
            radian->x = atan2(m01, m11);
            radian->z = 0.f;
            return false;
        }
    }

    bool IsValid() const
    {
        if (!NumberValid(m00)) return false;    if (!NumberValid(m01)) return false;    if (!NumberValid(m02)) return false;    if (!NumberValid(m03)) return false;
        if (!NumberValid(m10)) return false;    if (!NumberValid(m11)) return false;    if (!NumberValid(m12)) return false;    if (!NumberValid(m13)) return false;
        if (!NumberValid(m20)) return false;    if (!NumberValid(m21)) return false;    if (!NumberValid(m22)) return false;    if (!NumberValid(m23)) return false;
        return true;
    }

    friend Matrix34 operator * (const Matrix34& l, const Matrix34& r)
    {
        assert(l.IsValid());
        assert(r.IsValid());

        Matrix34 m = r;

        m.m00 = l.m00 * r.m00 + l.m01 * r.m10 + l.m02 * r.m20;
        m.m10 = l.m10 * r.m00 + l.m11 * r.m10 + l.m12 * r.m20;
        m.m20 = l.m20 * r.m00 + l.m21 * r.m10 + l.m22 * r.m20;
        m.m01 = l.m00 * r.m01 + l.m01 * r.m11 + l.m02 * r.m21;
        m.m11 = l.m10 * r.m01 + l.m11 * r.m11 + l.m12 * r.m21;
        m.m21 = l.m20 * r.m01 + l.m21 * r.m11 + l.m22 * r.m21;
        m.m02 = l.m00 * r.m02 + l.m01 * r.m12 + l.m02 * r.m22;
        m.m12 = l.m10 * r.m02 + l.m11 * r.m12 + l.m12 * r.m22;
        m.m22 = l.m20 * r.m02 + l.m21 * r.m12 + l.m22 * r.m22;
        m.m03 = l.m00 * r.m03 + l.m01 * r.m13 + l.m02 * r.m23 + l.m03;
        m.m13 = l.m10 * r.m03 + l.m11 * r.m13 + l.m12 * r.m23 + l.m13;
        m.m23 = l.m20 * r.m03 + l.m21 * r.m13 + l.m22 * r.m23 + l.m23;

        return m;
    }
};

struct AABB {
    Vec3 min;
    Vec3 max;
};

struct Quat_R {
    float x;
    float y;
    float z;
    float w;
};

Matrix33 ConvertToMatrix33(const Matrix34& Input)
{
    Vec3 vNULL = { 0, 0, 0 };

    Matrix33 Output = Matrix33(vNULL, vNULL, vNULL);

    Output.m00 = (Input.m00);
    Output.m01 = (Input.m01);
    Output.m02 = (Input.m02);
    Output.m10 = (Input.m10);
    Output.m11 = (Input.m11);
    Output.m12 = (Input.m12);
    Output.m20 = (Input.m20);
    Output.m21 = (Input.m21);
    Output.m22 = (Input.m22);

    return Output;
}

void NormalizeAngle(float* Angle)
{
    if (*Angle > M_PI)
        * Angle -= M_TPI;
}
enum EEntityHideFlags : uint32_t
{
    ENTITY_HIDE_NO_FLAG = 0,

    ENTITY_HIDE_LAYER = BIT32(0),
    ENTITY_HIDE_PARENT = BIT32(1),
};
enum Player_Type{
    None,
    Human,
    Infected,
};
enum eCameraModes
{
    eCameraModes_no_fly = 0,
    eCameraModes_fly_mode = 1,
    eCameraModes_fly_mode_noclip = 2,
};
template< typename Function > Function CallVirtual(PVOID Base, DWORD Index)
{
    PDWORD64* VTablePointer = (PDWORD64*)Base;

    if (IsBadReadPtr((PVOID)VTablePointer,8)==FALSE)
    {
        PDWORD64 VTableFunctionBase = *VTablePointer;
        if (IsBadReadPtr((PVOID)VTableFunctionBase, 8) == FALSE)
        {
            DWORD64 dwAddress = VTableFunctionBase[Index];

        if (IsBadReadPtr((PVOID)dwAddress, 8) == FALSE)
        {
            return (Function)(dwAddress);
        }
    }
    }

}

typedef unsigned int EntityId; // Copied from IEntity.h
struct w2s_info
{
    float Posx;
    float Posy;
    float Posz;
    float* Scrnx;
    float* Scrny;
    float* Scrnz;
};
class IRenderer
{

public:
    bool ProjectToScreen(float ptx, float pty, float ptz, float* sx, float* sy, float* sz)
    {
        typedef bool(__thiscall * oFunc)(void*, float, float, float, float*, float*, float*);
        return CallVirtual< oFunc >(this, 86)(this, ptx, pty, ptz, sx, sy, sz);
    }
    int GetHeight() {
        typedef int(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 70)(this);
    }
    int GetWidth() {
        typedef int(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 71)(this);
    }
};
class ISkeletonPose
{
public:
    QuatT& GetAbsJointByID(int32_t nJointID) {
        typedef QuatT& (__thiscall * oFunc)(void*, int32_t);
        return CallVirtual< oFunc >(this, 24)(this, nJointID);
    }

};
class IDefaultSkeleton
{
public:
    uint32_t GetJointCount() {
        typedef uint32_t(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this,1)(this);
    }
    const char* GetJointNameByID(int32_t id) {
        typedef const char* (__thiscall * oFunc)(void*, int32_t);
        return CallVirtual< oFunc >(this, 8)(this, id);
    }
    int32_t  GetJointIDByName(const char* name) {
        typedef int32_t(__thiscall * oFunc)(void*, const char*);
        return CallVirtual< oFunc >(this, 9)(this, name);
    }

};

class ICharacterInstance
{
public:
    ISkeletonPose* GetISkeletonPose() {
        typedef ISkeletonPose* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 17)(this);
    }
    IDefaultSkeleton* GetIDefaultSkeleton() {
        typedef IDefaultSkeleton* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 21)(this);
    }
    AABB* GetAABB(AABB* BoundBox) {
        typedef AABB* (__thiscall * oFunc)(void*, AABB*);
        return CallVirtual< oFunc >(this, 4)(this, BoundBox);
    }

};

class IEntityClass
{
public:

private:

};
class IAIObject
{

};
struct SpawnParams
{
};
class IParticleEffect
{

};

class IEntity
{
public:
    const char* GetName() {
        typedef const char* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 14)(this);
    }
    EntityId GetId() {
        typedef EntityId(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 1)(this);
    }
    IEntityClass* GetClass() {
        typedef IEntityClass*(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 3)(this);
    }
    void Hide(bool bHide, EEntityHideFlags hideFlags = ENTITY_HIDE_NO_FLAG) {
        typedef void(__thiscall * oFunc)(void*, bool bHide, EEntityHideFlags hideFlags );
        return CallVirtual< oFunc >(this, 54)(this, bHide, hideFlags);
    }
    bool IsHidden() {
        typedef bool(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 55)(this);
    }
    ICharacterInstance* GetCharacter(int nSlot) {
        //获取0x38也可以
        typedef ICharacterInstance*(__thiscall * oFunc)(void*,int);
        return CallVirtual< oFunc >(this, 110)(this, nSlot);
    }
    Matrix34& GetWorldTM() {
        typedef Matrix34& (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 29)(this);
    }
    void GetWorldBounds(AABB* BoundBox) {
        typedef void(__thiscall * oFunc)(void*, AABB*);
        return CallVirtual< oFunc >(this, 31)(this, BoundBox);
    }

    void GetWorldPos(Vec3* vec) {
        typedef void(__thiscall * oFunc)(void*, Vec3*);
        return CallVirtual< oFunc >(this, 42)(this, vec);
    }
    void SetPos(const Vec3& vPos, uintptr_t transformReasons, bool bRecalcPhyBounds = false, bool bForce = false) {
        typedef void(__thiscall * oFunc)(void*, const Vec3 & vPos, uintptr_t transformReasons, bool bRecalcPhyBounds, bool bForce);
        return CallVirtual< oFunc >(this, 35)(this, vPos, transformReasons, bRecalcPhyBounds, bForce);
    }
    //GetPos//36
    void SetRotation(const Quat& qRotation, uintptr_t transformReasons) {
        typedef void(__thiscall * oFunc)(void*, const Quat&, uintptr_t);
        return CallVirtual< oFunc >(this, 37)(this, qRotation, transformReasons);
    }
    Quat& GetRotation() {
        typedef Quat& (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 38)(this);
    }
    void SetScale(const Vec3& vScale, uintptr_t transformReasons = 0) {
        typedef void(__thiscall * oFunc)(void*, const Vec3&, uintptr_t);
        return CallVirtual< oFunc >(this, 39)(this, vScale, transformReasons);
    }
    IAIObject* GetAI() {
        typedef IAIObject* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 58)(this);
    }
    int LoadParticleEmitter(int nSlot, IParticleEffect* pEffect, SpawnParams const* params = NULL, bool bPrime = false, bool bSerialize = false) {
        typedef int(__thiscall * oFunc)(void*, int , IParticleEffect * , SpawnParams const*  , bool , bool   );
        return CallVirtual< oFunc >(this, 120)(this, nSlot, pEffect, params, bPrime, bSerialize);
    }

};
class IGameObject
{
public:

};

class IInventory
{
public:
    EntityId GetCurrentItem() {

        typedef int(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 62)(this);
}

};

class IMovementController
{
public:

};

class IActor {
public:
    /**
    char pad0x8[0x8];//0x0
    IEntity* m_Entity;//0x8
    IParticleEffect* m_pParticleEffect;//0x10
    char m_flags;//0x18
    char pad0x3[0x3];//0x19
    int m_slot;//0x1C
    char pad0x18[0x18];//0x20
    char m_active; //0x38
    char m_unk;//0x39
    float            m_height, m_rayWorldIntersectHeight, m_ratio;

    float            m_sizeScale, m_sizeGoal;

    float            m_countScale;

    float            m_speedScale, m_speedGoal;

    float            m_interpSpeed;

    float            m_maxHeightCountScale, m_maxHeightSizeScale;
    */
public:
    void SetFlyMode(uint8_t flyMode) {
        typedef void(__thiscall * oFunc)(void*, uint8_t);
        return CallVirtual< oFunc >(this, 78)(this, flyMode);
    }
    uint16_t GetChannelId() {
        typedef uint16_t(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 28)(this);
    }
    bool IsPlayer()
    {
        typedef bool(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 81)(this);
    }
    bool IsClient()
    {
        typedef bool(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 82)(this);
    }
    float GetMaxHealth() {
        typedef float(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 38)(this);
    }
    float GetHealth() {
        typedef float(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 35)(this);
    }
    int GetTeamId() {
        typedef int(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 41)(this);
    }
    void custom_SetTeamId(int id) {
        *(int*)(this + 0x0BDC) = id;
    }

    bool IsFallen() {
        typedef bool(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 42)(this);
     }
    bool IsDead() {
        typedef bool(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 43)(this);
     }
    int IsGod() {
        typedef int(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 44)(this);
     }
    IEntity* LinkToVehicle(EntityId vehicleId) {
        typedef IEntity* (__thiscall * oFunc)(void* ,EntityId);
        return CallVirtual< oFunc >(this, 71)(this,vehicleId);
    }

    IEntity* GetLinkedEntity() {
        return *(IEntity * *)(this + 0x8);
    }
    IParticleEffect* GetIParticleEffect() {
        return *(IParticleEffect * *)(this + 0x108);
    }
    IEntity* GetLinkedEntity_2() {
        typedef IEntity* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 72)(this);
    }

     uint8_t    GetSpectatorMode() {
         typedef uint8_t(__thiscall * oFunc)(void*);
         return CallVirtual< oFunc >(this, 73)(this);
    }

    bool     IsThirdPerson() {
        typedef bool(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 74)(this);
    }
    void     ToggleThirdPerson() {
        typedef void(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 75)(this);
    }
    const char* GetActorClassName() {
        typedef const char* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 86)(this);
    }
    const char* GetEntityClassName() {
        typedef const char* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 88)(this);
    }
    void SetViewRotation(const Quat& rotation) {
        typedef void(__thiscall * oFunc)(void*, const Quat&);
        return CallVirtual< oFunc >(this, 59)(this, rotation);
    }
    Quat& GetViewRotation(Quat& rotation) {
        typedef Quat& (__thiscall * oFunc)(void*, Quat&);
        return CallVirtual< oFunc >(this, 60)(this, rotation);
    }
    void OnTeleported() {
        typedef void(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 136)(this);
    }
    IItem* GetCurrentItem(bool includeVehicle) {
        typedef IItem* (__thiscall * oFunc)(void*, bool);
        return CallVirtual< oFunc >(this, 66)(this, includeVehicle);
    }
    IInventory* GetInventory() {
        typedef IInventory* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 68)(this);
    }
    IMovementController* GetMovementController() {
        typedef IMovementController* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 70)(this);
    }
};

class IActorIterator
{
public:
    uint32_t Count()
    {
        return *(uint32_t*)(*(uintptr_t*)(this + 8) + 56i64);
        //typedef uint32_t(__thiscall * OriginalFunc)(void* self);
        //return CallVirtual<OriginalFunc>(this, 1)(this);
    }
    IActor* Next2() // offset 0x10, vtable 2
    {
        typedef IActor* (__thiscall * OriginalFunc)(void* self);
        return CallVirtual<OriginalFunc>(this, 2)(this);

    }
    __int64* __fastcall Remove(__int64* a1)
    {
        __int64 v1; // rax
        __int64* v2; // rdx
        __int64** v3; // rcx
        __int64* j; // rax
        __int64 i; // rax

        v1 = *a1;
        v2 = a1;
        if (*(CHAR*)(*a1 + 0x19i64))
            return v2;
        v3 = *(__int64***)(v1 + 0x10);
        if (*((CHAR*)v3 + 0x19))
        {
            for (i = *(__int64*)(v1 + 8); !*(CHAR*)(i + 25); i = *(__int64*)(i + 8))
            {
                if (*v2 != *(__int64*)(i + 0x10))
                    break;
                *v2 = i;
            }
            *v2 = i;
            return v2;
        }
        for (j = *v3; !*((CHAR*)j + 25); j = (__int64*)* j)
            v3 = (__int64**)j;
        *v2 = (__int64)v3;
        return v2;
    }
    IActor* Next() // offset 0x10, vtable 2
    {
        __int64 v1; // rbx
        __int64 v3; // rbx
        if (this==nullptr)
        {
            return nullptr;
        }
        v1 = *(uintptr_t*)(this + 0x10);
        if (v1 == *(uintptr_t*)(*(uintptr_t*)(this + 8) + 0x30i64))
            return 0i64;
        v3 = *(uintptr_t*)(v1 + 0x28);
        Remove((__int64*)(this + 0x10));
        return (IActor*)v3;

    }

    void  AddRef() {
        typedef void(__thiscall * OriginalFunc)(void* self);
        return CallVirtual<OriginalFunc>(this, 3)(this);
     }
    void  Release() {
        typedef void(__thiscall * OriginalFunc)(void* self);
        return CallVirtual<OriginalFunc>(this, 4)(this);
     }
};

class IActorSystem
{
public:
    IActor* GetActor(EntityId id)
    {
        typedef IActor* (__thiscall * OriginalFunc)(void* self, EntityId id);
        return CallVirtual<OriginalFunc>(this, 3)(this, id);
    }
    int GetActorCount()
    {
        typedef int(__thiscall * OriginalFunc)(void* self);
        return CallVirtual<OriginalFunc>(this, 6)(this);
    }
    void CreateActorIterator(IActorIterator** pIt)
    {
        typedef void(__thiscall * OriginalFunc)(void* self, IActorIterator * *pIt);
        return CallVirtual<OriginalFunc>(this, 7)(this, pIt);

    }
};
class IFireMode
{
public:
    /**
    (*(void(__fastcall**)(__int64, const char*, __int64, _QWORD))(*(_QWORD*)qword_141B45848 + 1216i64))(
        qword_141B45848,
        "FilterMaskedBlurring_Amount",
        v8,
        0i64);
}
      }
    }
  }
  m_pWeapon_1 = *(_QWORD*)(m_pWeapon + 8) + 0x2B8i64;
  v12 = *(_QWORD*)m_pWeapon_1;
  GetCurrentFireMode = (*(__int64 (**)(void))(*(_QWORD*)m_pWeapon_1 + 248i64))();
  pFireMode = (*(__int64(__fastcall * *)(signed __int64, _QWORD))(v12 + 0xE8))(
      *(_QWORD*)(m_pWeapon + 8) + 0x2B8i64,
      GetCurrentFireMode);
  if (pFireMode)
      (*(void(__fastcall**)(__int64))(*(_QWORD*)pFireMode + 528i64))(pFireMode);// //OnZoomStateChanged
  IViewSystem = (*(__int64 (**)(void))(*(_QWORD*)IGameFramework + 0xD0i64))();// //GetIViewSystem
  IView = (*(__int64(__fastcall * *)(__int64))(*(_QWORD*)IViewSystem + 56i64))(IViewSystem);// //GetActiveView
  if (IView)
  {
      v17 = *(unsigned int*)(*(_QWORD*)(m_pWeapon + 0x20) + 0x118i64);
      IView = (*(__int64(__fastcall * *)(__int64))(*(_QWORD*)IView + 120i64))(IView);// //SetZoomedScale
  }
  *(_DWORD*)(m_pWeapon + 88) = 0;              // //m_swayTime
  return IView;
  */

};

class IWeapon
{
public:
    IFireMode* GetFireMode(int idx) {

        typedef IFireMode* (__thiscall * oFunc)(void*, int);
        return CallVirtual< oFunc >(this, 25)(this, idx);
    }
    int GetCurrentFireMode() {

        typedef int(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 28)(this);
    }
};

class IItem
{
public:
    IWeapon* GetIWeapon() {
        typedef IWeapon* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 85)(this);
    }
};

class IEquipmentManager
{
public:

};

class IItemSystem
{
public:
    IItem* GetItem(EntityId itemId) {
        typedef IItem* (__thiscall * oFunc)(void*, EntityId);
        return CallVirtual< oFunc >(this, 21)(this, itemId);
    }
    IEquipmentManager* GetIEquipmentManager() {
        typedef IEquipmentManager* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 42)(this);
    }

};

class CCamera
{
public:
    enum EEye
    {
        eEye_Left = 0,
        eEye_Right,

        eEye_eCount,
        eEye_Both = eEye_eCount
    };

public:

    Vec3 *GetViewdir() {
        typedef Vec3* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 108)(this);
    }
    Matrix34* GetViewMatrix() {
        typedef Matrix34*(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 109)(this);
    }
    Vec3 GetPosition() {
        typedef Matrix34* (__thiscall * oFunc)(void*);
        Matrix34*  mat = CallVirtual< oFunc >(this, 109)(this);
        return mat->GetTranslation();
     }

};

class IGameFramework
{
public:

    IActorSystem* GetIActorSystem() {
        typedef IActorSystem* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 22)(this);
    }
    IItemSystem* GetIItemSystem() {
        typedef IItemSystem* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 23)(this);
    }
    IActor* GetClientActor() {
        typedef IActor* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 64)(this);
    }
};
struct IPhysicalEntity
{
    int GetiForeignData() {
        typedef int(__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 11)(this);
    }
    void* GetForeignData() {
        typedef void* (__thiscall * oFunc)(void*);
        return CallVirtual< oFunc >(this, 10)(this);
    }
};

#pragma  pack(push)  
#pragma  pack(1)  
struct ray_hit
{
    float            dist;//0x0
    int unk0x4;//0x4
    IPhysicalEntity* pCollider;//0x8
    int              ipart;//0x10
    int              partid;//0x14
    short            surface_idx;//0x18
    short            idmatOrg; //!< original material index, not mapped with material mapping //0x1A
    int              foreignIdx;//0x1C
    int              iNode; //!< BV tree node that had the intersection; can be used for "warm start" next time//0x20
    Vec3             pt;//0x24
    Vec3             n;        //!< surface normal//0x30
    int              bTerrain; //!< global terrain hit//0x3C
    int              iPrim;    //!< hit triangle index//0x40
    ray_hit* next;     //!< reserved for internal use, do not change//0x44
};
#pragma  pack(pop)  
struct ray_hit_cached   //!< used in conjunction with rwi_reuse_last_hit
{
    ray_hit_cached() { pCollider = 0; ipart = 0; }
    ray_hit_cached(const ray_hit& hit) { pCollider = hit.pCollider; ipart = hit.ipart; iNode = hit.iNode; }
    ray_hit_cached& operator=(const ray_hit& hit) { pCollider = hit.pCollider; ipart = hit.ipart; iNode = hit.iNode; return *this; }

    IPhysicalEntity* pCollider;
    int              ipart;
    int              iNode;
};
struct SCollisionClass
{
    uint32_t type;     //!< Collision_class flags to identify the entity.
    uint32_t ignore;   //!< Another entity will be ignored if *any* of these bits are set in its type.

    SCollisionClass() {}

    SCollisionClass(uint32_t t, uint32_t i)
    {
        type = t;
        ignore = i;
    }
};
#pragma  pack(push)  
#pragma  pack(1)  
struct SRWIParams
{
    void * pForeignData; //0x0
    int iForeignData; //0x8
    int unk;//0xC
    void* unk2; //0x10
    Vec3 org;   //0x18
    Vec3 dir;   //0x24
    int objtypes;//0x30
    int flags;//0x34
    ray_hit* hits;//0x38
    int nMaxHits;//0x40
    int unk11;//0x44
    ray_hit_cached* phitLast;//0x48
    int nSkipEnts;//0x50
    int nMaxPortals;              //0x54
    IPhysicalEntity** pSkipEnts;//0x58
    SCollisionClass   collclass;//0x60

};
#pragma  pack(pop)  
enum phentity_flags
{
    // PE_PARTICLE-specific flags
    particle_single_contact = 0x01,  //!< Full stop after first contact.
    particle_constant_orientation = 0x02,  //!< Forces constant orientation.
    particle_no_roll = 0x04,  //!< 'sliding' mode; entity's 'normal' vector axis will be alinged with the ground normal.
    particle_no_path_alignment = 0x08,  //!< Unless set, entity's y axis will be aligned along the movement trajectory.
    particle_no_spin = 0x10,  //!< Disables spinning while flying.
    particle_no_self_collisions = 0x100, //!< Disables collisions with other particles.
    particle_no_impulse = 0x200, //!< Particle will not add hit impulse (expecting that some other system will).

    // PE_LIVING-specific flags
    lef_push_objects = 0x01, lef_push_players = 0x02, //!< Push objects and players during contacts.
    lef_snap_velocities = 0x04,                          //!< Quantizes velocities after each step (was ised in MP for precise deterministic sync).
    lef_loosen_stuck_checks = 0x08,                          //!< Don't do additional intersection checks after each step (recommended for NPCs to improve performance).
    lef_report_sliding_contacts = 0x10,                          //!< Unless set, 'grazing' contacts are not reported.

    // PE_ROPE-specific flags
    rope_findiff_attached_vel = 0x01,                              //!< Approximate velocity of the parent object as v = (pos1-pos0)/time_interval.
    rope_no_solver = 0x02,                              //!< No velocity solver; will rely on stiffness (if set) and positional length enforcement.
    rope_ignore_attachments = 0x4,                               //!< No collisions with objects the rope is attached to.
    rope_target_vtx_rel0 = 0x08, rope_target_vtx_rel1 = 0x10, //!< Whether target vertices are set in the parent entity's frame.
    rope_subdivide_segs = 0x100,                             //!< Turns on 'dynamic subdivision' mode (only in this mode contacts in a strained state are handled correctly).
    rope_no_tears = 0x200,                             //!< Rope will not tear when it reaches its force limit, but stretch.
    rope_collides = 0x200000,                          //!< Rope will collide with objects other than the terrain.
    rope_collides_with_terrain = 0x400000,                          //!< Rope will collide with the terrain.
    rope_collides_with_attachment = 0x80,                              //!< Rope will collide with the objects it's attached to even if the other collision flags are not set.
    rope_no_stiffness_when_colliding = 0x10000000,                        //!< Rope will use stiffness 0 if it has contacts.

    //! PE_SOFT-specific flags
    se_skip_longest_edges = 0x01, //!< the longest edge in each triangle with not participate in the solver
    se_rigid_core = 0x02, //!< soft body will have an additional rigid body core

    //! PE_RIGID-specific flags (note that PE_ARTICULATED and PE_WHEELEDVEHICLE are derived from it)
    ref_use_simple_solver = 0x01,                                //!< use penalty-based solver (obsolete)
    ref_no_splashes = 0x04,                                //!< will not generate EventPhysCollisions when contacting water
    ref_checksum_received = 0x04, ref_checksum_outofsync = 0x08, //!< obsolete
    ref_small_and_fast = 0x100,                               //!< entity will trace rays against alive characters; set internally unless overriden

    //! PE_ARTICULATED-specific flags
    aef_recorded_physics = 0x02, //!< specifies a an entity that contains pre-baked physics simulation

    //! PE_WHEELEDVEHICLE-specific flags
    wwef_fake_inner_wheels = 0x08, //!< exclude wheels between the first and the last one from the solver
                                   //! (only wheels with non-0 suspension are considered)

    //! general flags
    pef_parts_traceable = 0x10,                                                      //!< each entity part will be registered separately in the entity grid
    pef_disabled = 0x20,                                                      //!< entity will not be simulated
    pef_never_break = 0x40,                                                      //!< entity will not break or deform other objects
    pef_deforming = 0x80,                                                      //!< entity undergoes a dynamic breaking/deforming
    pef_pushable_by_players = 0x200,                                                     //!< entity can be pushed by playerd
    pef_traceable = 0x400, particle_traceable = 0x400, rope_traceable = 0x400, //!< entity is registered in the entity grid
    pef_update = 0x800,                                                     //!< only entities with this flag are updated if ent_flagged_only is used in TimeStep()
    pef_monitor_state_changes = 0x1000,                                                    //!< generate immediate events for simulation class changed (typically rigid bodies falling asleep)
    pef_monitor_collisions = 0x2000,                                                    //!< generate immediate events for collisions
    pef_monitor_env_changes = 0x4000,                                                    //!< generate immediate events when something breaks nearby
    pef_never_affect_triggers = 0x8000,                                                    //!< don't generate events when moving through triggers
    pef_invisible = 0x10000,                                                   //!< will apply certain optimizations for invisible entities
    pef_ignore_ocean = 0x20000,                                                   //!< entity will ignore global water area
    pef_fixed_damping = 0x40000,                                                   //!< entity will force its damping onto the entire group
    pef_monitor_poststep = 0x80000,                                                   //!< entity will generate immediate post step events
    pef_always_notify_on_deletion = 0x100000,                                                  //!< when deleted, entity will awake objects around it even if it's not referenced (has refcount 0)
    pef_override_impulse_scale = 0x200000,                                                  //!< entity will ignore breakImpulseScale in PhysVars
    pef_players_can_break = 0x400000,                                                  //!< playes can break the entiy by bumping into it
    pef_cannot_squash_players = 0x10000000,                                                //!< entity will never trigger 'squashed' state when colliding with players
    pef_ignore_areas = 0x800000,                                                  //!< entity will ignore phys areas (gravity and water)
    pef_log_state_changes = 0x1000000,                                                 //!< entity will log simulation class change events
    pef_log_collisions = 0x2000000,                                                 //!< entity will log collision events
    pef_log_env_changes = 0x4000000,                                                 //!< entity will log EventPhysEnvChange when something breaks nearby
    pef_log_poststep = 0x8000000,                                                 //!< entity will log EventPhysPostStep events
};
enum draw_helper_flags { pe_helper_collisions = 1, pe_helper_geometry = 2, pe_helper_bbox = 4, pe_helper_lattice = 8 };
enum surface_flags { sf_pierceable_mask = 0x0F, sf_max_pierceable = 0x0F, sf_important = 0x200, sf_manually_breakable = 0x400, sf_matbreakable_bit = 16 };
enum rwi_flags
{
    rwi_ignore_terrain_holes = 0x20, rwi_ignore_noncolliding = 0x40, rwi_ignore_back_faces = 0x80, rwi_ignore_solid_back_faces = 0x100,
    rwi_pierceability_mask = 0x0F, rwi_pierceability0 = 0, rwi_stop_at_pierceable = 0x0F,
    rwi_max_piercing = 0x10,         //!< the ray will pierce all surfaces (including those with pierceability 0)
    rwi_separate_important_hits = sf_important, //!< among pierceble hits, materials with sf_important will have priority
    rwi_colltype_bit = 16,           //!< used to manually specify collision geometry types (default is geom_colltype_ray)
    rwi_colltype_any = 0x400,        //!< if several colltype flag are specified, switches between requiring all or any of them in a geometry
    rwi_queue = 0x800,        //!< queues the RWI request, when done it'll generate EventPhysRWIResult
    rwi_force_pierceable_noncoll = 0x1000,       //!< non-colliding geometries will be treated as pierceable regardless of the actual material
    rwi_update_last_hit = 0x4000,       //!< update phitLast with the current hit results (should be set if the last hit should be reused for a "warm" start)
    rwi_any_hit = 0x8000        //!< returns the first found hit for meshes, not necessarily the closets
};
#define rwi_pierceability(pty)      (pty)
#define rwi_colltype_all(colltypes) ((colltypes) << rwi_colltype_bit)
#define rwi_colltype_any(colltypes) ((colltypes) << rwi_colltype_bit | rwi_colltype_any)

//! see GetEntitiesInBox and RayWorldIntersection
enum entity_query_flags
{
    ent_static = 1, ent_sleeping_rigid = 2, ent_rigid = 4, ent_living = 8, ent_independent = 16, ent_deleted = 128, ent_terrain = 0x100,
    ent_all = ent_static | ent_sleeping_rigid | ent_rigid | ent_living | ent_independent | ent_terrain,
    ent_flagged_only = pef_update, ent_skip_flagged = pef_update * 2, //!< "flagged" meas has pef_update set
    ent_areas = 32, ent_triggers = 64,
    ent_ignore_noncolliding = 0x10000,
    ent_sort_by_mass = 0x20000,  //!< sort by mass in ascending order
    ent_allocate_list = 0x40000,  //!< if not set, the function will return an internal pointer
    ent_water = 0x200,    //!< can only be used in RayWorldIntersection
    ent_no_ondemand_activation = 0x80000,  //!< can only be used in RayWorldIntersection
    ent_delayed_deformations = 0x80000,  //!< queues procedural breakage requests; can only be used in SimulateExplosion
    ent_addref_results = 0x100000, //!< will call AddRef on each entity in the list (expecting the caller call Release)
    ent_use_sync_coords = 0x200000, //<! use entity coords that are sync'ed to the last poststep event pump
    ent_reserved2 = 0x20000000,
    ent_reserved1 = 0x40000000
};
class IPhysicalWorld
{
public:
    int RayWorldIntersection(SRWIParams& info, const char* pNameTag = "RayWorldIntersection(Game)", int i = 4) {
        sizeof(SRWIParams);
        typedef int(__thiscall * oFunc)(void*, SRWIParams & , const char*, int);
        return CallVirtual< oFunc >(this, 35)(this, info, pNameTag,i);
    }
    inline int RayWorldIntersection(const Vec3& org, const Vec3& dir, int objtypes, unsigned int flags, ray_hit* hits, int nMaxHits,
        IPhysicalEntity** pSkipEnts = 0, int nSkipEnts = 0, void* pForeignData = 0, int iForeignData = 0,
        const char* pNameTag = "RayWorldIntersection(Game)", ray_hit_cached * phitLast = 0, int iCaller = 4)
    {
        SRWIParams rp;

        rp.org = org;
        rp.dir = dir;
        rp.objtypes = objtypes;
        rp.flags = flags;
        rp.hits = hits;
        rp.nMaxHits = nMaxHits;
        rp.pForeignData = pForeignData;
        rp.iForeignData = iForeignData;
        rp.phitLast = phitLast;
        rp.pSkipEnts = pSkipEnts;
        rp.nSkipEnts = nSkipEnts;

        sizeof(rp);
        return RayWorldIntersection(rp, pNameTag, iCaller);
    }
};

struct SProjectileLaunchParams
{
    float    fSpeedScale;
    EntityId trackingId;
    Vec3     vShootTargetPos;

};
**骨骼的一些东西**
Vec3 GetBonePositionByID(IEntity* Entity, int BoneID)
{
    ICharacterInstance* CharacterInstance = Entity->GetCharacter(0);

    if (!CharacterInstance)
        return EmptyVec;

    ISkeletonPose* SkeletonPose = CharacterInstance->GetISkeletonPose();

    if (!SkeletonPose)
        return EmptyVec;

    int TargetBoneID = BoneID;

    if (TargetBoneID < 0)
        return EmptyVec;

    Matrix34 World = Entity->GetWorldTM();
    Matrix34 SkeletonAbs = Matrix34(SkeletonPose->GetAbsJointByID(TargetBoneID));
    Matrix34 MatrixWorld = World;

    float MatrixA, MatrixB, MatrixC;

    MatrixA = (World.m00 * SkeletonAbs.m03) + (World.m01 * SkeletonAbs.m13) + (World.m02 * SkeletonAbs.m23) + World.m03;
    MatrixWorld.m03 = MatrixA;

    MatrixB = (World.m10 * SkeletonAbs.m03) + (World.m11 * SkeletonAbs.m13) + (World.m12 * SkeletonAbs.m23) + World.m13;
    MatrixWorld.m13 = MatrixB;

    MatrixC = (World.m20 * SkeletonAbs.m03) + (World.m21 * SkeletonAbs.m13) + (World.m22 * SkeletonAbs.m23) + World.m23;
    MatrixWorld.m23 = MatrixC;

    return MatrixWorld.GetTranslation();
}
Matrix33 GetBoneOriginMatrix(IEntity* Entity, int BoneID)
{
    ICharacterInstance* CharacterInstance = Entity->GetCharacter(0);

    if (!CharacterInstance)
        return EmptyMatrix;

    ISkeletonPose* SkeletonPose = CharacterInstance->GetISkeletonPose();

    if (!SkeletonPose)
        return EmptyMatrix;

    int TargetBoneID = BoneID;

    if (TargetBoneID < 0)
        return EmptyMatrix;

    Matrix34 World = Entity->GetWorldTM();
    Matrix34 SkeletonAbs = Matrix34(SkeletonPose->GetAbsJointByID(TargetBoneID));
    Matrix34 MatrixWorld = World * SkeletonAbs;

    return ConvertToMatrix33(MatrixWorld);
}
Vec3 GetBonePositionByBoneID(IEntity* Entity,Bone id) {
    ICharacterInstance* ICharacter = Entity->GetCharacter(0);
    if (!ICharacter)return EmptyVec;

    IDefaultSkeleton* IDefault= ICharacter->GetIDefaultSkeleton();
    if (!IDefault)return EmptyVec;

    int32_t idx = IDefault->GetJointIDByName(Bone_Name[id].c_str());

    return GetBonePositionByID(Entity, idx);
}
Matrix33 GetBoneMatrixByBoneID(IEntity* Entity, Bone id) {
    ICharacterInstance* ICharacter = Entity->GetCharacter(0);
    if (!ICharacter)return EmptyMatrix;

    IDefaultSkeleton* IDefault = ICharacter->GetIDefaultSkeleton();
    if (!IDefault)return EmptyMatrix;

    int32_t idx = IDefault->GetJointIDByName(Bone_Name[id].c_str());

    return GetBoneOriginMatrix(Entity, idx);
}
绘制骨骼的例子
VOID DrawBone(IEntity* Entity,RGBA col) {
    if (!Entity)return;
    Vec3 Head;
    Vec3 Neck;
    Vec3 LClavicle;
    Vec3 RClavicle;
    Vec3 Spine1;
    Vec3 Spine;
    Vec3 IndiHips;

    Head = GetBonePositionByBoneID(Entity,Bone::Bip01_Head);
    Neck = GetBonePositionByBoneID(Entity, Bone::Bip01_Neck);
    LClavicle = GetBonePositionByBoneID(Entity, Bone::Bip01_L_Clavicle);
    RClavicle = GetBonePositionByBoneID(Entity, Bone::Bip01_R_Clavicle);
//  Spine1 = GetBonePositionByBoneID(Entity, Bone::Bip01_Spine1);
    Spine = GetBonePositionByBoneID(Entity, Bone::Bip01_Spine);
    IndiHips = GetBonePositionByBoneID(Entity, Bone::Bip01_IndiHips);

    if (!WorldToScreen(Head, &Head))return;
    if (!WorldToScreen(Neck, &Neck))return;
    if (!WorldToScreen(LClavicle, &LClavicle))return;

    if (!WorldToScreen(RClavicle, &RClavicle))return;
    //if (!WorldToScreen(Spine1, &Spine1))return;
    if (!WorldToScreen(Spine, &Spine))return;

    if (!WorldToScreen(IndiHips, &IndiHips))return;

    //头部到臀部
    Imgui_DrawLine(Head.x, Head.y, Neck.x, Neck.y, col);
    Imgui_DrawLine(Neck.x, Neck.y, Spine.x, Spine.y, col);
    Imgui_DrawLine(Spine.x, Spine.y, IndiHips.x, IndiHips.y, col);

    Imgui_DrawLine(Neck.x, Neck.y, LClavicle.x, LClavicle.y, col);
    Imgui_DrawLine(Neck.x, Neck.y, RClavicle.x, RClavicle.y, col);

}
**坐标转换**
bool WorldToScreen(Vec3 vEntPos, Vec3* ScreenPos)
{
    w2s_info info;
    info.Posx = vEntPos.x;
    info.Posy = vEntPos.y;
    info.Posz = vEntPos.z;

    info.Scrnx = &ScreenPos->x;
    info.Scrny = &ScreenPos->y;
    info.Scrnz = &ScreenPos->z;

    g_IRenderer->ProjectToScreen(vEntPos.x, vEntPos.y, vEntPos.z, &ScreenPos->x, &ScreenPos->y, &ScreenPos->z);

    if (ScreenPos->z < 0.0f || ScreenPos->z > 1.0f) {
        return false;
    }

    ScreenPos->x *= (g_IRenderer->GetWidth() / 100.0f);
    ScreenPos->y *= (g_IRenderer->GetHeight() / 100.0f);
    //ScreenPos->z *= 1.0f;

    return (ScreenPos->z < 1.0f);
}
**游戏的引擎可见性判断**
bool IsVisible(Vec3 TargetPosition, Vec3 MyPosition)
{
    Vec3 CalculatedPosition;
    CalculatedPosition.x = TargetPosition.x - MyPosition.x;
    CalculatedPosition.y = TargetPosition.y - MyPosition.y;
    CalculatedPosition.z = TargetPosition.z - MyPosition.z;

    ray_hit RayHit = { 0 };
    bool ret= !g_IPhysicalWorld->RayWorldIntersection(MyPosition, CalculatedPosition, 0x101, (COLLISION_RAY_PIERCABILITY & RWI_RAY_PIERCABILITY_MASK), &RayHit, 1, 0, 0, 0, 0, "RayWorldIntersection(Game)", 0, 4);

    return ret;
}

Vec3 GetRay(Vec3 TargetPosition, Vec3 MyPosition)
{
    Vec3 CalculatedPosition;
    CalculatedPosition.x = TargetPosition.x - MyPosition.x;
    CalculatedPosition.y = TargetPosition.y - MyPosition.y;
    CalculatedPosition.z = TargetPosition.z - MyPosition.z;
    ray_hit RayHit;
    if ((g_IPhysicalWorld->RayWorldIntersection(MyPosition, CalculatedPosition, 0x101, (COLLISION_RAY_PIERCABILITY & RWI_RAY_PIERCABILITY_MASK), &RayHit, 1, 0, 0, 0, 0, "RayWorldIntersection(Game)", 0, 4))==false)
    {
        return RayHit.pt;
    }
    return EmptyVec;
}
**绘制人物方框**
void DrawBoundingBox(IEntity* pLocalEntity, IEntity* pIEntity, AABB Bounds, int TeamId)
{
    FLOAT High = 0.0f;
    FLOAT Low = 0.0f;
    ImVec2 vect = Imgui_GetTextSize("123", gFont_Size);
    GameBox box;
    RGBA Box_Color;
    RGBA Type_Color;
    std::string type = "";
    Vec3 local = GetBonePositionByBoneID(pLocalEntity, Bone::Bip01_Camera);
    Vec3 target = GetBonePositionByBoneID(pIEntity, Bone::Bip01_Head);
    bool vis = IsVisible(target, local);
    float dist = GetDistance(pLocalEntity, pIEntity);
    bool aim = false;

    if (pIEntity ==Deceit_CryEngine::Engine::Aimbot::AimPlayer)
    {
        aim = TRUE;
    }
    if (TeamId == Player_Type::Human)
    {
        Type_Color = GREEN;
        type = "人类";
    }
    else
    {
        Type_Color = RED;
        type = "狼人";
    }
    if (vis)
    {
        Box_Color = RED;
    }
    else {
        Box_Color = GREEN;
    }

    if (GetBox(Bounds.min, Bounds.max, box))
    {
        float x = box.x;
        float y = box.y;
        float w = box.w;
        float h = box.h;
        Imgui_DrawBox(x, y, w, h, Box_Color, 1.0f);
        High += vect.y;
        Imgui_DrawString2_Storke(true, x + (w / 2), y - High, gFont_Size, Type_Color, BLACK, "%s", type.c_str());

        if (aim)
        {
            High += vect.y;

            Imgui_DrawString2_Storke(true, x + (w / 2), y - High, gFont_Size, Type_Color, BLACK, "%s", "[Tp]");
        }
        Imgui_DrawString2_Storke(true, x + (w / 2), y + h, gFont_Size, RED, BLACK, "%1.0fM", dist);
    }

}
**人物传送功能**
void TeleportedToPos(IActor* LocalActor,IEntity* pLocalEntity,Vec3 & pos) {
    //Quat q = pLocalEntity->GetRotation();
    pLocalEntity->SetPos(pos, 0);
    //pLocalEntity->SetRotation(q, 0);
    //LocalActor->SetViewRotation(q);
    //LocalActor->OnTeleported();//reset tp flags
}
**对象遍历 以及获取当前人物对象**
IActor* GetLocalActor() {
    return g_IGameFramework->GetClientActor();
}
IEntity* GetLocalIEntity() {
IActor* LocalActor=  g_IGameFramework->GetClientActor();
if (!LocalActor)return nullptr;

return LocalActor->GetLinkedEntity();
}

//对象遍历
IActor* LocalActor = GetLocalActor();
    if (LocalActor)
    {

        //LocalActor->m_speedScale = 100.f;
    //  LocalActor->m_speedGoal = 100.f;
        //LocalActor->m_interpSpeed = 100.f;
        //Debug("%pn", LocalActor);
        IEntity* pLocalEntity = GetLocalIEntity();;
        if (!pLocalEntity) return;

        if (KeyState(VK_END, 1000))
            LocalActor->ToggleThirdPerson();

        IActorSystem* m_pActorSystem = g_IGameFramework->GetIActorSystem();
        if (!m_pActorSystem)
            return;

        IActorIterator* m_pIActorIterator = nullptr;
        m_pActorSystem->CreateActorIterator(&m_pIActorIterator);

        int num = 1;

        IActor* m_pActor = nullptr;
        if (m_pIActorIterator==nullptr)
            return;
        if (IsBadReadPtr(m_pIActorIterator, 4))
            return;

        for (; m_pActor= m_pIActorIterator->Next(); )
        {
            if (!m_pActor)
            {
                break;
            }
            if (!m_pIActorIterator)
            {
                break;
            }
            if (m_pActor== LocalActor)
            {
                continue;
            }
            IEntity* pIEntity = m_pActor->GetLinkedEntity();
            if (!pIEntity)
            {
                continue;
            }
            if (m_pActor->IsDead() )
            {
                continue;
            }

            AABB Boundaries = { EmptyVec, EmptyVec };
            pIEntity->GetWorldBounds(&Boundaries);
            DrawBoundingBox(pLocalEntity, pIEntity,Boundaries, m_pActor->GetTeamId());
            SelectAimPlayer(pIEntity, m_pActor);

            //定点
            if (KeyState(VK_F1, 1000))
            {

                Deceit_CryEngine::Tp::savepos = GetBonePositionByBoneID(pLocalEntity, Bone::Bip01_Head);
                //Debug("保存坐标:{%1.0f  ,%1.0f ,%1.0f}n", Deceit_CryEngine::Tp::savepos.x, Deceit_CryEngine::Tp::savepos.y, Deceit_CryEngine::Tp::savepos.z);
            }

            //瞬移

            if (KeyState(VK_F2, 1000))
            {

                TeleportedToPos(LocalActor, pLocalEntity, Deceit_CryEngine::Tp::savepos);
                //Debug("归位坐标:{%1.0f  ,%1.0f ,%1.0f}n", Deceit_CryEngine::Tp::savepos.x, Deceit_CryEngine::Tp::savepos.y, Deceit_CryEngine::Tp::savepos.z);
            }

            if (KeyState(VK_F3, 1000))
            {
                Vec3 POS =  GetBonePositionByBoneID(pLocalEntity, Bone::Bip01_Head);
                POS.z = POS.z + 5.0f;
                TeleportedToPos(LocalActor, pLocalEntity, POS);
                //Debug("上移坐标:{%1.0f  ,%1.0f ,%1.0f}n", POS.x, POS.y, POS.z);
                Deceit_CryEngine::Tp::savepos = POS;
            }
            if (KeyState(VK_F4, 1000))
            {
                Vec3 POS = GetBonePositionByBoneID(pLocalEntity, Bone::Bip01_Head);
                POS.z = POS.z - 5.0f;
                TeleportedToPos(LocalActor, pLocalEntity, POS);
                //Debug("下移坐标:{%1.0f  ,%1.0f ,%1.0f}n", POS.x, POS.y, POS.z);
                Deceit_CryEngine::Tp::savepos = POS;
            }

            if (KeyState(VK_F5, 1000))
            {
                Deceit_CryEngine::Tp::lock = !Deceit_CryEngine::Tp::lock;
                Deceit_CryEngine::Tp::LocalEntity = pLocalEntity;
            }
            else
            {
                if (Deceit_CryEngine::Tp::LocalEntity!= pLocalEntity)
                {
                    Deceit_CryEngine::Tp::lock = false;
                }
            }
            if (Deceit_CryEngine::Tp::lock)
            {
                TeleportedToPos(LocalActor, pLocalEntity, Deceit_CryEngine::Tp::savepos);
            }

        }

        if (Deceit_CryEngine::Engine::Aimbot::AimPlayer && Deceit_CryEngine::Engine::Aimbot::IC_AimPlayer && pLocalEntity && LocalActor)
        {

            if (LocalActor->IsDead()==FALSE)
            {
                //绘制当前选定的人
                AABB Boundaries = { EmptyVec, EmptyVec };
                Deceit_CryEngine::Engine::Aimbot::AimPlayer->GetWorldBounds(&Boundaries);
                DrawBoundingBox(pLocalEntity, Deceit_CryEngine::Engine::Aimbot::AimPlayer, Boundaries, Deceit_CryEngine::Engine::Aimbot::IC_AimPlayer->GetTeamId());

                //按Home键TP过去
                if ((GetAsyncKeyState(VK_HOME) & 0x8000)) {
                    Deceit_CryEngine::Tp::lock = false;
                    Vec3 pos = GetBonePositionByBoneID(Deceit_CryEngine::Engine::Aimbot::AimPlayer, Bone::Bip01_Head);
                    TeleportedToPos(LocalActor, pLocalEntity, pos);
                }

                //自动瞄准
                if ((GetAsyncKeyState(VK_RBUTTON) & 0x8000))
                {
                    Vec3 local = GetBonePositionByBoneID(pLocalEntity, Bone::Bip01_Camera);
                    Vec3 target = GetBonePositionByBoneID(Deceit_CryEngine::Engine::Aimbot::AimPlayer, Bone::Bip01_Head);
                    bool vis = IsVisible(target, local);
                    if (vis)
                    {
                        Deceit_CryEngine::Engine::Aimbot::LockIng = TRUE;

                        Vec3 vDiffer;

                        vDiffer = target - local;

                        Quat Heading = Quat::CreateRotationVDir(vDiffer.normalize());

                        LocalActor->SetViewRotation(Heading);

                    }
                    else {
                        Deceit_CryEngine::Engine::Aimbot::LockIng = FALSE;
                    }
                }
                else {
                    Deceit_CryEngine::Engine::Aimbot::LockIng = FALSE;
                }

            }

        }
        //清理自瞄对象
        if (Deceit_CryEngine::Engine::Aimbot::AimPlayer == NULL || Deceit_CryEngine::Engine::Aimbot::LockIng == FALSE) {
            Deceit_CryEngine::Engine::Aimbot::AimPlayer = nullptr;
            Deceit_CryEngine::Engine::Aimbot::AimDistance = 0;
            Deceit_CryEngine::Engine::Aimbot::CurrentDistance = 0;
            Deceit_CryEngine::Engine::Aimbot::NearestDistance = 0;
        }
    }
**关于骨骼 
我是转储出来骨骼名称 建立map**
void InitBoneNameMap() {
    Bone_Name[Bone::Bip01] = "Bip01";
    Bone_Name[Bone::Bip01_Pelvis] = "Bip01 Pelvis";
    Bone_Name[Bone::u_T_SH_SpineBase01J] = "u_T_SH_SpineBase01J";
    Bone_Name[Bone::Bip01_LookTarget] = "Bip01 LookTarget";
    Bone_Name[Bone::Bip01_AimTarget] = "Bip01 AimTarget";
    Bone_Name[Bone::Bip01_IndiHips] = "Bip01 IndiHips";
    Bone_Name[Bone::Bip01_Spine] = "Bip01 Spine";
    Bone_Name[Bone::Bip01_RHand2LPocket_IKTarget] = "Bip01 RHand2LPocket IKTarget";
    Bone_Name[Bone::Bip01_RHand2LPocket_IKBlend] = "Bip01 RHand2LPocket IKBlend";
    Bone_Name[Bone::Bip01_Spine1] = "Bip01 Spine1";
    Bone_Name[Bone::Bip01_Neck] = "Bip01 Neck";
    Bone_Name[Bone::Bip01_L_Clavicle] = "Bip01 L Clavicle";
    Bone_Name[Bone::Bip01_R_Clavicle] = "Bip01 R Clavicle";
    Bone_Name[Bone::Bip01_Head] = "Bip01 Head";
    Bone_Name[Bone::u_Jaw_14] = "u_Jaw";
    Bone_Name[Bone::Bip01_IndiHips] = "Bip01 IndiHips";
    Bone_Name[Bone::Bip01_Camera] = "Bip01 Camera";
}
以下是我当时转储的骨骼信息
Deceit Bone Dumper Start----
Bip01 0
Bip01 Pelvis 1
u_T_SH_SpineBase01J 2
Bip01 LookTarget 3
Bip01 AimTarget 4
Bip01 IndiHips 5
Bip01 Spine 6
Bip01 RHand2LPocket IKTarget 7
Bip01 RHand2LPocket IKBlend 8
Bip01 Spine1 9
Bip01 Neck 10
Bip01 L Clavicle 11
Bip01 R Clavicle 12
Bip01 Head 13
u_Jaw 14
Bip01 Camera 15
eye left bone 16
eye right bone 17
u_r_eyebrow_3_jnt 18
u_r_eyebrow_2_jnt 19
u_r_eyebrow_1_jnt 20
u_l_eyebrow_1_jnt 21
u_l_eyebrow_2_jnt 22
u_l_eyebrow_3_jnt 23
u_c_lip_top_mid_root_jnt 24
u_c_lip_bottom_mid_root_jnt 25
u_l_lip_corner_root_jnt 26
u_r_lip_corner_root_jnt 27
u_l_lip_top_slope_root_jnt 28
u_l_lip_bottom_slope_root_jnt 29
u_r_lip_top_slope_root_jnt 30
u_r_lip_bottom_slope_root_jnt 31
u_r_cheek_jnt 32
u_l_cheek_jnt 33
u_r_cheekbone_jnt 34
u_l_cheekbone_jnt 35
u_r_nostril_jnt 36
u_l_nostril_jnt 37
Bip01 Look 38
u_l_eyelid_top_b_jnt 39
u_l_eyelid_top_a_jnt 40
u_l_eyelid_top_c_jnt 41
u_l_eyelid_bottom_b_jnt 42
u_l_eyelid_bottom_a_jnt 43
u_l_eyelid_bottom_c_jnt 44
u_r_eyelid_top_c_jnt 45
u_r_eyelid_top_a_jnt 46
u_r_eyelid_top_b_jnt 47
u_r_eyelid_bottom_c_jnt 48
u_r_eyelid_bottom_a_jnt 49
u_r_eyelid_bottom_b_jnt 50
Bip01 HUD 51
u_c_lip_top_mid_jnt 52
u_c_lip_top_mid_bound_jnt 53
u_c_lip_bottom_mid_jnt 54
u_c_lip_bottom_mid_bound_jnt 55
u_l_lip_corner_jnt 56
u_l_lip_corner_bound_jnt 57
u_r_lip_corner_jnt 58
u_r_lip_corner_bound_jnt 59
u_l_lip_top_slope_jnt 60
u_l_lip_top_slope_bound_jnt 61
u_l_lip_bottom_slope_jnt 62
u_l_lip_bottom_slope_bound_jnt 63
u_r_lip_top_slope_jnt 64
u_r_lip_top_slope_bound_jnt 65
u_r_lip_bottom_slope_jnt 66
u_r_lip_bottom_slope_bound_jnt 67
u_l_eyelid_top_b_end_jnt 68
u_l_eyelid_top_a_end_jnt 69
u_l_eyelid_top_c_end_jnt 70
u_l_eyelid_bottom_b_end_jnt 71
u_l_eyelid_bottom_a_end_jnt 72
u_l_eyelid_bottom_c_end_jnt 73
u_r_eyelid_top_c_end_jnt 74
u_r_eyelid_top_a_end_jnt 75
u_r_eyelid_top_b_end_jnt 76
u_r_eyelid_bottom_c_end_jnt 77
u_r_eyelid_bottom_a_end_jnt 78
u_r_eyelid_bottom_b_end_jnt 79
Bip01 L UpperArm 80
Bip01 L Forearm 81
Bip01 L UpperTwist 82
Bip01 L UpperTwist1 83
Bip01 L UpperTwist2 84
Bip01 L ForeTwist 85
Bip01 L ForeTwist1 86
Bip01 L ForeTwist2 87
Bip01 L Hand 88
Bip01 L Finger0 89
Bip01 L Finger1 90
Bip01 L Finger2 91
Bip01 L Finger3 92
Bip01 L Finger4 93
Lweapon bone 94
Bip01 L Finger01 95
Bip01 L Finger02 96
Bip01 L Finger11 97
Bip01 L Finger12 98
Bip01 L Finger21 99
Bip01 L Finger22 100
Bip01 L Finger31 101
Bip01 L Finger32 102
Bip01 L Finger41 103
Bip01 L Finger42 104
Bip01 R UpperArm 105
Bip01 R Forearm 106
Bip01 R UpperTwist 107
Bip01 R UpperTwist1 108
Bip01 R UpperTwist2 109
Bip01 R ForeTwist 110
Bip01 R ForeTwist1 111
Bip01 R ForeTwist2 112
Bip01 R Hand 113
Bip01 R Finger0 114
Bip01 R Finger1 115
Bip01 R Finger2 116
Bip01 R Finger3 117
Bip01 R Finger4 118
Rweapon bone 119
Bip01 R Finger01 120
Bip01 R Finger02 121
Bip01 R Finger11 122
Bip01 R Finger12 123
Bip01 R Finger21 124
Bip01 R Finger22 125
Bip01 R Finger31 126
Bip01 R Finger32 127
Bip01 R Finger41 128
Bip01 R Finger42 129
Rweapon IKTarget 130
Rweapon IKBlend 131
Bip01 R Thigh 132
Bip01 L Thigh 133
Bip01 R ThighCorrect 134
Bip01 L ThighCorrect 135
Bip01 L ButtCorrect 136
Bip01 R ButtCorrect 137
Bip01 R Calf 138
Bip01 R Foot 139
Bip01 planeTargetRight 140
Bip01 planeWeightRight 141
Bip01 R Toe0 142
Bip01 R Heel 143
Bip01 L Calf 144
Bip01 L Foot 145
Bip01 planeTargetLeft 146
Bip01 planeWeightLeft 147
Bip01 L Toe0 148
Bip01 L Heel 149
Bip01 L ButtCorrectNub 150
Bip01 R ButtCorrectNub 151
Deceit Bone Dumper End----
0 0 vote
文章评分

由FAKE

Через тернии к звездам,
через радость и слезы
Мы проложим дорогу

Subscribe
提醒
guest
0 评论
Inline Feedbacks
View all comments