Running script for a group to access functions within group parts - lua

I was just wondering in roblox if anyone has ever come upon a situation where they needed to run scripts from another script. My situation is that I am making a control point system for a game. I need to be able to know if the other points are captured in order to capture the next ones so I am attempting to write a controller on top of it but i am not sure exactly how to access the functions from within the control point script.

Yes! ROBLOX provides a very useful feature called ModuleScripts for the very purpose of calling scripts from other scripts. The icon for ModuleScripts looks the same as the icon for regular Scripts except with a little brick in the bottom-right.
The way it works is that regular Scripts can call ModuleScripts in the game using the special require() function. The easiest way to explain this is with an example.
To begin, let's imagine that we have a Script and a ModuleScript. The Script will be located at game.Workspace.normalScript, and the ModuleScript will be located inside a brick called part at game.Workspace.part.moduleScript.
moduleScript will contain the following code:
script.Parent.Transparency = .5 --"Parent" is the part since this ModuleScript is located inside the part
Now, normalScript will contain the following code:
require(game.Workspace.part.moduleScript)
When you run the game, normalScript will execute moduleScript, changing the transparency of part to .5. When one calls require() on a ModuleScript, it will act as though it were a normal function being called. moduleScript acted as though it were a function, and ModuleScripts in general act the same way as functions for the most part.
This also means that ModuleScripts can return values like functions. For example, if we have the following code in moduleScript:
return 3+3
Now, our script will contain the following code:
local number = require(game.Workspace.moduleScript)
print(number) --> 6
This code will print "6" to the console since moduleScript returned 6. As you might guess, this means that ModuleScripts have many more uses than simply remotely executing code.
Here are two more examples of uses of ModuleScripts:
1) Returning functions:
moduleScript:
return function()
print("hey")
end
normalScript:
local func = require(game.Workspace.moduleScript)
func() --> hey
2) Returning modules such as apple below:
moduleScript:
local apple = {}
apple.flavor = "sweet"
return apple
normalScript:
local fruit = require(game.Workspace.moduleScript)
print(fruit.flavor) --> sweet
These are rather silly examples of ModuleScript uses, but ModuleScripts can actually be very powerful tools. For some cool examples, visit the ROBLOX Wiki page on ModuleScripts and scroll about halfway down.

Related

What does this piece of lua code from awesome wm do?

Take a look at this code:
local urgent = {}
local capi =
{
client = client,
}
local client
do
client = setmetatable({}, {
__index = function(_, k)
client = require("awful.client")
return client[k]
end,
__newindex = error -- Just to be sure in case anything ever does this
})
end
I'm having trouble understanding what it does. It's from the awesome-wm project. These are the things I'm having trouble understanding:
client = client in the declaration of capi
setmetatable stuff inside do-end
client = client in the declaration of capi
This is defining what portion of the capi is available in this file's scope, If you look at the client.lua file you will see that the capi defined in it has client, mouse, screen, and awesome.
For each item defined in the capi table there is a corresponding .c file. These files define objects such as client. urgent.lua has visibility of that object, likely it is a global variable, that is how we can set client = client the second client refers to the global variable.
Here is an example of 2 files:
main.lua
bar = "Hello World!"
local foo = require('foo')
print(foo.bar)
foo.lua
local foo = {
bar = bar
}
return foo
The print function in main.lua will result in Hello World!
setmetatable stuff inside do-end
Here by warping the setmetatable in a do-end block the code is executing in a restricted scope. This is normally done to contain the block's local variables so that they do not persist after the code's execution.
That said that is not the purpose of this block as the block has no local variables. As I see it, the blocking is simply to show that the object being modified is the local variable of client and not the global variable of client.
Additionally the metatable here is used to prevent circular dependency loops, this is mentioned comments in some of the places where similar code appears in the project, such as client.lua where local screen is defined.
#Nifim answer is excellent. I just want to add more context on why this code exist in its proper historical context. Before Lua 5.2, the module system was different. There was a magic module() function defined in the core Lua library. When you made a module, you had to first make local version of all global variables before calling module() because otherwise it would run in its own global environment. "capi" stands for "Core API" or "C (language) API" depending on the weather. If Awesome was written today with all the knowledge we now have, there would not be a public "C language" API and they would always be hidden in the private section to increase flexibility. Right now setting "c.my_own_property" do a couple round trips between capi.client and awful.client just to accommodate all the legacy constraints.
Now, the metatable magic is a Lua pattern called meta-lazy-loading. Because the urgent is a submodule of awful.client, it cannot directly import awful.client without causing a circular dependency. Over time, as Awesome APIs became better defined, more and more refactoring were made and they often introduced weird dependencies to maintain some degree of backward compatibility. In the best universe, we would have disregarded all users config and just re-engineered the whole code to avoid these circular dependencies. However every time we do that all users of the said APIs wake up one morning and they cannot login into their computer anymore. So this kind of workaround exist to prevent such events in return for some weird code and maintenance burden.

