MX_Master

Общий мини "HELP ME" топик по скриптингу

Recommended Posts

Серьезная ошибка при создании обработчиков событий.

addEventHandler ( "onClientPlayerVehicleExit", getRootElement(), Exit ) 

Это значит, что обработчик событий будет вызывать функцию для любого игрока, который садится в авто, что в данном случае приводит к удалению бинда, когда второй игрок садится в авто.

Чтобы это исправить нужно либо прикрепить обработчик к элементу локального игрока:

addEventHandler ( "onClientPlayerVehicleExit", localPlayer, Exit ) 

Либо ввести проверку на игрока в теле функции:

function Exit ( vehicle ) 
    if source == localPlayer then 
         unbindKey ( "k", "down", create ) 
         setElementData ( localPlayer, "on", 0 ) 
         triggerServerEvent ( "removeVehicleFromTable", localPlayer, vehicle ) 
    end 
end 

Это нужно проделать также для onClientPlayerVehicleEnter

Дальше, обработчик события

addEventHandler ( "onClientVehicleExplode", getRootElement(), Explode ) 

В таком виде он будет удалять бинд при взрыве любого авто на сервере.

Чтобы это исправить нужно либо производить крепление обработчика при входе в авто:

function onEnterVehicle (vehicle) 
    ... 
    addEventHandler ( "onClientVehicleExplode", vehicle, Explode ) 
    ... 
end 

(Важно потом при выходе из авто удалять это событие!)

Либо вводить проверку на нахождение нашего игрока в данном авто:

function Explode ( ) 
    if source == getPedOccupiedVehicle ( localPlayer ) then 
        unbindKey ( "k", "down", create ) 
        setElementData ( localPlayer, "on", 0 ) 
        triggerServerEvent ( "removeVehicleFromTable", localPlayer, source ) 
    end 
end 

Это нужно проделать также для onClientElementDestroy

При желании можно существенно облегчить и улучшить логику скриптов, но это уже выходит за рамки данной проблемы.

Share this post


Link to post

1. Можно ли записать в базу массив, не используя несколько колонок, строку значений через пробел и пр. костыли?

2. Как лучше всего обозначать игроков в базе? Сейчас я использую просто имя, но игроки его могут менять. Нужно присвоить какой-то числовой ИД. Как это лучше и удобней всего сделать? Было бы очень хорошо, если бы можно было получить ИД аккаунта, но это невозможно.

Share this post


Link to post

1.

fromJSON 
toJSON 

либо

table.serialize/table.deserialize

viewtopic.php?f=141&t=33091

Первый вариант быстрее.

2. Используй атрибут auto_increment. При добавлении в базу аккаунта можно получить его ид используя функцию dbPoll

int: last insert id

https://wiki.multitheftauto.com/wiki/DbPoll

Share this post


Link to post

Спасибо большое, Kenix, буду пробовать. Как раз хотел вытащить этот ИД, но не знал как грамотно

Share this post


Link to post
При добавлении в базу аккаунта можно получить его ид используя функцию dbPoll

Вот тут по-подробней. Сделал так:

local accConnect = dbConnect("sqlite", ":/internal.db") 
local accQuery = dbQuery(accConnect, "SELECT * FROM accounts") 
local accResult, accRows, accID = dbPoll(accQuery, -1) 
destroyElement(accConnect) 

Дебаг пишет: "Нет такой таблицы: accounts". Что не так?

Share this post


Link to post
Создать таблицу accounts в БД?

База internal.db - это стандартная база с аккаунтами и аккаунт-датой. Она создаётся при первом запуске сервера автоматически. Таблица "accounts" соответственно также создаётся автоматом.

Share this post


Link to post

Моя глупость. Короче, к internal.db не подключиться, ибо dbConnect не знает коренной папки.

Можно только после регистрации записывать игрока в отдельную базу и через dbPoll получать ИД. А в случае смены ника менять его и в базе.

Кстати, кто подскажет, как из стандартной базы через executeSQLQuery получить если не последний, то хотя бы максимальный ИД?

Edited by Guest

Share this post


Link to post
ибо dbQuery не знает коренной папки.

А зачем этой функции знать корневую папку? Она с файлами ведь не работает.

В dbConnect предусмотрена возможность подключения к sqlite базам либо которые находятся в ресурсах, либо в главной папке с базами (mods\deathmatch\databases). Internal.db находится в mods\deathmatch и к нему поэтому нельзя подключиться. Если есть доступ к терминалу машины (например по SSH или telnet), то можешь создать символическую ссылку, но стабильную работу не гарантирую.

Edited by Guest

Share this post


Link to post

Хотел сделать авто логин чет я запутался помогите пожалуйста.

Клиентская часть

  
resourceRoot = getResourceRootElement(getThisResource()) 
  
