Софт RakSAMP Lite

Rei

Известный
Автор темы
Друг
1,612
1,670
Минималистичный фейк клиент с возможностью расширения функционала с помощью Lua API

raksamp-thread.png


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
События можно регистрировать двумя способами:
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 *
* поддерживает выход с помощью return true/false
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)
credits
Добавляет новые функции и методы битстрима, идет из коробки
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 и т.д. Полный список всех функций и событий есть в этой теме под спойлерами выше.
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
Задержка сработала, но вся программа зависла на 3 секунды, а персонаж на сервере стоял в афк, так что она практически не используется разработчиками. Для этого в аддоне есть менеджер корутин, принцип такой же, как и в MoonLoader. С помощью него мы можем создавать скриптовые потоки, которые можно ставить на паузу и не блокировать основной поток программы. Обратите внимание, что это не обеспечивает многопоточность в чистом виде, так что ресурсозатратные функции все равно будут вешать раксамп на время выполнения.
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

Синхронный запрос, который вешает поток программы во время выполнения
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
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
Есть поддержка SOCKS5 прокси для смены IP программы. Для подключения достаточно создать скрипт и вписать в него одну строку. Более подробные примеры использования в разделе "FAQ по скриптингу"
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 скрипты


 

Вложения

  • RakSAMP Lite.zip
    835.5 KB · Просмотры: 1,792
Последнее редактирование:

tRue:#

Известный
68
17
Говорю конечно не по теме, на ракбот крякнутый есть рабочий фастконнект на арз? P24Fix.asi работает, но через определенное время блочит айпи сервер(
Спасибо
 
  • Нравится
Реакции: ivansafr

AndreyCode

Новичок
21
24
Говорю конечно не по теме, на ракбот крякнутый есть рабочий фастконнект на арз? P24Fix.asi работает, но через определенное время блочит айпи сервер(
Спасибо
Просто зайди в код ( если он открытый ) и выставь задержку коннекта на 700 и всё норм
 

Rei

Известный
Автор темы
Друг
1,612
1,670
че по слапу и спавну?
слапфикса нет ( хз нужно ли добавлять ), про спавны не понял, нормально все с ними вроде

выглядит ахуенно, но что по своим скриптам?
нет и в ближайшее время не будет, тем более в соседней ветке уже пилят луа

Просто зайди в код ( если он открытый ) и выставь задержку коннекта на 700 и всё норм
он про ракбот вообще, но в моем проекте задержка меняется в конфиге в параметре connect
 

Dozor

Потрачен
359
143
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.

Rei

Известный
Автор темы
Друг
1,612
1,670
ну типа бывает кикает за хуевый спавн
протестировал все сервера из русского топа.

Absolute Play: кик после регистрации ( сбив анимации )
Galaxy RPG: кик на входе ( скорее всего за спавн ) FIXED
Gambit RolePlay: кик на входе за requestclass 0 и невалидную версию. буду разбираться еще. FIXED
1636633059970.png

Вот бы совместить "соседнюю ветку" с твоими фиксами)
а че не опенсорс, тогда и луа не нужно
я не очень представляю, как реализовывать класс битстрима, а без этого от луашки толку вообще нет. посмотрим
выложу сурсы, если заброшу проект, так и не реализовав луа апи
 
Последнее редактирование:
  • Нравится
Реакции: 123123A, sаnеk и Dozor

The Spark

Известный
656
690
Galaxy RPG: кик на входе ( скорее всего за спавн )
Там анти-чит говна на ракбота стоит, не ты виноват
 

Rei

Известный
Автор темы
Друг
1,612
1,670
Там анти-чит говна на ракбота стоит, не ты виноват
я пытаюсь привести логику выбора классов, спавнов, синхры и т.д. к обычной самповской, так что надо чинить
 

Rei

Известный
Автор темы
Друг
1,612
1,670
Обновление

- частично подправлена aim sync: теперь голова персонажа смотрит прямо
- улучшена логика классов и спавнов ( еще меньше киков от античитов )
- скип диалогов с ID >= 32768
- теперь сендрейты задаются только в конфиге ( серверные не имеют смысла, т.к. персонаж стоит на месте )
- убрана команда !sendrates
- теперь настройки off_at_spawn и clientversion рабочие
- теперь при запуске новой версии программы сбрасывается конфиг
- добавлена забытая приставка Lite у конфига и лога
 
  • Нравится
Реакции: white.