Is there a way to make a custom loadstring() function in lua? - lua

Here is an example
local CustomLoad = function(l) loadstring(l) end
CustomLoad("print('hi')")
Please let me know, beacuse I got into this like a week ago, and I've been trying to make it, yet I coudln't. Can some of you tell me if it's even possible?

If you aren't trying to run "print('hi')" in that example, then I do believe you're missing a return statement.
local CustomLoad = function(l) return loadstring(l) end
But if you are, then:
local CustomLoad = function(l) return loadstring(l) end
CustomLoad("print('hi')")()
or
local CustomLoad = function(l) local f = loadstring(l); f() end
CustomLoad("print('hi')")
Because loadstring creates a function, which, when run, executes the code in the string.
Hope that helped!

Related

Is there a possiblity to create a variable with a string for everything inside of a table?

Just wondering about that, because i don't find a solution for it. Pretty sure because I'm new to this c: Thanks for your help.
Edit: for explanation im gonna explain it with the code a bit.
local FileList = fs.list("") --Makes a Table with all the files and directories available (as strings) on the PC it's running on (Inside of a mod called computercraft for minecraft)
for _, file in ipairs(FileList) do
--Here I need a function which assigns every string from the table to a variable, just for the explanation I'll call it unknown.function
unknown.function
end
while true do
print(a) --a is for example one of the different variables made from the "unknown.function"
sleep(1)
end
LIKE this?
AllFiles = {}
function Crazyfunction(file)
AllFiles[table.getn(AllFiles)+1] = file
end
local FileList = fs.list("")
for _, file in ipairs(FileList) do
Crazyfunction(file)
end
while true do
print(AllFiles[NUMBE_OF_FILE_HERE])
sleep(1)
end
You mean like this?
local FileList = fs.list("")
for _, file in ipairs(FileList) do
-- file is the variable which contains a string from the table.
print(file)
sleep(1)
end
What you want is... already what your loop does. You just added an extra loop for no reason.

Prevent a file being written to more than once without file:close()

