Крашит игра из-за lua.

alarm0

Участник
Автор темы
44
3
Версия MoonLoader
.026-beta
У меня крашит игра, из-за моего крутого-мега скрипта...
Очень большие подозрения на эти две функции. Нужно экспертное мнение, на сколько это норм и не клоун ли я?
Функция accept вызывается, если выполняется условие в хуке OnServerMessage.
Крашит в lua51.dll. Изучив форумы узнал, что скорее всего из-за попытки обновить информацию в массивах...

Стек вызовов:
lua_rawgeti 0x570777D6
luaL_unref 0x570B9325
Unknown 0x5722A935
Unknown 0x57140957
Unknown 0x57119D99
Unknown 0x5707280D
?unregisterConsoleCommand@SAMPFUNCS@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z 0x57E5A497
Unknown 0x57DC225E C:\GTA\GTA BY SR Admins\SAMPFUNCS.asi
?unregisterConsoleCommand@SAMPFUNCS@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z 0x57E525CD
luaJIT_profile_stop 0x570B1952
Unknown 0x57072BB4
luaJIT_version_2_1_0_beta3 0x5709C21F
lua_close 0x570B1B2A
Unknown 0x57206959
RtlAllocateHeap 0x776E5DFE

Две функции:
function isKeysDown(keylist)
    local counter = #keylist
    local counterPressed = 0
    local success = false
    local timeout = false
 
    local timeoutThread = lua_thread.create(function()
        wait(20000)
        timeout = true
    end)

    while true do
        wait(0)
        if timeout then
            return false
        end

        counterPressed = 0
        for _, key in ipairs(keylist) do
            if isKeyDown(key) and not sampIsCursorActive() then
                counterPressed = counterPressed + 1
            end
        end

        if counterPressed == counter then
            success = true
            return true
        end
    end
end



function accept(nickname, typeHelp, vehicle)
    local success = false

    lua_thread.create(function()
        wait(10)
        local messageMap = {
            good = "приятной игры.",
            giveCar = "выдать т.с.",
            repair = "ремонт т.с.",
            flip = "перевернуть т.с.",
            fill = "заправить т.с.",
            hello = "приветствие.",
            sp = "слежка.",
        }

        local messageType = messageMap[typeHelp]
        if not messageType then
            return
        end

        local keyName = getNamesOfKeys(cfgHotkeys.v)
        local helpMessage = "{c9b0ff}Auto-Report {ffffff}¤ Нажмите {b8ff94}'" .. tostring(keyName) .. "'{ffffff}, для того чтобы принять {ff8c00}репорт{ffffff}. Тип помощи: {94f3ff}" .. messageType
        sampAddChatMessage(helpMessage, -1)

        while not success do
            wait(0)
            if isKeysDown(cfgHotkeys.v) then
                if typeHelp == "good" or typeHelp == "hello" then
                    shortAnswer(nickname, "good")
                elseif typeHelp == "giveCar" then
                    if vehicle == 510 or vehicle == 462 then
                        giveVehicle(nickname, vehicle)
                    end
                elseif typeHelp == "sp" then
                    giveEmergencyHelp(nickname, typeHelp)
                else
                    giveEmergencyHelp(nickname, typeHelp)
                end
                success = true
            else
                sampAddChatMessage("{c9b0ff}Auto-Report {ffffff}¤ Запрошенная помощь для {b8ff94}" .. nickname .. "{ffffff} была отменена.", -1)
                success = true
            end
        end
    end)
end

Фрагмент кода из хука:
    if settings.enabled and not settings.isPaused and not settings.spectating and text:find("/arep") and color == -11599617 then
        local nickname = getNickname(text)
        if nickname and sampIsPlayerConnected(sampGetPlayerIdByNickname(nickname)) and nickname ~= sampGetPlayerNickname(select(2, sampGetPlayerIdByCharHandle(playerPed))) then
            for _, keyword in ipairs(goodKeywords) do
                if string.find(string.nlower(text), keyword) then
                    if cfg.FLAGS.buttonUse then
                        accept(nickname, "good")                     
                        return
                    elseif not isBlacklisted(nickname) then
                        blacklistOneMinute(nickname)
                        shortAnswer(nickname, "good")
                        return
                    end
                end
            end
        end
    end
 
Последнее редактирование:

RedHolms