{LUA} How to fire another script in script?

I have a question from Lua/Roblox!
Basically, I want to fire a script from a script. This may sound like a stupid question, but actually it isn't :P
For example:
I have a script: script1 in ServerScriptStorage.
And, I want to code it to fire contents of script2.
Examples:
Content of script1:
game.Players.PlayerAdded:Connect(function()
HERE SCRIPT2 FIRING!
end)
Content of script2:
print("This message is triggered by event in script!")
This is fairly simple task I suppose, so please give me the SIMPLEST and SHORTEST version of code. I don't need any exclusives such like launching 2 script in 1. I'm a begginer script, so please keep it simple.
Thanks, NorteX.
In pure Lua, using dofile would probably make the most sense. However, in Roblox, the approach must be much different. The way I would recommend doing this is using a ModuleScript for "Script2". Then you would load the script using require(). Because "requiring" a script caches the returned value for future "requires", this means that the contents of the ModuleScript will only be executed once. Thus, if you have code you want to run multiple times, you should encapsulate it in a function that the ModuleScript returns.
Here's how the code would look like given your setup:
Script1:
local script2 = require(game.ServerScriptService.Script2)
game.Players.PlayerAdded:Connect(function(player)
script2()
end)
Script2:
-- In game.ServerScriptService.Script2 as a ModuleScript
return function()
print("This message is triggered by event in script!")
end
Check out the documentation for ModuleScripts to understand more about them.
workspace.SCRIPT2.Disabled = true -- Disables SCRIPT2 , you can remove this and manually disable it in SCRIPT2's properties.
game.Players.PlayerAdded:Connect(function()
workspace.SCRIPT2.Disabled = false -- Activates SCRIPT2. You can alter the "disabled" state multiple time to make it reboot and operate more than once.
end)
Also, you could replace workspace.SCRIPT2.Disabled by the location where your second script is, by example, workspace.FolderOne.scripts.SCRIPT2.Disabled . Just be sure it points to the script and keeps the "disabled" part on, so it knows to disable / enable it.

Hacking Lua - Inject new functions into built Lua

I am trying to hack a game (not for cheating though) by introducing new built-in methods and functions in order to communicate with the game using sockets. Here is a small "pseudo code" example of what I want to accomplish:
Inside the Lua code I am calling my_hack() and pass the current game state:
GameState = {}
-- Game state object to be passed on
function GameState:new()
-- Data
end
local gameState = GameState:new()
-- Collect game state data and pass it to 'my_hack' ..
my_hack(gameState)
and inside my_hack the object is getting sent away:
int my_hack(lua_State * l)
{
void* gameState= lua_topointer(l, 1);
// Send the game state:
socket->send_data(gameState);
return 0;
}
Now, the big question is how to introduce my_hack() to the game?
I assume, that all built in functions must be kept in some sort of lookup table. Since all Lua code is getting interpreted, functions like import etc. will have to be statically available, right? If that is correct, then it should be "enough" to find out where this code is residing in order to smuggle my code into the game that would allow me to call my_hack() in a Lua script.
There should be two options: The first is that the Lua built is embedded inside the executable and is completely static and the second is that all Lua code gets loaded dynamically from a DLL.
This question goes out to anybody who has a slightest clue about where and how I should keep looking for the built in functions. I've tried a few things with Cheat Engine but I wasn't too successful. I was able to cheat a bit ^^ but that's not what I'm looking out for.
Sorry for not providing a full answer, but if you can provide a custom Lua VM and change the standard libraries, you should be able to to change the luaL_openlibs method in the Lua source to provide a table with my_hack() inside of it.
Since the Lua interpreter is usually statically compiled into the host executable, modifying the interpreter in some way will probably not be possible.
I think your best bet is to find some piece of Lua code which gets called by the host, and from that file use dofile to run your own code.

I just want to call some specific function in my Lua script. How to do that?