function loginPanel() 
    showCursor(true,false) 
    login = guiCreateButton ( 0.21, 0.81, 0.56, 0.12, "Вход", true ) 
    addEventHandler ( "onClientGUIClick", login, function ( ) 
        triggerServerEvent ( "onClientSendLoginDataToServer", getLocalPlayer() ) 
    end, false ) 
end 
  
function finishlogin() 
  showCursor(false) 
end 
addEvent("onPlayerDoneLogin", true) 
addEventHandler("onPlayerDoneLogin", getRootElement(), finishlogin) 
  
addEventHandler("onClientResourceStart", resourceRoot,  
    function () 
        loginPanel() 
        guiSetInputMode("no_binds_when_editing") 
        fadeCamera (true)  
        setCameraMatrix(2658.2626953125, 2728.0246582031, 10.541299819946, 2659.0986328125, 2728.851484375, 10.774273872375) 
    end 
) 
  

Серверная часть

  
local root = getRootElement() 
  
function autoLogin ( playersource ) 
    cSerial = getPlayerSerial ( playersource ) 
    pass = sha256 ( cSerial ) 
    account = getAccount ( tostring ( cSerial ), pass ) or false 
    if not account then 
        account = addAccount ( tostring ( cSerial ), pass ) 
    end 
    logIn ( playersource, account, pass ) 
end 
addEvent ( "onClientSendLoginDataToServer", true ) 
addEventHandler ( "onClientSendLoginDataToServer", root, autoLogin) 
  
addEventHandler("onPlayerJoin", getRootElement(), function() 
    fadeCamera(source, true) 
    setCameraMatrix(source, 2658.2626953125, 2728.0246582031, 10.541299819946, 2659.0986328125, 2728.851484375, 10.774273872375) 
end 
) 
  

  
function onPlayerAutoLogin ( playersource ) 
    spawnPlayer ( playersource, 0, 0, 0, math.random ( 0, 360 ), 0, 0, 0 ) 
    fadeCamera ( playersource, true ) 
end 
addEvent("onPlayerAutoLogin", true) 
addEventHandler("onPlayerAutoLogin", getRootElement(), onPlayerAutoLogin) 
  

Скрипт не пашет. Help me

Edited by Guest

Share this post


Link to post

Такая дыра в безопасности...

Такая система аналогична тому, что я знаю все твои логины и пароли и могу войти на серв с админскими правами.

Share this post


Link to post
Хотел сделать авто логин чет я запутался помогите пожалуйста.

Клиентская часть

  
resourceRoot = getResourceRootElement(getThisResource()) 
  
function loginPanel() 
    showCursor(true,false) 
    login = guiCreateButton ( 0.21, 0.81, 0.56, 0.12, "Вход", true ) 
    addEventHandler ( "onClientGUIClick", login, function ( ) 
        triggerServerEvent ( "onClientSendLoginDataToServer", getLocalPlayer() ) 
    end, false ) 
end 
  
function finishlogin() 
  showCursor(false) 
end 
addEvent("onPlayerDoneLogin", true) 
addEventHandler("onPlayerDoneLogin", getRootElement(), finishlogin) 
  
addEventHandler("onClientResourceStart", resourceRoot,  
    function () 
        loginPanel() 
        guiSetInputMode("no_binds_when_editing") 
        fadeCamera (true)  
        setCameraMatrix(2658.2626953125, 2728.0246582031, 10.541299819946, 2659.0986328125, 2728.851484375, 10.774273872375) 
    end 
) 
  

Серверная часть

  
local root = getRootElement() 
  
function autoLogin ( playersource ) 
    cSerial = getPlayerSerial ( playersource ) 
    pass = sha256 ( cSerial ) 
    account = getAccount ( tostring ( cSerial ), pass ) or false 
    if not account then 
        account = addAccount ( tostring ( cSerial ), pass ) 
    end 
    logIn ( playersource, account, pass ) 
end 
addEvent ( "onClientSendLoginDataToServer", true ) 
addEventHandler ( "onClientSendLoginDataToServer", root, autoLogin) 
  
addEventHandler("onPlayerJoin", getRootElement(), function() 
    fadeCamera(source, true) 
    setCameraMatrix(source, 2658.2626953125, 2728.0246582031, 10.541299819946, 2659.0986328125, 2728.851484375, 10.774273872375) 
end 
) 
  

  
function onPlayerAutoLogin ( playersource ) 
    spawnPlayer ( playersource, 0, 0, 0, math.random ( 0, 360 ), 0, 0, 0 ) 
    fadeCamera ( playersource, true ) 
end 
addEvent("onPlayerAutoLogin", true) 
addEventHandler("onPlayerAutoLogin", getRootElement(), onPlayerAutoLogin) 
  

Скрипт не пашет. Help me

Помогите пожалуйста я еще новичок, хотел сделать авто логин скрипт, заранее благодарен

Share this post


Link to post