Известный
Проверенный
620
367
На своём опыте понял, потоки в мунлоадере работают через 3 очка.
Я взял на вооружение принцип - не создавать ни одного потока на рантайме, только при запуске скрипта.
Вот абстрактный пример подобного кода:
Lua:
   lua_thread.create(function()
      local update_stage_next_frame = false
      while true do
         if train_drugs then
            sampSendChat("/usedrugs " .. tostring(get_max_narko()))
            if not update_stage and not update_stage_next_frame then
               update_stage_next_frame = true
            elseif not update_stage then
               update_stage_next_frame = false
               wait(500)
               sampSendChat("/stats")
               update_stage = true
               update_stage_expire = winmm.timeGetTime() + 3000
            elseif update_stage and winmm.timeGetTime() > update_stage_expire then
               printChatWarning("Не удалось обновить информацию о стаже наркомана!")
               update_stage = false
            end
         else
            update_stage_next_frame = false
         end
         wait(1000)
      end
   end)
  
   DynamicCommands["drugs_trainer.command"] = function(arg)
      if not train_drugs then
         train_drugs = true
         current_stage = 0
         printChat("Кач нарко включён")
      else
         train_drugs = false
         buy_drugs = false
         update_stage = false
         printChat("Кач нарко выключен")
      end
   end
 

mcc

Участник
36
5
На своём опыте понял, потоки в мунлоадере работают через 3 очка.
Я взял на вооружение принцип - не создавать ни одного потока на рантайме, только при запуске скрипта.
Вот абстрактный пример подобного кода:
Lua:
   lua_thread.create(function()
      local update_stage_next_frame = false
      while true do
         if train_drugs then
            sampSendChat("/usedrugs " .. tostring(get_max_narko()))
            if not update_stage and not update_stage_next_frame then
               update_stage_next_frame = true
            elseif not update_stage then
               update_stage_next_frame = false
               wait(500)
               sampSendChat("/stats")
               update_stage = true
               update_stage_expire = winmm.timeGetTime() + 3000
            elseif update_stage and winmm.timeGetTime() > update_stage_expire then
               printChatWarning("Не удалось обновить информацию о стаже наркомана!")
               update_stage = false
            end
         else
            update_stage_next_frame = false
         end
         wait(1000)
      end
   end)
 
   DynamicCommands["drugs_trainer.command"] = function(arg)
      if not train_drugs then
         train_drugs = true
         current_stage = 0
         printChat("Кач нарко включён")
      else
         train_drugs = false
         buy_drugs = false
         update_stage = false
         printChat("Кач нарко выключен")
      end
   end
А можешь дать свой дискорд я незнаю просто как и куда вставлять?
 

Sadow

Известный
1,428
593
У меня крашит игра, из-за моего крутого-мега скрипта...
Очень большие подозрения на эти две функции. Нужно экспертное мнение, на сколько это норм и не клоун ли я?
Функция accept вызывается, если выполняется условие в хуке OnServerMessage.
Крашит в lua51.dll. Изучив форумы узнал, что скорее всего из-за попытки обновить информацию в массивах...

Стек вызовов:
lua_rawgeti 0x570777D6
luaL_unref 0x570B9325
Unknown 0x5722A935
Unknown 0x57140957
Unknown 0x57119D99
Unknown 0x5707280D
?unregisterConsoleCommand@SAMPFUNCS@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z 0x57E5A497
Unknown 0x57DC225E C:\GTA\GTA BY SR Admins\SAMPFUNCS.asi
?unregisterConsoleCommand@SAMPFUNCS@@QAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z 0x57E525CD
luaJIT_profile_stop 0x570B1952
Unknown 0x57072BB4
luaJIT_version_2_1_0_beta3 0x5709C21F
lua_close 0x570B1B2A
Unknown 0x57206959
RtlAllocateHeap 0x776E5DFE

Две функции:
function isKeysDown(keylist)
    local counter = #keylist
    local counterPressed = 0
    local success = false
    local timeout = false
 
    local timeoutThread = lua_thread.create(function()
        wait(20000)
        timeout = true
    end)

    while true do
        wait(0)
        if timeout then
            return false
        end

        counterPressed = 0
        for _, key in ipairs(keylist) do
            if isKeyDown(key) and not sampIsCursorActive() then
                counterPressed = counterPressed + 1
            end
        end

        if counterPressed == counter then
            success = true
            return true
        end
    end
