Get an object from a string

Okay, this is a weird use case, but

Users will pass a string as a reference to a part (for example, "workspace.Baseplate"). What’s the best way to take that reference to an object and get the object its referencing?

I would reccomend using the string.split() function using “.” as the separator. Then, use this hierarchy table to run FindFirstChild on each parent, starting with game, then “workspace”, then “baseplate”, and so on.

I was originally going to do that, but how would I only repeat FindFirstChild as many times as I need?

A method such as this would work:

local err, returnVal = pcall(function() 
	return loadstring("return workspace.Baseplate")()	
end)

-- ReturnVal will be Baseplate
returnVal.Material = Enum.Material.Grass

You can pcall it by using loadstring, returning what loadstring gives you but you’d also want to add a “return” in front of the normal string inside loadstring. This would require you to enable loadstring which is enabled on ServerScriptService settings:
test

Thats something else I considered, however there are two main reasons I don’t want to.

  1. (biggest) This will run in peoples games, so I don’t want them to have to enable loadstring
  2. I image theres a more efficient way

I don’t see the issue with it, loadstring can only be used on the server and you can sandbox loadstring.

You can actually sandbox loadstring very easily, here is an example:

local LoadStringRef = loadstring("code_here")
setfenv(LoadStringRef, new_env)
LoadStringRef()

Adding on to this, you can disable the feature if they don’t enable loadstring and it wouldn’t have negative effects if you sandbox it correctly. From what I know this will be the best method if you wish to not have a weird solution to solving this with string manipulation and etc.

You can use a for loop to accomplish it. I would reccomend against using loadstrings for this, as your game can be vulnerable to lua injections.

You use a recursive function.

local splitString = {“split”,”string”}
local function getDescendant(parent, descendant,pos)
  if not parent then return end
  I = i or 1
  return getDescendant(parent:FindFirstChild(“descendant”),splitString[i], i + 1)
end

getDescendant(game.Workspace, splitString)
4 Likes

No it wouldn’t, loadstring is server-sided and you can sandbox it, it would not make the game vulnerable in any circumstance if it is sandboxed correctly.

@grilme99 is looking for an efficient way, loadstring will be the most efficient solution currently and safest as it’s easiest to sandbox (stop bad code from running).

Yeah I get that you can sandbox loadstring, but that fact that this is going to be used in a massive variety of games, I don’t want to have everyone need to enable a feature that is disabled for security reasons.

Either way you’d want to sandbox user inputted code (assuming that this is for user inputted code), so any other method would just be much harder to implement and sandbox. If you’re looking for the most efficient solution then loadstring will be your best option.

If you don’t plan to use loadstring then what other methods are you looking for?

I’ll say it again. I plan on lots of games using this. I don’t want them all having to enable extra features for such a small thing.

I am going to use @tlr22’s suggestion, most likely.

I won’t lecture you on how it should be made, but with long lines of code that recursive function will end up not being efficient at all.

In all honesty, clever’s method is more efficient if you are talking about efficiency. This is a lot easier to use, and saves a lot of stress. LoadStrings as Clever mentioned, can’t be loaded client-side.

1 Like

I don’t really understand how it is more efficient and secure than just using @tlr22’s method. Can you please explain? Obviously it can’t be used client side, but it puts games at more of a risk of backdoors executing code.

I mean your code can already execute code so it wouldn’t matter. I don’t want to keep repeating myself but like I said if you sandbox it then it’s perfectly secure, I can even provide an entire sandbox that from my knowledge can’t be “escaped”.

Also efficiency wise; loadstring() is meant to execute lua code, making a recursive function that is meant to read code and “execute it” will eventually become inefficient when you attempt to execute massive lines of code.

I don’t think there is anything else to clarify on the topic as you’ve already chosen a solution and I’ve already outlined all the “pros & cons” of using loadstring() vs a recursive function.

3 Likes

I’m guessing you’re referring to my project the Marketplace which I made posts about before. We don’t simply “execute code”. We turn code into obfuscated bytecode which is then ran by a custom interpreter. We never use the built in loadstring.

Using a recursive method is far more efficient than using bandwidth (which I am cheated for) to send that bytecode to the game.

The recursive also doesn’t read and handle code, it just takes in the path of an object (game.Workspace.Part, for example).

Try using recursive method for like 200 lines of code, the server will instantly crash, with loadstrings however, this isn’t an issue.

Why would I use recursive for 200 lines of code?