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)
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);
62 // Get server from registry
63 Server *server = getServer(L);
65 server->notifyPlayer(name, narrow_to_wide(text));
69 // get_player_privs(name, text)
70 int ModApiServer::l_get_player_privs(lua_State *L)
73 const char *name = luaL_checkstring(L, 1);
74 // Get server from registry
75 Server *server = getServer(L);
78 int table = lua_gettop(L);
79 std::set<std::string> privs_s = server->getPlayerEffectivePrivs(name);
80 for(std::set<std::string>::const_iterator
81 i = privs_s.begin(); i != privs_s.end(); i++){
82 lua_pushboolean(L, true);
83 lua_setfield(L, table, i->c_str());
85 lua_pushvalue(L, table);
90 int ModApiServer::l_get_player_ip(lua_State *L)
93 const char * name = luaL_checkstring(L, 1);
94 Player *player = getEnv(L)->getPlayer(name);
97 lua_pushnil(L); // no such player
102 Address addr = getServer(L)->getPeerAddress(player->peer_id);
103 std::string ip_str = addr.serializeString();
104 lua_pushstring(L, ip_str.c_str());
107 catch(con::PeerNotFoundException) // unlikely
109 dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
110 lua_pushnil(L); // error
115 // get_player_information()
116 int ModApiServer::l_get_player_information(lua_State *L)
119 NO_MAP_LOCK_REQUIRED;
120 const char * name = luaL_checkstring(L, 1);
121 Player *player = getEnv(L)->getPlayer(name);
124 lua_pushnil(L); // no such player
131 addr = getServer(L)->getPeerAddress(player->peer_id);
133 catch(con::PeerNotFoundException) // unlikely
135 dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
136 lua_pushnil(L); // error
140 float min_rtt,max_rtt,avg_rtt,min_jitter,max_jitter,avg_jitter;
144 u8 ser_vers,major,minor,patch;
145 std::string vers_string;
149 dstream << __FUNCTION_NAME << ": peer was not found" << std::endl; \
150 lua_pushnil(L); /* error */ \
154 ERET(getServer(L)->getClientConInfo(player->peer_id,con::MIN_RTT,&min_rtt))
155 ERET(getServer(L)->getClientConInfo(player->peer_id,con::MAX_RTT,&max_rtt))
156 ERET(getServer(L)->getClientConInfo(player->peer_id,con::AVG_RTT,&avg_rtt))
157 ERET(getServer(L)->getClientConInfo(player->peer_id,con::MIN_JITTER,&min_jitter))
158 ERET(getServer(L)->getClientConInfo(player->peer_id,con::MAX_JITTER,&max_jitter))
159 ERET(getServer(L)->getClientConInfo(player->peer_id,con::AVG_JITTER,&avg_jitter))
161 ERET(getServer(L)->getClientInfo(player->peer_id,
162 &state, &uptime, &ser_vers, &prot_vers,
163 &major, &minor, &patch, &vers_string))
166 int table = lua_gettop(L);
168 lua_pushstring(L,"address");
169 lua_pushstring(L, addr.serializeString().c_str());
170 lua_settable(L, table);
172 lua_pushstring(L,"ip_version");
173 if (addr.getFamily() == AF_INET) {
174 lua_pushnumber(L, 4);
175 } else if (addr.getFamily() == AF_INET6) {
176 lua_pushnumber(L, 6);
178 lua_pushnumber(L, 0);
180 lua_settable(L, table);
182 lua_pushstring(L,"min_rtt");
183 lua_pushnumber(L, min_rtt);
184 lua_settable(L, table);
186 lua_pushstring(L,"max_rtt");
187 lua_pushnumber(L, max_rtt);
188 lua_settable(L, table);
190 lua_pushstring(L,"avg_rtt");
191 lua_pushnumber(L, avg_rtt);
192 lua_settable(L, table);
194 lua_pushstring(L,"min_jitter");
195 lua_pushnumber(L, min_jitter);
196 lua_settable(L, table);
198 lua_pushstring(L,"max_jitter");
199 lua_pushnumber(L, max_jitter);
200 lua_settable(L, table);
202 lua_pushstring(L,"avg_jitter");
203 lua_pushnumber(L, avg_jitter);
204 lua_settable(L, table);
206 lua_pushstring(L,"connection_uptime");
207 lua_pushnumber(L, uptime);
208 lua_settable(L, table);
211 lua_pushstring(L,"serialization_version");
212 lua_pushnumber(L, ser_vers);
213 lua_settable(L, table);
215 lua_pushstring(L,"protocol_version");
216 lua_pushnumber(L, prot_vers);
217 lua_settable(L, table);
219 lua_pushstring(L,"major");
220 lua_pushnumber(L, major);
221 lua_settable(L, table);
223 lua_pushstring(L,"minor");
224 lua_pushnumber(L, minor);
225 lua_settable(L, table);
227 lua_pushstring(L,"patch");
228 lua_pushnumber(L, patch);
229 lua_settable(L, table);
231 lua_pushstring(L,"version_string");
232 lua_pushstring(L, vers_string.c_str());
233 lua_settable(L, table);
235 lua_pushstring(L,"state");
236 lua_pushstring(L,ClientInterface::state2Name(state).c_str());
237 lua_settable(L, table);
245 int ModApiServer::l_get_ban_list(lua_State *L)
247 NO_MAP_LOCK_REQUIRED;
248 lua_pushstring(L, getServer(L)->getBanDescription("").c_str());
252 // get_ban_description()
253 int ModApiServer::l_get_ban_description(lua_State *L)
255 NO_MAP_LOCK_REQUIRED;
256 const char * ip_or_name = luaL_checkstring(L, 1);
257 lua_pushstring(L, getServer(L)->getBanDescription(std::string(ip_or_name)).c_str());
262 int ModApiServer::l_ban_player(lua_State *L)
264 NO_MAP_LOCK_REQUIRED;
265 const char * name = luaL_checkstring(L, 1);
266 Player *player = getEnv(L)->getPlayer(name);
269 lua_pushboolean(L, false); // no such player
274 Address addr = getServer(L)->getPeerAddress(getEnv(L)->getPlayer(name)->peer_id);
275 std::string ip_str = addr.serializeString();
276 getServer(L)->setIpBanned(ip_str, name);
278 catch(con::PeerNotFoundException) // unlikely
280 dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
281 lua_pushboolean(L, false); // error
284 lua_pushboolean(L, true);
288 // kick_player(name, [reason]) -> success
289 int ModApiServer::l_kick_player(lua_State *L)
291 NO_MAP_LOCK_REQUIRED;
292 const char *name = luaL_checkstring(L, 1);
294 if (lua_isstring(L, 2))
296 message = std::string("Kicked: ") + lua_tostring(L, 2);
302 Player *player = getEnv(L)->getPlayer(name);
305 lua_pushboolean(L, false); // No such player
308 getServer(L)->DenyAccess(player->peer_id, narrow_to_wide(message));
309 lua_pushboolean(L, true);
313 // unban_player_or_ip()
314 int ModApiServer::l_unban_player_or_ip(lua_State *L)
316 NO_MAP_LOCK_REQUIRED;
317 const char * ip_or_name = luaL_checkstring(L, 1);
318 getServer(L)->unsetIpBanned(ip_or_name);
319 lua_pushboolean(L, true);
323 // show_formspec(playername,formname,formspec)
324 int ModApiServer::l_show_formspec(lua_State *L)
326 NO_MAP_LOCK_REQUIRED;
327 const char *playername = luaL_checkstring(L, 1);
328 const char *formname = luaL_checkstring(L, 2);
329 const char *formspec = luaL_checkstring(L, 3);
331 if(getServer(L)->showFormspec(playername,formspec,formname))
333 lua_pushboolean(L, true);
335 lua_pushboolean(L, false);
340 // get_current_modname()
341 int ModApiServer::l_get_current_modname(lua_State *L)
343 NO_MAP_LOCK_REQUIRED;
344 lua_getfield(L, LUA_REGISTRYINDEX, "current_modname");
348 // get_modpath(modname)
349 int ModApiServer::l_get_modpath(lua_State *L)
351 NO_MAP_LOCK_REQUIRED;
352 std::string modname = luaL_checkstring(L, 1);
353 const ModSpec *mod = getServer(L)->getModSpec(modname);
358 lua_pushstring(L, mod->path.c_str());
363 // the returned list is sorted alphabetically for you
364 int ModApiServer::l_get_modnames(lua_State *L)
366 NO_MAP_LOCK_REQUIRED;
368 // Get a list of mods
369 std::list<std::string> mods_unsorted, mods_sorted;
370 getServer(L)->getModNames(mods_unsorted);
372 // Take unsorted items from mods_unsorted and sort them into
373 // mods_sorted; not great performance but the number of mods on a
374 // server will likely be small.
375 for(std::list<std::string>::iterator i = mods_unsorted.begin();
376 i != mods_unsorted.end(); ++i) {
378 for(std::list<std::string>::iterator x = mods_sorted.begin();
379 x != mods_sorted.end(); ++x) {
380 // I doubt anybody using Minetest will be using
381 // anything not ASCII based :)
382 if(i->compare(*x) <= 0) {
383 mods_sorted.insert(x, *i);
389 mods_sorted.push_back(*i);
392 // Package them up for Lua
393 lua_createtable(L, mods_sorted.size(), 0);
394 std::list<std::string>::iterator iter = mods_sorted.begin();
395 for (u16 i = 0; iter != mods_sorted.end(); iter++) {
396 lua_pushstring(L, iter->c_str());
397 lua_rawseti(L, -2, ++i);
403 int ModApiServer::l_get_worldpath(lua_State *L)
405 NO_MAP_LOCK_REQUIRED;
406 std::string worldpath = getServer(L)->getWorldPath();
407 lua_pushstring(L, worldpath.c_str());
411 // sound_play(spec, parameters)
412 int ModApiServer::l_sound_play(lua_State *L)
414 NO_MAP_LOCK_REQUIRED;
415 SimpleSoundSpec spec;
416 read_soundspec(L, 1, spec);
417 ServerSoundParams params;
418 read_server_sound_params(L, 2, params);
419 s32 handle = getServer(L)->playSound(spec, params);
420 lua_pushinteger(L, handle);
424 // sound_stop(handle)
425 int ModApiServer::l_sound_stop(lua_State *L)
427 NO_MAP_LOCK_REQUIRED;
428 int handle = luaL_checkinteger(L, 1);
429 getServer(L)->stopSound(handle);
434 int ModApiServer::l_is_singleplayer(lua_State *L)
436 NO_MAP_LOCK_REQUIRED;
437 lua_pushboolean(L, getServer(L)->isSingleplayer());
441 // notify_authentication_modified(name)
442 int ModApiServer::l_notify_authentication_modified(lua_State *L)
444 NO_MAP_LOCK_REQUIRED;
445 std::string name = "";
446 if(lua_isstring(L, 1))
447 name = lua_tostring(L, 1);
448 getServer(L)->reportPrivsModified(name);
452 void ModApiServer::Initialize(lua_State *L, int top)
454 API_FCT(request_shutdown);
455 API_FCT(get_server_status);
456 API_FCT(get_worldpath);
457 API_FCT(is_singleplayer);
459 API_FCT(get_current_modname);
460 API_FCT(get_modpath);
461 API_FCT(get_modnames);
463 API_FCT(chat_send_all);
464 API_FCT(chat_send_player);
465 API_FCT(show_formspec);
469 API_FCT(get_player_information);
470 API_FCT(get_player_privs);
471 API_FCT(get_player_ip);
472 API_FCT(get_ban_list);
473 API_FCT(get_ban_description);
475 API_FCT(kick_player);
476 API_FCT(unban_player_or_ip);
477 API_FCT(notify_authentication_modified);