end



function accept(nickname, typeHelp, vehicle)
    local success = false

    lua_thread.create(function()
        wait(10)
        local messageMap = {
            good = "приятной игры.",
            giveCar = "выдать т.с.",
            repair = "ремонт т.с.",
            flip = "перевернуть т.с.",
            fill = "заправить т.с.",
            hello = "приветствие.",
            sp = "слежка.",
        }

        local messageType = messageMap[typeHelp]
        if not messageType then
            return
        end

        local keyName = getNamesOfKeys(cfgHotkeys.v)
        local helpMessage = "{c9b0ff}Auto-Report {ffffff}¤ Нажмите {b8ff94}'" .. tostring(keyName) .. "'{ffffff}, для того чтобы принять {ff8c00}репорт{ffffff}. Тип помощи: {94f3ff}" .. messageType
        sampAddChatMessage(helpMessage, -1)

        while not success do
            wait(0)
            if isKeysDown(cfgHotkeys.v) then
                if typeHelp == "good" or typeHelp == "hello" then
                    shortAnswer(nickname, "good")
                elseif typeHelp == "giveCar" then
                    if vehicle == 510 or vehicle == 462 then
                        giveVehicle(nickname, vehicle)
                    end
                elseif typeHelp == "sp" then
                    giveEmergencyHelp(nickname, typeHelp)
                else
                    giveEmergencyHelp(nickname, typeHelp)
                end
                success = true
            else
                sampAddChatMessage("{c9b0ff}Auto-Report {ffffff}¤ Запрошенная помощь для {b8ff94}" .. nickname .. "{ffffff} была отменена.", -1)
                success = true
            end
        end
    end)
end

Фрагмент кода из хука:
    if settings.enabled and not settings.isPaused and not settings.spectating and text:find("/arep") and color == -11599617 then
        local nickname = getNickname(text)
        if nickname and sampIsPlayerConnected(sampGetPlayerIdByNickname(nickname)) and nickname ~= sampGetPlayerNickname(select(2, sampGetPlayerIdByCharHandle(playerPed))) then
            for _, keyword in ipairs(goodKeywords) do
                if string.find(string.nlower(text), keyword) then
                    if cfg.FLAGS.buttonUse then
                        accept(nickname, "good")                    
                        return
                    elseif not isBlacklisted(nickname) then
                        blacklistOneMinute(nickname)
                        shortAnswer(nickname, "good")
                        return
                    end
                end
            end
        end
    end
в IsKeyDown ты вызываешь бесконечный цикл вне потока
 

alarm0

Участник
Автор темы
44
3
в IsKeyDown ты вызываешь бесконечный цикл вне потока
ты не прав, isKeyDown вызываеться в функции, в которой в свою очередь есть поток и без этого крашило бы моментально...

На своём опыте понял, потоки в мунлоадере работают через 3 очка.
Я взял на вооружение принцип - не создавать ни одного потока на рантайме, только при запуске скрипта.
Вот абстрактный пример подобного кода:
Lua:
   lua_thread.create(function()
      local update_stage_next_frame = false
      while true do
         if train_drugs then
            sampSendChat("/usedrugs " .. tostring(get_max_narko()))
            if not update_stage and not update_stage_next_frame then
               update_stage_next_frame = true
            elseif not update_stage then
               update_stage_next_frame = false
               wait(500)
               sampSendChat("/stats")
               update_stage = true
               update_stage_expire = winmm.timeGetTime() + 3000
            elseif update_stage and winmm.timeGetTime() > update_stage_expire then
               printChatWarning("Не удалось обновить информацию о стаже наркомана!")
               update_stage = false
            end
         else
            update_stage_next_frame = false
         end
         wait(1000)
      end
   end)
 
   DynamicCommands["drugs_trainer.command"] = function(arg)
      if not train_drugs then
         train_drugs = true
         current_stage = 0
         printChat("Кач нарко включён")
      else
         train_drugs = false
         buy_drugs = false
         update_stage = false
         printChat("Кач нарко выключен")
      end
   end
в целом я понимаю, что их использование нужно сводить к минимуму, ну в моих случаях я трудно себе представляю реализацию без них
 
  • Злость
Реакции: qdIbp