Вопросы по Lua скриптингу

Общая тема для вопросов по разработке скриптов на языке программирования Lua, в частности под MoonLoader.
  • Задавая вопрос, убедитесь, что его нет в списке частых вопросов и что на него ещё не отвечали (воспользуйтесь поиском).
  • Поищите ответ в теме посвященной разработке Lua скриптов в MoonLoader
  • Отвечая, убедитесь, что ваш ответ корректен.
  • Старайтесь как можно точнее выразить мысль, а если проблема связана с кодом, то обязательно прикрепите его к сообщению, используя блок [code=lua]здесь мог бы быть ваш код[/code].
  • Если вопрос связан с MoonLoader-ом первым делом желательно поискать решение на wiki.

Частые вопросы

Как научиться писать скрипты? С чего начать?
Информация - Гайд - Всё о Lua скриптинге для MoonLoader(https://blast.hk/threads/22707/)
Как вывести текст на русском? Вместо русского текста у меня какие-то каракули.
Изменить кодировку файла скрипта на Windows-1251. В Atom: комбинация клавиш Ctrl+Shift+U, в Notepad++: меню Кодировки -> Кодировки -> Кириллица -> Windows-1251.
Как получить транспорт, в котором сидит игрок?
Lua:
local veh = storeCarCharIsInNoSave(PLAYER_PED)
Как получить свой id или id другого игрока?
Lua:
local _, id = sampGetPlayerIdByCharHandle(PLAYER_PED) -- получить свой ид
local _, id = sampGetPlayerIdByCharHandle(ped) -- получить ид другого игрока. ped - это хендл персонажа
Как проверить, что строка содержит какой-то текст?
Lua:
if string.find(str, 'текст', 1, true) then
-- строка str содержит "текст"
end
Как эмулировать нажатие игровой клавиши?
Lua:
local game_keys = require 'game.keys' -- где-нибудь в начале скрипта вне функции main

setGameKeyState(game_keys.player.FIREWEAPON, -1) -- будет сэмулировано нажатие клавиши атаки
Все иды клавиш находятся в файле moonloader/lib/game/keys.lua.
Подробнее о функции setGameKeyState здесь: lua - setgamekeystate | BlastHack — DEV_WIKI(https://www.blast.hk/wiki/lua:setgamekeystate)
Как получить id другого игрока, в которого целюсь я?
Lua:
local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE) -- получить хендл персонажа, в которого целится игрок
if valid and doesCharExist(ped) then -- если цель есть и персонаж существует
  local result, id = sampGetPlayerIdByCharHandle(ped) -- получить samp-ид игрока по хендлу персонажа
  if result then -- проверить, прошло ли получение ида успешно
    -- здесь любые действия с полученным идом игрока
  end
end
Как зарегистрировать команду чата SAMP?
Lua:
-- До бесконечного цикла/задержки
sampRegisterChatCommand("mycommand", function (param)
     -- param будет содержать весь текст введенный после команды, чтобы разделить его на аргументы используйте string.match()
    sampAddChatMessage("MyCMD", -1)
end)
Крашит игру при вызове sampSendChat. Как это исправить?
Это происходит из-за бага в SAMPFUNCS, когда производится попытка отправки пакета определенными функциями изнутри события исходящих RPC и пакетов. Исправления для этого бага нет, но есть способ не провоцировать его. Вызов sampSendChat изнутри обработчика исходящих RPC/пакетов нужно обернуть в скриптовый поток с нулевой задержкой:
Lua:
function onSendRpc(id)
  -- крашит:
  -- sampSendChat('Send RPC: ' .. id)

  -- норм:
  lua_thread.create(function()
    wait(0)
    sampSendChat('Send RPC: ' .. id)
  end)
end
 
Последнее редактирование:

joumey

Активный
195
44
Где можnо nайти иnфу как этим пользоваться
Код:
    // Stateful path API, add points then finish with PathFillConvex() or PathStroke()
    // - Filled shapes must always use clockwise winding order. The anti-aliasing fringe depends on it. Counter-clockwise shapes will have "inward" anti-aliasing.
    inline    void  PathClear()                                                 { _Path.Size = 0; }
    inline    void  PathLineTo(const ImVec2& pos)                               { _Path.push_back(pos); }
    inline    void  PathLineToMergeDuplicate(const ImVec2& pos)                 { if (_Path.Size == 0 || memcmp(&_Path.Data[_Path.Size - 1], &pos, 8) != 0) _Path.push_back(pos); }
    inline    void  PathFillConvex(ImU32 col)                                   { AddConvexPolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; }
    inline    void  PathStroke(ImU32 col, ImDrawFlags flags = 0, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, flags, thickness); _Path.Size = 0; }
    IMGUI_API void  PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 0);
    IMGUI_API void  PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12);                // Use precomputed angles for a 12 steps circle
    IMGUI_API void  PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0); // Cubic Bezier (4 control points)
    IMGUI_API void  PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0);               // Quadratic Bezier (3 control points)
    IMGUI_API void  PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawFlags flags = 0);
up
 

s3nder_

Известный
60
83
Lua:
local str = 'хуй' -- слово которое нужно искать

