Jump to content

load function from file


Overkillz

Recommended Posts

Hello dear community, Im here with a problem which is annoying me a lot. Well, Im using fileOpen, fileRead ...etc to save a file in cache folder. Well, I decided to save script files in cache and try to load them with a custom script loader, however, I couldn't do it. Im not sure what am I doing wrong. I started to do it with a simple script, however, I don't know what is wrong with the code. When I run it I get the game freeze and I need to task manager and force to close MTA

Here is the code. Thanks for reading

local filePath = ":theScript/temporalCache/mapTest/water.lua"

function scriptReadaa()
	local file = fileOpen(filePath)
	if not file then error("Error opening File.") return end
	local data
	data = fileRead(file, fileGetSize(file))
	iprint(data)
	fileClose(file)
	loadScript(data)
end
addCommandHandler("doit",scriptReadaa)

function loadScript(scriptData)
	local simpleContador = 0
	local Xfunction = load(function()
		simpleContador = simpleContador + 1
		return scriptData
	end)
	if Xfunction then
		pCallPrev = Xfunction
		pcall(pCallPrev)
	else
		outputDebugString("Couldn't load the script")
		return
	end
	triggerEvent("onClientResourceStart", resourceRoot, getResourceFromName("SHIscriptloader"))
end

--##water.lua containts the following function
function startclient()
	setWaterColor(0, 0, 255)
end
addEventHandler("onClientResourceStart", resourceRoot, startclient)

 

Edited by Overkillz
Link to comment
13 minutes ago, LopSided_ said:

Why don't you use exported functions instead? https://wiki.multitheftauto.com/wiki/Call

Quote

Call: This function is used to call a function from another resource (which must be running).

I think I can't use it. The resource must be running and I haven't the resource running which contain that file. What does it mean? The file that I mentioned before isn't even on meta's resource

Regards.

 

Link to comment
  • Moderators

There was something strange about the <load> function. Afaik it didn't work for me because of some sort of security(MTA) problem.

But that was a while ago, so it might be changed over time.

 

Well, try first figure out where you crash starts. Probably line: 16 or 22 (Your default code)

Run this. Write /doit and after that /testNext until your MTA starts to crash.

 

local filePath = ":theScript/temporalCache/mapTest/water.lua"

function hold (reason)
	iprint("Code pauses, reason:", reason)
	coroutine.yield()
end

local coroutineOfscriptReadaa

function scriptReadaa()
  	hold("Called function scriptReadaa")
	local file = fileOpen(filePath)
	if not file then error("Error opening File.") return end
  	hold("File file is open")
	local data
	data = fileRead(file, fileGetSize(file))
	hold("I did read the file")
	fileClose(file)
	hold("I did close the file")
	loadScript(data)
  	hold("Everything seems to be OK")
end

addCommandHandler("doit",
function ()
    if not coroutineOfscriptReadaa then
		hold("Lets get started. I am your slave. Write: /testNext To go to the next step(s).")
		coroutineOfscriptReadaa = coroutine.create(scriptReadaa)
		coroutine.resume(coroutineOfscriptReadaa)
   	end
end)


addCommandHandler("testNext",
function ()
    if coroutineOfscriptReadaa then
		local state, error = coroutine.resume(coroutineOfscriptReadaa)
		if not state then
			iprint("coroutine ended. You can use /doit again.")
			coroutineOfscriptReadaa = nil
		end
    end
end)



function loadScript(scriptData)
  	hold("Called the loadScript function")
	local simpleContador = 0
	local Xfunction = load(function()
		simpleContador = simpleContador + 1
		return scriptData
	end)
  	hold("Called the load function.")
	if Xfunction then
    	hold("Xfunction does exist.")
		pCallPrev = Xfunction
		pcall(pCallPrev)
    	hold("Called the pcall function")
	else
		outputDebugString("Couldn't load the script")
		return
	end
  	
	triggerEvent("onClientResourceStart", resourceRoot, getResourceFromName("SHIscriptloader"))
  	hold("triggerEvent onClientResourceStart has been called.")
end

--##water.lua containts the following function
function startclient()
	setWaterColor(0, 0, 255)
end
addEventHandler("onClientResourceStart", resourceRoot, startclient)

 

This example gives also answer on your question here:

 

Edited by IIYAMA
  • Like 1
Link to comment
On 30/9/2017 at 22:06, IIYAMA said:

There was something strange about the <load> function. Afaik it didn't work for me because of some sort of security(MTA) problem.

But that was a while ago, so it might be changed over time.

 

Well, try first figure out where you crash starts. Probably line: 16 or 22 (Your default code)

Run this. Write /doit and after that /testNext until your MTA starts to crash.

 


local filePath = ":theScript/temporalCache/mapTest/water.lua"

function hold (reason)
	iprint("Code pauses, reason:", reason)
	coroutine.yield()
end

local coroutineOfscriptReadaa

function scriptReadaa()
  	hold("Called function scriptReadaa")
	local file = fileOpen(filePath)
	if not file then error("Error opening File.") return end
  	hold("File file is open")
	local data
	data = fileRead(file, fileGetSize(file))
	hold("I did read the file")
	fileClose(file)
	hold("I did close the file")
	loadScript(data)
  	hold("Everything seems to be OK")
end

addCommandHandler("doit",
function ()
    if not coroutineOfscriptReadaa then
		hold("Lets get started. I am your slave. Write: /testNext To go to the next step(s).")
		coroutineOfscriptReadaa = coroutine.create(scriptReadaa)
		coroutine.resume(coroutineOfscriptReadaa)
   	end
end)


