Подведи собственные итоги года совместно с YOUGAME и забери ценные призы! Перейти

LUA скрипт [GS] Weapon Spread & Inaccuracy (VFunc in Lua)

4096
Пользователь
Пользователь
Статус
Оффлайн
Регистрация
13 Май 2022
Сообщения
166
Реакции
33
Lua:
Expand Collapse Copy
local ffi = require("ffi")
local bit = require("bit")
local entity = entity
local globals = globals

ffi.cdef[[
    typedef uintptr_t (__thiscall* get_client_entity_t)(void*, int);
]]

local entity_list_pointer = ffi.cast("void***", client.create_interface("client.dll", "VClientEntityList003"))
local get_client_entity_fn = ffi.cast("get_client_entity_t", entity_list_pointer[0][3])

local get_entity_address = function(entity)
    entity = type(entity) == "number" and entity or entity:get_index()
    return get_client_entity_fn(entity_list_pointer, entity)
end

local function get_vfunc(ptr, index)
    if not ptr or ptr == 0 then
        return nil
    end
    
    local vtable = ffi.cast("void***", ptr)[0]
    if not vtable then
        return nil
    end
    
    return ffi.cast("void*", vtable[index])
end

local function get_weapon_spread(weapon_ptr)
    if not weapon_ptr or weapon_ptr == 0 then
        return 0
    end
    
    local vfunc = get_vfunc(weapon_ptr, 453) -- vfunc idx
    if not vfunc then
        return 0
    end
    
    local get_spread_func = ffi.cast("float(__thiscall*)(void*)", vfunc)
    if not get_spread_func then
        return 0
    end
    
    return get_spread_func(weapon_ptr)
end

local function get_weapon_inaccuracy(weapon_ptr)
    if not weapon_ptr or weapon_ptr == 0 then
        return 0
    end
    
    local vfunc = get_vfunc(weapon_ptr, 483) -- vfunc idx
    if not vfunc then
        return 0
    end
    
    local get_inaccuracy_func = ffi.cast("float(__thiscall*)(void*)", vfunc)
    if not get_inaccuracy_func then
        return 0
    end
    
    return get_inaccuracy_func(weapon_ptr)
end

local function get_local_weapon_spread_info()
    local local_player = entity.get_local_player()
    if not local_player then
        return 0, 0
    end
    
    local weapon = entity.get_player_weapon(local_player)
    if not weapon or weapon == -1 then
        return 0, 0
    end
    
    local weapon_ptr = ffi.cast("void*", get_entity_address(weapon))
    if not weapon_ptr or weapon_ptr == 0 then
        return 0, 0
    end
    
    local spread = get_weapon_spread(weapon_ptr)
    local inaccuracy = get_weapon_inaccuracy(weapon_ptr)
    
    return spread, inaccuracy
end

local weapon_virtuals = {}

local function setup_weapon_virtuals(weapon_ptr)
    if not weapon_ptr or weapon_ptr == 0 then
        return false
    end
    
    if weapon_virtuals[weapon_ptr] then
        return true
    end
    
    local vtable = ffi.cast("void***", weapon_ptr)[0]
    if not vtable then
        return false
    end
    
    weapon_virtuals[weapon_ptr] = {
        get_spread = ffi.cast("float(__thiscall*)(void*)", vtable[453]),
        get_inaccuracy = ffi.cast("float(__thiscall*)(void*)", vtable[483])
    }
    
    return true
end

local function get_weapon_info_optimized()
    local local_player = entity.get_local_player()
    if not local_player then
        return 0, 0
    end
    
    local weapon = entity.get_player_weapon(local_player)
    if not weapon or weapon == -1 then
        return 0, 0
    end
    
    local weapon_ptr = ffi.cast("void*", entity.get_address(weapon))
    if not weapon_ptr or weapon_ptr == 0 then
        return 0, 0
    end
    
    if not setup_weapon_virtuals(weapon_ptr) then
        return 0, 0
    end
    
    local virtuals = weapon_virtuals[weapon_ptr]
    
    local spread = 0
    local inaccuracy = 0
    
    if virtuals.get_spread then
        spread = virtuals.get_spread(weapon_ptr)
    end
    
    if virtuals.get_inaccuracy then
        inaccuracy = virtuals.get_inaccuracy(weapon_ptr)
    end
    
    return spread, inaccuracy
end

local last_weapon = nil
client.set_event_callback("run_command", function()
    local local_player = entity.get_local_player()
    if not local_player then
        return
    end
    
    local weapon = entity.get_player_weapon(local_player)
    if weapon and weapon ~= last_weapon then

        if last_weapon and last_weapon ~= -1 then
            local old_ptr = ffi.cast("void*", get_entity_address(last_weapon))
            if old_ptr and old_ptr ~= 0 then
                weapon_virtuals[old_ptr] = nil
            end
        end
        last_weapon = weapon
    end
end)

return {
    get_weapon_spread = get_local_weapon_spread_info,
    get_weapon_info = get_weapon_info_optimized,
    get_spread_and_inaccuracy = get_local_weapon_spread_info
}

usage:

local weapon_spread = require("weaponspread")

local spread, inaccuracy = weapon_spread.get_spread_and_inaccuracy()
 
local entity_list_pointer = ffi.cast("void***", client.create_interface("client.dll", "VClientEntityList003")) local get_client_entity_fn = ffi.cast("get_client_entity_t", entity_list_pointer[0][3]) local get_entity_address = function(entity) entity = type(entity) == "number" and entity or entity:get_index() return get_client_entity_fn(entity_list_pointer, entity) end
you could do this:

code_language.lua:
Expand Collapse Copy
local native_GetClientEntity = vtable_bind('client.dll', 'VClientEntityList003', 3, 'void*(__thiscall*)(void*, int)')
local get_entity_address = function(ent)
    return native_GetClientEntity(ent)
end
 
Назад
Сверху Снизу