3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
20 #include "lua_api/l_server.h"
21 #include "lua_api/l_internal.h"
22 #include "common/c_converter.h"
23 #include "common/c_content.h"
25 #include "environment.h"
29 int ModApiServer::l_request_shutdown(lua_State *L)
31 getServer(L)->requestShutdown();
35 // get_server_status()
36 int ModApiServer::l_get_server_status(lua_State *L)
39 lua_pushstring(L, wide_to_narrow(getServer(L)->getStatusString()).c_str());
43 // chat_send_all(text)
44 int ModApiServer::l_chat_send_all(lua_State *L)
47 const char *text = luaL_checkstring(L, 1);
48 // Get server from registry
49 Server *server = getServer(L);
51 server->notifyPlayers(narrow_to_wide(text));
55 // chat_send_player(name, text, prepend)
56 int ModApiServer::l_chat_send_player(lua_State *L)
59 const char *name = luaL_checkstring(L, 1);
60 const char *text = luaL_checkstring(L, 2);
63 if (lua_isboolean(L, 3))
64 prepend = lua_toboolean(L, 3);
66 // Get server from registry
67 Server *server = getServer(L);
69 server->notifyPlayer(name, narrow_to_wide(text), prepend);
73 // get_player_privs(name, text)
74 int ModApiServer::l_get_player_privs(lua_State *L)
77 const char *name = luaL_checkstring(L, 1);
78 // Get server from registry
79 Server *server = getServer(L);
82 int table = lua_gettop(L);
83 std::set<std::string> privs_s = server->getPlayerEffectivePrivs(name);
84 for(std::set<std::string>::const_iterator
85 i = privs_s.begin(); i != privs_s.end(); i++){
86 lua_pushboolean(L, true);
87 lua_setfield(L, table, i->c_str());
89 lua_pushvalue(L, table);
94 int ModApiServer::l_get_player_ip(lua_State *L)
97 const char * name = luaL_checkstring(L, 1);
98 Player *player = getEnv(L)->getPlayer(name);
101 lua_pushnil(L); // no such player
106 Address addr = getServer(L)->getPeerAddress(getEnv(L)->getPlayer(name)->peer_id);
107 std::string ip_str = addr.serializeString();
108 lua_pushstring(L, ip_str.c_str());
111 catch(con::PeerNotFoundException) // unlikely
113 dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
114 lua_pushnil(L); // error
120 int ModApiServer::l_get_ban_list(lua_State *L)
122 NO_MAP_LOCK_REQUIRED;
123 lua_pushstring(L, getServer(L)->getBanDescription("").c_str());
127 // get_ban_description()
128 int ModApiServer::l_get_ban_description(lua_State *L)
130 NO_MAP_LOCK_REQUIRED;
131 const char * ip_or_name = luaL_checkstring(L, 1);
132 lua_pushstring(L, getServer(L)->getBanDescription(std::string(ip_or_name)).c_str());
137 int ModApiServer::l_ban_player(lua_State *L)
139 NO_MAP_LOCK_REQUIRED;
140 const char * name = luaL_checkstring(L, 1);
141 Player *player = getEnv(L)->getPlayer(name);
144 lua_pushboolean(L, false); // no such player
149 Address addr = getServer(L)->getPeerAddress(getEnv(L)->getPlayer(name)->peer_id);
150 std::string ip_str = addr.serializeString();
151 getServer(L)->setIpBanned(ip_str, name);
153 catch(con::PeerNotFoundException) // unlikely
155 dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
156 lua_pushboolean(L, false); // error
159 lua_pushboolean(L, true);
163 // unban_player_or_ip()
164 int ModApiServer::l_unban_player_or_ip(lua_State *L)
166 NO_MAP_LOCK_REQUIRED;
167 const char * ip_or_name = luaL_checkstring(L, 1);
168 getServer(L)->unsetIpBanned(ip_or_name);
169 lua_pushboolean(L, true);
173 // show_formspec(playername,formname,formspec)
174 int ModApiServer::l_show_formspec(lua_State *L)
176 NO_MAP_LOCK_REQUIRED;
177 const char *playername = luaL_checkstring(L, 1);
178 const char *formname = luaL_checkstring(L, 2);
179 const char *formspec = luaL_checkstring(L, 3);
181 if(getServer(L)->showFormspec(playername,formspec,formname))
183 lua_pushboolean(L, true);
185 lua_pushboolean(L, false);
190 // get_current_modname()
191 int ModApiServer::l_get_current_modname(lua_State *L)
193 NO_MAP_LOCK_REQUIRED;
194 lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
198 // get_modpath(modname)
199 int ModApiServer::l_get_modpath(lua_State *L)
201 NO_MAP_LOCK_REQUIRED;
202 std::string modname = luaL_checkstring(L, 1);
204 if(modname == "__builtin"){
205 std::string path = getServer(L)->getBuiltinLuaPath();
206 lua_pushstring(L, path.c_str());
209 const ModSpec *mod = getServer(L)->getModSpec(modname);
214 lua_pushstring(L, mod->path.c_str());
219 // the returned list is sorted alphabetically for you
220 int ModApiServer::l_get_modnames(lua_State *L)
222 NO_MAP_LOCK_REQUIRED;
223 // Get a list of mods
224 std::list<std::string> mods_unsorted, mods_sorted;
225 getServer(L)->getModNames(mods_unsorted);
227 // Take unsorted items from mods_unsorted and sort them into
228 // mods_sorted; not great performance but the number of mods on a
229 // server will likely be small.
230 for(std::list<std::string>::iterator i = mods_unsorted.begin();
231 i != mods_unsorted.end(); ++i)
234 for(std::list<std::string>::iterator x = mods_sorted.begin();
235 x != mods_sorted.end(); ++x)
237 // I doubt anybody using Minetest will be using
238 // anything not ASCII based :)
239 if((*i).compare(*x) <= 0)
241 mods_sorted.insert(x, *i);
247 mods_sorted.push_back(*i);
250 // Get the table insertion function from Lua.
251 lua_getglobal(L, "table");
252 lua_getfield(L, -1, "insert");
253 int insertion_func = lua_gettop(L);
255 // Package them up for Lua
257 int new_table = lua_gettop(L);
258 std::list<std::string>::iterator i = mods_sorted.begin();
259 while(i != mods_sorted.end())
261 lua_pushvalue(L, insertion_func);
262 lua_pushvalue(L, new_table);
263 lua_pushstring(L, (*i).c_str());
264 if(lua_pcall(L, 2, 0, 0) != 0)
266 script_error(L, "error: %s", lua_tostring(L, -1));
274 int ModApiServer::l_get_worldpath(lua_State *L)
276 NO_MAP_LOCK_REQUIRED;
277 std::string worldpath = getServer(L)->getWorldPath();
278 lua_pushstring(L, worldpath.c_str());
282 // sound_play(spec, parameters)
283 int ModApiServer::l_sound_play(lua_State *L)
285 NO_MAP_LOCK_REQUIRED;
286 SimpleSoundSpec spec;
287 read_soundspec(L, 1, spec);
288 ServerSoundParams params;
289 read_server_sound_params(L, 2, params);
290 s32 handle = getServer(L)->playSound(spec, params);
291 lua_pushinteger(L, handle);
295 // sound_stop(handle)
296 int ModApiServer::l_sound_stop(lua_State *L)
298 NO_MAP_LOCK_REQUIRED;
299 int handle = luaL_checkinteger(L, 1);
300 getServer(L)->stopSound(handle);
305 int ModApiServer::l_is_singleplayer(lua_State *L)
307 NO_MAP_LOCK_REQUIRED;
308 lua_pushboolean(L, getServer(L)->isSingleplayer());
312 // notify_authentication_modified(name)
313 int ModApiServer::l_notify_authentication_modified(lua_State *L)
315 NO_MAP_LOCK_REQUIRED;
316 std::string name = "";
317 if(lua_isstring(L, 1))
318 name = lua_tostring(L, 1);
319 getServer(L)->reportPrivsModified(name);
323 void ModApiServer::Initialize(lua_State *L, int top)
325 API_FCT(request_shutdown);
326 API_FCT(get_server_status);
327 API_FCT(get_worldpath);
328 API_FCT(is_singleplayer);
330 API_FCT(get_current_modname);
331 API_FCT(get_modpath);
332 API_FCT(get_modnames);
334 API_FCT(chat_send_all);
335 API_FCT(chat_send_player);
336 API_FCT(show_formspec);
340 API_FCT(get_player_privs);
341 API_FCT(get_player_ip);
342 API_FCT(get_ban_list);
343 API_FCT(get_ban_description);
345 API_FCT(unban_player_or_ip);
346 API_FCT(notify_authentication_modified);