SA-MP LUA MOONLOADER
```lua
-- imports
local imgui = require "imgui"
local encoding = require "encoding"
encoding.default = "CP1251"
u8 = encoding.UTF8

-- Logger модуль
local Logger = {}
Logger.__index = Logger

function Logger:new()
    local o = {}
    setmetatable(o, self)
    o.enabled = true
    return o
end

function Logger:log(message, level)
    level = level or "INFO"
    if self.enabled then
        -- Можно расширить запись в файл или вывод в консоль с разными цветами
        print(string.format("[%s] %s", level, message))
    end
end

local logger = Logger:new()

-- Обработчик ошибок (пример)
local function safeCall(fn, ...)
    local ok, err = pcall(fn, ...)
    if not ok then
        logger:log("Error: " .. tostring(err), "ERROR")
    end
    return ok, err
end

-- Класс: SyncDataFactory
local ffi = require "ffi"
local sampfuncs = require "sampfuncs"
local raknet = require "samp.raknet"

local SyncDataFactory = {}
SyncDataFactory.__index = SyncDataFactory

-- Таблица с метаданными нужных типов синхронизации
SyncDataFactory.SYNC_TYPES = {
    player = {ctype = "PlayerSyncData", packet = raknet.PACKET.PLAYER_SYNC, copier = sampStorePlayerOnfootData},
    vehicle = {ctype = "VehicleSyncData", packet = raknet.PACKET.VEHICLE_SYNC, copier = sampStorePlayerIncarData},
    passenger = {ctype = "PassengerSyncData", packet = raknet.PACKET.PASSENGER_SYNC, copier = sampStorePlayerPassengerData},
    aim = {ctype = "AimSyncData", packet = raknet.PACKET.AIM_SYNC, copier = sampStorePlayerAimData},
    trailer = {ctype = "TrailerSyncData", packet = raknet.PACKET.TRAILER_SYNC, copier = sampStorePlayerTrailerData},
    unoccupied = {ctype = "UnoccupiedSyncData", packet = raknet.PACKET.UNOCCUPIED_SYNC, copier = nil},
    bullet = {ctype = "BulletSyncData", packet = raknet.PACKET.BULLET_SYNC, copier = nil},
    spectator = {ctype = "SpectatorSyncData", packet = raknet.PACKET.SPECTATOR_SYNC, copier = nil}
}

function SyncDataFactory:create(sync_type, copy_from_player)
    copy_from_player = copy_from_player == nil and true or copy_from_player
    local info = self.SYNC_TYPES[sync_type]
    if not info then
        error("Unknown sync_type: " .. tostring(sync_type))
    end

    local data = ffi.new("struct " .. info.ctype)
    local raw_ptr = tonumber(ffi.cast("uintptr_t", ffi.new(info.ctype .. "*", data)))

    -- Копируем синхронизационные данные при необходимости
    if copy_from_player and info.copier then
        local _, player_id = sampGetPlayerIdByCharHandle(PLAYER_PED)
        if not player_id or player_id < 0 then
            logger:log("Invalid player_id while copying sync data", "ERROR")
        else
            info.copier(player_id, raw_ptr)
        end
    end

    local function send()
        local bs = raknet.raknetNewBitStream()
        raknet.raknetBitStreamWriteInt8(bs, info.packet)
        raknet.raknetBitStreamWriteBuffer(bs, raw_ptr, ffi.sizeof(data))
        raknet.raknetSendBitStreamEx(bs, sampfuncs.HIGH_PRIORITY, sampfuncs.UNRELIABLE_SEQUENCED, 1)
        raknet.raknetDeleteBitStream(bs)
        logger:log("Sent sync data of type " .. sync_type)
    end

    -- Метатаблица для доступа к полям data и send()
    local mt = {
        __index = function(_, key)
            if key == "send" then return send end
            return data[key]
        end,
        __newindex = function(_, key, value)
            data[key] = value
        end,
    }

    return setmetatable({}, mt)
end

local syncFactory = SyncDataFactory

-- Класс: TeleportController
local TeleportController = {}
TeleportController.__index = TeleportController

function TeleportController:new(playerPed)
    local o = {
        playerPed = playerPed,
        stepCount = 5,
        stepDelayMs = 1000,
        logger = logger
    }
    setmetatable(o, self)
    return o
end

function TeleportController:setStepCount(count)
    if count and count > 0 then
        self.stepCount = count
        self.logger:log("Step count set to " .. tostring(count))
    else
        self.logger:log("Invalid step count: " .. tostring(count), "WARN")
    end
end

function TeleportController:setStepDelay(delayMs)
    if delayMs and delayMs >= 0 then
        self.stepDelayMs = delayMs
        self.logger:log("Step delay set to " .. tostring(delayMs) .. "ms")
    else
        self.logger:log("Invalid step delay: " .. tostring(delayMs), "WARN")
    end
end

function TeleportController:instantTeleport(x, y, z)
    if not (x and y and z) then
        self.logger:log("instantTeleport called with invalid coords", "ERROR")
        return false
    end
    setCharCoordinates(self.playerPed, x, y, z)
    self.logger:log(string.format("Instant teleported player to (%.3f, %.3f, %.3f)", x, y, z))
    return true
end

function TeleportController:stepTeleport(x, y, z)
    if not (x and y and z) then
        self.logger:log("stepTeleport called with invalid coords", "ERROR")
        return false
    end

    -- Запускаем Lua thread для плавной телепортации
    lua_thread.create(function()
        local startX, startY, startZ = getCharCoordinates(self.playerPed)
        local groundZ = getGroundZFor3dCoord(x, y, z)

        local deltaX = (x - startX) / self.stepCount
        local deltaY = (y - startY) / self.stepCount
        local deltaZ = (groundZ - startZ) / self.stepCount

        for i = 1, self.stepCount do
            startX = startX + deltaX
            startY = startY + deltaY
            startZ = startZ + deltaZ

            local syncData = syncFactory:create("player")
            -- Для реалистичности задаём случайную скорость движения — можно улучшить стратегию
            syncData.moveSpeed.x = math.random(100, 1000)
            syncData.moveSpeed.y = math.random(100, 1000)
            syncData.moveSpeed.z = math.random(100, 1000)
            syncData:send()
            sampForceOnfootSync()
            setCharCoordinates(self.playerPed, startX, startY, startZ)

            wait(self.stepDelayMs)
        end
        self.logger:log(string.format("Completed step teleport to (%.3f, %.3f, %.3f)", x, y, z))
    end)
    return true
end

-- Класс MarkerFinder
local MarkerFinder = {}
MarkerFinder.__index = MarkerFinder

function MarkerFinder:new()
    local o = {logger = logger}
    setmetatable(o, self)
    return o
end

--- Поиск ближайшего маркера в радиусе
---@param posX number
---@param posY number
---@param posZ number
---@param radius number
---@param isRace boolean использовать ли гонку
---@return boolean found, number x, number y, number z
function MarkerFinder:findNearestMarker(posX, posY, posZ, radius, isRace)
    local closestDistance = radius
    local resultX, resultY, resultZ = nil, nil, nil
    local found = false

    local baseAddress = isRace and 0xC7F168 or 0xC7DD88
    local stride = isRace and 56 or 160

    for id = 0, 31 do
        local markerAddress = baseAddress + id * stride
        local markerPosX = representIntAsFloat(readMemory(markerAddress + 0, 4, false))
        local markerPosY = representIntAsFloat(readMemory(markerAddress + 4, 4, false))
        local markerPosZ = representIntAsFloat(readMemory(markerAddress + 8, 4, false))

        -- Проверяем валидность координат
        if markerPosX ~= 0.0 or markerPosY ~= 0.0 or markerPosZ ~= 0.0 then
            local dist = getDistanceBetweenCoords3d(markerPosX, markerPosY, markerPosZ, posX, posY, posZ)
            if dist < closestDistance then
                closestDistance = dist
                resultX, resultY, resultZ = markerPosX, markerPosY, markerPosZ
                found = true
            end
        end
    end

    if found then
        self.logger:log(string.format("Found marker at (%.3f, %.3f, %.3f), distance %.2f", resultX, resultY, resultZ, closestDistance))
    else
        self.logger:log("No marker found within radius " .. tostring(radius), "WARN")
    end

    return found, resultX, resultY, resultZ
end

-- Класс BlipFinder
local BlipFinder = {}
BlipFinder.__index = BlipFinder

function BlipFinder:new()
    local o = {logger = logger}
    setmetatable(o, self)
    return o
end

-- Получение координат целевого blip с предварительной загрузкой коллизий
---@return boolean found, number x, number y, number z
function BlipFinder:getTargetBlipCoordinates()
    local found, x, y, z = getTargetBlipCoordinates()
    if not found then
        self.logger:log("No target blip found", "WARN")
        return false
    end
    requestCollision(x, y)
    loadScene(x, y, z)
    -- уточняем координаты повторно после загрузки
    local found2, x2, y2, z2 = getTargetBlipCoordinates()
    if not found2 then
        self.logger:log("No target blip found after loading scene", "WARN")
        return false
    end
    return true, x2, y2, z2
end

-- Класс UIManager — управление пользовательским интерфейсом
local UIManager = {}
UIManager.__index = UIManager

function UIManager:new(config)
    local o = {
        windowOpen = false,
        config = config or {}, -- Конфигурация или ссылки на контроллеры
        posBuffers = {x = imgui.ImBuffer(128), y = imgui.ImBuffer(128), z = imgui.ImBuffer(128)},
        checkboxStates = {
            enableTeleportSteps = imgui.ImBool(false),
            enableBlipFinder = imgui.ImBool(false),
            enableMarkerFinder = imgui.ImBool(false),
            enableGovnovoz = imgui.ImBool(false),
        },
        sliderValues = {
            stepCount = imgui.ImInt(5),
            stepDelay = imgui.ImInt(1000),
            markerDistance = imgui.ImInt(100),
            govnovozHeight = imgui.ImInt(100),
        },
        logger = logger,
    }
    setmetatable(o, self)
    return o
end

function UIManager:updatePositionFields(x, y, z)
    self.posBuffers.x.v = tostring(x)
    self.posBuffers.y.v = tostring(y)
    self.posBuffers.z.v = tostring(z)
end

function UIManager:draw()
    if not self.windowOpen then return end

    imgui.SetNextWindowPos(imgui.ImVec2(350, 250), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowSize(imgui.ImVec2(550, 450), imgui.Cond.FirstUseEver)
    if not imgui.Begin("OTP By Tectrex", self.checkboxStates) then
        imgui.End()
        return
    end

    local playerPed = self.config.playerPed
    local teleportController = self.config.teleportController
    local markerFinder = self.config.markerFinder
    local blipFinder = self.config.blipFinder

    -- Информация инкарса
    if isCharInAnyCar(playerPed) then
        imgui.Text("Player in car")
        if imgui.Checkbox("Enable Govnovoz", self.checkboxStates.enableGovnovoz) then
            local val = self.checkboxStates.enableGovnovoz.v
            self.logger:log("Govnovoz toggled: " .. tostring(val))
        end

        if self.checkboxStates.enableGovnovoz.v then
            local car = getCarCharIsUsing(playerPed)
            local posX, posY, _ = tonumber(self.posBuffers.x.v) or 0, tonumber(self.posBuffers.y.v) or 0, tonumber(self.posBuffers.z.v) or 0
            local carX, carY, _ = getCarCoordinates(car)
            local heading = getHeadingFromVector2d(posX - carX, posY - carY)
            setCarCoordinates(car, carX, carY, self.sliderValues.govnovozHeight.v)
            setCarForwardSpeed(car, 100)
            setCarHeading(car, heading)
            setCharCanBeKnockedOffBike(playerPed, true)
        else
            freezeCarPosition(getCarCharIsUsing(playerPed), false)
            setCharCanBeKnockedOffBike(playerPed, false)
        end

    else
        imgui.Text("Player not in car")
    end

    -- Coord Master (телепортация с шагами)
    if imgui.Checkbox("Enable Coord-Master", self.checkboxStates.enableTeleportSteps) then
        local val = self.checkboxStates.enableTeleportSteps.v
        self.logger:log("Coord-Master toggled: " .. tostring(val))
    end
    imgui.SameLine()
    imgui.Text(self.checkboxStates.enableTeleportSteps.v and "Enabled" or "Disabled")

    if imgui.Checkbox("Enable Blip Finder", self.checkboxStates.enableBlipFinder) then
        self.logger:log("Blip Finder toggled: " .. tostring(self.checkboxStates.enableBlipFinder.v))
    end
    imgui.SameLine()
    imgui.Text(self.checkboxStates.enableBlipFinder.v and "Enabled" or "Disabled")

    -- Авто вставка блип координат если включено
    if self.checkboxStates.enableBlipFinder.v then
        local found, bx, by, bz = blipFinder:getTargetBlipCoordinates()
        if found then
            self:updatePositionFields(bx, by, bz)
        else
            printStringNow("No blip found", 1000)
        end
    end

    if imgui.Checkbox("Enable Marker Finder", self.checkboxStates.enableMarkerFinder) then
        self.logger:log("Marker Finder toggled: " .. tostring(self.checkboxStates.enableMarkerFinder.v))
    end
    imgui.SameLine()
    imgui.Text(self.checkboxStates.enableMarkerFinder.v and "Enabled" or "Disabled")

    -- Маркеры
    if self.checkboxStates.enableMarkerFinder.v then
        local px, py, pz = getCharCoordinates(playerPed)
        local found, mx, my, mz = markerFinder:findNearestMarker(px, py, pz, self.sliderValues.markerDistance.v, false)
        if not found then     -- Попытка найти для гонок, если не найдено
            printStringNow("No marker found, trying race markers", 1000)
            found, mx, my, mz = markerFinder:findNearestMarker(px, py, pz, self.sliderValues.markerDistance.v, true)
        end
        if found then
            self:updatePositionFields(mx, my, mz)
        end
    end

    imgui.Separator()

    -- Поля ввода координат
    for _, axis in ipairs({"X", "Y", "Z"}) do
        if imgui.InputText(axis, self.posBuffers[string.lower(axis)]) then
            -- Можно добавить валидацию значения
        end
        imgui.SameLine()
    end

    imgui.NewLine()

    -- Кнопки для быстрого задания координат
    if imgui.Button("Get PLAYER_PED Coordinates") then
        local x, y, z = getCharCoordinates(playerPed)
        self:updatePositionFields(x, y, z)
        self.logger:log("Copied PLAYER_PED coordinates to input fields")
    end
    imgui.SameLine()
    if imgui.Button("Get Marker Coordinates") then
        local px, py, pz = getCharCoordinates(playerPed)
        local found, mx, my, mz = markerFinder:findNearestMarker(px, py, pz, self.sliderValues.markerDistance.v, false)
        if not found then
            printStringNow("No marker found, trying race markers", 1000)
            found, mx, my, mz = markerFinder:findNearestMarker(px, py, pz, self.sliderValues.markerDistance.v, true)
        end
        if found then
            self:updatePositionFields(mx, my, mz)
            self.logger:log("Copied marker coordinates to input fields")
        else
            printStringNow("No marker found", 1000)
            self.logger:log("Failed to find marker near player for copy")
        end
    end
    imgui.SameLine()
    if imgui.Button("Get Blip Coordinates") then
        local found, bx, by, bz = blipFinder:getTargetBlipCoordinates()
        if found then
            self:updatePositionFields(bx, by, bz)
            self.logger:log("Copied blip coordinates to input fields")
        else
            printStringNow("No blip found", 1000)
            self.logger:log("Failed to find blip for copy")
        end
    end

    imgui.Separator()

    -- Слайдеры
    local function sliderWithLabel(label, sliderVar, minVal, maxVal, description)
        if imgui.SliderInt(label, sliderVar, minVal, maxVal) then
            printStringNow(string.format("%s: %d", label, sliderVar.v), 1000)
            self.logger:log(string.format("%s changed to %d", label, sliderVar.v))
        end
        imgui.SameLine()
        imgui.TextDisabled("(" .. description .. ")")
    end
    sliderWithLabel("Govnovoz Height", self.sliderValues.govnovozHeight, 1, 500, "Высота говновоза")
    imgui.Separator()
    sliderWithLabel("Step Count", self.sliderValues.stepCount, 1, 500, "Кол-во шагов на телепортацию")
    imgui.Separator()
    sliderWithLabel("Step Delay (ms)", self.sliderValues.stepDelay, 0, 1000, "Задержка между шагами")
    imgui.Separator()
    sliderWithLabel("Marker Distance", self.sliderValues.markerDistance, 1, 10000, "Радиус поиска маркера")
    imgui.Separator()

    -- Кнопка Телепорта
    if imgui.Button("Teleport") then
        local x = tonumber(self.posBuffers.x.v)
        local y = tonumber(self.posBuffers.y.v)
        local z = tonumber(self.posBuffers.z.v)
        if x and y and z then
            teleportController:setStepCount(self.sliderValues.stepCount.v)
            teleportController:setStepDelay(self.sliderValues.stepDelay.v)
            if self.checkboxStates.enableTeleportSteps.v then
                teleportController:stepTeleport(x, y, z)
            else
                teleportController:instantTeleport(x, y, z)
            end
        else
            self.logger:log("Invalid coordinates entered for teleportation", "ERROR")
            print("Please enter valid numeric coordinates!")
        end
    end

    imgui.End()
end

-- Класс MainApp — точка входа и управление основным циклом
local MainApp = {}
MainApp.__index = MainApp

function MainApp:new()
    local o = {
        playerPed = PLAYER_PED,
        teleportController = nil,
        markerFinder = nil,
        blipFinder = nil,
        uiManager = nil,
        initialized = false
    }
    setmetatable(o, self)
    return o
end

function MainApp:init()
    if self.initialized then return end

    self.teleportController = TeleportController:new(self.playerPed)
    self.markerFinder = MarkerFinder:new()
    self.blipFinder = BlipFinder:new()
    self.uiManager = UIManager:new({
        playerPed = self.playerPed,
        teleportController = self.teleportController,
        markerFinder = self.markerFinder,
        blipFinder = self.blipFinder,
    })

    sampRegisterChatCommand("otp", function()
        self.uiManager.windowOpen = not self.uiManager.windowOpen
        logger:log("OTP window toggled: " .. tostring(self.uiManager.windowOpen))
    end)

    -- Быстрая телепортация по команде /otpr
    sampRegisterChatCommand("otpr", function()
        local x, y, z = tonumber(self.uiManager.posBuffers.x.v), tonumber(self.uiManager.posBuffers.y.v), tonumber(self.uiManager.posBuffers.z.v)
        if x and y and z then
            if self.uiManager.checkboxStates.enableTeleportSteps.v then
                self.teleportController:stepTeleport(x, y, z)
            else
                self.teleportController:instantTeleport(x, y, z)
            end
        else
            logger:log("Invalid coordinates provided in /otpr command", "ERROR")
            print("Invalid coordinates")
        end
    end)

    self.initialized = true
    logger:log("MainApp initialized")
end

function MainApp:run()
    self:init()

    while not isSampAvailable() do
        wait(200)
    end

    imgui.Process = false
    self.uiManager.windowOpen = false

    -- Главный цикл игры
    while true do
        wait(0)
        imgui.Process = self.uiManager.windowOpen
    end
end

-- MoonLoader callback для рисования UI (imgui)
function imgui.OnDrawFrame()
    -- Используем MainApp singleton
    if not _G.mainAppInstance then
        _G.mainAppInstance = MainApp:new()
    end
    safeCall(function()
        _G.mainAppInstance.uiManager:draw()
    end)
end

-- MoonLoader start point
function main()
    _G.mainAppInstance = MainApp:new()
    safeCall(function()
        _G.mainAppInstance:run()
    end)
end
```
Твоя задача улучшить интерфейс, сделать его красивее и современее. И написать весь код полностью.