I'm currently working on a logging system. My problems arise when using for loops and file writing. Here is a small example:
file = io.open("text.txt","a") --text.txt can be literally anything
for i=1,8 do
if x == true then
file:write("X is true.")
elseif y == true then
file:write("Y is true.")
end
end
Is there a way to stop the file from being written to multiple times without using file:close()? I have a huge number of different file:write sections, and adding file:close() after all of them would be a massive problem.
If file:close() every time is a massive problem, then this is the custom logic you need.
myFileMetatable = {} --implement all necessary file operations here
function myFileMetatable.write(self, str)
if not self.written then
self.written = true
self.f:write(str)
end
end
function myFileMetatable.close(self)
self.f:close()
end
myFile = {}
function myFile.open(filename, mode)
local t = {f = io.open(filename, mode)}
setmetatable(t, {__index = myFileMetatable})
return t
end
--now you can do
file = myFile.open("test", "w")
file:write("test")
file:write("hello")
file:write("world")
file:close() --and only "test" will be written
Note that this is probably much better than replacing file:write(str) with something file_write(file, str), since you need to store somewhere the fact that the file has already been written to, which you cannot store inside the FILE* object and using a global variable for that will break when using multiple files. That's why I wrap the FILE* object in a table and use myFileMetatable to implement my own methods that I will need.
However, if you need just one file at a time and don't mind the global variable then this is more efficient.
file_written = false
function file_write(file, str)
if not file_written then
file_written = true
file:write(str)
end
end
file = io.open("test", "w")
file_write(file, "test")
file_write(file, "hello")
file_write(file, "world")
file:close()
Mind that it's not as pretty as the first example and you might face a problem in the future, if you decide to expand beyond one file.
How Egor Skriptunoff already said, I'll recommend you to write your own writing function. I'm normally using sth. like this:
local function writeFile(filePath, str)
local outfile = io.open(filePath, 'w')
outfile:write(str)
outfile:close()
end
For appending to the file easily change the mode from w to a.
For my specific case, I've found a solution - since I just want a single option to print, and it's the last option (rather than the first, and I should've specified this), I can just set a variable to what I want my output to be and write that at the end.
log = ""
if x == 2 then
log = "X is 2."
elseif y == 2 then
log = "Y is 2."
end
file:write(log)
For the last option, I'd refer anyone to the accepted answer which should be perfect.

How to get wireshark heuristic dissector work?

I'm writting a lua script as wireshark(1.12.4) plugin to dissect my private protocols,I can get it work as normal dissector,which binding a certain port(such as 80) to DissectorTable "tcp.port".The pseudo-code as follows:
local my_pro = Proto("MyPro","My Protocol")
local my_pro_field_1 = ProtoField.uint16("MyPro.filed_1","Field 1",base.HEX)
local my_pro_field_2 = ProtoField.uint16("MyPro.filed_2","Field 2",base.HEX)
my_pro.fields = {my_pro_field_1,my_pro_field_2}
local data_dis = Dissector.get("data")
function my_pro.dissector(buf,pkt,root)
if (buf(0,2):uint() ~= 1 or buf(2,2):uint() ~= 1) then
data_dis:call(buf,pkt,root)
return false
end
pkt.cols.protocol = "My Protocol"
local tree = root:add(my_pro,buf(0,buf:len()))
tree:add_le(my_pro_field_1,buf(0,2))
tree:add_le(my_pro_field_2,buf(2,2))
return true
end
local tcp_encap_table = DissectorTable.get("tcp.port")
tcp_encap_table:add(80,my_pro)
The problem is:
What if My protocol is not running on a certain port,as I don't want to modify the port above every time,I actually want the dissector to be wise enough to dynamically identify some kind of pattern and do the right dissecting then.
I've searched out there's a so called "heuristic" dissector,I add codes below to test but I could't get it work.
local function my_heur_dissector(buf,pkt,root)
local ret = my_pro.dissector(buf,pkt,root)
if (not ret) then
return false
end
pkt.conversation = my_pro
return true
end
my_pro:register_heuristic("tcp",my_heur_dissector)
When I change the port,the packets're not parsed as my protocol,so I have to use "Decode as" menu.
So,how can I get the heuristic dissector work base on my code?Have I missed something?
BTW,the answer with code is appreciated.
Sadly, if you need a heuristic dissector (HD) it cannot be done in a plugin manner, and you need to write a new HD.
https://github.com/wireshark/wireshark/blob/master/doc/README.heuristic
(Yes, it has been over 2 years, but if some future-googler finds it...)

Getting function used to create coroutine/thread in Lua

Is it possible to get the original function used to create a coroutine ?
thread = coroutine.create(function()
-- Code
end)
f = get_function_from_thread(thread)
You can't do this out-of-the box, but you can always redefine coroutine.create:
local create=coroutine.create
local created={}
function coroutine.create(f)
local t=create(f)
created[t]=f
return t
end
function get_function_from_thread(t)
return created[t]
end
If you create lots of coroutines, consider setting created as a weak table.

Importing a bunch of names in Lua

In my script I follow the practice of "importing" functions from another module. So I have code similar to the following at the start of my script:
local some_function = assert(require("utils").some_function)
local another_func = assert(require("utils").another_func)
local yet_another = assert(require("utils").yet_another)
local and_another = assert(require("utils").and_another)
But this chunk of code is not quite readable.
(The assert() is there to guard against spelling mistakes in the function names.)
I know that I can easily write my own function, say require_names(), and turn the above code into:
local some_function, another_func, yet_another, and_another
= require_names("utils", { "some_function", "another_func", "yet_another", "and_another" })
This looks much better. Still, it's not optimal: there's redundancy in this code: the names of the functions repeat twice.
Is there a way for me to write my require_names() so that it doesn't have the redundancy problem?
Or, do you you have any ideas for solving the readability problem in some other way?
(I need solutions that run on both Lua 5.1 and 5.2)
If you want only a subset of what is in utils module, yet only create locals, then you can't. Other answers give you the whole utils module, in that case I don't see why not just use require 'yourmodule'. If you can relinquish locals, then:
function require_names(modName, objNames)
for i,v in ipairs(objNames) do
_G[v] = assert(require(modName)[v])
end
end
works in both 5.1 :
> print(setn)
nil
> print(insert)
nil
> require_names("table", {"setn", "insert"})
> print(setn)
function: 005F7910
> print(insert)
function: 005F7890
The only non-globals option is to put what you want in a local table, to get only the subset you need:
function require_names(modName, objNames)
local mod = {}
for i,v in ipairs(objNames) do
mod[v] = assert(require(modName)[v])
end
return mod
end
local utils = require_names("utils", { 'a', 'b' })
utils.a = asdfasf
print(utils.b)
However, the only benefit of above compared to local utils=require 'utils' is that it documents what you module is going to use from the required module. But it is a little noisy with all the quotes and braces.
I would do this:
local u = require 'utils'
Then use it like this:
u.some_function(...)
This is very easy to type and very obvious.
If you really need locals, then I would not use a single function called require_names but two: the regular require + extract. Here's extract
local function extract(t, keys)
local values = {}
for i=1, #keys do values[i] = t[keys[i]] end
return unpack(values)
end
Usage:
local utils = require 'utils'
local some_function, another_func, yet_another, and_another =
extract(utils, { "some_function", "another_function", "yet_another", "and_another"})

Resources