Полезные сниппеты и функции

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
Описание: скрыть/открыть диалог.
Lua:
function enableDialog(bool)
    local memory = require 'memory'
    memory.setint32(sampGetDialogInfoPtr()+40, bool and 1 or 0, true)
    sampToggleCursor(bool)
end
Пример:
Lua:
if wasKeyPressed(0x34) then -- 4
    enableDialog(false)
elseif wasKeyPressed(0x35) -- 5
    enableDialog(true)
end
 
Последнее редактирование:

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
Описание: эмулирует/отправляет RPC и пакет по ID или названию события из SAMP.Lua. Зависимость: SAMP.Lua.
Lua:
-- USAGE
-- emul_rpc(event name, arguments...)
-- emul_rpc(rpc id, arguments...)

local emul_rpc, emul_packet, send_rpc, send_packet
do
    local samp = require 'samp.events'
    local BitStreamIO = require 'samp.events.bitstream_io'

    -- from https://github.com/THE-FYP/SAMP.Lua
    local function write_data(bs, dataType, value)
        if type(dataType) ~= 'table' then
            BitStreamIO[dataType].write(bs, value)
        else -- process nested structures
            for _, it in ipairs(dataType) do
                local name, t = next(it)
                write_data(bs, t, value[name])
            end
        end
    end

    local function fill_bs(entry, bs, ...)
        if not bs then
            bs = raknetNewBitStream()
        end

        if type(entry[3]) == 'function' then
            entry[3](bs, { ... }) -- call custom writing function
        else
            local count = select('#', ...)
            assert(#entry - 1 == count)
            for i = 2, #entry do
                local _, t = next(entry[i]) -- type
                write_data(bs, t, select(i - 1, ...))
            end
        end
        return bs
    end

    local events = { 'OUTCOMING_RPCS', 'OUTCOMING_PACKETS', 'INCOMING_RPCS', 'INCOMING_PACKETS' }
    local function find_event(name)
        if type(name) == 'string' then
            for _, event in ipairs(events) do
                for id, info in pairs(samp.INTERFACE[event]) do
                    local key = info[1]
                    if type(key) == 'table' then
                        for _, _name in ipairs(key) do
                            if _name == name then return id, info end
                        end
                    elseif key == name then return id, info end
                end
            end
        elseif type(name) == 'number' then
            for _, event in ipairs(events) do
                for id, info in pairs(samp.INTERFACE[event]) do
                    if id == name then return id, info end
                end
            end
        end
    end

    function emul_rpc(event, ...)
        local id, entry = find_event(event)
        if not id then
            return
        end

        local bs = fill_bs(entry, nil, ...)
        raknetEmulRpcReceiveBitStream(id, bs)
        raknetDeleteBitStream(bs)
    end

    function emul_packet(event, ...)
        local id, entry = find_event(event)
        if not id then
            return
        end

        local bs = fill_bs(entry, nil, ...)
        raknetEmulPacketReceiveBitStream(id, bs)
        raknetDeleteBitStream(bs)
    end

    function send_rpc(event, ...)
        local id, entry = find_event(event)
        if not id then
            return
        end

        local bs = fill_bs(entry, nil, ...)
        raknetSendRpc(id, bs)
        raknetDeleteBitStream(bs)
    end

    function send_packet(event, ...)
        local id, entry = find_event(event)
        if not id then
            return
        end

        local bs = raknetNewBitStream()
        raknetBitStreamWriteInt8(bs, id)
        fill_bs(entry, bs, ...)
        raknetSendBitStream(bs)
        raknetDeleteBitStream(bs)
    end
end

Пример:
Lua:
sampRegisterChatCommand('setskin', function(text)
    local id, skin = text:match('(%d+)%s+(%d+)')
    if id then
        emul_rpc('onSetPlayerSkin', tonumber(id), tonumber(skin))
    end
end)

sampRegisterChatCommand('addmsg', function(text)
    emul_rpc(RPC_SCRCLIENTMESSAGE, -1, text)
end)

Описание: эмулирует RPC по названию Hook'а.
Lua:
function emul_rpc(hook, parameters)
    local bs_io = require 'samp.events.bitstream_io'
    local handler = require 'samp.events.handlers'
    local extra_types = require 'samp.events.extra_types'
    local hooks = {

        --[[ Outgoing rpcs
        ['onSendEnterVehicle'] = { 'int16', 'bool8', 26 },
        ['onSendClickPlayer'] = { 'int16', 'int8', 23 },
        ['onSendClientJoin'] = { 'int32', 'int8', 'string8', 'int32', 'string8', 'string8', 'int32', 25 },
        ['onSendEnterEditObject'] = { 'int32', 'int16', 'int32', 'vector3d', 27 },
        ['onSendCommand'] = { 'string32', 50 },
        ['onSendSpawn'] = { 52 },
        ['onSendDeathNotification'] = { 'int8', 'int16', 53 },
        ['onSendDialogResponse'] = { 'int16', 'int8', 'int16', 'string8', 62 },
        ['onSendClickTextDraw'] = { 'int16', 83 },
        ['onSendVehicleTuningNotification'] = { 'int32', 'int32', 'int32', 'int32', 96 },
        ['onSendChat'] = { 'string8', 101 },
        ['onSendClientCheckResponse'] = { 'int8', 'int32', 'int8', 103 },
        ['onSendVehicleDamaged'] = { 'int16', 'int32', 'int32', 'int8', 'int8', 106 },
        ['onSendEditAttachedObject'] = { 'int32', 'int32', 'int32', 'int32', 'vector3d', 'vector3d', 'vector3d', 'int32', 'int32', 116 },
        ['onSendEditObject'] = { 'bool', 'int16', 'int32', 'vector3d', 'vector3d', 117 },
        ['onSendInteriorChangeNotification'] = { 'int8', 118 },
        ['onSendMapMarker'] = { 'vector3d', 119 },
        ['onSendRequestClass'] = { 'int32', 128 },
        ['onSendRequestSpawn'] = { 129 },
        ['onSendPickedUpPickup'] = { 'int32', 131 },
        ['onSendMenuSelect'] = { 'int8', 132 },
        ['onSendVehicleDestroyed'] = { 'int16', 136 },
        ['onSendQuitMenu'] = { 140 },
        ['onSendExitVehicle'] = { 'int16', 154 },
        ['onSendUpdateScoresAndPings'] = { 155 },
        ['onSendGiveDamage'] = { 'int16', 'float', 'int32', 'int32', 115 },
        ['onSendTakeDamage'] = { 'int16', 'float', 'int32', 'int32', 115 },]]

        -- Incoming rpcs
        ['onInitGame'] = { 139 },
        ['onPlayerJoin'] = { 'int16', 'int32', 'bool8', 'string8', 137 },
        ['onPlayerQuit'] = { 'int16', 'int8', 138 },
        ['onRequestClassResponse'] = { 'bool8', 'int8', 'int32', 'int8', 'vector3d', 'float', 'Int32Array3', 'Int32Array3', 128 },
        ['onRequestSpawnResponse'] = { 'bool8', 129 },
        ['onSetPlayerName'] = { 'int16', 'string8', 'bool8', 11 },
        ['onSetPlayerPos'] = { 'vector3d', 12 },
        ['onSetPlayerPosFindZ'] = { 'vector3d', 13 },
        ['onSetPlayerHealth'] = { 'float', 14 },
        ['onTogglePlayerControllable'] = { 'bool8', 15 },
        ['onPlaySound'] = { 'int32', 'vector3d', 16 },
        ['onSetWorldBounds'] = { 'float', 'float', 'float', 'float', 17 },
        ['onGivePlayerMoney'] = { 'int32', 18 },
        ['onSetPlayerFacingAngle'] = { 'float', 19 },
        --['onResetPlayerMoney'] = { 20 },
        --['onResetPlayerWeapons'] = { 21 },
        ['onGivePlayerWeapon'] = { 'int32', 'int32', 22 },
        --['onCancelEdit'] = { 28 },
        ['onSetPlayerTime'] = { 'int8', 'int8', 29 },
        ['onSetToggleClock'] = { 'bool8', 30 },
        ['onPlayerStreamIn'] = { 'int16', 'int8', 'int32', 'vector3d', 'float', 'int32', 'int8', 32 },
        ['onSetShopName'] = { 'string256', 33 },
        ['onSetPlayerSkillLevel'] = { 'int16', 'int32', 'int16', 34 },
        ['onSetPlayerDrunk'] = { 'int32', 35 },
        ['onCreate3DText'] = { 'int16', 'int32', 'vector3d', 'float', 'bool8', 'int16', 'int16', 'encodedString4096', 36 },
        --['onDisableCheckpoint'] = { 37 },
        ['onSetRaceCheckpoint'] = { 'int8', 'vector3d', 'vector3d', 'float', 38 },
        --['onDisableRaceCheckpoint'] = { 39 },
        --['onGamemodeRestart'] = { 40 },
        ['onPlayAudioStream'] = { 'string8', 'vector3d', 'float', 'bool8', 41 },
        --['onStopAudioStream'] = { 42 },
        ['onRemoveBuilding'] = { 'int32', 'vector3d', 'float', 43 },
        ['onCreateObject'] = { 44 },
        ['onSetObjectPosition'] = { 'int16', 'vector3d', 45 },
        ['onSetObjectRotation'] = { 'int16', 'vector3d', 46 },
        ['onDestroyObject'] = { 'int16', 47 },
        ['onPlayerDeathNotification'] = { 'int16', 'int16', 'int8', 55 },
        ['onSetMapIcon'] = { 'int8', 'vector3d', 'int8', 'int32', 'int8', 56 },
        ['onRemoveVehicleComponent'] = { 'int16', 'int16', 57 },
        ['onRemove3DTextLabel'] = { 'int16', 58 },
        ['onPlayerChatBubble'] = { 'int16', 'int32', 'float', 'int32', 'string8', 59 },
        ['onUpdateGlobalTimer'] = { 'int32', 60 },
        ['onShowDialog'] = { 'int16', 'int8', 'string8', 'string8', 'string8', 'encodedString4096', 61 },
        ['onDestroyPickup'] = { 'int32', 63 },
        ['onLinkVehicleToInterior'] = { 'int16', 'int8', 65 },
        ['onSetPlayerArmour'] = { 'float', 66 },
        ['onSetPlayerArmedWeapon'] = { 'int32', 67 },
        ['onSetSpawnInfo'] = { 'int8', 'int32', 'int8', 'vector3d', 'float', 'Int32Array3', 'Int32Array3', 68 },
        ['onSetPlayerTeam'] = { 'int16', 'int8', 69 },
        ['onPutPlayerInVehicle'] = { 'int16', 'int8', 70 },
        --['onRemovePlayerFromVehicle'] = { 71 },
        ['onSetPlayerColor'] = { 'int16', 'int32', 72 },
        ['onDisplayGameText'] = { 'int32', 'int32', 'string32', 73 },
        --['onForceClassSelection'] = { 74 },
        ['onAttachObjectToPlayer'] = { 'int16', 'int16', 'vector3d', 'vector3d', 75 },
        ['onInitMenu'] = { 76 },
        ['onShowMenu'] = { 'int8', 77 },
        ['onHideMenu'] = { 'int8', 78 },
        ['onCreateExplosion'] = { 'vector3d', 'int32', 'float', 79 },
        ['onShowPlayerNameTag'] = { 'int16', 'bool8', 80 },
        ['onAttachCameraToObject'] = { 'int16', 81 },
        ['onInterpolateCamera'] = { 'bool', 'vector3d', 'vector3d', 'int32', 'int8', 82 },
        ['onGangZoneStopFlash'] = { 'int16', 85 },
        ['onApplyPlayerAnimation'] = { 'int16', 'string8', 'string8', 'bool', 'bool', 'bool', 'bool', 'int32', 86 },
        ['onClearPlayerAnimation'] = { 'int16', 87 },
        ['onSetPlayerSpecialAction'] = { 'int8', 88 },
        ['onSetPlayerFightingStyle'] = { 'int16', 'int8', 89 },
        ['onSetPlayerVelocity'] = { 'vector3d', 90 },
        ['onSetVehicleVelocity'] = { 'bool8', 'vector3d', 91 },
        ['onServerMessage'] = { 'int32', 'string32', 93 },
        ['onSetWorldTime'] = { 'int8', 94 },
        ['onCreatePickup'] = { 'int32', 'int32', 'int32', 'vector3d', 95 },
        ['onMoveObject'] = { 'int16', 'vector3d', 'vector3d', 'float', 'vector3d', 99 },
        ['onEnableStuntBonus'] = { 'bool', 104 },
        ['onTextDrawSetString'] = { 'int16', 'string16', 105 },
        ['onSetCheckpoint'] = { 'vector3d', 'float', 107 },
        ['onCreateGangZone'] = { 'int16', 'vector2d', 'vector2d', 'int32', 108 },
        ['onPlayCrimeReport'] = { 'int16', 'int32', 'int32', 'int32', 'int32', 'vector3d', 112 },
        ['onGangZoneDestroy'] = { 'int16', 120 },
        ['onGangZoneFlash'] = { 'int16', 'int32', 121 },
        ['onStopObject'] = { 'int16', 122 },
        ['onSetVehicleNumberPlate'] = { 'int16', 'string8', 123 },
        ['onTogglePlayerSpectating'] = { 'bool32', 124 },
        ['onSpectatePlayer'] = { 'int16', 'int8', 126 },
        ['onSpectateVehicle'] = { 'int16', 'int8', 127 },
        ['onShowTextDraw'] = { 134 },
        ['onSetPlayerWantedLevel'] = { 'int8', 133 },
        ['onTextDrawHide'] = { 'int16', 135 },
        ['onRemoveMapIcon'] = { 'int8', 144 },
        ['onSetWeaponAmmo'] = { 'int8', 'int16', 145 },
        ['onSetGravity'] = { 'float', 146 },
        ['onSetVehicleHealth'] = { 'int16', 'float', 147 },
        ['onAttachTrailerToVehicle'] = { 'int16', 'int16', 148 },
        ['onDetachTrailerFromVehicle'] = { 'int16', 149 },
        ['onSetWeather'] = { 'int8', 152 },
        ['onSetPlayerSkin'] = { 'int32', 'int32', 153 },
        ['onSetInterior'] = { 'int8', 156 },
        ['onSetCameraPosition'] = { 'vector3d', 157 },
        ['onSetCameraLookAt'] = { 'vector3d', 'int8', 158 },
        ['onSetVehiclePosition'] = { 'int16', 'vector3d', 159 },
        ['onSetVehicleAngle'] = { 'int16', 'float', 160 },
        ['onSetVehicleParams'] = { 'int16', 'int16', 'bool8', 161 },
        --['onSetCameraBehind'] = { 162 },
        ['onChatMessage'] = { 'int16', 'string8', 101 },
        ['onConnectionRejected'] = { 'int8', 130 },
        ['onPlayerStreamOut'] = { 'int16', 163 },
        ['onVehicleStreamIn'] = { 164 },
        ['onVehicleStreamOut'] = { 'int16', 165 },
        ['onPlayerDeath'] = { 'int16', 166 },
        ['onPlayerEnterVehicle'] = { 'int16', 'int16', 'bool8', 26 },
        ['onUpdateScoresAndPings'] = { 'PlayerScorePingMap', 155 },
        ['onSetObjectMaterial'] = { 84 },
        ['onSetObjectMaterialText'] = { 84 },
        ['onSetVehicleParamsEx'] = { 'int16', 'int8', 'int8', 'int8', 'int8', 'int8', 'int8', 'int8', 'int8', 'int8', 'int8', 'int8', 'int8', 'int8', 'int8', 'int8', 'int8', 24 },
        ['onSetPlayerAttachedObject'] = { 'int16', 'int32', 'bool', 'int32', 'int32', 'vector3d', 'vector3d', 'vector3d', 'int32', 'int32', 113 }

    }
    local handler_hook = {
        ['onInitGame'] = true,
        ['onCreateObject'] = true,
        ['onInitMenu'] = true,
        ['onShowTextDraw'] = true,
        ['onVehicleStreamIn'] = true,
        ['onSetObjectMaterial'] = true,
        ['onSetObjectMaterialText'] = true
    }
    local extra = {
        ['PlayerScorePingMap'] = true,
        ['Int32Array3'] = true
    }
    local hook_table = hooks[hook]
    if hook_table then
        local bs = raknetNewBitStream()
        if not handler_hook[hook] then
            local max = #hook_table-1
            if max > 0 then
                for i = 1, max do
                    local p = hook_table[i]
                    if extra[p] then extra_types[p]['write'](bs, parameters[i])
                    else bs_io[p]['write'](bs, parameters[i]) end
                end
            end
        else
            if hook == 'onInitGame' then handler.on_init_game_writer(bs, parameters)
            elseif hook == 'onCreateObject' then handler.on_create_object_writer(bs, parameters)
            elseif hook == 'onInitMenu' then handler.on_init_menu_writer(bs, parameters)
            elseif hook == 'onShowTextDraw' then handler.on_show_textdraw_writer(bs, parameters)
            elseif hook == 'onVehicleStreamIn' then handler.on_vehicle_stream_in_writer(bs, parameters)
            elseif hook == 'onSetObjectMaterial' then handler.on_set_object_material_writer(bs, parameters, 1)
            elseif hook == 'onSetObjectMaterialText' then handler.on_set_object_material_writer(bs, parameters, 2) end
        end
        raknetEmulRpcReceiveBitStream(hook_table[#hook_table], bs)
        raknetDeleteBitStream(bs)
    end
end
Пример:
Lua:
sampRegisterChatCommand('setskin', function(text)
    local id, skin = text:match('(%d+) (%d+)')
    if id then
        emul_rpc('onSetPlayerSkin' --[[Хук изменения скина]], { tonumber(id) --[[ID игрока]], tonumber(skin) --[[ID скина]] })
    end
end)
Lua:
sampRegisterChatCommand('obj_veg', function(id)
    if tonumber(id) then
        emul_rpc('onSetObjectMaterial', { tonumber(id) --[[ID объекта]], { materialId = 1, modelId = 1, libraryName = 'vegascourtbld', textureName = 'marbletilewal1_256', color = -1 } --[[Параметры материала]] })
    end
end)
 
Последнее редактирование:

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
Описание: узнать/изменить значение выносливости.
Lua:
function getSprintLocalPlayer()
    local float = memory.getfloat(0xB7CDB4)
    return float/31.47000244
end

function setSprintLocalPlayer(number)
    memory.setfloat(0xB7CDB4, number * 31.47000244)
end

Описание: узнать/изменить значение кислорода.
Lua:
function getWaterLocalPlayer()
    local float = memory.getfloat(0xB7CDE0)
    return float/39.97000244
end

function setWaterLocalPlayer(number)
    memory.setfloat(0xB7CDE0, number * 39.97000244)
end

p.s. в начало кода напишите
Lua:
memory = require 'memory'
 

AnWu

Известный
Всефорумный модератор
4,777
5,400
Описание: Устанавливает положение курсора в чате. ВАЖНО: Если используете sampSetChatInputText(), эту функцию вызывайте после её, т.к. sampSetChatInputText() устанавливает новое положение курсора.
Принимает два параметра - начало и конец выделения текста. Если второй параметр опущен, просто устанавливает курсор в нужное место.
Lua:
function sampSetChatInputCursor(start, finish)
    local finish = finish or start
    local start, finish = tonumber(start), tonumber(finish)
    local mem = require 'memory'
    local chatInfoPtr = sampGetInputInfoPtr()
    local chatBoxInfo = getStructElement(chatInfoPtr, 0x8, 4)
    mem.setint8(chatBoxInfo + 0x11E, start)
    mem.setint8(chatBoxInfo + 0x119, finish)
    return true
end
Пример использования:
Lua:
local vkeys = require 'vkeys'
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then
        return
    end
    while not isSampAvailable() do wait(100) end

    while true do
        wait(0)
        if wasKeyPressed(vkeys.VK_R) then
            sampSetChatInputText("test test test")
            sampSetChatInputCursor(4, 10)
            sampSetChatInputEnabled(true)
        end
    end
end

function sampSetChatInputCursor(start, finish)
    local finish = finish or start
    local start, finish = tonumber(start), tonumber(finish)
    local mem = require 'memory'
    local chatInfoPtr = sampGetInputInfoPtr()
    local chatBoxInfo = getStructElement(chatInfoPtr, 0x8, 4)
    mem.setint8(chatBoxInfo + 0x11E, start)
    mem.setint8(chatBoxInfo + 0x119, finish)
    return true
end
 

for (;;)

Участник
71
31
поиск в таблице по значению
Lua:
function checkIntable(t, str)
  for k, v in pairs(t) do
    if v == str then return true end
  end
  return false
end
Пример:
Lua:
local table = {144, 1634, 345345, 467}
local key = 144

function checkIntable(t, key)
  for k, v in pairs(t) do
    if v == key then return true end
  end
  return false
end

if checktable(table, key) then
  print("Ключ", key, "существует в таблице")
else
  print("Ключа", key, "не существует в таблице")
end

output: "Ключ 144 существует в таблице"
 
Последнее редактирование:

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
Описание: нопает RPC/Packet по названию события с SAMP.Lua.
Lua:
local samp = require 'samp.events'

local nop_hook
do
    local status = { OUTCOMING_RPCS = {}, OUTCOMING_PACKETS = {}, INCOMING_RPCS = {}, INCOMING_PACKETS = {} }
    local availabled = {}

    local function find_event(name)
        for event, _ in pairs(status) do
            for id, info in pairs(samp.INTERFACE[event]) do
                local key = info[1]
                if type(key) == 'table' then
                    for _, _name in ipairs(key) do
                        if _name == name then return id, event end
                    end
                elseif key == name then return id, event end
            end
        end
    end

    function nop_hook(event, bool)
        if availabled[event] == nil then
            local id, ev = find_event(event)
            if not id then return end
            availabled[event] = { ev, id }
        end
        local info = availabled[event]
        status[info[1]][info[2]] = bool
    end

    addEventHandler('onSendRpc', function(id) return not status.OUTCOMING_RPCS[id] end)
    addEventHandler('onSendPacket', function(id) return not status.OUTCOMING_PACKETS[id] end)
    addEventHandler('onReceiveRpc', function(id) return not status.INCOMING_RPCS[id] end)
    addEventHandler('onReceivePacket', function(id) return not status.INCOMING_PACKETS[id] end)
end

Lua:
function nopHook(name, bool)
    local samp = require 'samp.events'
    samp[name] = function()
        if bool then return false end
    end
end
Пример:
Lua:
nop_hook('onSendPlayerSync', true) -- нопает пакет onSendPlayerSync.
setCharCoordinates(playerPed, x, y, z)
nop_hook('onSendPlayerSync', false) -- прекращает нопать пакет.
 
Последнее редактирование:
1,417
1,032
Описание: работа в свернутом режиме(необходимо перевести игру в оконный режим и не ставить на паузу)
Lua:
function WorkInBackground(work)
    local memory = require 'memory'
    if work then -- on
        memory.setuint8(7634870, 1) 
        memory.setuint8(7635034, 1)
        memory.fill(7623723, 144, 8)
        memory.fill(5499528, 144, 6)
    else -- off
        memory.setuint8(7634870, 0)
        memory.setuint8(7635034, 0)
        memory.hex2bin('5051FF1500838500', 7623723, 8)
        memory.hex2bin('0F847B010000', 5499528, 6)
    end 
end
 

Laine_prikol

ДИДЖЕЙ МАДЕСТ
Проверенный
260
218
Описание: Разбивает строку на массив.
Lua:
function stringToArray(str)
local t = {}
for i = 1, #str do
  t[i] = str:sub(i, i)
end
return t
end
Пример:
Lua:
local tbl = stringToArray("Hello world")

print(table.concat(tbl, " "))
-- Напишет: H e l l o  w o r l d
 

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
Описание: получить точное время.
Lua:
function getTime(timezone)
    local https = require 'ssl.https'
    local time = https.request('http://alat.specihost.com/unix-time/')
    return time and tonumber(time:match('^Current Unix Timestamp: <b>(%d+)</b>')) + (timezone or 0) * 60 * 60
end
Пример:
Lua:
local time = getTime(3) -- moscow time.
print(os.date('%H:%M:%S', time))
 
Последнее редактирование:

checkdasound

Известный
Проверенный
963
410
Описание: Отключение чит-кодов игры (Вы сможете использовать встроенные чит-коды по типу HESOYAM в своих скриптах)
Lua:
function DisaCheatsInSAMP()
    memory.write(0x4384D0, 0x9090, 2)
    memory.write(0x4384D2, 0x90, 1)
    memory.write(0x4384D3, 0xE9, 1)
    memory.write(0x4384D4, 0x000000CD, 4)
end
Пример использования:
Lua:
local mem = require 'memory'

DisaCheatsInSAMP()
if testCheat("HESOYAM") then
    sampAddChatMessage(">GREENTEXT", 0x00DD00)
end
 

function DisaCheatsInSAMP()
    mem.write(0x4384D0, 0x9090, 2)
    mem.write(0x4384D2, 0x90, 1)
    mem.write(0x4384D3, 0xE9, 1)
    mem.write(0x4384D4, 0x000000CD, 4)
end
 

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
Описание: получить память жесткого диска (свободно и всего) в КБ.
Код:
Lua:
ffi = require 'ffi'
ffi.cdef[[
typedef uint32_t DWORD;

typedef union _ULARGE_INTEGER {
  struct {
    DWORD LowPart;
    DWORD HighPart;
  };
  struct {
    DWORD LowPart;
    DWORD HighPart;
  } u;
  unsigned __int64 QuadPart;
} ULARGE_INTEGER, *PULARGE_INTEGER;

bool __stdcall GetDiskFreeSpaceExA(
  char* lpDirectoryName,
  int lpFreeBytesAvailable,
  int lpTotalNumberOfBytes,
  int lpTotalNumberOfFreeBytes
);
]]

function getHardDiskMemory(disk)
  local free_p = ffi.cast('intptr_t', ffi.cast('ULARGE_INTEGER*', ffi.new('ULARGE_INTEGER', {})))
  local all_p = ffi.cast('intptr_t', ffi.cast('ULARGE_INTEGER*', ffi.new('ULARGE_INTEGER', {})))
  ffi.C.GetDiskFreeSpaceExA(ffi.cast('char*', disk..':/'), free_p, all_p, 0)

  local free = ffi.new('DWORD[1]', ffi.cast('ULARGE_INTEGER*', free_p).QuadPart / 1024)
  local all = ffi.new('DWORD[1]', ffi.cast('ULARGE_INTEGER*', all_p).QuadPart / 1024)
  return free[0], all[0]
end
Пример:
Lua:
for i, k in ipairs{'C', 'D'} do
  local free, all = getHardDiskMemory(k)
  print('Диcк '..k..':')
  print('- Свободно: '..('%.02f'):format( free / 1024 / 1024 )..' ГБ')
  print('- Занято: '..('%.02f'):format( ( all / 1024 / 1024 ) - ( free / 1024 / 1024 ) )..' ГБ')
  print('- Всего: '..('%.02f'):format( all / 1024 / 1024 )..' ГБ')
end
 

Aniki

🐰
Администратор
1,229
1,564
Описание: Открывает в браузере указанную ссылку.
Lua:
local ffi = require 'ffi'
ffi.cdef [[
    void* __stdcall ShellExecuteA(void* hwnd, const char* op, const char* file, const char* params, const char* dir, int show_cmd);
    uint32_t __stdcall CoInitializeEx(void*, uint32_t);
]]
local shell32 = ffi.load 'Shell32'
local ole32 = ffi.load 'Ole32'
ole32.CoInitializeEx(nil, 2 + 4)
print(shell32.ShellExecuteA(nil, 'open', 'Ваша ссылка', nil, nil, 1))
Пример использования:
Lua:
local ffi = require 'ffi'
ffi.cdef [[
    void* __stdcall ShellExecuteA(void* hwnd, const char* op, const char* file, const char* params, const char* dir, int show_cmd);
    uint32_t __stdcall CoInitializeEx(void*, uint32_t);
]]
local shell32 = ffi.load 'Shell32'
local ole32 = ffi.load 'Ole32'
ole32.CoInitializeEx(nil, 2 + 4)
print(shell32.ShellExecuteA(nil, 'open', 'https://vk.com/thenortonpclife', nil, nil, 1))
Дико извиняюсь за оффтоп, ибо не знаю куда еще написать. Чем это вот все лучше чем:
Lua:
os.execute('explorer "http://google.com"')
?
 

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
Ставит точки в числах, например
Lua:
print(setpoint(1000000)) -- output: 1.000.000
Сама функция:
Lua:
function setpoint(p)
if type(p) == "number" then
abs = tostring(p)
rabs = abs:reverse()
i = {}
for s in rabs:gmatch(".") do
table.insert(i, s)
end
for k, v in pairs(i) do
if math.fmod(k, 4) == 0 then
table.insert(i, k, ".")
end
end
str = ""
for k, v in pairs(i) do
str = str..v
end
return str:reverse()
elseif type(p) == "string" then
abs = p
rabs = abs:reverse()
i = {}
for s in rabs:gmatch(".") do
table.insert(i, s)
end
for k, v in pairs(i) do
if math.fmod(k, 4) == 0 then
table.insert(i, k, ".")
end
end
str = ""
for k, v in pairs(i) do
str = str..v
end
return str:reverse()
else
return 0
end
end
Lua:
function sumFormat(a)
    local b = tostring(a):reverse():gsub('%d%d%d', '%1.')
    local c = b:reverse():gsub('^%.', '')
    return c
end
может быть это:
upload_2018-6-27_14-41-40.png

так что обновляю функцию
Lua:
function sumFormat(a)
    local b, e = ('%d'):format(a):gsub('^%-', '')
    local c = b:reverse():gsub('%d%d%d', '%1.')
    local d = c:reverse():gsub('^%.', '')
    return (e == 1 and '-' or '')..d
end
upload_2018-6-27_14-46-36.png
 

Aniki

🐰
Администратор
1,229
1,564
Описание: Круговые диаграммы для имгуи (долой скучные гистограммы!), может кому будет полезно для модуля статистики. Лень было оформлять как отдельный модуль, поэтому лью сюда. UPD: теперь курсор после диаграммы встает в исходное положение под диаграммой
UPD2: Отказался от своих констант, используются только константы из стилей. Теперь диаграммы корректно работают со сдвигом (indent)
Lua:
function imgui.RoundDiagram(valTable, radius, segments)
    local draw_list = imgui.GetWindowDrawList()
    local default = imgui.GetStyle().AntiAliasedShapes
    imgui.GetStyle().AntiAliasedShapes = false
    local center = imgui.ImVec2(imgui.GetCursorScreenPos().x + radius, imgui.GetCursorScreenPos().y + radius)
    local function round(num)
        if num >= 0 then
            if select(2, math.modf(num)) >= 0.5 then
                return math.ceil(num)
            else
                return math.floor(num)
            end
        else
            if select(2, math.modf(num)) >= 0.5 then
                return math.floor(num)
            else
                return math.ceil(num)
            end
        end
    end

    local sum = 0
    local q = {}
 
    for k, v in ipairs(valTable) do
        sum = sum + v.v
    end

    for k, v in ipairs(valTable) do
        if k > 1 then
            q[k] = q[k-1] + round(valTable[k].v/sum*segments)
        else
            q[k] = round(valTable[k].v/sum*segments)
        end
    end

    local current = 1
    local count = 1
    local theta = 0
    local step = 2*math.pi/segments

    for i = 1, segments do -- theta < 2*math.pi
        if q[current] < count then
            current = current + 1
        end
        draw_list:AddTriangleFilled(center, imgui.ImVec2(center.x + radius*math.cos(theta), center.y + radius*math.sin(theta)), imgui.ImVec2(center.x + radius*math.cos(theta+step), center.y + radius*math.sin(theta+step)), valTable[current].color)
        theta = theta + step
        count = count + 1
    end

    local fontsize = imgui.GetFontSize()
    local indented = 2*(radius + imgui.GetStyle().ItemSpacing.x)
    imgui.Indent(indented)

    imgui.SameLine(0)
    imgui.NewLine() -- awful fix for first line padding
    imgui.SetCursorScreenPos(imgui.ImVec2(imgui.GetCursorScreenPos().x, center.y - imgui.GetTextLineHeight() * #valTable / 2))
    for k, v in ipairs(valTable) do
        draw_list:AddRectFilled(imgui.ImVec2(imgui.GetCursorScreenPos().x, imgui.GetCursorScreenPos().y), imgui.ImVec2(imgui.GetCursorScreenPos().x + fontsize, imgui.GetCursorScreenPos().y + fontsize), v.color)
        imgui.SetCursorPosX(imgui.GetCursorPosX() + fontsize*1.3)
        imgui.Text(u8(v.name .. ' - ' .. v.v .. ' (' .. string.format('%.2f', v.v/sum*100) .. '%)'))
    end
    imgui.Unindent(indented)
    imgui.SetCursorScreenPos(imgui.ImVec2(imgui.GetCursorScreenPos().x, center.y + radius + imgui.GetTextLineHeight()))
    imgui.GetStyle().AntiAliasedShapes = default
end
Пример использования:
Каждый элемент диаграммы представляет из себя структуру с тремя полями - значение(v), имя(name) и цвет(color). Цвет в формате ABGR (перевернутый RGBA). Первый аргумент функции - таблица с элементами диаграммы, второй - радиус диаграммы в пикселях, третий - число секторов (число углов в правильном многоугольнике).
Lua:
    local flightDiagram = {
        {
            v = 1553,
            name = 'Las Venturas - San Fierro',
            color = 0xFFFF7755
        },
        {
            v = 26,
            name = 'Las Venturas - Los Santos',
            color = 0xFF77FF55
        },
        {
            v = 0,
            name = 'Los Santos - San Fierro',
            color = 0xFF3F85CD
        }
    }

    imgui.RoundDiagram(flightDiagram, 60, 50)
Скриншот с примером прилагается
 

Вложения

  • sa-mp-247.png
    sa-mp-247.png
    5.3 KB · Просмотры: 2,492
Последнее редактирование:

imring

Ride the Lightning
Всефорумный модератор
2,365
2,552
Описание: оператор множественного выбора switch.
Код:
Lua:
function switch(key)
    return function(tab)
        local current = tab[key] or tab['default']
        if type(current) == 'function' then current() end
    end
end
Пример:
Lua:
switch(2)
{
  function() print'hello' end,
  function() print'bye' end,
  ['default'] = function() print'error' end
}
-- console: bye