Optional dependencies and properly handle mod name conflicts again
[oweals/minetest.git] / src / scriptapi.cpp
1 /*
2 Minetest
3 Copyright (C) 2013 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 Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser 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 "settings.h" // For accessing g_settings
31 #include "main.h" // For g_settings
32 #include "biome.h"
33 #include "emerge.h"
34 #include "script.h"
35 #include "rollback.h"
36
37 #include "scriptapi_types.h"
38 #include "scriptapi_env.h"
39 #include "scriptapi_nodetimer.h"
40 #include "scriptapi_inventory.h"
41 #include "scriptapi_nodemeta.h"
42 #include "scriptapi_object.h"
43 #include "scriptapi_noise.h"
44 #include "scriptapi_common.h"
45 #include "scriptapi_item.h"
46 #include "scriptapi_content.h"
47 #include "scriptapi_craft.h"
48 #include "scriptapi_particles.h"
49
50 /*****************************************************************************/
51 /* Mod related                                                               */
52 /*****************************************************************************/
53
54 class ModNameStorer
55 {
56 private:
57         lua_State *L;
58 public:
59         ModNameStorer(lua_State *L_, const std::string modname):
60                 L(L_)
61         {
62                 // Store current modname in registry
63                 lua_pushstring(L, modname.c_str());
64                 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
65         }
66         ~ModNameStorer()
67         {
68                 // Clear current modname in registry
69                 lua_pushnil(L);
70                 lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
71         }
72 };
73
74 bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
75                 const std::string &modname)
76 {
77         ModNameStorer modnamestorer(L, modname);
78
79         if(!string_allowed(modname, MODNAME_ALLOWED_CHARS)){
80                 errorstream<<"Error loading mod \""<<modname
81                                 <<"\": modname does not follow naming conventions: "
82                                 <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
83                 return false;
84         }
85
86         bool success = false;
87
88         try{
89                 success = script_load(L, scriptpath.c_str());
90         }
91         catch(LuaError &e){
92                 errorstream<<"Error loading mod \""<<modname
93                                 <<"\": "<<e.what()<<std::endl;
94         }
95
96         return success;
97 }
98
99
100 /*****************************************************************************/
101 /* Auth                                                                      */
102 /*****************************************************************************/
103
104 /*
105         Privileges
106 */
107 static void read_privileges(lua_State *L, int index,
108                 std::set<std::string> &result)
109 {
110         result.clear();
111         lua_pushnil(L);
112         if(index < 0)
113                 index -= 1;
114         while(lua_next(L, index) != 0){
115                 // key at index -2 and value at index -1
116                 std::string key = luaL_checkstring(L, -2);
117                 bool value = lua_toboolean(L, -1);
118                 if(value)
119                         result.insert(key);
120                 // removes value, keeps key for next iteration
121                 lua_pop(L, 1);
122         }
123 }
124
125 static void get_auth_handler(lua_State *L)
126 {
127         lua_getglobal(L, "minetest");
128         lua_getfield(L, -1, "registered_auth_handler");
129         if(lua_isnil(L, -1)){
130                 lua_pop(L, 1);
131                 lua_getfield(L, -1, "builtin_auth_handler");
132         }
133         if(lua_type(L, -1) != LUA_TTABLE)
134                 throw LuaError(L, "Authentication handler table not valid");
135 }
136
137 bool scriptapi_get_auth(lua_State *L, const std::string &playername,
138                 std::string *dst_password, std::set<std::string> *dst_privs)
139 {
140         realitycheck(L);
141         assert(lua_checkstack(L, 20));
142         StackUnroller stack_unroller(L);
143
144         get_auth_handler(L);
145         lua_getfield(L, -1, "get_auth");
146         if(lua_type(L, -1) != LUA_TFUNCTION)
147                 throw LuaError(L, "Authentication handler missing get_auth");
148         lua_pushstring(L, playername.c_str());
149         if(lua_pcall(L, 1, 1, 0))
150                 script_error(L, "error: %s", lua_tostring(L, -1));
151
152         // nil = login not allowed
153         if(lua_isnil(L, -1))
154                 return false;
155         luaL_checktype(L, -1, LUA_TTABLE);
156
157         std::string password;
158         bool found = getstringfield(L, -1, "password", password);
159         if(!found)
160                 throw LuaError(L, "Authentication handler didn't return password");
161         if(dst_password)
162                 *dst_password = password;
163
164         lua_getfield(L, -1, "privileges");
165         if(!lua_istable(L, -1))
166                 throw LuaError(L,
167                                 "Authentication handler didn't return privilege table");
168         if(dst_privs)
169                 read_privileges(L, -1, *dst_privs);
170         lua_pop(L, 1);
171
172         return true;
173 }
174
175 void scriptapi_create_auth(lua_State *L, const std::string &playername,
176                 const std::string &password)
177 {
178         realitycheck(L);
179         assert(lua_checkstack(L, 20));
180         StackUnroller stack_unroller(L);
181
182         get_auth_handler(L);
183         lua_getfield(L, -1, "create_auth");
184         if(lua_type(L, -1) != LUA_TFUNCTION)
185                 throw LuaError(L, "Authentication handler missing create_auth");
186         lua_pushstring(L, playername.c_str());
187         lua_pushstring(L, password.c_str());
188         if(lua_pcall(L, 2, 0, 0))
189                 script_error(L, "error: %s", lua_tostring(L, -1));
190 }
191
192 bool scriptapi_set_password(lua_State *L, const std::string &playername,
193                 const std::string &password)
194 {
195         realitycheck(L);
196         assert(lua_checkstack(L, 20));
197         StackUnroller stack_unroller(L);
198
199         get_auth_handler(L);
200         lua_getfield(L, -1, "set_password");
201         if(lua_type(L, -1) != LUA_TFUNCTION)
202                 throw LuaError(L, "Authentication handler missing set_password");
203         lua_pushstring(L, playername.c_str());
204         lua_pushstring(L, password.c_str());
205         if(lua_pcall(L, 2, 1, 0))
206                 script_error(L, "error: %s", lua_tostring(L, -1));
207         return lua_toboolean(L, -1);
208 }
209
210 /*****************************************************************************/
211 /* Misc                                                                      */
212 /*****************************************************************************/
213 /*
214         Groups
215 */
216 void read_groups(lua_State *L, int index,
217                 std::map<std::string, int> &result)
218 {
219         if (!lua_istable(L,index))
220                 return;
221         result.clear();
222         lua_pushnil(L);
223         if(index < 0)
224                 index -= 1;
225         while(lua_next(L, index) != 0){
226                 // key at index -2 and value at index -1
227                 std::string name = luaL_checkstring(L, -2);
228                 int rating = luaL_checkinteger(L, -1);
229                 result[name] = rating;
230                 // removes value, keeps key for next iteration
231                 lua_pop(L, 1);
232         }
233 }
234
235 struct EnumString es_BiomeTerrainType[] =
236 {
237         {BIOME_TERRAIN_NORMAL, "normal"},
238         {BIOME_TERRAIN_LIQUID, "liquid"},
239         {BIOME_TERRAIN_NETHER, "nether"},
240         {BIOME_TERRAIN_AETHER, "aether"},
241         {BIOME_TERRAIN_FLAT,   "flat"},
242         {0, NULL},
243 };
244
245 struct EnumString es_OreType[] =
246 {
247         {ORE_SCATTER,  "scatter"},
248         {ORE_SHEET,    "sheet"},
249         {ORE_CLAYLIKE, "claylike"},
250         {0, NULL},
251 };
252
253 /*****************************************************************************/
254 /* Parameters                                                                */
255 /*****************************************************************************/
256 /*
257         DigParams
258 */
259
260 static void set_dig_params(lua_State *L, int table,
261                 const DigParams &params)
262 {
263         setboolfield(L, table, "diggable", params.diggable);
264         setfloatfield(L, table, "time", params.time);
265         setintfield(L, table, "wear", params.wear);
266 }
267
268 static void push_dig_params(lua_State *L,
269                 const DigParams &params)
270 {
271         lua_newtable(L);
272         set_dig_params(L, -1, params);
273 }
274
275 /*
276         HitParams
277 */
278
279 static void set_hit_params(lua_State *L, int table,
280                 const HitParams &params)
281 {
282         setintfield(L, table, "hp", params.hp);
283         setintfield(L, table, "wear", params.wear);
284 }
285
286 static void push_hit_params(lua_State *L,
287                 const HitParams &params)
288 {
289         lua_newtable(L);
290         set_hit_params(L, -1, params);
291 }
292
293 /*
294         ServerSoundParams
295 */
296
297 static void read_server_sound_params(lua_State *L, int index,
298                 ServerSoundParams &params)
299 {
300         if(index < 0)
301                 index = lua_gettop(L) + 1 + index;
302         // Clear
303         params = ServerSoundParams();
304         if(lua_istable(L, index)){
305                 getfloatfield(L, index, "gain", params.gain);
306                 getstringfield(L, index, "to_player", params.to_player);
307                 lua_getfield(L, index, "pos");
308                 if(!lua_isnil(L, -1)){
309                         v3f p = read_v3f(L, -1)*BS;
310                         params.pos = p;
311                         params.type = ServerSoundParams::SSP_POSITIONAL;
312                 }
313                 lua_pop(L, 1);
314                 lua_getfield(L, index, "object");
315                 if(!lua_isnil(L, -1)){
316                         ObjectRef *ref = ObjectRef::checkobject(L, -1);
317                         ServerActiveObject *sao = ObjectRef::getobject(ref);
318                         if(sao){
319                                 params.object = sao->getId();
320                                 params.type = ServerSoundParams::SSP_OBJECT;
321                         }
322                 }
323                 lua_pop(L, 1);
324                 params.max_hear_distance = BS*getfloatfield_default(L, index,
325                                 "max_hear_distance", params.max_hear_distance/BS);
326                 getboolfield(L, index, "loop", params.loop);
327         }
328 }
329
330 /*****************************************************************************/
331 /* callbacks                                                                 */
332 /*****************************************************************************/
333
334 // Push the list of callbacks (a lua table).
335 // Then push nargs arguments.
336 // Then call this function, which
337 // - runs the callbacks
338 // - removes the table and arguments from the lua stack
339 // - pushes the return value, computed depending on mode
340 void scriptapi_run_callbacks(lua_State *L, int nargs,
341                 RunCallbacksMode mode)
342 {
343         // Insert the return value into the lua stack, below the table
344         assert(lua_gettop(L) >= nargs + 1);
345         lua_pushnil(L);
346         lua_insert(L, -(nargs + 1) - 1);
347         // Stack now looks like this:
348         // ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n>
349
350         int rv = lua_gettop(L) - nargs - 1;
351         int table = rv + 1;
352         int arg = table + 1;
353
354         luaL_checktype(L, table, LUA_TTABLE);
355
356         // Foreach
357         lua_pushnil(L);
358         bool first_loop = true;
359         while(lua_next(L, table) != 0){
360                 // key at index -2 and value at index -1
361                 luaL_checktype(L, -1, LUA_TFUNCTION);
362                 // Call function
363                 for(int i = 0; i < nargs; i++)
364                         lua_pushvalue(L, arg+i);
365                 if(lua_pcall(L, nargs, 1, 0))
366                         script_error(L, "error: %s", lua_tostring(L, -1));
367
368                 // Move return value to designated space in stack
369                 // Or pop it
370                 if(first_loop){
371                         // Result of first callback is always moved
372                         lua_replace(L, rv);
373                         first_loop = false;
374                 } else {
375                         // Otherwise, what happens depends on the mode
376                         if(mode == RUN_CALLBACKS_MODE_FIRST)
377                                 lua_pop(L, 1);
378                         else if(mode == RUN_CALLBACKS_MODE_LAST)
379                                 lua_replace(L, rv);
380                         else if(mode == RUN_CALLBACKS_MODE_AND ||
381                                         mode == RUN_CALLBACKS_MODE_AND_SC){
382                                 if((bool)lua_toboolean(L, rv) == true &&
383                                                 (bool)lua_toboolean(L, -1) == false)
384                                         lua_replace(L, rv);
385                                 else
386                                         lua_pop(L, 1);
387                         }
388                         else if(mode == RUN_CALLBACKS_MODE_OR ||
389                                         mode == RUN_CALLBACKS_MODE_OR_SC){
390                                 if((bool)lua_toboolean(L, rv) == false &&
391                                                 (bool)lua_toboolean(L, -1) == true)
392                                         lua_replace(L, rv);
393                                 else
394                                         lua_pop(L, 1);
395                         }
396                         else
397                                 assert(0);
398                 }
399
400                 // Handle short circuit modes
401                 if(mode == RUN_CALLBACKS_MODE_AND_SC &&
402                                 (bool)lua_toboolean(L, rv) == false)
403                         break;
404                 else if(mode == RUN_CALLBACKS_MODE_OR_SC &&
405                                 (bool)lua_toboolean(L, rv) == true)
406                         break;
407
408                 // value removed, keep key for next iteration
409         }
410
411         // Remove stuff from stack, leaving only the return value
412         lua_settop(L, rv);
413
414         // Fix return value in case no callbacks were called
415         if(first_loop){
416                 if(mode == RUN_CALLBACKS_MODE_AND ||
417                                 mode == RUN_CALLBACKS_MODE_AND_SC){
418                         lua_pop(L, 1);
419                         lua_pushboolean(L, true);
420                 }
421                 else if(mode == RUN_CALLBACKS_MODE_OR ||
422                                 mode == RUN_CALLBACKS_MODE_OR_SC){
423                         lua_pop(L, 1);
424                         lua_pushboolean(L, false);
425                 }
426         }
427 }
428
429 bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
430                 const std::string &message)
431 {
432         realitycheck(L);
433         assert(lua_checkstack(L, 20));
434         StackUnroller stack_unroller(L);
435
436         // Get minetest.registered_on_chat_messages
437         lua_getglobal(L, "minetest");
438         lua_getfield(L, -1, "registered_on_chat_messages");
439         // Call callbacks
440         lua_pushstring(L, name.c_str());
441         lua_pushstring(L, message.c_str());
442         scriptapi_run_callbacks(L, 2, RUN_CALLBACKS_MODE_OR_SC);
443         bool ate = lua_toboolean(L, -1);
444         return ate;
445 }
446
447 void scriptapi_on_shutdown(lua_State *L)
448 {
449         realitycheck(L);
450         assert(lua_checkstack(L, 20));
451         StackUnroller stack_unroller(L);
452
453         // Get registered shutdown hooks
454         lua_getglobal(L, "minetest");
455         lua_getfield(L, -1, "registered_on_shutdown");
456         // Call callbacks
457         scriptapi_run_callbacks(L, 0, RUN_CALLBACKS_MODE_FIRST);
458 }
459
460 void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player)
461 {
462         realitycheck(L);
463         assert(lua_checkstack(L, 20));
464         StackUnroller stack_unroller(L);
465
466         // Get minetest.registered_on_newplayers
467         lua_getglobal(L, "minetest");
468         lua_getfield(L, -1, "registered_on_newplayers");
469         // Call callbacks
470         objectref_get_or_create(L, player);
471         scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
472 }
473
474 void scriptapi_on_dieplayer(lua_State *L, ServerActiveObject *player)
475 {
476         realitycheck(L);
477         assert(lua_checkstack(L, 20));
478         StackUnroller stack_unroller(L);
479
480         // Get minetest.registered_on_dieplayers
481         lua_getglobal(L, "minetest");
482         lua_getfield(L, -1, "registered_on_dieplayers");
483         // Call callbacks
484         objectref_get_or_create(L, player);
485         scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
486 }
487
488 bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player)
489 {
490         realitycheck(L);
491         assert(lua_checkstack(L, 20));
492         StackUnroller stack_unroller(L);
493
494         // Get minetest.registered_on_respawnplayers
495         lua_getglobal(L, "minetest");
496         lua_getfield(L, -1, "registered_on_respawnplayers");
497         // Call callbacks
498         objectref_get_or_create(L, player);
499         scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_OR);
500         bool positioning_handled_by_some = lua_toboolean(L, -1);
501         return positioning_handled_by_some;
502 }
503
504 void scriptapi_on_joinplayer(lua_State *L, ServerActiveObject *player)
505 {
506         realitycheck(L);
507         assert(lua_checkstack(L, 20));
508         StackUnroller stack_unroller(L);
509
510         // Get minetest.registered_on_joinplayers
511         lua_getglobal(L, "minetest");
512         lua_getfield(L, -1, "registered_on_joinplayers");
513         // Call callbacks
514         objectref_get_or_create(L, player);
515         scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
516 }
517
518 void scriptapi_on_leaveplayer(lua_State *L, ServerActiveObject *player)
519 {
520         realitycheck(L);
521         assert(lua_checkstack(L, 20));
522         StackUnroller stack_unroller(L);
523
524         // Get minetest.registered_on_leaveplayers
525         lua_getglobal(L, "minetest");
526         lua_getfield(L, -1, "registered_on_leaveplayers");
527         // Call callbacks
528         objectref_get_or_create(L, player);
529         scriptapi_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
530 }
531
532 /*
533         player
534 */
535 void scriptapi_on_player_receive_fields(lua_State *L,
536                 ServerActiveObject *player,
537                 const std::string &formname,
538                 const std::map<std::string, std::string> &fields)
539 {
540         realitycheck(L);
541         assert(lua_checkstack(L, 20));
542         StackUnroller stack_unroller(L);
543
544         // Get minetest.registered_on_chat_messages
545         lua_getglobal(L, "minetest");
546         lua_getfield(L, -1, "registered_on_player_receive_fields");
547         // Call callbacks
548         // param 1
549         objectref_get_or_create(L, player);
550         // param 2
551         lua_pushstring(L, formname.c_str());
552         // param 3
553         lua_newtable(L);
554         for(std::map<std::string, std::string>::const_iterator
555                         i = fields.begin(); i != fields.end(); i++){
556                 const std::string &name = i->first;
557                 const std::string &value = i->second;
558                 lua_pushstring(L, name.c_str());
559                 lua_pushlstring(L, value.c_str(), value.size());
560                 lua_settable(L, -3);
561         }
562         scriptapi_run_callbacks(L, 3, RUN_CALLBACKS_MODE_OR_SC);
563 }
564 /*****************************************************************************/
565 /* Api functions                                                             */
566 /*****************************************************************************/
567
568 // debug(text)
569 // Writes a line to dstream
570 static int l_debug(lua_State *L)
571 {
572         std::string text = lua_tostring(L, 1);
573         dstream << text << std::endl;
574         return 0;
575 }
576
577 // log([level,] text)
578 // Writes a line to the logger.
579 // The one-argument version logs to infostream.
580 // The two-argument version accept a log level: error, action, info, or verbose.
581 static int l_log(lua_State *L)
582 {
583         std::string text;
584         LogMessageLevel level = LMT_INFO;
585         if(lua_isnone(L, 2))
586         {
587                 text = lua_tostring(L, 1);
588         }
589         else
590         {
591                 std::string levelname = luaL_checkstring(L, 1);
592                 text = luaL_checkstring(L, 2);
593                 if(levelname == "error")
594                         level = LMT_ERROR;
595                 else if(levelname == "action")
596                         level = LMT_ACTION;
597                 else if(levelname == "verbose")
598                         level = LMT_VERBOSE;
599         }
600         log_printline(level, text);
601         return 0;
602 }
603
604 // request_shutdown()
605 static int l_request_shutdown(lua_State *L)
606 {
607         get_server(L)->requestShutdown();
608         return 0;
609 }
610
611 // get_server_status()
612 static int l_get_server_status(lua_State *L)
613 {
614         lua_pushstring(L, wide_to_narrow(get_server(L)->getStatusString()).c_str());
615         return 1;
616 }
617
618
619 // register_biome({lots of stuff})
620 static int l_register_biome(lua_State *L)
621 {
622         int index = 1;
623         luaL_checktype(L, index, LUA_TTABLE);
624
625         BiomeDefManager *bmgr = get_server(L)->getEmergeManager()->biomedef;
626         if (!bmgr) {
627                 verbosestream << "register_biome: BiomeDefManager not active" << std::endl;
628                 return 0;
629         }
630         
631         enum BiomeTerrainType terrain = (BiomeTerrainType)getenumfield(L, index,
632                                         "terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL);
633         Biome *b = bmgr->createBiome(terrain);
634
635         b->name            = getstringfield_default(L, index, "name", "");
636         b->top_nodename    = getstringfield_default(L, index, "top_node", "");
637         b->top_depth       = getintfield_default(L, index, "top_depth", 0);
638         b->filler_nodename = getstringfield_default(L, index, "filler_node", "");
639         b->filler_height   = getintfield_default(L, index, "filler_height", 0);
640         b->height_min      = getintfield_default(L, index, "height_min", 0);
641         b->height_max      = getintfield_default(L, index, "height_max", 0);
642         b->heat_point      = getfloatfield_default(L, index, "heat_point", 0.);
643         b->humidity_point  = getfloatfield_default(L, index, "humidity_point", 0.);
644
645         b->flags    = 0; //reserved
646         b->c_top    = CONTENT_IGNORE;
647         b->c_filler = CONTENT_IGNORE;
648         bmgr->addBiome(b);
649
650         verbosestream << "register_biome: " << b->name << std::endl;
651         return 0;
652 }
653
654
655 static int l_register_ore(lua_State *L)
656 {
657         int index = 1;
658         luaL_checktype(L, index, LUA_TTABLE);
659         
660         EmergeManager *emerge = get_server(L)->getEmergeManager();
661         
662         enum OreType oretype = (OreType)getenumfield(L, index,
663                                 "ore_type", es_OreType, ORE_SCATTER);   
664         Ore *ore = createOre(oretype);
665         if (!ore) {
666                 errorstream << "register_ore: ore_type "
667                         << oretype << " not implemented";
668                 return 0;
669         }
670         
671         ore->ore_name       = getstringfield_default(L, index, "ore", "");
672         ore->ore_param2     = (u8)getintfield_default(L, index, "ore_param2", 0);
673         ore->wherein_name   = getstringfield_default(L, index, "wherein", "");
674         ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
675         ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
676         ore->clust_size     = getintfield_default(L, index, "clust_size", 0);
677         ore->height_min     = getintfield_default(L, index, "height_min", 0);
678         ore->height_max     = getintfield_default(L, index, "height_max", 0);
679         ore->flags          = getflagsfield(L, index, "flags", flagdesc_ore);
680         ore->nthresh        = getfloatfield_default(L, index, "noise_threshhold", 0.);
681
682         lua_getfield(L, index, "noise_params");
683         ore->np = read_noiseparams(L, -1);
684         lua_pop(L, 1);
685         
686         ore->noise = NULL;
687         
688         if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) {
689                 errorstream << "register_ore: clust_scarcity and clust_num_ores"
690                         " must be greater than 0" << std::endl;
691                 delete ore;
692                 return 0;
693         }
694         
695         emerge->ores.push_back(ore);
696         
697         verbosestream << "register_ore: ore '" << ore->ore_name
698                 << "' registered" << std::endl;
699         return 0;
700 }
701
702
703 // setting_set(name, value)
704 static int l_setting_set(lua_State *L)
705 {
706         const char *name = luaL_checkstring(L, 1);
707         const char *value = luaL_checkstring(L, 2);
708         g_settings->set(name, value);
709         return 0;
710 }
711
712 // setting_get(name)
713 static int l_setting_get(lua_State *L)
714 {
715         const char *name = luaL_checkstring(L, 1);
716         try{
717                 std::string value = g_settings->get(name);
718                 lua_pushstring(L, value.c_str());
719         } catch(SettingNotFoundException &e){
720                 lua_pushnil(L);
721         }
722         return 1;
723 }
724
725 // setting_getbool(name)
726 static int l_setting_getbool(lua_State *L)
727 {
728         const char *name = luaL_checkstring(L, 1);
729         try{
730                 bool value = g_settings->getBool(name);
731                 lua_pushboolean(L, value);
732         } catch(SettingNotFoundException &e){
733                 lua_pushnil(L);
734         }
735         return 1;
736 }
737
738 // setting_save()
739 static int l_setting_save(lua_State *L)
740 {
741         get_server(L)->saveConfig();
742         return 0;
743 }
744
745 // chat_send_all(text)
746 static int l_chat_send_all(lua_State *L)
747 {
748         const char *text = luaL_checkstring(L, 1);
749         // Get server from registry
750         Server *server = get_server(L);
751         // Send
752         server->notifyPlayers(narrow_to_wide(text));
753         return 0;
754 }
755
756 // chat_send_player(name, text, prepend)
757 static int l_chat_send_player(lua_State *L)
758 {
759         const char *name = luaL_checkstring(L, 1);
760         const char *text = luaL_checkstring(L, 2);
761         bool prepend = true;
762         if (lua_isboolean(L, 3))
763                 prepend = lua_toboolean(L, 3);
764         // Get server from registry
765         Server *server = get_server(L);
766         // Send
767         server->notifyPlayer(name, narrow_to_wide(text), prepend);
768         return 0;
769 }
770
771 // get_player_privs(name, text)
772 static int l_get_player_privs(lua_State *L)
773 {
774         const char *name = luaL_checkstring(L, 1);
775         // Get server from registry
776         Server *server = get_server(L);
777         // Do it
778         lua_newtable(L);
779         int table = lua_gettop(L);
780         std::set<std::string> privs_s = server->getPlayerEffectivePrivs(name);
781         for(std::set<std::string>::const_iterator
782                         i = privs_s.begin(); i != privs_s.end(); i++){
783                 lua_pushboolean(L, true);
784                 lua_setfield(L, table, i->c_str());
785         }
786         lua_pushvalue(L, table);
787         return 1;
788 }
789
790 // get_player_ip()
791 static int l_get_player_ip(lua_State *L)
792 {
793         const char * name = luaL_checkstring(L, 1);
794         Player *player = get_env(L)->getPlayer(name);
795         if(player == NULL)
796         {
797                 lua_pushnil(L); // no such player
798                 return 1;
799         }
800         try
801         {
802                 Address addr = get_server(L)->getPeerAddress(get_env(L)->getPlayer(name)->peer_id);
803                 std::string ip_str = addr.serializeString();
804                 lua_pushstring(L, ip_str.c_str());
805                 return 1;
806         }
807         catch(con::PeerNotFoundException) // unlikely
808         {
809                 dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
810                 lua_pushnil(L); // error
811                 return 1;
812         }
813 }
814
815 // get_ban_list()
816 static int l_get_ban_list(lua_State *L)
817 {
818         lua_pushstring(L, get_server(L)->getBanDescription("").c_str());
819         return 1;
820 }
821
822 // get_ban_description()
823 static int l_get_ban_description(lua_State *L)
824 {
825         const char * ip_or_name = luaL_checkstring(L, 1);
826         lua_pushstring(L, get_server(L)->getBanDescription(std::string(ip_or_name)).c_str());
827         return 1;
828 }
829
830 // ban_player()
831 static int l_ban_player(lua_State *L)
832 {
833         const char * name = luaL_checkstring(L, 1);
834         Player *player = get_env(L)->getPlayer(name);
835         if(player == NULL)
836         {
837                 lua_pushboolean(L, false); // no such player
838                 return 1;
839         }
840         try
841         {
842                 Address addr = get_server(L)->getPeerAddress(get_env(L)->getPlayer(name)->peer_id);
843                 std::string ip_str = addr.serializeString();
844                 get_server(L)->setIpBanned(ip_str, name);
845         }
846         catch(con::PeerNotFoundException) // unlikely
847         {
848                 dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
849                 lua_pushboolean(L, false); // error
850                 return 1;
851         }
852         lua_pushboolean(L, true);
853         return 1;
854 }
855
856 // unban_player_or_ip()
857 static int l_unban_player_of_ip(lua_State *L)
858 {
859         const char * ip_or_name = luaL_checkstring(L, 1);
860         get_server(L)->unsetIpBanned(ip_or_name);
861         lua_pushboolean(L, true);
862         return 1;
863 }
864
865 // show_formspec(playername,formname,formspec)
866 static int l_show_formspec(lua_State *L)
867 {
868         const char *playername = luaL_checkstring(L, 1);
869         const char *formname = luaL_checkstring(L, 2);
870         const char *formspec = luaL_checkstring(L, 3);
871
872         if(get_server(L)->showFormspec(playername,formspec,formname))
873         {
874                 lua_pushboolean(L, true);
875         }else{
876                 lua_pushboolean(L, false);
877         }
878         return 1;
879 }
880
881 // get_dig_params(groups, tool_capabilities[, time_from_last_punch])
882 static int l_get_dig_params(lua_State *L)
883 {
884         std::map<std::string, int> groups;
885         read_groups(L, 1, groups);
886         ToolCapabilities tp = read_tool_capabilities(L, 2);
887         if(lua_isnoneornil(L, 3))
888                 push_dig_params(L, getDigParams(groups, &tp));
889         else
890                 push_dig_params(L, getDigParams(groups, &tp,
891                                         luaL_checknumber(L, 3)));
892         return 1;
893 }
894
895 // get_hit_params(groups, tool_capabilities[, time_from_last_punch])
896 static int l_get_hit_params(lua_State *L)
897 {
898         std::map<std::string, int> groups;
899         read_groups(L, 1, groups);
900         ToolCapabilities tp = read_tool_capabilities(L, 2);
901         if(lua_isnoneornil(L, 3))
902                 push_hit_params(L, getHitParams(groups, &tp));
903         else
904                 push_hit_params(L, getHitParams(groups, &tp,
905                                         luaL_checknumber(L, 3)));
906         return 1;
907 }
908
909 // get_current_modname()
910 static int l_get_current_modname(lua_State *L)
911 {
912         lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
913         return 1;
914 }
915
916 // get_modpath(modname)
917 static int l_get_modpath(lua_State *L)
918 {
919         std::string modname = luaL_checkstring(L, 1);
920         // Do it
921         if(modname == "__builtin"){
922                 std::string path = get_server(L)->getBuiltinLuaPath();
923                 lua_pushstring(L, path.c_str());
924                 return 1;
925         }
926         const ModSpec *mod = get_server(L)->getModSpec(modname);
927         if(!mod){
928                 lua_pushnil(L);
929                 return 1;
930         }
931         lua_pushstring(L, mod->path.c_str());
932         return 1;
933 }
934
935 // get_modnames()
936 // the returned list is sorted alphabetically for you
937 static int l_get_modnames(lua_State *L)
938 {
939         // Get a list of mods
940         std::list<std::string> mods_unsorted, mods_sorted;
941         get_server(L)->getModNames(mods_unsorted);
942
943         // Take unsorted items from mods_unsorted and sort them into
944         // mods_sorted; not great performance but the number of mods on a
945         // server will likely be small.
946         for(std::list<std::string>::iterator i = mods_unsorted.begin();
947             i != mods_unsorted.end(); ++i)
948         {
949                 bool added = false;
950                 for(std::list<std::string>::iterator x = mods_sorted.begin();
951                     x != mods_sorted.end(); ++x)
952                 {
953                         // I doubt anybody using Minetest will be using
954                         // anything not ASCII based :)
955                         if((*i).compare(*x) <= 0)
956                         {
957                                 mods_sorted.insert(x, *i);
958                                 added = true;
959                                 break;
960                         }
961                 }
962                 if(!added)
963                         mods_sorted.push_back(*i);
964         }
965
966         // Get the table insertion function from Lua.
967         lua_getglobal(L, "table");
968         lua_getfield(L, -1, "insert");
969         int insertion_func = lua_gettop(L);
970
971         // Package them up for Lua
972         lua_newtable(L);
973         int new_table = lua_gettop(L);
974         std::list<std::string>::iterator i = mods_sorted.begin();
975         while(i != mods_sorted.end())
976         {
977                 lua_pushvalue(L, insertion_func);
978                 lua_pushvalue(L, new_table);
979                 lua_pushstring(L, (*i).c_str());
980                 if(lua_pcall(L, 2, 0, 0) != 0)
981                 {
982                         script_error(L, "error: %s", lua_tostring(L, -1));
983                 }
984                 ++i;
985         }
986         return 1;
987 }
988
989 // get_worldpath()
990 static int l_get_worldpath(lua_State *L)
991 {
992         std::string worldpath = get_server(L)->getWorldPath();
993         lua_pushstring(L, worldpath.c_str());
994         return 1;
995 }
996
997 // sound_play(spec, parameters)
998 static int l_sound_play(lua_State *L)
999 {
1000         SimpleSoundSpec spec;
1001         read_soundspec(L, 1, spec);
1002         ServerSoundParams params;
1003         read_server_sound_params(L, 2, params);
1004         s32 handle = get_server(L)->playSound(spec, params);
1005         lua_pushinteger(L, handle);
1006         return 1;
1007 }
1008
1009 // sound_stop(handle)
1010 static int l_sound_stop(lua_State *L)
1011 {
1012         int handle = luaL_checkinteger(L, 1);
1013         get_server(L)->stopSound(handle);
1014         return 0;
1015 }
1016
1017 // is_singleplayer()
1018 static int l_is_singleplayer(lua_State *L)
1019 {
1020         lua_pushboolean(L, get_server(L)->isSingleplayer());
1021         return 1;
1022 }
1023
1024 // get_password_hash(name, raw_password)
1025 static int l_get_password_hash(lua_State *L)
1026 {
1027         std::string name = luaL_checkstring(L, 1);
1028         std::string raw_password = luaL_checkstring(L, 2);
1029         std::string hash = translatePassword(name,
1030                         narrow_to_wide(raw_password));
1031         lua_pushstring(L, hash.c_str());
1032         return 1;
1033 }
1034
1035 // notify_authentication_modified(name)
1036 static int l_notify_authentication_modified(lua_State *L)
1037 {
1038         std::string name = "";
1039         if(lua_isstring(L, 1))
1040                 name = lua_tostring(L, 1);
1041         get_server(L)->reportPrivsModified(name);
1042         return 0;
1043 }
1044
1045 // rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds
1046 static int l_rollback_get_last_node_actor(lua_State *L)
1047 {
1048         v3s16 p = read_v3s16(L, 1);
1049         int range = luaL_checknumber(L, 2);
1050         int seconds = luaL_checknumber(L, 3);
1051         Server *server = get_server(L);
1052         IRollbackManager *rollback = server->getRollbackManager();
1053         v3s16 act_p;
1054         int act_seconds = 0;
1055         std::string actor = rollback->getLastNodeActor(p, range, seconds, &act_p, &act_seconds);
1056         lua_pushstring(L, actor.c_str());
1057         push_v3s16(L, act_p);
1058         lua_pushnumber(L, act_seconds);
1059         return 3;
1060 }
1061
1062 // rollback_revert_actions_by(actor, seconds) -> bool, log messages
1063 static int l_rollback_revert_actions_by(lua_State *L)
1064 {
1065         std::string actor = luaL_checkstring(L, 1);
1066         int seconds = luaL_checknumber(L, 2);
1067         Server *server = get_server(L);
1068         IRollbackManager *rollback = server->getRollbackManager();
1069         std::list<RollbackAction> actions = rollback->getRevertActions(actor, seconds);
1070         std::list<std::string> log;
1071         bool success = server->rollbackRevertActions(actions, &log);
1072         // Push boolean result
1073         lua_pushboolean(L, success);
1074         // Get the table insert function and push the log table
1075         lua_getglobal(L, "table");
1076         lua_getfield(L, -1, "insert");
1077         int table_insert = lua_gettop(L);
1078         lua_newtable(L);
1079         int table = lua_gettop(L);
1080         for(std::list<std::string>::const_iterator i = log.begin();
1081                         i != log.end(); i++)
1082         {
1083                 lua_pushvalue(L, table_insert);
1084                 lua_pushvalue(L, table);
1085                 lua_pushstring(L, i->c_str());
1086                 if(lua_pcall(L, 2, 0, 0))
1087                         script_error(L, "error: %s", lua_tostring(L, -1));
1088         }
1089         lua_remove(L, -2); // Remove table
1090         lua_remove(L, -2); // Remove insert
1091         return 2;
1092 }
1093
1094 static const struct luaL_Reg minetest_f [] = {
1095         {"debug", l_debug},
1096         {"log", l_log},
1097         {"request_shutdown", l_request_shutdown},
1098         {"get_server_status", l_get_server_status},
1099         {"register_item_raw", l_register_item_raw},
1100         {"register_alias_raw", l_register_alias_raw},
1101         {"register_craft", l_register_craft},
1102         {"register_biome", l_register_biome},
1103         {"register_ore", l_register_ore},
1104         {"setting_set", l_setting_set},
1105         {"setting_get", l_setting_get},
1106         {"setting_getbool", l_setting_getbool},
1107         {"setting_save",l_setting_save},
1108         {"chat_send_all", l_chat_send_all},
1109         {"chat_send_player", l_chat_send_player},
1110         {"get_player_privs", l_get_player_privs},
1111         {"get_player_ip", l_get_player_ip},
1112         {"get_ban_list", l_get_ban_list},
1113         {"get_ban_description", l_get_ban_description},
1114         {"ban_player", l_ban_player},
1115         {"unban_player_or_ip", l_unban_player_of_ip},
1116         {"get_inventory", l_get_inventory},
1117         {"create_detached_inventory_raw", l_create_detached_inventory_raw},
1118         {"show_formspec", l_show_formspec},
1119         {"get_dig_params", l_get_dig_params},
1120         {"get_hit_params", l_get_hit_params},
1121         {"get_current_modname", l_get_current_modname},
1122         {"get_modpath", l_get_modpath},
1123         {"get_modnames", l_get_modnames},
1124         {"get_worldpath", l_get_worldpath},
1125         {"sound_play", l_sound_play},
1126         {"sound_stop", l_sound_stop},
1127         {"is_singleplayer", l_is_singleplayer},
1128         {"get_password_hash", l_get_password_hash},
1129         {"notify_authentication_modified", l_notify_authentication_modified},
1130         {"get_craft_result", l_get_craft_result},
1131         {"get_craft_recipe", l_get_craft_recipe},
1132         {"get_all_craft_recipes", l_get_all_craft_recipes},
1133         {"rollback_get_last_node_actor", l_rollback_get_last_node_actor},
1134         {"rollback_revert_actions_by", l_rollback_revert_actions_by},
1135         {"add_particle", l_add_particle},
1136         {"add_particlespawner", l_add_particlespawner},
1137         {"delete_particlespawner", l_delete_particlespawner},
1138         {NULL, NULL}
1139 };
1140
1141
1142 /*
1143         Main export function
1144 */
1145
1146 void scriptapi_export(lua_State *L, Server *server)
1147 {
1148         realitycheck(L);
1149         assert(lua_checkstack(L, 20));
1150         verbosestream<<"scriptapi_export()"<<std::endl;
1151         StackUnroller stack_unroller(L);
1152
1153         // Store server as light userdata in registry
1154         lua_pushlightuserdata(L, server);
1155         lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");
1156
1157         // Register global functions in table minetest
1158         lua_newtable(L);
1159         luaL_register(L, NULL, minetest_f);
1160         lua_setglobal(L, "minetest");
1161
1162         // Get the main minetest table
1163         lua_getglobal(L, "minetest");
1164
1165         // Add tables to minetest
1166         lua_newtable(L);
1167         lua_setfield(L, -2, "object_refs");
1168         lua_newtable(L);
1169         lua_setfield(L, -2, "luaentities");
1170
1171         // Register wrappers
1172         LuaItemStack::Register(L);
1173         InvRef::Register(L);
1174         NodeMetaRef::Register(L);
1175         NodeTimerRef::Register(L);
1176         ObjectRef::Register(L);
1177         EnvRef::Register(L);
1178         LuaPseudoRandom::Register(L);
1179         LuaPerlinNoise::Register(L);
1180         LuaPerlinNoiseMap::Register(L);
1181 }