f7a2ce9aae1c423f28afb96a079c226ea925b13d
[oweals/minetest.git] / src / scriptapi.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "scriptapi.h"
21
22 #include <iostream>
23 #include <list>
24 extern "C" {
25 #include <lua.h>
26 #include <lualib.h>
27 #include <lauxlib.h>
28 }
29
30 #include "log.h"
31 #include "server.h"
32 #include "porting.h"
33 #include "filesys.h"
34 #include "serverobject.h"
35 #include "script.h"
36 //#include "luna.h"
37 #include "luaentity_common.h"
38 #include "content_sao.h" // For LuaEntitySAO
39 #include "tooldef.h"
40 #include "nodedef.h"
41 #include "craftdef.h"
42 #include "craftitemdef.h"
43 #include "main.h" // For g_settings
44 #include "settings.h" // For accessing g_settings
45 #include "nodemetadata.h"
46 #include "mapblock.h" // For getNodeBlockPos
47 #include "content_nodemeta.h"
48 #include "utility.h"
49
50 static void stackDump(lua_State *L, std::ostream &o)
51 {
52   int i;
53   int top = lua_gettop(L);
54   for (i = 1; i <= top; i++) {  /* repeat for each level */
55         int t = lua_type(L, i);
56         switch (t) {
57
58           case LUA_TSTRING:  /* strings */
59                 o<<"\""<<lua_tostring(L, i)<<"\"";
60                 break;
61
62           case LUA_TBOOLEAN:  /* booleans */
63                 o<<(lua_toboolean(L, i) ? "true" : "false");
64                 break;
65
66           case LUA_TNUMBER:  /* numbers */ {
67                 char buf[10];
68                 snprintf(buf, 10, "%g", lua_tonumber(L, i));
69                 o<<buf;
70                 break; }
71
72           default:  /* other values */
73                 o<<lua_typename(L, t);
74                 break;
75
76         }
77         o<<" ";
78   }
79   o<<std::endl;
80 }
81
82 static void realitycheck(lua_State *L)
83 {
84         int top = lua_gettop(L);
85         if(top >= 30){
86                 dstream<<"Stack is over 30:"<<std::endl;
87                 stackDump(L, dstream);
88                 script_error(L, "Stack is over 30 (reality check)");
89         }
90 }
91
92 class StackUnroller
93 {
94 private:
95         lua_State *m_lua;
96         int m_original_top;
97 public:
98         StackUnroller(lua_State *L):
99                 m_lua(L),
100                 m_original_top(-1)
101         {
102                 m_original_top = lua_gettop(m_lua); // store stack height
103         }
104         ~StackUnroller()
105         {
106                 lua_settop(m_lua, m_original_top); // restore stack height
107         }
108 };
109
110 class ModNameStorer
111 {
112 private:
113         lua_State *L;
114 public:
115         ModNameStorer(lua_State *L_, const std::string modname):
116                 L(L_)
117         {
118                 // Store current modname in registry
119                 lua_pushstring(L, modname.c_str());
120                 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
121         }
122         ~ModNameStorer()
123         {
124                 // Clear current modname in registry
125                 lua_pushnil(L);
126                 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
127         }
128 };
129
130 std::string get_current_modname(lua_State *L)
131 {
132         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
133         std::string modname = "";
134         if(lua_type(L, -1) == LUA_TSTRING)
135                 modname = lua_tostring(L, -1);
136         lua_pop(L, 1);
137         return modname;
138 }
139
140 void check_modname_prefix(lua_State *L, std::string &name)
141 {
142         if(name.size() == 0)
143                 throw LuaError(L, std::string("Name is empty"));
144         
145         if(name[0] == ':'){
146                 name = name.substr(1);
147                 return;
148         }
149         
150         std::string modname = get_current_modname(L);
151         assert(modname != "");
152         
153         // For __builtin, anything goes
154         if(modname == "__builtin")
155                 return;
156         
157         if(name.substr(0, modname.size()+1) != modname + ":")
158                 throw LuaError(L, std::string("Name \"")+name
159                                 +"\" does not follow naming conventions: "
160                                 +"\"modname:\" or \":\" prefix required)");
161         
162         std::string subname = name.substr(modname.size()+1);
163         if(!string_allowed(subname, "abcdefghijklmnopqrstuvwxyz"
164                         "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"))
165                 throw LuaError(L, std::string("Name \"")+name
166                                 +"\" does not follow naming conventions: "
167                                 +"\"contains unallowed characters");
168 }
169
170 static void push_v3f(lua_State *L, v3f p)
171 {
172         lua_newtable(L);
173         lua_pushnumber(L, p.X);
174         lua_setfield(L, -2, "x");
175         lua_pushnumber(L, p.Y);
176         lua_setfield(L, -2, "y");
177         lua_pushnumber(L, p.Z);
178         lua_setfield(L, -2, "z");
179 }
180
181 static v2s16 read_v2s16(lua_State *L, int index)
182 {
183         v2s16 p;
184         luaL_checktype(L, index, LUA_TTABLE);
185         lua_getfield(L, index, "x");
186         p.X = lua_tonumber(L, -1);
187         lua_pop(L, 1);
188         lua_getfield(L, index, "y");
189         p.Y = lua_tonumber(L, -1);
190         lua_pop(L, 1);
191         return p;
192 }
193
194 static v2f read_v2f(lua_State *L, int index)
195 {
196         v2f p;
197         luaL_checktype(L, index, LUA_TTABLE);
198         lua_getfield(L, index, "x");
199         p.X = lua_tonumber(L, -1);
200         lua_pop(L, 1);
201         lua_getfield(L, index, "y");
202         p.Y = lua_tonumber(L, -1);
203         lua_pop(L, 1);
204         return p;
205 }
206
207 static Server* get_server(lua_State *L)
208 {
209         // Get server from registry
210         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
211         return (Server*)lua_touserdata(L, -1);
212 }
213
214 static ServerEnvironment* get_env(lua_State *L)
215 {
216         // Get environment from registry
217         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_env");
218         return (ServerEnvironment*)lua_touserdata(L, -1);
219 }
220
221 static v3f readFloatPos(lua_State *L, int index)
222 {
223         v3f pos;
224         luaL_checktype(L, index, LUA_TTABLE);
225         lua_getfield(L, index, "x");
226         pos.X = lua_tonumber(L, -1);
227         lua_pop(L, 1);
228         lua_getfield(L, index, "y");
229         pos.Y = lua_tonumber(L, -1);
230         lua_pop(L, 1);
231         lua_getfield(L, index, "z");
232         pos.Z = lua_tonumber(L, -1);
233         lua_pop(L, 1);
234         pos *= BS; // Scale to internal format
235         return pos;
236 }
237
238 static void pushFloatPos(lua_State *L, v3f p)
239 {
240         p /= BS;
241         push_v3f(L, p);
242 }
243
244 static void pushpos(lua_State *L, v3s16 p)
245 {
246         lua_newtable(L);
247         lua_pushnumber(L, p.X);
248         lua_setfield(L, -2, "x");
249         lua_pushnumber(L, p.Y);
250         lua_setfield(L, -2, "y");
251         lua_pushnumber(L, p.Z);
252         lua_setfield(L, -2, "z");
253 }
254
255 static v3s16 readpos(lua_State *L, int index)
256 {
257         // Correct rounding at <0
258         v3f pf = readFloatPos(L, index);
259         return floatToInt(pf, BS);
260 }
261
262 static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
263 {
264         lua_newtable(L);
265         lua_pushstring(L, ndef->get(n).name.c_str());
266         lua_setfield(L, -2, "name");
267         lua_pushnumber(L, n.getParam1());
268         lua_setfield(L, -2, "param1");
269         lua_pushnumber(L, n.getParam2());
270         lua_setfield(L, -2, "param2");
271 }
272
273 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
274 {
275         lua_getfield(L, index, "name");
276         const char *name = luaL_checkstring(L, -1);
277         lua_pop(L, 1);
278         u8 param1;
279         lua_getfield(L, index, "param1");
280         if(lua_isnil(L, -1))
281                 param1 = 0;
282         else
283                 param1 = lua_tonumber(L, -1);
284         lua_pop(L, 1);
285         u8 param2;
286         lua_getfield(L, index, "param2");
287         if(lua_isnil(L, -1))
288                 param2 = 0;
289         else
290                 param2 = lua_tonumber(L, -1);
291         lua_pop(L, 1);
292         return MapNode(ndef, name, param1, param2);
293 }
294
295 static video::SColor readARGB8(lua_State *L, int index)
296 {
297         video::SColor color;
298         luaL_checktype(L, index, LUA_TTABLE);
299         lua_getfield(L, index, "a");
300         if(lua_isnumber(L, -1))
301                 color.setAlpha(lua_tonumber(L, -1));
302         lua_pop(L, 1);
303         lua_getfield(L, index, "r");
304         color.setRed(lua_tonumber(L, -1));
305         lua_pop(L, 1);
306         lua_getfield(L, index, "g");
307         color.setGreen(lua_tonumber(L, -1));
308         lua_pop(L, 1);
309         lua_getfield(L, index, "b");
310         color.setBlue(lua_tonumber(L, -1));
311         lua_pop(L, 1);
312         return color;
313 }
314
315 static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
316 {
317         core::aabbox3d<f32> box;
318         if(lua_istable(L, -1)){
319                 lua_rawgeti(L, -1, 1);
320                 box.MinEdge.X = lua_tonumber(L, -1) * scale;
321                 lua_pop(L, 1);
322                 lua_rawgeti(L, -1, 2);
323                 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
324                 lua_pop(L, 1);
325                 lua_rawgeti(L, -1, 3);
326                 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
327                 lua_pop(L, 1);
328                 lua_rawgeti(L, -1, 4);
329                 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
330                 lua_pop(L, 1);
331                 lua_rawgeti(L, -1, 5);
332                 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
333                 lua_pop(L, 1);
334                 lua_rawgeti(L, -1, 6);
335                 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
336                 lua_pop(L, 1);
337         }
338         return box;
339 }
340
341 static bool getstringfield(lua_State *L, int table,
342                 const char *fieldname, std::string &result)
343 {
344         lua_getfield(L, table, fieldname);
345         bool got = false;
346         if(lua_isstring(L, -1)){
347                 result = lua_tostring(L, -1);
348                 got = true;
349         }
350         lua_pop(L, 1);
351         return got;
352 }
353
354 static bool getintfield(lua_State *L, int table,
355                 const char *fieldname, int &result)
356 {
357         lua_getfield(L, table, fieldname);
358         bool got = false;
359         if(lua_isnumber(L, -1)){
360                 result = lua_tonumber(L, -1);
361                 got = true;
362         }
363         lua_pop(L, 1);
364         return got;
365 }
366
367 static bool getfloatfield(lua_State *L, int table,
368                 const char *fieldname, float &result)
369 {
370         lua_getfield(L, table, fieldname);
371         bool got = false;
372         if(lua_isnumber(L, -1)){
373                 result = lua_tonumber(L, -1);
374                 got = true;
375         }
376         lua_pop(L, 1);
377         return got;
378 }
379
380 static bool getboolfield(lua_State *L, int table,
381                 const char *fieldname, bool &result)
382 {
383         lua_getfield(L, table, fieldname);
384         bool got = false;
385         if(lua_isboolean(L, -1)){
386                 result = lua_toboolean(L, -1);
387                 got = true;
388         }
389         lua_pop(L, 1);
390         return got;
391 }
392
393 static std::string getstringfield_default(lua_State *L, int table,
394                 const char *fieldname, const std::string &default_)
395 {
396         std::string result = default_;
397         getstringfield(L, table, fieldname, result);
398         return result;
399 }
400
401 static int getintfield_default(lua_State *L, int table,
402                 const char *fieldname, int default_)
403 {
404         int result = default_;
405         getintfield(L, table, fieldname, result);
406         return result;
407 }
408
409 /*static float getfloatfield_default(lua_State *L, int table,
410                 const char *fieldname, float default_)
411 {
412         float result = default_;
413         getfloatfield(L, table, fieldname, result);
414         return result;
415 }*/
416
417 static bool getboolfield_default(lua_State *L, int table,
418                 const char *fieldname, bool default_)
419 {
420         bool result = default_;
421         getboolfield(L, table, fieldname, result);
422         return result;
423 }
424
425 struct EnumString
426 {
427         int num;
428         const char *str;
429 };
430
431 static bool string_to_enum(const EnumString *spec, int &result,
432                 const std::string &str)
433 {
434         const EnumString *esp = spec;
435         while(esp->str){
436                 if(str == std::string(esp->str)){
437                         result = esp->num;
438                         return true;
439                 }
440                 esp++;
441         }
442         return false;
443 }
444
445 /*static bool enum_to_string(const EnumString *spec, std::string &result,
446                 int num)
447 {
448         const EnumString *esp = spec;
449         while(esp){
450                 if(num == esp->num){
451                         result = esp->str;
452                         return true;
453                 }
454                 esp++;
455         }
456         return false;
457 }*/
458
459 static int getenumfield(lua_State *L, int table,
460                 const char *fieldname, const EnumString *spec, int default_)
461 {
462         int result = default_;
463         string_to_enum(spec, result,
464                         getstringfield_default(L, table, fieldname, ""));
465         return result;
466 }
467
468 static void setfloatfield(lua_State *L, int table,
469                 const char *fieldname, float value)
470 {
471         lua_pushnumber(L, value);
472         if(table < 0)
473                 table -= 1;
474         lua_setfield(L, table, fieldname);
475 }
476
477 static void warn_if_field_exists(lua_State *L, int table,
478                 const char *fieldname, const std::string &message)
479 {
480         lua_getfield(L, table, fieldname);
481         if(!lua_isnil(L, -1)){
482                 infostream<<script_get_backtrace(L)<<std::endl;
483                 infostream<<"WARNING: field \""<<fieldname<<"\": "
484                                 <<message<<std::endl;
485         }
486         lua_pop(L, 1);
487 }
488
489 /*
490         Inventory stuff
491 */
492
493 static void inventory_set_list_from_lua(Inventory *inv, const char *name,
494                 lua_State *L, int tableindex, IGameDef *gamedef, int forcesize=-1)
495 {
496         if(tableindex < 0)
497                 tableindex = lua_gettop(L) + 1 + tableindex;
498         // If nil, delete list
499         if(lua_isnil(L, tableindex)){
500                 inv->deleteList(name);
501                 return;
502         }
503         // Otherwise set list
504         std::list<std::string> items;
505         luaL_checktype(L, tableindex, LUA_TTABLE);
506         int table = tableindex;
507         lua_pushnil(L);
508         while(lua_next(L, table) != 0){
509                 // key at index -2 and value at index -1
510                 luaL_checktype(L, -1, LUA_TSTRING);
511                 std::string itemstring = luaL_checkstring(L, -1);
512                 items.push_back(itemstring);
513                 // removes value, keeps key for next iteration
514                 lua_pop(L, 1);
515         }
516         int listsize = (forcesize != -1) ? forcesize : items.size();
517         InventoryList *invlist = inv->addList(name, listsize);
518         int index = 0;
519         for(std::list<std::string>::const_iterator
520                         i = items.begin(); i != items.end(); i++){
521                 if(forcesize != -1 && index == forcesize)
522                         break;
523                 const std::string &itemstring = *i;
524                 InventoryItem *newitem = NULL;
525                 if(itemstring != "")
526                         newitem = InventoryItem::deSerialize(itemstring,
527                                         gamedef);
528                 InventoryItem *olditem = invlist->changeItem(index, newitem);
529                 delete olditem;
530                 index++;
531         }
532         while(forcesize != -1 && index < forcesize){
533                 InventoryItem *olditem = invlist->changeItem(index, NULL);
534                 delete olditem;
535                 index++;
536         }
537 }
538
539 static void inventory_get_list_to_lua(Inventory *inv, const char *name,
540                 lua_State *L)
541 {
542         InventoryList *invlist = inv->getList(name);
543         if(invlist == NULL){
544                 lua_pushnil(L);
545                 return;
546         }
547         // Get the table insert function
548         lua_getglobal(L, "table");
549         lua_getfield(L, -1, "insert");
550         int table_insert = lua_gettop(L);
551         // Create and fill table
552         lua_newtable(L);
553         int table = lua_gettop(L);
554         for(u32 i=0; i<invlist->getSize(); i++){
555                 InventoryItem *item = invlist->getItem(i);
556                 lua_pushvalue(L, table_insert);
557                 lua_pushvalue(L, table);
558                 if(item == NULL){
559                         lua_pushstring(L, "");
560                 } else {
561                         lua_pushstring(L, item->getItemString().c_str());
562                 }
563                 if(lua_pcall(L, 2, 0, 0))
564                         script_error(L, "error: %s", lua_tostring(L, -1));
565         }
566 }
567
568 static void push_stack_item(lua_State *L, InventoryItem *item0)
569 {
570         if(item0 == NULL){
571                 lua_pushnil(L);
572         }
573         if(std::string("MaterialItem") == item0->getName()){
574                 MaterialItem *item = (MaterialItem*)item0;
575                 lua_newtable(L);
576                 lua_pushstring(L, "NodeItem");
577                 lua_setfield(L, -2, "type");
578                 lua_pushstring(L, item->getNodeName().c_str());
579                 lua_setfield(L, -2, "name");
580         }
581         else if(std::string("CraftItem") == item0->getName()){
582                 CraftItem *item = (CraftItem*)item0;
583                 lua_newtable(L);
584                 lua_pushstring(L, "CraftItem");
585                 lua_setfield(L, -2, "type");
586                 lua_pushstring(L, item->getSubName().c_str());
587                 lua_setfield(L, -2, "name");
588         }
589         else if(std::string("ToolItem") == item0->getName()){
590                 ToolItem *item = (ToolItem*)item0;
591                 lua_newtable(L);
592                 lua_pushstring(L, "ToolItem");
593                 lua_setfield(L, -2, "type");
594                 lua_pushstring(L, item->getToolName().c_str());
595                 lua_setfield(L, -2, "name");
596                 lua_pushstring(L, itos(item->getWear()).c_str());
597                 lua_setfield(L, -2, "wear");
598         }
599         else{
600                 errorstream<<"push_stack_item: Unknown item name: \""
601                                 <<item0->getName()<<"\""<<std::endl;
602                 lua_pushnil(L);
603         }
604 }
605
606 static InventoryItem* check_stack_item(lua_State *L, int index)
607 {
608         if(index < 0)
609                 index = lua_gettop(L) + 1 + index;
610         if(lua_isnil(L, index))
611                 return NULL;
612         if(!lua_istable(L, index))
613                 throw LuaError(L, "check_stack_item: Item not nil or table");
614         // A very crappy implementation for now
615         // Will be replaced when unified namespace for items is made
616         std::string type = getstringfield_default(L, index, "type", "");
617         std::string name = getstringfield_default(L, index, "name", "");
618         std::string num = getstringfield_default(L, index, "wear", "_");
619         if(num == "_")
620                 num = 1;
621         std::string itemstring = type + " \"" + name + "\" " + num;
622         try{
623                 return InventoryItem::deSerialize(itemstring, get_server(L));
624         }catch(SerializationError &e){
625                 throw LuaError(L, std::string("check_stack_item: "
626                                 "internal error (itemstring=\"")+itemstring+"\")");
627         }
628 }
629
630 /*
631         ToolDiggingProperties
632 */
633
634 static ToolDiggingProperties read_tool_digging_properties(
635                 lua_State *L, int table)
636 {
637         ToolDiggingProperties prop;
638         getfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
639         getfloatfield(L, table, "basetime", prop.basetime);
640         getfloatfield(L, table, "dt_weight", prop.dt_weight);
641         getfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
642         getfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
643         getfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
644         getfloatfield(L, table, "basedurability", prop.basedurability);
645         getfloatfield(L, table, "dd_weight", prop.dd_weight);
646         getfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
647         getfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
648         getfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
649         return prop;
650 }
651
652 static void set_tool_digging_properties(lua_State *L, int table,
653                 const ToolDiggingProperties &prop)
654 {
655         setfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
656         setfloatfield(L, table, "basetime", prop.basetime);
657         setfloatfield(L, table, "dt_weight", prop.dt_weight);
658         setfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
659         setfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
660         setfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
661         setfloatfield(L, table, "basedurability", prop.basedurability);
662         setfloatfield(L, table, "dd_weight", prop.dd_weight);
663         setfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
664         setfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
665         setfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
666 }
667
668 static void push_tool_digging_properties(lua_State *L,
669                 const ToolDiggingProperties &prop)
670 {
671         lua_newtable(L);
672         set_tool_digging_properties(L, -1, prop);
673 }
674
675 /*
676         ToolDefinition
677 */
678
679 static ToolDefinition read_tool_definition(lua_State *L, int table)
680 {
681         ToolDefinition def;
682         getstringfield(L, table, "image", def.imagename);
683         def.properties = read_tool_digging_properties(L, table);
684         return def;
685 }
686
687 static void push_tool_definition(lua_State *L, const ToolDefinition &def)
688 {
689         lua_newtable(L);
690         lua_pushstring(L, def.imagename.c_str());
691         lua_setfield(L, -2, "image");
692         set_tool_digging_properties(L, -1, def.properties);
693 }
694
695 /*
696         EnumString definitions
697 */
698
699 struct EnumString es_DrawType[] =
700 {
701         {NDT_NORMAL, "normal"},
702         {NDT_AIRLIKE, "airlike"},
703         {NDT_LIQUID, "liquid"},
704         {NDT_FLOWINGLIQUID, "flowingliquid"},
705         {NDT_GLASSLIKE, "glasslike"},
706         {NDT_ALLFACES, "allfaces"},
707         {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
708         {NDT_TORCHLIKE, "torchlike"},
709         {NDT_SIGNLIKE, "signlike"},
710         {NDT_PLANTLIKE, "plantlike"},
711         {NDT_FENCELIKE, "fencelike"},
712         {NDT_RAILLIKE, "raillike"},
713         {0, NULL},
714 };
715
716 struct EnumString es_ContentParamType[] =
717 {
718         {CPT_NONE, "none"},
719         {CPT_LIGHT, "light"},
720         {CPT_MINERAL, "mineral"},
721         {CPT_FACEDIR_SIMPLE, "facedir_simple"},
722         {0, NULL},
723 };
724
725 struct EnumString es_LiquidType[] =
726 {
727         {LIQUID_NONE, "none"},
728         {LIQUID_FLOWING, "flowing"},
729         {LIQUID_SOURCE, "source"},
730         {0, NULL},
731 };
732
733 struct EnumString es_NodeBoxType[] =
734 {
735         {NODEBOX_REGULAR, "regular"},
736         {NODEBOX_FIXED, "fixed"},
737         {NODEBOX_WALLMOUNTED, "wallmounted"},
738         {0, NULL},
739 };
740
741 struct EnumString es_Diggability[] =
742 {
743         {DIGGABLE_NOT, "not"},
744         {DIGGABLE_NORMAL, "normal"},
745         {DIGGABLE_CONSTANT, "constant"},
746         {0, NULL},
747 };
748
749 /*
750         Global functions
751 */
752
753 static int l_register_nodedef_defaults(lua_State *L)
754 {
755         luaL_checktype(L, 1, LUA_TTABLE);
756
757         lua_pushvalue(L, 1); // Explicitly put parameter 1 on top of stack
758         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
759
760         return 0;
761 }
762
763 // Register new object prototype
764 // register_entity(name, prototype)
765 static int l_register_entity(lua_State *L)
766 {
767         std::string name = luaL_checkstring(L, 1);
768         check_modname_prefix(L, name);
769         //infostream<<"register_entity: "<<name<<std::endl;
770         luaL_checktype(L, 2, LUA_TTABLE);
771
772         // Get minetest.registered_entities
773         lua_getglobal(L, "minetest");
774         lua_getfield(L, -1, "registered_entities");
775         luaL_checktype(L, -1, LUA_TTABLE);
776         int registered_entities = lua_gettop(L);
777         lua_pushvalue(L, 2); // Object = param 2 -> stack top
778         // registered_entities[name] = object
779         lua_setfield(L, registered_entities, name.c_str());
780         
781         // Get registered object to top of stack
782         lua_pushvalue(L, 2);
783         
784         // Set __index to point to itself
785         lua_pushvalue(L, -1);
786         lua_setfield(L, -2, "__index");
787
788         // Set metatable.__index = metatable
789         luaL_getmetatable(L, "minetest.entity");
790         lua_pushvalue(L, -1); // duplicate metatable
791         lua_setfield(L, -2, "__index");
792         // Set object metatable
793         lua_setmetatable(L, -2);
794
795         return 0; /* number of results */
796 }
797
798 class LuaABM : public ActiveBlockModifier
799 {
800 private:
801         lua_State *m_lua;
802         int m_id;
803
804         std::set<std::string> m_trigger_contents;
805         std::set<std::string> m_required_neighbors;
806         float m_trigger_interval;
807         u32 m_trigger_chance;
808 public:
809         LuaABM(lua_State *L, int id,
810                         const std::set<std::string> &trigger_contents,
811                         const std::set<std::string> &required_neighbors,
812                         float trigger_interval, u32 trigger_chance):
813                 m_lua(L),
814                 m_id(id),
815                 m_trigger_contents(trigger_contents),
816                 m_required_neighbors(required_neighbors),
817                 m_trigger_interval(trigger_interval),
818                 m_trigger_chance(trigger_chance)
819         {
820         }
821         virtual std::set<std::string> getTriggerContents()
822         {
823                 return m_trigger_contents;
824         }
825         virtual std::set<std::string> getRequiredNeighbors()
826         {
827                 return m_required_neighbors;
828         }
829         virtual float getTriggerInterval()
830         {
831                 return m_trigger_interval;
832         }
833         virtual u32 getTriggerChance()
834         {
835                 return m_trigger_chance;
836         }
837         virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
838                         u32 active_object_count, u32 active_object_count_wider)
839         {
840                 lua_State *L = m_lua;
841         
842                 realitycheck(L);
843                 assert(lua_checkstack(L, 20));
844                 StackUnroller stack_unroller(L);
845
846                 // Get minetest.registered_abms
847                 lua_getglobal(L, "minetest");
848                 lua_getfield(L, -1, "registered_abms");
849                 luaL_checktype(L, -1, LUA_TTABLE);
850                 int registered_abms = lua_gettop(L);
851
852                 // Get minetest.registered_abms[m_id]
853                 lua_pushnumber(L, m_id);
854                 lua_gettable(L, registered_abms);
855                 if(lua_isnil(L, -1))
856                         assert(0);
857                 
858                 // Call action
859                 luaL_checktype(L, -1, LUA_TTABLE);
860                 lua_getfield(L, -1, "action");
861                 luaL_checktype(L, -1, LUA_TFUNCTION);
862                 pushpos(L, p);
863                 pushnode(L, n, env->getGameDef()->ndef());
864                 lua_pushnumber(L, active_object_count);
865                 lua_pushnumber(L, active_object_count_wider);
866                 if(lua_pcall(L, 4, 0, 0))
867                         script_error(L, "error: %s", lua_tostring(L, -1));
868         }
869 };
870
871 // register_abm({...})
872 static int l_register_abm(lua_State *L)
873 {
874         //infostream<<"register_abm"<<std::endl;
875         luaL_checktype(L, 1, LUA_TTABLE);
876
877         // Get minetest.registered_abms
878         lua_getglobal(L, "minetest");
879         lua_getfield(L, -1, "registered_abms");
880         luaL_checktype(L, -1, LUA_TTABLE);
881         int registered_abms = lua_gettop(L);
882
883         int id = 1;
884         // Find free id
885         for(;;){
886                 lua_pushnumber(L, id);
887                 lua_gettable(L, registered_abms);
888                 if(lua_isnil(L, -1))
889                         break;
890                 lua_pop(L, 1);
891                 id++;
892         }
893         lua_pop(L, 1);
894
895         infostream<<"register_abm: id="<<id<<std::endl;
896
897         // registered_abms[id] = spec
898         lua_pushnumber(L, id);
899         lua_pushvalue(L, 1);
900         lua_settable(L, registered_abms);
901         
902         return 0; /* number of results */
903 }
904
905 // register_tool(name, {lots of stuff})
906 static int l_register_tool(lua_State *L)
907 {
908         std::string name = luaL_checkstring(L, 1);
909         check_modname_prefix(L, name);
910         //infostream<<"register_tool: "<<name<<std::endl;
911         luaL_checktype(L, 2, LUA_TTABLE);
912         int table = 2;
913
914         // Get the writable tool definition manager from the server
915         IWritableToolDefManager *tooldef =
916                         get_server(L)->getWritableToolDefManager();
917         
918         ToolDefinition def = read_tool_definition(L, table);
919
920         tooldef->registerTool(name, def);
921         return 0; /* number of results */
922 }
923
924 // register_craftitem(name, {lots of stuff})
925 static int l_register_craftitem(lua_State *L)
926 {
927         std::string name = luaL_checkstring(L, 1);
928         check_modname_prefix(L, name);
929         //infostream<<"register_craftitem: "<<name<<std::endl;
930         luaL_checktype(L, 2, LUA_TTABLE);
931         int table = 2;
932
933         // Get the writable CraftItem definition manager from the server
934         IWritableCraftItemDefManager *craftitemdef =
935                         get_server(L)->getWritableCraftItemDefManager();
936         
937         // Check if on_drop is defined
938         lua_getfield(L, table, "on_drop");
939         bool got_on_drop = !lua_isnil(L, -1);
940         lua_pop(L, 1);
941
942         // Check if on_use is defined
943         lua_getfield(L, table, "on_use");
944         bool got_on_use = !lua_isnil(L, -1);
945         lua_pop(L, 1);
946
947         CraftItemDefinition def;
948         
949         getstringfield(L, table, "image", def.imagename);
950         getstringfield(L, table, "cookresult_itemstring", def.cookresult_item);
951         getfloatfield(L, table, "furnace_cooktime", def.furnace_cooktime);
952         getfloatfield(L, table, "furnace_burntime", def.furnace_burntime);
953         def.usable = getboolfield_default(L, table, "usable", got_on_use);
954         getboolfield(L, table, "liquids_pointable", def.liquids_pointable);
955         def.dropcount = getintfield_default(L, table, "dropcount", def.dropcount);
956         def.stack_max = getintfield_default(L, table, "stack_max", def.stack_max);
957
958         // If an on_drop callback is defined, force dropcount to 1
959         if (got_on_drop)
960                 def.dropcount = 1;
961
962         // Register it
963         craftitemdef->registerCraftItem(name, def);
964
965         lua_pushvalue(L, table);
966         scriptapi_add_craftitem(L, name.c_str());
967
968         return 0; /* number of results */
969 }
970
971 // register_node(name, {lots of stuff})
972 static int l_register_node(lua_State *L)
973 {
974         std::string name = luaL_checkstring(L, 1);
975         check_modname_prefix(L, name);
976         //infostream<<"register_node: "<<name<<std::endl;
977         luaL_checktype(L, 2, LUA_TTABLE);
978         int nodedef_table = 2;
979
980         // Get the writable node definition manager from the server
981         IWritableNodeDefManager *nodedef =
982                         get_server(L)->getWritableNodeDefManager();
983         
984         // Get default node definition from registry
985         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
986         int nodedef_default = lua_gettop(L);
987
988         /*
989                 Add to minetest.registered_nodes with default as metatable
990         */
991         
992         // Get the node definition table given as parameter
993         lua_pushvalue(L, nodedef_table);
994
995         // Set __index to point to itself
996         lua_pushvalue(L, -1);
997         lua_setfield(L, -2, "__index");
998
999         // Set nodedef_default as metatable for the definition
1000         lua_pushvalue(L, nodedef_default);
1001         lua_setmetatable(L, nodedef_table);
1002         
1003         // minetest.registered_nodes[name] = nodedef
1004         lua_getglobal(L, "minetest");
1005         lua_getfield(L, -1, "registered_nodes");
1006         luaL_checktype(L, -1, LUA_TTABLE);
1007         lua_pushstring(L, name.c_str());
1008         lua_pushvalue(L, nodedef_table);
1009         lua_settable(L, -3);
1010
1011         /*
1012                 Create definition
1013         */
1014         
1015         ContentFeatures f;
1016
1017         // Default to getting the corresponding NodeItem when dug
1018         f.dug_item = std::string("NodeItem \"")+name+"\" 1";
1019         
1020         // Default to unknown_block.png as all textures
1021         f.setAllTextures("unknown_block.png");
1022
1023         /*
1024                 Read definiton from Lua
1025         */
1026
1027         f.name = name;
1028         
1029         /* Visual definition */
1030
1031         f.drawtype = (NodeDrawType)getenumfield(L, nodedef_table, "drawtype", es_DrawType,
1032                         NDT_NORMAL);
1033         getfloatfield(L, nodedef_table, "visual_scale", f.visual_scale);
1034
1035         lua_getfield(L, nodedef_table, "tile_images");
1036         if(lua_istable(L, -1)){
1037                 int table = lua_gettop(L);
1038                 lua_pushnil(L);
1039                 int i = 0;
1040                 while(lua_next(L, table) != 0){
1041                         // key at index -2 and value at index -1
1042                         if(lua_isstring(L, -1))
1043                                 f.tname_tiles[i] = lua_tostring(L, -1);
1044                         else
1045                                 f.tname_tiles[i] = "";
1046                         // removes value, keeps key for next iteration
1047                         lua_pop(L, 1);
1048                         i++;
1049                         if(i==6){
1050                                 lua_pop(L, 1);
1051                                 break;
1052                         }
1053                 }
1054                 // Copy last value to all remaining textures
1055                 if(i >= 1){
1056                         std::string lastname = f.tname_tiles[i-1];
1057                         while(i < 6){
1058                                 f.tname_tiles[i] = lastname;
1059                                 i++;
1060                         }
1061                 }
1062         }
1063         lua_pop(L, 1);
1064
1065         getstringfield(L, nodedef_table, "inventory_image", f.tname_inventory);
1066
1067         lua_getfield(L, nodedef_table, "special_materials");
1068         if(lua_istable(L, -1)){
1069                 int table = lua_gettop(L);
1070                 lua_pushnil(L);
1071                 int i = 0;
1072                 while(lua_next(L, table) != 0){
1073                         // key at index -2 and value at index -1
1074                         int smtable = lua_gettop(L);
1075                         std::string tname = getstringfield_default(
1076                                         L, smtable, "image", "");
1077                         bool backface_culling = getboolfield_default(
1078                                         L, smtable, "backface_culling", true);
1079                         MaterialSpec mspec(tname, backface_culling);
1080                         f.setSpecialMaterial(i, mspec);
1081                         // removes value, keeps key for next iteration
1082                         lua_pop(L, 1);
1083                         i++;
1084                         if(i==6){
1085                                 lua_pop(L, 1);
1086                                 break;
1087                         }
1088                 }
1089         }
1090         lua_pop(L, 1);
1091
1092         f.alpha = getintfield_default(L, nodedef_table, "alpha", 255);
1093
1094         /* Other stuff */
1095         
1096         lua_getfield(L, nodedef_table, "post_effect_color");
1097         if(!lua_isnil(L, -1))
1098                 f.post_effect_color = readARGB8(L, -1);
1099         lua_pop(L, 1);
1100
1101         f.param_type = (ContentParamType)getenumfield(L, nodedef_table, "paramtype",
1102                         es_ContentParamType, CPT_NONE);
1103         
1104         // True for all ground-like things like stone and mud, false for eg. trees
1105         getboolfield(L, nodedef_table, "is_ground_content", f.is_ground_content);
1106         f.light_propagates = (f.param_type == CPT_LIGHT);
1107         warn_if_field_exists(L, nodedef_table, "light_propagates",
1108                         "deprecated: determined from paramtype");
1109         getboolfield(L, nodedef_table, "sunlight_propagates", f.sunlight_propagates);
1110         // This is used for collision detection.
1111         // Also for general solidness queries.
1112         getboolfield(L, nodedef_table, "walkable", f.walkable);
1113         // Player can point to these
1114         getboolfield(L, nodedef_table, "pointable", f.pointable);
1115         // Player can dig these
1116         getboolfield(L, nodedef_table, "diggable", f.diggable);
1117         // Player can climb these
1118         getboolfield(L, nodedef_table, "climbable", f.climbable);
1119         // Player can build on these
1120         getboolfield(L, nodedef_table, "buildable_to", f.buildable_to);
1121         // If true, param2 is set to direction when placed. Used for torches.
1122         // NOTE: the direction format is quite inefficient and should be changed
1123         getboolfield(L, nodedef_table, "wall_mounted", f.wall_mounted);
1124         // Whether this content type often contains mineral.
1125         // Used for texture atlas creation.
1126         // Currently only enabled for CONTENT_STONE.
1127         getboolfield(L, nodedef_table, "often_contains_mineral", f.often_contains_mineral);
1128         // Inventory item string as which the node appears in inventory when dug.
1129         // Mineral overrides this.
1130         getstringfield(L, nodedef_table, "dug_item", f.dug_item);
1131         // Extra dug item and its rarity
1132         getstringfield(L, nodedef_table, "extra_dug_item", f.extra_dug_item);
1133         // Usual get interval for extra dug item
1134         getintfield(L, nodedef_table, "extra_dug_item_rarity", f.extra_dug_item_rarity);
1135         // Metadata name of node (eg. "furnace")
1136         getstringfield(L, nodedef_table, "metadata_name", f.metadata_name);
1137         // Whether the node is non-liquid, source liquid or flowing liquid
1138         f.liquid_type = (LiquidType)getenumfield(L, nodedef_table, "liquidtype",
1139                         es_LiquidType, LIQUID_NONE);
1140         // If the content is liquid, this is the flowing version of the liquid.
1141         getstringfield(L, nodedef_table, "liquid_alternative_flowing",
1142                         f.liquid_alternative_flowing);
1143         // If the content is liquid, this is the source version of the liquid.
1144         getstringfield(L, nodedef_table, "liquid_alternative_source",
1145                         f.liquid_alternative_source);
1146         // Viscosity for fluid flow, ranging from 1 to 7, with
1147         // 1 giving almost instantaneous propagation and 7 being
1148         // the slowest possible
1149         f.liquid_viscosity = getintfield_default(L, nodedef_table,
1150                         "liquid_viscosity", f.liquid_viscosity);
1151         // Amount of light the node emits
1152         f.light_source = getintfield_default(L, nodedef_table,
1153                         "light_source", f.light_source);
1154         f.damage_per_second = getintfield_default(L, nodedef_table,
1155                         "damage_per_second", f.damage_per_second);
1156         
1157         lua_getfield(L, nodedef_table, "selection_box");
1158         if(lua_istable(L, -1)){
1159                 f.selection_box.type = (NodeBoxType)getenumfield(L, -1, "type",
1160                                 es_NodeBoxType, NODEBOX_REGULAR);
1161
1162                 lua_getfield(L, -1, "fixed");
1163                 if(lua_istable(L, -1))
1164                         f.selection_box.fixed = read_aabbox3df32(L, -1, BS);
1165                 lua_pop(L, 1);
1166
1167                 lua_getfield(L, -1, "wall_top");
1168                 if(lua_istable(L, -1))
1169                         f.selection_box.wall_top = read_aabbox3df32(L, -1, BS);
1170                 lua_pop(L, 1);
1171
1172                 lua_getfield(L, -1, "wall_bottom");
1173                 if(lua_istable(L, -1))
1174                         f.selection_box.wall_bottom = read_aabbox3df32(L, -1, BS);
1175                 lua_pop(L, 1);
1176
1177                 lua_getfield(L, -1, "wall_side");
1178                 if(lua_istable(L, -1))
1179                         f.selection_box.wall_side = read_aabbox3df32(L, -1, BS);
1180                 lua_pop(L, 1);
1181         }
1182         lua_pop(L, 1);
1183
1184         lua_getfield(L, nodedef_table, "material");
1185         if(lua_istable(L, -1)){
1186                 f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
1187                                 es_Diggability, DIGGABLE_NORMAL);
1188                 
1189                 getfloatfield(L, -1, "constant_time", f.material.constant_time);
1190                 getfloatfield(L, -1, "weight", f.material.weight);
1191                 getfloatfield(L, -1, "crackiness", f.material.crackiness);
1192                 getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
1193                 getfloatfield(L, -1, "cuttability", f.material.cuttability);
1194                 getfloatfield(L, -1, "flammability", f.material.flammability);
1195         }
1196         lua_pop(L, 1);
1197
1198         getstringfield(L, nodedef_table, "cookresult_itemstring", f.cookresult_item);
1199         getfloatfield(L, nodedef_table, "furnace_cooktime", f.furnace_cooktime);
1200         getfloatfield(L, nodedef_table, "furnace_burntime", f.furnace_burntime);
1201         
1202         /*
1203                 Register it
1204         */
1205         
1206         nodedef->set(name, f);
1207         
1208         return 0; /* number of results */
1209 }
1210
1211 // alias_node(name, convert_to_name)
1212 static int l_alias_node(lua_State *L)
1213 {
1214         std::string name = luaL_checkstring(L, 1);
1215         std::string convert_to = luaL_checkstring(L, 2);
1216
1217         // Get the writable node definition manager from the server
1218         IWritableNodeDefManager *nodedef =
1219                         get_server(L)->getWritableNodeDefManager();
1220         
1221         nodedef->setAlias(name, convert_to);
1222         
1223         return 0; /* number of results */
1224 }
1225
1226 // alias_tool(name, convert_to_name)
1227 static int l_alias_tool(lua_State *L)
1228 {
1229         std::string name = luaL_checkstring(L, 1);
1230         std::string convert_to = luaL_checkstring(L, 2);
1231
1232         // Get the writable tool definition manager from the server
1233         IWritableToolDefManager *tooldef =
1234                         get_server(L)->getWritableToolDefManager();
1235         
1236         tooldef->setAlias(name, convert_to);
1237
1238         return 0; /* number of results */
1239 }
1240
1241 // alias_craftitem(name, convert_to_name)
1242 static int l_alias_craftitem(lua_State *L)
1243 {
1244         std::string name = luaL_checkstring(L, 1);
1245         std::string convert_to = luaL_checkstring(L, 2);
1246
1247         // Get the writable CraftItem definition manager from the server
1248         IWritableCraftItemDefManager *craftitemdef =
1249                         get_server(L)->getWritableCraftItemDefManager();
1250         
1251         craftitemdef->setAlias(name, convert_to);
1252
1253         return 0; /* number of results */
1254 }
1255
1256 // register_craft({output=item, recipe={{item00,item10},{item01,item11}})
1257 static int l_register_craft(lua_State *L)
1258 {
1259         //infostream<<"register_craft"<<std::endl;
1260         luaL_checktype(L, 1, LUA_TTABLE);
1261         int table0 = 1;
1262
1263         // Get the writable craft definition manager from the server
1264         IWritableCraftDefManager *craftdef =
1265                         get_server(L)->getWritableCraftDefManager();
1266         
1267         std::string output;
1268         int width = 0;
1269         std::vector<std::string> input;
1270
1271         lua_getfield(L, table0, "output");
1272         luaL_checktype(L, -1, LUA_TSTRING);
1273         if(lua_isstring(L, -1))
1274                 output = lua_tostring(L, -1);
1275         lua_pop(L, 1);
1276
1277         lua_getfield(L, table0, "recipe");
1278         luaL_checktype(L, -1, LUA_TTABLE);
1279         if(lua_istable(L, -1)){
1280                 int table1 = lua_gettop(L);
1281                 lua_pushnil(L);
1282                 int rowcount = 0;
1283                 while(lua_next(L, table1) != 0){
1284                         int colcount = 0;
1285                         // key at index -2 and value at index -1
1286                         luaL_checktype(L, -1, LUA_TTABLE);
1287                         if(lua_istable(L, -1)){
1288                                 int table2 = lua_gettop(L);
1289                                 lua_pushnil(L);
1290                                 while(lua_next(L, table2) != 0){
1291                                         // key at index -2 and value at index -1
1292                                         luaL_checktype(L, -1, LUA_TSTRING);
1293                                         input.push_back(lua_tostring(L, -1));
1294                                         // removes value, keeps key for next iteration
1295                                         lua_pop(L, 1);
1296                                         colcount++;
1297                                 }
1298                         }
1299                         if(rowcount == 0){
1300                                 width = colcount;
1301                         } else {
1302                                 if(colcount != width){
1303                                         std::string error;
1304                                         error += "Invalid crafting recipe (output=\""
1305                                                         + output + "\")";
1306                                         throw LuaError(L, error);
1307                                 }
1308                         }
1309                         // removes value, keeps key for next iteration
1310                         lua_pop(L, 1);
1311                         rowcount++;
1312                 }
1313         }
1314         lua_pop(L, 1);
1315
1316         CraftDefinition def(output, width, input);
1317         craftdef->registerCraft(def);
1318
1319         return 0; /* number of results */
1320 }
1321
1322 // setting_get(name)
1323 static int l_setting_get(lua_State *L)
1324 {
1325         const char *name = luaL_checkstring(L, 1);
1326         try{
1327                 std::string value = g_settings->get(name);
1328                 lua_pushstring(L, value.c_str());
1329         } catch(SettingNotFoundException &e){
1330                 lua_pushnil(L);
1331         }
1332         return 1;
1333 }
1334
1335 // setting_getbool(name)
1336 static int l_setting_getbool(lua_State *L)
1337 {
1338         const char *name = luaL_checkstring(L, 1);
1339         try{
1340                 bool value = g_settings->getBool(name);
1341                 lua_pushboolean(L, value);
1342         } catch(SettingNotFoundException &e){
1343                 lua_pushnil(L);
1344         }
1345         return 1;
1346 }
1347
1348 // chat_send_all(text)
1349 static int l_chat_send_all(lua_State *L)
1350 {
1351         const char *text = luaL_checkstring(L, 1);
1352         // Get server from registry
1353         Server *server = get_server(L);
1354         // Send
1355         server->notifyPlayers(narrow_to_wide(text));
1356         return 0;
1357 }
1358
1359 // chat_send_player(name, text)
1360 static int l_chat_send_player(lua_State *L)
1361 {
1362         const char *name = luaL_checkstring(L, 1);
1363         const char *text = luaL_checkstring(L, 2);
1364         // Get server from registry
1365         Server *server = get_server(L);
1366         // Send
1367         server->notifyPlayer(name, narrow_to_wide(text));
1368         return 0;
1369 }
1370
1371 // get_player_privs(name, text)
1372 static int l_get_player_privs(lua_State *L)
1373 {
1374         const char *name = luaL_checkstring(L, 1);
1375         // Get server from registry
1376         Server *server = get_server(L);
1377         // Do it
1378         lua_newtable(L);
1379         int table = lua_gettop(L);
1380         u64 privs_i = server->getPlayerAuthPrivs(name);
1381         // Special case for the "name" setting (local player / server owner)
1382         if(name == g_settings->get("name"))
1383                 privs_i = PRIV_ALL;
1384         std::set<std::string> privs_s = privsToSet(privs_i);
1385         for(std::set<std::string>::const_iterator
1386                         i = privs_s.begin(); i != privs_s.end(); i++){
1387                 lua_pushboolean(L, true);
1388                 lua_setfield(L, table, i->c_str());
1389         }
1390         lua_pushvalue(L, table);
1391         return 1;
1392 }
1393
1394 // get_modpath(modname)
1395 static int l_get_modpath(lua_State *L)
1396 {
1397         const char *modname = luaL_checkstring(L, 1);
1398         // Get server from registry
1399         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
1400         Server *server = (Server*)lua_touserdata(L, -1);
1401         // Do it
1402         const ModSpec *mod = server->getModSpec(modname);
1403         if(!mod){
1404                 lua_pushnil(L);
1405                 return 1;
1406         }
1407         lua_pushstring(L, mod->path.c_str());
1408         return 1;
1409 }
1410
1411 static const struct luaL_Reg minetest_f [] = {
1412         {"register_nodedef_defaults", l_register_nodedef_defaults},
1413         {"register_entity", l_register_entity},
1414         {"register_tool", l_register_tool},
1415         {"register_craftitem", l_register_craftitem},
1416         {"register_node", l_register_node},
1417         {"register_craft", l_register_craft},
1418         {"register_abm", l_register_abm},
1419         {"alias_node", l_alias_node},
1420         {"alias_tool", l_alias_tool},
1421         {"alias_craftitem", l_alias_craftitem},
1422         {"setting_get", l_setting_get},
1423         {"setting_getbool", l_setting_getbool},
1424         {"chat_send_all", l_chat_send_all},
1425         {"chat_send_player", l_chat_send_player},
1426         {"get_player_privs", l_get_player_privs},
1427         {"get_modpath", l_get_modpath},
1428         {NULL, NULL}
1429 };
1430
1431 /*
1432         LuaEntity functions
1433 */
1434
1435 static const struct luaL_Reg minetest_entity_m [] = {
1436         {NULL, NULL}
1437 };
1438
1439 /*
1440         Getters for stuff in main tables
1441 */
1442
1443 static void objectref_get(lua_State *L, u16 id)
1444 {
1445         // Get minetest.object_refs[i]
1446         lua_getglobal(L, "minetest");
1447         lua_getfield(L, -1, "object_refs");
1448         luaL_checktype(L, -1, LUA_TTABLE);
1449         lua_pushnumber(L, id);
1450         lua_gettable(L, -2);
1451         lua_remove(L, -2); // object_refs
1452         lua_remove(L, -2); // minetest
1453 }
1454
1455 static void luaentity_get(lua_State *L, u16 id)
1456 {
1457         // Get minetest.luaentities[i]
1458         lua_getglobal(L, "minetest");
1459         lua_getfield(L, -1, "luaentities");
1460         luaL_checktype(L, -1, LUA_TTABLE);
1461         lua_pushnumber(L, id);
1462         lua_gettable(L, -2);
1463         lua_remove(L, -2); // luaentities
1464         lua_remove(L, -2); // minetest
1465 }
1466
1467 /*
1468         Object wrappers
1469 */
1470
1471 #define method(class, name) {#name, class::l_##name}
1472
1473 /*
1474         InvStack
1475 */
1476
1477 class InvStack
1478 {
1479 private:
1480         InventoryItem *m_stack;
1481
1482         static const char className[];
1483         static const luaL_reg methods[];
1484
1485         // Exported functions
1486         
1487         // garbage collector
1488         static int gc_object(lua_State *L) {
1489                 InvStack *o = *(InvStack **)(lua_touserdata(L, 1));
1490                 delete o;
1491                 return 0;
1492         }
1493
1494         // take_item(self)
1495         static int l_take_item(lua_State *L)
1496         {
1497                 InvStack *o = checkobject(L, 1);
1498                 push_stack_item(L, o->m_stack);
1499                 if(o->m_stack->getCount() == 1){
1500                         delete o->m_stack;
1501                         o->m_stack = NULL;
1502                 } else {
1503                         o->m_stack->remove(1);
1504                 }
1505                 return 1;
1506         }
1507
1508         // put_item(self, item) -> true/false
1509         static int l_put_item(lua_State *L)
1510         {
1511                 InvStack *o = checkobject(L, 1);
1512                 InventoryItem *item = check_stack_item(L, 2);
1513                 if(!item){ // nil can always be inserted
1514                         lua_pushboolean(L, true);
1515                         return 1;
1516                 }
1517                 if(!item->addableTo(o->m_stack)){
1518                         lua_pushboolean(L, false);
1519                         return 1;
1520                 }
1521                 o->m_stack->add(1);
1522                 delete item;
1523                 lua_pushboolean(L, true);
1524                 return 1;
1525         }
1526
1527 public:
1528         InvStack(InventoryItem *item=NULL):
1529                 m_stack(item)
1530         {
1531         }
1532
1533         ~InvStack()
1534         {
1535                 delete m_stack;
1536         }
1537
1538         static InvStack* checkobject(lua_State *L, int narg)
1539         {
1540                 luaL_checktype(L, narg, LUA_TUSERDATA);
1541                 void *ud = luaL_checkudata(L, narg, className);
1542                 if(!ud) luaL_typerror(L, narg, className);
1543                 return *(InvStack**)ud;  // unbox pointer
1544         }
1545
1546         InventoryItem* getItemCopy()
1547         {
1548                 if(!m_stack)
1549                         return NULL;
1550                 return m_stack->clone();
1551         }
1552         
1553         // Creates an InvStack and leaves it on top of stack
1554         static int create_object(lua_State *L)
1555         {
1556                 InventoryItem *item = NULL;
1557                 if(lua_isstring(L, 1)){
1558                         std::string itemstring = lua_tostring(L, 1);
1559                         if(itemstring != ""){
1560                                 try{
1561                                         IGameDef *gdef = get_server(L);
1562                                         item = InventoryItem::deSerialize(itemstring, gdef);
1563                                 }catch(SerializationError &e){
1564                                 }
1565                         }
1566                 }
1567                 InvStack *o = new InvStack(item);
1568                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1569                 luaL_getmetatable(L, className);
1570                 lua_setmetatable(L, -2);
1571                 return 1;
1572         }
1573         // Not callable from Lua
1574         static int create(lua_State *L, InventoryItem *item)
1575         {
1576                 InvStack *o = new InvStack(item);
1577                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1578                 luaL_getmetatable(L, className);
1579                 lua_setmetatable(L, -2);
1580                 return 1;
1581         }
1582
1583         static void Register(lua_State *L)
1584         {
1585                 lua_newtable(L);
1586                 int methodtable = lua_gettop(L);
1587                 luaL_newmetatable(L, className);
1588                 int metatable = lua_gettop(L);
1589
1590                 lua_pushliteral(L, "__metatable");
1591                 lua_pushvalue(L, methodtable);
1592                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
1593
1594                 lua_pushliteral(L, "__index");
1595                 lua_pushvalue(L, methodtable);
1596                 lua_settable(L, metatable);
1597
1598                 lua_pushliteral(L, "__gc");
1599                 lua_pushcfunction(L, gc_object);
1600                 lua_settable(L, metatable);
1601
1602                 lua_pop(L, 1);  // drop metatable
1603
1604                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
1605                 lua_pop(L, 1);  // drop methodtable
1606
1607                 // Can be created from Lua (InvStack::create(itemstring))
1608                 lua_register(L, className, create_object);
1609         }
1610 };
1611 const char InvStack::className[] = "InvStack";
1612 const luaL_reg InvStack::methods[] = {
1613         method(InvStack, take_item),
1614         method(InvStack, put_item),
1615         {0,0}
1616 };
1617
1618 /*
1619         InvRef
1620 */
1621
1622 class InvRef
1623 {
1624 private:
1625         InventoryLocation m_loc;
1626
1627         static const char className[];
1628         static const luaL_reg methods[];
1629
1630         static InvRef *checkobject(lua_State *L, int narg)
1631         {
1632                 luaL_checktype(L, narg, LUA_TUSERDATA);
1633                 void *ud = luaL_checkudata(L, narg, className);
1634                 if(!ud) luaL_typerror(L, narg, className);
1635                 return *(InvRef**)ud;  // unbox pointer
1636         }
1637         
1638         static Inventory* getinv(lua_State *L, InvRef *ref)
1639         {
1640                 return get_server(L)->getInventory(ref->m_loc);
1641         }
1642
1643         static InventoryList* getlist(lua_State *L, InvRef *ref,
1644                         const char *listname)
1645         {
1646                 Inventory *inv = getinv(L, ref);
1647                 if(!inv)
1648                         return NULL;
1649                 return inv->getList(listname);
1650         }
1651
1652         static InventoryItem* getitem(lua_State *L, InvRef *ref,
1653                         const char *listname, int i)
1654         {
1655                 InventoryList *list = getlist(L, ref, listname);
1656                 if(!list)
1657                         return NULL;
1658                 return list->getItem(i);
1659         }
1660
1661         static void reportInventoryChange(lua_State *L, InvRef *ref)
1662         {
1663                 // Inform other things that the inventory has changed
1664                 get_server(L)->setInventoryModified(ref->m_loc);
1665         }
1666         
1667         // Exported functions
1668         
1669         // garbage collector
1670         static int gc_object(lua_State *L) {
1671                 InvRef *o = *(InvRef **)(lua_touserdata(L, 1));
1672                 delete o;
1673                 return 0;
1674         }
1675
1676         // set_size(self, listname, size)
1677         static int l_set_size(lua_State *L)
1678         {
1679                 InvRef *ref = checkobject(L, 1);
1680                 const char *listname = luaL_checkstring(L, 2);
1681                 int newsize = luaL_checknumber(L, 3);
1682                 Inventory *inv = getinv(L, ref);
1683                 if(newsize == 0){
1684                         inv->deleteList(listname);
1685                         return 0;
1686                 }
1687                 InventoryList *list = inv->getList(listname);
1688                 if(list){
1689                         list->setSize(newsize);
1690                 } else {
1691                         list = inv->addList(listname, newsize);
1692                 }
1693                 return 0;
1694         }
1695
1696         // get_stack(self, listname, i)
1697         static int l_get_stack(lua_State *L)
1698         {
1699                 InvRef *ref = checkobject(L, 1);
1700                 const char *listname = luaL_checkstring(L, 2);
1701                 int i = luaL_checknumber(L, 3);
1702                 InventoryItem *item = getitem(L, ref, listname, i);
1703                 if(!item){
1704                         InvStack::create(L, NULL);
1705                         return 1;
1706                 }
1707                 InvStack::create(L, item->clone());
1708                 return 1;
1709         }
1710
1711         // set_stack(self, listname, i, stack)
1712         static int l_set_stack(lua_State *L)
1713         {
1714                 InvRef *ref = checkobject(L, 1);
1715                 const char *listname = luaL_checkstring(L, 2);
1716                 int i = luaL_checknumber(L, 3);
1717                 InvStack *stack = InvStack::checkobject(L, 4);
1718                 InventoryList *list = getlist(L, ref, listname);
1719                 if(!list){
1720                         lua_pushboolean(L, false);
1721                         return 1;
1722                 }
1723                 InventoryItem *newitem = stack->getItemCopy();
1724                 InventoryItem *olditem = list->changeItem(i, newitem);
1725                 bool success = (olditem != newitem);
1726                 delete olditem;
1727                 lua_pushboolean(L, success);
1728                 return 1;
1729         }
1730
1731 public:
1732         InvRef(const InventoryLocation &loc):
1733                 m_loc(loc)
1734         {
1735         }
1736
1737         ~InvRef()
1738         {
1739         }
1740
1741         // Creates an InvRef and leaves it on top of stack
1742         // Not callable from Lua; all references are created on the C side.
1743         static void create(lua_State *L, const InventoryLocation &loc)
1744         {
1745                 InvRef *o = new InvRef(loc);
1746                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
1747                 luaL_getmetatable(L, className);
1748                 lua_setmetatable(L, -2);
1749         }
1750         static void createPlayer(lua_State *L, Player *player)
1751         {
1752                 InventoryLocation loc;
1753                 loc.setPlayer(player->getName());
1754                 create(L, loc);
1755         }
1756         static void createNodeMeta(lua_State *L, v3s16 p)
1757         {
1758                 InventoryLocation loc;
1759                 loc.setNodeMeta(p);
1760                 create(L, loc);
1761         }
1762
1763         static void Register(lua_State *L)
1764         {
1765                 lua_newtable(L);
1766                 int methodtable = lua_gettop(L);
1767                 luaL_newmetatable(L, className);
1768                 int metatable = lua_gettop(L);
1769
1770                 lua_pushliteral(L, "__metatable");
1771                 lua_pushvalue(L, methodtable);
1772                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
1773
1774                 lua_pushliteral(L, "__index");
1775                 lua_pushvalue(L, methodtable);
1776                 lua_settable(L, metatable);
1777
1778                 lua_pushliteral(L, "__gc");
1779                 lua_pushcfunction(L, gc_object);
1780                 lua_settable(L, metatable);
1781
1782                 lua_pop(L, 1);  // drop metatable
1783
1784                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
1785                 lua_pop(L, 1);  // drop methodtable
1786
1787                 // Cannot be created from Lua
1788                 //lua_register(L, className, create_object);
1789         }
1790 };
1791 const char InvRef::className[] = "InvRef";
1792 const luaL_reg InvRef::methods[] = {
1793         method(InvRef, set_size),
1794         method(InvRef, get_stack),
1795         method(InvRef, set_stack),
1796         {0,0}
1797 };
1798
1799 /*
1800         NodeMetaRef
1801 */
1802
1803 class NodeMetaRef
1804 {
1805 private:
1806         v3s16 m_p;
1807         ServerEnvironment *m_env;
1808
1809         static const char className[];
1810         static const luaL_reg methods[];
1811
1812         static NodeMetaRef *checkobject(lua_State *L, int narg)
1813         {
1814                 luaL_checktype(L, narg, LUA_TUSERDATA);
1815                 void *ud = luaL_checkudata(L, narg, className);
1816                 if(!ud) luaL_typerror(L, narg, className);
1817                 return *(NodeMetaRef**)ud;  // unbox pointer
1818         }
1819         
1820         static NodeMetadata* getmeta(NodeMetaRef *ref)
1821         {
1822                 NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
1823                 return meta;
1824         }
1825
1826         /*static IGenericNodeMetadata* getgenericmeta(NodeMetaRef *ref)
1827         {
1828                 NodeMetadata *meta = getmeta(ref);
1829                 if(meta == NULL)
1830                         return NULL;
1831                 if(meta->typeId() != NODEMETA_GENERIC)
1832                         return NULL;
1833                 return (IGenericNodeMetadata*)meta;
1834         }*/
1835
1836         static void reportMetadataChange(NodeMetaRef *ref)
1837         {
1838                 // Inform other things that the metadata has changed
1839                 v3s16 blockpos = getNodeBlockPos(ref->m_p);
1840                 MapEditEvent event;
1841                 event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
1842                 event.p = blockpos;
1843                 ref->m_env->getMap().dispatchEvent(&event);
1844                 // Set the block to be saved
1845                 MapBlock *block = ref->m_env->getMap().getBlockNoCreateNoEx(blockpos);
1846                 if(block)
1847                         block->raiseModified(MOD_STATE_WRITE_NEEDED,
1848                                         "NodeMetaRef::reportMetadataChange");
1849         }
1850         
1851         // Exported functions
1852         
1853         // garbage collector
1854         static int gc_object(lua_State *L) {
1855                 NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
1856                 delete o;
1857                 return 0;
1858         }
1859
1860         // get_type(self)
1861         static int l_get_type(lua_State *L)
1862         {
1863                 NodeMetaRef *ref = checkobject(L, 1);
1864                 NodeMetadata *meta = getmeta(ref);
1865                 if(meta == NULL){
1866                         lua_pushnil(L);
1867                         return 1;
1868                 }
1869                 // Do it
1870                 lua_pushstring(L, meta->typeName());
1871                 return 1;
1872         }
1873
1874         // allows_text_input(self)
1875         static int l_allows_text_input(lua_State *L)
1876         {
1877                 NodeMetaRef *ref = checkobject(L, 1);
1878                 NodeMetadata *meta = getmeta(ref);
1879                 if(meta == NULL) return 0;
1880                 // Do it
1881                 lua_pushboolean(L, meta->allowsTextInput());
1882                 return 1;
1883         }
1884
1885         // set_text(self, text)
1886         static int l_set_text(lua_State *L)
1887         {
1888                 NodeMetaRef *ref = checkobject(L, 1);
1889                 NodeMetadata *meta = getmeta(ref);
1890                 if(meta == NULL) return 0;
1891                 // Do it
1892                 std::string text = luaL_checkstring(L, 2);
1893                 meta->setText(text);
1894                 reportMetadataChange(ref);
1895                 return 0;
1896         }
1897
1898         // get_text(self)
1899         static int l_get_text(lua_State *L)
1900         {
1901                 NodeMetaRef *ref = checkobject(L, 1);
1902                 NodeMetadata *meta = getmeta(ref);
1903                 if(meta == NULL) return 0;
1904                 // Do it
1905                 std::string text = meta->getText();
1906                 lua_pushstring(L, text.c_str());
1907                 return 1;
1908         }
1909
1910         // get_owner(self)
1911         static int l_get_owner(lua_State *L)
1912         {
1913                 NodeMetaRef *ref = checkobject(L, 1);
1914                 NodeMetadata *meta = getmeta(ref);
1915                 if(meta == NULL) return 0;
1916                 // Do it
1917                 std::string owner = meta->getOwner();
1918                 lua_pushstring(L, owner.c_str());
1919                 return 1;
1920         }
1921
1922         /* IGenericNodeMetadata interface */
1923         
1924         // set_infotext(self, text)
1925         static int l_set_infotext(lua_State *L)
1926         {
1927                 infostream<<__FUNCTION_NAME<<std::endl;
1928                 NodeMetaRef *ref = checkobject(L, 1);
1929                 NodeMetadata *meta = getmeta(ref);
1930                 if(meta == NULL) return 0;
1931                 // Do it
1932                 std::string text = luaL_checkstring(L, 2);
1933                 meta->setInfoText(text);
1934                 reportMetadataChange(ref);
1935                 return 0;
1936         }
1937
1938         // inventory_set_list(self, name, {item1, item2, ...})
1939         static int l_inventory_set_list(lua_State *L)
1940         {
1941                 NodeMetaRef *ref = checkobject(L, 1);
1942                 NodeMetadata *meta = getmeta(ref);
1943                 if(meta == NULL) return 0;
1944                 // Do it
1945                 Inventory *inv = meta->getInventory();
1946                 const char *name = luaL_checkstring(L, 2);
1947                 inventory_set_list_from_lua(inv, name, L, 3,
1948                                 ref->m_env->getGameDef());
1949                 reportMetadataChange(ref);
1950                 return 0;
1951         }
1952
1953         // inventory_get_list(self, name)
1954         static int l_inventory_get_list(lua_State *L)
1955         {
1956                 NodeMetaRef *ref = checkobject(L, 1);
1957                 NodeMetadata *meta = getmeta(ref);
1958                 if(meta == NULL) return 0;
1959                 // Do it
1960                 Inventory *inv = meta->getInventory();
1961                 const char *name = luaL_checkstring(L, 2);
1962                 inventory_get_list_to_lua(inv, name, L);
1963                 return 1;
1964         }
1965
1966         // set_inventory_draw_spec(self, text)
1967         static int l_set_inventory_draw_spec(lua_State *L)
1968         {
1969                 NodeMetaRef *ref = checkobject(L, 1);
1970                 NodeMetadata *meta = getmeta(ref);
1971                 if(meta == NULL) return 0;
1972                 // Do it
1973                 std::string text = luaL_checkstring(L, 2);
1974                 meta->setInventoryDrawSpec(text);
1975                 reportMetadataChange(ref);
1976                 return 0;
1977         }
1978
1979         // set_allow_text_input(self, text)
1980         static int l_set_allow_text_input(lua_State *L)
1981         {
1982                 NodeMetaRef *ref = checkobject(L, 1);
1983                 NodeMetadata *meta = getmeta(ref);
1984                 if(meta == NULL) return 0;
1985                 // Do it
1986                 bool b = lua_toboolean(L, 2);
1987                 meta->setAllowTextInput(b);
1988                 reportMetadataChange(ref);
1989                 return 0;
1990         }
1991
1992         // set_allow_removal(self, text)
1993         static int l_set_allow_removal(lua_State *L)
1994         {
1995                 NodeMetaRef *ref = checkobject(L, 1);
1996                 NodeMetadata *meta = getmeta(ref);
1997                 if(meta == NULL) return 0;
1998                 // Do it
1999                 bool b = lua_toboolean(L, 2);
2000                 meta->setRemovalDisabled(!b);
2001                 reportMetadataChange(ref);
2002                 return 0;
2003         }
2004
2005         // set_enforce_owner(self, text)
2006         static int l_set_enforce_owner(lua_State *L)
2007         {
2008                 NodeMetaRef *ref = checkobject(L, 1);
2009                 NodeMetadata *meta = getmeta(ref);
2010                 if(meta == NULL) return 0;
2011                 // Do it
2012                 bool b = lua_toboolean(L, 2);
2013                 meta->setEnforceOwner(b);
2014                 reportMetadataChange(ref);
2015                 return 0;
2016         }
2017
2018         // is_inventory_modified(self)
2019         static int l_is_inventory_modified(lua_State *L)
2020         {
2021                 NodeMetaRef *ref = checkobject(L, 1);
2022                 NodeMetadata *meta = getmeta(ref);
2023                 if(meta == NULL) return 0;
2024                 // Do it
2025                 lua_pushboolean(L, meta->isInventoryModified());
2026                 return 1;
2027         }
2028
2029         // reset_inventory_modified(self)
2030         static int l_reset_inventory_modified(lua_State *L)
2031         {
2032                 NodeMetaRef *ref = checkobject(L, 1);
2033                 NodeMetadata *meta = getmeta(ref);
2034                 if(meta == NULL) return 0;
2035                 // Do it
2036                 meta->resetInventoryModified();
2037                 reportMetadataChange(ref);
2038                 return 0;
2039         }
2040
2041         // is_text_modified(self)
2042         static int l_is_text_modified(lua_State *L)
2043         {
2044                 NodeMetaRef *ref = checkobject(L, 1);
2045                 NodeMetadata *meta = getmeta(ref);
2046                 if(meta == NULL) return 0;
2047                 // Do it
2048                 lua_pushboolean(L, meta->isTextModified());
2049                 return 1;
2050         }
2051
2052         // reset_text_modified(self)
2053         static int l_reset_text_modified(lua_State *L)
2054         {
2055                 NodeMetaRef *ref = checkobject(L, 1);
2056                 NodeMetadata *meta = getmeta(ref);
2057                 if(meta == NULL) return 0;
2058                 // Do it
2059                 meta->resetTextModified();
2060                 reportMetadataChange(ref);
2061                 return 0;
2062         }
2063
2064         // set_string(self, name, var)
2065         static int l_set_string(lua_State *L)
2066         {
2067                 NodeMetaRef *ref = checkobject(L, 1);
2068                 NodeMetadata *meta = getmeta(ref);
2069                 if(meta == NULL) return 0;
2070                 // Do it
2071                 std::string name = luaL_checkstring(L, 2);
2072                 size_t len = 0;
2073                 const char *s = lua_tolstring(L, 3, &len);
2074                 std::string str(s, len);
2075                 meta->setString(name, str);
2076                 reportMetadataChange(ref);
2077                 return 0;
2078         }
2079
2080         // get_string(self, name)
2081         static int l_get_string(lua_State *L)
2082         {
2083                 NodeMetaRef *ref = checkobject(L, 1);
2084                 NodeMetadata *meta = getmeta(ref);
2085                 if(meta == NULL) return 0;
2086                 // Do it
2087                 std::string name = luaL_checkstring(L, 2);
2088                 std::string str = meta->getString(name);
2089                 lua_pushlstring(L, str.c_str(), str.size());
2090                 return 1;
2091         }
2092
2093 public:
2094         NodeMetaRef(v3s16 p, ServerEnvironment *env):
2095                 m_p(p),
2096                 m_env(env)
2097         {
2098         }
2099
2100         ~NodeMetaRef()
2101         {
2102         }
2103
2104         // Creates an NodeMetaRef and leaves it on top of stack
2105         // Not callable from Lua; all references are created on the C side.
2106         static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
2107         {
2108                 NodeMetaRef *o = new NodeMetaRef(p, env);
2109                 //infostream<<"NodeMetaRef::create: o="<<o<<std::endl;
2110                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2111                 luaL_getmetatable(L, className);
2112                 lua_setmetatable(L, -2);
2113         }
2114
2115         static void Register(lua_State *L)
2116         {
2117                 lua_newtable(L);
2118                 int methodtable = lua_gettop(L);
2119                 luaL_newmetatable(L, className);
2120                 int metatable = lua_gettop(L);
2121
2122                 lua_pushliteral(L, "__metatable");
2123                 lua_pushvalue(L, methodtable);
2124                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
2125
2126                 lua_pushliteral(L, "__index");
2127                 lua_pushvalue(L, methodtable);
2128                 lua_settable(L, metatable);
2129
2130                 lua_pushliteral(L, "__gc");
2131                 lua_pushcfunction(L, gc_object);
2132                 lua_settable(L, metatable);
2133
2134                 lua_pop(L, 1);  // drop metatable
2135
2136                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
2137                 lua_pop(L, 1);  // drop methodtable
2138
2139                 // Cannot be created from Lua
2140                 //lua_register(L, className, create_object);
2141         }
2142 };
2143 const char NodeMetaRef::className[] = "NodeMetaRef";
2144 const luaL_reg NodeMetaRef::methods[] = {
2145         method(NodeMetaRef, get_type),
2146         method(NodeMetaRef, allows_text_input),
2147         method(NodeMetaRef, set_text),
2148         method(NodeMetaRef, get_text),
2149         method(NodeMetaRef, get_owner),
2150         method(NodeMetaRef, set_infotext),
2151         method(NodeMetaRef, inventory_set_list),
2152         method(NodeMetaRef, inventory_get_list),
2153         method(NodeMetaRef, set_inventory_draw_spec),
2154         method(NodeMetaRef, set_allow_text_input),
2155         method(NodeMetaRef, set_allow_removal),
2156         method(NodeMetaRef, set_enforce_owner),
2157         method(NodeMetaRef, is_inventory_modified),
2158         method(NodeMetaRef, reset_inventory_modified),
2159         method(NodeMetaRef, is_text_modified),
2160         method(NodeMetaRef, reset_text_modified),
2161         method(NodeMetaRef, set_string),
2162         method(NodeMetaRef, get_string),
2163         {0,0}
2164 };
2165
2166 /*
2167         ObjectRef
2168 */
2169
2170 class ObjectRef
2171 {
2172 private:
2173         ServerActiveObject *m_object;
2174
2175         static const char className[];
2176         static const luaL_reg methods[];
2177
2178         static ObjectRef *checkobject(lua_State *L, int narg)
2179         {
2180                 luaL_checktype(L, narg, LUA_TUSERDATA);
2181                 void *ud = luaL_checkudata(L, narg, className);
2182                 if(!ud) luaL_typerror(L, narg, className);
2183                 return *(ObjectRef**)ud;  // unbox pointer
2184         }
2185         
2186         static ServerActiveObject* getobject(ObjectRef *ref)
2187         {
2188                 ServerActiveObject *co = ref->m_object;
2189                 return co;
2190         }
2191         
2192         static LuaEntitySAO* getluaobject(ObjectRef *ref)
2193         {
2194                 ServerActiveObject *obj = getobject(ref);
2195                 if(obj == NULL)
2196                         return NULL;
2197                 if(obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
2198                         return NULL;
2199                 return (LuaEntitySAO*)obj;
2200         }
2201         
2202         static ServerRemotePlayer* getplayer(ObjectRef *ref)
2203         {
2204                 ServerActiveObject *obj = getobject(ref);
2205                 if(obj == NULL)
2206                         return NULL;
2207                 if(obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
2208                         return NULL;
2209                 return static_cast<ServerRemotePlayer*>(obj);
2210         }
2211         
2212         // Exported functions
2213         
2214         // garbage collector
2215         static int gc_object(lua_State *L) {
2216                 ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
2217                 //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
2218                 delete o;
2219                 return 0;
2220         }
2221
2222         // remove(self)
2223         static int l_remove(lua_State *L)
2224         {
2225                 ObjectRef *ref = checkobject(L, 1);
2226                 ServerActiveObject *co = getobject(ref);
2227                 if(co == NULL) return 0;
2228                 infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
2229                 co->m_removed = true;
2230                 return 0;
2231         }
2232         
2233         // getpos(self)
2234         // returns: {x=num, y=num, z=num}
2235         static int l_getpos(lua_State *L)
2236         {
2237                 ObjectRef *ref = checkobject(L, 1);
2238                 ServerActiveObject *co = getobject(ref);
2239                 if(co == NULL) return 0;
2240                 v3f pos = co->getBasePosition() / BS;
2241                 lua_newtable(L);
2242                 lua_pushnumber(L, pos.X);
2243                 lua_setfield(L, -2, "x");
2244                 lua_pushnumber(L, pos.Y);
2245                 lua_setfield(L, -2, "y");
2246                 lua_pushnumber(L, pos.Z);
2247                 lua_setfield(L, -2, "z");
2248                 return 1;
2249         }
2250         
2251         // setpos(self, pos)
2252         static int l_setpos(lua_State *L)
2253         {
2254                 ObjectRef *ref = checkobject(L, 1);
2255                 //LuaEntitySAO *co = getluaobject(ref);
2256                 ServerActiveObject *co = getobject(ref);
2257                 if(co == NULL) return 0;
2258                 // pos
2259                 v3f pos = readFloatPos(L, 2);
2260                 // Do it
2261                 co->setPos(pos);
2262                 return 0;
2263         }
2264         
2265         // moveto(self, pos, continuous=false)
2266         static int l_moveto(lua_State *L)
2267         {
2268                 ObjectRef *ref = checkobject(L, 1);
2269                 //LuaEntitySAO *co = getluaobject(ref);
2270                 ServerActiveObject *co = getobject(ref);
2271                 if(co == NULL) return 0;
2272                 // pos
2273                 v3f pos = readFloatPos(L, 2);
2274                 // continuous
2275                 bool continuous = lua_toboolean(L, 3);
2276                 // Do it
2277                 co->moveTo(pos, continuous);
2278                 return 0;
2279         }
2280
2281         // punch(self, puncher); puncher = an another ObjectRef
2282         static int l_punch(lua_State *L)
2283         {
2284                 ObjectRef *ref = checkobject(L, 1);
2285                 ObjectRef *ref2 = checkobject(L, 2);
2286                 ServerActiveObject *co = getobject(ref);
2287                 ServerActiveObject *co2 = getobject(ref2);
2288                 if(co == NULL) return 0;
2289                 if(co2 == NULL) return 0;
2290                 // Do it
2291                 co->punch(co2);
2292                 return 0;
2293         }
2294
2295         // right_click(self, clicker); clicker = an another ObjectRef
2296         static int l_right_click(lua_State *L)
2297         {
2298                 ObjectRef *ref = checkobject(L, 1);
2299                 ObjectRef *ref2 = checkobject(L, 2);
2300                 ServerActiveObject *co = getobject(ref);
2301                 ServerActiveObject *co2 = getobject(ref2);
2302                 if(co == NULL) return 0;
2303                 if(co2 == NULL) return 0;
2304                 // Do it
2305                 co->rightClick(co2);
2306                 return 0;
2307         }
2308
2309         // get_wield_digging_properties(self)
2310         static int l_get_wield_digging_properties(lua_State *L)
2311         {
2312                 ObjectRef *ref = checkobject(L, 1);
2313                 ServerActiveObject *co = getobject(ref);
2314                 if(co == NULL) return 0;
2315                 // Do it
2316                 ToolDiggingProperties prop;
2317                 co->getWieldDiggingProperties(&prop);
2318                 push_tool_digging_properties(L, prop);
2319                 return 1;
2320         }
2321
2322         // damage_wielded_item(self, amount)
2323         static int l_damage_wielded_item(lua_State *L)
2324         {
2325                 ObjectRef *ref = checkobject(L, 1);
2326                 ServerActiveObject *co = getobject(ref);
2327                 if(co == NULL) return 0;
2328                 // Do it
2329                 int amount = lua_tonumber(L, 2);
2330                 co->damageWieldedItem(amount);
2331                 return 0;
2332         }
2333
2334         // add_to_inventory(self, itemstring)
2335         // returns: true if item was added, (false, "reason") otherwise
2336         static int l_add_to_inventory(lua_State *L)
2337         {
2338                 ObjectRef *ref = checkobject(L, 1);
2339                 luaL_checkstring(L, 2);
2340                 ServerActiveObject *co = getobject(ref);
2341                 if(co == NULL) return 0;
2342                 // itemstring
2343                 const char *itemstring = luaL_checkstring(L, 2);
2344                 infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
2345                                 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
2346                 // Do it
2347                 std::istringstream is(itemstring, std::ios::binary);
2348                 ServerEnvironment *env = co->getEnv();
2349                 assert(env);
2350                 IGameDef *gamedef = env->getGameDef();
2351                 try{
2352                         InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
2353                         if(item->getCount() == 0)
2354                                 item->setCount(1);
2355                         bool added = co->addToInventory(item);
2356                         // Return
2357                         lua_pushboolean(L, added);
2358                         if(!added)
2359                                 lua_pushstring(L, "failed to add item");
2360                         return 2;
2361                 } catch(SerializationError &e){
2362                         // Return
2363                         lua_pushboolean(L, false);
2364                         lua_pushstring(L, (std::string("Invalid item: ")
2365                                         + e.what()).c_str());
2366                         return 2;
2367                 }
2368         }
2369
2370         // add_to_inventory_later(self, itemstring)
2371         // returns: nil
2372         static int l_add_to_inventory_later(lua_State *L)
2373         {
2374                 ObjectRef *ref = checkobject(L, 1);
2375                 luaL_checkstring(L, 2);
2376                 ServerActiveObject *co = getobject(ref);
2377                 if(co == NULL) return 0;
2378                 // itemstring
2379                 const char *itemstring = luaL_checkstring(L, 2);
2380                 infostream<<"ObjectRef::l_add_to_inventory_later(): id="<<co->getId()
2381                                 <<" itemstring=\""<<itemstring<<"\""<<std::endl;
2382                 // Do it
2383                 std::istringstream is(itemstring, std::ios::binary);
2384                 ServerEnvironment *env = co->getEnv();
2385                 assert(env);
2386                 IGameDef *gamedef = env->getGameDef();
2387                 InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
2388                 infostream<<"item="<<env<<std::endl;
2389                 co->addToInventoryLater(item);
2390                 // Return
2391                 return 0;
2392         }
2393
2394         // set_hp(self, hp)
2395         // hp = number of hitpoints (2 * number of hearts)
2396         // returns: nil
2397         static int l_set_hp(lua_State *L)
2398         {
2399                 ObjectRef *ref = checkobject(L, 1);
2400                 luaL_checknumber(L, 2);
2401                 ServerActiveObject *co = getobject(ref);
2402                 if(co == NULL) return 0;
2403                 int hp = lua_tonumber(L, 2);
2404                 infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
2405                                 <<" hp="<<hp<<std::endl;
2406                 // Do it
2407                 co->setHP(hp);
2408                 // Return
2409                 return 0;
2410         }
2411
2412         // get_hp(self)
2413         // returns: number of hitpoints (2 * number of hearts)
2414         // 0 if not applicable to this type of object
2415         static int l_get_hp(lua_State *L)
2416         {
2417                 ObjectRef *ref = checkobject(L, 1);
2418                 ServerActiveObject *co = getobject(ref);
2419                 if(co == NULL) return 0;
2420                 int hp = co->getHP();
2421                 infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
2422                                 <<" hp="<<hp<<std::endl;
2423                 // Return
2424                 lua_pushnumber(L, hp);
2425                 return 1;
2426         }
2427
2428         /* LuaEntitySAO-only */
2429
2430         // setvelocity(self, {x=num, y=num, z=num})
2431         static int l_setvelocity(lua_State *L)
2432         {
2433                 ObjectRef *ref = checkobject(L, 1);
2434                 LuaEntitySAO *co = getluaobject(ref);
2435                 if(co == NULL) return 0;
2436                 // pos
2437                 v3f pos = readFloatPos(L, 2);
2438                 // Do it
2439                 co->setVelocity(pos);
2440                 return 0;
2441         }
2442         
2443         // setacceleration(self, {x=num, y=num, z=num})
2444         static int l_setacceleration(lua_State *L)
2445         {
2446                 ObjectRef *ref = checkobject(L, 1);
2447                 LuaEntitySAO *co = getluaobject(ref);
2448                 if(co == NULL) return 0;
2449                 // pos
2450                 v3f pos = readFloatPos(L, 2);
2451                 // Do it
2452                 co->setAcceleration(pos);
2453                 return 0;
2454         }
2455         
2456         // getacceleration(self)
2457         static int l_getacceleration(lua_State *L)
2458         {
2459                 ObjectRef *ref = checkobject(L, 1);
2460                 LuaEntitySAO *co = getluaobject(ref);
2461                 if(co == NULL) return 0;
2462                 // Do it
2463                 v3f v = co->getAcceleration();
2464                 pushFloatPos(L, v);
2465                 return 1;
2466         }
2467         
2468         // settexturemod(self, mod)
2469         static int l_settexturemod(lua_State *L)
2470         {
2471                 ObjectRef *ref = checkobject(L, 1);
2472                 LuaEntitySAO *co = getluaobject(ref);
2473                 if(co == NULL) return 0;
2474                 // Do it
2475                 std::string mod = luaL_checkstring(L, 2);
2476                 co->setTextureMod(mod);
2477                 return 0;
2478         }
2479         
2480         // setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
2481         //           select_horiz_by_yawpitch=false)
2482         static int l_setsprite(lua_State *L)
2483         {
2484                 ObjectRef *ref = checkobject(L, 1);
2485                 LuaEntitySAO *co = getluaobject(ref);
2486                 if(co == NULL) return 0;
2487                 // Do it
2488                 v2s16 p(0,0);
2489                 if(!lua_isnil(L, 2))
2490                         p = read_v2s16(L, 2);
2491                 int num_frames = 1;
2492                 if(!lua_isnil(L, 3))
2493                         num_frames = lua_tonumber(L, 3);
2494                 float framelength = 0.2;
2495                 if(!lua_isnil(L, 4))
2496                         framelength = lua_tonumber(L, 4);
2497                 bool select_horiz_by_yawpitch = false;
2498                 if(!lua_isnil(L, 5))
2499                         select_horiz_by_yawpitch = lua_toboolean(L, 5);
2500                 co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
2501                 return 0;
2502         }
2503
2504         /* Player-only */
2505         
2506         // get_player_name(self)
2507         static int l_get_player_name(lua_State *L)
2508         {
2509                 ObjectRef *ref = checkobject(L, 1);
2510                 ServerRemotePlayer *player = getplayer(ref);
2511                 if(player == NULL){
2512                         lua_pushnil(L);
2513                         return 1;
2514                 }
2515                 // Do it
2516                 lua_pushstring(L, player->getName());
2517                 return 1;
2518         }
2519         
2520         // inventory_set_list(self, name, {item1, item2, ...})
2521         static int l_inventory_set_list(lua_State *L)
2522         {
2523                 ObjectRef *ref = checkobject(L, 1);
2524                 ServerRemotePlayer *player = getplayer(ref);
2525                 if(player == NULL) return 0;
2526                 const char *name = luaL_checkstring(L, 2);
2527                 // Do it
2528                 inventory_set_list_from_lua(&player->inventory, name, L, 3,
2529                                 player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
2530                 player->m_inventory_not_sent = true;
2531                 return 0;
2532         }
2533
2534         // inventory_get_list(self, name)
2535         static int l_inventory_get_list(lua_State *L)
2536         {
2537                 ObjectRef *ref = checkobject(L, 1);
2538                 ServerRemotePlayer *player = getplayer(ref);
2539                 if(player == NULL) return 0;
2540                 const char *name = luaL_checkstring(L, 2);
2541                 // Do it
2542                 inventory_get_list_to_lua(&player->inventory, name, L);
2543                 return 1;
2544         }
2545
2546         // get_wielded_itemstring(self)
2547         static int l_get_wielded_itemstring(lua_State *L)
2548         {
2549                 ObjectRef *ref = checkobject(L, 1);
2550                 ServerRemotePlayer *player = getplayer(ref);
2551                 if(player == NULL) return 0;
2552                 // Do it
2553                 InventoryItem *item = player->getWieldedItem();
2554                 if(item == NULL){
2555                         lua_pushnil(L);
2556                         return 1;
2557                 }
2558                 lua_pushstring(L, item->getItemString().c_str());
2559                 return 1;
2560         }
2561
2562         // get_wielded_item(self)
2563         static int l_get_wielded_item(lua_State *L)
2564         {
2565                 ObjectRef *ref = checkobject(L, 1);
2566                 ServerRemotePlayer *player = getplayer(ref);
2567                 if(player == NULL) return 0;
2568                 // Do it
2569                 InventoryItem *item0 = player->getWieldedItem();
2570                 push_stack_item(L, item0);
2571                 return 1;
2572         }
2573
2574         // get_look_dir(self)
2575         static int l_get_look_dir(lua_State *L)
2576         {
2577                 ObjectRef *ref = checkobject(L, 1);
2578                 ServerRemotePlayer *player = getplayer(ref);
2579                 if(player == NULL) return 0;
2580                 // Do it
2581                 float pitch = player->getRadPitch();
2582                 float yaw = player->getRadYaw();
2583                 v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
2584                 push_v3f(L, v);
2585                 return 1;
2586         }
2587
2588         // get_look_pitch(self)
2589         static int l_get_look_pitch(lua_State *L)
2590         {
2591                 ObjectRef *ref = checkobject(L, 1);
2592                 ServerRemotePlayer *player = getplayer(ref);
2593                 if(player == NULL) return 0;
2594                 // Do it
2595                 lua_pushnumber(L, player->getRadPitch());
2596                 return 1;
2597         }
2598
2599         // get_look_yaw(self)
2600         static int l_get_look_yaw(lua_State *L)
2601         {
2602                 ObjectRef *ref = checkobject(L, 1);
2603                 ServerRemotePlayer *player = getplayer(ref);
2604                 if(player == NULL) return 0;
2605                 // Do it
2606                 lua_pushnumber(L, player->getRadYaw());
2607                 return 1;
2608         }
2609
2610 public:
2611         ObjectRef(ServerActiveObject *object):
2612                 m_object(object)
2613         {
2614                 //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
2615         }
2616
2617         ~ObjectRef()
2618         {
2619                 /*if(m_object)
2620                         infostream<<"ObjectRef destructing for id="
2621                                         <<m_object->getId()<<std::endl;
2622                 else
2623                         infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
2624         }
2625
2626         // Creates an ObjectRef and leaves it on top of stack
2627         // Not callable from Lua; all references are created on the C side.
2628         static void create(lua_State *L, ServerActiveObject *object)
2629         {
2630                 ObjectRef *o = new ObjectRef(object);
2631                 //infostream<<"ObjectRef::create: o="<<o<<std::endl;
2632                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2633                 luaL_getmetatable(L, className);
2634                 lua_setmetatable(L, -2);
2635         }
2636
2637         static void set_null(lua_State *L)
2638         {
2639                 ObjectRef *o = checkobject(L, -1);
2640                 o->m_object = NULL;
2641         }
2642         
2643         static void Register(lua_State *L)
2644         {
2645                 lua_newtable(L);
2646                 int methodtable = lua_gettop(L);
2647                 luaL_newmetatable(L, className);
2648                 int metatable = lua_gettop(L);
2649
2650                 lua_pushliteral(L, "__metatable");
2651                 lua_pushvalue(L, methodtable);
2652                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
2653
2654                 lua_pushliteral(L, "__index");
2655                 lua_pushvalue(L, methodtable);
2656                 lua_settable(L, metatable);
2657
2658                 lua_pushliteral(L, "__gc");
2659                 lua_pushcfunction(L, gc_object);
2660                 lua_settable(L, metatable);
2661
2662                 lua_pop(L, 1);  // drop metatable
2663
2664                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
2665                 lua_pop(L, 1);  // drop methodtable
2666
2667                 // Cannot be created from Lua
2668                 //lua_register(L, className, create_object);
2669         }
2670 };
2671 const char ObjectRef::className[] = "ObjectRef";
2672 const luaL_reg ObjectRef::methods[] = {
2673         // ServerActiveObject
2674         method(ObjectRef, remove),
2675         method(ObjectRef, getpos),
2676         method(ObjectRef, setpos),
2677         method(ObjectRef, moveto),
2678         method(ObjectRef, punch),
2679         method(ObjectRef, right_click),
2680         method(ObjectRef, get_wield_digging_properties),
2681         method(ObjectRef, damage_wielded_item),
2682         method(ObjectRef, add_to_inventory),
2683         method(ObjectRef, add_to_inventory_later),
2684         method(ObjectRef, set_hp),
2685         method(ObjectRef, get_hp),
2686         // LuaEntitySAO-only
2687         method(ObjectRef, setvelocity),
2688         method(ObjectRef, setacceleration),
2689         method(ObjectRef, getacceleration),
2690         method(ObjectRef, settexturemod),
2691         method(ObjectRef, setsprite),
2692         // Player-only
2693         method(ObjectRef, get_player_name),
2694         method(ObjectRef, inventory_set_list),
2695         method(ObjectRef, inventory_get_list),
2696         method(ObjectRef, get_wielded_itemstring),
2697         method(ObjectRef, get_wielded_item),
2698         method(ObjectRef, get_look_dir),
2699         method(ObjectRef, get_look_pitch),
2700         method(ObjectRef, get_look_yaw),
2701         {0,0}
2702 };
2703
2704 // Creates a new anonymous reference if id=0
2705 static void objectref_get_or_create(lua_State *L,
2706                 ServerActiveObject *cobj)
2707 {
2708         if(cobj->getId() == 0){
2709                 ObjectRef::create(L, cobj);
2710         } else {
2711                 objectref_get(L, cobj->getId());
2712         }
2713 }
2714
2715 /*
2716         EnvRef
2717 */
2718
2719 class EnvRef
2720 {
2721 private:
2722         ServerEnvironment *m_env;
2723
2724         static const char className[];
2725         static const luaL_reg methods[];
2726
2727         static EnvRef *checkobject(lua_State *L, int narg)
2728         {
2729                 luaL_checktype(L, narg, LUA_TUSERDATA);
2730                 void *ud = luaL_checkudata(L, narg, className);
2731                 if(!ud) luaL_typerror(L, narg, className);
2732                 return *(EnvRef**)ud;  // unbox pointer
2733         }
2734         
2735         // Exported functions
2736
2737         // EnvRef:add_node(pos, node)
2738         // pos = {x=num, y=num, z=num}
2739         static int l_add_node(lua_State *L)
2740         {
2741                 //infostream<<"EnvRef::l_add_node()"<<std::endl;
2742                 EnvRef *o = checkobject(L, 1);
2743                 ServerEnvironment *env = o->m_env;
2744                 if(env == NULL) return 0;
2745                 // pos
2746                 v3s16 pos = readpos(L, 2);
2747                 // content
2748                 MapNode n = readnode(L, 3, env->getGameDef()->ndef());
2749                 // Do it
2750                 bool succeeded = env->getMap().addNodeWithEvent(pos, n);
2751                 lua_pushboolean(L, succeeded);
2752                 return 1;
2753         }
2754
2755         // EnvRef:remove_node(pos)
2756         // pos = {x=num, y=num, z=num}
2757         static int l_remove_node(lua_State *L)
2758         {
2759                 //infostream<<"EnvRef::l_remove_node()"<<std::endl;
2760                 EnvRef *o = checkobject(L, 1);
2761                 ServerEnvironment *env = o->m_env;
2762                 if(env == NULL) return 0;
2763                 // pos
2764                 v3s16 pos = readpos(L, 2);
2765                 // Do it
2766                 bool succeeded = env->getMap().removeNodeWithEvent(pos);
2767                 lua_pushboolean(L, succeeded);
2768                 return 1;
2769         }
2770
2771         // EnvRef:get_node(pos)
2772         // pos = {x=num, y=num, z=num}
2773         static int l_get_node(lua_State *L)
2774         {
2775                 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2776                 EnvRef *o = checkobject(L, 1);
2777                 ServerEnvironment *env = o->m_env;
2778                 if(env == NULL) return 0;
2779                 // pos
2780                 v3s16 pos = readpos(L, 2);
2781                 // Do it
2782                 MapNode n = env->getMap().getNodeNoEx(pos);
2783                 // Return node
2784                 pushnode(L, n, env->getGameDef()->ndef());
2785                 return 1;
2786         }
2787
2788         // EnvRef:get_node_or_nil(pos)
2789         // pos = {x=num, y=num, z=num}
2790         static int l_get_node_or_nil(lua_State *L)
2791         {
2792                 //infostream<<"EnvRef::l_get_node()"<<std::endl;
2793                 EnvRef *o = checkobject(L, 1);
2794                 ServerEnvironment *env = o->m_env;
2795                 if(env == NULL) return 0;
2796                 // pos
2797                 v3s16 pos = readpos(L, 2);
2798                 // Do it
2799                 try{
2800                         MapNode n = env->getMap().getNode(pos);
2801                         // Return node
2802                         pushnode(L, n, env->getGameDef()->ndef());
2803                         return 1;
2804                 } catch(InvalidPositionException &e)
2805                 {
2806                         lua_pushnil(L);
2807                         return 1;
2808                 }
2809         }
2810
2811         // EnvRef:get_node_light(pos, timeofday)
2812         // pos = {x=num, y=num, z=num}
2813         // timeofday: nil = current time, 0 = night, 0.5 = day
2814         static int l_get_node_light(lua_State *L)
2815         {
2816                 EnvRef *o = checkobject(L, 1);
2817                 ServerEnvironment *env = o->m_env;
2818                 if(env == NULL) return 0;
2819                 // Do it
2820                 v3s16 pos = readpos(L, 2);
2821                 u32 time_of_day = env->getTimeOfDay();
2822                 if(lua_isnumber(L, 3))
2823                         time_of_day = 24000.0 * lua_tonumber(L, 3);
2824                 time_of_day %= 24000;
2825                 u32 dnr = time_to_daynight_ratio(time_of_day);
2826                 MapNode n = env->getMap().getNodeNoEx(pos);
2827                 try{
2828                         MapNode n = env->getMap().getNode(pos);
2829                         INodeDefManager *ndef = env->getGameDef()->ndef();
2830                         lua_pushinteger(L, n.getLightBlend(dnr, ndef));
2831                         return 1;
2832                 } catch(InvalidPositionException &e)
2833                 {
2834                         lua_pushnil(L);
2835                         return 1;
2836                 }
2837         }
2838
2839         // EnvRef:add_entity(pos, entityname)
2840         // pos = {x=num, y=num, z=num}
2841         static int l_add_entity(lua_State *L)
2842         {
2843                 //infostream<<"EnvRef::l_add_entity()"<<std::endl;
2844                 EnvRef *o = checkobject(L, 1);
2845                 ServerEnvironment *env = o->m_env;
2846                 if(env == NULL) return 0;
2847                 // pos
2848                 v3f pos = readFloatPos(L, 2);
2849                 // content
2850                 const char *name = luaL_checkstring(L, 3);
2851                 // Do it
2852                 ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
2853                 env->addActiveObject(obj);
2854                 return 0;
2855         }
2856
2857         // EnvRef:add_item(pos, inventorystring)
2858         // pos = {x=num, y=num, z=num}
2859         static int l_add_item(lua_State *L)
2860         {
2861                 infostream<<"EnvRef::l_add_item()"<<std::endl;
2862                 EnvRef *o = checkobject(L, 1);
2863                 ServerEnvironment *env = o->m_env;
2864                 if(env == NULL) return 0;
2865                 // pos
2866                 v3f pos = readFloatPos(L, 2);
2867                 // inventorystring
2868                 const char *inventorystring = luaL_checkstring(L, 3);
2869                 // Do it
2870                 ServerActiveObject *obj = new ItemSAO(env, pos, inventorystring);
2871                 env->addActiveObject(obj);
2872                 return 0;
2873         }
2874
2875         // EnvRef:add_rat(pos)
2876         // pos = {x=num, y=num, z=num}
2877         static int l_add_rat(lua_State *L)
2878         {
2879                 infostream<<"EnvRef::l_add_rat()"<<std::endl;
2880                 EnvRef *o = checkobject(L, 1);
2881                 ServerEnvironment *env = o->m_env;
2882                 if(env == NULL) return 0;
2883                 // pos
2884                 v3f pos = readFloatPos(L, 2);
2885                 // Do it
2886                 ServerActiveObject *obj = new RatSAO(env, pos);
2887                 env->addActiveObject(obj);
2888                 return 0;
2889         }
2890
2891         // EnvRef:add_firefly(pos)
2892         // pos = {x=num, y=num, z=num}
2893         static int l_add_firefly(lua_State *L)
2894         {
2895                 infostream<<"EnvRef::l_add_firefly()"<<std::endl;
2896                 EnvRef *o = checkobject(L, 1);
2897                 ServerEnvironment *env = o->m_env;
2898                 if(env == NULL) return 0;
2899                 // pos
2900                 v3f pos = readFloatPos(L, 2);
2901                 // Do it
2902                 ServerActiveObject *obj = new FireflySAO(env, pos);
2903                 env->addActiveObject(obj);
2904                 return 0;
2905         }
2906
2907         // EnvRef:get_meta(pos)
2908         static int l_get_meta(lua_State *L)
2909         {
2910                 //infostream<<"EnvRef::l_get_meta()"<<std::endl;
2911                 EnvRef *o = checkobject(L, 1);
2912                 ServerEnvironment *env = o->m_env;
2913                 if(env == NULL) return 0;
2914                 // Do it
2915                 v3s16 p = readpos(L, 2);
2916                 NodeMetaRef::create(L, p, env);
2917                 return 1;
2918         }
2919
2920         // EnvRef:get_player_by_name(name)
2921         static int l_get_player_by_name(lua_State *L)
2922         {
2923                 EnvRef *o = checkobject(L, 1);
2924                 ServerEnvironment *env = o->m_env;
2925                 if(env == NULL) return 0;
2926                 // Do it
2927                 const char *name = luaL_checkstring(L, 2);
2928                 ServerRemotePlayer *player =
2929                                 static_cast<ServerRemotePlayer*>(env->getPlayer(name));
2930                 if(player == NULL){
2931                         lua_pushnil(L);
2932                         return 1;
2933                 }
2934                 // Put player on stack
2935                 objectref_get_or_create(L, player);
2936                 return 1;
2937         }
2938
2939         // EnvRef:get_objects_inside_radius(pos, radius)
2940         static int l_get_objects_inside_radius(lua_State *L)
2941         {
2942                 // Get the table insert function
2943                 lua_getglobal(L, "table");
2944                 lua_getfield(L, -1, "insert");
2945                 int table_insert = lua_gettop(L);
2946                 // Get environemnt
2947                 EnvRef *o = checkobject(L, 1);
2948                 ServerEnvironment *env = o->m_env;
2949                 if(env == NULL) return 0;
2950                 // Do it
2951                 v3f pos = readFloatPos(L, 2);
2952                 float radius = luaL_checknumber(L, 3) * BS;
2953                 std::set<u16> ids = env->getObjectsInsideRadius(pos, radius);
2954                 lua_newtable(L);
2955                 int table = lua_gettop(L);
2956                 for(std::set<u16>::const_iterator
2957                                 i = ids.begin(); i != ids.end(); i++){
2958                         ServerActiveObject *obj = env->getActiveObject(*i);
2959                         // Insert object reference into table
2960                         lua_pushvalue(L, table_insert);
2961                         lua_pushvalue(L, table);
2962                         objectref_get_or_create(L, obj);
2963                         if(lua_pcall(L, 2, 0, 0))
2964                                 script_error(L, "error: %s", lua_tostring(L, -1));
2965                 }
2966                 return 1;
2967         }
2968
2969         static int gc_object(lua_State *L) {
2970                 EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
2971                 delete o;
2972                 return 0;
2973         }
2974
2975 public:
2976         EnvRef(ServerEnvironment *env):
2977                 m_env(env)
2978         {
2979                 infostream<<"EnvRef created"<<std::endl;
2980         }
2981
2982         ~EnvRef()
2983         {
2984                 infostream<<"EnvRef destructing"<<std::endl;
2985         }
2986
2987         // Creates an EnvRef and leaves it on top of stack
2988         // Not callable from Lua; all references are created on the C side.
2989         static void create(lua_State *L, ServerEnvironment *env)
2990         {
2991                 EnvRef *o = new EnvRef(env);
2992                 //infostream<<"EnvRef::create: o="<<o<<std::endl;
2993                 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
2994                 luaL_getmetatable(L, className);
2995                 lua_setmetatable(L, -2);
2996         }
2997
2998         static void set_null(lua_State *L)
2999         {
3000                 EnvRef *o = checkobject(L, -1);
3001                 o->m_env = NULL;
3002         }
3003         
3004         static void Register(lua_State *L)
3005         {
3006                 lua_newtable(L);
3007                 int methodtable = lua_gettop(L);
3008                 luaL_newmetatable(L, className);
3009                 int metatable = lua_gettop(L);
3010
3011                 lua_pushliteral(L, "__metatable");
3012                 lua_pushvalue(L, methodtable);
3013                 lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
3014
3015                 lua_pushliteral(L, "__index");
3016                 lua_pushvalue(L, methodtable);
3017                 lua_settable(L, metatable);
3018
3019                 lua_pushliteral(L, "__gc");
3020                 lua_pushcfunction(L, gc_object);
3021                 lua_settable(L, metatable);
3022
3023                 lua_pop(L, 1);  // drop metatable
3024
3025                 luaL_openlib(L, 0, methods, 0);  // fill methodtable
3026                 lua_pop(L, 1);  // drop methodtable
3027
3028                 // Cannot be created from Lua
3029                 //lua_register(L, className, create_object);
3030         }
3031 };
3032 const char EnvRef::className[] = "EnvRef";
3033 const luaL_reg EnvRef::methods[] = {
3034         method(EnvRef, add_node),
3035         method(EnvRef, remove_node),
3036         method(EnvRef, get_node),
3037         method(EnvRef, get_node_or_nil),
3038         method(EnvRef, get_node_light),
3039         method(EnvRef, add_entity),
3040         method(EnvRef, add_item),
3041         method(EnvRef, add_rat),
3042         method(EnvRef, add_firefly),
3043         method(EnvRef, get_meta),
3044         method(EnvRef, get_player_by_name),
3045         method(EnvRef, get_objects_inside_radius),
3046         {0,0}
3047 };
3048
3049 /*
3050         Main export function
3051 */
3052
3053 void scriptapi_export(lua_State *L, Server *server)
3054 {
3055         realitycheck(L);
3056         assert(lua_checkstack(L, 20));
3057         infostream<<"scriptapi_export"<<std::endl;
3058         StackUnroller stack_unroller(L);
3059
3060         // Store server as light userdata in registry
3061         lua_pushlightuserdata(L, server);
3062         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
3063
3064         // Store nil as minetest_nodedef_defaults in registry
3065         lua_pushnil(L);
3066         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_nodedef_default");
3067         
3068         // Register global functions in table minetest
3069         lua_newtable(L);
3070         luaL_register(L, NULL, minetest_f);
3071         lua_setglobal(L, "minetest");
3072         
3073         // Get the main minetest table
3074         lua_getglobal(L, "minetest");
3075
3076         // Add tables to minetest
3077         
3078         lua_newtable(L);
3079         lua_setfield(L, -2, "registered_nodes");
3080         lua_newtable(L);
3081         lua_setfield(L, -2, "registered_entities");
3082         lua_newtable(L);
3083         lua_setfield(L, -2, "registered_craftitems");
3084         lua_newtable(L);
3085         lua_setfield(L, -2, "registered_abms");
3086         
3087         lua_newtable(L);
3088         lua_setfield(L, -2, "object_refs");
3089         lua_newtable(L);
3090         lua_setfield(L, -2, "luaentities");
3091
3092         // Create entity prototype
3093         luaL_newmetatable(L, "minetest.entity");
3094         // metatable.__index = metatable
3095         lua_pushvalue(L, -1); // Duplicate metatable
3096         lua_setfield(L, -2, "__index");
3097         // Put functions in metatable
3098         luaL_register(L, NULL, minetest_entity_m);
3099         // Put other stuff in metatable
3100         
3101         // Register reference wrappers
3102         NodeMetaRef::Register(L);
3103         EnvRef::Register(L);
3104         ObjectRef::Register(L);
3105 }
3106
3107 bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
3108                 const std::string &modname)
3109 {
3110         ModNameStorer modnamestorer(L, modname);
3111
3112         if(!string_allowed(modname, "abcdefghijklmnopqrstuvwxyz"
3113                         "0123456789_")){
3114                 errorstream<<"Error loading mod \""<<modname
3115                                 <<"\": modname does not follow naming conventions: "
3116                                 <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
3117                 return false;
3118         }
3119         
3120         bool success = false;
3121
3122         try{
3123                 success = script_load(L, scriptpath.c_str());
3124         }
3125         catch(LuaError &e){
3126                 errorstream<<"Error loading mod \""<<modname
3127                                 <<"\": "<<e.what()<<std::endl;
3128         }
3129
3130         return success;
3131 }
3132
3133 void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
3134 {
3135         realitycheck(L);
3136         assert(lua_checkstack(L, 20));
3137         infostream<<"scriptapi_add_environment"<<std::endl;
3138         StackUnroller stack_unroller(L);
3139
3140         // Create EnvRef on stack
3141         EnvRef::create(L, env);
3142         int envref = lua_gettop(L);
3143
3144         // minetest.env = envref
3145         lua_getglobal(L, "minetest");
3146         luaL_checktype(L, -1, LUA_TTABLE);
3147         lua_pushvalue(L, envref);
3148         lua_setfield(L, -2, "env");
3149
3150         // Store environment as light userdata in registry
3151         lua_pushlightuserdata(L, env);
3152         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
3153
3154         /*
3155                 Add ActiveBlockModifiers to environment
3156         */
3157
3158         // Get minetest.registered_abms
3159         lua_getglobal(L, "minetest");
3160         lua_getfield(L, -1, "registered_abms");
3161         luaL_checktype(L, -1, LUA_TTABLE);
3162         int registered_abms = lua_gettop(L);
3163         
3164         if(lua_istable(L, registered_abms)){
3165                 int table = lua_gettop(L);
3166                 lua_pushnil(L);
3167                 while(lua_next(L, table) != 0){
3168                         // key at index -2 and value at index -1
3169                         int id = lua_tonumber(L, -2);
3170                         int current_abm = lua_gettop(L);
3171
3172                         std::set<std::string> trigger_contents;
3173                         lua_getfield(L, current_abm, "nodenames");
3174                         if(lua_istable(L, -1)){
3175                                 int table = lua_gettop(L);
3176                                 lua_pushnil(L);
3177                                 while(lua_next(L, table) != 0){
3178                                         // key at index -2 and value at index -1
3179                                         luaL_checktype(L, -1, LUA_TSTRING);
3180                                         trigger_contents.insert(lua_tostring(L, -1));
3181                                         // removes value, keeps key for next iteration
3182                                         lua_pop(L, 1);
3183                                 }
3184                         } else if(lua_isstring(L, -1)){
3185                                 trigger_contents.insert(lua_tostring(L, -1));
3186                         }
3187                         lua_pop(L, 1);
3188
3189                         std::set<std::string> required_neighbors;
3190                         lua_getfield(L, current_abm, "neighbors");
3191                         if(lua_istable(L, -1)){
3192                                 int table = lua_gettop(L);
3193                                 lua_pushnil(L);
3194                                 while(lua_next(L, table) != 0){
3195                                         // key at index -2 and value at index -1
3196                                         luaL_checktype(L, -1, LUA_TSTRING);
3197                                         required_neighbors.insert(lua_tostring(L, -1));
3198                                         // removes value, keeps key for next iteration
3199                                         lua_pop(L, 1);
3200                                 }
3201                         } else if(lua_isstring(L, -1)){
3202                                 required_neighbors.insert(lua_tostring(L, -1));
3203                         }
3204                         lua_pop(L, 1);
3205
3206                         float trigger_interval = 10.0;
3207                         getfloatfield(L, current_abm, "interval", trigger_interval);
3208
3209                         int trigger_chance = 50;
3210                         getintfield(L, current_abm, "chance", trigger_chance);
3211
3212                         LuaABM *abm = new LuaABM(L, id, trigger_contents,
3213                                         required_neighbors, trigger_interval, trigger_chance);
3214                         
3215                         env->addActiveBlockModifier(abm);
3216
3217                         // removes value, keeps key for next iteration
3218                         lua_pop(L, 1);
3219                 }
3220         }
3221         lua_pop(L, 1);
3222 }
3223
3224 #if 0
3225 // Dump stack top with the dump2 function
3226 static void dump2(lua_State *L, const char *name)
3227 {
3228         // Dump object (debug)
3229         lua_getglobal(L, "dump2");
3230         luaL_checktype(L, -1, LUA_TFUNCTION);
3231         lua_pushvalue(L, -2); // Get previous stack top as first parameter
3232         lua_pushstring(L, name);
3233         if(lua_pcall(L, 2, 0, 0))
3234                 script_error(L, "error: %s", lua_tostring(L, -1));
3235 }
3236 #endif
3237
3238 /*
3239         object_reference
3240 */
3241
3242 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
3243 {
3244         realitycheck(L);
3245         assert(lua_checkstack(L, 20));
3246         //infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
3247         StackUnroller stack_unroller(L);
3248
3249         // Create object on stack
3250         ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
3251         int object = lua_gettop(L);
3252
3253         // Get minetest.object_refs table
3254         lua_getglobal(L, "minetest");
3255         lua_getfield(L, -1, "object_refs");
3256         luaL_checktype(L, -1, LUA_TTABLE);
3257         int objectstable = lua_gettop(L);
3258         
3259         // object_refs[id] = object
3260         lua_pushnumber(L, cobj->getId()); // Push id
3261         lua_pushvalue(L, object); // Copy object to top of stack
3262         lua_settable(L, objectstable);
3263 }
3264
3265 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
3266 {
3267         realitycheck(L);
3268         assert(lua_checkstack(L, 20));
3269         //infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
3270         StackUnroller stack_unroller(L);
3271
3272         // Get minetest.object_refs table
3273         lua_getglobal(L, "minetest");
3274         lua_getfield(L, -1, "object_refs");
3275         luaL_checktype(L, -1, LUA_TTABLE);
3276         int objectstable = lua_gettop(L);
3277         
3278         // Get object_refs[id]
3279         lua_pushnumber(L, cobj->getId()); // Push id
3280         lua_gettable(L, objectstable);
3281         // Set object reference to NULL
3282         ObjectRef::set_null(L);
3283         lua_pop(L, 1); // pop object
3284
3285         // Set object_refs[id] = nil
3286         lua_pushnumber(L, cobj->getId()); // Push id
3287         lua_pushnil(L);
3288         lua_settable(L, objectstable);
3289 }
3290
3291 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
3292                 const std::string &message)
3293 {
3294         realitycheck(L);
3295         assert(lua_checkstack(L, 20));
3296         StackUnroller stack_unroller(L);
3297
3298         // Get minetest.registered_on_chat_messages
3299         lua_getglobal(L, "minetest");
3300         lua_getfield(L, -1, "registered_on_chat_messages");
3301         luaL_checktype(L, -1, LUA_TTABLE);
3302         int table = lua_gettop(L);
3303         // Foreach
3304         lua_pushnil(L);
3305         while(lua_next(L, table) != 0){
3306                 // key at index -2 and value at index -1
3307                 luaL_checktype(L, -1, LUA_TFUNCTION);
3308                 // Call function
3309                 lua_pushstring(L, name.c_str());
3310                 lua_pushstring(L, message.c_str());
3311                 if(lua_pcall(L, 2, 1, 0))
3312                         script_error(L, "error: %s", lua_tostring(L, -1));
3313                 bool ate = lua_toboolean(L, -1);
3314                 lua_pop(L, 1);
3315                 if(ate)
3316                         return true;
3317                 // value removed, keep key for next iteration
3318         }
3319         return false;
3320 }
3321
3322 /*
3323         misc
3324 */
3325
3326 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
3327 {
3328         realitycheck(L);
3329         assert(lua_checkstack(L, 20));
3330         StackUnroller stack_unroller(L);
3331
3332         // Get minetest.registered_on_newplayers
3333         lua_getglobal(L, "minetest");
3334         lua_getfield(L, -1, "registered_on_newplayers");
3335         luaL_checktype(L, -1, LUA_TTABLE);
3336         int table = lua_gettop(L);
3337         // Foreach
3338         lua_pushnil(L);
3339         while(lua_next(L, table) != 0){
3340                 // key at index -2 and value at index -1
3341                 luaL_checktype(L, -1, LUA_TFUNCTION);
3342                 // Call function
3343                 objectref_get_or_create(L, player);
3344                 if(lua_pcall(L, 1, 0, 0))
3345                         script_error(L, "error: %s", lua_tostring(L, -1));
3346                 // value removed, keep key for next iteration
3347         }
3348 }
3349 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
3350 {
3351         realitycheck(L);
3352         assert(lua_checkstack(L, 20));
3353         StackUnroller stack_unroller(L);
3354
3355         bool positioning_handled_by_some = false;
3356
3357         // Get minetest.registered_on_respawnplayers
3358         lua_getglobal(L, "minetest");
3359         lua_getfield(L, -1, "registered_on_respawnplayers");
3360         luaL_checktype(L, -1, LUA_TTABLE);
3361         int table = lua_gettop(L);
3362         // Foreach
3363         lua_pushnil(L);
3364         while(lua_next(L, table) != 0){
3365                 // key at index -2 and value at index -1
3366                 luaL_checktype(L, -1, LUA_TFUNCTION);
3367                 // Call function
3368                 objectref_get_or_create(L, player);
3369                 if(lua_pcall(L, 1, 1, 0))
3370                         script_error(L, "error: %s", lua_tostring(L, -1));
3371                 bool positioning_handled = lua_toboolean(L, -1);
3372                 lua_pop(L, 1);
3373                 if(positioning_handled)
3374                         positioning_handled_by_some = true;
3375                 // value removed, keep key for next iteration
3376         }
3377         return positioning_handled_by_some;
3378 }
3379
3380 void scriptapi_get_creative_inventory(lua_State *L, ServerRemotePlayer *player)
3381 {
3382         lua_getglobal(L, "minetest");
3383         lua_getfield(L, -1, "creative_inventory");
3384         luaL_checktype(L, -1, LUA_TTABLE);
3385         inventory_set_list_from_lua(&player->inventory, "main", L, -1,
3386                         player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
3387 }
3388
3389 /*
3390         craftitem
3391 */
3392
3393 static void pushPointedThing(lua_State *L, const PointedThing& pointed)
3394 {
3395         lua_newtable(L);
3396         if(pointed.type == POINTEDTHING_NODE)
3397         {
3398                 lua_pushstring(L, "node");
3399                 lua_setfield(L, -2, "type");
3400                 pushpos(L, pointed.node_undersurface);
3401                 lua_setfield(L, -2, "under");
3402                 pushpos(L, pointed.node_abovesurface);
3403                 lua_setfield(L, -2, "above");
3404         }
3405         else if(pointed.type == POINTEDTHING_OBJECT)
3406         {
3407                 lua_pushstring(L, "object");
3408                 lua_setfield(L, -2, "type");
3409                 objectref_get(L, pointed.object_id);
3410                 lua_setfield(L, -2, "ref");
3411         }
3412         else
3413         {
3414                 lua_pushstring(L, "nothing");
3415                 lua_setfield(L, -2, "type");
3416         }
3417 }
3418
3419 void scriptapi_add_craftitem(lua_State *L, const char *name)
3420 {
3421         StackUnroller stack_unroller(L);
3422         assert(lua_gettop(L) > 0);
3423
3424         // Set minetest.registered_craftitems[name] = table on top of stack
3425         lua_getglobal(L, "minetest");
3426         lua_getfield(L, -1, "registered_craftitems");
3427         luaL_checktype(L, -1, LUA_TTABLE);
3428         lua_pushvalue(L, -3); // push another reference to the table to be registered
3429         lua_setfield(L, -2, name); // set minetest.registered_craftitems[name]
3430 }
3431
3432 static bool get_craftitem_callback(lua_State *L, const char *name,
3433                 const char *callbackname)
3434 {
3435         // Get minetest.registered_craftitems[name][callbackname]
3436         // If that is nil or on error, return false and stack is unchanged
3437         // If that is a function, returns true and pushes the
3438         // function onto the stack
3439
3440         lua_getglobal(L, "minetest");
3441         lua_getfield(L, -1, "registered_craftitems");
3442         lua_remove(L, -2);
3443         luaL_checktype(L, -1, LUA_TTABLE);
3444         lua_getfield(L, -1, name);
3445         lua_remove(L, -2);
3446         // Should be a table
3447         if(lua_type(L, -1) != LUA_TTABLE)
3448         {
3449                 errorstream<<"CraftItem name \""<<name<<"\" not defined"<<std::endl;
3450                 lua_pop(L, 1);
3451                 return false;
3452         }
3453         lua_getfield(L, -1, callbackname);
3454         lua_remove(L, -2);
3455         // Should be a function or nil
3456         if(lua_type(L, -1) == LUA_TFUNCTION)
3457         {
3458                 return true;
3459         }
3460         else if(lua_isnil(L, -1))
3461         {
3462                 lua_pop(L, 1);
3463                 return false;
3464         }
3465         else
3466         {
3467                 errorstream<<"CraftItem name \""<<name<<"\" callback \""
3468                         <<callbackname<<" is not a function"<<std::endl;
3469                 lua_pop(L, 1);
3470                 return false;
3471         }
3472 }
3473
3474 bool scriptapi_craftitem_on_drop(lua_State *L, const char *name,
3475                 ServerActiveObject *dropper, v3f pos,
3476                 bool &callback_exists)
3477 {
3478         realitycheck(L);
3479         assert(lua_checkstack(L, 20));
3480         //infostream<<"scriptapi_craftitem_on_drop"<<std::endl;
3481         StackUnroller stack_unroller(L);
3482
3483         bool result = false;
3484         callback_exists = get_craftitem_callback(L, name, "on_drop");
3485         if(callback_exists)
3486         {
3487                 // Call function
3488                 lua_pushstring(L, name);
3489                 objectref_get_or_create(L, dropper);
3490                 pushFloatPos(L, pos);
3491                 if(lua_pcall(L, 3, 1, 0))
3492                         script_error(L, "error: %s", lua_tostring(L, -1));
3493                 result = lua_toboolean(L, -1);
3494         }
3495         return result;
3496 }
3497
3498 bool scriptapi_craftitem_on_place_on_ground(lua_State *L, const char *name,
3499                 ServerActiveObject *placer, v3f pos,
3500                 bool &callback_exists)
3501 {
3502         realitycheck(L);
3503         assert(lua_checkstack(L, 20));
3504         //infostream<<"scriptapi_craftitem_on_place_on_ground"<<std::endl;
3505         StackUnroller stack_unroller(L);
3506
3507         bool result = false;
3508         callback_exists = get_craftitem_callback(L, name, "on_place_on_ground");
3509         if(callback_exists)
3510         {
3511                 // Call function
3512                 lua_pushstring(L, name);
3513                 objectref_get_or_create(L, placer);
3514                 pushFloatPos(L, pos);
3515                 if(lua_pcall(L, 3, 1, 0))
3516                         script_error(L, "error: %s", lua_tostring(L, -1));
3517                 result = lua_toboolean(L, -1);
3518         }
3519         return result;
3520 }
3521
3522 bool scriptapi_craftitem_on_use(lua_State *L, const char *name,
3523                 ServerActiveObject *user, const PointedThing& pointed,
3524                 bool &callback_exists)
3525 {
3526         realitycheck(L);
3527         assert(lua_checkstack(L, 20));
3528         //infostream<<"scriptapi_craftitem_on_use"<<std::endl;
3529         StackUnroller stack_unroller(L);
3530
3531         bool result = false;
3532         callback_exists = get_craftitem_callback(L, name, "on_use");
3533         if(callback_exists)
3534         {
3535                 // Call function
3536                 lua_pushstring(L, name);
3537                 objectref_get_or_create(L, user);
3538                 pushPointedThing(L, pointed);
3539                 if(lua_pcall(L, 3, 1, 0))
3540                         script_error(L, "error: %s", lua_tostring(L, -1));
3541                 result = lua_toboolean(L, -1);
3542         }
3543         return result;
3544 }
3545
3546 /*
3547         environment
3548 */
3549
3550 void scriptapi_environment_step(lua_State *L, float dtime)
3551 {
3552         realitycheck(L);
3553         assert(lua_checkstack(L, 20));
3554         //infostream<<"scriptapi_environment_step"<<std::endl;
3555         StackUnroller stack_unroller(L);
3556
3557         // Get minetest.registered_globalsteps
3558         lua_getglobal(L, "minetest");
3559         lua_getfield(L, -1, "registered_globalsteps");
3560         luaL_checktype(L, -1, LUA_TTABLE);
3561         int table = lua_gettop(L);
3562         // Foreach
3563         lua_pushnil(L);
3564         while(lua_next(L, table) != 0){
3565                 // key at index -2 and value at index -1
3566                 luaL_checktype(L, -1, LUA_TFUNCTION);
3567                 // Call function
3568                 lua_pushnumber(L, dtime);
3569                 if(lua_pcall(L, 1, 0, 0))
3570                         script_error(L, "error: %s", lua_tostring(L, -1));
3571                 // value removed, keep key for next iteration
3572         }
3573 }
3574
3575 void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
3576                 ServerActiveObject *placer)
3577 {
3578         realitycheck(L);
3579         assert(lua_checkstack(L, 20));
3580         //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
3581         StackUnroller stack_unroller(L);
3582
3583         // Get the writable node definition manager from the server
3584         IWritableNodeDefManager *ndef =
3585                         get_server(L)->getWritableNodeDefManager();
3586         
3587         // Get minetest.registered_on_placenodes
3588         lua_getglobal(L, "minetest");
3589         lua_getfield(L, -1, "registered_on_placenodes");
3590         luaL_checktype(L, -1, LUA_TTABLE);
3591         int table = lua_gettop(L);
3592         // Foreach
3593         lua_pushnil(L);
3594         while(lua_next(L, table) != 0){
3595                 // key at index -2 and value at index -1
3596                 luaL_checktype(L, -1, LUA_TFUNCTION);
3597                 // Call function
3598                 pushpos(L, p);
3599                 pushnode(L, newnode, ndef);
3600                 objectref_get_or_create(L, placer);
3601                 if(lua_pcall(L, 3, 0, 0))
3602                         script_error(L, "error: %s", lua_tostring(L, -1));
3603                 // value removed, keep key for next iteration
3604         }
3605 }
3606
3607 void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
3608                 ServerActiveObject *digger)
3609 {
3610         realitycheck(L);
3611         assert(lua_checkstack(L, 20));
3612         //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
3613         StackUnroller stack_unroller(L);
3614
3615         // Get the writable node definition manager from the server
3616         IWritableNodeDefManager *ndef =
3617                         get_server(L)->getWritableNodeDefManager();
3618         
3619         // Get minetest.registered_on_dignodes
3620         lua_getglobal(L, "minetest");
3621         lua_getfield(L, -1, "registered_on_dignodes");
3622         luaL_checktype(L, -1, LUA_TTABLE);
3623         int table = lua_gettop(L);
3624         // Foreach
3625         lua_pushnil(L);
3626         while(lua_next(L, table) != 0){
3627                 // key at index -2 and value at index -1
3628                 luaL_checktype(L, -1, LUA_TFUNCTION);
3629                 // Call function
3630                 pushpos(L, p);
3631                 pushnode(L, oldnode, ndef);
3632                 objectref_get_or_create(L, digger);
3633                 if(lua_pcall(L, 3, 0, 0))
3634                         script_error(L, "error: %s", lua_tostring(L, -1));
3635                 // value removed, keep key for next iteration
3636         }
3637 }
3638
3639 void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
3640                 ServerActiveObject *puncher)
3641 {
3642         realitycheck(L);
3643         assert(lua_checkstack(L, 20));
3644         //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
3645         StackUnroller stack_unroller(L);
3646
3647         // Get the writable node definition manager from the server
3648         IWritableNodeDefManager *ndef =
3649                         get_server(L)->getWritableNodeDefManager();
3650         
3651         // Get minetest.registered_on_punchnodes
3652         lua_getglobal(L, "minetest");
3653         lua_getfield(L, -1, "registered_on_punchnodes");
3654         luaL_checktype(L, -1, LUA_TTABLE);
3655         int table = lua_gettop(L);
3656         // Foreach
3657         lua_pushnil(L);
3658         while(lua_next(L, table) != 0){
3659                 // key at index -2 and value at index -1
3660                 luaL_checktype(L, -1, LUA_TFUNCTION);
3661                 // Call function
3662                 pushpos(L, p);
3663                 pushnode(L, node, ndef);
3664                 objectref_get_or_create(L, puncher);
3665                 if(lua_pcall(L, 3, 0, 0))
3666                         script_error(L, "error: %s", lua_tostring(L, -1));
3667                 // value removed, keep key for next iteration
3668         }
3669 }
3670
3671 void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
3672 {
3673         realitycheck(L);
3674         assert(lua_checkstack(L, 20));
3675         //infostream<<"scriptapi_environment_on_generated"<<std::endl;
3676         StackUnroller stack_unroller(L);
3677
3678         // Get minetest.registered_on_generateds
3679         lua_getglobal(L, "minetest");
3680         lua_getfield(L, -1, "registered_on_generateds");
3681         luaL_checktype(L, -1, LUA_TTABLE);
3682         int table = lua_gettop(L);
3683         // Foreach
3684         lua_pushnil(L);
3685         while(lua_next(L, table) != 0){
3686                 // key at index -2 and value at index -1
3687                 luaL_checktype(L, -1, LUA_TFUNCTION);
3688                 // Call function
3689                 pushpos(L, minp);
3690                 pushpos(L, maxp);
3691                 if(lua_pcall(L, 2, 0, 0))
3692                         script_error(L, "error: %s", lua_tostring(L, -1));
3693                 // value removed, keep key for next iteration
3694         }
3695 }
3696
3697 /*
3698         luaentity
3699 */
3700
3701 bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
3702                 const std::string &staticdata)
3703 {
3704         realitycheck(L);
3705         assert(lua_checkstack(L, 20));
3706         infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
3707                         <<name<<"\""<<std::endl;
3708         StackUnroller stack_unroller(L);
3709         
3710         // Get minetest.registered_entities[name]
3711         lua_getglobal(L, "minetest");
3712         lua_getfield(L, -1, "registered_entities");
3713         luaL_checktype(L, -1, LUA_TTABLE);
3714         lua_pushstring(L, name);
3715         lua_gettable(L, -2);
3716         // Should be a table, which we will use as a prototype
3717         //luaL_checktype(L, -1, LUA_TTABLE);
3718         if(lua_type(L, -1) != LUA_TTABLE){
3719                 errorstream<<"LuaEntity name \""<<name<<"\" not defined"<<std::endl;
3720                 return false;
3721         }
3722         int prototype_table = lua_gettop(L);
3723         //dump2(L, "prototype_table");
3724         
3725         // Create entity object
3726         lua_newtable(L);
3727         int object = lua_gettop(L);
3728
3729         // Set object metatable
3730         lua_pushvalue(L, prototype_table);
3731         lua_setmetatable(L, -2);
3732         
3733         // Add object reference
3734         // This should be userdata with metatable ObjectRef
3735         objectref_get(L, id);
3736         luaL_checktype(L, -1, LUA_TUSERDATA);
3737         if(!luaL_checkudata(L, -1, "ObjectRef"))
3738                 luaL_typerror(L, -1, "ObjectRef");
3739         lua_setfield(L, -2, "object");
3740
3741         // minetest.luaentities[id] = object
3742         lua_getglobal(L, "minetest");
3743         lua_getfield(L, -1, "luaentities");
3744         luaL_checktype(L, -1, LUA_TTABLE);
3745         lua_pushnumber(L, id); // Push id
3746         lua_pushvalue(L, object); // Copy object to top of stack
3747         lua_settable(L, -3);
3748         
3749         // Get on_activate function
3750         lua_pushvalue(L, object);
3751         lua_getfield(L, -1, "on_activate");
3752         if(!lua_isnil(L, -1)){
3753                 luaL_checktype(L, -1, LUA_TFUNCTION);
3754                 lua_pushvalue(L, object); // self
3755                 lua_pushlstring(L, staticdata.c_str(), staticdata.size());
3756                 // Call with 2 arguments, 0 results
3757                 if(lua_pcall(L, 2, 0, 0))
3758                         script_error(L, "error running function %s:on_activate: %s\n",
3759                                         name, lua_tostring(L, -1));
3760         }
3761         
3762         return true;
3763 }
3764
3765 void scriptapi_luaentity_rm(lua_State *L, u16 id)
3766 {
3767         realitycheck(L);
3768         assert(lua_checkstack(L, 20));
3769         infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
3770
3771         // Get minetest.luaentities table
3772         lua_getglobal(L, "minetest");
3773         lua_getfield(L, -1, "luaentities");
3774         luaL_checktype(L, -1, LUA_TTABLE);
3775         int objectstable = lua_gettop(L);
3776         
3777         // Set luaentities[id] = nil
3778         lua_pushnumber(L, id); // Push id
3779         lua_pushnil(L);
3780         lua_settable(L, objectstable);
3781         
3782         lua_pop(L, 2); // pop luaentities, minetest
3783 }
3784
3785 std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
3786 {
3787         realitycheck(L);
3788         assert(lua_checkstack(L, 20));
3789         infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
3790         StackUnroller stack_unroller(L);
3791
3792         // Get minetest.luaentities[id]
3793         luaentity_get(L, id);
3794         int object = lua_gettop(L);
3795         
3796         // Get get_staticdata function
3797         lua_pushvalue(L, object);
3798         lua_getfield(L, -1, "get_staticdata");
3799         if(lua_isnil(L, -1))
3800                 return "";
3801         
3802         luaL_checktype(L, -1, LUA_TFUNCTION);
3803         lua_pushvalue(L, object); // self
3804         // Call with 1 arguments, 1 results
3805         if(lua_pcall(L, 1, 1, 0))
3806                 script_error(L, "error running function get_staticdata: %s\n",
3807                                 lua_tostring(L, -1));
3808         
3809         size_t len=0;
3810         const char *s = lua_tolstring(L, -1, &len);
3811         return std::string(s, len);
3812 }
3813
3814 void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
3815                 LuaEntityProperties *prop)
3816 {
3817         realitycheck(L);
3818         assert(lua_checkstack(L, 20));
3819         infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
3820         StackUnroller stack_unroller(L);
3821
3822         // Get minetest.luaentities[id]
3823         luaentity_get(L, id);
3824         //int object = lua_gettop(L);
3825
3826         /* Read stuff */
3827         
3828         getboolfield(L, -1, "physical", prop->physical);
3829
3830         getfloatfield(L, -1, "weight", prop->weight);
3831
3832         lua_getfield(L, -1, "collisionbox");
3833         if(lua_istable(L, -1))
3834                 prop->collisionbox = read_aabbox3df32(L, -1, 1.0);
3835         lua_pop(L, 1);
3836
3837         getstringfield(L, -1, "visual", prop->visual);
3838         
3839         lua_getfield(L, -1, "visual_size");
3840         if(lua_istable(L, -1))
3841                 prop->visual_size = read_v2f(L, -1);
3842         lua_pop(L, 1);
3843
3844         lua_getfield(L, -1, "textures");
3845         if(lua_istable(L, -1)){
3846                 prop->textures.clear();
3847                 int table = lua_gettop(L);
3848                 lua_pushnil(L);
3849                 while(lua_next(L, table) != 0){
3850                         // key at index -2 and value at index -1
3851                         if(lua_isstring(L, -1))
3852                                 prop->textures.push_back(lua_tostring(L, -1));
3853                         else
3854                                 prop->textures.push_back("");
3855                         // removes value, keeps key for next iteration
3856                         lua_pop(L, 1);
3857                 }
3858         }
3859         lua_pop(L, 1);
3860         
3861         lua_getfield(L, -1, "spritediv");
3862         if(lua_istable(L, -1))
3863                 prop->spritediv = read_v2s16(L, -1);
3864         lua_pop(L, 1);
3865
3866         lua_getfield(L, -1, "initial_sprite_basepos");
3867         if(lua_istable(L, -1))
3868                 prop->initial_sprite_basepos = read_v2s16(L, -1);
3869         lua_pop(L, 1);
3870 }
3871
3872 void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
3873 {
3874         realitycheck(L);
3875         assert(lua_checkstack(L, 20));
3876         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
3877         StackUnroller stack_unroller(L);
3878
3879         // Get minetest.luaentities[id]
3880         luaentity_get(L, id);
3881         int object = lua_gettop(L);
3882         // State: object is at top of stack
3883         // Get step function
3884         lua_getfield(L, -1, "on_step");
3885         if(lua_isnil(L, -1))
3886                 return;
3887         luaL_checktype(L, -1, LUA_TFUNCTION);
3888         lua_pushvalue(L, object); // self
3889         lua_pushnumber(L, dtime); // dtime
3890         // Call with 2 arguments, 0 results
3891         if(lua_pcall(L, 2, 0, 0))
3892                 script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
3893 }
3894
3895 // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch)
3896 void scriptapi_luaentity_punch(lua_State *L, u16 id,
3897                 ServerActiveObject *puncher, float time_from_last_punch)
3898 {
3899         realitycheck(L);
3900         assert(lua_checkstack(L, 20));
3901         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
3902         StackUnroller stack_unroller(L);
3903
3904         // Get minetest.luaentities[id]
3905         luaentity_get(L, id);
3906         int object = lua_gettop(L);
3907         // State: object is at top of stack
3908         // Get function
3909         lua_getfield(L, -1, "on_punch");
3910         if(lua_isnil(L, -1))
3911                 return;
3912         luaL_checktype(L, -1, LUA_TFUNCTION);
3913         lua_pushvalue(L, object); // self
3914         objectref_get_or_create(L, puncher); // Clicker reference
3915         lua_pushnumber(L, time_from_last_punch);
3916         // Call with 2 arguments, 0 results
3917         if(lua_pcall(L, 3, 0, 0))
3918                 script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
3919 }
3920
3921 // Calls entity:on_rightclick(ObjectRef clicker)
3922 void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
3923                 ServerActiveObject *clicker)
3924 {
3925         realitycheck(L);
3926         assert(lua_checkstack(L, 20));
3927         //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
3928         StackUnroller stack_unroller(L);
3929
3930         // Get minetest.luaentities[id]
3931         luaentity_get(L, id);
3932         int object = lua_gettop(L);
3933         // State: object is at top of stack
3934         // Get function
3935         lua_getfield(L, -1, "on_rightclick");
3936         if(lua_isnil(L, -1))
3937                 return;
3938         luaL_checktype(L, -1, LUA_TFUNCTION);
3939         lua_pushvalue(L, object); // self
3940         objectref_get_or_create(L, clicker); // Clicker reference
3941         // Call with 2 arguments, 0 results
3942         if(lua_pcall(L, 2, 0, 0))
3943                 script_error(L, "error running function 'on_rightclick': %s\n", lua_tostring(L, -1));
3944 }
3945