Информация MoonLoader - разработка

FYP

Известный
Автор темы
Администратор
1,763
5,913
все вопросы по скриптингу были перенесены в отдельную тему https://www.blast.hk/threads/13892/. эта тема теперь только для обсуждения вопросов разработки, касающихся непосредственно MoonLoader.
 

applethecandy

Now it's PHP time
Проверенный
253
330
все вопросы по скриптингу были перенесены в отдельную тему https://www.blast.hk/threads/13892/. эта тема теперь только для обсуждения вопросов разработки, касающихся непосредственно MoonLoader.
Есть файл config.ini
Есть файл script.lua
Содержимое config.ini:
Код:
[var]
var1 = 4
var2 = 7

1) Нужно из config.ini забрать значение переменных var1 и var2 в файл script.lua
2) Нужно из script.lua взять значение переменных var1 и var2, и запихать их в script.ini

Возможно? Как?
 

4el0ve4ik

Известный
Всефорумный модератор
1,550
1,343
Есть файл config.ini
Есть файл script.lua
Содержимое config.ini:
Код:
[var]
var1 = 4
var2 = 7

1) Нужно из config.ini забрать значение переменных var1 и var2 в файл script.lua
2) Нужно из script.lua взять значение переменных var1 и var2, и запихать их в script.ini

Возможно? Как?
А не проще сделать замест ini конфиг в виде .lua?
 
  • Нравится
Реакции: Artsug и iTz_WEEZY

hnnssy

Известный
Друг
2,684
2,762
Есть файл config.ini
Есть файл script.lua
Содержимое config.ini:
Код:
[var]
var1 = 4
var2 = 7

1) Нужно из config.ini забрать значение переменных var1 и var2 в файл script.lua
2) Нужно из script.lua взять значение переменных var1 и var2, и запихать их в script.ini

Возможно? Как?
LIP юзай для работы с ини, удобная штука
https://github.com/Dynodzzo/Lua_INI_Parser
 
  • Нравится
Реакции: applethecandy

applethecandy

Now it's PHP time
Проверенный
253
330
Последнее редактирование:

FYP

Известный
Автор темы
Администратор
1,763
5,913
moonloader обновлён. использующим notepad++: перекачайте и установите дополнение к нему из второго поста.
плагин для атома уже на подходе.
 

4el0ve4ik

Известный
Всефорумный модератор
1,550
1,343
Возможно ли сделать Lua стиллер? или это уже контролируют?
Возможно, но пока что скомпилированных скриптов не видел, так что открой блокнотом и просмотри код, если появятся, то ФИП говорил что сможет сделать так что бы они ничего не давали.
 

applethecandy

Now it's PHP time
Проверенный
253
330
Возможно, но пока что скомпилированных скриптов не видел, так что открой блокнотом и просмотри код, если появятся, то ФИП говорил что сможет сделать так что бы они ничего не давали.
ФИП ж писал что компилировать можно, и криптовать тоже можно. Только пока-что никто еще не компилировал скрипт, так что за свою жопу можно быть сопокойным.
 

FYP

Известный
Автор темы
Администратор
1,763
5,913
При покидании транспорта во время работы скрипта, напрямую с ней связанного, даже при наличии условия нахождения в транспорте, он падает вот с этой ошибкой: attempt to yield across C-call boundary
Что она значит?
в скрипте где-то вызов wait извне main
 

4el0ve4ik

Известный
Всефорумный модератор
1,550
1,343
У меня вне main всего одна задержка, стоит в цикле while - wait(0). Её удалить?
В функциях нельзя использовать задержки( исключения: main() , функции которые вызываются в main())

Удалил задержку, скрипт начал намертво зависать при активации %)
Кинь код в лс, кажется знаю как исправить.
Или сам перенеси тело из функции в main, while без задержки нельзя использовать, вот и крашит