require('samp.events').onServerMessage = function (color, text)
    if text:match('(%w+_%w+)%[(%d+)%] говорит:{B7AFAF}(.+)') then
        local nick, id, msg = text:match('(%w+_%w+)%[(%d+)%] говорит:{B7AFAF}(.+)')
        if msg:find(str) then
            sampAddChatMessage(id..' написал '..str, -1)
        end
    end
end
Результат:
1685973068040.png
 

MTG MODS

Активный
260
181
Как перепродключиться к серверу? Знаю что есть фастконект/реконект от Аира, но мне надо именно на луа реконект

Пробовал sampSetGamestate, работает, но баги с маппингом
 

s3nder_

Известный
60
83
Как перепродключиться к серверу? Знаю что есть фастконект/реконект от Аира, но мне надо именно на луа реконект

Пробовал sampSetGamestate, работает, но баги с маппингом
Lua:
sampDisconnectWithReason()
sampConnectToServer(sampGetCurrentServerAddress())
 
  • Нравится
Реакции: MTG MODS

ewin

Известный
673
372
в ini cfg сохраняется название клавиши и проверяется через функцию при прожатии
isKeyJustPressed(vkeys.name_to_id(ini.binds.test, true))
но если в названии указать "1"(hex 31(либо любую другую цифру)), то ничего не работает, как исправить можно?
 

Andrinall

Известный
701
518
Нужна помощь человека хорошо шарящего за ffi(работу с указателями, виртуальными таблицами, вызовами методов vtable) и d3d9.

В чём суть:
Не так давно наткнулся в заказах на тему с блуром в имгуи, мне показалось интересным использовать приложенный код на плюсах, перевести на луа и юзать, но не всё так просто оказалось.
В целом я там накостылил всякой фигни и это даже как-то работало если нарочно вызывать ошибку в коде либы.
(backBuffer выводился в окно imgui, а картинка у самой игры стопилась, рамки окна моментами глючило)
Но это не то что мне нужно было + если не вызывать ошибку, то игру просто крашит
Исключение по адресу: 0x00000000 Обращение к недоступной памяти.
Как-то раз я смог выбить исключение в d3d9.dll, но легче от этого не стало.

UPD: пофиксил краши игры и скрипта, но есть другая проблема в виде не создающегося шейдера(blurShader.x[0] == ffi.NULL всегда)
Прошу помощи у знающих людей для доведения кода до ума.
Репозиторий откуда всё это дело бралось


Код:
Исключение по адресу: 0x00000000

Обращение к недоступной памяти.
Подробности: Попытка прочитать недоступный участок памяти
EXCEPTION_ACCESS_VIOLATION

Регистры:
EAX: 0x09A91DF0    EBX: 0x0028F560    ECX: 0x00000000    EDX: 0x00000000
ESI: 0x00011B90    EDI: 0x09A5F6D8    ESP: 0x0028F51C    EBP: 0x0028F538
EFLAGS: 0x00010297

Стек вызовов:
Unknown                         0x00000000
Unknown                         0x715F475B    V:\GTASAMP_037R1\lua51.dll
lua_yield                       0x71604ED5    V:\GTASAMP_037R1\lua51.dll
luaopen_debug                   0x7163B9F3    V:\GTASAMP_037R1\lua51.dll
Unknown                         0x715F280D    V:\GTASAMP_037R1\lua51.dll
ImGui_ImplDX9_RenderDrawData    0x70C7F20C    V:\GTASAMP_037R1\moonloader\lib\mimgui\cimguidx9.DLL
Unknown                         0x715F475B    V:\GTASAMP_037R1\lua51.dll
lua_yield                       0x71604ED5    V:\GTASAMP_037R1\lua51.dll
luaopen_debug                   0x7163B9F3    V:\GTASAMP_037R1\lua51.dll
Unknown                         0x715F280D    V:\GTASAMP_037R1\lua51.dll
lua_pcall                       0x715F73EB    V:\GTASAMP_037R1\lua51.dll
Unknown                         0x710AF9E5    V:\GTASAMP_037R1\MoonLoader.asi
Unknown                         0x710AC887    V:\GTASAMP_037R1\MoonLoader.asi
RtlFreeHeap                     0x7783E0F3    C:\Windows\SysWOW64\ntdll.dll
HeapFree                        0x74FB14AD    C:\Windows\syswow64\kernel32.dll
Unknown                         0x70884C1A    C:\Windows\system32\d3d9.dll
Unknown                         0x710AB69F    V:\GTASAMP_037R1\MoonLoader.asi