addCommandHandler("testNext",
function ()
    if coroutineOfscriptReadaa then
		local state, error = coroutine.resume(coroutineOfscriptReadaa)
		if not state then
			iprint("coroutine ended. You can use /doit again.")
			coroutineOfscriptReadaa = nil
		end
    end
end)



function loadScript(scriptData)
  	hold("Called the loadScript function")
	local simpleContador = 0
	local Xfunction = load(function()
		simpleContador = simpleContador + 1
		return scriptData
	end)
  	hold("Called the load function.")
	if Xfunction then
    	hold("Xfunction does exist.")
		pCallPrev = Xfunction
		pcall(pCallPrev)
    	hold("Called the pcall function")
	else
		outputDebugString("Couldn't load the script")
		return
	end
  	
	triggerEvent("onClientResourceStart", resourceRoot, getResourceFromName("SHIscriptloader"))
  	hold("triggerEvent onClientResourceStart has been called.")
end

--##water.lua containts the following function
function startclient()
	setWaterColor(0, 0, 255)
end
addEventHandler("onClientResourceStart", resourceRoot, startclient)

 

This example gives also answer on your question here:

 

First of all, thanks for bringing me a code which will help me alot in a near future. Well, respecting the code, I tried to test your coroutine function (I have never heard about this function before). Sadly. There is something wrong there.

Here you have an screenshot about the problem

d87d5d3c1b.png

Thanks for reading. Best regards.

 

Link to comment
  • Moderators

    local filePath = ":theScript/temporalCache/mapTest/water.lua"

    function hold (reason)
    	iprint("Code pauses, reason:", reason)
    	coroutine.yield()
    end

    local coroutineOfscriptReadaa

    function scriptReadaa()
      	hold("Called function scriptReadaa")
    	local file = fileOpen(filePath)
    	if not file then error("Error opening File.") return end
      	hold("File file is open")
    	local data
    	data = fileRead(file, fileGetSize(file))
    	hold("I did read the file")
    	fileClose(file)
    	hold("I did close the file")
    	loadScript(data)
      	hold("Everything seems to be OK")
    end

    addCommandHandler("doit",
    function ()
        if not coroutineOfscriptReadaa then
    		coroutineOfscriptReadaa = coroutine.create(scriptReadaa)
    		coroutine.resume(coroutineOfscriptReadaa)
       	end
    end)


    addCommandHandler("testNext",
    function ()
        if coroutineOfscriptReadaa then
    		local state, error = coroutine.resume(coroutineOfscriptReadaa)
    		if not state then
    			iprint("coroutine ended. You can use /doit again.")
    			coroutineOfscriptReadaa = nil
    		end
        end
    end)



    function loadScript(scriptData)
      	hold("Called the loadScript function")
    	local simpleContador = 0
    	local Xfunction = load(function()
    		simpleContador = simpleContador + 1
    		return scriptData
    	end)
      	hold("Called the load function.")
    	if Xfunction then
        	hold("Xfunction does exist.")
    		pCallPrev = Xfunction
    		pcall(pCallPrev)
        	hold("Called the pcall function")
    	else
    		outputDebugString("Couldn't load the script")
    		return
    	end
      	
    	triggerEvent("onClientResourceStart", resourceRoot, getResourceFromName("SHIscriptloader"))
      	hold("triggerEvent onClientResourceStart has been called.")
    end

    --##water.lua containts the following function
    function startclient()
    	setWaterColor(0, 0, 255)
    end
    addEventHandler("onClientResourceStart", resourceRoot, startclient)

Edited. (found the problem)

 

I tested it. (you should test it too)

It seems to be the load function. Nor sure why or what.

 


I too recommend you:

 

+  environment set: https://www.lua.org/manual/5.1/manual.html#pdf-setfenv

 

Edited by IIYAMA
Link to comment

Well, I couldn't be online to test the fix that you gave me. I implement it to the code and now looks like it works pretty fine. However, I needed to change the load function to loadstring and u suggested me before. Sadly, It doesn't execute the function. Here you can see the result of it (I added iprint to the loadScript to let you see water.lua | The water colour should be blue)

function loadScript(scriptData)
	iprint(scriptData)
    hold("Called the loadScript function")
	local loaded = loadstring(tostring(scriptData))
	local ex = pcall(loaded) 
	hold("Called the load function.")
	if ex then outputChatBox("loaded the code") end 
end

ef554a3aa3.jpg

Thanks for helping me. Best regards.

Edited by Overkillz
Link to comment
  • Moderators

Put a debug or outputChatBox function on top of the code you are loading, just to be sure.(onClientResource start event doesn't trigger once loaded, only for other resources)

If that doesn't work, debug results of the pcall function:

local status, err = pcall(loaded)
iprint("status:",status,"error:",err)

 

And don't be afraid to call the function manually:

loaded()

 

  • Like 1
Link to comment

Thanks, I could fix it with the idea that u gave me. Otherwise, is there some problem with load and loadstring to not to laod copile scripts ? I have uploaded a map on my server which has copiled scripts and when I use load or loadstring functions it doesn't load the scripts.

Edited by Overkillz
  • Haha 1
Link to comment
  • Moderators

You can run them normally. There is no other option.

Compiled scripts require a decompiler (and a MTA decrypter) to read the file.

 

LUA scripting been implemented at a level which is limited by a the security system which does not allow to access this.

Please give up on trying to load MTA compiled scripts with LUA. (absolutely not going to working)

 

 

  • Like 1
Link to comment

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.
×
×
  • Create New...