С РакСампа на Самп

Official_Nekras

Известный
Автор темы
13
0
Может кто-то может переписать этот скрипт для воспроизведения маршрута форматом .rt c РакСампа на самп.

Код:
--    Route Recorder for shitty app called "Rakbot".
--    I don't trust that shit gonna work right, but whatever
--         + Onfoot sync record/replay system
--        + Incar sync record/replay system.
--         + Moonloader lua script for this shit to record sync in compatible file format (.rt)
--         * I don't really understand how to do all this stuff, but I did!!!
--
--    TODO:
--        + Loop current route
--        + Stop current route
--        * Record/Play train routes
--        + Optimize code
--
--    Author: Shamanije
--    URL: https://blast.hk/members/163165/
--    Version: 1.2.1

local rep = false
local loop = false
local packet, veh = {}, {}
local counter = 0

local bitstream = {
    onfoot = bitStreamNew(),
    incar = bitStreamNew(),
    aim = bitStreamNew()
}

function onRunCommand(cmd)
    if cmd:find('!play') or cmd:find('!stop') or cmd:find('!loop') then
        runRoute(cmd)
        return true
    end
end

function onSync()
    if rep then return true end
end

function onSendPacket(id, data, size)
    if not rep and id == 200 then
        local bs = bitStreamInit(data, size)
        bitStreamSetReadOffset(bs, 1)
        local vehId = bitStreamReadDWord(bs)
        bitStreamSetReadOffset(bs, 49)
        local vehHealth = bitStreamReadFloat(bs)
        veh[vehId] = vehHealth
    end
end

function onScriptUpdate()
    if rep then
        local ok = fillBitStream(getBotState())
        if ok then
            sendPacket(getBotState() == 1 and bitstream.onfoot or getBotState() == 2 and bitstream.incar)
            setPosition(packet[counter].x, packet[counter].y, packet[counter].z)
            counter = counter + 1
            if counter%20 == 0 then
                local aok = fillBitStream(3)
                if aok then sendPacket(bitstream.aim) else err() end
            end
        else
            err()
        end
        bitStreamReset(bitstream.incar); bitStreamReset(bitstream.onfoot); bitStreamReset(bitstream.aim)
        if counter == #packet then
            if not loop then
                rep = false
                setPosition(packet[counter].x, packet[counter].y, packet[counter].z)
                setQuaternion(packet[counter].qw, packet[counter].qx, packet[counter].qy, packet[counter].qz)
                packet = {}
            end
            counter = 1
        end
    end
end

local printLog = function(arg) return printLog('[Route Player]: '..arg) end

function err()
    rep = false
    packet = {}
    counter = 1
    printLog('an error has occured while writing data')
end