У меня такой вопрос как можно сделать управляемую ракету как на гидре. Есть ли такой обьект?

Share this post


Link to post

Есть один интересный вопрос, который отделяет меня от реализации очень интересного проекта, прошу помощи.

Предположим есть client only функция, а именно setVehicleComponentVisible.

Соответственно когда я скрываю компонент это видно только мне. Могу я сделать так чтобы все игроки видели что я скрыл этот компонент?

Share this post


Link to post
triggerClientEvent 

Отправляешь всем игрокам информацию и применяешь setVehicleComponentVisible.

Share this post


Link to post
triggerClientEvent 

Отправляешь всем игрокам информацию и применяешь setVehicleComponentVisible.

вообще не понимаю что куда отправлять..

как то так?

function camStart(theVehicle, seat) 
                local vModel = getElementModel(theVehicle) 
                if (vModel ==  421 ) then 
addCommandHandler("hide", 
    function() 
        local theVeh = getPedOccupiedVehicle(localPlayer) 
    local getComponent = getVehicleComponents(theVeh)  
        if (theVeh) then 
            for k in pairs (getComponent) do 
            local isVisible = getVehicleComponentVisible(theVeh, "bump_front_dummy") 
        if (isVisible == true) then 
                setVehicleComponentVisible(theVeh, "bump_front_dummy", false)  
        end    
            end 
        end 
    end 
) 
addCommandHandler("show", 
    function() 
        local theVeh = getPedOccupiedVehicle(localPlayer) 
    local getComponent = getVehicleComponents(theVeh)  
        if (theVeh) then 
            for k in pairs (getComponent) do 
            local isVisible = getVehicleComponentVisible(theVeh, "bump_front_dummy") 
        if (isVisible == false) then 
                setVehicleComponentVisible(theVeh, "bump_front_dummy", true)  
        end    
            end 
        end 
    end 
) 
end 
end 
addEventHandler("onClientPlayerVehicleEnter", getLocalPlayer(), camStart) 
  
function camStop(theVehicle, seat) 
removeCommandHandler( "show" ) 
removeCommandHandler( "hide" ) 
end 
addEventHandler("onClientPlayerVehicleExit", getLocalPlayer(), camStop) 
addEventHandler("onClientVehicleExplode", getRootElement(), camStop ) 
  
addEventHandler("onClientElementDestroy", getRootElement(), function () 
    if getElementType(source) == "vehicle" and getPedOccupiedVehicle(getLocalPlayer()) == source then 
removeCommandHandler( "show" ) 
removeCommandHandler( "hide" ) 
    end 
end) 
  
addEvent( "onGreeting", true ) 
addEventHandler( "onGreeting", localPlayer, camStart ) 

function greetingCommand ( playerSource ) 
    triggerClientEvent ( playerSource, "onGreeting", playerSource ) 
end 

Share this post


Link to post

Беда у вас, а не код... Я думаю, theKenix имел ввиду что-то подобное:

Server:

  
addCommandHandler("hide", function ( thePlayer ) 
     if isPedInVehicle ( thePlayer ) then 
          local veh = getPedOccupiedVehicle ( thePlayer ) 
          for i, player in ipairs ( getElementsByType("player") ) do 
               triggerClientEvent ( player, "hideComp", player, veh ) 
          end 
     end 
end ) 

Client:

addEvent( "hideComp", true ) 
addEventHandler( "hideComp", localPlayer, function ( theVeh ) 
        local isVisible = getVehicleComponentVisible(theVeh, "bump_front_dummy") 
        if (isVisible == true) then 
                setVehicleComponentVisible(theVeh, "bump_front_dummy", false) 
        end   
end ) 

Share this post


Link to post

Зачем в цикле обрабатывать всех игроков и для каждого посылать пакет?

Вызывайте событие для root.

Share this post


Link to post

Как получить таблицу находясь в ней? т.е. я хочу чтобы

local Table = { name = 'test', level = 1, maxcount = 1000 + 1000 * Table.level } 

вместо Table.level использовать не константу, а переменную (типа self.level). Простите, что так изъясняюсь, но лучше формулировке не придумал

Share this post


Link to post

У вас maxcount имеет тип переменной число, это значит что и хранит оно только число, а не то как оно вычисляется, и пока вы не присвоите новое значение, оно не изменится.

Вашу задачу, можно выполнять через мета-таблицы.

Или же просто делая maxcount функцией, и вызывая как Table:maxcount().

А вот '' self '', как раз и передается посредством '' : ''. Т.е. Table:maxcount() = Table.maxcount(Table) .

Это описывается в большинстве мануалов Lua.

Share this post


Link to post

Собственно вопрос. Необходимо узнать макс. скорость авто при езде скриптово(не из таблицы), это возможно сделать как то? Вопрос стоит в том, чтобы знать ее макс. скорость и текущую. С текущей понятно, но с макс. как?

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.