Стек:
+0x0000    0x09476780    0x710AB69F    0x0028FA28
+0x0010    0x711E0A69    0x0028FA1C    0x00000000
+0x0020    0x00000001    0x09481FE0    0x70884C1A
+0x0030    0x130E7DC0    0x00000000    0x02030000
+0x0040    0x0028F9C8    0x130E7DB8    0x00000000
+0x0050    0x130E7DE0    0x7783E0F3    0x0028F9B4
+0x0060    0x00000001    0x130E7D58    0x01BAEDB0
+0x0070    0x0947C270    0x0028F9D0    0x00000000
+0x0080    0x09476780    0x0028F9B4    0x710AC887
+0x0090    0x0028F9EC    0x099601C0    0x099601C0
+0x00A0    0xFFFFFFFF    0x00000000    0x099601C0
+0x00B0    0x00000001    0x00000000    0x00000000
+0x00C0    0x00000000    0x00000000    0x099601C0
+0x00D0    0x09481FD8    0x099601F0    0x099DF658
+0x00E0    0x71614360    0x0028F9E0    0x12B96EA0
+0x00F0    0x099BD688    0x099DF678    0x00000003
+0x0100    0x099DF688    0x099DF670    0x000010D7
+0x0110    0x099601C0    0x099602C8    0x09960D58
+0x0120    0x09A91A70    0x099601C0    0x7163B9F3
+0x0130    0x099BE398    0x7161C8D4    0xC9476AB1
+0x0140    0x099AECD0    0x09A70448    0x099BAD08
+0x0150    0x099601C0    0x099601C0    0x099DF6A0
+0x0160    0x099601C0    0x70C7EEA0    0x099E5B28
+0x0170    0x00000000    0x00000000    0x09960008
+0x0180    0x00000000    0x09960008    0x715F4DEB
+0x0190    0x099AECD0    0x099601F0    0x099601C0
+0x01A0    0x0028F87C    0x00000000    0x0028F888
+0x01B0    0x0028F874    0x70C20000    0x778402C2
+0x01C0    0xFFFFFFFE    0x02A559A3    0x1417A86C
+0x01D0    0x00000000    0x00000000    0x00000000
+0x01E0    0x00000000    0x00000000    0x09A60B78
+0x01F0    0x0028F7C0    0x70C7EEA0    0x00000000
+0x0200    0x61447761    0x09A91A70    0x099AECD0
+0x0210    0x099601C0    0x000010D7    0x71604ED5
+0x0220    0x00000009    0x099601C0    0x71604EB5
+0x0230    0x1417A86C    0x0FC44828    0x715F475B
+0x0240    0xCDD3FE7D    0x00000383    0x0000063C
+0x0250    0x00000004    0x3F800000    0x00000000
+0x0260    0x00000000    0x00000000    0x3F800000
+0x0270    0x00000000    0x00000000    0x00000000
+0x0280    0x00000000    0x00000000    0x00000000
+0x0290    0x3F800000    0x3F800000    0x40E71FFA
+0x02A0    0xC05DE97E    0x00000000    0xBE063066
+0x02B0    0x80000000    0x00000000    0x3F304AD9
+0x02C0    0x3F382850    0x00000000    0xBF3691C4
+0x02D0    0x3F31D36A    0x00000000    0xBE99C8D8
+0x02E0    0x80000000    0x3F800000    0x3F80275F
+0x02F0    0x00000000    0x00000000    0x00000000
+0x0300    0x00000000    0x00000000    0x00000000

Lua:
local ffi = require 'ffi'

