Jump to content

loadstring and wrappers


Bonsai

Recommended Posts

Posted

Hey Peeps,

I did a lot of research before, but I didn't find any good answer to my question.

When I'm loading a script file by loadstring, where do I put my wrapper functions?

It obviously does not work to just have them in the same resource.

Do I have to edit the loaded script string before executing?

Bonsai

  • Replies 57
  • Created
  • Last Reply

Top Posters In This Topic

Posted

i just created another resource which handles that. The code looks like:

  
local objects = { } 
local _createObject = createObject -- save the original function 
  
function createObject(id,x,y,z,rx,ry,rz,islod) -- replace the original one 
  if not id or not x or not y or not z then 
    return false 
  end 
  local rx = rx or 0 
  local ry = ry or 0 
  local rz = rz or 0 
  local object = _createObject(id,x,y,z,rx,ry,rz,islod) -- use the old function 
  if object then 
    table.insert(objects,object) 
    return object -- Don't forget to return the info of the original one 
  end 
end 
  
function loadCode(content) 
  local loaded = loadstring(content) 
  local ex = pcall(loaded) 
  if ex then outputChatBox("loaded the code") end 
end 
  
function unloadCode() 
  for i,v in ipairs(objects) do 
    if isElement(v) then 
      destroyElement(v) 
    end 
  end 
end 

Posted

Okay, I tested yours and it works...

My code did pretty much look like that, don't know why it wasn't working.

Anyway, now I can finally get started. Thank you.

Posted

Something is not working well with this way of loading code.

I get an error if my script looks e.g. like:

grav1 = createMarker ( 5595.1923828125, -1091.1322021484, 91.135231018066 , "corona" , 7, 0, 0, 0, 0) 
addEventHandler( "onClientMarkerHit", grav1, markerHit2) 

It says element attached to Handler is nil...

EDIT: Nevermind, I've found the problem. Thanks anyway.

Posted
setfenv doesn't seem to work with MTA, does it?

It didn't work for me. Don't know if I did it right.

Is there a way to get rid of variables without restarting the resource?

Bonsai

Posted

I use _EVN changes and that seems to work though. The only thing I have to do is to move _G stuff into the environment table. Seems to help. Then just empty the environment and it should be fine. At least that's how it works at my server.

Posted
setfenv doesn't seem to work with MTA, does it?

setfenv should work just fine.

setfenv doesn't seem to work with MTA, does it?

It didn't work for me. Don't know if I did it right.

Is there a way to get rid of variables without restarting the resource?

Bonsai

If you use separate environments, just clear it (or delete it completely) - it's all just a table.

Posted
local env = {} 
  
local func = loadstring(data) 
setfenv(func, env) 
pcall(func) 
  

It tells me "bad argument #1 to setfenv (number expected, got nil)"

Posted
local env = {} 
  
local func = loadstring(data) 
setfenv(func, env) 
pcall(func) 
  

It tells me "bad argument #1 to setfenv (number expected, got nil)"

I'm unable to reproduce this. Are you sure the string passed to loadstring is valid code and that the function is returning the correct result? Also, is this code being executed on the client or server?

This is the code I used on the server side:

local env = {} 
env.outputServerLog = outputServerLog 
  
local func = loadstring ( "outputServerLog ( \"hey\" )" ) 
local _func = loadstring ( "var = 1" ) 
  
outputServerLog ( tostring ( func ) ) 
outputServerLog ( tostring ( _func ) ) 
  
setfenv ( func, env ) 
setfenv ( _func, env ) 
  
outputServerLog ( tostring ( pcall ( func ) ) ) 
outputServerLog ( tostring ( pcall ( _func ) ) ) 
outputServerLog ( "var: " .. env.var ) 

Output:

function: 01C06C78 
function: 01C06CB8 
hey 
true 
true 
var: 1 

Posted

Confirmed, it works. I had a problem of moving functions into the new env table:

-- DOESN'T WORK 
for i,v in ipairs(_G) do 
  if not (v == "cacheFiles" or v == "loadData" or v == "unloadAll") then 
    --table.insert(RUNCODE,v) -- Neither this 
    RUNCODE[#RUNCODE+1] = v -- Nor that 
 end 
end 

-- WORKS 
setmetatable(RUNCODE,{__index = _G}) 

Posted
Confirmed, it works. I had a problem of moving functions into the new env table:
-- DOESN'T WORK 
for i,v in ipairs(_G) do 
  if not (v == "cacheFiles" or v == "loadData" or v == "unloadAll") then 
    --table.insert(RUNCODE,v) -- Neither this 
    RUNCODE[#RUNCODE+1] = v -- Nor that 
 end 
end 

-- WORKS 
setmetatable(RUNCODE,{__index = _G}) 

viewtopic.php?f=91&t=69031#p644203 Read from there on.

And,

for k,v in pairs ( _G ) do 
    if ( not ( k == "cacheFiles" or k == "loadData" or k == "unloadAll" or k == "_G" ) ) then 
        RUNCODE[k] = v 
    end 
end 

Posted

This seems to be the hardest part when making wrappers.

Its easy to destroy created elements or set back world functions to normal, but getting rid of set variables is complicated.

Easiest way seems to be just to restart the wrapper resource, but it turned out restart takes too long so its not up again when server side scripts ask for execution.

PS: When I want to remove an EventHandler, but the attached Element doesn't exist anymore at that time, could I just use root? Or isn't it necesssary to remove that handler at all?

Posted
Unfortunately, the way of copying _G causes problems for some scripts. I'd stick to metatables with index.

Can you enumerate them?

This seems to be the hardest part when making wrappers.

Its easy to destroy created elements or set back world functions to normal, but getting rid of set variables is complicated.

It's as simple as clearing a table, what's your problem?

PS: When I want to remove an EventHandler, but the attached Element doesn't exist anymore at that time, could I just use root? Or isn't it necesssary to remove that handler at all?

Event handlers are removed automatically when the element is deleted.

Posted
Event handlers are removed automatically when the element is deleted.

Okay, thanks for that.

It's as simple as clearing a table, what's your problem?

I'm loading a complete script by loadstring. Everything works fine. Wrapper do their job etc.

But when I put setfenv on my loadstring it outputs an error.

"bad argument #1 to setfenv (number expected, got nil)"

Simple functions like in your example work fine. But a script does not.

Posted
Mind showing your loader code?
function loadScript(file, dim) 
  
dimension = dim 
local file = fileOpen(file) 
local content = fileRead(file, fileGetSize(file)) 
local loaded = loadstring(content) 
pcall(loaded) 
  
end 
_addEventHandler("onLoadScript", root, loadScript) 

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...