function fillBitStream(mode)
    if mode == 2 then
        local bs = bitstream.incar
        bitStreamWriteByte(bs, packet[counter].packetId)
        bitStreamWriteWord(bs, getBotVehicle())
        bitStreamWriteWord(bs, packet[counter].lr)
        bitStreamWriteWord(bs, packet[counter].ud)
        bitStreamWriteWord(bs, packet[counter].keys)
        bitStreamWriteFloat(bs, packet[counter].qw)
        bitStreamWriteFloat(bs, packet[counter].qx)
        bitStreamWriteFloat(bs, packet[counter].qy)
        bitStreamWriteFloat(bs, packet[counter].qz)
        bitStreamWriteFloat(bs, packet[counter].x)
        bitStreamWriteFloat(bs, packet[counter].y)
        bitStreamWriteFloat(bs, packet[counter].z)
        bitStreamWriteFloat(bs, packet[counter].sx)
        bitStreamWriteFloat(bs, packet[counter].sy)
        bitStreamWriteFloat(bs, packet[counter].sz)
        bitStreamWriteFloat(bs, veh[getBotVehicle()])
        bitStreamWriteByte(bs, getHealth())
        bitStreamWriteByte(bs, getArmour())
        bitStreamWriteByte(bs, getWeapon())
        bitStreamWriteByte(bs, 0)
        bitStreamWriteByte(bs, packet[counter].gear)
        bitStreamWriteWord(bs, 0)
        bitStreamWriteFloat(bs, 0)
    elseif mode == 1 then
        local bs = bitstream.onfoot
        bitStreamWriteByte(bs, packet[counter].packetId)
        bitStreamWriteWord(bs, packet[counter].lr)
        bitStreamWriteWord(bs, packet[counter].ud)
        bitStreamWriteWord(bs, packet[counter].keys)
        bitStreamSetWriteOffset(bs, 7)
        bitStreamWriteFloat(bs, packet[counter].x)
        bitStreamWriteFloat(bs, packet[counter].y)
        bitStreamWriteFloat(bs, packet[counter].z)
        bitStreamWriteFloat(bs, packet[counter].qw)
        bitStreamWriteFloat(bs, packet[counter].qx)
        bitStreamWriteFloat(bs, packet[counter].qy)
        bitStreamWriteFloat(bs, packet[counter].qz)
        bitStreamWriteByte(bs, getHealth())
        bitStreamWriteByte(bs, getArmour())
        bitStreamWriteByte(bs, getWeapon())
        bitStreamWriteByte(bs, packet[counter].sa)
        bitStreamWriteFloat(bs, packet[counter].sx)
        bitStreamWriteFloat(bs, packet[counter].sy)
        bitStreamWriteFloat(bs, packet[counter].sz)
        bitStreamWriteFloat(bs, 0)
        bitStreamWriteFloat(bs, 0)
        bitStreamWriteFloat(bs, 0)
        bitStreamWriteWord(bs, 0)
        bitStreamWriteWord(bs, packet[counter].anim)
        bitStreamWriteWord(bs, packet[counter].flags)
    elseif mode == 3 then
        local bs = bitstream.aim
        bitStreamWriteByte(bs, 203)
        bitStreamWriteByte(bs, packet[counter].mode)
        bitStreamWriteFloat(bs, packet[counter].cx)
        bitStreamWriteFloat(bs, packet[counter].cy)
        bitStreamWriteFloat(bs, packet[counter].cz)
        bitStreamWriteFloat(bs, packet[counter].px)
        bitStreamWriteFloat(bs, packet[counter].py)
        bitStreamWriteFloat(bs, packet[counter].pz)
        bitStreamWriteFloat(bs, packet[counter].az)
        bitStreamWriteByte(bs, packet[counter].zoom)
        bitStreamWriteByte(bs, packet[counter].wstate)
        bitStreamWriteByte(bs, packet[counter].unk)
    else return false end
    return true
end

function runRoute(act)
    if act:find('!play .*') then
        packet = loadIni(getRakBotPath(1)..'routes\\'..act:match('!play (.*)')..'.rt')
        if packet then
            printLog('playing route "'..act:match('!play (.*)')..'". total length: '..#packet)
            counter = 1
            rep = true
            loop = false
        else
            printLog('route doesnt exist')
        end
    elseif act:find('!loop') then
        if rep then loop = not loop; printLog(loop and 'looping current route' or 'loop off') else printLog('not playing any route') end
    elseif act:find('!stop') then
        if counter > 1 then rep = not rep else printLog('not playing any route') end
        if not rep then setQuaternion(packet[counter].qw, packet[counter].qx, packet[counter].qy, packet[counter].qz) end
        printLog(rep and 'playing resumed' or 'stopped on packet: '.. counter)
    end
end

function loadIni(fileName)
    local file = io.open(fileName, 'r')
    if file then
        local data = {}
        local section
        for line in file:lines() do
            local tempSection = line:match('^%[([^%[%]]+)%]$')
            if tempSection then
                section = tonumber(tempSection) and tonumber(tempSection) or tempSection
                data[section] = data[section] or {}
            end
            local param, value = line:match('^([%w|_]+)%s-=%s-(.+)$')
            if param and value ~= nil then
                if tonumber(value) then
                    value = tonumber(value)
                elseif value == 'true' then
                    value = true
                elseif value == 'false' then
                    value = false
                end
                if tonumber(param) then
                    param = tonumber(param)
                end
                data[section][param] = value
            end
        end
        file:close()
        return data
    end
    return false
end