ffi.cdef[[
typedef enum _D3DFORMAT {
    D3DFMT_UNKNOWN              =  0,

    D3DFMT_R8G8B8               = 20,
    D3DFMT_A8R8G8B8             = 21,
    D3DFMT_X8R8G8B8             = 22,
    D3DFMT_R5G6B5               = 23,
    D3DFMT_X1R5G5B5             = 24,
    D3DFMT_A1R5G5B5             = 25,
    D3DFMT_A4R4G4B4             = 26,
    D3DFMT_R3G3B2               = 27,
    D3DFMT_A8                   = 28,
    D3DFMT_A8R3G3B2             = 29,
    D3DFMT_X4R4G4B4             = 30,
    D3DFMT_A2B10G10R10          = 31,
    D3DFMT_A8B8G8R8             = 32,
    D3DFMT_X8B8G8R8             = 33,
    D3DFMT_G16R16               = 34,
    D3DFMT_A2R10G10B10          = 35,
    D3DFMT_A16B16G16R16         = 36,

    D3DFMT_A8P8                 = 40,
    D3DFMT_P8                   = 41,

    D3DFMT_L8                   = 50,
    D3DFMT_A8L8                 = 51,
    D3DFMT_A4L4                 = 52,

    D3DFMT_V8U8                 = 60,
    D3DFMT_L6V5U5               = 61,
    D3DFMT_X8L8V8U8             = 62,
    D3DFMT_Q8W8V8U8             = 63,
    D3DFMT_V16U16               = 64,
    D3DFMT_A2W10V10U10          = 67,

    D3DFMT_UYVY                 = 0x59565955, // MAKEFOURCC('U', 'Y', 'V', 'Y'),
    D3DFMT_R8G8_B8G8            = 0x47424752, // MAKEFOURCC('R', 'G', 'B', 'G'),
    D3DFMT_YUY2                 = 0x32595559, // MAKEFOURCC('Y', 'U', 'Y', '2'),
    D3DFMT_G8R8_G8B8            = 0x42475247, // MAKEFOURCC('G', 'R', 'G', 'B'),
    D3DFMT_DXT1                 = 0x31545844, // MAKEFOURCC('D', 'X', 'T', '1'),
    D3DFMT_DXT2                 = 0x32545844, // MAKEFOURCC('D', 'X', 'T', '2'),
    D3DFMT_DXT3                 = 0x33545844, // MAKEFOURCC('D', 'X', 'T', '3'),
    D3DFMT_DXT4                 = 0x34545844, // MAKEFOURCC('D', 'X', 'T', '4'),
    D3DFMT_DXT5                 = 0x35545844, // MAKEFOURCC('D', 'X', 'T', '5'),

    D3DFMT_D16_LOCKABLE         = 70,
    D3DFMT_D32                  = 71,
    D3DFMT_D15S1                = 73,
    D3DFMT_D24S8                = 75,
    D3DFMT_D24X8                = 77,
    D3DFMT_D24X4S4              = 79,
    D3DFMT_D16                  = 80,

    D3DFMT_D32F_LOCKABLE        = 82,
    D3DFMT_D24FS8               = 83,

    D3DFMT_D32_LOCKABLE         = 84,
    D3DFMT_S8_LOCKABLE          = 85,

    D3DFMT_L16                  = 81,

    D3DFMT_VERTEXDATA           =100,
    D3DFMT_INDEX16              =101,
    D3DFMT_INDEX32              =102,

    D3DFMT_Q16W16V16U16         =110,

    D3DFMT_MULTI2_ARGB8         = 0x3154454d, // MAKEFOURCC('M','E','T','1'),

    D3DFMT_R16F                 = 111,
    D3DFMT_G16R16F              = 112,
    D3DFMT_A16B16G16R16F        = 113,

    D3DFMT_R32F                 = 114,
    D3DFMT_G32R32F              = 115,
    D3DFMT_A32B32G32R32F        = 116,

    D3DFMT_CxV8U8               = 117,

    D3DFMT_A1                   = 118,
    D3DFMT_A2B10G10R10_XR_BIAS  = 119,
    D3DFMT_BINARYBUFFER         = 199,

    D3DFMT_FORCE_DWORD          = 0x7fffffff
} D3DFORMAT, *LPD3DFORMAT;

typedef enum D3DRESOURCETYPE {
    D3DRTYPE_SURFACE        = 1,
    D3DRTYPE_VOLUME         = 2,
    D3DRTYPE_TEXTURE        = 3,
    D3DRTYPE_VOLUMETEXTURE  = 4,
    D3DRTYPE_CUBETEXTURE    = 5,
    D3DRTYPE_VERTEXBUFFER   = 6,
    D3DRTYPE_INDEXBUFFER    = 7,
    D3DRTYPE_FORCE_DWORD    = 0x7fffffff
} D3DRESOURCETYPE, *LPD3DRESOURCETYPE;

typedef enum D3DPOOL {
    D3DPOOL_DEFAULT      = 0,
    D3DPOOL_MANAGED      = 1,
    D3DPOOL_SYSTEMMEM    = 2,
    D3DPOOL_SCRATCH      = 3,
    D3DPOOL_FORCE_DWORD  = 0x7fffffff
} D3DPOOL, *LPD3DPOOL;

typedef enum D3DMULTISAMPLE_TYPE {
    D3DMULTISAMPLE_NONE          = 0,
    D3DMULTISAMPLE_NONMASKABLE   = 1,
    D3DMULTISAMPLE_2_SAMPLES     = 2,
    D3DMULTISAMPLE_3_SAMPLES     = 3,
    D3DMULTISAMPLE_4_SAMPLES     = 4,
    D3DMULTISAMPLE_5_SAMPLES     = 5,
    D3DMULTISAMPLE_6_SAMPLES     = 6,
    D3DMULTISAMPLE_7_SAMPLES     = 7,
    D3DMULTISAMPLE_8_SAMPLES     = 8,
    D3DMULTISAMPLE_9_SAMPLES     = 9,
    D3DMULTISAMPLE_10_SAMPLES    = 10,
    D3DMULTISAMPLE_11_SAMPLES    = 11,
    D3DMULTISAMPLE_12_SAMPLES    = 12,
    D3DMULTISAMPLE_13_SAMPLES    = 13,
    D3DMULTISAMPLE_14_SAMPLES    = 14,
    D3DMULTISAMPLE_15_SAMPLES    = 15,
    D3DMULTISAMPLE_16_SAMPLES    = 16,
    D3DMULTISAMPLE_FORCE_DWORD   = 0xffffffff
} D3DMULTISAMPLE_TYPE, *LPD3DMULTISAMPLE_TYPE;

typedef enum D3DSAMPLERSTATETYPE {
    D3DSAMP_ADDRESSU       = 1,
    D3DSAMP_ADDRESSV       = 2,
    D3DSAMP_ADDRESSW       = 3,
    D3DSAMP_BORDERCOLOR    = 4,
    D3DSAMP_MAGFILTER      = 5,
    D3DSAMP_MINFILTER      = 6,
    D3DSAMP_MIPFILTER      = 7,
    D3DSAMP_MIPMAPLODBIAS  = 8,
    D3DSAMP_MAXMIPLEVEL    = 9,
    D3DSAMP_MAXANISOTROPY  = 10,
    D3DSAMP_SRGBTEXTURE    = 11,
    D3DSAMP_ELEMENTINDEX   = 12,
    D3DSAMP_DMAPOFFSET     = 13,
    D3DSAMP_FORCE_DWORD    = 0x7fffffff
} D3DSAMPLERSTATETYPE, *LPD3DSAMPLERSTATETYPE;

typedef enum D3DTEXTUREFILTERTYPE {
    D3DTEXF_NONE             = 0,
    D3DTEXF_POINT            = 1,
    D3DTEXF_LINEAR           = 2,
    D3DTEXF_ANISOTROPIC      = 3,
    D3DTEXF_PYRAMIDALQUAD    = 6,
    D3DTEXF_GAUSSIANQUAD     = 7,
    D3DTEXF_CONVOLUTIONMONO  = 8,
    D3DTEXF_FORCE_DWORD      = 0x7fffffff
} D3DTEXTUREFILTERTYPE, *LPD3DTEXTUREFILTERTYPE;

typedef enum D3DBACKBUFFER_TYPE {
    D3DBACKBUFFER_TYPE_MONO         = 0,
    D3DBACKBUFFER_TYPE_LEFT         = 1,
    D3DBACKBUFFER_TYPE_RIGHT        = 2,
    D3DBACKBUFFER_TYPE_FORCE_DWORD  = 0x7fffffff
} D3DBACKBUFFER_TYPE, *LPD3DBACKBUFFER_TYPE;

typedef struct D3DSURFACE_DESC {
    D3DFORMAT             Format;
    D3DRESOURCETYPE     Type;
    unsigned long         Usage;
    D3DPOOL                Pool;
    D3DMULTISAMPLE_TYPE MultiSampleType;
    unsigned long        MultiSampleQuality;
    unsigned int          Width;
    unsigned int        Height;
} D3DSURFACE_DESC, *LPD3DSURFACE_DESC;
]]