I just want to call some specific function in my Lua script.
A simple script:
msg("hello")
function showamsgbox()
msg("123")
end
I just want to let my C app call showamsgbox() only but not to run msg("hello") beacuse it will show a msgbox when i load this script! So how to do that to keep this situation away?
PS:it is just example.sometimes i want to let users make thier own plugins in my program.but I do not want them write something outside the functions(i want to use functions to decide what to do.for example function OnLoad() means it will be run when i load it ).If there is something outside functions i cannot control them!
You can't. The script defines two variables when run: a and geta. Recall that function geta()...end is the same as geta=function()...end.
The a = 9 will be called when the script is initially evaluated in a lua_State.
If you reuse that lua_State instance, you can retrieve the function and invoke it without re-initializing a.
It seems that you want to sandbox scripts. Just give them a suitable, separate environment before running them. It may be an empty one or it may contain references to the functions you want them to use. They can write at will in their environment and it will not affect yours. Then just get the value of OnLoad or whatever user function you want to call and call it.

hot swap code in lua

I've heard mumblings around the internets about being able to hot-swap code in Lua similar to how it's done in Java, Erlang, Lisp, etc. However, 30 minutes of googling for it has turned up nothing. Has anyone read anything substantial about this? Anyone have any experience doing it? Does it work in LuaJIT or only in the reference VM?
I'm more interested in the technique as a shortcut in development/debugging than an upgrade path in a live environment.
Lua, and most scripting languages for that matter, do not support the most generalized form of "hot swapping" as you define it. That is, you cannot guaranteeably change a file on disk and have any changes in it propagate itself into an executing program.
However, Lua, and most scripting languages for that matter, are perfectly capable of controlled forms of hot swapping. Global functions are global functions. Modules simply load global functions (if you use them that way). So if a module loads global functions, you can reload the module again if it is changed, and those global function references will change to the newly loaded functions.
However, Lua, and most scripting languages for that matter, makes no guarantees about this. All that's happening is the changing of global state data. If someone copied an old function into a local variable, they can still access it. If your module uses local state data, the new version of the module cannot access the old module's state. If a module creates some kind of object that has member functions, unless those members are fetched from globals, these objects will always refer to the old functions, not the new ones. And so forth.
Also, Lua is not thread safe; you can't just interrupt a lua_State at some point and try to load a module again. So you would have to set up some specific point in time for it to check stuff out and reload changed files.
So you can do it, but it isn't "supported" in the sense that it can just happen. You have to work for it, and you have to be careful about how you write things and what you put in local vs. global functions.
As Nicol said, the language itself doesn't do it for you.
If you want to implement something like this yourself though, it's not that hard, the only thing "preventing" you is any "leftover" references (which will still point to the old code) and the fact require caches its return value in package.loaded.
The way I'd do it is by dividing your code into 3 modules:
the reloading logic at entry point (main.lua)
any data you want to preserve across reloads (data.lua)
the actual code to reload (payload.lua), making sure you don't keep any references to that (which is sometimes not possible when you e.g. have to give callbacks to some library; see below).
-- main.lua:
local PL = require("payload")
local D = require("data")
function reload(module)
package.loaded[module]=nil -- this makes `require` forget about its cache
return require(module)
end
PL.setX(5)
PL.setY(10)
PL.printX()
PL.printY()
-- .... somehow detect you want to reload:
print "reloading"
PL = reload("payload") -- make sure you don't keep references to PL elsewhere, e.g. as a function upvalue!
PL.printX()
PL.printY()
-- data.lua:
return {} -- this is a pretty dumb module, it's literally just a table stored in `package.loaded.data` to make sure everyone gets the same instance when requiring it.
-- payload.lua:
local D = require("data")
local y = 0
return {
setX = function(nx) D.x = nx end, -- using the data module is preserved
setY = function(ny) y = ny end, -- using a local is reset upon reload
printX = function() print("x:",D.x) end,
printY = function() print("y:", y) end
}
output:
x: 5
y: 10
reloading
x: 5
y: 0
you could flesh out that logic a bit better by having a "registry module" that keeps track of all the requiring/reloading for you and abstracts away any access into modules (thus allowing you to replace the references), and, using the __index metatable on that registry you could make it pretty much transparent without having to call ugly getters all over the place. this also means you can supply "one liner" callbacks that then actually just tail-call through the registry, if any 3rd party library needs that.

Resources