ac-minetest / basic_robot

Write mods without server restart while playing. Create custom machines that can build, dig, produce... Create your own games like minesweeper, sokoban,ctf, hide and seek...
26 stars 21 forks source link

Auto pause instead of crashing when exceding time limits for coroutine robots #20

Open Kimapr opened 5 years ago

Kimapr commented 5 years ago

When robots use more resources (execution count, dig,place,etc) than allowed per run, they crash. However, coroutine has pause function and it could replace crashing the robot, by pausing the robot when it exceeds execution count or operations per sec.

ac-minetest commented 5 years ago

Could be. And what happens if robot does not use coroutine mode? Just skip requested action without warning?

If we only pause (when using coroutine) then player won't be notified about the problem.

Kimapr commented 5 years ago

Why this is a problem? I think the opposite is the problem because the player is forced to place pause() everywhere. This makes the program slower because the program pauses very often. If the robot doesn't use coroutine mode, don't change anything. Make them crash as always. And maybe we should replace non-coroutine mode with coroutine mode repeating with a minimum interval of one step (1s). Also, 'good' programs (thus programs which never exceed execution/operation limits) are not affected

Kimapr commented 5 years ago

This is not a problem for the server - because robot pauses anyways, this is not problem for players - it is a good for them, this is not a problem for devs - no conflicts with other features (depends on implementation), no problems with finding devs who want to develop this (I am already found)

Kimapr commented 5 years ago

Also, plainstring replace of pause with _c_ = 0; pause is bad because the pause func can be overriden. It is better to override pause func in top of the file with something like :

do
  local raw_pause = pause
  function pause()
    _c_ = 0; raw_pause()
  end
end
ac-minetest commented 5 years ago

great suggestion about pause. why do you need to insert as 'code block' between 'do .. end' ? im thinking of adding on top of source:

_pause_ = pause; pause = function() _c_ = 0; _pause_() end

and then i prevent user from using _pause_ in their program. This way they can still modify 'pause' if they want but they can't force running _c_ = 0 which was the issue. It would be best if lua would let you simply make some variables 'read_only' in sandbox so that user cant change them.

How do i add you as contributor to basic_robot ?

ac-minetest commented 5 years ago

i don't even need to prevent user from using _pause_' and modifying it. They can't putcin their program anyway, which is the only problem here. If they modifypause` only thing that happens is their robot crashes.

ac-minetest commented 5 years ago

forgot local _pause_ above - then it works, otherwise infinite recursion crash (just local works, don't need to insert between do... end)

Kimapr commented 5 years ago

great suggestion about pause. why do you need to insert as 'code block' between 'do .. end' ?

Because this way it's safe to allow users to modify the pause func. If they modify the func, they can If not, players could just replace raw_pause with empty func. Also i'm against disallowing any expressions in syntax. This is a restriction imposed on players, and i don't like such things. Disallowing variable names is even worse. It would be better, for example to analyze syntax of Lua (you need a lexer), and replace all unsafe things you find with safe (equivalent!) alternatives. Or replace the whole thing with Lua interpreter written in Lua or something else you can fully control from Lua. You can stop disallowing use of _c_ and _G in robots' code and do something like this:

local countfunc<lots of random characters>
do
  local counter = 0
  local raw_pause = pause
  function pause()
    counter = 0; raw_pause()
  end
  local not_so_raw_pause = pause
  countfunc<lots of random characters> = function()
    counter = counter + 1
    if counter >  <execution count limit> then
      not_so_raw_pause()
    end
  end
end

and then inject this into the beginning of the code. Also inject countfunc<lots of random characters>() in the beginning of loops, funcs, etc. instead of _c_=_c_+1; if _c_ > <ecl> then <crash> end

How do i add you as contributor to basic_robot ?

IDK, maybe just merge my PR?

ac-minetest commented 4 years ago

Another good idea.

using c instead of c would work as well. Then no need for disallow c. cK4mO0p7T thats 8 random chars, and this would change on every recompile of the code in 'secure secret way'.

Question: is there a way to use debug.getinfo or something similar to see how much memory ALL the variables in given ENVIROMENT are using? There is command with collectgarbage("count") which i could potentially use before and after player script is run and get "memory_delta". If total sums of those deltas would exceed some treshold it would stop program. Not sure how good this would be and what are the cons of doing this. This is assuming that garbage collector itself does not run during program execution and frees memory by ~50MB which would defeat this and show fake 'total delta'.

Enviroments seem to be related not to value of ENV but to pointer address of ENV as lua table. Because if you use setfenv(function, ENV)` with another ENV1 which has same values as ENV but its different lua table (pointer) there are no variables you defined previously using ENV. It would be nice to be able to get some quick info on ENV itself (interested in memory use). Im sure you can do all that if you change c++ code just want to do it from lua.

ac-minetest commented 4 years ago

*using using _c<randomstring>_ instead of _c_ would work as well.