Do you mean server-sided executor, or just client-sided?
No itās already until my last comment, I use LuaVM and loadstring as testing, with LogService Message Out I can print the log service but itās like on video. Well but with GetLogHistory() i donāt know how, because I use @eaterofananas8 code but it doesnāt clone the textlabel, just look to my video thank you.
Why use GetLogHistory if you can connect the MessageOut event?
It always duplicateā¦ thatās why look my video.
It only duplicates in Studio
Oh only on studio? So if in-game itās not gonna duplicate?
Yes.
is there a way that studio also doesnāt duplicate?
It is a bug.
Why do you bind to LogService?
You should replace print
with another function that adds a line of text to the output GUI.
Iām not 100% sure how to do it and I canāt verify it, but your options are:
- Use
setfenv
to replace the loaded functionās environment with one that contains a differentprint
function; - Prepend code to the function that replaces
print
with something else before the userās code runs.
What??? How to do itā¦ hmm? I donāt know what do you mean.
So is this just a virtial script interface?
Both of these options are a billion trillion times simpler and more reliable than whatever you were doing above this.
Normally print()
will output a message to the log, which you can get with LogService.
I suggested replacing print
with something that outputs to the GUI directly instead of the log.
e.g.
function print(...)
local messages = {...}
-- convert each argument to string
for i, message in ipairs(messages) do
messages[i] = tostring(message)
end
-- show the result in a textlabel
local TextLabel = game.ReplicatedStorage.Output:Clone()
TextLabel.Text = table.concat(messages, "\t")
TextLabel.Parent = Player.PlayerGui.NC.Output.ScrollingFrame
end
The first option was to replace the environment of the function.
local env = {
print = print, -- the print function from above
Player = Player, -- the player that ran this code
game = game, -- you'll have to add a LOT of stuff here
}
local func = loadstring(YOUR_CODE_HERE)
setfenv(func, env)
func()
The second option was to add code that runs before your userās code.
This is a lot less reliable, though. In fact, itās very poor form, but still better than reading the console.
local preamble = [[
local Player = ]] .. Player:GetFullName() .. [[
function print(...)
local messages = {...}
-- convert each argument to string
for i, message in ipairs(messages) do
messages[i] = tostring(message)
end
-- show the result in a textlabel
local TextLabel = game.ReplicatedStorage.Output:Clone()
TextLabel.Text = table.concat(messages, "\t")
TextLabel.Parent = Player.PlayerGui.NC.Output.ScrollingFrame
end
]]
local func = loadstring(preamble .. YOUR_CODE_HERE)
func()
Well is like roblox studio command bar or script runner but in-game.
How to use the first option tho?
I know the point of option 2, but like you said itās less reliable as option 1. So how to use option 1?
But second option I try and it says attempt to index nil with robloxjw02 ā my username
Thatās what I meant by āless reliableā. Itās generating code that tries and fails to get game.Players
.
How to use the first option tho?
You just use setfenv(func, environment)
to change the environment of a function to another table.
has an example of this.
Iām not sure how you couldnāt get the first one to work if you could make the second one run and show an error.
local RemoteEvent = game.ReplicatedStorage.Test
--local Modules = game.ReplicatedStorage.Loadstring
--local LogService = game:GetService("LogService")
local Players = game:GetService("Players")
RemoteEvent.OnServerEvent:Connect(function(Player, Text)
local preamble = [[
local preamble = [[
local Player = ]] .. Player:GetFullName() .. [[
function print(...)
local messages = {...}
-- convert each argument to string
for i, message in ipairs(messages) do
messages[i] = tostring(message)
end
-- show the result in a textlabel
local TextLabel = game.ReplicatedStorage.Output:Clone()
TextLabel.Text = table.concat(messages, "\t")
TextLabel.Parent = Player.PlayerGui.NC.Output.ScrollingFrame
end
]]
local func = loadstring(preamble..Text)
func()
end)
This is my code now using your second option.
If i use the first option, where should i put the function print(ā¦), inside ServerEvent or outside?