local device    = {}
local texture   = {}
local surface   = {}
device.__index  = device
texture.__index = texture
surface.__index = surface

local err = function(t) return "Error in " .. t end
local ass_pcall = function(fn, text, ...) return assert(pcall(fn, table.unpack({...})), text) end

local function IUnknown_Release(vtbl, ptr)
    return select(1, pcall(ffi.cast("unsigned long(__stdcall*)(void*)", vtbl[2]), ptr))
end

local function stdcall(vtbl, idx, retn, args)
    return ffi.cast(("%s(__stdcall*)(%s)"):format(retn or "void", args and "void*, " .. table.concat(args, ", ") or "void*"), vtbl[idx])
end

function device.new(device_ptr)
    return setmetatable({ ptr = device_ptr, vtbl = ffi.cast("intptr_t**", device_ptr)[0] }, device)
end

function surface.new(surface_ptr)
    return setmetatable({ ptr = surface_ptr, vtbl = ffi.cast("intptr_t**", surface_ptr)[0] }, surface)
end

function texture.new(texture_ptr)
    return setmetatable({ ptr = texture_ptr, vtbl = ffi.cast("intptr_t**", texture_ptr)[0] }, texture)
end

function device:GetBackBuffer(iSwapChain, iBackBuffer, Type, ppBuffer) -- 18 idx
    -- UINT, UINT, D3DBACKBUFFER_TYPE, IDirect3DSurface9**
    local fn = stdcall(self.vtbl, 18, _, { "unsigned int", "unsigned int", "D3DBACKBUFFER_TYPE", "void**" })
    ass_pcall(fn, err "device:GetBackBuffer", self.ptr, iSwapChain, iBackBuffer, Type, ppBuffer)
end

function device:CreateTexture(Width, Height, Levels, Usage, Format, Pool, ppTexture, pSharedHandle) -- 23 idx
    -- UINT, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, IDirect3DTexture9**, HANDLE*
    local fn = stdcall(self.vtbl, 23, _, { "uint16_t", "uint16_t", "uint16_t", "uint32_t", "D3DFORMAT", "D3DPOOL", "void**", "void**" })
    ass_pcall(fn, err "device:CreateTexture", self.ptr, Width, Height, Levels, Usage, Format, Pool, ppTexture, pSharedHandle)
end

function device:StretchRect(pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter) -- 34 idx
    -- IDirect3DSurface9*, const RECT*, IDirect3DSurface9*, const RECT*, D3DTEXTUREFILTERTYPE
    local fn = stdcall(self.vtbl, 34, _, { "void*", "const void*", "void*", "const void*", "D3DTEXTUREFILTERTYPE" })
    ass_pcall(fn, err "device:StretchRect", self.ptr, pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter)
end

function device:SetRenderTarget(RenderTargetIndex, pRenderTarget)
    -- DWORD, IDirect3DSurface9*
    local fn = stdcall(self.vtbl, 37, _, { "unsigned long", "void*" })
    ass_pcall(fn, err "device:SetRenderTarget", self.ptr, RenderTargetIndex, pRenderTarget)
end

function device:GetRenderTarger(RenderTargetIndex, ppRenderTarget)
    -- DWORD, IDirect3DSurface9**
    local fn = stdcall(self.vtbl, 38, _, { "unsigned long", "void**" })
    ass_pcall(fn, err "device:GetRenderTarger", self.ptr, RenderTargetIndex, ppRenderTarget)
end

function device:SetSamplerState(Sampler, Type, Value)
    local fn = stdcall(self.vtbl, 69, _, { "unsigned long", "D3DSAMPLERSTATETYPE", "unsigned long" })
    ass_pcall(fn, err "device:SetSamplerState", self.ptr, Sampler, Type, Value)
end

function device:CreatePixelShader(pFunction, ppShader)
    -- const DWORD*, IDirect3DPixelShader9**
    local fn = stdcall(self.vtbl, 106, _, { "const uint32_t*", "void**" })
    ass_pcall(fn, err "device:CreatePixelShader", self.ptr, pFunction, ppShader)
end

