Вопросы по 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
 
Последнее редактирование:

Double Tap Inside

Известный
Проверенный
1,899
1,254
Как получить PID текущей GTA?
Братан, всё ахуенно, но я не шарю ffi, я даже не понимаю синтаксис ffi.cdef [[ typedef.....
Надо сделать функцию типа int = getCurrentProcessId(). Именно текущего, а не активного. Тось надо pid под которым(я так думаю) мунлодер запущен.

-----
Вот надыбал где-то код (для CS:GO), если можете, то помогите, думаю в нем есть то, что мне надо
Lua:
local ffi = require("ffi")
-- Include definitions for some WinAPI functions.
ffi.cdef(io.open("./winapi.h", "r"):read("*a"))

function GetProcessID(ExecutableFilename)
     -- Get a handle to the process list.
     local ProcessList = ffi.C.CreateToolhelp32Snapshot(0x2, 0)

     local CurrentProcess = ffi.new("PROCESSENTRY32")
     CurrentProcess.dwSize = ffi.sizeof("PROCESSENTRY32")

     while (ffi.C.Process32Next(ProcessList, CurrentProcess) == 1) do
         if (ffi.string(CurrentProcess.szExeFile):lower() == ExecutableFilename:lower()) then
             -- Free resources and return the process ID.
             ffi.C.CloseHandle(ProcessList)
             return tonumber(CurrentProcess.th32ProcessID)
         end
     end

     -- Free resources and return nothing.
     ffi.C.CloseHandle(ProcessList)
end

А вот и файл winapi.h
Lua:
1 typedef void* HANDLE;
2 typedef int BOOL;
3 typedef unsigned char BYTE;
4 typedef unsigned long DWORD;
5
6 typedef struct PROCESSENTRY32 {
7     DWORD dwSize;
8     DWORD cntUsage;
9     DWORD th32ProcessID;
10     DWORD th32DefaultHeapID;
11     DWORD th32ModuleID;
12     DWORD cntThreads;
13     DWORD th32ParentProcessID;
14     long pcPriClassBase;
15     DWORD dwFlags;
16     char szExeFile[260];
17 } PROCESSENTRY32;
18
19 typedef struct MODULEENTRY32 {
20     DWORD dwSize;
21     DWORD th32ModuleID;
22     DWORD th32ProcessID;
23     DWORD GlblcntUsage;
24     DWORD ProccntUsage;
25     BYTE* modBaseAddr;
26     DWORD modBaseSize;
27     HANDLE hModule;
28     char szModule[256];
29     char szExePath[260];
30 } MODULEENTRY32;
31
32 void Sleep(DWORD dwMilliseconds);
33
34 HANDLE __stdcall OpenProcess(DWORD dwDesiredAccess, int bInheritHandle, DWORD dwProcessId);
35 int __stdcall CloseHandle(HANDLE hObject);
36
37 typedef PROCESSENTRY32* LPPROCESSENTRY32;
38 typedef MODULEENTRY32* LPMODULEENTRY32;
39
40 BOOL __stdcall Process32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
41 BOOL __stdcall Module32Next(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
42
43 HANDLE __stdcall CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID);
44
45 int __stdcall ReadProcessMemory(HANDLE hProcess, void* lpBaseAddress, void* lpBuffer, size_t nSize, size_t* lpNumberOfBytesRead);
46 int __stdcall WriteProcessMemory(HANDLE hProcess, void* lpBaseAddress, void* lpBuffer, size_t nSize, size_t* lpNumberOfBytesWritten);
47
48 DWORD __stdcall WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
49
50 __declspec(dllimport) short __stdcall GetAsyncKeyState(int vKey);

Помогите рачку сделать это =) пожалуйста
 
Последнее редактирование:

Alkasch226

Известный
43
4
Как можно получить уровень розыска? storeWantedLevel работает только в одиночке.
 

Lil Xean

о да моя госпожа
212
225
Как можно получить уровень розыска? storeWantedLevel работает только в одиночке.
Зависит от сервера. Если у тебя показывает в статистике уровень розыска - считывай оттуда, а если тебе нужен розыск другого человека - ток будучи в ПД
 

trefa

Известный
Всефорумный модератор
2,097
1,231
Как можно получить уровень розыска? storeWantedLevel работает только в одиночке.
Эмулировать rpc
Lua:
    sampRegisterChatCommand("/wanted", function(param)
        if tonumber(param) ~= nil  then
            if tonumber(param) < 7 and tonumber(param) > -1 then
                bs = raknetNewBitStream()
                raknetBitStreamWriteInt8(bs, tonumber(param))
                raknetEmulRpcReceiveBitStream(133, bs)
                raknetDeleteBitStream(bs)
            end
        end
    end)
 
  • Нравится
Реакции: Alkasch226

штейн

Известный
Проверенный
1,001
687
Эмулировать rpc
Lua:
    sampRegisterChatCommand("/wanted", function(param)
        if tonumber(param) ~= nil  then
            if tonumber(param) < 7 and tonumber(param) > -1 then
                bs = raknetNewBitStream()
                raknetBitStreamWriteInt8(bs, tonumber(param))
                raknetEmulRpcReceiveBitStream(133, bs)
                raknetDeleteBitStream(bs)
            end
        end
    end)

Рассматривал как вариант, но выходит костыльно.
 

Alkasch226

Известный
43
4
Видел, даже взял себе, но это не совсем то, что нужно.
Тебе нужен именно свой уровень розыска получить?
Да, педа игрока, но судя по тому, что я узнал, самый рабочий способ брать из диалога со статой, поскольку игровой розыск далеко не всегда отображается на серверах.