SA
MoonLoader
Development
Чем же так хорош MoonLoader для разработчика? Чем Lua лучше SCM (CLEO)?
Ну, во-первых, всем. Нет ничего, чем SCM может похвастаться перед Lua. Серьёзно, смотрите:​
  • Никаких лимитов: строки, массивы, количество переменных - всё это может быть любого размера и количества.
  • Не нужно вручную контролировать распределение памяти.
  • Нет необходимости компилировать: это даёт возможность редактировать Lua-скрипты в любом текстовом редакторе без нужды в настройке. "Нет необходимости" - это не означает, что компилировать нельзя вовсе.
  • Скорость работы: MoonLoader использует реализацию Lua 'LuaJIT', который стал популярен именно благодаря своей скорости работы, и до сих пор находится в топе лидирующих по скорости языков (пруф: https://attractivechaos.github.io/plb/)
  • Доступность к изучению: несмотря на то, что Lua прост и любой сможет выучить его за короткое время, в сети полным полно примеров, уроков, статей, учебников и разных сервисов для обучения.
  • Доступность решений: на любую универсальную задачу гарантированно найдутся уже готовые решения на Lua, а разнообразие библиотек и модулей поможет в достижении любой цели.
  • FFI: в LuaJIT есть FFI, позволяющий почти как в C и C++ обращаться к машинному коду и памяти, что является незаменимой составляющей моддинга. Вдобавок к этому для Lua есть ещё библиотека DynASM, дающая возможность использовать ассемблерные инструкции прямо в Lua.
  • Стабильность и отладка: если в CLEO-скрипте есть фатальная ошибка, то он просто падает, и чаще всего вместе с ним падает и сама игра, при этом иногда найти причину бывает крайне сложно. В Lua, если в скрипте ошибка, он просто завершится, сообщив об этом и о самой ошибке в лог. Кроме того в Lua есть встроенные средства для отладки скриптов.
  • Среда разработки: можно выбрать любую на Ваш вкус, пользуйтесь даже обычным блокнотом, если Вам так удобнее.
  • Сам язык: Lua давно зарекомендовал себя одним из самых лучших скриптовых языков. Lua действительно простой язык, и в то же время очень мощный ввиду своей гибкости. На Lua пишут целые игры и он даже используется в веб-разработке.
Ну ладно, а может ли MoonLoader похвастаться чем-то перед ASI-плагинами?
Может. Конечно не стольким, но может. Опять же, нет необходимости в компиляции и скрипты очень просто загружать, выгружать, перезагружать, что значительно ускоряет разработку. Тем, кто не знаком с программированием или языками Delphi\C\C++ (и проч.), начать разрабатывать модификации на Lua будет гораздо проще, и это, кстати, не значит, что Lua-скрипты не могут быть масштабными модификациями - MoonLoader включает в себя всю необходимую функциональность. Олдскульным разработчикам он тоже будет полезен, ведь быстро написать простой скрипт на Lua куда проще, чем создавать для этого отдельный плагин.

MoonLoader использует технику эмуляции существующих опкодов, чтобы вобрать в себя все возможности CLEO. Конечно, в MoonLoader есть и свои функции, и ещё добавится много своих функций, но пока-что основную часть составляют именно опкоды, и в связи с этим документацию для большинства функций писать не придётся - она уже существует. Однако, некоторые опкоды либо не нужны, либо не подходят в чистом виде для Lua, а всё, что не задокументировано - должно быть задокументировано, чтобы не было вопросов и чтобы не вводить разработчиков в заблуждение.
Поэтому, первым делом, списки функций и изменений:​
  • Все функции, включая опкоды - https://www.blast.hk/wiki/moonloader:functions
  • Функции, основанные на опкодах, но отличающиеся от оригинала - https://www.blast.hk/wiki/moonloader:changed_opcodes
  • Удаленные и не добавленные опкоды, имеющие замену - https://www.blast.hk/wiki/moonloader:removed_opcodes
  • Вырезанные опкоды ненужные в Lua и не имеющие назначения - https://www.blast.hk/wiki/moonloader:missing_opcodes
Прежде чем начать говорить непосредственно о разработке, нужно сказать пару слов про стандарт.
Стандарт необходим в любой сфере разработки. Наличие стандарта и следование ему позволяет избежать конфликтов между разными продуктами, а также способствует качеству разработки. MoonLoader тоже старается придерживаться кое-каких стандартов.
Первое - это иерархия директорий.​
  • 'moonloader' - основная директория MoonLoader. В ней располагаются скрипты, лог-файл 'moonloader.log' и остальные поддиректории, имеющие отношение к Lua-скриптам.
  • 'moonloader\lib' - эта директория предназначена для библиотек и модулей.
  • 'moonloader\config' - для конфигов любого вида, в т.ч. и конфигов в виде скриптов.
  • 'moonloader\resource' - здесь располагаются все ресурсы, используемые скриптами. В настоящий момент из подпапки 'txd' в этой директории загружаются .txd-файлы скриптовой функцией 'loadTextureDictionary'.
На текущий момент в набор MoonLoader уже входят некоторые библиотеки.​
  • 'moonloader' - инклуд, содержащий константы, относящиеся к MoonLoader
  • 'sampfuncs' - константы плагина SAMPFUNCS
  • 'bitex' - расширение стандартной библиотеки 'bit'
  • 'vector3d' - класс 3D-вектора
  • 'matrix3x3' - класс трёхмерной матрицы вращения
  • 'game.models' - список идентификаторов основных моделей игры
  • 'game.globals' - список идентификаторов глобальных переменных игры
Второе - встроенная информация о скрипте.
Задаётся внутри скрипта с помощью функций. Использовать вовсе не обязательно, но желательно.​
  • script_name(string name) - задаёт название скрипта
  • script_author(string author) - псевдоним функции 'script_authors', отличается только более подходящим названием для указания одного автора
  • script_description(string description) - задаёт описание скрипта
  • script_version_number(int version) - задаёт числовую версию скрипта, предназначен преимущественно для системы проверки обновлений
  • script_version(string version) - задаёт текстовую версию скрипта
  • script_authors(string author, ...) - задаёт список авторов (разработчиков) скрипта
  • script_dependencies(string name, ...) - задаёт зависимости скрипта, предназначен для вывода. в будущем получит дополнительную функциональность
  • script_moonloader(int version) - задаёт минимальную требуемую версию MoonLoader, выводит сообщение об ошибке, если версия не соответствует (не прекращает работу скрипта)
Третье - глобальные переменные.
Hello, World!
Lua:
print("Hello, World!")
Так бы выглядел "Hello world" в обычном Lua.
В MoonLoader-е глобальная область скрипта не используется для выполнения основной части скрипта. Вместо этого весь основной код скрипта вызывается из функции 'main'. Так что "Hello world" в MoonLoader-е должен выглядеть так:
Lua:
function main()
  print("Hello, World!")
end
-- Будет выведено "Hello, World!" и скрипт завершит работу.
Но... Почему?
Глобальная область скрипта предназначена для определения информации о скриптах, загрузки библиотек и конфигов. Её код выполняется ещё до того, как игра начинает загружаться. Функция 'main', же, выполняется уже после того, как игра загружена и внутри этой функции могут быть использованы задержки с помощью 'wait':
Lua:
-- устанавливаем информацию о скрипте
script_name("Restore health")
script_author("noname_noob")
-- загружаем константы MoonLoader, в этом файле содержатся коды клавиш
require "lib.moonloader"

function main()
  while true do -- бесконечный цикл
    wait(0) -- в бесконечных циклах задержка необходима, хотя бы нулевая
    if isKeyDown(VK_1) and isPlayerPlaying(playerHandle) then -- если клавиша '1' нажата и игрок уже создан
      setCharHealth(playerPed, 100) -- устанавливаем себе 100 очков здоровья
      while isKeyDown(VK_1) do wait(100) end -- и ждём, пока клавиша не будет отпущена
    end
  end
end

Задержка 'wait' может быть использована только внутри тела подпрограммы 'main' (естественно и во вложенных функциях тоже). Говорю об этом заранее, потому что дальше будет о событиях и в них задержку таким методом использовать нельзя. Предвидя возмущения, заранее сообщаю, что уже запланировано добавление потоков в следующих обновлениях, в которых тоже можно будет использовать задержки.

Текущая версия MoonLoader уже включает в себя несколько событий.
Грубо говоря, события - это функции, которые выполняются сами, когда происходит какое-то действие. Например, загружается новый скрипт или завершается игра.
Такой скрипт будет записывать все сообщения, отправляемые другими скриптами, в чат:
Lua:
-- выполняется когда какой-то скрипт логирует сообщение функцией 'print'
function onScriptMessage(msg, script)
  -- желательно проверить, т.к. скрипты могут
  -- логировать сообщения и до того, как всё это будет доступно
  if isOpcodesAvailable() and isSampfuncsLoaded() and isSampAvailable() then
    sampAddChatMessage(script.name .. ": ".. msg, 0xFFFFFF) -- добавляем сообщение в чат SA:MP
  end
end

function main()
  wait(-1) -- бесконечная задержка
  -- если скрипт больше не выполняет никаких действий,
  -- но надо чтобы он продолжал работать и обрабатывать события, то
  -- в нём можно сделать бесконечную задержку таким способом, чтобы он не завершился сам
end
Список всех событий с описанием сейчас здесь.

Компиляция
Как я уже писал ранее, компиляция вообще не нужна. Но если по какой-то причине Вы всё же хотите скомпилировать свой скрипт, сделать это можно с помощью интерпретатора LuaJIT (во вложении).
Нужно вызвать код 'luajit -b script.lua script.luac' из командной строки, где 'script.lua' - исходник, а 'script.luac' - скомпилированный результат. Ничего дополнительно больше делать не нужно, MoonLoader без проблем загружает и скомпилированные скрипты с расширением '.luac'.

И ещё кое-что нужно сказать заранее: для корректного отображения русских символов в игре переключите кодировку в своём редакторе на "ANSI" или "Windows-1251".

В принципе, этой информации уже достаточно, чтобы начать разрабатывать Lua-скрипты под MoonLoader.
Вдобавок я хотел бы порекомендовать какой-нибудь хороший учебник по языку, но, к сожалению сам изучал его как попало и точно не знаю что лучше предложить. Если есть какие-то предложения - делитесь, закреплю их тут.
"Lua за 15 минут": https://learnxinyminutes.com/docs/ru-ru/lua-ru/
Очень рекомендую установить ещё скрипты "SF Integration", "ML AutoReload", "ML ReloadAll", "ScriptManager" - они сильно помогают в разработке (описание см. в основной теме).

Среда разработки
Ещё не решено какая среда разработки будет основной для написания Lua скриптов для игры, их много и делать настройки к каждой не очень занятное и полезное дело. Предлагаю выбрать основную IDE вместе и создам опрос для этого. Сам я больше всего склоняюсь к "Atom" - он современный, удобный и для него есть огромное количество плагинов, позволяющих превратить его в идеальную IDE под свои нужды.

Что будет дальше
MoonLoader продолжит развиваться. Сейчас уже есть кое-какие планы по новым функциям - это набор функций для работы с памятью, конфигами, обширный апи DirectX и потоки. Любые Ваши предложения тоже приветствуются.

Эта тема создана для обсуждения вопросов, касающихся разработки под MoonLoader, а так же для предложений по изменению/дополнению функциональности, касающейся разработки. Для всего остального - основная тема.
Вся дополнительная информация по MoonLoader располагается на Wiki.

Напоминаю, если Вы заинтересованы, рекомендую подписаться на тему, чтобы ничего не пропустить.
При попытке компиляции, при вводе "luajit -b script.lua script.luac" выдает ошибку, типо ожидалось "=" вместо "-", как исправить?
 
Последнее редактирование модератором:

RollUp

Участник
52
38
Будет исправляться то, что задержка может быть использована только в main?
 

CAPTA!N

Новичок
220
50
Будет исправляться то, что задержка может быть использована только в main?
Это не ошибка.

Как правильно записать вот это в луа?
CLEO:
0B2D: write_samp_memory offset 0x16FA0 value 50064 size 2
Я пытался так
Lua:
local memory = require "memory"
------------------------------
memory.setint16(0x16FA0, 50064, true)
Я уверен что это достаточно тупо, но я просто не пойму как мне его записать...
 

FYP

Известный
Автор темы
Администратор
1,763
5,913
Будет исправляться то, что задержка может быть использована только в main?
это сделано специально. вот как, например, по твоему, обрабатывать задержку в командах, если пользователь введёт ту же команду повторно, когда действует задержка и тело команды ещё не выполнилось до конца?
ещё более наглядный пример - хук исходящих пакетов. что должно происходить, если в нём будет использована задержка да ещё и в цикле, завершающимся только по какому-то условию?
тема задержек в калбэках очень противоречива и никакой встроенной реализации задержек для них однозначно не будет.
в планах есть добавление некоего рода потоков, которые можно будет создавать из любого места, в т.ч. из калбэков, и использовать в них задержки, как и в main.

концепт примерно такой:
Lua:
function dumbThread()
wait(1000)
-- do something
end

function onSendPacket(id)
  if id == PACKET_PLAYER_SYNC then
    thread.create(dumbThread) -- каждый вызов будет приводить к перезапуску потока dumbThread, а не создавать новый. т.е. если поток не завершился сам, то будет завершён не выполнившись целиком, и пересоздан
    -- thread.create_new(dumbThread) -- будет создавать новый поток при каждом вызове, не завершая уже запущенные копии
  end
  -- после вызова thread.create функция dumbThread выполнится до задержки, и затем onSendPacket продолжит выполнение до возврата, а созданный поток будет существовать и продолжать выполнение, пока не отработает полностью (либо не будет пересоздан)
end
и то я не знаю, насколько это всё реализуемо.

Как правильно записать вот это в луа?
CLEO:
0B2D: write_samp_memory offset 0x16FA0 value 50064 size 2
Я пытался так
Lua:
local memory = require "memory"
------------------------------
memory.setint16( 0x16FA0, 50064, true)
Я уверен что это достаточно тупо, но я просто не пойму как мне его записать...
memory.setint16(sampGetBase() + 0x16FA0, 50064, true)
с подобными вопросами лучше в соответствующую тему.