LCOV - code coverage report
Current view: top level - src/script/lua_api - l_server.cpp (source / functions) Hit Total Coverage
Test: report Lines: 1 234 0.4 %
Date: 2015-07-11 18:23:49 Functions: 2 24 8.3 %

          Line data    Source code
       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 "lua_api/l_server.h"
      21             : #include "lua_api/l_internal.h"
      22             : #include "common/c_converter.h"
      23             : #include "common/c_content.h"
      24             : #include "cpp_api/s_base.h"
      25             : #include "server.h"
      26             : #include "environment.h"
      27             : #include "player.h"
      28             : #include "log.h"
      29             : 
      30             : // request_shutdown()
      31           0 : int ModApiServer::l_request_shutdown(lua_State *L)
      32             : {
      33           0 :         getServer(L)->requestShutdown();
      34           0 :         return 0;
      35             : }
      36             : 
      37             : // get_server_status()
      38           0 : int ModApiServer::l_get_server_status(lua_State *L)
      39             : {
      40           0 :         NO_MAP_LOCK_REQUIRED;
      41           0 :         lua_pushstring(L, wide_to_narrow(getServer(L)->getStatusString()).c_str());
      42           0 :         return 1;
      43             : }
      44             : 
      45             : // chat_send_all(text)
      46           0 : int ModApiServer::l_chat_send_all(lua_State *L)
      47             : {
      48           0 :         NO_MAP_LOCK_REQUIRED;
      49           0 :         const char *text = luaL_checkstring(L, 1);
      50             :         // Get server from registry
      51           0 :         Server *server = getServer(L);
      52             :         // Send
      53           0 :         server->notifyPlayers(narrow_to_wide(text));
      54           0 :         return 0;
      55             : }
      56             : 
      57             : // chat_send_player(name, text)
      58           0 : int ModApiServer::l_chat_send_player(lua_State *L)
      59             : {
      60           0 :         NO_MAP_LOCK_REQUIRED;
      61           0 :         const char *name = luaL_checkstring(L, 1);
      62           0 :         const char *text = luaL_checkstring(L, 2);
      63             : 
      64             :         // Get server from registry
      65           0 :         Server *server = getServer(L);
      66             :         // Send
      67           0 :         server->notifyPlayer(name, narrow_to_wide(text));
      68           0 :         return 0;
      69             : }
      70             : 
      71             : // get_player_privs(name, text)
      72           0 : int ModApiServer::l_get_player_privs(lua_State *L)
      73             : {
      74           0 :         NO_MAP_LOCK_REQUIRED;
      75           0 :         const char *name = luaL_checkstring(L, 1);
      76             :         // Get server from registry
      77           0 :         Server *server = getServer(L);
      78             :         // Do it
      79           0 :         lua_newtable(L);
      80           0 :         int table = lua_gettop(L);
      81           0 :         std::set<std::string> privs_s = server->getPlayerEffectivePrivs(name);
      82           0 :         for(std::set<std::string>::const_iterator
      83           0 :                         i = privs_s.begin(); i != privs_s.end(); i++){
      84           0 :                 lua_pushboolean(L, true);
      85           0 :                 lua_setfield(L, table, i->c_str());
      86             :         }
      87           0 :         lua_pushvalue(L, table);
      88           0 :         return 1;
      89             : }
      90             : 
      91             : // get_player_ip()
      92           0 : int ModApiServer::l_get_player_ip(lua_State *L)
      93             : {
      94           0 :         NO_MAP_LOCK_REQUIRED;
      95           0 :         const char * name = luaL_checkstring(L, 1);
      96           0 :         Player *player = getEnv(L)->getPlayer(name);
      97           0 :         if(player == NULL)
      98             :         {
      99           0 :                 lua_pushnil(L); // no such player
     100           0 :                 return 1;
     101             :         }
     102             :         try
     103             :         {
     104           0 :                 Address addr = getServer(L)->getPeerAddress(player->peer_id);
     105           0 :                 std::string ip_str = addr.serializeString();
     106           0 :                 lua_pushstring(L, ip_str.c_str());
     107           0 :                 return 1;
     108             :         }
     109           0 :         catch(con::PeerNotFoundException) // unlikely
     110             :         {
     111           0 :                 dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
     112           0 :                 lua_pushnil(L); // error
     113           0 :                 return 1;
     114             :         }
     115             : }
     116             : 
     117             : // get_player_information()
     118           0 : int ModApiServer::l_get_player_information(lua_State *L)
     119             : {
     120             : 
     121           0 :         NO_MAP_LOCK_REQUIRED;
     122           0 :         const char * name = luaL_checkstring(L, 1);
     123           0 :         Player *player = getEnv(L)->getPlayer(name);
     124           0 :         if(player == NULL)
     125             :         {
     126           0 :                 lua_pushnil(L); // no such player
     127           0 :                 return 1;
     128             :         }
     129             : 
     130           0 :         Address addr;
     131             :         try
     132             :         {
     133           0 :                 addr = getServer(L)->getPeerAddress(player->peer_id);
     134             :         }
     135           0 :         catch(con::PeerNotFoundException) // unlikely
     136             :         {
     137           0 :                 dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
     138           0 :                 lua_pushnil(L); // error
     139           0 :                 return 1;
     140             :         }
     141             : 
     142             :         float min_rtt,max_rtt,avg_rtt,min_jitter,max_jitter,avg_jitter;
     143             :         ClientState state;
     144             :         u32 uptime;
     145             :         u16 prot_vers;
     146             :         u8 ser_vers,major,minor,patch;
     147           0 :         std::string vers_string;
     148             : 
     149             : #define ERET(code)                                                             \
     150             :         if (!(code)) {                                                             \
     151             :                 dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;     \
     152             :                 lua_pushnil(L); /* error */                                            \
     153             :                 return 1;                                                              \
     154             :         }
     155             : 
     156           0 :         ERET(getServer(L)->getClientConInfo(player->peer_id,con::MIN_RTT,&min_rtt))
     157           0 :         ERET(getServer(L)->getClientConInfo(player->peer_id,con::MAX_RTT,&max_rtt))
     158           0 :         ERET(getServer(L)->getClientConInfo(player->peer_id,con::AVG_RTT,&avg_rtt))
     159           0 :         ERET(getServer(L)->getClientConInfo(player->peer_id,con::MIN_JITTER,&min_jitter))
     160           0 :         ERET(getServer(L)->getClientConInfo(player->peer_id,con::MAX_JITTER,&max_jitter))
     161           0 :         ERET(getServer(L)->getClientConInfo(player->peer_id,con::AVG_JITTER,&avg_jitter))
     162             : 
     163           0 :         ERET(getServer(L)->getClientInfo(player->peer_id,
     164             :                                                                                 &state, &uptime, &ser_vers, &prot_vers,
     165             :                                                                                 &major, &minor, &patch, &vers_string))
     166             : 
     167           0 :         lua_newtable(L);
     168           0 :         int table = lua_gettop(L);
     169             : 
     170           0 :         lua_pushstring(L,"address");
     171           0 :         lua_pushstring(L, addr.serializeString().c_str());
     172           0 :         lua_settable(L, table);
     173             : 
     174           0 :         lua_pushstring(L,"ip_version");
     175           0 :         if (addr.getFamily() == AF_INET) {
     176           0 :                 lua_pushnumber(L, 4);
     177           0 :         } else if (addr.getFamily() == AF_INET6) {
     178           0 :                 lua_pushnumber(L, 6);
     179             :         } else {
     180           0 :                 lua_pushnumber(L, 0);
     181             :         }
     182           0 :         lua_settable(L, table);
     183             : 
     184           0 :         lua_pushstring(L,"min_rtt");
     185           0 :         lua_pushnumber(L, min_rtt);
     186           0 :         lua_settable(L, table);
     187             : 
     188           0 :         lua_pushstring(L,"max_rtt");
     189           0 :         lua_pushnumber(L, max_rtt);
     190           0 :         lua_settable(L, table);
     191             : 
     192           0 :         lua_pushstring(L,"avg_rtt");
     193           0 :         lua_pushnumber(L, avg_rtt);
     194           0 :         lua_settable(L, table);
     195             : 
     196           0 :         lua_pushstring(L,"min_jitter");
     197           0 :         lua_pushnumber(L, min_jitter);
     198           0 :         lua_settable(L, table);
     199             : 
     200           0 :         lua_pushstring(L,"max_jitter");
     201           0 :         lua_pushnumber(L, max_jitter);
     202           0 :         lua_settable(L, table);
     203             : 
     204           0 :         lua_pushstring(L,"avg_jitter");
     205           0 :         lua_pushnumber(L, avg_jitter);
     206           0 :         lua_settable(L, table);
     207             : 
     208           0 :         lua_pushstring(L,"connection_uptime");
     209           0 :         lua_pushnumber(L, uptime);
     210           0 :         lua_settable(L, table);
     211             : 
     212             : #ifndef NDEBUG
     213             :         lua_pushstring(L,"serialization_version");
     214             :         lua_pushnumber(L, ser_vers);
     215             :         lua_settable(L, table);
     216             : 
     217             :         lua_pushstring(L,"protocol_version");
     218             :         lua_pushnumber(L, prot_vers);
     219             :         lua_settable(L, table);
     220             : 
     221             :         lua_pushstring(L,"major");
     222             :         lua_pushnumber(L, major);
     223             :         lua_settable(L, table);
     224             : 
     225             :         lua_pushstring(L,"minor");
     226             :         lua_pushnumber(L, minor);
     227             :         lua_settable(L, table);
     228             : 
     229             :         lua_pushstring(L,"patch");
     230             :         lua_pushnumber(L, patch);
     231             :         lua_settable(L, table);
     232             : 
     233             :         lua_pushstring(L,"version_string");
     234             :         lua_pushstring(L, vers_string.c_str());
     235             :         lua_settable(L, table);
     236             : 
     237             :         lua_pushstring(L,"state");
     238             :         lua_pushstring(L,ClientInterface::state2Name(state).c_str());
     239             :         lua_settable(L, table);
     240             : #endif
     241             : 
     242             : #undef ERET
     243           0 :         return 1;
     244             : }
     245             : 
     246             : // get_ban_list()
     247           0 : int ModApiServer::l_get_ban_list(lua_State *L)
     248             : {
     249           0 :         NO_MAP_LOCK_REQUIRED;
     250           0 :         lua_pushstring(L, getServer(L)->getBanDescription("").c_str());
     251           0 :         return 1;
     252             : }
     253             : 
     254             : // get_ban_description()
     255           0 : int ModApiServer::l_get_ban_description(lua_State *L)
     256             : {
     257           0 :         NO_MAP_LOCK_REQUIRED;
     258           0 :         const char * ip_or_name = luaL_checkstring(L, 1);
     259           0 :         lua_pushstring(L, getServer(L)->getBanDescription(std::string(ip_or_name)).c_str());
     260           0 :         return 1;
     261             : }
     262             : 
     263             : // ban_player()
     264           0 : int ModApiServer::l_ban_player(lua_State *L)
     265             : {
     266           0 :         NO_MAP_LOCK_REQUIRED;
     267           0 :         const char * name = luaL_checkstring(L, 1);
     268           0 :         Player *player = getEnv(L)->getPlayer(name);
     269           0 :         if(player == NULL)
     270             :         {
     271           0 :                 lua_pushboolean(L, false); // no such player
     272           0 :                 return 1;
     273             :         }
     274             :         try
     275             :         {
     276           0 :                 Address addr = getServer(L)->getPeerAddress(getEnv(L)->getPlayer(name)->peer_id);
     277           0 :                 std::string ip_str = addr.serializeString();
     278           0 :                 getServer(L)->setIpBanned(ip_str, name);
     279             :         }
     280           0 :         catch(con::PeerNotFoundException) // unlikely
     281             :         {
     282           0 :                 dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
     283           0 :                 lua_pushboolean(L, false); // error
     284           0 :                 return 1;
     285             :         }
     286           0 :         lua_pushboolean(L, true);
     287           0 :         return 1;
     288             : }
     289             : 
     290             : // kick_player(name, [reason]) -> success
     291           0 : int ModApiServer::l_kick_player(lua_State *L)
     292             : {
     293           0 :         NO_MAP_LOCK_REQUIRED;
     294           0 :         const char *name = luaL_checkstring(L, 1);
     295           0 :         std::string message;
     296           0 :         if (lua_isstring(L, 2))
     297             :         {
     298           0 :                 message = std::string("Kicked: ") + lua_tostring(L, 2);
     299             :         }
     300             :         else
     301             :         {
     302           0 :                 message = "Kicked.";
     303             :         }
     304           0 :         Player *player = getEnv(L)->getPlayer(name);
     305           0 :         if (player == NULL)
     306             :         {
     307           0 :                 lua_pushboolean(L, false); // No such player
     308           0 :                 return 1;
     309             :         }
     310           0 :         getServer(L)->DenyAccess_Legacy(player->peer_id, narrow_to_wide(message));
     311           0 :         lua_pushboolean(L, true);
     312           0 :         return 1;
     313             : }
     314             : 
     315             : // unban_player_or_ip()
     316           0 : int ModApiServer::l_unban_player_or_ip(lua_State *L)
     317             : {
     318           0 :         NO_MAP_LOCK_REQUIRED;
     319           0 :         const char * ip_or_name = luaL_checkstring(L, 1);
     320           0 :         getServer(L)->unsetIpBanned(ip_or_name);
     321           0 :         lua_pushboolean(L, true);
     322           0 :         return 1;
     323             : }
     324             : 
     325             : // show_formspec(playername,formname,formspec)
     326           0 : int ModApiServer::l_show_formspec(lua_State *L)
     327             : {
     328           0 :         NO_MAP_LOCK_REQUIRED;
     329           0 :         const char *playername = luaL_checkstring(L, 1);
     330           0 :         const char *formname = luaL_checkstring(L, 2);
     331           0 :         const char *formspec = luaL_checkstring(L, 3);
     332             : 
     333           0 :         if(getServer(L)->showFormspec(playername,formspec,formname))
     334             :         {
     335           0 :                 lua_pushboolean(L, true);
     336             :         }else{
     337           0 :                 lua_pushboolean(L, false);
     338             :         }
     339           0 :         return 1;
     340             : }
     341             : 
     342             : // get_current_modname()
     343           0 : int ModApiServer::l_get_current_modname(lua_State *L)
     344             : {
     345           0 :         NO_MAP_LOCK_REQUIRED;
     346           0 :         lua_getfield(L, LUA_REGISTRYINDEX, SCRIPT_MOD_NAME_FIELD);
     347           0 :         return 1;
     348             : }
     349             : 
     350             : // get_modpath(modname)
     351           0 : int ModApiServer::l_get_modpath(lua_State *L)
     352             : {
     353           0 :         NO_MAP_LOCK_REQUIRED;
     354           0 :         std::string modname = luaL_checkstring(L, 1);
     355           0 :         const ModSpec *mod = getServer(L)->getModSpec(modname);
     356           0 :         if (!mod) {
     357           0 :                 lua_pushnil(L);
     358           0 :                 return 1;
     359             :         }
     360           0 :         lua_pushstring(L, mod->path.c_str());
     361           0 :         return 1;
     362             : }
     363             : 
     364             : // get_modnames()
     365             : // the returned list is sorted alphabetically for you
     366           0 : int ModApiServer::l_get_modnames(lua_State *L)
     367             : {
     368           0 :         NO_MAP_LOCK_REQUIRED;
     369             : 
     370             :         // Get a list of mods
     371           0 :         std::vector<std::string> modlist;
     372           0 :         getServer(L)->getModNames(modlist);
     373             : 
     374             :         // Take unsorted items from mods_unsorted and sort them into
     375             :         // mods_sorted; not great performance but the number of mods on a
     376             :         // server will likely be small.
     377           0 :         std::sort(modlist.begin(), modlist.end());
     378             : 
     379             :         // Package them up for Lua
     380           0 :         lua_createtable(L, modlist.size(), 0);
     381           0 :         std::vector<std::string>::iterator iter = modlist.begin();
     382           0 :         for (u16 i = 0; iter != modlist.end(); iter++) {
     383           0 :                 lua_pushstring(L, iter->c_str());
     384           0 :                 lua_rawseti(L, -2, ++i);
     385             :         }
     386           0 :         return 1;
     387             : }
     388             : 
     389             : // get_worldpath()
     390           0 : int ModApiServer::l_get_worldpath(lua_State *L)
     391             : {
     392           0 :         NO_MAP_LOCK_REQUIRED;
     393           0 :         std::string worldpath = getServer(L)->getWorldPath();
     394           0 :         lua_pushstring(L, worldpath.c_str());
     395           0 :         return 1;
     396             : }
     397             : 
     398             : // sound_play(spec, parameters)
     399           0 : int ModApiServer::l_sound_play(lua_State *L)
     400             : {
     401           0 :         NO_MAP_LOCK_REQUIRED;
     402           0 :         SimpleSoundSpec spec;
     403           0 :         read_soundspec(L, 1, spec);
     404           0 :         ServerSoundParams params;
     405           0 :         read_server_sound_params(L, 2, params);
     406           0 :         s32 handle = getServer(L)->playSound(spec, params);
     407           0 :         lua_pushinteger(L, handle);
     408           0 :         return 1;
     409             : }
     410             : 
     411             : // sound_stop(handle)
     412           0 : int ModApiServer::l_sound_stop(lua_State *L)
     413             : {
     414           0 :         NO_MAP_LOCK_REQUIRED;
     415           0 :         int handle = luaL_checkinteger(L, 1);
     416           0 :         getServer(L)->stopSound(handle);
     417           0 :         return 0;
     418             : }
     419             : 
     420             : // is_singleplayer()
     421           0 : int ModApiServer::l_is_singleplayer(lua_State *L)
     422             : {
     423           0 :         NO_MAP_LOCK_REQUIRED;
     424           0 :         lua_pushboolean(L, getServer(L)->isSingleplayer());
     425           0 :         return 1;
     426             : }
     427             : 
     428             : // notify_authentication_modified(name)
     429           0 : int ModApiServer::l_notify_authentication_modified(lua_State *L)
     430             : {
     431           0 :         NO_MAP_LOCK_REQUIRED;
     432           0 :         std::string name = "";
     433           0 :         if(lua_isstring(L, 1))
     434           0 :                 name = lua_tostring(L, 1);
     435           0 :         getServer(L)->reportPrivsModified(name);
     436           0 :         return 0;
     437             : }
     438             : 
     439             : #ifndef NDEBUG
     440             : // cause_error(type_of_error)
     441             : int ModApiServer::l_cause_error(lua_State *L)
     442             : {
     443             :         NO_MAP_LOCK_REQUIRED;
     444             :         std::string type_of_error = "none";
     445             :         if(lua_isstring(L, 1))
     446             :                 type_of_error = lua_tostring(L, 1);
     447             : 
     448             :         errorstream << "Error handler test called, errortype=" << type_of_error << std::endl;
     449             : 
     450             :         if(type_of_error == "segv") {
     451             :                 volatile int* some_pointer = 0;
     452             :                 errorstream << "Cause a sigsegv now: " << (*some_pointer) << std::endl;
     453             : 
     454             :         } else if (type_of_error == "zerodivision") {
     455             : 
     456             :                 unsigned int some_number = porting::getTimeS();
     457             :                 unsigned int zerovalue = 0;
     458             :                 unsigned int result = some_number / zerovalue;
     459             :                 errorstream << "Well this shouldn't ever be shown: " << result << std::endl;
     460             : 
     461             :         } else if (type_of_error == "exception") {
     462             :                 throw BaseException("Errorhandler test fct called");
     463             :         }
     464             : 
     465             :         return 0;
     466             : }
     467             : #endif
     468             : 
     469           0 : void ModApiServer::Initialize(lua_State *L, int top)
     470             : {
     471           0 :         API_FCT(request_shutdown);
     472           0 :         API_FCT(get_server_status);
     473           0 :         API_FCT(get_worldpath);
     474           0 :         API_FCT(is_singleplayer);
     475             : 
     476           0 :         API_FCT(get_current_modname);
     477           0 :         API_FCT(get_modpath);
     478           0 :         API_FCT(get_modnames);
     479             : 
     480           0 :         API_FCT(chat_send_all);
     481           0 :         API_FCT(chat_send_player);
     482           0 :         API_FCT(show_formspec);
     483           0 :         API_FCT(sound_play);
     484           0 :         API_FCT(sound_stop);
     485             : 
     486           0 :         API_FCT(get_player_information);
     487           0 :         API_FCT(get_player_privs);
     488           0 :         API_FCT(get_player_ip);
     489           0 :         API_FCT(get_ban_list);
     490           0 :         API_FCT(get_ban_description);
     491           0 :         API_FCT(ban_player);
     492           0 :         API_FCT(kick_player);
     493           0 :         API_FCT(unban_player_or_ip);
     494           0 :         API_FCT(notify_authentication_modified);
     495             : 
     496             : #ifndef NDEBUG
     497             :         API_FCT(cause_error);
     498             : #endif
     499           3 : }

Generated by: LCOV version 1.11