function device:SetPixelShader(pShader)
    local fn = stdcall(self.vtbl, 107, _, { "void*" --[[ IDirect3DPixelShader9* ]] })
    ass_pcall(fn, err "device:SetPixelShader", self.ptr, pShader)
end

function device:SetPixelShaderConstantF(StartRegister, pConstantData, Vector4fCount)
    local fn = stdcall(self.vtbl, 109, _, { "unsigned int", "const float*, unsigned int" })
    ass_pcall(fn, err "device:SetPixelShaderConstantF", self.ptr, StartRegister, pConstantData, Vector4fCount)
end

function texture:Release() return assert(IUnknown_Release(self.vtbl, self.ptr), err "texture:Release") end

function texture:GetSurfaceLevel(Level, ppSurface)
    local fn = stdcall(self.vtbl, 18, _, { "unsigned int", "void**" --[[ IDirect3DSurface9** ]] })
    ass_pcall(fn, err "texture:GetSurfaceLevel", self.ptr, Level, ppSurface)
end

function surface:Release() return assert(IUnknown_Release(self.vtbl, self.ptr), err "surface:Release") end

function surface:GetDesc(pDesc)
    local fn = stdcall(self.vtbl, 12, _, { "D3DSURFACE_DESC*" })
    ass_pcall(fn, err "surface:GetDesc", self.ptr, pDesc)
end

return {
    device  = device,
    texture = texture,
    surface = surface,
    create = { d3dSurfaceDesc = function() return ffi.new("D3DSURFACE_DESC[1]") end }
}
Lua:
local ffi = require 'ffi'

local separate = function(text)
    local retn = {}
    for i = 1, #text do table.insert(retn, text:sub(i, i)) end
    return retn
end

local decode = function(char) return char >= string.byte("\\") and char - 36 or char - 35 end

