Минималистичный фейк клиент с возможностью расширения функционала с помощью Lua API
credits
Искать нужный диалог можно еще, например, по названию
Lua:
print(string text) -- вывести сообщение
sleep(int ms) -- задержка ( вешает всю программу )
exit() -- выйти из программы ( с отключением от сервера и выгрузкой скриптов )
setServerAddress(string address) -- установить адрес сервера
setBotNick(string nick) -- установить ник боту
setBotPosition(float x, float y, float z) -- установить позицию боту
setBotQuaternion(float w, float x, float y, float z) -- установить кватернион боту
setBotRotation(float angle) -- установить угол боту
setBotHealth(float health) -- установить хп боту
setBotArmor(float armor) -- установить броню боту
setNetworkAdapter(string ip) -- установить сетевой адаптер
setWindowTitle(string title) -- установить заголовок окну программы
lockWindowTitle(bool lock) -- заблокировать изменение заголовка окна программой
setWindowText(string text) -- установить текст в строке состояния над чатом ( GUI )
lockWindowText(bool lock) -- заблокировать изменение строки состояния
flashWindow() -- моргнуть окном
showWindow() -- развернуть окно
setRate(int rate, int value) -- установить рейты ( 0-8 ) **
runCommand(string cmd) -- обработать команду раксампа
reconnect(int ms) -- переподключиться к серверу, вызов без параметров установит стандартную задержку
spawn() -- заспавниться
updateSync() -- обновить синхру
resetConnectTimeout() -- сбросить текущий таймер переподключения
setBotVehicle(int id, int seat = 0) -- установить авто боту. id 0 - нет авто, seat 0 - водительское
coordStart(float x, float y, float z, int delay, float step, bool off_at_spawn) -- включить курд
coordStop() -- выключить курд
setLogPath(string path) -- установить файл лога
setAutoPick(bool state) -- включить/выключить автовзятие пикапов
proxyConnect(string address, string username, string password) -- подключиться к прокси, 2 и 3 аргумент необязательны
proxyDisconnect() -- отключиться от прокси
setBotMoney(int money) -- установить деньги боту
registerHandler(string event, function handler) -- регистрирует обработчик события
destroyHandlers() -- удаляет все обработчики событий скрипта
int id = getBotId() -- получить ид бота
string ip = getServerAddress() -- получить адрес сервера
string name = getServerName() -- получить название сервера
string nick = getBotNick() -- получить ник бота
int score = getBotScore() -- получить очки ( лвл ) бота
int ping = getBotPing() -- получить пинг бота
bool spawned = isBotSpawned() -- проверить, заспавнен ли бот
int interior = getBotInterior() -- получить интерьер бота
int skin = getBotSkin() -- получить скин бота
float x, float y, float z = getBotPosition() -- получить позицию бота
float w, float x, float y, float z = getBotQuaternion() -- получить кватернион бота
float angle = getBotRotation() -- получить угол бота
float health = getBotHealth() -- получить хп бота
float armor = getBotArmor() -- получить броню бота
string ip = getNetworkAdapter() -- получить сетевой адаптер
string args = getCommandLineArgs() -- получить аргументы командной строки
bool connected = isBotConnected() -- проверить, подключен ли бот к серверу
int vehicle = getBotVehicle() -- получить авто бота. 0 - нет авто
bool active = isCoordActive() -- проверить, включен ли курд
string path = getPath(string additional) -- получить корень программы
bool connected = isProxyConnected() -- проверить, подключен ли к прокси
int money = getBotMoney() -- получить деньги бота
int count = getPlayerCount(bool stream = false) -- получить количество игроков
bool connected = isPlayerConnected(int id) -- проверить, подключен ли игрок
bool exist = doesPlayerExist(int id) -- проверить, существует ли игрок
bool exist = doesVehicleExist(int id) -- проверить, существует ли авто
bool exist = doesPickupExist(int id) -- проверить, существует ли пикап
bool exist = doesLabelExist(int id) -- проверить, существует ли 3д текст
table players = getAllPlayers() -- получить всех игроков
table vehicles = getAllVehicles() -- получить все авто
table pickups = getAllPickups() -- получить все пикапы
table labels = getAllLabels() -- получить все 3д тексты
table player = getPlayer(int id) -- получить игрока, не вернет ничего, если не подключен
table vehicle = getVehicle(int id) -- получить авто *
table pickup = getPickup(int id) -- получить пикап *
table label = getLabel(int id) -- получить 3д текст *
* не вернет ничего, если не существует
-- структуры:
getAllPlayers() = {
[id] = {
int score,
int ping,
string nick,
bool exist,
int skin,
int color,
table position
},
...
}
getAllVehicles() = {
[id] = {
float health,
int model,
string name,
string number,
bool engine,
bool lights,
bool alarm,
bool locked,
table position
},
...
}
getAllPickups() = {
[id] = {
int model,
int type,
table position
},
...
}
getAllLabels() = {
[id] = {
float distance,
int color,
bool test_los,
int player_id,
int vehicle_id,
string text,
table position
},
...
}
** рейты:
RATE_SLEEP
RATE_CONNECT
RATE_RECONNECT
RATE_NETWORK
RATE_LUA
RATE_SPECTATE
RATE_ONFOOT
RATE_INCAR
RATE_AIM
События можно регистрировать двумя способами:
Список событий
* поддерживает выход с помощью return true/false
Lua:
-- по классике
function onRunCommand(cmd)
print(cmd)
end
-- либо так
registerHandler("onRunCommand", function(cmd)
print(cmd)
end)
Список событий
Lua:
onLoad() -- загрузка скрипта
onUnload() -- выгрузка скрипта
onUpdate() -- вызывается каждые N ms, указывается в конфиге
onRequestConnect() -- запрос на подключение к серверу *
onConnect() -- коннект к серверу
onDisconnect() -- дисконнект от сервера
onProxyConnect() -- подключение к прокси
onProxyDisconnect() -- отключение от прокси
onProxyError() -- ошибка подключения к прокси
onCoordStart() -- старт курда
onCoordStop() -- остановка курда
onRunCommand(string cmd) -- ввод клиентской команды !cmd *
onPrintLog(string text) -- вывод в лог *
onSendPacket(id, bs) -- отправка пакета *
onReceivePacket(id, bs) -- получение пакета *
onSendRPC(id, bs) -- отправка RPC *
onReceiveRPC(id, bs) -- получение RPC *
Lua:
bitStream bs = bitStream.new() -- создать новый объект
bs:writeBool(bool value)
bs:writeInt8(int value)
bs:writeUInt8(int value)
bs:writeInt16(int value)
bs:writeUInt16(int value)
bs:writeInt32(int value)
bs:writeUInt32(int value)
bs:writeFloat(float value)
bs:writeString(string value)
bs:writeEncoded(string value)
bs:writeBitStream(bitStream bs)
bs:resetWritePointer()
bs:resetReadPointer()
bs:setWriteOffset(int offset)
bs:setReadOffset(int offset)
bs:writeBuffer(int bitStreamPtr, int size)
bs:ignoreBits(int value)
bs:ignoreBytes(int value)
bs:reset()
bool value = bs:readBool()
int value = bs:readInt8()
int value = bs:readUInt8()
int value = bs:readInt16()
int value = bs:readUInt16()
int value = bs:readInt32()
int value = bs:readUInt32()
float value = bs:readFloat()
string value = bs:readString(int length)
string value = bs:readEncoded(int length)
bitStream bs = bs:getBitStream()
int offset = bs:getWriteOffset()
int offset = bs:getReadOffset()
bool result = bs:readBuffer(int data_ptr, int size)
int value = bs:getNumberOfBitsUsed()
int value = bs:getNumberOfBytesUsed()
int value = bs:getNumberOfUnreadBits()
int value = bs:getNumberOfUnreadBytes()
int ptr = bs:getDataPtr()
int ptr = bs:getBitStreamPtr()
bool result = bs:sendRPC(int id)
bool result = bs:sendPacket()
bool result = bs:sendRPCEx(int id, int priority, int reliability, int channel, bool timestamp)
bool result = bs:sendPacketEx(int priority, int reliability, int channel)
Добавляет новые функции и методы битстрима, идет из коробки
Lua:
require("addon") -- подключить аддон
bool value = isBotInAnyVehicle() -- проверить, находится ли бот в авто
sendSpawnRequest() -- отправить запрос спавна
sendDialogResponse(int id, int button, int list, string input) -- отправить ответ на диалог
sendClickTextdraw(int id) -- кликнуть по текстдраву
sendPickedUpPickup(int id) -- поднять пикап
sendVehicleEnter(int id, bool passenger) -- отправить посадку в авто
sendVehicleExit(int id) -- отправить выход из авто
sendTargetUpdate(int object, int vehicle, int player, int actor) -- отправить таргет камеры
sendInput(string text) -- отправить в чат ( текст с / отошлется командой )
bitStream:readString8() -- прочитать строку с длиной int8
bitStream:writeString8(string value) -- записать длину в int8 и строку
bitStream:readBool8() -- прочитать bool в int8
bitStream:writeBool8(bool value) -- записать bool в int8
bitStream:writeArray(table value) -- записать массив байтов
bitStream:writeVector3(table value ) -- записать vector3
bitStream:readVector3() -- прочитать vector3
task = newTask(function f, bool/int halted, ...) -- создать таску и получить объект
-- если halted - true, то таска запустится приостановленной
-- если halted - число, то запустится с указанной задержкой
-- ... - аргументы, передаваемые в функцию
clearTasks() -- убить все таски
wait(int time) -- задержка в мс, работает только внутри тасков
-- методы
task:halt() -- поставить на паузу
task:tick() -- принудительно выполнить
task:resume() -- возобновить выполнение
task:kill() -- убить таску
bool alive = task:isAlive() -- проверить, существует ли таска
bool halted = task:isHalted() -- проверить, на паузе ли таска
Так как основная цель этого апи - прописать реакцию бота на внешние раздражители, весь код выполняется в различных событиях. Таких как загрузка/выгрузка скрипта, подключение/отключение к серверу/прокси, сетевые события, скриптовые RPC и т.д. Полный список всех функций и событий есть в этой теме под спойлерами выше.
Часто нужно вызывать несколько функций подряд с некоторой задержкой. Самый простой вариант - функция sleep
Задержка сработала, но вся программа зависла на 3 секунды, а персонаж на сервере стоял в афк, так что она практически не используется разработчиками. Для этого в аддоне есть менеджер корутин, принцип такой же, как и в MoonLoader. С помощью него мы можем создавать скриптовые потоки, которые можно ставить на паузу и не блокировать основной поток программы. Обратите внимание, что это не обеспечивает многопоточность в чистом виде, так что ресурсозатратные функции все равно будут вешать раксамп на время выполнения.
И рассмотрим напоследок то, с чем больше всего придется работать - samp events. Больше информации и примеров в основной теме SAMP.Lua
Lua:
-- сразу можем подключить две либы, они используются почти во всех скриптах
require "addon" -- стандартная библиотека с доп. функциями на lua
local sampev = require "samp.events" -- библиотека FYP'а, адаптированная под раксамп
-- onLoad - аналог main в MoonLoader. За исключением того, что в нем нельзя использовать задержку без потока, о ней ниже
function onLoad()
print("hello world")
setRate(RATE_LUA, 100) -- теперь функция onUpdate будет вызываться каждые 100 ms
end
function onConnect()
print("мы подключились к серверу!")
end
-- эта функция вызывается постоянно каждые n миллисекунд, в onLoad
function onUpdate()
-- так же
end
-- функция вызывается при выгрузке скрипта в двух случаях: перезагрузка всех скриптов и выход из программы
-- можно в ней сделать сохранение каких-нибудь данных скрипта
-- но важные данные лучше сохранять до, т.к. при аварийном выходе она не всегда будет вызвана
function onUnload()
print("выгружаемся")
end
Часто нужно вызывать несколько функций подряд с некоторой задержкой. Самый простой вариант - функция sleep
Lua:
function onLoad()
print("добрый день")
sleep(3000) -- ждём 3 секунды
print("хороший сегодня день")
end
Lua:
-- если текст для флуда был задан пользователем через команду,
-- то текст будет отправляться в чат каждую секунду
function onLoad()
print("флудер загружен")
newTask(function()
wait(1000)
if flood_text then
sendInput(flood_text)
end
end)
end
-- ловим в событии ввод команды в программу
function onRunCommand(cmd)
if cmd:find("^!flood") then
if flood_text then -- если флудер работает, то повторный ввод команды выключит его
flood_text = nil
else
flood_text = cmd:match("^!flood (.-)$") -- с помощью регулярного выражения получаем из команды аргумент
end
return false -- чтобы она не шла пошла дальше в стандартный обработчик команд и не получить ошибку "неизвестная команда" от раксампа
end
end
И рассмотрим напоследок то, с чем больше всего придется работать - samp events. Больше информации и примеров в основной теме SAMP.Lua
Lua:
math.randomseed(os.time()) -- без этого math.random будет выдавать каждый раз одинаковые результаты
-- хук сообщений от сервера
function sampev.onServerMessage(color, text)
if text:find("^Администратор .- Вы тут?")
-- если вам нужен поток всего для одной функции, а не блока кода,
-- то проще создать поток таким образом
newTask(sendInput, math.random(3000, 6000, "тут")
end
if text:find("хуй") then -- фильтруем базар
text = text:gsub("хуй", "***")
end
return { color, text } -- возвращаем исправленное сообщение
end
-- фриз персонажа
function sampev.onTogglePlayerControllable(controllable)
if not controllable then
print("нашего бота заморозили!")
else
print("фух, разморожен")
end
end
-- сервер устанавливает хп
function sampev.onSetPlayerHealth(health)
if health < 100 then
return false -- отклоняем пакет, получается антиголод
end
end
-- пакет с информацией о выпущенной пули
function sampev.onBulletSync(id, data)
if data.targetId == getBotId() then -- если пуля летит в нас, то отклоняем ее - гм от пуль
return false
end
end
Lua:
require("addon")
local sampev = require("samp.events")
local password = "123456"
local dialog_id = 2
function sampev.onShowDialog(id, style, title, btn1, btn2, text)
if id == dialog_id then
sendDialogResponse(id, 1, -1, password)
return false
end
end
Искать нужный диалог можно еще, например, по названию
Lua:
function sampev.onShowDialog(id, style, title, btn1, btn2, text)
if title:find("Авторизация") then
sendDialogResponse(id, 1, -1, password)
return false
end
end
Используем requests
Синхронный запрос, который вешает поток программы во время выполнения
Асинхронный запрос с помощью effil. Для работы нужно обновить либу до последней версии отсюда: github
Примеры использования
Синхронный запрос, который вешает поток программы во время выполнения
Lua:
local requests = require("requests")
-- получить свой IP
local response = requests.get("https://api.ipify.org")
if response.status_code == 200 then -- OK
print(response.text)
end
Асинхронный запрос с помощью effil. Для работы нужно обновить либу до последней версии отсюда: github
Lua:
local effil = require 'effil'
async_http_request = setmetatable({}, {
__index = function(_, method)
return function(url, args, resolve, reject)
local runner = effil.thread(function(method, url, args)
local requests = require 'requests'
local result, response = pcall(requests.request, method:upper(), url, args and effil.dump(args))
if result then
response.json, response.xml = nil, nil
return true, response
else
return false, response
end
end)(method, url, args)
if not resolve then resolve = function() end end
if not reject then reject = function() end end
newTask(function()
while true do
local status, err = runner:status()
if err then
return reject(err)
elseif status == 'cancelled' then
return reject(status)
elseif status == 'completed' then
local result, response = runner:get()
if result then
return resolve(response)
end
return reject(response)
end
wait(0)
end
end)
end
end
})
Примеры использования
Lua:
-- отправка сообщения в тг
async_http_request.get("https://api.telegram.org/bot5678126785:AJsfj8i123j5rtAJSF91/sendMessage", {
params = {
chat_id = "12848142",
text = "huyita"
}
})
-- получение своего IP
async_http_request.get("https://api.ipify.org",
function(response) -- эта функция вызовется при успешном запросе
print(response.text)
print(response.status_code)
end,
function(err) -- эта функция вызовется при ошибке
print("ошибка:", err)
end)
Кнопки отправляются в синхре игрока в поле keysData. У вас не получится сесть в авто только лишь с помощью нажатия F/G или прожать текстдрав через клик мыши, для этого есть отдельные функции!
Список айди кнопок : wiki
Клавиши: Y/N/H ( 1/2/3 соответственно ) отправляются в поле specialKey
Использование:
Список айди кнопок : wiki
Клавиши: Y/N/H ( 1/2/3 соответственно ) отправляются в поле specialKey
Lua:
local sampev = require("samp.events")
-- обычные клавиши ( alt, f, лкм, ... )
function sendKey(id)
key = id
updateSync() -- принудительно отправляем пакет синхронизации с кнопками
end
-- Y, N, H
function sendSpecialKey(id)
skey = id
updateSync()
end
function onRunCommand(cmd)
if cmd:find("^!key %d+$") then
sendKey(tonumber(cmd:match("%d+")))
return false
elseif cmd:find("^!skey %d+$") then
sendSpecialKey(tonumber(cmd:match("%d+")))
return false
end
end
function sampev.onSendPlayerSync(data)
if key then
data.keysData = key -- в исходящей синхронизации подставляем свою кнопку
key = nil -- чистим, чтобы клавиша не была зажата
end
if skey then
data.specialKey = skey -- ( Y, N, H )
skey = nil
end
end
-- то же самое, что и в функции выше, только еще и для авто
function sampev.onSendVehicleSync(data)
if key then
data.keysData = key
key = nil
end
if skey then
data.specialKey = skey
skey = nil
end
end
-- помимо этого, keysData и specialKey есть в PassengerSyncData. А в SpectatorSyncData только keysData
-- см. libs/samp/synchronization.lua
Lua:
sendKey(1024) -- отправить alt
sendSpecialKey(1) -- отправить Y
!key 1024
!skey 1
Lua:
-- подключаемся к прокси после загрузки скрипта
function onLoad()
proxyConnect("123.145.167.189:58765", "user", "pass")
end
-- чтоб не подключался к серверу без прокси
function onRequestConnect()
if not isProxyConnected() then return false end
end
-- функция вызывается при ошибки
function onProxyError()
print("ошибка при подключении к прокси")
end
-- функция вызывается при успешном подключении
function onProxyConnect()
print("успешно подключились к прокси!")
end
Фиксы:
WeaponFix
interpolate camera fix
ConnectFix
Connect Accepted Fix
HitFix
SendPing Fix
AimSync FIX
Slapfix
Другие
Follow ( липучка )
Route Recording System
WeaponFix
interpolate camera fix
ConnectFix
Connect Accepted Fix
HitFix
SendPing Fix
AimSync FIX
Slapfix
Другие
Follow ( липучка )
Route Recording System
Есть поддержка SOCKS5 прокси для смены IP программы. Для подключения достаточно создать скрипт и вписать в него одну строку. Более подробные примеры использования в разделе "FAQ по скриптингу"
В бесплатных прокси листах сложно найти что-то рабочее, так что советую платные проверенные сервисы ⬇️
proxy6.net - купон на 5% скидку: WQhFNHVGM3
proxys.io - купон на 5% скидку: raksamp ( много стран )
proxymania.ru - купон на 5% скидку: raksamp
proxyline.net - купон на 5% скидку: raksamp
⚠️ У сервисов есть возможность авторизации по IP, чтоб не вводить логин и пароль. Но не советую пользоваться этой функцией, в текущей версии есть проблема с авторизацией без пароля
Lua:
proxyConnect("123.145.167.189:58765", "user", "pass")
В бесплатных прокси листах сложно найти что-то рабочее, так что советую платные проверенные сервисы ⬇️
proxy6.net - купон на 5% скидку: WQhFNHVGM3
proxys.io - купон на 5% скидку: raksamp ( много стран )
proxymania.ru - купон на 5% скидку: raksamp
proxyline.net - купон на 5% скидку: raksamp
⚠️ У сервисов есть возможность авторизации по IP, чтоб не вводить логин и пароль. Но не советую пользоваться этой функцией, в текущей версии есть проблема с авторизацией без пароля
!exit/quit - выход из программы
!reconnect - перезаход
!reload - перезагрузить настройки
!players - вывести список игроков
!npcs - вывести список npc
!vehicles- вывести список авто
!pickups - вывести список пикапов
!labels - вывести список 3д текстов
!goto <id> - телепортироваться к игроку
!gotocp - телепортироваться к чекпоинту
!vdeath - отправить серверу уведомление о взрыве авто
!fu - отправить серверу потерю соединения
!menusel <n> - выбрать пункт в gta menu
!class <id> - отправить request class
!spawn - заспавниться
!reqspawn - отправить request spawn
!gm - переключить гм
!kill - убиться
!pickup <id> - подобрать пикап
!weapon <id> - установить оружие
!selveh <id> [seat] - установить авто. id 0 - нет авто, seat 0 - водительское
!setip <ip:port> - установить сервер
!setnick <nick> - установить ник
!pos <x> <y> <z> - установить позицию
!rot <angle> - установить угол
!coord <x> <y> <z> - курд мастер
!diagsend <button> <listbox> <input> - отправить ответ последнему диалогу
!scmevent <type> <param1> <param2> <param3> - отправить scm эвент
!fakekick - кикнуться с помощью невалидного авто
!seltd <id> - кликнуть по текстдраву
!autopick - переключить автовзятие пикапов
!reloadlua - перезагрузить Lua скрипты
!reconnect - перезаход
!reload - перезагрузить настройки
!players - вывести список игроков
!npcs - вывести список npc
!vehicles- вывести список авто
!pickups - вывести список пикапов
!labels - вывести список 3д текстов
!goto <id> - телепортироваться к игроку
!gotocp - телепортироваться к чекпоинту
!vdeath - отправить серверу уведомление о взрыве авто
!fu - отправить серверу потерю соединения
!menusel <n> - выбрать пункт в gta menu
!class <id> - отправить request class
!spawn - заспавниться
!reqspawn - отправить request spawn
!gm - переключить гм
!kill - убиться
!pickup <id> - подобрать пикап
!weapon <id> - установить оружие
!selveh <id> [seat] - установить авто. id 0 - нет авто, seat 0 - водительское
!setip <ip:port> - установить сервер
!setnick <nick> - установить ник
!pos <x> <y> <z> - установить позицию
!rot <angle> - установить угол
!coord <x> <y> <z> - курд мастер
!diagsend <button> <listbox> <input> - отправить ответ последнему диалогу
!scmevent <type> <param1> <param2> <param3> - отправить scm эвент
!fakekick - кикнуться с помощью невалидного авто
!seltd <id> - кликнуть по текстдраву
!autopick - переключить автовзятие пикапов
!reloadlua - перезагрузить Lua скрипты
beta версия от 15 мая 2024, список изменений
Вложения
Последнее редактирование: