Lua API global Variable Viewer (gvv)

by Ritn

This is a debugging tool. This mod adds commands /gvv and others and a hotkey(Ctrl+Shift+V) to allow you to check _G and global table of map or each mods. Only admins can use command if it is multiplay game. You have to input some code for temporary accessibility or have to edit "control.lua" of other mod or map to access global table of the mod or map. See "Helper" tab for instructions.

Utilities
a month ago
1.0 - 2.0
3.33K

b Do not interate into custom tables

3 years ago

@Pi-C reported that he got an error in the output of gvv's "_G" remote function in the gvv gui "global" tab. I dug into your code and found this in gvv.lua:

if t=='table'
and type(o.__self) == 'userdata'
and o.object_name then

@Pi-C uses some functions of my library mod "eradicators-library" which creates some tables that are protected by metatables, so the attempt to read "__self" causes an error. This can be prevented by not parsing tables that have metatable - because you never know what those metatables are going to do.

if t=='table'
and getmetatable(o) then
  j=j+1 r='<table-with-metatable>'
elseif t=='table'
and type(o.__self) == 'userdata'
and o.object_name then
3 years ago

Thank you for reviewing my code.
I think this mod can't handle cases(mods) that overriding default behavior of essential functions to check data.
But I think some people still need ability to inspect table with metatable. So I can't accept your proposed code that ignoring table-with-metatable.
I tried to write code individually bypassing tables causing errors, leaving error message when it failes for each entry. Now loaded onto 0.4.4.

3 years ago
(updated 3 years ago)

Thanks for looking into it. I know completely ignoring table-with-meta isn't the nicest solution, but it's a solution that is (almost) guaranteed to not have side-effects. Pcalling doesn't prevent invoking metamethods. And invoking metamethods can always result in undesired changes to the table state that might not result in an immedeate error, but cause errors later on. A better approach might be using next() to circumvent __pairs and rawget() to circumvent __index. That would show a bit more info than completely ignoring the table and should not cause unexpected side-effects. Ironically one of the tables that @Pi-C reported to me that causes an error even has an object_name, but not __self.

Also btw, reviewing your code is quite tiresome due to lack of indentation, is there any particular reason for this?

3 years ago

Thank you for guiding me about usage of metamethods and more detailed situation. I'm still not good at lua language, so I will study more.
In my source code, gvv.lua at root directory is not "source" but "copy&pasted".

To make some codes able to be copyied&pasted, I made "source" as "string".
And "source string" is at

gvv/modules/remote_code/get_g.lua

which have indentation. I copy the code printed at in-game GUI from this "source" and paste into "gvv.lua" file.

3 years ago

https://github.com/x2605/gvv/commit/d689aa5a002a388cb5714842deff238fc1da421b#diff-1953c9581ea8244609ca0b256b2b75e8b5afa3f1cbc7dd4766808eaa5d78e49b
I updated gvv code to 0.4.5.

I tried to use the fact that getmetatable() of Factorio returns 'private' string value to check whether a table is a Factorio object.

if t=='table'
and getmetatable(o)=='private'
and type(o.__self)=='userdata'
and o.object_name then
...

I guess failure of checking 'private' will prevent attempt to access '__self' & 'object_name' key.
I hope any other modder do not to try mimic getmetatable(own_custom_table) to return 'private' value...
I hope there is no other places invoking metamethod of a table being checked in gvv's "_G" bringer remote function code.

New response