local decode85 = function(input)
    local _in = ffi.cast("const char*", input)
    local _out = {} -- #input * 4 / 5
    local i, j = 1, 1
    while i < #input do
        local tmp = decode(_in[i]) + 85 * (decode(_in[i + 1]) + 85 * (decode(_in[i + 2]) + 85 * (decode(_in[i + 3]) + 85 * decode(_in[i + 4]))))
        _out[j]     = bit.band(bit.rshift(tmp, 0),  0xFF)
        _out[j + 1] = bit.band(bit.rshift(tmp, 8),  0xFF)
        _out[j + 2] = bit.band(bit.rshift(tmp, 16), 0xFF)
        _out[j + 3] = bit.band(bit.rshift(tmp, 24), 0xFF)

        i = i + 5
        j = j + 4
    end
    return ffi.new(("uint32_t[" .. tostring(#input * 4 / 5) .. "]"), _out)
end

return {
    blur_x = decode85("%/P:vP>$(#>T$<8?####Q$###%/P:v%####?####$&###J$###h####&####$####t#########.$###%####$####:$########tn=j=$8HlEQ2TuY3l:$#%),##$#########0g'WC`-.:CVjSuY&5>##%),##$#########C,.33UnSc;'AViF6JrEH<Sk:0+bVe=K&&PDlf1eGdfX1F$*fUCs'el1K>,C5AH3I3b48(#$QUV$)%XHVd;#K7#####X/'.7`7r'7$QUV$*%XHVd:i[7bmhf6##########D5YY#NSi.L,nHS[D5YY#_9r:Q0=XHVi>uu#^XF0LdfIl[[BA`V&5YY#W.]/Lpu$GV+>uu#PYr.LOV%JLou$GV&5YY#Q`%/Lpv*PV(>uu#Sf./L5hJcLdfIl[(>uu#Rf./L4_/GLdfIl[&5YY#Y.]/Lqu$GV+>uu#RYr.LQV%JLou$GV&5YY#S`%/Lpv*PV(>uu#Uf./L7hJcLdfIl[(>uu#Tf./L6_/GLdfIl[i>uu#_XF0L4_/GL[BA`Vi>uu#`XF0L5_/GL[BA`Vi>uu#aXF0L6_/GL[BA`Vi>uu#bXF0L7_/GL[BA`V+>uu#W(S/L5_/GLpw0YV+G:;$W(S/L3_/GLpx6cV5_/GL+G:;$V(S/L4_/GLpw0YV5_/GL+G:;$V(S/L7_/GLqv*PV4_/GL+G:;$U(S/L6_/GLqv*PV4_/GL&5YY#fqF0L3_/GL#),##"),
    blur_y = decode85("%/P:vP>$(#>T$<8?####Q$###%/P:v%####?####$&###J$###h####&####$####t#########.$###%####$####:$########tn=j=$8HlEQ2TuY3l:$#%),##$#########0g'WCQk;nDhpF/#&5>##%),##$#########C,.33UnSc;'AViF6JrEH<Sk:0+bVe=K&&PDlf1eGdfX1F$*fUCs'el1K>,C5AH3I3b48(#$QUV$)%XHVd;#K7NSi.LX/'.7`7r'7$QUV$*%XHVd:i[7bmhf6##########D5YY#NSi.L,nHS[D5YY#_9r:Q0=XHVi>uu#^XF0LdfIl[[BA`V&5YY#W.]/Lpu$GV+>uu#PYr.LOV%JLou$GV&5YY#Q`%/LP].JL&5YY#PYr.Lpv*PV(>uu#Rf./L4_/GLdfIl[&5YY#QYr.L)[-S[+G:;$R`%/Lou$GVOV%JL)]3][&5YY#Y.]/Lqu$GV+>uu#Sl7/LQV%JLou$GV&5YY#S`%/LP_:]L&5YY#RYr.Lpv*PV(>uu#Tf./L6_/GLdfIl[&5YY#SYr.L)[-S[+G:;$T`%/Lou$GVQV%JL)]3][i>uu#_XF0L4_/GL[BA`Vi>uu#`XF0L5_/GL[BA`Vi>uu#aXF0L6_/GL[BA`Vi>uu#bXF0L7_/GL[BA`V+>uu#V(S/L4_/GLpw0YV+G:;$V(S/L3_/GLpx6cV4_/GL+G:;$V(S/L5_/GLpw0YV4_/GL+G:;$V(S/L6_/GLqv*PV4_/GL+G:;$U(S/L7_/GLqv*PV4_/GL&5YY#fqF0L3_/GL#),##")
}
Lua:
local ffi = require 'ffi'
local d3d = require 'mim_blur.d3d'
local bin = require 'mim_blur.blur_binary'
local imgui = require 'mimgui'

local function createPVoid(ptr) return ffi.new("void*[1]") end

local module = {}
local rtBackup = createPVoid()
local blurShader = { x = createPVoid(), y = createPVoid() }
local blurTexture = nil
local backBufferSize = { x = 0, y = 0 }

module.BeginBlur = ffi.cast("ImDrawCallback", function(draw_list, cmd)
    local device = d3d.device.new(cmd.UserCallbackData)
    
    if blurShader.x[0] == ffi.NULL then
        device:CreatePixelShader(ffi.cast("const uint32_t*", bin.blur_x), blurShader.x) -- если передать blurShader.x[0] - крашнет
    end

    if blurShader.y[0] == ffi.NULL then
        device:CreatePixelShader(ffi.cast("const uint32_t*", bin.blur_y), blurShader.y)
    end

    local backBuffer = createPVoid()
    device:GetBackBuffer(0, 0, 0 --[[ D3DBACKBUFFER_TYPE_MONO ]], backBuffer)
    backBuffer = d3d.surface.new(backBuffer[0])
    local desc = d3d.create.d3dSurfaceDesc()
    backBuffer:GetDesc(desc)
    if backBufferSize.x ~= desc[0].Width or backBufferSize.y ~= desc[0].Height then
        if blurTexture ~= nil then
            imgui.ReleaseTexture(blurTexture.ptr)
            blurTexture = nil
        end

        backBufferSize.x = desc[0].Width
        backBufferSize.y = desc[0].Height
        blurTexture = createPVoid()
        device:CreateTexture(desc[0].Width, desc[0].Height, 1, 0x00000001, 21, 0, blurTexture, ffi.cast("void**", ffi.cast("void*", ffi.NULL)))
        blurTexture = d3d.texture.new(blurTexture[0])
    end

    rtBackup = createPVoid()
    device:GetRenderTarger(0, rtBackup)
    rtBackup = d3d.surface.new(rtBackup[0])

    --do
        local surface = createPVoid()
        blurTexture:GetSurfaceLevel(0, surface)
        surface = d3d.surface.new(surface[0])
        device:StretchRect(backBuffer.ptr, ffi.cast("void*", ffi.NULL), surface.ptr, ffi.cast("void*", ffi.NULL), 0)
        device:SetRenderTarget(0, surface.ptr)
        surface:Release()
        surface = nil
    --end

    backBuffer:Release()
    backBuffer = nil

    device:SetSamplerState(0, 1, 3)
    device:SetSamplerState(0, 2, 3)
    return 0
end)

module.FirstBlurPass = ffi.cast("ImDrawCallback", function(draw_list, cmd)
    local device = d3d.device.new(cmd.UserCallbackData)
    local params = ffi.new("float[4]", { (backBufferSize.x == 0 and 1.0 or 1.0 / backBufferSize.x), 0.0, 0.0, 0.0 })
    device:SetPixelShader(blurShader.x[0])
    device:SetPixelShaderConstantF(0, params, 1)
    return 0
end)

module.SecondBlurPass = ffi.cast("ImDrawCallback", function(draw_list, cmd)
    local device = d3d.device.new(cmd.UserCallbackData)
    local params = ffi.new("float[4]", { (backBufferSize.y == 0 and 1.0 or 1.0 / backBufferSize.y), 0.0, 0.0, 0.0 })
    device:SetPixelShader(blurShader.y[0])
    device:SetPixelShaderConstantF(0, params, 1)
    return 0
end)

module.EndBlur = ffi.cast("ImDrawCallback", function(draw_list, cmd)
    local device = d3d.device.new(cmd.UserCallbackData)
    device:SetRenderTarget(0, rtBackup.ptr)
    rtBackup:Release()
    rtBackup = nil

    device:SetPixelShader(ffi.cast("void*", ffi.NULL))
    device:SetSamplerState(0, 1, 3)
    device:SetSamplerState(0, 2, 3)
    return 0
end)

local function checkTexture(texture)
    return texture and (texture.ptr ~= ffi.NULL and texture.ptr or nil)
end

function module.DrawBackgroundBlur(draw_list, device, level)
    level = level or 9
    draw_list:AddCallback(module.BeginBlur, device)

    for i = 1, level do
        draw_list:AddCallback(module.FirstBlurPass, device)
        draw_list:AddImage(checkTexture(blurTexture), imgui.ImVec2(0,0), imgui.ImVec2(backBufferSize.x, backBufferSize.y))
        draw_list:AddCallback(module.SecondBlurPass, device)
        draw_list:AddImage(checkTexture(blurTexture), imgui.ImVec2(0,0), imgui.ImVec2(backBufferSize.x, backBufferSize.y))
    end

    draw_list:AddCallback(module.EndBlur, device)
    draw_list:AddImageRounded(checkTexture(blurTexture), imgui.ImVec2(0,0), imgui.ImVec2(backBufferSize.x, backBufferSize.y), imgui.ImVec2(0,0), imgui.ImVec2(1,1), 0xFFFFFFFF, 7.0)
end

return module

Lua:
local imgui = require 'mimgui'
local bBlur = require 'mim_blur'

local bool = imgui.new.bool(false)
local map_image = nil

imgui.OnInitialize(function()
    imgui.GetIO().IniFilename = nil

    sw, sh = getScreenResolution()
    map_image = imgui.CreateTextureFromFile(getWorkingDirectory() .. "\\resource\\HUDMAP.png")
end)

local test_frame = imgui.OnFrame(function() return bool[0] end, function()
    imgui.SetNextWindowSize(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowPos(imgui.ImVec2(200, 200), imgui.Cond.FirstUseEver)
    if imgui.Begin("Tested Blured Window", bool, imgui.WindowFlags.NoCollapse) then
        local draw = imgui.GetWindowDrawList()
        imgui.Image(map_image, imgui.ImVec2(500, 500))
        imgui.Text("Text below blur effect")
        if imgui.IsInitialized() then bBlur.DrawBackgroundBlur(draw, imgui.GetRenderer().d3ddevice, 1) end
        imgui.Text("Text above blur effect")
        imgui.End()
    end
end)

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    repeat wait(100) until isSampAvailable()

    sampRegisterChatCommand("bTest", function() bool[0] = not bool[0] end)

    wait(-1)
end
UP
Порешал некоторые траблы со своим говнокодом(не без помощи дискордовского Clyde) и даже удалось сделать Blur Effect, но теперь другая проблема - ошибка "table overflow" через не продолжительное время заблюривания, помогите пофиксить :D

upd: выпадение ошибки не зависит от размера области для блюра, она выпадет в любом случае

1686031542704.png
 

Вложения

  • обновлённые файлы.zip
    6.1 KB · Просмотры: 6
Последнее редактирование:
  • Вау
Реакции: YarikVL

s3nder_

Известный
60
83
в ini cfg сохраняется название клавиши и проверяется через функцию при прожатии
isKeyJustPressed(vkeys.name_to_id(ini.binds.test, true))
но если в названии указать "1"(hex 31(либо любую другую цифру)), то ничего не работает, как исправить можно?
не обязательно использовать vkeys, чтобы ставить бинд, у каждой клавиши есть свой ID, который равен какой либо цифре
 
  • Нравится
Реакции: deleted-user-139653

goodflex

Активный
280
57
Как реализовать чтобы через setCurrentCharWeapon (или что то другое) переключало на следующее оружие если в руках например м4 (31)
 
D

deleted-user-139653

Гость
Как реализовать чтобы через setCurrentCharWeapon (или что то другое) переключало на следующее оружие если в руках например м4 (31)
Lua:
local weapons = {21, 22, 24, 25, 26, 27, 28, 29, 30, 31}
local currentWeaponIndex = 1

function switchToNextWeapon()
   currentWeaponIndex = currentWeaponIndex + 1
   if currentWeaponIndex > #weapons then
      currentWeaponIndex = 1
   end
   setCurrentCharWeapon(PLAYER_PED, weapons[currentWeaponIndex])
end

function main()
   while true do wait(0)
        local currentWeapon = getCurrentCharWeapon(PLAYER_PED)
        if currentWeapon == 31 then
            switchToNextWeapon()
        end
    end
end
 
  • Нравится
Реакции: goodflex

kyrtion

Известный
978
355
это и так нормальный исходник диалога без поправок
По моему не так настраиваешь скрипт.
Проверяйте, что стоит там кодировка, либы и прочее.


1686093832655.png


Lua:
-- где text - это текст диалога, не заголовка!
local text = "{73B461}-{ffffff} Вы успешно приобрели разрешение на покупку {73B461}Дома (342){ffffff}!\n\nПоспешите забрать {73B461}Дома{ffffff} первым, пока Вас не опередили!\n\n{cccccc}Разрешение будет действовать {73B461}20 минут{ffffff} на выбранный тип недвижимости\nЕсли вы перезайдете, заспавнитесь, умрете - все разрешения будут {73B461}аннулированы{ffffff}!"

local ntext = text:gsub('{......}', '')
for line in ntext:gmatch("[^\r\n]+") do
    if line:find('^%- Вы успешно приобрели разрешение на покупку Дома %(%d+%)%!$') then
        local id_house = line:match('Дома %((%d+)%)%!$')
        print('Found ID House: '..id_house)
    end
end
 
  • Нравится
Реакции: Willy4ka