Omnicleanup: header cleanup, add ModApiUtil shared between game and mainmenu
authorKahrl <kahrl@gmx.net>
Sun, 11 Aug 2013 02:09:45 +0000 (04:09 +0200)
committerKahrl <kahrl@gmx.net>
Wed, 14 Aug 2013 19:03:33 +0000 (21:03 +0200)
158 files changed:
builtin/mainmenu.lua
doc/lua_api.txt
doc/menu_lua_api.txt
minetest.conf.example
src/CMakeLists.txt
src/activeobject.h
src/ban.cpp
src/chat.cpp
src/chat.h
src/client.cpp
src/client.h
src/clientserver.cpp [deleted file]
src/clientserver.h
src/connection.h
src/constants.h
src/content_abm.cpp
src/content_nodemeta.cpp
src/content_nodemeta.h
src/content_sao.cpp
src/craftdef.cpp
src/debug.cpp
src/debug.h
src/defaultsettings.cpp
src/emerge.cpp
src/emerge.h
src/environment.cpp
src/environment.h
src/exceptions.h
src/filecache.cpp
src/filesys.cpp
src/game.cpp
src/game.h
src/guiEngine.cpp
src/guiEngine.h
src/guiFormSpecMenu.cpp
src/guiFormSpecMenu.h
src/guiLuaApi.cpp [deleted file]
src/guiLuaApi.h [deleted file]
src/guiVolumeChange.cpp
src/hud.cpp
src/hud.h
src/inventory.h
src/inventorymanager.cpp
src/irrlichttypes_bloated.h
src/irrlichttypes_extrabloated.h
src/itemgroup.h
src/light.h
src/main.cpp
src/main.h
src/map.cpp
src/map.h
src/mapblock.cpp
src/mapblock.h
src/mapgen.cpp
src/mapgen.h
src/mapgen_singlenode.cpp
src/mapnode.h
src/mapsector.cpp
src/mapsector.h
src/mesh.cpp
src/mods.h
src/nameidmapping.cpp
src/nodemetadata.h
src/nodetimer.cpp
src/nodetimer.h
src/noise.cpp
src/object_properties.cpp
src/pathfinder.cpp
src/pathfinder.h
src/player.cpp
src/player.h
src/porting.h
src/profiler.h
src/rollback.cpp
src/script/CMakeLists.txt
src/script/common/CMakeLists.txt
src/script/common/c_content.cpp
src/script/common/c_content.h
src/script/common/c_internal.cpp
src/script/common/c_internal.h
src/script/common/c_types.h
src/script/cpp_api/CMakeLists.txt
src/script/cpp_api/s_base.cpp
src/script/cpp_api/s_base.h
src/script/cpp_api/s_entity.cpp
src/script/cpp_api/s_env.cpp
src/script/cpp_api/s_internal.h [new file with mode: 0644]
src/script/cpp_api/s_inventory.cpp
src/script/cpp_api/s_item.cpp
src/script/cpp_api/s_mainmenu.cpp [new file with mode: 0644]
src/script/cpp_api/s_mainmenu.h [new file with mode: 0644]
src/script/cpp_api/s_node.cpp
src/script/cpp_api/s_nodemeta.cpp
src/script/cpp_api/s_player.cpp
src/script/cpp_api/s_player.h
src/script/cpp_api/s_server.cpp [new file with mode: 0644]
src/script/cpp_api/s_server.h [new file with mode: 0644]
src/script/cpp_api/scriptapi.cpp [deleted file]
src/script/cpp_api/scriptapi.h [deleted file]
src/script/lua_api/CMakeLists.txt
src/script/lua_api/l_base.cpp
src/script/lua_api/l_base.h
src/script/lua_api/l_craft.cpp
src/script/lua_api/l_craft.h
src/script/lua_api/l_env.cpp
src/script/lua_api/l_env.h
src/script/lua_api/l_internal.h [new file with mode: 0644]
src/script/lua_api/l_inventory.cpp
src/script/lua_api/l_inventory.h
src/script/lua_api/l_item.cpp
src/script/lua_api/l_item.h
src/script/lua_api/l_mainmenu.cpp [new file with mode: 0644]
src/script/lua_api/l_mainmenu.h [new file with mode: 0644]
src/script/lua_api/l_mapgen.cpp [new file with mode: 0644]
src/script/lua_api/l_mapgen.h [new file with mode: 0644]
src/script/lua_api/l_nodemeta.cpp
src/script/lua_api/l_nodemeta.h
src/script/lua_api/l_nodetimer.cpp
src/script/lua_api/l_nodetimer.h
src/script/lua_api/l_noise.cpp
src/script/lua_api/l_noise.h
src/script/lua_api/l_object.cpp
src/script/lua_api/l_object.h
src/script/lua_api/l_particles.cpp
src/script/lua_api/l_particles.h
src/script/lua_api/l_rollback.cpp [new file with mode: 0644]
src/script/lua_api/l_rollback.h [new file with mode: 0644]
src/script/lua_api/l_server.cpp [new file with mode: 0644]
src/script/lua_api/l_server.h [new file with mode: 0644]
src/script/lua_api/l_util.cpp [new file with mode: 0644]
src/script/lua_api/l_util.h [new file with mode: 0644]
src/script/lua_api/l_vmanip.cpp
src/script/lua_api/l_vmanip.h
src/script/lua_api/luaapi.cpp [deleted file]
src/script/lua_api/luaapi.h [deleted file]
src/script/scripting_game.cpp [new file with mode: 0644]
src/script/scripting_game.h [new file with mode: 0644]
src/script/scripting_mainmenu.cpp [new file with mode: 0644]
src/script/scripting_mainmenu.h [new file with mode: 0644]
src/server.cpp
src/server.h
src/settings.h
src/socket.cpp
src/strfnd.h
src/test.cpp
src/threads.h
src/tool.cpp
src/treegen.cpp
src/treegen.h
src/util/container.h
src/util/numeric.h
src/util/pointedthing.cpp
src/util/serialize.cpp
src/util/serialize.h
src/util/string.cpp
src/util/string.h
src/voxel.cpp
src/voxel.h

index e0ab82ebb241f021788686eea0ea07385817015e..926f3f2d92dc3a58b35dee1e7d36534eca1fe3ab 100644 (file)
@@ -1,3 +1,5 @@
+print = engine.debug
+math.randomseed(os.time())
 os.setlocale("C", "numeric")
 
 local scriptpath = engine.get_scriptdir()
@@ -9,6 +11,7 @@ mt_color_dark_green = "#003300"
 
 --for all other colors ask sfan5 to complete his worK!
 
+dofile(scriptpath .. DIR_DELIM .. "misc_helpers.lua")
 dofile(scriptpath .. DIR_DELIM .. "filterlist.lua")
 dofile(scriptpath .. DIR_DELIM .. "modmgr.lua")
 dofile(scriptpath .. DIR_DELIM .. "modstore.lua")
index eefcc68a29c91802fb400d1d361628b7e119080d..59e70581cdfea613f6b963a11ed273ba20b5a17e 100644 (file)
@@ -1167,6 +1167,7 @@ minetest.register_authentication_handler(handler)
 Setting-related:
 minetest.setting_set(name, value)
 minetest.setting_get(name) -> string or nil
+minetest.setting_setbool(name, value)
 minetest.setting_getbool(name) -> boolean value or nil
 minetest.setting_get_pos(name) -> position or nil
 minetest.setting_save() -> nil, save all settings to config file
index 164d7876a71766ca126f2f0c550c907c66c60bd9..3812f11fddb2ef7786931e87b0ef11d915cd0fa9 100644 (file)
@@ -127,11 +127,19 @@ engine.get_favorites(location) -> list of favorites
 }
 engine.delete_favorite(id, location) -> success
 
+Logging:
+engine.debug(line)
+^ Always printed to stderr and logfile (print() is redirected here)
+engine.log(line)
+engine.log(loglevel, line)
+^ loglevel one of "error", "action", "info", "verbose"
+
 Settings:
 engine.setting_set(name, value)
 engine.setting_get(name) -> string or nil
 engine.setting_setbool(name, value)
 engine.setting_getbool(name) -> bool or nil
+engine.setting_save() -> nil, save all settings to config file
 
 Worlds:
 engine.get_worlds() -> list of worlds
@@ -164,4 +172,4 @@ dump(obj, dumped={})
 string:split(separator)
 ^ eg. string:split("a,b", ",") == {"a","b"}
 string:trim()
-^ eg. string.trim("\n \t\tfoo bar\t ") == "foo bar"
\ No newline at end of file
+^ eg. string.trim("\n \t\tfoo bar\t ") == "foo bar"
index b1732fa07a3803d5c6ef62fd6a1812322fbb637a..96f075e76e4278ad5d03d4f3701983c5ad2cbb39 100644 (file)
 # to IPv6 clients, depending on system configuration.
 #ipv6_server = false
 
+#main_menu_script =
 #main_menu_game_mgr = 0
 #main_menu_mod_mgr = 1
 #modstore_download_url = https://forum.minetest.net/media/
index a1fcdd96564a82cc44667767b758bf470e8bad83..18cdaa725c6fe897d4b66df25385dafec50c1d1d 100644 (file)
@@ -267,12 +267,11 @@ set(common_SRCS
        base64.cpp
        ban.cpp
        biome.cpp
-       clientserver.cpp
        staticobject.cpp
        serverlist.cpp
        pathfinder.cpp
        convert_json.cpp
-       ${SCRIPT_SRCS}
+       ${common_SCRIPT_SRCS}
        ${UTIL_SRCS}
 )
 
@@ -329,9 +328,9 @@ set(minetest_SRCS
        game.cpp
        main.cpp
        guiEngine.cpp
-       guiLuaApi.cpp
        guiFileSelectMenu.cpp
        convert_json.cpp
+       ${minetest_SCRIPT_SRCS}
 )
 
 if(USE_FREETYPE)
@@ -341,11 +340,14 @@ if(USE_FREETYPE)
        )
 endif(USE_FREETYPE)
 
+list(SORT minetest_SRCS)
+
 # Server sources
 set(minetestserver_SRCS
        ${common_SRCS}
        main.cpp
 )
+list(SORT minetestserver_SRCS)
 
 include_directories(
        ${PROJECT_BINARY_DIR}
index f4d721a552a09cba4c6fdfc2c60a2ea445ae3ea1..46880fc7feb10819a775bc9c0cbee0ce8e7a0fb9 100644 (file)
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef ACTIVEOBJECT_HEADER
 #define ACTIVEOBJECT_HEADER
 
-#include "irrlichttypes_bloated.h"
+#include "irr_aabb3d.h"
 #include <string>
 
 #define ACTIVEOBJECT_TYPE_INVALID 0
index 25d7f4ccb18f6ba1c23163395a8deef286d1c21f..5bb470a676f5e6c3a010e50f26cb83990a65614b 100644 (file)
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <sstream>
 #include <set>
 #include "strfnd.h"
+#include "util/string.h"
 #include "log.h"
 #include "filesys.h"
 
index 3102e194a0851d5c48f840c08ee141fac1ad464b..0bd5c16709bb54565f677e7d34123cd6af173608 100644 (file)
@@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "chat.h"
 #include "debug.h"
-#include <cassert>
+#include "strfnd.h"
 #include <cctype>
 #include <sstream>
 #include "util/string.h"
index 19b48456ec7dd013b1c2aba40fdde360488ef360..e39d97ec2a67252093df25ac978be1dba286471e 100644 (file)
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef CHAT_HEADER
 #define CHAT_HEADER
 
-#include "irrlichttypes_bloated.h"
+#include "irrlichttypes.h"
 #include <string>
 #include <vector>
 #include <list>
index f9908ad2cbdc6d5f1b1625523e02080a9738d21e..ecbb32dd22ddd9743f768d8770e58071a9c34f0b 100644 (file)
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "jmutexautolock.h"
 #include "main.h"
 #include <sstream>
+#include "filesys.h"
 #include "porting.h"
 #include "mapsector.h"
 #include "mapblock_mesh.h"
@@ -1356,8 +1357,6 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
                        std::istringstream is(datastring, std::ios_base::binary);
                        //t3.stop();
                        
-                       //m_env.printPlayers(infostream);
-
                        //TimeTaker t4("player get", m_device);
                        Player *player = m_env.getLocalPlayer();
                        assert(player != NULL);
index fc26f317825886851a54f88668a2e4d98d1d7f2b..9146941e8263dbb02f3906d3eaac52f5401671db 100644 (file)
@@ -25,12 +25,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "irrlichttypes_extrabloated.h"
 #include "jmutex.h"
 #include <ostream>
+#include <map>
 #include <set>
 #include <vector>
 #include "clientobject.h"
 #include "gamedef.h"
 #include "inventorymanager.h"
-#include "filesys.h"
 #include "filecache.h"
 #include "localplayer.h"
 #include "server.h"
@@ -246,6 +246,57 @@ struct ClientEvent
        };
 };
 
+/*
+       Packet counter
+*/
+
+class PacketCounter
+{
+public:
+       PacketCounter()
+       {
+       }
+
+       void add(u16 command)
+       {
+               std::map<u16, u16>::iterator n = m_packets.find(command);
+               if(n == m_packets.end())
+               {
+                       m_packets[command] = 1;
+               }
+               else
+               {
+                       n->second++;
+               }
+       }
+
+       void clear()
+       {
+               for(std::map<u16, u16>::iterator
+                               i = m_packets.begin();
+                               i != m_packets.end(); ++i)
+               {
+                       i->second = 0;
+               }
+       }
+
+       void print(std::ostream &o)
+       {
+               for(std::map<u16, u16>::iterator
+                               i = m_packets.begin();
+                               i != m_packets.end(); ++i)
+               {
+                       o<<"cmd "<<i->first
+                                       <<" count "<<i->second
+                                       <<std::endl;
+               }
+       }
+
+private:
+       // command, count
+       std::map<u16, u16> m_packets;
+};
+
 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
 {
 public:
@@ -419,8 +470,6 @@ private:
        void Receive();
        
        void sendPlayerPos();
-       // This sends the player's current name etc to the server
-       void sendPlayerInfo();
        // Send the item number 'item' as player item to the server
        void sendPlayerItem(u16 item);
        
diff --git a/src/clientserver.cpp b/src/clientserver.cpp
deleted file mode 100644 (file)
index 591a955..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-Minetest
-Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "clientserver.h"
-#include "util/serialize.h"
-
-SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time, float time_speed)
-{
-       SharedBuffer<u8> data(2+2+4);
-       writeU16(&data[0], TOCLIENT_TIME_OF_DAY);
-       writeU16(&data[2], time);
-       writeF1000(&data[4], time_speed);
-       return data;
-}
-
index ebfe7f3c79d87fdf0be40a12024768d595b4a6b9..fb442cfc0fdf2ee80708aa0f01788b545d60d4fd 100644 (file)
@@ -20,10 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef CLIENTSERVER_HEADER
 #define CLIENTSERVER_HEADER
 
-#include "util/pointer.h"
-
-SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time, float time_speed);
-
 /*
        changes by PROTOCOL_VERSION:
 
index e68557ccde68918d8f8cb1c1b3e11653b85eb925..a1d564849810b1afc1d995ed858c56d2cf03db72 100644 (file)
@@ -191,15 +191,14 @@ TODO: Should we have a receiver_peer_id also?
        [6] u8 channel
 sender_peer_id:
        Unique to each peer.
-       value 0 is reserved for making new connections
-       value 1 is reserved for server
+       value 0 (PEER_ID_INEXISTENT) is reserved for making new connections
+       value 1 (PEER_ID_SERVER) is reserved for server
+       these constants are defined in constants.h
 channel:
        The lower the number, the higher the priority is.
        Only channels 0, 1 and 2 exist.
 */
 #define BASE_HEADER_SIZE 7
-#define PEER_ID_INEXISTENT 0
-#define PEER_ID_SERVER 1
 #define CHANNEL_COUNT 3
 /*
 Packet types:
index e9d9f884ad4a44b7a30c606e1e1f5157efd8e726..8c478ac6a2a1a3fdb7b1963a79da9726f1106d17 100644 (file)
@@ -32,6 +32,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
     Connection
 */
 
+#define PEER_ID_INEXISTENT 0
+#define PEER_ID_SERVER 1
+
 // Define for simulating the quirks of sending through internet.
 // Causes the socket class to deliberately drop random packets.
 // This disables unit testing of socket and connection.
@@ -83,12 +86,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 // Size of player's main inventory
 #define PLAYER_INVENTORY_SIZE (8*4)
 
-/*
-       This is good to be a bit different than 0 so that water level is not
-    between two MapBlocks
-*/
-#define WATER_LEVEL 1
-
 // Maximum hit points of a player
 #define PLAYER_MAX_HP 20
 
index 57e4637d4f98a4c83e77a94acd0857b1cfd0ecdd..6e2d438fdbc32971fbf3b401d3cc855143b82c69 100644 (file)
@@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "treegen.h" // For treegen::make_tree
 #include "main.h" // for g_settings
 #include "map.h"
-#include "cpp_api/scriptapi.h"
+#include "scripting_game.h"
 #include "log.h"
 
 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
index a9a8cc60c7846a3bd382c82c51be506afab0af8d..f504924f956a39dcc8fe29bbe323496186efcef7 100644 (file)
@@ -18,8 +18,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "content_nodemeta.h"
+#include "nodemetadata.h"
+#include "nodetimer.h"
 #include "inventory.h"
 #include "log.h"
+#include "serialization.h"
 #include "util/serialize.h"
 #include "util/string.h"
 #include "constants.h" // MAP_BLOCKSIZE
index 907649b5fa7b7941d9f639a399c2cf8d0517b716..0b08bc6a13a23681ef047d0cdcaa4c5f0689d47c 100644 (file)
@@ -20,8 +20,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef CONTENT_NODEMETA_HEADER
 #define CONTENT_NODEMETA_HEADER
 
-#include "nodemetadata.h"
-#include "nodetimer.h"
+#include <iostream>
+
+class NodeMetadataList;
+class NodeTimerList;
+class IGameDef;
 
 /*
        Legacy nodemeta definitions
index f3ccd6db0fe45de38374b61d77fd71ec78e1253b..347e8892949c5d48fcc0898dc33f81dd9d6e3d02 100644 (file)
@@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "tool.h" // For ToolCapabilities
 #include "gamedef.h"
 #include "player.h"
-#include "cpp_api/scriptapi.h"
+#include "scripting_game.h"
 #include "genericobject.h"
 #include "util/serialize.h"
 #include "util/mathconstants.h"
@@ -399,7 +399,7 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
 LuaEntitySAO::~LuaEntitySAO()
 {
        if(m_registered){
-               ENV_TO_SA(m_env)->luaentity_Remove(m_id);
+               m_env->getScriptIface()->luaentity_Remove(m_id);
        }
 }
 
@@ -408,15 +408,18 @@ void LuaEntitySAO::addedToEnvironment(u32 dtime_s)
        ServerActiveObject::addedToEnvironment(dtime_s);
        
        // Create entity from name
-       m_registered = ENV_TO_SA(m_env)->luaentity_Add(m_id, m_init_name.c_str());
+       m_registered = m_env->getScriptIface()->
+               luaentity_Add(m_id, m_init_name.c_str());
        
        if(m_registered){
                // Get properties
-               ENV_TO_SA(m_env)->luaentity_GetProperties(m_id, &m_prop);
+               m_env->getScriptIface()->
+                       luaentity_GetProperties(m_id, &m_prop);
                // Initialize HP from properties
                m_hp = m_prop.hp_max;
                // Activate entity, supplying serialized state
-               ENV_TO_SA(m_env)->luaentity_Activate(m_id, m_init_state.c_str(), dtime_s);
+               m_env->getScriptIface()->
+                       luaentity_Activate(m_id, m_init_state.c_str(), dtime_s);
        }
 }
 
@@ -530,7 +533,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
        }
 
        if(m_registered){
-               ENV_TO_SA(m_env)->luaentity_Step(m_id, dtime);
+               m_env->getScriptIface()->luaentity_Step(m_id, dtime);
        }
 
        if(send_recommended == false)
@@ -640,7 +643,8 @@ std::string LuaEntitySAO::getStaticData()
        os<<serializeString(m_init_name);
        // state
        if(m_registered){
-               std::string state = ENV_TO_SA(m_env)->luaentity_GetStaticdata(m_id);
+               std::string state = m_env->getScriptIface()->
+                       luaentity_GetStaticdata(m_id);
                os<<serializeLongString(state);
        } else {
                os<<serializeLongString(m_init_state);
@@ -707,7 +711,7 @@ int LuaEntitySAO::punch(v3f dir,
                        m_removed = true;
        }
 
-       ENV_TO_SA(m_env)->luaentity_Punch(m_id, puncher,
+       m_env->getScriptIface()->luaentity_Punch(m_id, puncher,
                        time_from_last_punch, toolcap, dir);
 
        return result.wear;
@@ -720,7 +724,7 @@ void LuaEntitySAO::rightClick(ServerActiveObject *clicker)
        // It's best that attachments cannot be clicked
        if(isAttached())
                return;
-       ENV_TO_SA(m_env)->luaentity_Rightclick(m_id, clicker);
+       m_env->getScriptIface()->luaentity_Rightclick(m_id, clicker);
 }
 
 void LuaEntitySAO::setPos(v3f pos)
index c79408f9986b177aa0933f7aa777e6ef38aea78f..5c7c3a4659d5012ace8901179e61c331cdedafa2 100644 (file)
@@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "inventory.h"
 #include "util/serialize.h"
 #include "strfnd.h"
+#include "exceptions.h"
 
 // Check if input matches recipe
 // Takes recipe groups into account
@@ -150,23 +151,6 @@ static bool craftGetBounds(const std::vector<std::string> &items, unsigned int w
        return success;
 }
 
-#if 0
-// This became useless when group support was added to shapeless recipes
-// Convert a list of item names to a multiset
-static std::multiset<std::string> craftMakeMultiset(const std::vector<std::string> &names)
-{
-       std::multiset<std::string> set;
-       for(std::vector<std::string>::const_iterator
-                       i = names.begin();
-                       i != names.end(); i++)
-       {
-               if(*i != "")
-                       set.insert(*i);
-       }
-       return set;
-}
-#endif
-
 // Removes 1 from each item stack
 static void craftDecrementInput(CraftInput &input, IGameDef *gamedef)
 {
index 2e4992a78013f752ae51211db4d5d018cda11498..6bdd1bce55e8e1df910c898b1714afdfb6254b8c 100644 (file)
@@ -19,16 +19,34 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 
 #include "debug.h"
+#include "exceptions.h"
+#include "threads.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <cstring>
+#include <map>
+#include <jmutex.h>
+#include <jmutexautolock.h>
 
 /*
        Debug output
 */
 
+#define DEBUGSTREAM_COUNT 2
+
 FILE *g_debugstreams[DEBUGSTREAM_COUNT] = {stderr, NULL};
 
+#define DEBUGPRINT(...)\
+{\
+       for(int i=0; i<DEBUGSTREAM_COUNT; i++)\
+       {\
+               if(g_debugstreams[i] != NULL){\
+                       fprintf(g_debugstreams[i], __VA_ARGS__);\
+                       fflush(g_debugstreams[i]);\
+               }\
+       }\
+}
+
 void debugstreams_init(bool disable_stderr, const char *filename)
 {
        if(disable_stderr)
@@ -53,6 +71,47 @@ void debugstreams_deinit()
                fclose(g_debugstreams[1]);
 }
 
+class Debugbuf : public std::streambuf
+{
+public:
+       Debugbuf(bool disable_stderr)
+       {
+               m_disable_stderr = disable_stderr;
+       }
+
+       int overflow(int c)
+       {
+               for(int i=0; i<DEBUGSTREAM_COUNT; i++)
+               {
+                       if(g_debugstreams[i] == stderr && m_disable_stderr)
+                               continue;
+                       if(g_debugstreams[i] != NULL)
+                               (void)fwrite(&c, 1, 1, g_debugstreams[i]);
+                       //TODO: Is this slow?
+                       fflush(g_debugstreams[i]);
+               }
+               
+               return c;
+       }
+       std::streamsize xsputn(const char *s, std::streamsize n)
+       {
+               for(int i=0; i<DEBUGSTREAM_COUNT; i++)
+               {
+                       if(g_debugstreams[i] == stderr && m_disable_stderr)
+                               continue;
+                       if(g_debugstreams[i] != NULL)
+                               (void)fwrite(s, 1, n, g_debugstreams[i]);
+                       //TODO: Is this slow?
+                       fflush(g_debugstreams[i]);
+               }
+
+               return n;
+       }
+       
+private:
+       bool m_disable_stderr;
+};
+
 Debugbuf debugbuf(false);
 std::ostream dstream(&debugbuf);
 Debugbuf debugbuf_no_stderr(true);
@@ -83,6 +142,18 @@ void assert_fail(const char *assertion, const char *file,
        DebugStack
 */
 
+struct DebugStack
+{
+       DebugStack(threadid_t id);
+       void print(FILE *file, bool everything);
+       void print(std::ostream &os, bool everything);
+       
+       threadid_t threadid;
+       char stack[DEBUG_STACK_SIZE][DEBUG_STACK_TEXT_SIZE];
+       int stack_i; // Points to the lowest empty position
+       int stack_max_i; // Highest i that was seen
+};
+
 DebugStack::DebugStack(threadid_t id)
 {
        threadid = id;
index 31855cce705a9bcaed118919a6310e27c86a8eec..1532be824a2918a048e5dc592078fb2dead14c5d 100644 (file)
@@ -20,18 +20,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef DEBUG_HEADER
 #define DEBUG_HEADER
 
-#include <stdio.h>
-#include <jmutex.h>
-#include <jmutexautolock.h>
 #include <iostream>
-#include "irrlichttypes.h"
-#include <irrMap.h>
-#include "threads.h"
+#include <exception>
 #include "gettime.h"
-#include "exceptions.h"
-#include <map>
 
-#ifdef _WIN32
+#if (defined(WIN32) || defined(_WIN32_WCE))
        #define WIN32_LEAN_AND_MEAN
        #ifndef _WIN32_WINNT
                #define _WIN32_WINNT 0x0501
@@ -40,7 +33,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        #ifdef _MSC_VER
                #include <eh.h>
        #endif
+       #define __NORETURN __declspec(noreturn)
+       #define __FUNCTION_NAME __FUNCTION__
 #else
+       #define __NORETURN __attribute__ ((__noreturn__))
+       #define __FUNCTION_NAME __PRETTY_FUNCTION__
 #endif
 
 // Whether to catch all std::exceptions.
@@ -58,65 +55,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #define DTIME (getTimestamp()+": ")
 
-#define DEBUGSTREAM_COUNT 2
-
-extern FILE *g_debugstreams[DEBUGSTREAM_COUNT];
-
 extern void debugstreams_init(bool disable_stderr, const char *filename);
 extern void debugstreams_deinit();
 
-#define DEBUGPRINT(...)\
-{\
-       for(int i=0; i<DEBUGSTREAM_COUNT; i++)\
-       {\
-               if(g_debugstreams[i] != NULL){\
-                       fprintf(g_debugstreams[i], __VA_ARGS__);\
-                       fflush(g_debugstreams[i]);\
-               }\
-       }\
-}
-
-class Debugbuf : public std::streambuf
-{
-public:
-       Debugbuf(bool disable_stderr)
-       {
-               m_disable_stderr = disable_stderr;
-       }
-
-       int overflow(int c)
-       {
-               for(int i=0; i<DEBUGSTREAM_COUNT; i++)
-               {
-                       if(g_debugstreams[i] == stderr && m_disable_stderr)
-                               continue;
-                       if(g_debugstreams[i] != NULL)
-                               (void)fwrite(&c, 1, 1, g_debugstreams[i]);
-                       //TODO: Is this slow?
-                       fflush(g_debugstreams[i]);
-               }
-               
-               return c;
-       }
-       std::streamsize xsputn(const char *s, std::streamsize n)
-       {
-               for(int i=0; i<DEBUGSTREAM_COUNT; i++)
-               {
-                       if(g_debugstreams[i] == stderr && m_disable_stderr)
-                               continue;
-                       if(g_debugstreams[i] != NULL)
-                               (void)fwrite(s, 1, n, g_debugstreams[i]);
-                       //TODO: Is this slow?
-                       fflush(g_debugstreams[i]);
-               }
-
-               return n;
-       }
-       
-private:
-       bool m_disable_stderr;
-};
-
 // This is used to redirect output to /dev/null
 class Nullstream : public std::ostream {
 public:
@@ -127,7 +68,6 @@ public:
 private:
 };
 
-extern Debugbuf debugbuf;
 extern std::ostream dstream;
 extern std::ostream dstream_no_stderr;
 extern Nullstream dummyout;
@@ -154,25 +94,11 @@ __NORETURN extern void assert_fail(
 #define DEBUG_STACK_SIZE 50
 #define DEBUG_STACK_TEXT_SIZE 300
 
-struct DebugStack
-{
-       DebugStack(threadid_t id);
-       void print(FILE *file, bool everything);
-       void print(std::ostream &os, bool everything);
-       
-       threadid_t threadid;
-       char stack[DEBUG_STACK_SIZE][DEBUG_STACK_TEXT_SIZE];
-       int stack_i; // Points to the lowest empty position
-       int stack_max_i; // Highest i that was seen
-};
-
-extern std::map<threadid_t, DebugStack*> g_debug_stacks;
-extern JMutex g_debug_stacks_mutex;
-
 extern void debug_stacks_init();
 extern void debug_stacks_print_to(std::ostream &os);
 extern void debug_stacks_print();
 
+struct DebugStack;
 class DebugStacker
 {
 public:
@@ -193,57 +119,6 @@ private:
                        DEBUG_STACK_TEXT_SIZE, __VA_ARGS__);\
        DebugStacker __debug_stacker(__buf);
 
-/*
-       Packet counter
-*/
-
-class PacketCounter
-{
-public:
-       PacketCounter()
-       {
-       }
-
-       void add(u16 command)
-       {
-               std::map<u16, u16>::iterator n = m_packets.find(command);
-               if(n == m_packets.end())
-               {
-                       m_packets[command] = 1;
-               }
-               else
-               {
-                       n->second++;
-               }
-       }
-
-       void clear()
-       {
-               for(std::map<u16, u16>::iterator
-                               i = m_packets.begin();
-                               i != m_packets.end(); ++i)
-               {
-                       i->second = 0;
-               }
-       }
-
-       void print(std::ostream &o)
-       {
-               for(std::map<u16, u16>::iterator
-                               i = m_packets.begin();
-                               i != m_packets.end(); ++i)
-               {
-                       o<<"cmd "<<i->first
-                                       <<" count "<<i->second
-                                       <<std::endl;
-               }
-       }
-
-private:
-       // command, count
-       std::map<u16, u16> m_packets;
-};
-
 /*
        These should be put into every thread
 */
@@ -259,14 +134,6 @@ private:
        #ifdef _WIN32 // Windows
                #ifdef _MSC_VER // MSVC
 void se_trans_func(unsigned int, EXCEPTION_POINTERS*);
-
-class FatalSystemException : public BaseException
-{
-public:
-       FatalSystemException(const char *s):
-               BaseException(s)
-       {}
-};
                        #define BEGIN_DEBUG_EXCEPTION_HANDLER \
                                BEGIN_PORTABLE_DEBUG_EXCEPTION_HANDLER\
                                _set_se_translator(se_trans_func);
index 38d278ef0388e4c025f301a14cb563740ec816fa..a0adf159a5d1bc74ae3f74e814b2f70594651a5e 100644 (file)
@@ -273,6 +273,7 @@ void set_default_settings(Settings *settings)
        settings->setDefault("enable_ipv6", "true");
        settings->setDefault("ipv6_server", "false");
 
+       settings->setDefault("main_menu_script","");
        settings->setDefault("main_menu_mod_mgr","1");
        settings->setDefault("old_style_mod_selection","true");
        settings->setDefault("main_menu_game_mgr","0");
index f97763718eacebb79d86f3653de7494c9b25a7a4..a81ff7d929be8416947f983d5ccfb79a3848158d 100644 (file)
@@ -19,12 +19,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 
+#include "emerge.h"
 #include "server.h"
 #include <iostream>
 #include <queue>
-#include "clientserver.h"
 #include "map.h"
-#include "jmutexautolock.h"
+#include "environment.h"
+#include "util/container.h"
+#include "util/thread.h"
 #include "main.h"
 #include "constants.h"
 #include "voxel.h"
@@ -32,12 +34,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapblock.h"
 #include "serverobject.h"
 #include "settings.h"
-#include "cpp_api/scriptapi.h"
+#include "scripting_game.h"
 #include "profiler.h"
 #include "log.h"
 #include "nodedef.h"
 #include "biome.h"
-#include "emerge.h"
 #include "mapgen_v6.h"
 #include "mapgen_v7.h"
 #include "mapgen_indev.h"
@@ -45,6 +46,46 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapgen_math.h"
 
 
+class EmergeThread : public SimpleThread
+{
+public:
+       Server *m_server;
+       ServerMap *map;
+       EmergeManager *emerge;
+       Mapgen *mapgen;
+       bool enable_mapgen_debug_info;
+       int id;
+       
+       Event qevent;
+       std::queue<v3s16> blockqueue;
+       
+       EmergeThread(Server *server, int ethreadid):
+               SimpleThread(),
+               m_server(server),
+               map(NULL),
+               emerge(NULL),
+               mapgen(NULL),
+               id(ethreadid)
+       {
+       }
+
+       void *Thread();
+
+       void trigger()
+       {
+               setRun(true);
+               if(IsRunning() == false)
+               {
+                       Start();
+               }
+       }
+
+       bool popBlockEmerge(v3s16 *pos, u8 *flags);
+       bool getBlockOrStartGen(v3s16 p, MapBlock **b,
+                       BlockMakeData *data, bool allow_generate);
+};
+
+
 /////////////////////////////// Emerge Manager ////////////////////////////////
 
 EmergeManager::EmergeManager(IGameDef *gamedef) {
@@ -183,6 +224,11 @@ Mapgen *EmergeManager::getCurrentMapgen() {
 }
 
 
+void EmergeManager::triggerAllThreads() {
+       for (unsigned int i = 0; i != emergethread.size(); i++)
+               emergethread[i]->trigger();
+}
+
 bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate) {
        std::map<v3s16, BlockEmergeData *>::const_iterator iter;
        BlockEmergeData *bedata;
@@ -466,7 +512,8 @@ void *EmergeThread::Thread() {
                                                ign(&m_server->m_ignore_map_edit_events_area,
                                                VoxelArea(minp, maxp));
                                        {  // takes about 90ms with -O1 on an e3-1230v2
-                                               SERVER_TO_SA(m_server)->environment_OnGenerated(
+                                               m_server->getScriptIface()->
+                                                               environment_OnGenerated(
                                                                minp, maxp, emerge->getBlockSeed(minp));
                                        }
 
index ee95c348f9e1a595c2fa69c88853e49dc116d85e..458a366fc803a87515ac850293445be70f1d905a 100644 (file)
@@ -21,8 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define EMERGE_HEADER
 
 #include <map>
-#include <queue>
-#include "util/thread.h"
+#include "irr_v3d.h"
+#include "util/container.h"
+#include "map.h" // for ManualMapVoxelManipulator
 
 #define MGPARAMS_SET_MGNAME      1
 #define MGPARAMS_SET_SEED        2
@@ -35,15 +36,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        { if (enable_mapgen_debug_info) \
        infostream << "EmergeThread: " x << std::endl; }
 
+class EmergeThread;
 class Mapgen;
 struct MapgenParams;
 struct MapgenFactory;
 class Biome;
 class BiomeDefManager;
-class EmergeThread;
-class ManualMapVoxelManipulator;
-
-#include "server.h"
+class Decoration;
+class Ore;
+class INodeDefManager;
+class Settings;
 
 struct BlockMakeData {
        ManualMapVoxelManipulator *vmanip;
@@ -68,7 +70,14 @@ struct BlockEmergeData {
        u8 flags;
 };
 
-class EmergeManager {
+class IBackgroundBlockEmerger
+{
+public:
+       virtual bool enqueueBlockEmerge(u16 peer_id, v3s16 p,
+                       bool allow_generate) = 0;
+};
+
+class EmergeManager : public IBackgroundBlockEmerger {
 public:
        INodeDefManager *ndef;
 
@@ -106,6 +115,7 @@ public:
        Mapgen *createMapgen(std::string mgname, int mgid,
                                                MapgenParams *mgparams);
        MapgenParams *createMapgenParams(std::string mgname);
+       void triggerAllThreads();
        bool enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate);
        
        void registerMapgen(std::string name, MapgenFactory *mgfactory);
@@ -119,43 +129,4 @@ public:
        u32 getBlockSeed(v3s16 p);
 };
 
-class EmergeThread : public SimpleThread
-{
-public:
-       Server *m_server;
-       ServerMap *map;
-       EmergeManager *emerge;
-       Mapgen *mapgen;
-       bool enable_mapgen_debug_info;
-       int id;
-       
-       Event qevent;
-       std::queue<v3s16> blockqueue;
-       
-       EmergeThread(Server *server, int ethreadid):
-               SimpleThread(),
-               m_server(server),
-               map(NULL),
-               emerge(NULL),
-               mapgen(NULL),
-               id(ethreadid)
-       {
-       }
-
-       void *Thread();
-
-       void trigger()
-       {
-               setRun(true);
-               if(IsRunning() == false)
-               {
-                       Start();
-               }
-       }
-
-       bool popBlockEmerge(v3s16 *pos, u8 *flags);
-       bool getBlockOrStartGen(v3s16 p, MapBlock **b, 
-                                                       BlockMakeData *data, bool allow_generate);
-};
-
 #endif
index eacc2a008cad11e31b1766f9e3c15e8a8513a206..86c98f2c2afdaf70aa66d30e70be017f5ad1ef65 100644 (file)
@@ -17,9 +17,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include <set>
-#include <list>
-#include <map>
 #include "environment.h"
 #include "filesys.h"
 #include "porting.h"
@@ -31,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "settings.h"
 #include "log.h"
 #include "profiler.h"
-#include "cpp_api/scriptapi.h"
+#include "scripting_game.h"
 #include "nodedef.h"
 #include "nodemetadata.h"
 #include "main.h" // For g_settings, g_profiler
@@ -43,6 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #endif
 #include "daynightratio.h"
 #include "map.h"
+#include "emerge.h"
 #include "util/serialize.h"
 
 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
@@ -190,17 +188,6 @@ std::list<Player*> Environment::getPlayers(bool ignore_disconnected)
        return newlist;
 }
 
-void Environment::printPlayers(std::ostream &o)
-{
-       o<<"Players in environment:"<<std::endl;
-       for(std::list<Player*>::iterator i = m_players.begin();
-                       i != m_players.end(); i++)
-       {
-               Player *player = *i;
-               o<<"Player peer_id="<<player->peer_id<<std::endl;
-       }
-}
-
 u32 Environment::getDayNightRatio()
 {
        bool smooth = g_settings->getBool("enable_shaders");
@@ -320,7 +307,8 @@ void ActiveBlockList::update(std::list<v3s16> &active_positions,
        ServerEnvironment
 */
 
-ServerEnvironment::ServerEnvironment(ServerMap *map, ScriptApi *scriptIface,
+ServerEnvironment::ServerEnvironment(ServerMap *map,
+               GameScripting *scriptIface,
                IGameDef *gamedef, IBackgroundBlockEmerger *emerger):
        m_map(map),
        m_script(scriptIface),
@@ -1149,7 +1137,8 @@ void ServerEnvironment::step(float dtime)
                        MapBlock *block = m_map->getBlockNoCreateNoEx(p);
                        if(block==NULL){
                                // Block needs to be fetched first
-                               m_emerger->queueBlockEmerge(p, false);
+                               m_emerger->enqueueBlockEmerge(
+                                               PEER_ID_INEXISTENT, p, false);
                                m_active_blocks.m_list.erase(p);
                                continue;
                        }
@@ -1505,7 +1494,9 @@ ActiveObjectMessage ServerEnvironment::getActiveObjectMessage()
        if(m_active_object_messages.empty())
                return ActiveObjectMessage(0);
        
-       return m_active_object_messages.pop_front();
+       ActiveObjectMessage message = m_active_object_messages.front();
+       m_active_object_messages.pop_front();
+       return message;
 }
 
 /*
@@ -2574,13 +2565,14 @@ void ClientEnvironment::getActiveObjects(v3f origin, f32 max_d,
 
 ClientEnvEvent ClientEnvironment::getClientEvent()
 {
+       ClientEnvEvent event;
        if(m_client_event_queue.empty())
-       {
-               ClientEnvEvent event;
                event.type = CEE_NONE;
-               return event;
+       else {
+               event = m_client_event_queue.front();
+               m_client_event_queue.pop_front();
        }
-       return m_client_event_queue.pop_front();
+       return event;
 }
 
 #endif // #ifndef SERVER
index b59ce83c16dd31d17177b9e97eae79cb72af48f4..597ad5ff0187698bdc6c4338f0e3c7e07cea714f 100644 (file)
@@ -32,11 +32,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include <set>
 #include <list>
-#include "irrlichttypes_extrabloated.h"
-#include "player.h"
-#include <ostream>
+#include <map>
+#include "irr_v3d.h"
 #include "activeobject.h"
-#include "util/container.h"
 #include "util/numeric.h"
 #include "mapnode.h"
 #include "mapblock.h"
@@ -44,13 +42,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 class ServerEnvironment;
 class ActiveBlockModifier;
 class ServerActiveObject;
-typedef struct lua_State lua_State;
 class ITextureSource;
 class IGameDef;
+class IBackgroundBlockEmerger;
 class Map;
 class ServerMap;
 class ClientMap;
-class ScriptApi;
+class GameScripting;
+class Player;
 
 class Environment
 {
@@ -77,7 +76,6 @@ public:
        Player * getNearestConnectedPlayer(v3f pos);
        std::list<Player*> getPlayers();
        std::list<Player*> getPlayers(bool ignore_disconnected);
-       void printPlayers(std::ostream &o);
        
        u32 getDayNightRatio();
        
@@ -176,12 +174,6 @@ public:
 private:
 };
 
-class IBackgroundBlockEmerger
-{
-public:
-       virtual void queueBlockEmerge(v3s16 blockpos, bool allow_generate)=0;
-};
-
 /*
        The server-side environment.
 
@@ -191,7 +183,8 @@ public:
 class ServerEnvironment : public Environment
 {
 public:
-       ServerEnvironment(ServerMap *map, ScriptApi *iface, IGameDef *gamedef,
+       ServerEnvironment(ServerMap *map, GameScripting *scriptIface,
+                       IGameDef *gamedef,
                        IBackgroundBlockEmerger *emerger);
        ~ServerEnvironment();
 
@@ -200,7 +193,7 @@ public:
        ServerMap & getServerMap();
 
        //TODO find way to remove this fct!
-       ScriptApi* getScriptIface()
+       GameScripting* getScriptIface()
                { return m_script; }
 
        IGameDef *getGameDef()
@@ -354,15 +347,15 @@ private:
        // The map
        ServerMap *m_map;
        // Lua state
-       ScriptApi* m_script;
+       GameScripting* m_script;
        // Game definition
        IGameDef *m_gamedef;
-       // Background block emerger (the server, in practice)
+       // Background block emerger (the EmergeManager, in practice)
        IBackgroundBlockEmerger *m_emerger;
        // Active object list
        std::map<u16, ServerActiveObject*> m_active_objects;
        // Outgoing network message buffer for active objects
-       Queue<ActiveObjectMessage> m_active_object_messages;
+       std::list<ActiveObjectMessage> m_active_object_messages;
        // Some timers
        float m_random_spawn_timer; // used for experimental code
        float m_send_recommended_timer;
@@ -503,7 +496,7 @@ private:
        IrrlichtDevice *m_irr;
        std::map<u16, ClientActiveObject*> m_active_objects;
        std::list<ClientSimpleObject*> m_simple_objects;
-       Queue<ClientEnvEvent> m_client_event_queue;
+       std::list<ClientEnvEvent> m_client_event_queue;
        IntervalLimiter m_active_object_light_update_interval;
        IntervalLimiter m_lava_hurt_interval;
        IntervalLimiter m_drowning_interval;
index 458fb50b1b7090db65e11f88da49984d450c0339..085b424177af20c1bc861afe5ea1d5f619caacc6 100644 (file)
@@ -140,6 +140,15 @@ public:
        {}
 };
 
+// Only used on Windows (SEH)
+class FatalSystemException : public BaseException
+{
+public:
+       FatalSystemException(const char *s):
+               BaseException(s)
+       {}
+};
+
 /*
        Some "old-style" interrupts:
 */
index 23df1d7d081e5d137e631dd4e8fbeca99182750f..c4de6cf8220bfc8f6db0e0323e44a0bba1bb3f30 100644 (file)
@@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <iostream>
 #include <fstream>
 #include <sstream>
+#include <stdlib.h>
 
 bool FileCache::loadByPath(const std::string &path, std::ostream &os)
 {
index a1795c8eadf9873ae77a41b9e3a7df5e88683c42..eda36c83307a39e93392e52048933b5185091f13 100644 (file)
@@ -18,12 +18,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "filesys.h"
-#include "strfnd.h"
+#include "util/string.h"
 #include <iostream>
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
-#include <sstream>
 #include <fstream>
 #include "log.h"
 
index 7954c8d8003ab6c7e12f9a51bfbb0aaf32e0980b..650b5e2f8fc7671842356ecbbd7a1f8c3834f6d1 100644 (file)
@@ -915,7 +915,6 @@ void the_game(
        std::string address, // If "", local server is used
        u16 port,
        std::wstring &error_message,
-       std::string configpath,
        ChatBackend &chat_backend,
        const SubgameSpec &gamespec, // Used for local game,
        bool simple_singleplayer_mode
@@ -1001,7 +1000,7 @@ void the_game(
                draw_load_screen(text, device, font,0,25);
                delete[] text;
                infostream<<"Creating server"<<std::endl;
-               server = new Server(map_dir, configpath, gamespec,
+               server = new Server(map_dir, gamespec,
                                simple_singleplayer_mode);
                server->start(port);
        }
@@ -3340,7 +3339,7 @@ void the_game(
                */
                {
                        TimeTaker timer("endScene");
-                       endSceneX(driver);
+                       driver->endScene();
                        endscenetime = timer.stop(true);
                }
 
index a2c1fc09cc48eb7cb7d9790ab6cf6c3216ff8911..1c831c530067527c3bda16135109ec2728eae465 100644 (file)
@@ -137,7 +137,6 @@ void the_game(
        std::string address, // If "", local server is used
        u16 port,
        std::wstring &error_message,
-       std::string configpath,
        ChatBackend &chat_backend,
        const SubgameSpec &gamespec, // Used for local game
        bool simple_singleplayer_mode
index b62c1a5471456e474c608aa8615f578b2a385578..37f570acf1d469d1d59c2525564a40f3a705ed78 100644 (file)
@@ -17,14 +17,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-extern "C" {
-#include "lua.h"
-#include "lauxlib.h"
-#include "lualib.h"
-}
-
-#include "irrlicht.h"
+#include "guiEngine.h"
 
+#include "scripting_mainmenu.h"
+#include "config.h"
 #include "porting.h"
 #include "filesys.h"
 #include "main.h"
@@ -33,30 +29,13 @@ extern "C" {
 #include "sound.h"
 #include "sound_openal.h"
 
-#include "guiEngine.h"
+#include <IGUIStaticText.h>
+#include <ICameraSceneNode.h>
 
 #if USE_CURL
 #include <curl/curl.h>
 #endif
 
-/******************************************************************************/
-int menuscript_ErrorHandler(lua_State *L) {
-       lua_getfield(L, LUA_GLOBALSINDEX, "debug");
-       if (!lua_istable(L, -1)) {
-       lua_pop(L, 1);
-       return 1;
-       }
-       lua_getfield(L, -1, "traceback");
-       if (!lua_isfunction(L, -1)) {
-       lua_pop(L, 2);
-       return 1;
-       }
-       lua_pushvalue(L, 1);
-       lua_pushinteger(L, 2);
-       lua_call(L, 2, 1);
-       return 1;
-}
-
 /******************************************************************************/
 TextDestGuiEngine::TextDestGuiEngine(GUIEngine* engine)
 {
@@ -66,13 +45,33 @@ TextDestGuiEngine::TextDestGuiEngine(GUIEngine* engine)
 /******************************************************************************/
 void TextDestGuiEngine::gotText(std::map<std::string, std::string> fields)
 {
-       m_engine->handleButtons(fields);
+       m_engine->getScriptIface()->handleMainMenuButtons(fields);
 }
 
 /******************************************************************************/
 void TextDestGuiEngine::gotText(std::wstring text)
 {
-       m_engine->handleEvent(wide_to_narrow(text));
+       m_engine->getScriptIface()->handleMainMenuEvent(wide_to_narrow(text));
+}
+
+/******************************************************************************/
+void MenuMusicFetcher::fetchSounds(const std::string &name,
+                       std::set<std::string> &dst_paths,
+                       std::set<std::string> &dst_datas)
+{
+       if(m_fetched.count(name))
+               return;
+       m_fetched.insert(name);
+       std::string base;
+       base = porting::path_share + DIR_DELIM + "sounds";
+       dst_paths.insert(base + DIR_DELIM + name + ".ogg");
+       int i;
+       for(i=0; i<10; i++)
+               dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
+       base = porting::path_user + DIR_DELIM + "sounds";
+       dst_paths.insert(base + DIR_DELIM + name + ".ogg");
+       for(i=0; i<10; i++)
+               dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
 }
 
 /******************************************************************************/
@@ -91,8 +90,7 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
        m_buttonhandler(0),
        m_menu(0),
        m_startgame(false),
-       m_engineluastack(0),
-       m_luaerrorhandler(-1),
+       m_script(0),
        m_scriptdir(""),
        m_irr_toplefttext(0),
        m_clouds_enabled(true),
@@ -105,26 +103,6 @@ GUIEngine::GUIEngine(      irr::IrrlichtDevice* dev,
        // is deleted by guiformspec!
        m_buttonhandler = new TextDestGuiEngine(this);
 
-       //create luastack
-       m_engineluastack = luaL_newstate();
-
-       //load basic lua modules
-       luaL_openlibs(m_engineluastack);
-
-       //init
-       guiLuaApi::initialize(m_engineluastack,this);
-
-       //push errorstring
-       if (m_data->errormessage != "")
-       {
-               lua_getglobal(m_engineluastack, "gamedata");
-               int gamedata_idx = lua_gettop(m_engineluastack);
-               lua_pushstring(m_engineluastack, "errormessage");
-               lua_pushstring(m_engineluastack,m_data->errormessage.c_str());
-               lua_settable(m_engineluastack, gamedata_idx);
-               m_data->errormessage = "";
-       }
-
        //create soundmanager
        MenuMusicFetcher soundfetcher;
 #if USE_SOUND
@@ -160,68 +138,76 @@ GUIEngine::GUIEngine(     irr::IrrlichtDevice* dev,
        m_menu->setTextDest(m_buttonhandler);
        m_menu->useGettext(true);
 
-       std::string builtin_helpers
-               = porting::path_share + DIR_DELIM + "builtin"
-                       + DIR_DELIM + "misc_helpers.lua";
+       // Initialize scripting
 
-       if (!runScript(builtin_helpers)) {
-               errorstream
-                       << "GUIEngine::GUIEngine unable to load builtin helper script"
-                       << std::endl;
-               return;
-       }
+       infostream<<"GUIEngine: Initializing Lua"<<std::endl;
 
-       std::string menuscript = "";
-       if (g_settings->exists("main_menu_script"))
-               menuscript = g_settings->get("main_menu_script");
-       std::string builtin_menuscript =
-                       porting::path_share + DIR_DELIM + "builtin"
-                               + DIR_DELIM + "mainmenu.lua";
+       m_script = new MainMenuScripting(this);
 
-       lua_pushcfunction(m_engineluastack, menuscript_ErrorHandler);
-       m_luaerrorhandler = lua_gettop(m_engineluastack);
+       try {
+               if (m_data->errormessage != "")
+               {
+                       m_script->setMainMenuErrorMessage(m_data->errormessage);
+                       m_data->errormessage = "";
+               }
 
-       m_scriptdir = menuscript.substr(0,menuscript.find_last_of(DIR_DELIM)-1);
-       if((menuscript == "") || (!runScript(menuscript))) {
-               infostream
-                       << "GUIEngine::GUIEngine execution of custom menu failed!"
-                       << std::endl
-                       << "\tfalling back to builtin menu"
-                       << std::endl;
-               m_scriptdir = fs::RemoveRelativePathComponents(porting::path_share + DIR_DELIM + "builtin"+ DIR_DELIM);
-               if(!runScript(builtin_menuscript)) {
-                       errorstream
-                               << "GUIEngine::GUIEngine unable to load builtin menu"
-                               << std::endl;
+               if (!loadMainMenuScript())
                        assert("no future without mainmenu" == 0);
-               }
-       }
 
-       run();
+               run();
+       }
+       catch(LuaError &e) {
+               errorstream << "MAINMENU ERROR: " << e.what() << std::endl;
+               m_data->errormessage = e.what();
+       }
 
-       m_menumanager->deletingMenu(m_menu);
+       m_menu->quitMenu();
        m_menu->drop();
        m_menu = 0;
 }
 
 /******************************************************************************/
-bool GUIEngine::runScript(std::string script) {
-
-       int ret =       luaL_loadfile(m_engineluastack, script.c_str()) ||
-                               lua_pcall(m_engineluastack, 0, 0, m_luaerrorhandler);
-       if(ret){
-               errorstream<<"========== ERROR FROM LUA WHILE CREATING MAIN MENU ==========="<<std::endl;
-               errorstream<<"Failed to load and run script from "<<std::endl;
-               errorstream<<script<<":"<<std::endl;
-               errorstream<<std::endl;
-               errorstream<<lua_tostring(m_engineluastack, -1)<<std::endl;
-               errorstream<<std::endl;
-               errorstream<<"=================== END OF ERROR FROM LUA ===================="<<std::endl;
-               lua_pop(m_engineluastack, 1); // Pop error message from stack
-               lua_pop(m_engineluastack, 1); // Pop the error handler from stack
-               return false;
+bool GUIEngine::loadMainMenuScript()
+{
+       // Try custom menu script (main_menu_script)
+
+       std::string menuscript = g_settings->get("main_menu_script");
+       if(menuscript != "") {
+               m_scriptdir = fs::RemoveLastPathComponent(menuscript);
+
+               if(m_script->loadMod(menuscript, "__custommenu")) {
+                       // custom menu script loaded
+                       return true;
+               }
+               else {
+                       infostream
+                               << "GUIEngine: execution of custom menu failed!"
+                               << std::endl
+                               << "\tfalling back to builtin menu"
+                               << std::endl;
+               }
        }
-       return true;
+
+       // Try builtin menu script (main_menu_script)
+
+       std::string builtin_menuscript =
+                       porting::path_share + DIR_DELIM + "builtin"
+                               + DIR_DELIM + "mainmenu.lua";
+
+       m_scriptdir = fs::RemoveRelativePathComponents(
+                       fs::RemoveLastPathComponent(builtin_menuscript));
+
+       if(m_script->loadMod(builtin_menuscript, "__builtinmenu")) {
+               // builtin menu script loaded
+               return true;
+       }
+       else {
+               errorstream
+                       << "GUIEngine: unable to load builtin menu"
+                       << std::endl;
+       }
+
+       return false;
 }
 
 /******************************************************************************/
@@ -257,52 +243,6 @@ void GUIEngine::run()
                else
                        sleep_ms(25);
        }
-
-       m_menu->quitMenu();
-}
-
-/******************************************************************************/
-void GUIEngine::handleEvent(std::string text)
-{
-       lua_getglobal(m_engineluastack, "engine");
-
-       lua_getfield(m_engineluastack, -1, "event_handler");
-
-       if(lua_isnil(m_engineluastack, -1))
-               return;
-
-       luaL_checktype(m_engineluastack, -1, LUA_TFUNCTION);
-
-       lua_pushstring(m_engineluastack, text.c_str());
-
-       if(lua_pcall(m_engineluastack, 1, 0, m_luaerrorhandler))
-               scriptError("error: %s", lua_tostring(m_engineluastack, -1));
-}
-
-/******************************************************************************/
-void GUIEngine::handleButtons(std::map<std::string, std::string> fields)
-{
-       lua_getglobal(m_engineluastack, "engine");
-
-       lua_getfield(m_engineluastack, -1, "button_handler");
-
-       if(lua_isnil(m_engineluastack, -1))
-               return;
-
-       luaL_checktype(m_engineluastack, -1, LUA_TFUNCTION);
-
-       lua_newtable(m_engineluastack);
-       for(std::map<std::string, std::string>::const_iterator
-               i = fields.begin(); i != fields.end(); i++){
-               const std::string &name = i->first;
-               const std::string &value = i->second;
-               lua_pushstring(m_engineluastack, name.c_str());
-               lua_pushlstring(m_engineluastack, value.c_str(), value.size());
-               lua_settable(m_engineluastack, -3);
-       }
-
-       if(lua_pcall(m_engineluastack, 1, 0, m_luaerrorhandler))
-               scriptError("error: %s", lua_tostring(m_engineluastack, -1));
 }
 
 /******************************************************************************/
@@ -318,7 +258,8 @@ GUIEngine::~GUIEngine()
 
        //TODO: clean up m_menu here
 
-       lua_close(m_engineluastack);
+       infostream<<"GUIEngine: Deinitializing scripting"<<std::endl;
+       delete m_script;
 
        m_irr_toplefttext->setText(L"");
 
@@ -565,17 +506,6 @@ bool GUIEngine::downloadFile(std::string url,std::string target) {
        return false;
 }
 
-/******************************************************************************/
-void GUIEngine::scriptError(const char *fmt, ...)
-{
-       va_list argp;
-       va_start(argp, fmt);
-       char buf[10000];
-       vsnprintf(buf, 10000, fmt, argp);
-       va_end(argp);
-       errorstream<<"MAINMENU ERROR: "<<buf;
-}
-
 /******************************************************************************/
 void GUIEngine::setTopleftText(std::string append) {
        std::string toset = "Minetest " VERSION_STRING;
index 2f96b0b1c4669f51ed2e4f6cd5a363909ced1095..3987b52c73dc50df9e6446e86b6f54f3153ccdb6 100644 (file)
@@ -26,7 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "irrlichttypes.h"
 #include "modalMenu.h"
 #include "clouds.h"
-#include "guiLuaApi.h"
 #include "guiFormSpecMenu.h"
 #include "sound.h"
 
@@ -50,6 +49,7 @@ typedef enum {
 /* forward declarations                                                       */
 /******************************************************************************/
 class GUIEngine;
+class MainMenuScripting;
 struct MainMenuData;
 struct SimpleSoundSpec;
 
@@ -86,35 +86,17 @@ class MenuMusicFetcher: public OnDemandSoundFetcher
 {
        std::set<std::string> m_fetched;
 public:
-
        void fetchSounds(const std::string &name,
                        std::set<std::string> &dst_paths,
-                       std::set<std::string> &dst_datas)
-       {
-               if(m_fetched.count(name))
-                       return;
-               m_fetched.insert(name);
-               std::string base;
-               base = porting::path_share + DIR_DELIM + "sounds";
-               dst_paths.insert(base + DIR_DELIM + name + ".ogg");
-               int i;
-               for(i=0; i<10; i++)
-                       dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
-               base = porting::path_user + DIR_DELIM + "sounds";
-               dst_paths.insert(base + DIR_DELIM + name + ".ogg");
-               for(i=0; i<10; i++)
-                       dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
-               }
+                       std::set<std::string> &dst_datas);
 };
 
 /** implementation of main menu based uppon formspecs */
 class GUIEngine {
-public:
-       /** TextDestGuiEngine needs to transfer data to engine */
-       friend class TextDestGuiEngine;
-       /** guiLuaApi is used to initialize contained stack */
-       friend class guiLuaApi;
+       /** grant ModApiMainMenu access to private members */
+       friend class ModApiMainMenu;
 
+public:
        /**
         * default constructor
         * @param dev device to draw at
@@ -132,20 +114,12 @@ public:
        /** default destructor */
        virtual ~GUIEngine();
 
-       s32 playSound(SimpleSoundSpec spec, bool looped);
-       void stopSound(s32 handle);
-
-protected:
        /**
-        * process field data recieved from formspec
-        * @param fields data in field format
+        * return MainMenuScripting interface
         */
-       void handleButtons(std::map<std::string, std::string> fields);
-       /**
-        * process events received from formspec
-        * @param text events in textual form
-        */
-       void handleEvent(std::string text);
+       MainMenuScripting* getScriptIface() {
+               return m_script;
+       }
 
        /**
         * return dir of current menuscript
@@ -156,7 +130,10 @@ protected:
 
 private:
 
-       /* run main menu loop */
+       /** find and run the main menu script */
+       bool loadMainMenuScript();
+
+       /** run main menu loop */
        void run();
 
        /** handler to limit frame rate within main menu */
@@ -185,27 +162,8 @@ private:
        /** variable used to abort menu and return back to main game handling */
        bool                                    m_startgame;
 
-       /**
-        * initialize lua stack
-        * @param L stack to initialize
-        */
-       void initalize_api(lua_State * L);
-
-       /**
-        * run a lua script
-        * @param script full path to script to run
-        */
-       bool runScript(std::string script);
-
-       /**
-        * script error handler to process errors within lua
-        */
-       void scriptError(const char *fmt, ...);
-
-       /** lua stack */
-       lua_State*                              m_engineluastack;
-       /** lua internal stack number of error handler*/
-       int                                             m_luaerrorhandler;
+       /** scripting interface */
+       MainMenuScripting*                      m_script;
 
        /** script basefolder */
        std::string                             m_scriptdir;
@@ -284,6 +242,12 @@ private:
        /** data used to draw clouds */
        clouddata                               m_cloud;
 
+       /** start playing a sound and return handle */
+       s32 playSound(SimpleSoundSpec spec, bool looped);
+       /** stop playing a sound started with playSound() */
+       void stopSound(s32 handle);
+
+
 };
 
 
index 0f09eaf5205844c7c5dc425c3f0ef87fb0f1d1c3..f09996ef3544cb35249eb89cb1be4c256996f951 100644 (file)
@@ -39,6 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <IGUIComboBox.h>
 #include "log.h"
 #include "tile.h" // ITextureSource
+#include "hud.h" // drawItemStack
 #include "util/string.h"
 #include "util/numeric.h"
 #include "filesys.h"
@@ -61,92 +62,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        }
 
 
-void drawItemStack(video::IVideoDriver *driver,
-               gui::IGUIFont *font,
-               const ItemStack &item,
-               const core::rect<s32> &rect,
-               const core::rect<s32> *clip,
-               IGameDef *gamedef)
-{
-       if(item.empty())
-               return;
-       
-       const ItemDefinition &def = item.getDefinition(gamedef->idef());
-       video::ITexture *texture = gamedef->idef()->getInventoryTexture(def.name, gamedef);
-
-       // Draw the inventory texture
-       if(texture != NULL)
-       {
-               const video::SColor color(255,255,255,255);
-               const video::SColor colors[] = {color,color,color,color};
-               driver->draw2DImage(texture, rect,
-                       core::rect<s32>(core::position2d<s32>(0,0),
-                       core::dimension2di(texture->getOriginalSize())),
-                       clip, colors, true);
-       }
-
-       if(def.type == ITEM_TOOL && item.wear != 0)
-       {
-               // Draw a progressbar
-               float barheight = rect.getHeight()/16;
-               float barpad_x = rect.getWidth()/16;
-               float barpad_y = rect.getHeight()/16;
-               core::rect<s32> progressrect(
-                       rect.UpperLeftCorner.X + barpad_x,
-                       rect.LowerRightCorner.Y - barpad_y - barheight,
-                       rect.LowerRightCorner.X - barpad_x,
-                       rect.LowerRightCorner.Y - barpad_y);
-
-               // Shrink progressrect by amount of tool damage
-               float wear = item.wear / 65535.0;
-               int progressmid =
-                       wear * progressrect.UpperLeftCorner.X +
-                       (1-wear) * progressrect.LowerRightCorner.X;
-
-               // Compute progressbar color
-               //   wear = 0.0: green
-               //   wear = 0.5: yellow
-               //   wear = 1.0: red
-               video::SColor color(255,255,255,255);
-               int wear_i = MYMIN(floor(wear * 600), 511);
-               wear_i = MYMIN(wear_i + 10, 511);
-               if(wear_i <= 255)
-                       color.set(255, wear_i, 255, 0);
-               else
-                       color.set(255, 255, 511-wear_i, 0);
-
-               core::rect<s32> progressrect2 = progressrect;
-               progressrect2.LowerRightCorner.X = progressmid;
-               driver->draw2DRectangle(color, progressrect2, clip);
-
-               color = video::SColor(255,0,0,0);
-               progressrect2 = progressrect;
-               progressrect2.UpperLeftCorner.X = progressmid;
-               driver->draw2DRectangle(color, progressrect2, clip);
-       }
-
-       if(font != NULL && item.count >= 2)
-       {
-               // Get the item count as a string
-               std::string text = itos(item.count);
-               v2u32 dim = font->getDimension(narrow_to_wide(text).c_str());
-               v2s32 sdim(dim.X,dim.Y);
-
-               core::rect<s32> rect2(
-                       /*rect.UpperLeftCorner,
-                       core::dimension2d<u32>(rect.getWidth(), 15)*/
-                       rect.LowerRightCorner - sdim,
-                       sdim
-               );
-
-               video::SColor bgcolor(128,0,0,0);
-               driver->draw2DRectangle(bgcolor, rect2, clip);
-
-               video::SColor color(255,255,255,255);
-               font->draw(text.c_str(), rect2, color, false, false, clip);
-       }
-}
-
 /*
        GUIFormSpecMenu
 */
index 116f7b95d54ac4cd3bf3d63523bae65d468bf4c8..84124afc3fa60272a1752855a3594725e3584539 100644 (file)
@@ -57,13 +57,6 @@ public:
        virtual std::string resolveText(std::string str){ return str; }
 };
 
-void drawItemStack(video::IVideoDriver *driver,
-               gui::IGUIFont *font,
-               const ItemStack &item,
-               const core::rect<s32> &rect,
-               const core::rect<s32> *clip,
-               IGameDef *gamedef);
-
 class GUIFormSpecMenu : public GUIModalMenu
 {
        struct ItemSpec
diff --git a/src/guiLuaApi.cpp b/src/guiLuaApi.cpp
deleted file mode 100644 (file)
index 5d3e9dc..0000000
+++ /dev/null
@@ -1,1128 +0,0 @@
-/*
-Minetest
-Copyright (C) 2013 sapier
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-extern "C" {
-#include "lua.h"
-#include "lauxlib.h"
-#include "lualib.h"
-}
-#include "porting.h"
-#include "guiMainMenu.h"
-#include "subgame.h"
-#include "guiKeyChangeMenu.h"
-#include "guiFileSelectMenu.h"
-#include "main.h"
-#include "settings.h"
-#include "filesys.h"
-#include "convert_json.h"
-#include "sound.h"
-
-
-#include "IFileArchive.h"
-#include "IFileSystem.h"
-
-#include "guiLuaApi.h"
-#include "guiEngine.h"
-
-#define API_FCT(name) registerFunction(L,#name,l_##name,top)
-
-void guiLuaApi::initialize(lua_State* L,GUIEngine* engine)
-{
-       lua_pushlightuserdata(L, engine);
-       lua_setfield(L, LUA_REGISTRYINDEX, "engine");
-
-       lua_pushstring(L, DIR_DELIM);
-       lua_setglobal(L, "DIR_DELIM");
-
-       lua_newtable(L);
-       lua_setglobal(L, "gamedata");
-
-       lua_newtable(L);
-       lua_setglobal(L, "engine");
-
-       lua_getglobal(L, "engine");
-       int top = lua_gettop(L);
-
-       bool retval = true;
-
-       //add api functions
-       retval &= API_FCT(update_formspec);
-       retval &= API_FCT(set_clouds);
-       retval &= API_FCT(get_textlist_index);
-       retval &= API_FCT(get_worlds);
-       retval &= API_FCT(get_games);
-       retval &= API_FCT(start);
-       retval &= API_FCT(close);
-       retval &= API_FCT(get_favorites);
-       retval &= API_FCT(show_keys_menu);
-       retval &= API_FCT(setting_set);
-       retval &= API_FCT(setting_get);
-       retval &= API_FCT(setting_getbool);
-       retval &= API_FCT(setting_setbool);
-       retval &= API_FCT(create_world);
-       retval &= API_FCT(delete_world);
-       retval &= API_FCT(delete_favorite);
-       retval &= API_FCT(set_background);
-       retval &= API_FCT(set_topleft_text);
-       retval &= API_FCT(get_modpath);
-       retval &= API_FCT(get_gamepath);
-       retval &= API_FCT(get_texturepath);
-       retval &= API_FCT(get_dirlist);
-       retval &= API_FCT(create_dir);
-       retval &= API_FCT(delete_dir);
-       retval &= API_FCT(copy_dir);
-       retval &= API_FCT(extract_zip);
-       retval &= API_FCT(get_scriptdir);
-       retval &= API_FCT(show_file_open_dialog);
-       retval &= API_FCT(get_version);
-       retval &= API_FCT(download_file);
-       retval &= API_FCT(get_modstore_details);
-       retval &= API_FCT(get_modstore_list);
-       retval &= API_FCT(sound_play);
-       retval &= API_FCT(sound_stop);
-
-       if (!retval) {
-               //TODO show error
-       }
-}
-
-/******************************************************************************/
-bool guiLuaApi::registerFunction(      lua_State* L,
-                                                                       const char* name,
-                                                                       lua_CFunction fct,
-                                                                       int top
-                                                                       )
-{
-       lua_pushstring(L,name);
-       lua_pushcfunction(L,fct);
-       lua_settable(L, top);
-
-       return true;
-}
-
-/******************************************************************************/
-GUIEngine* guiLuaApi::get_engine(lua_State *L)
-{
-       // Get server from registry
-       lua_getfield(L, LUA_REGISTRYINDEX, "engine");
-       GUIEngine* sapi_ptr = (GUIEngine*) lua_touserdata(L, -1);
-       lua_pop(L, 1);
-       return sapi_ptr;
-}
-
-/******************************************************************************/
-std::string guiLuaApi::getTextData(lua_State *L, std::string name)
-{
-       lua_getglobal(L, "gamedata");
-
-       lua_getfield(L, -1, name.c_str());
-
-       if(lua_isnil(L, -1))
-               return "";
-
-       return luaL_checkstring(L, -1);
-}
-
-/******************************************************************************/
-int guiLuaApi::getIntegerData(lua_State *L, std::string name,bool& valid)
-{
-       lua_getglobal(L, "gamedata");
-
-       lua_getfield(L, -1, name.c_str());
-
-       if(lua_isnil(L, -1)) {
-               valid = false;
-               return -1;
-               }
-
-       valid = true;
-       return luaL_checkinteger(L, -1);
-}
-
-/******************************************************************************/
-int guiLuaApi::getBoolData(lua_State *L, std::string name,bool& valid)
-{
-       lua_getglobal(L, "gamedata");
-
-       lua_getfield(L, -1, name.c_str());
-
-       if(lua_isnil(L, -1)) {
-               valid = false;
-               return false;
-               }
-
-       valid = true;
-       return lua_toboolean(L, -1);
-}
-
-/******************************************************************************/
-int guiLuaApi::l_update_formspec(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       if (engine->m_startgame)
-               return 0;
-
-       //read formspec
-       std::string formspec(luaL_checkstring(L, 1));
-
-       if (engine->m_formspecgui != 0) {
-               engine->m_formspecgui->setForm(formspec);
-       }
-
-       return 0;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_start(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       //update c++ gamedata from lua table
-
-       bool valid = false;
-
-
-       engine->m_data->selected_world          = getIntegerData(L, "selected_world",valid) -1;
-       engine->m_data->simple_singleplayer_mode = getBoolData(L,"singleplayer",valid);
-       engine->m_data->name                            = getTextData(L,"playername");
-       engine->m_data->password                        = getTextData(L,"password");
-       engine->m_data->address                         = getTextData(L,"address");
-       engine->m_data->port                            = getTextData(L,"port");
-       engine->m_data->serverdescription       = getTextData(L,"serverdescription");
-       engine->m_data->servername                      = getTextData(L,"servername");
-
-       //close menu next time
-       engine->m_startgame = true;
-       return 0;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_close(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       engine->m_data->kill = true;
-
-       //close menu next time
-       engine->m_startgame = true;
-       engine->m_menu->quitMenu();
-       return 0;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_set_background(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       std::string backgroundlevel(luaL_checkstring(L, 1));
-       std::string texturename(luaL_checkstring(L, 2));
-
-       bool retval = false;
-
-       if (backgroundlevel == "background") {
-               retval |= engine->setTexture(TEX_LAYER_BACKGROUND,texturename);
-       }
-
-       if (backgroundlevel == "overlay") {
-               retval |= engine->setTexture(TEX_LAYER_OVERLAY,texturename);
-       }
-
-       if (backgroundlevel == "header") {
-               retval |= engine->setTexture(TEX_LAYER_HEADER,texturename);
-       }
-
-       if (backgroundlevel == "footer") {
-               retval |= engine->setTexture(TEX_LAYER_FOOTER,texturename);
-       }
-
-       lua_pushboolean(L,retval);
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_set_clouds(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       bool value = lua_toboolean(L,1);
-
-       engine->m_clouds_enabled = value;
-
-       return 0;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_get_textlist_index(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       std::string listboxname(luaL_checkstring(L, 1));
-
-       int selection = engine->m_menu->getListboxIndex(listboxname);
-
-       if (selection >= 0)
-               selection++;
-
-       lua_pushinteger(L, selection);
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_get_worlds(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       std::vector<WorldSpec> worlds = getAvailableWorlds();
-
-       lua_newtable(L);
-       int top = lua_gettop(L);
-       unsigned int index = 1;
-
-       for (unsigned int i = 0; i < worlds.size(); i++)
-       {
-               lua_pushnumber(L,index);
-
-               lua_newtable(L);
-               int top_lvl2 = lua_gettop(L);
-
-               lua_pushstring(L,"path");
-               lua_pushstring(L,worlds[i].path.c_str());
-               lua_settable(L, top_lvl2);
-
-               lua_pushstring(L,"name");
-               lua_pushstring(L,worlds[i].name.c_str());
-               lua_settable(L, top_lvl2);
-
-               lua_pushstring(L,"gameid");
-               lua_pushstring(L,worlds[i].gameid.c_str());
-               lua_settable(L, top_lvl2);
-
-               lua_settable(L, top);
-               index++;
-       }
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_get_games(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       std::vector<SubgameSpec> games = getAvailableGames();
-
-       lua_newtable(L);
-       int top = lua_gettop(L);
-       unsigned int index = 1;
-
-       for (unsigned int i = 0; i < games.size(); i++)
-       {
-               lua_pushnumber(L,index);
-               lua_newtable(L);
-               int top_lvl2 = lua_gettop(L);
-
-               lua_pushstring(L,"id");
-               lua_pushstring(L,games[i].id.c_str());
-               lua_settable(L, top_lvl2);
-
-               lua_pushstring(L,"path");
-               lua_pushstring(L,games[i].path.c_str());
-               lua_settable(L, top_lvl2);
-
-               lua_pushstring(L,"gamemods_path");
-               lua_pushstring(L,games[i].gamemods_path.c_str());
-               lua_settable(L, top_lvl2);
-
-               lua_pushstring(L,"name");
-               lua_pushstring(L,games[i].name.c_str());
-               lua_settable(L, top_lvl2);
-
-               lua_pushstring(L,"menuicon_path");
-               lua_pushstring(L,games[i].menuicon_path.c_str());
-               lua_settable(L, top_lvl2);
-
-               lua_pushstring(L,"addon_mods_paths");
-               lua_newtable(L);
-               int table2 = lua_gettop(L);
-               int internal_index=1;
-               for (std::set<std::string>::iterator iter = games[i].addon_mods_paths.begin();
-                               iter != games[i].addon_mods_paths.end(); iter++) {
-                       lua_pushnumber(L,internal_index);
-                       lua_pushstring(L,(*iter).c_str());
-                       lua_settable(L, table2);
-                       internal_index++;
-               }
-               lua_settable(L, top_lvl2);
-               lua_settable(L, top);
-               index++;
-       }
-       return 1;
-}
-/******************************************************************************/
-int guiLuaApi::l_get_modstore_details(lua_State *L)
-{
-       const char *modid       = luaL_checkstring(L, 1);
-
-       if (modid != 0) {
-               Json::Value details;
-               std::string url = "";
-               try{
-                       url = g_settings->get("modstore_details_url");
-               }
-               catch(SettingNotFoundException &e) {
-                       lua_pushnil(L);
-                       return 1;
-               }
-
-               size_t idpos = url.find("*");
-               url.erase(idpos,1);
-               url.insert(idpos,modid);
-
-               details = getModstoreUrl(url);
-
-               ModStoreModDetails current_mod = readModStoreModDetails(details);
-
-               if ( current_mod.valid) {
-                       lua_newtable(L);
-                       int top = lua_gettop(L);
-
-                       lua_pushstring(L,"id");
-                       lua_pushnumber(L,current_mod.id);
-                       lua_settable(L, top);
-
-                       lua_pushstring(L,"title");
-                       lua_pushstring(L,current_mod.title.c_str());
-                       lua_settable(L, top);
-
-                       lua_pushstring(L,"basename");
-                       lua_pushstring(L,current_mod.basename.c_str());
-                       lua_settable(L, top);
-
-                       lua_pushstring(L,"description");
-                       lua_pushstring(L,current_mod.description.c_str());
-                       lua_settable(L, top);
-
-                       lua_pushstring(L,"author");
-                       lua_pushstring(L,current_mod.author.username.c_str());
-                       lua_settable(L, top);
-
-                       lua_pushstring(L,"download_url");
-                       lua_pushstring(L,current_mod.versions[0].file.c_str());
-                       lua_settable(L, top);
-
-                       lua_pushstring(L,"screenshot_url");
-                       lua_pushstring(L,current_mod.titlepic.file.c_str());
-                       lua_settable(L, top);
-
-                       lua_pushstring(L,"license");
-                       lua_pushstring(L,current_mod.license.shortinfo.c_str());
-                       lua_settable(L, top);
-
-                       lua_pushstring(L,"rating");
-                       lua_pushnumber(L,current_mod.rating);
-                       lua_settable(L, top);
-
-                       //TODO depends
-
-                       //TODO softdepends
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_get_modstore_list(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       std::string listtype = "local";
-
-       if (!lua_isnone(L,1)) {
-               listtype = luaL_checkstring(L,1);
-       }
-       Json::Value mods;
-       std::string url = "";
-       try{
-               url = g_settings->get("modstore_listmods_url");
-       }
-       catch(SettingNotFoundException &e) {
-               lua_pushnil(L);
-               return 1;
-       }
-
-       mods = getModstoreUrl(url);
-
-       std::vector<ModStoreMod> moddata = readModStoreList(mods);
-
-       lua_newtable(L);
-       int top = lua_gettop(L);
-       unsigned int index = 1;
-
-       for (unsigned int i = 0; i < moddata.size(); i++)
-       {
-               if (moddata[i].valid) {
-                       lua_pushnumber(L,index);
-                       lua_newtable(L);
-
-                       int top_lvl2 = lua_gettop(L);
-
-                       lua_pushstring(L,"id");
-                       lua_pushnumber(L,moddata[i].id);
-                       lua_settable(L, top_lvl2);
-
-                       lua_pushstring(L,"title");
-                       lua_pushstring(L,moddata[i].title.c_str());
-                       lua_settable(L, top_lvl2);
-
-                       lua_pushstring(L,"basename");
-                       lua_pushstring(L,moddata[i].basename.c_str());
-                       lua_settable(L, top_lvl2);
-
-                       lua_settable(L, top);
-                       index++;
-               }
-       }
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_get_favorites(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       std::string listtype = "local";
-
-       if (!lua_isnone(L,1)) {
-               listtype = luaL_checkstring(L,1);
-       }
-
-       std::vector<ServerListSpec> servers;
-#if USE_CURL
-       if(listtype == "online") {
-               servers = ServerList::getOnline();
-       } else {
-               servers = ServerList::getLocal();
-       }
-#else
-       servers = ServerList::getLocal();
-#endif
-
-       lua_newtable(L);
-       int top = lua_gettop(L);
-       unsigned int index = 1;
-
-       for (unsigned int i = 0; i < servers.size(); i++)
-       {
-               lua_pushnumber(L,index);
-
-               lua_newtable(L);
-               int top_lvl2 = lua_gettop(L);
-
-               if (servers[i]["clients"].asString().size()) {
-
-                       const char* clients_raw = servers[i]["clients"].asString().c_str();
-                       char* endptr = 0;
-                       int numbervalue = strtol(clients_raw,&endptr,10);
-
-                       if ((*clients_raw != 0) && (*endptr == 0)) {
-                               lua_pushstring(L,"clients");
-                               lua_pushnumber(L,numbervalue);
-                               lua_settable(L, top_lvl2);
-                       }
-               }
-
-               if (servers[i]["clients_max"].asString().size()) {
-
-                       const char* clients_max_raw = servers[i]["clients_max"].asString().c_str();
-                       char* endptr = 0;
-                       int numbervalue = strtol(clients_max_raw,&endptr,10);
-
-                       if ((*clients_max_raw != 0) && (*endptr == 0)) {
-                               lua_pushstring(L,"clients_max");
-                               lua_pushnumber(L,numbervalue);
-                               lua_settable(L, top_lvl2);
-                       }
-               }
-
-               if (servers[i]["version"].asString().size()) {
-                       lua_pushstring(L,"version");
-                       lua_pushstring(L,servers[i]["version"].asString().c_str());
-                       lua_settable(L, top_lvl2);
-               }
-
-               if (servers[i]["password"].asString().size()) {
-                       lua_pushstring(L,"password");
-                       lua_pushboolean(L,true);
-                       lua_settable(L, top_lvl2);
-               }
-
-               if (servers[i]["creative"].asString().size()) {
-                       lua_pushstring(L,"creative");
-                       lua_pushboolean(L,true);
-                       lua_settable(L, top_lvl2);
-               }
-
-               if (servers[i]["damage"].asString().size()) {
-                       lua_pushstring(L,"damage");
-                       lua_pushboolean(L,true);
-                       lua_settable(L, top_lvl2);
-               }
-
-               if (servers[i]["pvp"].asString().size()) {
-                       lua_pushstring(L,"pvp");
-                       lua_pushboolean(L,true);
-                       lua_settable(L, top_lvl2);
-               }
-
-               if (servers[i]["description"].asString().size()) {
-                       lua_pushstring(L,"description");
-                       lua_pushstring(L,servers[i]["description"].asString().c_str());
-                       lua_settable(L, top_lvl2);
-               }
-
-               if (servers[i]["name"].asString().size()) {
-                       lua_pushstring(L,"name");
-                       lua_pushstring(L,servers[i]["name"].asString().c_str());
-                       lua_settable(L, top_lvl2);
-               }
-
-               if (servers[i]["address"].asString().size()) {
-                       lua_pushstring(L,"address");
-                       lua_pushstring(L,servers[i]["address"].asString().c_str());
-                       lua_settable(L, top_lvl2);
-               }
-
-               if (servers[i]["port"].asString().size()) {
-                       lua_pushstring(L,"port");
-                       lua_pushstring(L,servers[i]["port"].asString().c_str());
-                       lua_settable(L, top_lvl2);
-               }
-
-               lua_settable(L, top);
-               index++;
-       }
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_delete_favorite(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       std::vector<ServerListSpec> servers;
-
-       std::string listtype = "local";
-
-       if (!lua_isnone(L,2)) {
-               listtype = luaL_checkstring(L,2);
-       }
-
-       if ((listtype != "local") &&
-               (listtype != "online"))
-               return 0;
-
-#if USE_CURL
-       if(listtype == "online") {
-               servers = ServerList::getOnline();
-       } else {
-               servers = ServerList::getLocal();
-       }
-#else
-       servers = ServerList::getLocal();
-#endif
-
-       int fav_idx     = luaL_checkinteger(L,1) -1;
-
-       if ((fav_idx >= 0) &&
-                       (fav_idx < (int) servers.size())) {
-
-               ServerList::deleteEntry(servers[fav_idx]);
-       }
-
-       return 0;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_show_keys_menu(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       GUIKeyChangeMenu *kmenu
-               = new GUIKeyChangeMenu( engine->m_device->getGUIEnvironment(),
-                                                               engine->m_parent,
-                                                               -1,
-                                                               engine->m_menumanager);
-       kmenu->drop();
-       return 0;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_setting_set(lua_State *L)
-{
-       const char *name = luaL_checkstring(L, 1);
-       const char *value = luaL_checkstring(L, 2);
-       g_settings->set(name, value);
-       return 0;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_setting_get(lua_State *L)
-{
-       const char *name = luaL_checkstring(L, 1);
-       try{
-               std::string value = g_settings->get(name);
-               lua_pushstring(L, value.c_str());
-       } catch(SettingNotFoundException &e){
-               lua_pushnil(L);
-       }
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_setting_getbool(lua_State *L)
-{
-       const char *name = luaL_checkstring(L, 1);
-       try{
-               bool value = g_settings->getBool(name);
-               lua_pushboolean(L, value);
-       } catch(SettingNotFoundException &e){
-               lua_pushnil(L);
-       }
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_setting_setbool(lua_State *L)
-{
-       const char *name = luaL_checkstring(L, 1);
-       bool value = lua_toboolean(L,2);
-
-       g_settings->setBool(name,value);
-
-       return 0;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_create_world(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       const char *name        = luaL_checkstring(L, 1);
-       int gameidx                     = luaL_checkinteger(L,2) -1;
-
-       std::string path = porting::path_user + DIR_DELIM
-                       "worlds" + DIR_DELIM
-                       + name;
-
-       std::vector<SubgameSpec> games = getAvailableGames();
-
-       if ((gameidx >= 0) &&
-                       (gameidx < (int) games.size())) {
-
-               // Create world if it doesn't exist
-               if(!initializeWorld(path, games[gameidx].id)){
-                       lua_pushstring(L, "Failed to initialize world");
-
-               }
-               else {
-               lua_pushnil(L);
-               }
-       }
-       else {
-               lua_pushstring(L, "Invalid game index");
-       }
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_delete_world(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       int worldidx    = luaL_checkinteger(L,1) -1;
-
-       std::vector<WorldSpec> worlds = getAvailableWorlds();
-
-       if ((worldidx >= 0) &&
-               (worldidx < (int) worlds.size())) {
-
-               WorldSpec spec = worlds[worldidx];
-
-               std::vector<std::string> paths;
-               paths.push_back(spec.path);
-               fs::GetRecursiveSubPaths(spec.path, paths);
-
-               // Delete files
-               if (!fs::DeletePaths(paths)) {
-                       lua_pushstring(L, "Failed to delete world");
-               }
-               else {
-                       lua_pushnil(L);
-               }
-       }
-       else {
-               lua_pushstring(L, "Invalid world index");
-       }
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_set_topleft_text(lua_State *L)
-{
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       std::string text = "";
-
-       if (!lua_isnone(L,1) && !lua_isnil(L,1))
-               text = luaL_checkstring(L, 1);
-
-       engine->setTopleftText(text);
-       return 0;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_get_modpath(lua_State *L)
-{
-       std::string modpath
-                       = fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "mods" + DIR_DELIM);
-       lua_pushstring(L, modpath.c_str());
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_get_gamepath(lua_State *L)
-{
-       std::string gamepath
-                       = fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "games" + DIR_DELIM);
-       lua_pushstring(L, gamepath.c_str());
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_get_texturepath(lua_State *L)
-{
-       std::string gamepath
-                       = fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "textures");
-       lua_pushstring(L, gamepath.c_str());
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_get_dirlist(lua_State *L) {
-       const char *path        = luaL_checkstring(L, 1);
-       bool dironly            = lua_toboolean(L, 2);
-
-       std::vector<fs::DirListNode> dirlist = fs::GetDirListing(path);
-
-       unsigned int index = 1;
-       lua_newtable(L);
-       int table = lua_gettop(L);
-
-       for (unsigned int i=0;i< dirlist.size(); i++) {
-               if ((dirlist[i].dir) || (dironly == false)) {
-                       lua_pushnumber(L,index);
-                       lua_pushstring(L,dirlist[i].name.c_str());
-                       lua_settable(L, table);
-                       index++;
-               }
-       }
-
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_create_dir(lua_State *L) {
-       const char *path        = luaL_checkstring(L, 1);
-
-       if (guiLuaApi::isMinetestPath(path)) {
-               lua_pushboolean(L,fs::CreateAllDirs(path));
-               return 1;
-       }
-       lua_pushboolean(L,false);
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_delete_dir(lua_State *L) {
-       const char *path        = luaL_checkstring(L, 1);
-
-       std::string absolute_path = fs::RemoveRelativePathComponents(path);
-
-       if (guiLuaApi::isMinetestPath(absolute_path)) {
-               lua_pushboolean(L,fs::RecursiveDelete(absolute_path));
-               return 1;
-       }
-       lua_pushboolean(L,false);
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_copy_dir(lua_State *L) {
-       const char *source      = luaL_checkstring(L, 1);
-       const char *destination = luaL_checkstring(L, 2);
-
-       bool keep_source = true;
-
-       if ((!lua_isnone(L,3)) &&
-                       (!lua_isnil(L,3))) {
-               keep_source = lua_toboolean(L,3);
-       }
-
-       std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
-       std::string absolute_source = fs::RemoveRelativePathComponents(source);
-
-       if ((guiLuaApi::isMinetestPath(absolute_source)) &&
-                       (guiLuaApi::isMinetestPath(absolute_destination))) {
-               bool retval = fs::CopyDir(absolute_source,absolute_destination);
-
-               if (retval && (!keep_source)) {
-
-                       retval &= fs::RecursiveDelete(absolute_source);
-               }
-               lua_pushboolean(L,retval);
-               return 1;
-       }
-       lua_pushboolean(L,false);
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_extract_zip(lua_State *L) {
-
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       const char *zipfile     = luaL_checkstring(L, 1);
-       const char *destination = luaL_checkstring(L, 2);
-
-       std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
-
-       if (guiLuaApi::isMinetestPath(absolute_destination)) {
-               fs::CreateAllDirs(absolute_destination);
-
-               io::IFileSystem* fs = engine->m_device->getFileSystem();
-
-               fs->addFileArchive(zipfile,true,false,io::EFAT_ZIP);
-
-               assert(fs->getFileArchiveCount() > 0);
-
-               /**********************************************************************/
-               /* WARNING this is not threadsafe!!                                   */
-               /**********************************************************************/
-               io::IFileArchive* opened_zip =
-                       fs->getFileArchive(fs->getFileArchiveCount()-1);
-
-               const io::IFileList* files_in_zip = opened_zip->getFileList();
-
-               unsigned int number_of_files = files_in_zip->getFileCount();
-
-               for (unsigned int i=0; i < number_of_files;  i++) {
-                       std::string fullpath = destination;
-                       fullpath += DIR_DELIM;
-                       fullpath += files_in_zip->getFullFileName(i).c_str();
-
-                       if (files_in_zip->isDirectory(i)) {
-                               if (! fs::CreateAllDirs(fullpath) ) {
-                                       fs->removeFileArchive(fs->getFileArchiveCount()-1);
-                                       lua_pushboolean(L,false);
-                                       return 1;
-                               }
-                       }
-                       else {
-                               io::IReadFile* toread = opened_zip->createAndOpenFile(i);
-
-                               FILE *targetfile = fopen(fullpath.c_str(),"wb");
-
-                               if (targetfile == NULL) {
-                                       fs->removeFileArchive(fs->getFileArchiveCount()-1);
-                                       lua_pushboolean(L,false);
-                                       return 1;
-                               }
-
-                               char read_buffer[1024];
-                               unsigned int total_read = 0;
-
-                               while (total_read < toread->getSize()) {
-
-                                       unsigned int bytes_read =
-                                                       toread->read(read_buffer,sizeof(read_buffer));
-                                       unsigned int bytes_written;
-                                       if ((bytes_read < 0 ) ||
-                                               (bytes_written = fwrite(read_buffer, 1, bytes_read, targetfile) != bytes_read))
-                                       {
-                                               fclose(targetfile);
-                                               fs->removeFileArchive(fs->getFileArchiveCount()-1);
-                                               lua_pushboolean(L,false);
-                                               return 1;
-                                       }
-                                       total_read += bytes_read;
-                               }
-
-                               fclose(targetfile);
-                       }
-
-               }
-
-               fs->removeFileArchive(fs->getFileArchiveCount()-1);
-               lua_pushboolean(L,true);
-               return 1;
-       }
-
-       lua_pushboolean(L,false);
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_get_scriptdir(lua_State *L) {
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       lua_pushstring(L,engine->getScriptDir().c_str());
-       return 1;
-}
-
-/******************************************************************************/
-bool guiLuaApi::isMinetestPath(std::string path) {
-
-
-       if (fs::PathStartsWith(path,fs::TempPath()))
-               return true;
-
-       /* games */
-       if (fs::PathStartsWith(path,fs::RemoveRelativePathComponents(porting::path_share + DIR_DELIM + "games")))
-               return true;
-
-       /* mods */
-       if (fs::PathStartsWith(path,fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "mods")))
-               return true;
-
-       /* worlds */
-       if (fs::PathStartsWith(path,fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "worlds")))
-               return true;
-
-
-       return false;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_show_file_open_dialog(lua_State *L) {
-
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       const char *formname= luaL_checkstring(L, 1);
-       const char *title       = luaL_checkstring(L, 2);
-
-       GUIFileSelectMenu* fileOpenMenu =
-               new GUIFileSelectMenu(engine->m_device->getGUIEnvironment(),
-                                                               engine->m_parent,
-                                                               -1,
-                                                               engine->m_menumanager,
-                                                               title,
-                                                               formname);
-       fileOpenMenu->setTextDest(engine->m_buttonhandler);
-       fileOpenMenu->drop();
-       return 0;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_get_version(lua_State *L) {
-       lua_pushstring(L,VERSION_STRING);
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_sound_play(lua_State *L) {
-       GUIEngine* engine = get_engine(L);
-
-       SimpleSoundSpec spec;
-       if(lua_isnil(L, 1))
-       {
-       } else if(lua_istable(L, 1)){
-               lua_getfield(L, 1, "name");
-               if(lua_isstring(L, -1)){
-                       size_t len = 0;
-                       spec.name = lua_tolstring(L, -1, &len);
-               }
-               lua_pop(L, 1);
-
-               //luaL_checkfloat(L, 1, "gain", spec.gain);
-               lua_getfield(L, 1, "gain");
-               if(lua_isnumber(L, -1)){
-                       spec.gain = lua_tonumber(L, -1);
-               }
-               lua_pop(L, 1);
-       } else if(lua_isstring(L, 1)){
-               spec.name = luaL_checkstring(L, 1);
-       }
-       bool looped = lua_toboolean(L, 2);
-
-       u32 handle = engine->playSound(spec, looped);
-
-       lua_pushinteger(L, handle);
-
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_sound_stop(lua_State *L) {
-       GUIEngine* engine = get_engine(L);
-
-       u32 handle = luaL_checkinteger(L, 1);
-       engine->stopSound(handle);
-
-       return 1;
-}
-
-/******************************************************************************/
-int guiLuaApi::l_download_file(lua_State *L) {
-       GUIEngine* engine = get_engine(L);
-       assert(engine != 0);
-
-       const char *url    = luaL_checkstring(L, 1);
-       const char *target = luaL_checkstring(L, 2);
-
-       //check path
-       std::string absolute_destination = fs::RemoveRelativePathComponents(target);
-
-       if (guiLuaApi::isMinetestPath(absolute_destination)) {
-               if (engine->downloadFile(url,absolute_destination)) {
-                       lua_pushboolean(L,true);
-                       return 1;
-               }
-       }
-       lua_pushboolean(L,false);
-       return 1;
-}
diff --git a/src/guiLuaApi.h b/src/guiLuaApi.h
deleted file mode 100644 (file)
index 9555f00..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
-Minetest
-Copyright (C) 2013 sapier
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef GUILUAAPI_H_
-#define GUILUAAPI_H_
-
-/******************************************************************************/
-/* Includes                                                                   */
-/******************************************************************************/
-#include "serverlist.h"
-
-/******************************************************************************/
-/* Typedefs and macros                                                        */
-/******************************************************************************/
-typedef int (*lua_CFunction) (lua_State *L);
-
-/******************************************************************************/
-/* forward declarations                                                       */
-/******************************************************************************/
-class GUIEngine;
-
-
-/******************************************************************************/
-/* declarations                                                               */
-/******************************************************************************/
-
-/** Implementation of lua api support for mainmenu */
-class guiLuaApi {
-
-public:
-       /**
-        * initialize given Lua stack
-        * @param L lua stack to initialize
-        * @param engine pointer to GUIEngine element to use as reference
-        */
-       static void initialize(lua_State* L,GUIEngine* engine);
-
-       /** default destructor */
-       virtual ~guiLuaApi() {}
-
-private:
-       /**
-        * read a text variable from gamedata table within lua stack
-        * @param L stack to read variable from
-        * @param name name of variable to read
-        * @return string value of requested variable
-        */
-       static std::string getTextData(lua_State *L, std::string name);
-
-       /**
-        * read a integer variable from gamedata table within lua stack
-        * @param L stack to read variable from
-        * @param name name of variable to read
-        * @return integer value of requested variable
-        */
-       static int getIntegerData(lua_State *L, std::string name,bool& valid);
-
-       /**
-        * read a bool variable from gamedata table within lua stack
-        * @param L stack to read variable from
-        * @param name name of variable to read
-        * @return bool value of requested variable
-        */
-       static int getBoolData(lua_State *L, std::string name,bool& valid);
-
-       /**
-        * get the corresponding engine pointer from a lua stack
-        * @param L stack to read pointer from
-        * @return pointer to GUIEngine
-        */
-       static GUIEngine* get_engine(lua_State *L);
-
-
-       /**
-        * register a static member function as lua api call at current position of stack
-        * @param L stack to registe fct to
-        * @param name of function within lua
-        * @param fct C-Function to call on lua call of function
-        * @param top current top of stack
-        */
-       static bool registerFunction(   lua_State* L,
-                                                                       const char* name,
-                                                                       lua_CFunction fct,
-                                                                       int top
-                                                               );
-
-       /**
-        * check if a path is within some of minetests folders
-        * @param path path to check
-        * @return true/false
-        */
-       static bool isMinetestPath(std::string path);
-
-       //api calls
-
-       static int l_start(lua_State *L);
-
-       static int l_close(lua_State *L);
-
-       static int l_create_world(lua_State *L);
-
-       static int l_delete_world(lua_State *L);
-
-       static int l_get_worlds(lua_State *L);
-
-       static int l_get_games(lua_State *L);
-
-       static int l_get_favorites(lua_State *L);
-
-       static int l_delete_favorite(lua_State *L);
-
-       static int l_get_version(lua_State *L);
-
-       static int l_sound_play(lua_State *L);
-
-       static int l_sound_stop(lua_State *L);
-
-       //gui
-
-       static int l_show_keys_menu(lua_State *L);
-
-       static int l_show_file_open_dialog(lua_State *L);
-
-       static int l_set_topleft_text(lua_State *L);
-
-       static int l_set_clouds(lua_State *L);
-
-       static int l_get_textlist_index(lua_State *L);
-
-       static int l_set_background(lua_State *L);
-
-       static int l_update_formspec(lua_State *L);
-
-       //settings
-
-       static int l_setting_set(lua_State *L);
-
-       static int l_setting_get(lua_State *L);
-
-       static int l_setting_getbool(lua_State *L);
-
-       static int l_setting_setbool(lua_State *L);
-
-       //filesystem
-
-       static int l_get_scriptdir(lua_State *L);
-
-       static int l_get_modpath(lua_State *L);
-
-       static int l_get_gamepath(lua_State *L);
-       
-       static int l_get_texturepath(lua_State *L);
-
-       static int l_get_dirlist(lua_State *L);
-
-       static int l_create_dir(lua_State *L);
-
-       static int l_delete_dir(lua_State *L);
-
-       static int l_copy_dir(lua_State *L);
-
-       static int l_extract_zip(lua_State *L);
-
-       static int l_get_modstore_details(lua_State *L);
-
-       static int l_get_modstore_list(lua_State *L);
-
-       static int l_download_file(lua_State *L);
-
-
-};
-
-#endif
index c272b132dc3e7f80a47ce4f8ad839da5a3cddb95..2f462b7729c8eb553a9a816e9e008d65452fdb5d 100644 (file)
@@ -27,6 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <IGUIStaticText.h>
 #include <IGUIFont.h>
 #include "main.h"
+#include "settings.h"
 
 #include "gettext.h"
 
index f1a4ab523e17cbe59c2add602dd5f900feacd786..58a6c7cf86c693977c57b3d269b8ea83aa91e0e1 100644 (file)
@@ -19,14 +19,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include <IGUIStaticText.h>
-
-#include "guiFormSpecMenu.h"
+#include "hud.h"
 #include "main.h"
+#include "settings.h"
 #include "util/numeric.h"
 #include "log.h"
-#include "client.h"
-#include "hud.h"
+#include "gamedef.h"
+#include "itemdef.h"
+#include "inventory.h"
+#include "tile.h"
+#include "localplayer.h"
+
+#include <IGUIStaticText.h>
 
 
 Hud::Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv,
@@ -339,3 +343,90 @@ void Hud::resizeHotbar() {
        else
                hotbar_imagesize = 64;
 }
+
+void drawItemStack(video::IVideoDriver *driver,
+               gui::IGUIFont *font,
+               const ItemStack &item,
+               const core::rect<s32> &rect,
+               const core::rect<s32> *clip,
+               IGameDef *gamedef)
+{
+       if(item.empty())
+               return;
+       
+       const ItemDefinition &def = item.getDefinition(gamedef->idef());
+       video::ITexture *texture = gamedef->idef()->getInventoryTexture(def.name, gamedef);
+
+       // Draw the inventory texture
+       if(texture != NULL)
+       {
+               const video::SColor color(255,255,255,255);
+               const video::SColor colors[] = {color,color,color,color};
+               driver->draw2DImage(texture, rect,
+                       core::rect<s32>(core::position2d<s32>(0,0),
+                       core::dimension2di(texture->getOriginalSize())),
+                       clip, colors, true);
+       }
+
+       if(def.type == ITEM_TOOL && item.wear != 0)
+       {
+               // Draw a progressbar
+               float barheight = rect.getHeight()/16;
+               float barpad_x = rect.getWidth()/16;
+               float barpad_y = rect.getHeight()/16;
+               core::rect<s32> progressrect(
+                       rect.UpperLeftCorner.X + barpad_x,
+                       rect.LowerRightCorner.Y - barpad_y - barheight,
+                       rect.LowerRightCorner.X - barpad_x,
+                       rect.LowerRightCorner.Y - barpad_y);
+
+               // Shrink progressrect by amount of tool damage
+               float wear = item.wear / 65535.0;
+               int progressmid =
+                       wear * progressrect.UpperLeftCorner.X +
+                       (1-wear) * progressrect.LowerRightCorner.X;
+
+               // Compute progressbar color
+               //   wear = 0.0: green
+               //   wear = 0.5: yellow
+               //   wear = 1.0: red
+               video::SColor color(255,255,255,255);
+               int wear_i = MYMIN(floor(wear * 600), 511);
+               wear_i = MYMIN(wear_i + 10, 511);
+               if(wear_i <= 255)
+                       color.set(255, wear_i, 255, 0);
+               else
+                       color.set(255, 255, 511-wear_i, 0);
+
+               core::rect<s32> progressrect2 = progressrect;
+               progressrect2.LowerRightCorner.X = progressmid;
+               driver->draw2DRectangle(color, progressrect2, clip);
+
+               color = video::SColor(255,0,0,0);
+               progressrect2 = progressrect;
+               progressrect2.UpperLeftCorner.X = progressmid;
+               driver->draw2DRectangle(color, progressrect2, clip);
+       }
+
+       if(font != NULL && item.count >= 2)
+       {
+               // Get the item count as a string
+               std::string text = itos(item.count);
+               v2u32 dim = font->getDimension(narrow_to_wide(text).c_str());
+               v2s32 sdim(dim.X,dim.Y);
+
+               core::rect<s32> rect2(
+                       /*rect.UpperLeftCorner,
+                       core::dimension2d<u32>(rect.getWidth(), 15)*/
+                       rect.LowerRightCorner - sdim,
+                       sdim
+               );
+
+               video::SColor bgcolor(128,0,0,0);
+               driver->draw2DRectangle(bgcolor, rect2, clip);
+
+               video::SColor color(255,255,255,255);
+               font->draw(text.c_str(), rect2, color, false, false, clip);
+       }
+}
+
index c7289f7c4f79244b963f17cd6ef00266c3c960f0..27e23929715910a5e32bca78efe9d94c0a12187b 100644 (file)
--- a/src/hud.h
+++ b/src/hud.h
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define HUD_HEADER
 
 #include "irrlichttypes_extrabloated.h"
+#include <string>
 
 #define HUD_DIR_LEFT_RIGHT 0
 #define HUD_DIR_RIGHT_LEFT 1
@@ -42,8 +43,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define HUD_HOTBAR_ITEMCOUNT_DEFAULT 8
 #define HUD_HOTBAR_ITEMCOUNT_MAX     23
 
-class Player;
-
 enum HudElementType {
        HUD_ELEM_IMAGE     = 0,
        HUD_ELEM_TEXT      = 1,
@@ -76,23 +75,18 @@ struct HudElement {
        v2f offset;
 };
 
-
-inline u32 hud_get_free_id(Player *player) {
-       size_t size = player->hud.size();
-       for (size_t i = 0; i != size; i++) {
-               if (!player->hud[i])
-                       return i;
-       }
-       return size;
-}
-
 #ifndef SERVER
 
+#include <vector>
 #include <IGUIFont.h>
+#include "irr_aabb3d.h"
 
-#include "gamedef.h"
-#include "inventory.h"
-#include "localplayer.h"
+class IGameDef;
+class ITextureSource;
+class Inventory;
+class InventoryList;
+class LocalPlayer;
+struct ItemStack;
 
 class Hud {
 public:
@@ -130,6 +124,14 @@ public:
        void drawSelectionBoxes(std::vector<aabb3f> &hilightboxes);
 };
 
+void drawItemStack(video::IVideoDriver *driver,
+               gui::IGUIFont *font,
+               const ItemStack &item,
+               const core::rect<s32> &rect,
+               const core::rect<s32> *clip,
+               IGameDef *gamedef);
+
+
 #endif
 
 #endif
index 1a66a13a4b9ceb4109890461a83e9748f65af3bb..cd592a17ac9cfe0375eac4a13ba77ecf9176c097 100644 (file)
@@ -21,10 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define INVENTORY_HEADER
 
 #include <iostream>
-#include <sstream>
 #include <string>
 #include <vector>
-#include "irrlichttypes_bloated.h"
+#include "irrlichttypes.h"
 #include "debug.h"
 #include "itemdef.h"
 
index 6187675d47e2c22002acfb3f2e8bc6166e23c1fc..c81f7a19e6515e1e71a8a10fb2a50f9c781cbe5d 100644 (file)
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "inventorymanager.h"
 #include "log.h"
 #include "environment.h"
-#include "cpp_api/scriptapi.h"
+#include "scripting_game.h"
 #include "serverobject.h"
 #include "main.h"  // for g_settings
 #include "settings.h"
@@ -29,6 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
 
+#define PLAYER_TO_SA(p)   p->getEnv()->getScriptIface()
+
 /*
        InventoryLocation
 */
index 2ce19999ea25e3a65d5ad72a821d564e3d570e93..77aba350c83192ef439033d733deb989a0fbb765 100644 (file)
@@ -26,9 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "irr_v3d.h"
 #include "irr_aabb3d.h"
 
-#include <irrMap.h>
-#include <irrList.h>
-#include <irrArray.h>
 #include <SColor.h>
 
 #endif
index a541b1a02b85c81457a382d8eea90bc8a9a41f31..cd6cb1d2c6cbebf15e5d3e03edc27d37f97852fe 100644 (file)
@@ -20,9 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef IRRLICHTTYPES_EXTRABLOATED_HEADER
 #define IRRLICHTTYPES_EXTRABLOATED_HEADER
 
-#define endSceneX(d){d->draw2DLine(v2s32(0,0),v2s32(1,0),\
-video::SColor(255,30,30,30));d->endScene();}
-
 #include "irrlichttypes_bloated.h"
 
 #ifndef SERVER
index 69678064fe606fe3583bc7b9b1e886b35d67460a..f6ae8673666c4f45b82a6d489ace49c38c419d9b 100644 (file)
@@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef ITEMGROUP_HEADER
 #define ITEMGROUP_HEADER
 
-#include "irrlichttypes_extrabloated.h"
 #include <string>
 #include <map>
 
index e847e1ce9362cc46b429952d194ab4cd3d323bb1..769ca31ce11b4e8c993a60b40d9886353b2a12e0 100644 (file)
@@ -21,16 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define LIGHT_HEADER
 
 #include "irrlichttypes.h"
-#include "debug.h"
-
-/*
-       Day/night cache:
-       Meshes are cached for different day-to-night transition values
-*/
-
-/*#define DAYNIGHT_CACHE_COUNT 3
-// First one is day, last one is night.
-extern u32 daynight_cache_ratios[DAYNIGHT_CACHE_COUNT];*/
 
 /*
        Lower level lighting stuff
index f495a6ba253f5780e6953b9de3552d1a469f3e91..7450593d326d380b6fc4d63e661dbaf671da0646 100644 (file)
@@ -84,6 +84,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 Settings main_settings;
 Settings *g_settings = &main_settings;
+std::string g_settings_path;
 
 // Global profiler
 Profiler main_profiler;
@@ -913,7 +914,7 @@ int main(int argc, char *argv[])
        */
        
        // Path of configuration file in use
-       std::string configpath = "";
+       g_settings_path = "";
        
        if(cmd_args.exists("config"))
        {
@@ -924,7 +925,7 @@ int main(int argc, char *argv[])
                                        <<cmd_args.get("config")<<"\""<<std::endl;
                        return 1;
                }
-               configpath = cmd_args.get("config");
+               g_settings_path = cmd_args.get("config");
        }
        else
        {
@@ -946,14 +947,14 @@ int main(int argc, char *argv[])
                        bool r = g_settings->readConfigFile(filenames[i].c_str());
                        if(r)
                        {
-                               configpath = filenames[i];
+                               g_settings_path = filenames[i];
                                break;
                        }
                }
                
                // If no path found, use the first one (menu creates the file)
-               if(configpath == "")
-                       configpath = filenames[0];
+               if(g_settings_path == "")
+                       g_settings_path = filenames[0];
        }
        
        // Initialize debug streams
@@ -1193,7 +1194,7 @@ int main(int argc, char *argv[])
                verbosestream<<_("Using gameid")<<" ["<<gamespec.id<<"]"<<std::endl;
 
                // Create server
-               Server server(world_path, configpath, gamespec, false);
+               Server server(world_path, gamespec, false);
                server.start(port);
                
                // Run server
@@ -1573,6 +1574,11 @@ int main(int argc, char *argv[])
 
                                }
 
+                               if(menudata.errormessage != ""){
+                                       error_message = narrow_to_wide(menudata.errormessage);
+                                       continue;
+                               }
+
                                //update worldspecs (necessary as new world may have been created)
                                worldspecs = getAvailableWorlds();
 
@@ -1675,7 +1681,10 @@ int main(int argc, char *argv[])
 
                        // Break out of menu-game loop to shut down cleanly
                        if(device->run() == false || kill == true) {
-                               g_settings->updateConfigFile(configpath.c_str());
+                               if(g_settings_path != "") {
+                                       g_settings->updateConfigFile(
+                                               g_settings_path.c_str());
+                               }
                                break;
                        }
 
@@ -1694,7 +1703,6 @@ int main(int argc, char *argv[])
                                current_address,
                                current_port,
                                error_message,
-                               configpath,
                                chat_backend,
                                gamespec,
                                simple_singleplayer_mode
@@ -1749,8 +1757,8 @@ int main(int argc, char *argv[])
 #endif // !SERVER
        
        // Update configuration file
-       if(configpath != "")
-               g_settings->updateConfigFile(configpath.c_str());
+       if(g_settings_path != "")
+               g_settings->updateConfigFile(g_settings_path.c_str());
        
        // Print modified quicktune values
        {
index df67a634848bfecd28d534749cf82018bc39c404..191b418873096abc447e358d723cf2703b532847 100644 (file)
@@ -20,9 +20,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef MAIN_HEADER
 #define MAIN_HEADER
 
+#include <string>
+
 // Settings
 class Settings;
 extern Settings *g_settings;
+extern std::string g_settings_path;
 
 // Global profiler
 class Profiler;
index 331aa48d943541e5c2856ed05480387bfe134201..62ba85c4774c085162a78755eb6ac9b73edae4c6 100644 (file)
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "filesys.h"
 #include "voxel.h"
 #include "porting.h"
+#include "serialization.h"
 #include "nodemetadata.h"
 #include "settings.h"
 #include "log.h"
@@ -33,9 +34,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/directiontables.h"
 #include "util/mathconstants.h"
 #include "rollback_interface.h"
+#include "environment.h"
 #include "emerge.h"
 #include "mapgen_v6.h"
-#include "mapgen_indev.h"
 #include "biome.h"
 
 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
index c90106ed1a689041676e9b011b887fead2a3dcdc..2f8bfaebabc4cb19bba80af6964982de61b47ef5 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -20,9 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef MAP_HEADER
 #define MAP_HEADER
 
-#include <jmutex.h>
-#include <jmutexautolock.h>
-#include <jthread.h>
 #include <iostream>
 #include <sstream>
 #include <set>
@@ -33,11 +30,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapnode.h"
 #include "constants.h"
 #include "voxel.h"
-#include "mapgen.h" //for MapgenParams
 #include "modifiedstate.h"
 #include "util/container.h"
 #include "nodetimer.h"
-#include "environment.h"
 
 extern "C" {
        #include "sqlite3.h"
@@ -51,7 +46,9 @@ class NodeMetadata;
 class IGameDef;
 class IRollbackReportSink;
 class EmergeManager;
+class ServerEnvironment;
 struct BlockMakeData;
+struct MapgenParams;
 
 
 /*
index 617ba658447343d5f98231ce40d6dc8b8b717b30..b8278b3be740829bdc0e0428ec705f0823f4139b 100644 (file)
@@ -21,8 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include <sstream>
 #include "map.h"
-// For g_settings
-#include "main.h"
 #include "light.h"
 #include "nodedef.h"
 #include "nodemetadata.h"
@@ -31,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "nameidmapping.h"
 #include "content_mapnode.h" // For legacy name-id mapping
 #include "content_nodemeta.h" // For legacy deserialization
+#include "serialization.h"
 #ifndef SERVER
 #include "mapblock_mesh.h"
 #endif
index 576122201ba78f78ff23cdff653bbe3145b88fbb..de49e613055069616b4b5ae2a0f99cc2b5918cf7 100644 (file)
@@ -20,19 +20,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef MAPBLOCK_HEADER
 #define MAPBLOCK_HEADER
 
-#include <jmutex.h>
-#include <jmutexautolock.h>
-#include <exception>
 #include <set>
 #include "debug.h"
-#include "irrlichttypes.h"
 #include "irr_v3d.h"
-#include "irr_aabb3d.h"
 #include "mapnode.h"
 #include "exceptions.h"
-#include "serialization.h"
 #include "constants.h"
-#include "voxel.h"
 #include "staticobject.h"
 #include "nodemetadata.h"
 #include "nodetimer.h"
@@ -43,6 +36,7 @@ class Map;
 class NodeMetadataList;
 class IGameDef;
 class MapBlockMesh;
+class VoxelManipulator;
 
 #define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff
 
@@ -514,7 +508,6 @@ public:
 
 #ifndef SERVER // Only on client
        MapBlockMesh *mesh;
-       //JMutex mesh_mutex;
 #endif
        
        NodeMetadataList m_node_metadata;
index be65694aa27a28f6473e7b55507b8ed4e5d2fb33..301601b6c4441fbb64c260b6df7afe39c2b0b129 100644 (file)
@@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "treegen.h"
 #include "mapgen_v6.h"
 #include "mapgen_v7.h"
+#include "serialization.h"
 #include "util/serialize.h"
 #include "filesys.h"
 
index 2e87c62bfc7db26b7f2cedebb0fbf7938fa705bc..040320f27cf8f3155024ab462638b85f321f777e 100644 (file)
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef MAPGEN_HEADER
 #define MAPGEN_HEADER
 
-#include "irrlichttypes_extrabloated.h"
+#include "irrlichttypes_bloated.h"
 #include "util/container.h" // UniqueQueue
 #include "gamedef.h"
 #include "nodedef.h"
index 30787c6bb660bfbae38231e3e20f8e783f7b78ce..fd443995c6ef50a0c9040f484260ff82a5266baa 100644 (file)
@@ -25,8 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "nodedef.h"
 #include "voxelalgorithms.h"
 #include "profiler.h"
-#include "settings.h" // For g_settings
-#include "main.h" // For g_profiler
 #include "emerge.h"
 
 //////////////////////// Mapgen Singlenode parameter read/write
index 785537759a4ea2ee0b12891b080fe9c759dd53de..3c6208436e584f743db816f79c9fa697706d0ca0 100644 (file)
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "irr_v3d.h"
 #include "irr_aabb3d.h"
 #include "light.h"
+#include <string>
 #include <vector>
 
 class INodeDefManager;
index ebb050ec364be99b060ef7af72d88a41351293ef..0d40a659d4003e558b493bdec2606b4736a14072 100644 (file)
@@ -18,12 +18,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "mapsector.h"
-#include "jmutexautolock.h"
-#ifndef SERVER
-#include "client.h"
-#endif
 #include "exceptions.h"
 #include "mapblock.h"
+#include "serialization.h"
 
 MapSector::MapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
                differs_from_disk(false),
index 4f2b3f31feb35acf3a555f51ba3168ded618d52b..dac4ee8d634992d55d933b63e7d587e4b2863bcd 100644 (file)
@@ -20,9 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef MAPSECTOR_HEADER
 #define MAPSECTOR_HEADER
 
-#include <jmutex.h>
-#include "irrlichttypes_bloated.h"
-#include "exceptions.h"
+#include "irrlichttypes.h"
+#include "irr_v2d.h"
 #include <ostream>
 #include <map>
 #include <list>
index 14a194b8822943c4ccac799672db5cf353ecbc47..5e5f9f8637c2481a257134e96b9a0c8241e5063b 100644 (file)
@@ -18,8 +18,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "mesh.h"
+#include "debug.h"
 #include "log.h"
-#include <cassert>
 #include <iostream>
 #include <IAnimatedMesh.h>
 #include <SAnimatedMesh.h>
index e10d49324bbf8a603af9f54f4d29f4576466c5ac..dedcc98978ff1ceb241dba2af5f32c9e22f75af3 100644 (file)
@@ -21,14 +21,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define MODS_HEADER
 
 #include "irrlichttypes.h"
-#include <irrList.h>
 #include <list>
 #include <set>
 #include <vector>
 #include <string>
 #include <map>
 #include <exception>
-#include <list>
 #include "json/json.h"
 #include "config.h"
 
@@ -152,10 +150,9 @@ private:
        // exists. A name conflict happens when two or more mods
        // at the same level have the same name but different paths.
        // Levels (mods in higher levels override mods in lower levels):
-       // 1. common mod in modpack; 2. common mod;
-       // 3. game mod in modpack; 4. game mod;
-       // 5. world mod in modpack; 6. world mod;
-       // 7. addon mod in modpack; 8. addon mod.
+       // 1. game mod in modpack; 2. game mod;
+       // 3. world mod in modpack; 4. world mod;
+       // 5. addon mod in modpack; 6. addon mod.
        std::set<std::string> m_name_conflicts;
 
 };
index bcddb45151406f9a1fd3f569eec6eba4f3d93433..ebe65076eafe8f9e9a5787d13417cecf39c0b7dc 100644 (file)
@@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "nameidmapping.h"
+#include "exceptions.h"
 #include "util/serialize.h"
 
 void NameIdMapping::serialize(std::ostream &os) const
index 5af10d0f0ef8133a9fad5d177c1026fcdb6060cf..ce2c9e6d9f0e9aaf81309f8c567a03d62a26dd26 100644 (file)
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef NODEMETADATA_HEADER
 #define NODEMETADATA_HEADER
 
-#include "irrlichttypes_bloated.h"
+#include "irr_v3d.h"
 #include <string>
 #include <iostream>
 #include <map>
index db5fb08b67d54b0f1940f827e1934d35c1600f49..5fc652bb76d386f78c82f04f17f18b1837230858 100644 (file)
@@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "nodetimer.h"
 #include "log.h"
+#include "serialization.h"
 #include "util/serialize.h"
 #include "constants.h" // MAP_BLOCKSIZE
 
index bdbd322939e6929c01b527e077aa0976b1994e4f..9fb56edecc33a711fe364450bc9560f271c9ed26 100644 (file)
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef NODETIMER_HEADER
 #define NODETIMER_HEADER
 
-#include "irrlichttypes_bloated.h"
+#include "irr_v3d.h"
 #include <iostream>
 #include <map>
 
index 5788a83203e3ba08230728676bbc56592ab8c9f0..35057146da9c919c7bb8d90f64451bc51dd0431c 100644 (file)
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <math.h>
 #include "noise.h"
 #include <iostream>
+#include <string.h> // memset
 #include "debug.h"
 #include "util/numeric.h"
 
index 7fad25cceda3c84a8aff4abc01395e2508570768..b6ad9f6dfa85057b3371232b56b6235e008eab37 100644 (file)
@@ -19,9 +19,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "object_properties.h"
 #include "irrlichttypes_bloated.h"
+#include "exceptions.h"
 #include "util/serialize.h"
 #include <sstream>
-#include <map>
 
 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
 #define PP2(x) "("<<(x).X<<","<<(x).Y<<")"
index bbda073624caf938a8ad1a025513f7fa1d3bb83c..43e1e287f6d72a94b3901a4b386c2ec2880d86cd 100644 (file)
@@ -22,6 +22,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 /******************************************************************************/
 
 #include "pathfinder.h"
+#include "environment.h"
+#include "map.h"
+#include "log.h"
 
 #ifdef PATHFINDER_DEBUG
 #include <iomanip>
index 7caf5844e3ec09a185486d8ae878e4d461f40893..dd41227f78c1b30a382de5cac0bd68303ffe46db 100644 (file)
@@ -25,10 +25,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 /******************************************************************************/
 #include <vector>
 
-#include "server.h"
 #include "irr_v3d.h"
 
 
+/******************************************************************************/
+/* Forward declarations                                                       */
+/******************************************************************************/
+
+class ServerEnvironment;
+
 /******************************************************************************/
 /* Typedefs and macros                                                        */
 /******************************************************************************/
index 193de55a90f55ba9f723fba32b03600b28cf49a1..584c00dd0855158a400ecc14bc5e0f3b72588281 100644 (file)
@@ -21,7 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "hud.h"
 #include "constants.h"
 #include "gamedef.h"
-#include "connection.h" // PEER_ID_INEXISTENT
 #include "settings.h"
 #include "content_sao.h"
 #include "util/numeric.h"
index 7ddc40b370356ea42dc2af7ec1503b0da58880ce..12ea0dba1c14e087a74e5fd3e98cee2f7c0cdfa9 100644 (file)
@@ -194,6 +194,15 @@ public:
                return m_collisionbox;
        }
 
+       u32 getFreeHudID() const {
+               size_t size = hud.size();
+               for (size_t i = 0; i != size; i++) {
+                       if (!hud[i])
+                               return i;
+               }
+               return size;
+       }
+
        virtual bool isLocal() const
        { return false; }
        virtual PlayerSAO *getPlayerSAO()
index 12c390893facb134d98c1624a0a8ce19d965af47..ea7f31b137f3dda6aaf93d07215878198aa9d99f 100644 (file)
@@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "debug.h"
 #include "constants.h"
 #include "gettime.h"
+#include "threads.h"
 
 #ifdef _MSC_VER
        #define SWPRINTF_CHARSTRING L"%S"
index 271ad70c1f1947c0b03dfd575b7ce656a1cb592f..e22a865c070bafce51a9e580cd2a7faa479d38a7 100644 (file)
@@ -20,13 +20,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef PROFILER_HEADER
 #define PROFILER_HEADER
 
-#include "irrlichttypes_bloated.h"
+#include "irrlichttypes.h"
 #include <string>
 #include <jmutex.h>
 #include <jmutexautolock.h>
 #include <map>
 #include "util/timetaker.h"
 #include "util/numeric.h" // paging()
+#include "debug.h" // assert()
 
 /*
        Time profiler
index fe1d59d0cac201d57960dd7ea3cfc9165dc34d8d..e110068267dc062089fb396229641a9d76edcea4 100644 (file)
@@ -27,7 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "nodedef.h"
 #include "util/serialize.h"
 #include "util/string.h"
-#include "strfnd.h"
 #include "util/numeric.h"
 #include "inventorymanager.h" // deserializing InventoryLocations
 
index e1a03b95ac994382514d4eb6f977ab496c3ecc17..491c05a1eea3b4033f4aa7c177322260f33d7a45 100644 (file)
@@ -2,8 +2,18 @@ add_subdirectory(common)
 add_subdirectory(cpp_api)
 add_subdirectory(lua_api)
 
-set(SCRIPT_SRCS 
-       ${SCRIPT_COMMON_SRCS}
-       ${SCRIPT_CPP_API_SRCS}
-       ${SCRIPT_LUA_API_SRCS}
+# Used by server and client
+set(common_SCRIPT_SRCS 
+       ${CMAKE_CURRENT_SOURCE_DIR}/scripting_game.cpp
+       ${common_SCRIPT_COMMON_SRCS}
+       ${common_SCRIPT_CPP_API_SRCS}
+       ${common_SCRIPT_LUA_API_SRCS}
+       PARENT_SCOPE)
+
+# Used by client only
+set(minetest_SCRIPT_SRCS 
+       ${CMAKE_CURRENT_SOURCE_DIR}/scripting_mainmenu.cpp
+       ${minetest_SCRIPT_COMMON_SRCS}
+       ${minetest_SCRIPT_CPP_API_SRCS}
+       ${minetest_SCRIPT_LUA_API_SRCS}
        PARENT_SCOPE)
index c8f7ef7836ec2478b35e472d6bddee437efd1cb2..27e2fb4d54909a35f3e900267060df2ea7f10ef8 100644 (file)
@@ -1,6 +1,11 @@
-set(SCRIPT_COMMON_SRCS
+# Used by server and client
+set(common_SCRIPT_COMMON_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/c_content.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/c_converter.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/c_types.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/c_internal.cpp
        PARENT_SCOPE)
+
+# Used by client only
+set(minetest_SCRIPT_COMMON_SRCS
+       PARENT_SCOPE)
index cb2b0e737ae68b96c292de4fd1e16aaa22123552..2e26adb76898082cb0d234f3162ee14ab24068fd 100644 (file)
@@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "server.h"
 #include "log.h"
 #include "tool.h"
-#include "server.h"
+#include "serverobject.h"
 #include "mapgen.h"
 
 struct EnumString es_TileAnimationType[] =
@@ -694,8 +694,7 @@ void push_tool_capabilities(lua_State *L,
 }
 
 /******************************************************************************/
-void push_inventory_list(Inventory *inv, const char *name,
-               lua_State *L)
+void push_inventory_list(lua_State *L, Inventory *inv, const char *name)
 {
        InventoryList *invlist = inv->getList(name);
        if(invlist == NULL){
@@ -709,8 +708,8 @@ void push_inventory_list(Inventory *inv, const char *name,
 }
 
 /******************************************************************************/
-void read_inventory_list(Inventory *inv, const char *name,
-               lua_State *L, int tableindex, Server* srv,int forcesize)
+void read_inventory_list(lua_State *L, int tableindex,
+               Inventory *inv, const char *name, Server* srv, int forcesize)
 {
        if(tableindex < 0)
                tableindex = lua_gettop(L) + 1 + tableindex;
index fc00ce089e915f7c847d250ccd966b6bc5ef14d4..6d1dfe1d5a7d5f34c373ed452fdc2be84e9b1549 100644 (file)
@@ -87,14 +87,13 @@ void               read_object_properties    (lua_State *L,
                                               int index,
                                               ObjectProperties *prop);
 
-//TODO fix parameter oreder!
-void               push_inventory_list       (Inventory *inv,
-                                              const char *name,
-                                              lua_State *L);
-void               read_inventory_list       (Inventory *inv,
-                                              const char *name,
-                                              lua_State *L,
+void               push_inventory_list       (lua_State *L,
+                                              Inventory *inv,
+                                              const char *name);
+void               read_inventory_list       (lua_State *L,
                                               int tableindex,
+                                              Inventory *inv,
+                                              const char *name,
                                               Server* srv,
                                               int forcesize=-1);
 
index 42e9fb3e1e66a02943fd67f3cc4b670148478b45..5c16b88d9d281c8518122f8fd05ed736bef9db6d 100644 (file)
@@ -18,17 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "common/c_internal.h"
-#include "server.h"
-#include "cpp_api/scriptapi.h"
-
-ScriptApi* get_scriptapi(lua_State *L)
-{
-       // Get server from registry
-       lua_getfield(L, LUA_REGISTRYINDEX, "scriptapi");
-       ScriptApi* sapi_ptr = (ScriptApi*) lua_touserdata(L, -1);
-       lua_pop(L, 1);
-       return sapi_ptr;
-}
+#include "debug.h"
 
 std::string script_get_backtrace(lua_State *L)
 {
@@ -51,15 +41,108 @@ std::string script_get_backtrace(lua_State *L)
        return s;
 }
 
-void script_error(lua_State* L,const char *fmt, ...)
+void script_error(lua_State *L, const char *fmt, ...)
 {
        va_list argp;
        va_start(argp, fmt);
        char buf[10000];
        vsnprintf(buf, 10000, fmt, argp);
        va_end(argp);
-       //errorstream<<"SCRIPT ERROR: "<<buf;
        throw LuaError(L, buf);
 }
 
+// Push the list of callbacks (a lua table).
+// Then push nargs arguments.
+// Then call this function, which
+// - runs the callbacks
+// - removes the table and arguments from the lua stack
+// - pushes the return value, computed depending on mode
+void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode)
+{
+       // Insert the return value into the lua stack, below the table
+       assert(lua_gettop(L) >= nargs + 1);
+       lua_pushnil(L);
+       lua_insert(L, -(nargs + 1) - 1);
+       // Stack now looks like this:
+       // ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n>
+
+       int rv = lua_gettop(L) - nargs - 1;
+       int table = rv + 1;
+       int arg = table + 1;
+
+       luaL_checktype(L, table, LUA_TTABLE);
+
+       // Foreach
+       lua_pushnil(L);
+       bool first_loop = true;
+       while(lua_next(L, table) != 0){
+               // key at index -2 and value at index -1
+               luaL_checktype(L, -1, LUA_TFUNCTION);
+               // Call function
+               for(int i = 0; i < nargs; i++)
+                       lua_pushvalue(L, arg+i);
+               if(lua_pcall(L, nargs, 1, 0))
+                       script_error(L, "error: %s", lua_tostring(L, -1));
+
+               // Move return value to designated space in stack
+               // Or pop it
+               if(first_loop){
+                       // Result of first callback is always moved
+                       lua_replace(L, rv);
+                       first_loop = false;
+               } else {
+                       // Otherwise, what happens depends on the mode
+                       if(mode == RUN_CALLBACKS_MODE_FIRST)
+                               lua_pop(L, 1);
+                       else if(mode == RUN_CALLBACKS_MODE_LAST)
+                               lua_replace(L, rv);
+                       else if(mode == RUN_CALLBACKS_MODE_AND ||
+                                       mode == RUN_CALLBACKS_MODE_AND_SC){
+                               if((bool)lua_toboolean(L, rv) == true &&
+                                               (bool)lua_toboolean(L, -1) == false)
+                                       lua_replace(L, rv);
+                               else
+                                       lua_pop(L, 1);
+                       }
+                       else if(mode == RUN_CALLBACKS_MODE_OR ||
+                                       mode == RUN_CALLBACKS_MODE_OR_SC){
+                               if((bool)lua_toboolean(L, rv) == false &&
+                                               (bool)lua_toboolean(L, -1) == true)
+                                       lua_replace(L, rv);
+                               else
+                                       lua_pop(L, 1);
+                       }
+                       else
+                               assert(0);
+               }
+
+               // Handle short circuit modes
+               if(mode == RUN_CALLBACKS_MODE_AND_SC &&
+                               (bool)lua_toboolean(L, rv) == false)
+                       break;
+               else if(mode == RUN_CALLBACKS_MODE_OR_SC &&
+                               (bool)lua_toboolean(L, rv) == true)
+                       break;
+
+               // value removed, keep key for next iteration
+       }
+
+       // Remove stuff from stack, leaving only the return value
+       lua_settop(L, rv);
+
+       // Fix return value in case no callbacks were called
+       if(first_loop){
+               if(mode == RUN_CALLBACKS_MODE_AND ||
+                               mode == RUN_CALLBACKS_MODE_AND_SC){
+                       lua_pop(L, 1);
+                       lua_pushboolean(L, true);
+               }
+               else if(mode == RUN_CALLBACKS_MODE_OR ||
+                               mode == RUN_CALLBACKS_MODE_OR_SC){
+                       lua_pop(L, 1);
+                       lua_pushboolean(L, false);
+               }
+       }
+}
+
 
index dafde5843aa6a3e8670283faaf7acaf8cd033318..9a50b8e960c18db32cd65a97cb9ac02c7f7ef96c 100644 (file)
@@ -27,34 +27,46 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef C_INTERNAL_H_
 #define C_INTERNAL_H_
 
-class Server;
-class ScriptApi;
-#include <iostream>
-
-#include "lua_api/l_base.h"
-
 extern "C" {
-#include "lua.h"
+#include <lua.h>
+#include <lauxlib.h>
 }
 
-#define luamethod(class, name) {#name, class::l_##name}
-#define STACK_TO_SERVER(L) get_scriptapi(L)->getServer()
-#define API_FCT(name) registerFunction(L,#name,l_##name,top)
-
-#define REGISTER_LUA_REF(cln)                                                  \
-class ModApi_##cln : public ModApiBase {                                       \
-       public:                                                                    \
-               ModApi_##cln() : ModApiBase() {};                                      \
-               bool Initialize(lua_State* L, int top) {                               \
-                       cln::Register(L);                                                  \
-                       return true;                                                       \
-               };                                                                     \
-};                                                                             \
-ModApi_##cln macro_generated_prototype__##cln;
+#include "common/c_types.h"
 
+// What script_run_callbacks does with the return values of callbacks.
+// Regardless of the mode, if only one callback is defined,
+// its return value is the total return value.
+// Modes only affect the case where 0 or >= 2 callbacks are defined.
+enum RunCallbacksMode
+{
+       // Returns the return value of the first callback
+       // Returns nil if list of callbacks is empty
+       RUN_CALLBACKS_MODE_FIRST,
+       // Returns the return value of the last callback
+       // Returns nil if list of callbacks is empty
+       RUN_CALLBACKS_MODE_LAST,
+       // If any callback returns a false value, the first such is returned
+       // Otherwise, the first callback's return value (trueish) is returned
+       // Returns true if list of callbacks is empty
+       RUN_CALLBACKS_MODE_AND,
+       // Like above, but stops calling callbacks (short circuit)
+       // after seeing the first false value
+       RUN_CALLBACKS_MODE_AND_SC,
+       // If any callback returns a true value, the first such is returned
+       // Otherwise, the first callback's return value (falseish) is returned
+       // Returns false if list of callbacks is empty
+       RUN_CALLBACKS_MODE_OR,
+       // Like above, but stops calling callbacks (short circuit)
+       // after seeing the first true value
+       RUN_CALLBACKS_MODE_OR_SC,
+       // Note: "a true value" and "a false value" refer to values that
+       // are converted by lua_toboolean to true or false, respectively.
+};
 
-ScriptApi*  get_scriptapi          (lua_State *L);
 std::string script_get_backtrace   (lua_State *L);
 void        script_error           (lua_State *L, const char *fmt, ...);
+void        script_run_callbacks   (lua_State *L, int nargs,
+                                    RunCallbacksMode mode);
 
 #endif /* C_INTERNAL_H_ */
index 7df869432553df24781e7e0476451c114a24ccc8..bc9f1cb9671d7b8916c20b69678f37324bb3f469 100644 (file)
@@ -50,26 +50,6 @@ public:
        }
 };
 
-class ModNameStorer
-{
-private:
-       lua_State *L;
-public:
-       ModNameStorer(lua_State *L_, const std::string modname):
-               L(L_)
-       {
-               // Store current modname in registry
-               lua_pushstring(L, modname.c_str());
-               lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
-       }
-       ~ModNameStorer()
-       {
-               // Clear current modname in registry
-               lua_pushnil(L);
-               lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
-       }
-};
-
 class LuaError : public std::exception
 {
 public:
index 6f5b51a4952c8095870c4137da0d6364008785c8..b753eda17ecb16467815d8a8e226c5374459df73 100644 (file)
@@ -1,4 +1,5 @@
-set(SCRIPT_CPP_API_SRCS
+# Used by server and client
+set(common_SCRIPT_CPP_API_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/s_base.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/s_entity.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/s_env.cpp
@@ -7,5 +8,10 @@ set(SCRIPT_CPP_API_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/s_node.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/s_nodemeta.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/s_player.cpp
-       ${CMAKE_CURRENT_SOURCE_DIR}/scriptapi.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/s_server.cpp
+       PARENT_SCOPE)
+
+# Used by client only
+set(minetest_SCRIPT_CPP_API_SRCS
+       ${CMAKE_CURRENT_SOURCE_DIR}/s_mainmenu.cpp
        PARENT_SCOPE)
index e2e586357e22d179919e8d17a741e49983f5e39f..e26d54ba71302a47cd4d3c49ba787c9e41843199 100644 (file)
@@ -17,30 +17,141 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
+#include "cpp_api/s_base.h"
+#include "cpp_api/s_internal.h"
+#include "lua_api/l_object.h"
+#include "serverobject.h"
+#include "debug.h"
+#include "log.h"
+#include "mods.h"
+#include "util/string.h"
+
+
+extern "C" {
+#include "lualib.h"
+}
+
 #include <stdio.h>
 #include <cstdarg>
 
-extern "C" {
-#include "lua.h"
-#include "lauxlib.h"
+
+class ModNameStorer
+{
+private:
+       lua_State *L;
+public:
+       ModNameStorer(lua_State *L_, const std::string modname):
+               L(L_)
+       {
+               // Store current modname in registry
+               lua_pushstring(L, modname.c_str());
+               lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
+       }
+       ~ModNameStorer()
+       {
+               // Clear current modname in registry
+               lua_pushnil(L);
+               lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
+       }
+};
+
+static int loadScript_ErrorHandler(lua_State *L) {
+       lua_getfield(L, LUA_GLOBALSINDEX, "debug");
+       if (!lua_istable(L, -1)) {
+               lua_pop(L, 1);
+               return 1;
+       }
+       lua_getfield(L, -1, "traceback");
+       if (!lua_isfunction(L, -1)) {
+               lua_pop(L, 2);
+               return 1;
+       }
+       lua_pushvalue(L, 1);
+       lua_pushinteger(L, 2);
+       lua_call(L, 2, 1);
+       return 1;
 }
 
-#include "cpp_api/s_base.h"
-#include "lua_api/l_object.h"
-#include "serverobject.h"
 
-ScriptApiBase::ScriptApiBase() :
-               m_luastackmutex(),
-#ifdef LOCK_DEBUG
-               m_locked(false),
-#endif
-               m_luastack(0),
-               m_server(0),
-               m_environment(0)
+/*
+       ScriptApiBase
+*/
+
+ScriptApiBase::ScriptApiBase()
 {
+       m_luastackmutex.Init();
+
+       #ifdef SCRIPTAPI_LOCK_DEBUG
+       m_locked = false;
+       #endif
 
+       m_luastack = luaL_newstate();
+       assert(m_luastack);
+
+       // Make the ScriptApiBase* accessible to ModApiBase
+       lua_pushlightuserdata(m_luastack, this);
+       lua_setfield(m_luastack, LUA_REGISTRYINDEX, "scriptapi");
+
+       m_server = 0;
+       m_environment = 0;
+       m_guiengine = 0;
 }
 
+ScriptApiBase::~ScriptApiBase()
+{
+       lua_close(m_luastack);
+}
+
+bool ScriptApiBase::loadMod(const std::string &scriptpath,
+               const std::string &modname)
+{
+       ModNameStorer modnamestorer(getStack(), modname);
+
+       if(!string_allowed(modname, MODNAME_ALLOWED_CHARS)){
+               errorstream<<"Error loading mod \""<<modname
+                               <<"\": modname does not follow naming conventions: "
+                               <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
+               return false;
+       }
+
+       bool success = false;
+
+       try{
+               success = loadScript(scriptpath);
+       }
+       catch(LuaError &e){
+               errorstream<<"Error loading mod \""<<modname
+                               <<"\": "<<e.what()<<std::endl;
+       }
+
+       return success;
+}
+
+bool ScriptApiBase::loadScript(const std::string &scriptpath)
+{
+       verbosestream<<"Loading and running script from "<<scriptpath<<std::endl;
+
+       lua_State *L = getStack();
+
+       lua_pushcfunction(L, loadScript_ErrorHandler);
+       int errorhandler = lua_gettop(L);
+
+       int ret = luaL_loadfile(L, scriptpath.c_str()) || lua_pcall(L, 0, 0, errorhandler);
+       if(ret){
+               errorstream<<"========== ERROR FROM LUA ==========="<<std::endl;
+               errorstream<<"Failed to load and run script from "<<std::endl;
+               errorstream<<scriptpath<<":"<<std::endl;
+               errorstream<<std::endl;
+               errorstream<<lua_tostring(L, -1)<<std::endl;
+               errorstream<<std::endl;
+               errorstream<<"=======END OF ERROR FROM LUA ========"<<std::endl;
+               lua_pop(L, 1); // Pop error message from stack
+               lua_pop(L, 1); // Pop the error handler from stack
+               return false;
+       }
+       lua_pop(L, 1); // Pop the error handler from stack
+       return true;
+}
 
 void ScriptApiBase::realityCheck()
 {
@@ -52,7 +163,7 @@ void ScriptApiBase::realityCheck()
        }
 }
 
-void  ScriptApiBase::scriptError(const char *fmt, ...)
+void ScriptApiBase::scriptError(const char *fmt, ...)
 {
        va_list argp;
        va_start(argp, fmt);
@@ -65,130 +176,34 @@ void  ScriptApiBase::scriptError(const char *fmt, ...)
 
 void ScriptApiBase::stackDump(std::ostream &o)
 {
-  int i;
-  int top = lua_gettop(m_luastack);
-  for (i = 1; i <= top; i++) {  /* repeat for each level */
-       int t = lua_type(m_luastack, i);
-       switch (t) {
-
-         case LUA_TSTRING:  /* strings */
-               o<<"\""<<lua_tostring(m_luastack, i)<<"\"";
-               break;
-
-         case LUA_TBOOLEAN:  /* booleans */
-               o<<(lua_toboolean(m_luastack, i) ? "true" : "false");
-               break;
-
-         case LUA_TNUMBER:  /* numbers */ {
-               char buf[10];
-               snprintf(buf, 10, "%g", lua_tonumber(m_luastack, i));
-               o<<buf;
-               break; }
-
-         default:  /* other values */
-               o<<lua_typename(m_luastack, t);
-               break;
-
-       }
-       o<<" ";
-  }
-  o<<std::endl;
-}
-
-// Push the list of callbacks (a lua table).
-// Then push nargs arguments.
-// Then call this function, which
-// - runs the callbacks
-// - removes the table and arguments from the lua stack
-// - pushes the return value, computed depending on mode
-void ScriptApiBase::runCallbacks(int nargs,RunCallbacksMode mode)
-{
-       lua_State *L = getStack();
-
-       // Insert the return value into the lua stack, below the table
-       assert(lua_gettop(L) >= nargs + 1);
-       lua_pushnil(L);
-       lua_insert(L, -(nargs + 1) - 1);
-       // Stack now looks like this:
-       // ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n>
+       int i;
+       int top = lua_gettop(m_luastack);
+       for (i = 1; i <= top; i++) {  /* repeat for each level */
+               int t = lua_type(m_luastack, i);
+               switch (t) {
 
-       int rv = lua_gettop(L) - nargs - 1;
-       int table = rv + 1;
-       int arg = table + 1;
+                       case LUA_TSTRING:  /* strings */
+                               o<<"\""<<lua_tostring(m_luastack, i)<<"\"";
+                               break;
 
-       luaL_checktype(L, table, LUA_TTABLE);
+                       case LUA_TBOOLEAN:  /* booleans */
+                               o<<(lua_toboolean(m_luastack, i) ? "true" : "false");
+                               break;
 
-       // Foreach
-       lua_pushnil(L);
-       bool first_loop = true;
-       while(lua_next(L, table) != 0){
-               // key at index -2 and value at index -1
-               luaL_checktype(L, -1, LUA_TFUNCTION);
-               // Call function
-               for(int i = 0; i < nargs; i++)
-                       lua_pushvalue(L, arg+i);
-               if(lua_pcall(L, nargs, 1, 0))
-                       scriptError("error: %s", lua_tostring(L, -1));
-
-               // Move return value to designated space in stack
-               // Or pop it
-               if(first_loop){
-                       // Result of first callback is always moved
-                       lua_replace(L, rv);
-                       first_loop = false;
-               } else {
-                       // Otherwise, what happens depends on the mode
-                       if(mode == RUN_CALLBACKS_MODE_FIRST)
-                               lua_pop(L, 1);
-                       else if(mode == RUN_CALLBACKS_MODE_LAST)
-                               lua_replace(L, rv);
-                       else if(mode == RUN_CALLBACKS_MODE_AND ||
-                                       mode == RUN_CALLBACKS_MODE_AND_SC){
-                               if((bool)lua_toboolean(L, rv) == true &&
-                                               (bool)lua_toboolean(L, -1) == false)
-                                       lua_replace(L, rv);
-                               else
-                                       lua_pop(L, 1);
-                       }
-                       else if(mode == RUN_CALLBACKS_MODE_OR ||
-                                       mode == RUN_CALLBACKS_MODE_OR_SC){
-                               if((bool)lua_toboolean(L, rv) == false &&
-                                               (bool)lua_toboolean(L, -1) == true)
-                                       lua_replace(L, rv);
-                               else
-                                       lua_pop(L, 1);
-                       }
-                       else
-                               assert(0);
-               }
+                       case LUA_TNUMBER:  /* numbers */ {
+                               char buf[10];
+                               snprintf(buf, 10, "%g", lua_tonumber(m_luastack, i));
+                               o<<buf;
+                               break; }
 
-               // Handle short circuit modes
-               if(mode == RUN_CALLBACKS_MODE_AND_SC &&
-                               (bool)lua_toboolean(L, rv) == false)
-                       break;
-               else if(mode == RUN_CALLBACKS_MODE_OR_SC &&
-                               (bool)lua_toboolean(L, rv) == true)
-                       break;
+                       default:  /* other values */
+                               o<<lua_typename(m_luastack, t);
+                               break;
 
-               // value removed, keep key for next iteration
-       }
-
-       // Remove stuff from stack, leaving only the return value
-       lua_settop(L, rv);
-
-       // Fix return value in case no callbacks were called
-       if(first_loop){
-               if(mode == RUN_CALLBACKS_MODE_AND ||
-                               mode == RUN_CALLBACKS_MODE_AND_SC){
-                       lua_pop(L, 1);
-                       lua_pushboolean(L, true);
-               }
-               else if(mode == RUN_CALLBACKS_MODE_OR ||
-                               mode == RUN_CALLBACKS_MODE_OR_SC){
-                       lua_pop(L, 1);
-                       lua_pushboolean(L, false);
                }
+               o<<" ";
        }
+       o<<std::endl;
 }
 
 void ScriptApiBase::addObjectReference(ServerActiveObject *cobj)
index 8799d3c0021e5e15e7f6d8b57898ba80ab985dc3..3cb59634b01f2b576ea1d8d44667c40899e58a4f 100644 (file)
@@ -21,67 +21,37 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define S_BASE_H_
 
 #include <iostream>
+#include <string>
+
+extern "C" {
+#include <lua.h>
+}
 
 #include "irrlichttypes.h"
 #include "jmutex.h"
 #include "jmutexautolock.h"
 #include "common/c_types.h"
-#include "debug.h"
 
-#define LOCK_DEBUG
+#define SCRIPTAPI_LOCK_DEBUG
 
 class Server;
 class Environment;
+class GUIEngine;
 class ServerActiveObject;
-class LuaABM;
-class InvRef;
-class ModApiBase;
-class ModApiEnvMod;
-class ObjectRef;
-class NodeMetaRef;
-
-
-/* definitions */
-// What scriptapi_run_callbacks does with the return values of callbacks.
-// Regardless of the mode, if only one callback is defined,
-// its return value is the total return value.
-// Modes only affect the case where 0 or >= 2 callbacks are defined.
-enum RunCallbacksMode
-{
-       // Returns the return value of the first callback
-       // Returns nil if list of callbacks is empty
-       RUN_CALLBACKS_MODE_FIRST,
-       // Returns the return value of the last callback
-       // Returns nil if list of callbacks is empty
-       RUN_CALLBACKS_MODE_LAST,
-       // If any callback returns a false value, the first such is returned
-       // Otherwise, the first callback's return value (trueish) is returned
-       // Returns true if list of callbacks is empty
-       RUN_CALLBACKS_MODE_AND,
-       // Like above, but stops calling callbacks (short circuit)
-       // after seeing the first false value
-       RUN_CALLBACKS_MODE_AND_SC,
-       // If any callback returns a true value, the first such is returned
-       // Otherwise, the first callback's return value (falseish) is returned
-       // Returns false if list of callbacks is empty
-       RUN_CALLBACKS_MODE_OR,
-       // Like above, but stops calling callbacks (short circuit)
-       // after seeing the first true value
-       RUN_CALLBACKS_MODE_OR_SC,
-       // Note: "a true value" and "a false value" refer to values that
-       // are converted by lua_toboolean to true or false, respectively.
-};
-
 
 class ScriptApiBase {
 public:
 
+       ScriptApiBase();
+       virtual ~ScriptApiBase();
+
+       bool loadMod(const std::string &scriptpath, const std::string &modname);
+       bool loadScript(const std::string &scriptpath);
+
        /* object */
        void addObjectReference(ServerActiveObject *cobj);
        void removeObjectReference(ServerActiveObject *cobj);
 
-       ScriptApiBase();
-
 protected:
        friend class LuaABM;
        friend class InvRef;
@@ -91,78 +61,35 @@ protected:
        friend class ModApiEnvMod;
        friend class LuaVoxelManip;
 
-
-       inline lua_State* getStack()
+       lua_State* getStack()
                { return m_luastack; }
 
-       bool setStack(lua_State* stack) {
-               if (m_luastack == 0) {
-                       m_luastack = stack;
-                       return true;
-               }
-               return false;
-       }
-
        void realityCheck();
        void scriptError(const char *fmt, ...);
        void stackDump(std::ostream &o);
-       void runCallbacks(int nargs,RunCallbacksMode mode);
 
-       inline Server* getServer() { return m_server; }
+       Server* getServer() { return m_server; }
        void setServer(Server* server) { m_server = server; }
 
        Environment* getEnv() { return m_environment; }
        void setEnv(Environment* env) { m_environment = env; }
 
+       GUIEngine* getGuiEngine() { return m_guiengine; }
+       void setGuiEngine(GUIEngine* guiengine) { m_guiengine = guiengine; }
+
        void objectrefGetOrCreate(ServerActiveObject *cobj);
        void objectrefGet(u16 id);
 
-       JMutex                  m_luastackmutex;
-#ifdef LOCK_DEBUG
+       JMutex          m_luastackmutex;
+#ifdef SCRIPTAPI_LOCK_DEBUG
        bool            m_locked;
 #endif
 private:
        lua_State*      m_luastack;
 
-       Server*                 m_server;
-       Environment*    m_environment;
-
-
-};
-
-#ifdef LOCK_DEBUG
-class LockChecker {
-public:
-       LockChecker(bool* variable) {
-               assert(*variable == false);
-
-               m_variable = variable;
-               *m_variable = true;
-       }
-       ~LockChecker() {
-               *m_variable = false;
-       }
-private:
-bool* m_variable;
+       Server*         m_server;
+       Environment*    m_environment;
+       GUIEngine*      m_guiengine;
 };
 
-#define LOCK_CHECK LockChecker(&(this->m_locked))
-#else
-#define LOCK_CHECK while(0)
-#endif
-
-#define LUA_STACK_AUTOLOCK JMutexAutoLock(this->m_luastackmutex)
-
-#define SCRIPTAPI_PRECHECKHEADER                                               \
-               LUA_STACK_AUTOLOCK;                                                    \
-               LOCK_CHECK;                                                            \
-               realityCheck();                                                        \
-               lua_State *L = getStack();                                             \
-               assert(lua_checkstack(L, 20));                                         \
-               StackUnroller stack_unroller(L);
-
-#define PLAYER_TO_SA(p)   p->getEnv()->getScriptIface()
-#define ENV_TO_SA(env)    env->getScriptIface()
-#define SERVER_TO_SA(srv) srv->getScriptIface()
-
 #endif /* S_BASE_H_ */
index c494e8232e96e22505e784e835e6271c1390dce9..cefa27cb18eef653ea6662e25f4a494042ada11e 100644 (file)
@@ -18,15 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "cpp_api/s_entity.h"
+#include "cpp_api/s_internal.h"
 #include "log.h"
 #include "object_properties.h"
 #include "common/c_converter.h"
 #include "common/c_content.h"
 
-extern "C" {
-#include "lauxlib.h"
-}
-
 bool ScriptApiEntity::luaentity_Add(u16 id, const char *name)
 {
        SCRIPTAPI_PRECHECKHEADER
index 632b28f458c5e455e4ab49b6bb6fc65550bf9954..ef3a1dddf77cca3df4b9bcc11824088671207cf6 100644 (file)
@@ -18,16 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "cpp_api/s_env.h"
+#include "cpp_api/s_internal.h"
 #include "common/c_converter.h"
 #include "log.h"
 #include "environment.h"
 #include "mapgen.h"
 #include "lua_api/l_env.h"
 
-extern "C" {
-#include "lauxlib.h"
-}
-
 void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp,
                u32 blockseed)
 {
@@ -40,7 +37,7 @@ void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp,
        push_v3s16(L, minp);
        push_v3s16(L, maxp);
        lua_pushnumber(L, blockseed);
-       runCallbacks(3, RUN_CALLBACKS_MODE_FIRST);
+       script_run_callbacks(L, 3, RUN_CALLBACKS_MODE_FIRST);
 }
 
 void ScriptApiEnv::environment_Step(float dtime)
@@ -53,7 +50,7 @@ void ScriptApiEnv::environment_Step(float dtime)
        lua_getfield(L, -1, "registered_globalsteps");
        // Call callbacks
        lua_pushnumber(L, dtime);
-       runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
+       script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
 }
 
 void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams)
@@ -80,7 +77,7 @@ void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams)
        lua_pushstring(L, flagstr.c_str());
        lua_setfield(L, -2, "flags");
        
-       runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
+       script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
 }
 
 void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
diff --git a/src/script/cpp_api/s_internal.h b/src/script/cpp_api/s_internal.h
new file mode 100644 (file)
index 0000000..10ee1a7
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+/******************************************************************************/
+/******************************************************************************/
+/* WARNING!!!! do NOT add this header in any include file or any code file    */
+/*             not being a modapi file!!!!!!!!                                */
+/******************************************************************************/
+/******************************************************************************/
+
+#ifndef S_INTERNAL_H_
+#define S_INTERNAL_H_
+
+#include "common/c_internal.h"
+#include "cpp_api/s_base.h"
+
+#ifdef SCRIPTAPI_LOCK_DEBUG
+#include "debug.h" // assert()
+class LockChecker {
+public:
+       LockChecker(bool* variable) {
+               assert(*variable == false);
+
+               m_variable = variable;
+               *m_variable = true;
+       }
+       ~LockChecker() {
+               *m_variable = false;
+       }
+private:
+bool* m_variable;
+};
+
+#define SCRIPTAPI_LOCK_CHECK LockChecker(&(this->m_locked))
+#else
+#define SCRIPTAPI_LOCK_CHECK while(0)
+#endif
+
+#define SCRIPTAPI_PRECHECKHEADER                                               \
+               JMutexAutoLock(this->m_luastackmutex);                                 \
+               SCRIPTAPI_LOCK_CHECK;                                                  \
+               realityCheck();                                                        \
+               lua_State *L = getStack();                                             \
+               assert(lua_checkstack(L, 20));                                         \
+               StackUnroller stack_unroller(L);
+
+#endif /* S_INTERNAL_H_ */
index 2402d198c1ca6a5d6c2c73c42d16bec98a83c511..09f26d80caceb92c6a47eadd7f3a1db64d025d87 100644 (file)
@@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "cpp_api/s_inventory.h"
+#include "cpp_api/s_internal.h"
 #include "inventorymanager.h"
 #include "lua_api/l_inventory.h"
 #include "lua_api/l_item.h"
index 6937ebbebf21529c8c57e98fe6bc167228e1d9c4..b4536ac63b95b49184a5096abb31e000b6637a7d 100644 (file)
@@ -18,10 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "cpp_api/s_item.h"
+#include "cpp_api/s_internal.h"
 #include "common/c_converter.h"
 #include "common/c_content.h"
 #include "lua_api/l_item.h"
 #include "server.h"
+#include "log.h"
+#include "util/pointedthing.h"
 
 bool ScriptApiItem::item_OnDrop(ItemStack &item,
                ServerActiveObject *dropper, v3f pos)
diff --git a/src/script/cpp_api/s_mainmenu.cpp b/src/script/cpp_api/s_mainmenu.cpp
new file mode 100644 (file)
index 0000000..af92c59
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "cpp_api/s_mainmenu.h"
+#include "cpp_api/s_internal.h"
+#include "common/c_converter.h"
+
+void ScriptApiMainMenu::setMainMenuErrorMessage(std::string errormessage)
+{
+       SCRIPTAPI_PRECHECKHEADER
+
+       lua_getglobal(L, "gamedata");
+       int gamedata_idx = lua_gettop(L);
+       lua_pushstring(L, "errormessage");
+       lua_pushstring(L, errormessage.c_str());
+       lua_settable(L, gamedata_idx);
+       lua_pop(L, 1);
+}
+
+void ScriptApiMainMenu::handleMainMenuEvent(std::string text)
+{
+       SCRIPTAPI_PRECHECKHEADER
+
+       // Get handler function
+       lua_getglobal(L, "engine");
+       lua_getfield(L, -1, "event_handler");
+       if(lua_isnil(L, -1))
+               return;
+       luaL_checktype(L, -1, LUA_TFUNCTION);
+
+       // Call it
+       lua_pushstring(L, text.c_str());
+       if(lua_pcall(L, 1, 0, 0))
+               scriptError("error running function engine.event_handler: %s\n",
+                               lua_tostring(L, -1));
+}
+
+void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> fields)
+{
+       SCRIPTAPI_PRECHECKHEADER
+
+       // Get handler function
+       lua_getglobal(L, "engine");
+       lua_getfield(L, -1, "button_handler");
+       if(lua_isnil(L, -1))
+               return;
+       luaL_checktype(L, -1, LUA_TFUNCTION);
+
+       // Convert fields to lua table
+       lua_newtable(L);
+       for(std::map<std::string, std::string>::const_iterator
+               i = fields.begin(); i != fields.end(); i++){
+               const std::string &name = i->first;
+               const std::string &value = i->second;
+               lua_pushstring(L, name.c_str());
+               lua_pushlstring(L, value.c_str(), value.size());
+               lua_settable(L, -3);
+       }
+
+       // Call it
+       if(lua_pcall(L, 1, 0, 0))
+               scriptError("error running function engine.button_handler: %s\n",
+                               lua_tostring(L, -1));
+}
diff --git a/src/script/cpp_api/s_mainmenu.h b/src/script/cpp_api/s_mainmenu.h
new file mode 100644 (file)
index 0000000..53dcd37
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef S_MAINMENU_H_
+#define S_MAINMENU_H_
+
+#include "cpp_api/s_base.h"
+#include <map>
+
+class ScriptApiMainMenu
+               : virtual public ScriptApiBase
+{
+public:
+       /**
+        * set gamedata.errormessage to inform lua of an error
+        * @param errormessage the error message
+        */
+       void setMainMenuErrorMessage(std::string errormessage);
+
+       /**
+        * process events received from formspec
+        * @param text events in textual form
+        */
+       void handleMainMenuEvent(std::string text);
+
+       /**
+        * process field data recieved from formspec
+        * @param fields data in field format
+        */
+       void handleMainMenuButtons(std::map<std::string, std::string> fields);
+};
+
+#endif /* S_MAINMENU_H_ */
index d0b0583c03eb71d85f7c2c072e45e885824e8fd7..92fd00a7477f68e5a74390faa3bc5fae90be488f 100644 (file)
@@ -18,10 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "cpp_api/s_node.h"
+#include "cpp_api/s_internal.h"
 #include "common/c_converter.h"
 #include "common/c_content.h"
 #include "nodedef.h"
 #include "server.h"
+#include "environment.h"
 
 
 struct EnumString ScriptApiNode::es_DrawType[] =
index 56cea8e5f99d35a3b18ce72dee46d00544f2c767..e87464c612a51d2857bac6e0d4570899bef36e39 100644 (file)
@@ -18,16 +18,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "cpp_api/s_nodemeta.h"
+#include "cpp_api/s_internal.h"
 #include "common/c_converter.h"
 #include "nodedef.h"
 #include "mapnode.h"
 #include "server.h"
+#include "environment.h"
 #include "lua_api/l_item.h"
 
-extern "C" {
-#include "lauxlib.h"
-}
-
 // Return number of accepted items to be moved
 int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
                const std::string &from_list, int from_index,
index 0dbd52527ad58ea3a652c94092324969f1c4f732..215a34d534578dfcb8bd6d4f677a40739e3148eb 100644 (file)
@@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "cpp_api/s_player.h"
+#include "cpp_api/s_internal.h"
 
 void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
 {
@@ -28,7 +29,7 @@ void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
        lua_getfield(L, -1, "registered_on_newplayers");
        // Call callbacks
        objectrefGetOrCreate(player);
-       runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
+       script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
 }
 
 void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player)
@@ -40,7 +41,7 @@ void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player)
        lua_getfield(L, -1, "registered_on_dieplayers");
        // Call callbacks
        objectrefGetOrCreate(player);
-       runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
+       script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
 }
 
 bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
@@ -52,7 +53,7 @@ bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
        lua_getfield(L, -1, "registered_on_respawnplayers");
        // Call callbacks
        objectrefGetOrCreate(player);
-       runCallbacks(1, RUN_CALLBACKS_MODE_OR);
+       script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_OR);
        bool positioning_handled_by_some = lua_toboolean(L, -1);
        return positioning_handled_by_some;
 }
@@ -66,7 +67,7 @@ void ScriptApiPlayer::on_joinplayer(ServerActiveObject *player)
        lua_getfield(L, -1, "registered_on_joinplayers");
        // Call callbacks
        objectrefGetOrCreate(player);
-       runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
+       script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
 }
 
 void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player)
@@ -78,7 +79,7 @@ void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player)
        lua_getfield(L, -1, "registered_on_leaveplayers");
        // Call callbacks
        objectrefGetOrCreate(player);
-       runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
+       script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
 }
 
 void ScriptApiPlayer::on_cheat(ServerActiveObject *player,
@@ -94,7 +95,7 @@ void ScriptApiPlayer::on_cheat(ServerActiveObject *player,
        lua_newtable(L);
        lua_pushlstring(L, cheat_type.c_str(), cheat_type.size());
        lua_setfield(L, -2, "type");
-       runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
+       script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_FIRST);
 }
 
 void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player,
@@ -121,7 +122,7 @@ void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player,
                lua_pushlstring(L, value.c_str(), value.size());
                lua_settable(L, -3);
        }
-       runCallbacks(3, RUN_CALLBACKS_MODE_OR_SC);
+       script_run_callbacks(L, 3, RUN_CALLBACKS_MODE_OR_SC);
 }
 ScriptApiPlayer::~ScriptApiPlayer() {
 }
index c0409a481e7f45130a4c37425349c46e1d2adcfa..88221f4869431a62635e9424ae6eb212c09a2217 100644 (file)
@@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef S_PLAYER_H_
 #define S_PLAYER_H_
 
+#include <map>
+
 #include "cpp_api/s_base.h"
 
 
diff --git a/src/script/cpp_api/s_server.cpp b/src/script/cpp_api/s_server.cpp
new file mode 100644 (file)
index 0000000..d41805b
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "cpp_api/s_server.h"
+#include "cpp_api/s_internal.h"
+#include "common/c_converter.h"
+
+bool ScriptApiServer::getAuth(const std::string &playername,
+               std::string *dst_password,
+               std::set<std::string> *dst_privs)
+{
+       SCRIPTAPI_PRECHECKHEADER
+
+       getAuthHandler();
+       lua_getfield(L, -1, "get_auth");
+       if(lua_type(L, -1) != LUA_TFUNCTION)
+               throw LuaError(L, "Authentication handler missing get_auth");
+       lua_pushstring(L, playername.c_str());
+       if(lua_pcall(L, 1, 1, 0))
+               scriptError("error: %s", lua_tostring(L, -1));
+
+       // nil = login not allowed
+       if(lua_isnil(L, -1))
+               return false;
+       luaL_checktype(L, -1, LUA_TTABLE);
+
+       std::string password;
+       bool found = getstringfield(L, -1, "password", password);
+       if(!found)
+               throw LuaError(L, "Authentication handler didn't return password");
+       if(dst_password)
+               *dst_password = password;
+
+       lua_getfield(L, -1, "privileges");
+       if(!lua_istable(L, -1))
+               throw LuaError(L,
+                               "Authentication handler didn't return privilege table");
+       if(dst_privs)
+               readPrivileges(-1, *dst_privs);
+       lua_pop(L, 1);
+
+       return true;
+}
+
+void ScriptApiServer::getAuthHandler()
+{
+       lua_State *L = getStack();
+
+       lua_getglobal(L, "minetest");
+       lua_getfield(L, -1, "registered_auth_handler");
+       if(lua_isnil(L, -1)){
+               lua_pop(L, 1);
+               lua_getfield(L, -1, "builtin_auth_handler");
+       }
+       if(lua_type(L, -1) != LUA_TTABLE)
+               throw LuaError(L, "Authentication handler table not valid");
+}
+
+void ScriptApiServer::readPrivileges(int index, std::set<std::string> &result)
+{
+       lua_State *L = getStack();
+
+       result.clear();
+       lua_pushnil(L);
+       if(index < 0)
+               index -= 1;
+       while(lua_next(L, index) != 0){
+               // key at index -2 and value at index -1
+               std::string key = luaL_checkstring(L, -2);
+               bool value = lua_toboolean(L, -1);
+               if(value)
+                       result.insert(key);
+               // removes value, keeps key for next iteration
+               lua_pop(L, 1);
+       }
+}
+
+void ScriptApiServer::createAuth(const std::string &playername,
+               const std::string &password)
+{
+       SCRIPTAPI_PRECHECKHEADER
+
+       getAuthHandler();
+       lua_getfield(L, -1, "create_auth");
+       if(lua_type(L, -1) != LUA_TFUNCTION)
+               throw LuaError(L, "Authentication handler missing create_auth");
+       lua_pushstring(L, playername.c_str());
+       lua_pushstring(L, password.c_str());
+       if(lua_pcall(L, 2, 0, 0))
+               scriptError("error: %s", lua_tostring(L, -1));
+}
+
+bool ScriptApiServer::setPassword(const std::string &playername,
+               const std::string &password)
+{
+       SCRIPTAPI_PRECHECKHEADER
+
+       getAuthHandler();
+       lua_getfield(L, -1, "set_password");
+       if(lua_type(L, -1) != LUA_TFUNCTION)
+               throw LuaError(L, "Authentication handler missing set_password");
+       lua_pushstring(L, playername.c_str());
+       lua_pushstring(L, password.c_str());
+       if(lua_pcall(L, 2, 1, 0))
+               scriptError("error: %s", lua_tostring(L, -1));
+       return lua_toboolean(L, -1);
+}
+
+bool ScriptApiServer::on_chat_message(const std::string &name,
+               const std::string &message)
+{
+       SCRIPTAPI_PRECHECKHEADER
+
+       // Get minetest.registered_on_chat_messages
+       lua_getglobal(L, "minetest");
+       lua_getfield(L, -1, "registered_on_chat_messages");
+       // Call callbacks
+       lua_pushstring(L, name.c_str());
+       lua_pushstring(L, message.c_str());
+       script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_OR_SC);
+       bool ate = lua_toboolean(L, -1);
+       return ate;
+}
+
+void ScriptApiServer::on_shutdown()
+{
+       SCRIPTAPI_PRECHECKHEADER
+
+       // Get registered shutdown hooks
+       lua_getglobal(L, "minetest");
+       lua_getfield(L, -1, "registered_on_shutdown");
+       // Call callbacks
+       script_run_callbacks(L, 0, RUN_CALLBACKS_MODE_FIRST);
+}
+
diff --git a/src/script/cpp_api/s_server.h b/src/script/cpp_api/s_server.h
new file mode 100644 (file)
index 0000000..a63e363
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef S_SERVER_H_
+#define S_SERVER_H_
+
+#include "cpp_api/s_base.h"
+#include <set>
+
+class ScriptApiServer
+               : virtual public ScriptApiBase
+{
+public:
+       // Calls on_chat_message handlers
+       // Returns true if script handled message
+       bool on_chat_message(const std::string &name, const std::string &message);
+
+       // Calls on_shutdown handlers
+       void on_shutdown();
+
+       /* auth */
+       bool getAuth(const std::string &playername,
+                       std::string *dst_password,
+                       std::set<std::string> *dst_privs);
+       void createAuth(const std::string &playername,
+                       const std::string &password);
+       bool setPassword(const std::string &playername,
+                       const std::string &password);
+private:
+       void getAuthHandler();
+       void readPrivileges(int index, std::set<std::string> &result);
+};
+
+
+
+#endif /* S_SERVER_H_ */
diff --git a/src/script/cpp_api/scriptapi.cpp b/src/script/cpp_api/scriptapi.cpp
deleted file mode 100644 (file)
index b6d376b..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
-Minetest
-Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-extern "C" {
-#include "lua.h"
-#include "lauxlib.h"
-#include "lualib.h"
-}
-
-
-#include "scriptapi.h"
-#include "common/c_converter.h"
-#include "lua_api/l_base.h"
-#include "log.h"
-#include "mods.h"
-
-int script_ErrorHandler(lua_State *L) {
-       lua_getfield(L, LUA_GLOBALSINDEX, "debug");
-       if (!lua_istable(L, -1)) {
-               lua_pop(L, 1);
-               return 1;
-       }
-       lua_getfield(L, -1, "traceback");
-       if (!lua_isfunction(L, -1)) {
-               lua_pop(L, 2);
-               return 1;
-       }
-       lua_pushvalue(L, 1);
-       lua_pushinteger(L, 2);
-       lua_call(L, 2, 1);
-       return 1;
-}
-
-
-bool ScriptApi::getAuth(const std::string &playername,
-               std::string *dst_password, std::set<std::string> *dst_privs)
-{
-       SCRIPTAPI_PRECHECKHEADER
-
-       getAuthHandler();
-       lua_getfield(L, -1, "get_auth");
-       if(lua_type(L, -1) != LUA_TFUNCTION)
-               throw LuaError(L, "Authentication handler missing get_auth");
-       lua_pushstring(L, playername.c_str());
-       if(lua_pcall(L, 1, 1, 0))
-               scriptError("error: %s", lua_tostring(L, -1));
-
-       // nil = login not allowed
-       if(lua_isnil(L, -1))
-               return false;
-       luaL_checktype(L, -1, LUA_TTABLE);
-
-       std::string password;
-       bool found = getstringfield(L, -1, "password", password);
-       if(!found)
-               throw LuaError(L, "Authentication handler didn't return password");
-       if(dst_password)
-               *dst_password = password;
-
-       lua_getfield(L, -1, "privileges");
-       if(!lua_istable(L, -1))
-               throw LuaError(L,
-                               "Authentication handler didn't return privilege table");
-       if(dst_privs)
-               readPrivileges(-1, *dst_privs);
-       lua_pop(L, 1);
-
-       return true;
-}
-
-void ScriptApi::getAuthHandler()
-{
-       lua_State *L = getStack();
-
-       lua_getglobal(L, "minetest");
-       lua_getfield(L, -1, "registered_auth_handler");
-       if(lua_isnil(L, -1)){
-               lua_pop(L, 1);
-               lua_getfield(L, -1, "builtin_auth_handler");
-       }
-       if(lua_type(L, -1) != LUA_TTABLE)
-               throw LuaError(L, "Authentication handler table not valid");
-}
-
-void ScriptApi::readPrivileges(int index,std::set<std::string> &result)
-{
-       lua_State *L = getStack();
-
-       result.clear();
-       lua_pushnil(L);
-       if(index < 0)
-               index -= 1;
-       while(lua_next(L, index) != 0){
-               // key at index -2 and value at index -1
-               std::string key = luaL_checkstring(L, -2);
-               bool value = lua_toboolean(L, -1);
-               if(value)
-                       result.insert(key);
-               // removes value, keeps key for next iteration
-               lua_pop(L, 1);
-       }
-}
-
-void ScriptApi::createAuth(const std::string &playername,
-               const std::string &password)
-{
-       SCRIPTAPI_PRECHECKHEADER
-
-       getAuthHandler();
-       lua_getfield(L, -1, "create_auth");
-       if(lua_type(L, -1) != LUA_TFUNCTION)
-               throw LuaError(L, "Authentication handler missing create_auth");
-       lua_pushstring(L, playername.c_str());
-       lua_pushstring(L, password.c_str());
-       if(lua_pcall(L, 2, 0, 0))
-               scriptError("error: %s", lua_tostring(L, -1));
-}
-
-bool ScriptApi::setPassword(const std::string &playername,
-               const std::string &password)
-{
-       SCRIPTAPI_PRECHECKHEADER
-
-       getAuthHandler();
-       lua_getfield(L, -1, "set_password");
-       if(lua_type(L, -1) != LUA_TFUNCTION)
-               throw LuaError(L, "Authentication handler missing set_password");
-       lua_pushstring(L, playername.c_str());
-       lua_pushstring(L, password.c_str());
-       if(lua_pcall(L, 2, 1, 0))
-               scriptError("error: %s", lua_tostring(L, -1));
-       return lua_toboolean(L, -1);
-}
-
-bool ScriptApi::on_chat_message(const std::string &name,
-               const std::string &message)
-{
-       SCRIPTAPI_PRECHECKHEADER
-
-       // Get minetest.registered_on_chat_messages
-       lua_getglobal(L, "minetest");
-       lua_getfield(L, -1, "registered_on_chat_messages");
-       // Call callbacks
-       lua_pushstring(L, name.c_str());
-       lua_pushstring(L, message.c_str());
-       runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC);
-       bool ate = lua_toboolean(L, -1);
-       return ate;
-}
-
-void ScriptApi::on_shutdown()
-{
-       SCRIPTAPI_PRECHECKHEADER
-
-       // Get registered shutdown hooks
-       lua_getglobal(L, "minetest");
-       lua_getfield(L, -1, "registered_on_shutdown");
-       // Call callbacks
-       runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
-}
-
-bool ScriptApi::loadMod(const std::string &scriptpath,const std::string &modname)
-{
-       ModNameStorer modnamestorer(getStack(), modname);
-
-       if(!string_allowed(modname, MODNAME_ALLOWED_CHARS)){
-               errorstream<<"Error loading mod \""<<modname
-                               <<"\": modname does not follow naming conventions: "
-                               <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
-               return false;
-       }
-
-       bool success = false;
-
-       try{
-               success = scriptLoad(scriptpath.c_str());
-       }
-       catch(LuaError &e){
-               errorstream<<"Error loading mod \""<<modname
-                               <<"\": "<<e.what()<<std::endl;
-       }
-
-       return success;
-}
-
-ScriptApi::ScriptApi() {
-       assert("Invalid call to default constructor of scriptapi!" == 0);
-}
-
-ScriptApi::ScriptApi(Server* server)
-{
-
-       setServer(server);
-       setStack(luaL_newstate());
-       assert(getStack());
-
-       //TODO add security
-
-       luaL_openlibs(getStack());
-
-       SCRIPTAPI_PRECHECKHEADER
-
-       lua_pushlightuserdata(L, this);
-       lua_setfield(L, LUA_REGISTRYINDEX, "scriptapi");
-
-       lua_newtable(L);
-       lua_setglobal(L, "minetest");
-
-
-       for (std::vector<ModApiBase*>::iterator i = m_mod_api_modules->begin();
-                       i != m_mod_api_modules->end(); i++) {
-               //initializers are called within minetest global table!
-               lua_getglobal(L, "minetest");
-               int top = lua_gettop(L);
-               bool ModInitializedSuccessfull = (*i)->Initialize(L,top);
-               assert(ModInitializedSuccessfull);
-       }
-
-       infostream << "SCRIPTAPI: initialized " << m_mod_api_modules->size()
-                                                                                                       << " modules" << std::endl;
-
-       // Get the main minetest table
-       lua_getglobal(L, "minetest");
-
-       // Add tables to minetest
-       lua_newtable(L);
-       lua_setfield(L, -2, "object_refs");
-
-       lua_newtable(L);
-       lua_setfield(L, -2, "luaentities");
-}
-
-ScriptApi::~ScriptApi() {
-       lua_close(getStack());
-}
-
-bool ScriptApi::scriptLoad(const char *path)
-{
-       lua_State* L = getStack();
-       setStack(0);
-
-       verbosestream<<"Loading and running script from "<<path<<std::endl;
-
-       lua_pushcfunction(L, script_ErrorHandler);
-       int errorhandler = lua_gettop(L);
-
-       int ret = luaL_loadfile(L, path) || lua_pcall(L, 0, 0, errorhandler);
-       if(ret){
-               errorstream<<"========== ERROR FROM LUA ==========="<<std::endl;
-               errorstream<<"Failed to load and run script from "<<std::endl;
-               errorstream<<path<<":"<<std::endl;
-               errorstream<<std::endl;
-               errorstream<<lua_tostring(L, -1)<<std::endl;
-               errorstream<<std::endl;
-               errorstream<<"=======END OF ERROR FROM LUA ========"<<std::endl;
-               lua_pop(L, 1); // Pop error message from stack
-               lua_pop(L, 1); // Pop the error handler from stack
-               return false;
-       }
-       lua_pop(L, 1); // Pop the error handler from stack
-       return true;
-}
-
-bool ScriptApi::registerModApiModule(ModApiBase* ptr) {
-       if (ScriptApi::m_mod_api_modules == 0)
-               ScriptApi::m_mod_api_modules = new std::vector<ModApiBase*>();
-
-       assert(ScriptApi::m_mod_api_modules != 0);
-
-       ScriptApi::m_mod_api_modules->push_back(ptr);
-
-       return true;
-}
-
-std::vector<ModApiBase*>* ScriptApi::m_mod_api_modules = 0;
diff --git a/src/script/cpp_api/scriptapi.h b/src/script/cpp_api/scriptapi.h
deleted file mode 100644 (file)
index bbd0bdd..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-Minetest
-Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef SCRIPTAPI_H_
-#define SCRIPTAPI_H_
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include "cpp_api/s_base.h"
-#include "cpp_api/s_player.h"
-#include "cpp_api/s_env.h"
-#include "cpp_api/s_node.h"
-#include "cpp_api/s_inventory.h"
-#include "cpp_api/s_entity.h"
-
-class ModApiBase;
-
-/*****************************************************************************/
-/* Scriptapi <-> Core Interface                                              */
-/*****************************************************************************/
-
-class ScriptApi
-               : virtual public ScriptApiBase,
-                 public ScriptApiPlayer,
-                 public ScriptApiEnv,
-                 public ScriptApiNode,
-                 public ScriptApiDetached,
-                 public ScriptApiEntity
-{
-public:
-       ScriptApi();
-       ScriptApi(Server* server);
-       ~ScriptApi();
-
-       // Returns true if script handled message
-       bool on_chat_message(const std::string &name, const std::string &message);
-
-       /* server */
-       void on_shutdown();
-
-       /* auth */
-       bool getAuth(const std::string &playername,
-                       std::string *dst_password, std::set<std::string> *dst_privs);
-       void createAuth(const std::string &playername,
-                       const std::string &password);
-       bool setPassword(const std::string &playername,
-                       const std::string &password);
-
-       /** register a lua api module to scriptapi */
-       static bool registerModApiModule(ModApiBase* prototype);
-       /** load a mod **/
-       bool loadMod(const std::string &scriptpath,const std::string &modname);
-
-private:
-       void getAuthHandler();
-       void readPrivileges(int index,std::set<std::string> &result);
-
-       bool scriptLoad(const char *path);
-
-       static std::vector<ModApiBase*>* m_mod_api_modules;
-
-};
-
-#endif /* SCRIPTAPI_H_ */
index f67cf6886a62658ffe427af479bd1716f4d4cd2a..d75c04335cbd0c812facd2553aa4cecf4c987537 100644 (file)
@@ -1,14 +1,23 @@
-set(SCRIPT_LUA_API_SRCS
+# Used by server and client
+set(common_SCRIPT_LUA_API_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/l_base.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_craft.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_env.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_inventory.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_item.cpp
-       ${CMAKE_CURRENT_SOURCE_DIR}/luaapi.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/l_mapgen.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_nodemeta.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_nodetimer.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_noise.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_object.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_particles.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/l_rollback.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/l_server.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/l_util.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/l_vmanip.cpp
        PARENT_SCOPE)
+
+# Used by client only
+set(minetest_SCRIPT_LUA_API_SRCS
+       ${CMAKE_CURRENT_SOURCE_DIR}/l_mainmenu.cpp
+       PARENT_SCOPE)
index b1766e6df6652e9c18aa0f0f5d792c4218894317..b8d673ee4cd35dd26ffaf58b18a38d3e44de890b 100644 (file)
@@ -17,32 +17,35 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "cpp_api/scriptapi.h"
 #include "lua_api/l_base.h"
-#include "common/c_internal.h"
-#include "log.h"
-
-extern "C" {
-#include "lua.h"
+#include "lua_api/l_internal.h"
+#include "cpp_api/s_base.h"
+
+ScriptApiBase* ModApiBase::getScriptApiBase(lua_State *L) {
+       // Get server from registry
+       lua_getfield(L, LUA_REGISTRYINDEX, "scriptapi");
+       ScriptApiBase *sapi_ptr = (ScriptApiBase*) lua_touserdata(L, -1);
+       lua_pop(L, 1);
+       return sapi_ptr;
 }
 
-ModApiBase::ModApiBase() {
-       ScriptApi::registerModApiModule(this);
+Server* ModApiBase::getServer(lua_State *L) {
+       return getScriptApiBase(L)->getServer();
 }
 
-Server* ModApiBase::getServer(lua_State* L) {
-       return get_scriptapi(L)->getServer();
+Environment* ModApiBase::getEnv(lua_State *L) {
+       return getScriptApiBase(L)->getEnv();
 }
 
-Environment* ModApiBase::getEnv(lua_State* L) {
-       return get_scriptapi(L)->getEnv();
+GUIEngine* ModApiBase::getGuiEngine(lua_State *L) {
+       return getScriptApiBase(L)->getGuiEngine();
 }
 
-bool ModApiBase::registerFunction(     lua_State* L,
-                                                               const char* name,
-                                                               lua_CFunction fct,
-                                                               int top
-                                                               ) {
+bool ModApiBase::registerFunction(lua_State *L,
+               const char *name,
+               lua_CFunction fct,
+               int top
+               ) {
        //TODO check presence first!
 
        lua_pushstring(L,name);
@@ -51,13 +54,3 @@ bool ModApiBase::registerFunction(   lua_State* L,
 
        return true;
 }
-
-struct EnumString es_BiomeTerrainType[] =
-{
-       {BIOME_TERRAIN_NORMAL, "normal"},
-       {BIOME_TERRAIN_LIQUID, "liquid"},
-       {BIOME_TERRAIN_NETHER, "nether"},
-       {BIOME_TERRAIN_AETHER, "aether"},
-       {BIOME_TERRAIN_FLAT,   "flat"},
-       {0, NULL},
-};
index f2e0d59a9ecfc55e542e4f84f27163c55f939eda..71ebd215c1c15cebba0169c20e48b8b576baa23f 100644 (file)
@@ -20,44 +20,43 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef L_BASE_H_
 #define L_BASE_H_
 
-#include "biome.h"
 #include "common/c_types.h"
 
 extern "C" {
-#include "lua.h"
+#include <lua.h>
+#include <lauxlib.h>
 }
 
-extern struct EnumString es_BiomeTerrainType[];
-
-class ScriptApi;
+class ScriptApiBase;
 class Server;
 class Environment;
+class GUIEngine;
 
-typedef class ModApiBase {
-
-public:
-       ModApiBase();
-
-       virtual bool Initialize(lua_State* L, int top) = 0;
-       virtual ~ModApiBase() {};
+class ModApiBase {
 
 protected:
-       static Server* getServer(      lua_State* L);
-       static Environment* getEnv(    lua_State* L);
-       static bool registerFunction(   lua_State* L,
-                                                                       const char* name,
-                                                                       lua_CFunction fct,
-                                                                       int top
-                                                                       );
-} ModApiBase;
-
-#if (defined(WIN32) || defined(_WIN32_WCE))
-#define NO_MAP_LOCK_REQUIRED
-#else
-#include "main.h"
-#include "profiler.h"
-#define NO_MAP_LOCK_REQUIRED ScopeProfiler nolocktime(g_profiler,"Scriptapi: unlockable time",SPT_ADD)
-//#define NO_ENVLOCK_REQUIRED assert(getServer(L).m_env_mutex.IsLocked() == false)
-#endif
+       static ScriptApiBase*   getScriptApiBase(lua_State *L);
+       static Server*          getServer(lua_State *L);
+       static Environment*     getEnv(lua_State *L);
+       static GUIEngine*       getGuiEngine(lua_State *L);
+
+       // Get an arbitrary subclass of ScriptApiBase
+       // by using dynamic_cast<> on getScriptApiBase()
+       template<typename T>
+       static T* getScriptApi(lua_State *L) {
+               ScriptApiBase *scriptIface = getScriptApiBase(L);
+               T *scriptIfaceDowncast = dynamic_cast<T*>(scriptIface);
+               if (!scriptIfaceDowncast) {
+                       throw LuaError(L, "Requested unavailable ScriptApi - core engine bug!");
+               }
+               return scriptIfaceDowncast;
+       }
+
+       static bool registerFunction(lua_State *L,
+                       const char* name,
+                       lua_CFunction fct,
+                       int top
+                       );
+};
 
 #endif /* L_BASE_H_ */
index a32fb9dffb7880a528cf3900e006a3c1d8b607fd..b0a47bfc195bdf3b4b669611e62484cc1afe8ce5 100644 (file)
@@ -19,20 +19,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 
 #include "lua_api/l_craft.h"
-#include "common/c_internal.h"
+#include "lua_api/l_internal.h"
+#include "lua_api/l_item.h"
 #include "common/c_converter.h"
 #include "common/c_content.h"
 #include "server.h"
-#include "lua_api/l_item.h"
-
-extern "C" {
-#include "lauxlib.h"
-}
-
-ModApiCraft::ModApiCraft()
-       : ModApiBase() {
-
-}
+#include "craftdef.h"
 
 struct EnumString ModApiCraft::es_CraftMethod[] =
 {
@@ -463,15 +455,10 @@ int ModApiCraft::l_get_all_craft_recipes(lua_State *L)
        return 1;
 }
 
-bool ModApiCraft::Initialize(lua_State* L, int top) {
-       bool retval = true;
-
-       retval &= API_FCT(get_all_craft_recipes);
-       retval &= API_FCT(get_craft_recipe);
-       retval &= API_FCT(get_craft_result);
-       retval &= API_FCT(register_craft);
-
-       return retval;
+void ModApiCraft::Initialize(lua_State *L, int top)
+{
+       API_FCT(get_all_craft_recipes);
+       API_FCT(get_craft_recipe);
+       API_FCT(get_craft_result);
+       API_FCT(register_craft);
 }
-
-ModApiCraft modapicraft_prototype;
index d8319199decb98d8a9b7fc09221bb0ebd427677b..548608776ef6aebd253ea7ab70ef5adc486256f2 100644 (file)
@@ -20,19 +20,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef L_CRAFT_H_
 #define L_CRAFT_H_
 
+#include <string>
 #include <vector>
 
-extern "C" {
-#include <lua.h>
-}
-
 #include "lua_api/l_base.h"
-#include "craftdef.h"
+
+struct CraftReplacements;
 
 class ModApiCraft : public ModApiBase {
-public:
-       ModApiCraft();
-       bool Initialize(lua_State* L, int top);
 private:
        static int l_register_craft(lua_State *L);
        static int l_get_craft_recipe(lua_State *L);
@@ -47,6 +42,9 @@ private:
                        int &width, std::vector<std::string> &recipe);
 
        static struct EnumString es_CraftMethod[];
+
+public:
+       static void Initialize(lua_State *L, int top);
 };
 
 #endif /* L_CRAFT_H_ */
index 47bc9baf7bcc43858d7fa42b358cbf5c7c1467b1..dbaf6fb368cb1fb538f646f7da37dda17527dd80 100644 (file)
@@ -17,53 +17,39 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "cpp_api/scriptapi.h"
-#include "lua_api/l_base.h"
 #include "lua_api/l_env.h"
+#include "lua_api/l_internal.h"
+#include "lua_api/l_nodemeta.h"
+#include "lua_api/l_nodetimer.h"
+#include "lua_api/l_noise.h"
 #include "lua_api/l_vmanip.h"
+#include "common/c_converter.h"
+#include "common/c_content.h"
+#include "scripting_game.h"
 #include "environment.h"
 #include "server.h"
+#include "nodedef.h"
 #include "daynightratio.h"
 #include "util/pointedthing.h"
 #include "content_sao.h"
-
-#include "common/c_converter.h"
-#include "common/c_content.h"
-#include "common/c_internal.h"
-#include "lua_api/l_nodemeta.h"
-#include "lua_api/l_nodetimer.h"
-#include "lua_api/l_noise.h"
 #include "treegen.h"
 #include "pathfinder.h"
-#include "emerge.h"
-#include "mapgen_v7.h"
 
 
 #define GET_ENV_PTR ServerEnvironment* env =                                   \
                                dynamic_cast<ServerEnvironment*>(getEnv(L));                   \
                                if( env == NULL) return 0
                                
-struct EnumString ModApiEnvMod::es_MapgenObject[] =
-{
-       {MGOBJ_VMANIP,    "voxelmanip"},
-       {MGOBJ_HEIGHTMAP, "heightmap"},
-       {MGOBJ_BIOMEMAP,  "biomemap"},
-       {MGOBJ_HEATMAP,   "heatmap"},
-       {MGOBJ_HUMIDMAP,  "humiditymap"},
-       {0, NULL},
-};
-
-
 ///////////////////////////////////////////////////////////////////////////////
 
 
 void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
                u32 active_object_count, u32 active_object_count_wider)
 {
-       ScriptApi* scriptIface = SERVER_TO_SA(env);
+       GameScripting *scriptIface = env->getScriptIface();
        scriptIface->realityCheck();
 
-       lua_StateL = scriptIface->getStack();
+       lua_State *L = scriptIface->getStack();
        assert(lua_checkstack(L, 20));
        StackUnroller stack_unroller(L);
 
@@ -196,8 +182,13 @@ int ModApiEnvMod::l_place_node(lua_State *L)
 {
        GET_ENV_PTR;
 
+       ScriptApiItem *scriptIfaceItem = getScriptApi<ScriptApiItem>(L);
+       Server *server = getServer(L);
+       INodeDefManager *ndef = server->ndef();
+       IItemDefManager *idef = server->idef();
+
        v3s16 pos = read_v3s16(L, 1);
-       MapNode n = readnode(L, 2, env->getGameDef()->ndef());
+       MapNode n = readnode(L, 2, ndef);
 
        // Don't attempt to load non-loaded area as of now
        MapNode n_old = env->getMap().getNodeNoEx(pos);
@@ -206,8 +197,6 @@ int ModApiEnvMod::l_place_node(lua_State *L)
                return 1;
        }
        // Create item to place
-       INodeDefManager *ndef = getServer(L)->ndef();
-       IItemDefManager *idef = getServer(L)->idef();
        ItemStack item(ndef->get(n).name, 1, 0, "", idef);
        // Make pointed position
        PointedThing pointed;
@@ -216,7 +205,7 @@ int ModApiEnvMod::l_place_node(lua_State *L)
        pointed.node_undersurface = pos + v3s16(0,-1,0);
        // Place it with a NULL placer (appears in Lua as a non-functional
        // ObjectRef)
-       bool success = get_scriptapi(L)->item_OnPlace(item, NULL, pointed);
+       bool success = scriptIfaceItem->item_OnPlace(item, NULL, pointed);
        lua_pushboolean(L, success);
        return 1;
 }
@@ -227,6 +216,8 @@ int ModApiEnvMod::l_dig_node(lua_State *L)
 {
        GET_ENV_PTR;
 
+       ScriptApiNode *scriptIfaceNode = getScriptApi<ScriptApiNode>(L);
+
        v3s16 pos = read_v3s16(L, 1);
 
        // Don't attempt to load non-loaded area as of now
@@ -237,7 +228,7 @@ int ModApiEnvMod::l_dig_node(lua_State *L)
        }
        // Dig it out with a NULL digger (appears in Lua as a
        // non-functional ObjectRef)
-       bool success = get_scriptapi(L)->node_on_dig(pos, n, NULL);
+       bool success = scriptIfaceNode->node_on_dig(pos, n, NULL);
        lua_pushboolean(L, success);
        return 1;
 }
@@ -248,6 +239,8 @@ int ModApiEnvMod::l_punch_node(lua_State *L)
 {
        GET_ENV_PTR;
 
+       ScriptApiNode *scriptIfaceNode = getScriptApi<ScriptApiNode>(L);
+
        v3s16 pos = read_v3s16(L, 1);
 
        // Don't attempt to load non-loaded area as of now
@@ -258,7 +251,7 @@ int ModApiEnvMod::l_punch_node(lua_State *L)
        }
        // Punch it with a NULL puncher (appears in Lua as a non-functional
        // ObjectRef)
-       bool success = get_scriptapi(L)->node_on_punch(pos, n, NULL);
+       bool success = scriptIfaceNode->node_on_punch(pos, n, NULL);
        lua_pushboolean(L, success);
        return 1;
 }
@@ -361,7 +354,7 @@ int ModApiEnvMod::l_add_entity(lua_State *L)
        if(objectid == 0)
                return 0;
        // Return ObjectRef
-       get_scriptapi(L)->objectrefGetOrCreate(obj);
+       getScriptApiBase(L)->objectrefGetOrCreate(obj);
        return 1;
 }
 
@@ -420,7 +413,7 @@ int ModApiEnvMod::l_get_player_by_name(lua_State *L)
                return 1;
        }
        // Put player on stack
-       get_scriptapi(L)->objectrefGetOrCreate(sao);
+       getScriptApiBase(L)->objectrefGetOrCreate(sao);
        return 1;
 }
 
@@ -446,7 +439,7 @@ int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L)
                // Insert object reference into table
                lua_pushvalue(L, table_insert);
                lua_pushvalue(L, table);
-               get_scriptapi(L)->objectrefGetOrCreate(obj);
+               getScriptApiBase(L)->objectrefGetOrCreate(obj);
                if(lua_pcall(L, 2, 0, 0))
                        script_error(L, "error: %s", lua_tostring(L, -1));
        }
@@ -624,142 +617,6 @@ int ModApiEnvMod::l_get_voxel_manip(lua_State *L)
        return 1;
 }
 
-// minetest.get_mapgen_object(objectname)
-// returns the requested object used during map generation
-int ModApiEnvMod::l_get_mapgen_object(lua_State *L)
-{
-       const char *mgobjstr = lua_tostring(L, 1);
-       
-       int mgobjint;
-       if (!string_to_enum(es_MapgenObject, mgobjint, mgobjstr ? mgobjstr : ""))
-               return 0;
-               
-       enum MapgenObject mgobj = (MapgenObject)mgobjint;
-
-       EmergeManager *emerge = getServer(L)->getEmergeManager();
-       Mapgen *mg = emerge->getCurrentMapgen();
-       if (!mg)
-               return 0;
-       
-       size_t maplen = mg->csize.X * mg->csize.Z;
-       
-       int nargs = 1;
-       
-       switch (mgobj) {
-               case MGOBJ_VMANIP: {
-                       ManualMapVoxelManipulator *vm = mg->vm;
-                       
-                       // VoxelManip object
-                       LuaVoxelManip *o = new LuaVoxelManip(vm, true);
-                       *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
-                       luaL_getmetatable(L, "VoxelManip");
-                       lua_setmetatable(L, -2);
-                       
-                       // emerged min pos
-                       push_v3s16(L, vm->m_area.MinEdge);
-
-                       // emerged max pos
-                       push_v3s16(L, vm->m_area.MaxEdge);
-                       
-                       nargs = 3;
-                       
-                       break; }
-               case MGOBJ_HEIGHTMAP: {
-                       if (!mg->heightmap)
-                               return 0;
-                       
-                       lua_newtable(L);
-                       for (size_t i = 0; i != maplen; i++) {
-                               lua_pushinteger(L, mg->heightmap[i]);
-                               lua_rawseti(L, -2, i + 1);
-                       }
-                       break; }
-               case MGOBJ_BIOMEMAP: {
-                       if (!mg->biomemap)
-                               return 0;
-                       
-                       lua_newtable(L);
-                       for (size_t i = 0; i != maplen; i++) {
-                               lua_pushinteger(L, mg->biomemap[i]);
-                               lua_rawseti(L, -2, i + 1);
-                       }
-                       break; }
-               case MGOBJ_HEATMAP: { // Mapgen V7 specific objects
-               case MGOBJ_HUMIDMAP:
-                       if (strcmp(emerge->params->mg_name.c_str(), "v7"))
-                               return 0;
-                       
-                       MapgenV7 *mgv7 = (MapgenV7 *)mg;
-
-                       float *arr = (mgobj == MGOBJ_HEATMAP) ? 
-                               mgv7->noise_heat->result : mgv7->noise_humidity->result;
-                       if (!arr)
-                               return 0;
-                       
-                       lua_newtable(L);
-                       for (size_t i = 0; i != maplen; i++) {
-                               lua_pushnumber(L, arr[i]);
-                               lua_rawseti(L, -2, i + 1);
-                       }
-                       break; }
-       }
-       
-       return nargs;
-}
-
-// minetest.set_mapgen_params(params)
-// set mapgen parameters
-int ModApiEnvMod::l_set_mapgen_params(lua_State *L)
-{
-       if (!lua_istable(L, 1))
-               return 0;
-
-       EmergeManager *emerge = getServer(L)->getEmergeManager();
-       if (emerge->mapgen.size())
-               return 0;
-       
-       MapgenParams *oparams = new MapgenParams;
-       u32 paramsmodified = 0;
-       u32 flagmask = 0;
-       
-       lua_getfield(L, 1, "mgname");
-       if (lua_isstring(L, -1)) {
-               oparams->mg_name = std::string(lua_tostring(L, -1));
-               paramsmodified |= MGPARAMS_SET_MGNAME;
-       }
-       
-       lua_getfield(L, 1, "seed");
-       if (lua_isnumber(L, -1)) {
-               oparams->seed = lua_tointeger(L, -1);
-               paramsmodified |= MGPARAMS_SET_SEED;
-       }
-       
-       lua_getfield(L, 1, "water_level");
-       if (lua_isnumber(L, -1)) {
-               oparams->water_level = lua_tointeger(L, -1);
-               paramsmodified |= MGPARAMS_SET_WATER_LEVEL;
-       }
-
-       lua_getfield(L, 1, "flags");
-       if (lua_isstring(L, -1)) {
-               std::string flagstr = std::string(lua_tostring(L, -1));
-               oparams->flags = readFlagString(flagstr, flagdesc_mapgen);
-               paramsmodified |= MGPARAMS_SET_FLAGS;
-       
-               lua_getfield(L, 1, "flagmask");
-               if (lua_isstring(L, -1)) {
-                       flagstr = std::string(lua_tostring(L, -1));
-                       flagmask = readFlagString(flagstr, flagdesc_mapgen);
-               }
-       }
-       
-       emerge->luaoverride_params          = oparams;
-       emerge->luaoverride_params_modified = paramsmodified;
-       emerge->luaoverride_flagmask        = flagmask;
-       
-       return 0;
-}
-
 // minetest.clear_objects()
 // clear all objects in the environment
 int ModApiEnvMod::l_clear_objects(lua_State *L)
@@ -913,48 +770,39 @@ int ModApiEnvMod::l_get_humidity(lua_State *L)
 }
 
 
-bool ModApiEnvMod::Initialize(lua_State *L,int top)
-{
-
-       bool retval = true;
-
-       retval &= API_FCT(set_node);
-       retval &= API_FCT(add_node);
-       retval &= API_FCT(add_item);
-       retval &= API_FCT(remove_node);
-       retval &= API_FCT(get_node);
-       retval &= API_FCT(get_node_or_nil);
-       retval &= API_FCT(get_node_light);
-       retval &= API_FCT(place_node);
-       retval &= API_FCT(dig_node);
-       retval &= API_FCT(punch_node);
-       retval &= API_FCT(get_node_max_level);
-       retval &= API_FCT(get_node_level);
-       retval &= API_FCT(set_node_level);
-       retval &= API_FCT(add_node_level);
-       retval &= API_FCT(add_entity);
-       retval &= API_FCT(get_meta);
-       retval &= API_FCT(get_node_timer);
-       retval &= API_FCT(get_player_by_name);
-       retval &= API_FCT(get_objects_inside_radius);
-       retval &= API_FCT(set_timeofday);
-       retval &= API_FCT(get_timeofday);
-       retval &= API_FCT(find_node_near);
-       retval &= API_FCT(find_nodes_in_area);
-       retval &= API_FCT(get_perlin);
-       retval &= API_FCT(get_perlin_map);
-       retval &= API_FCT(get_voxel_manip);
-       retval &= API_FCT(get_mapgen_object);
-       retval &= API_FCT(set_mapgen_params);
-       retval &= API_FCT(clear_objects);
-       retval &= API_FCT(spawn_tree);
-       retval &= API_FCT(find_path);
-       retval &= API_FCT(line_of_sight);
-       retval &= API_FCT(transforming_liquid_add);
-       retval &= API_FCT(get_heat);
-       retval &= API_FCT(get_humidity);
-
-       return retval;
-}
-
-ModApiEnvMod modapienv_prototype;
+void ModApiEnvMod::Initialize(lua_State *L, int top)
+{
+       API_FCT(set_node);
+       API_FCT(add_node);
+       API_FCT(add_item);
+       API_FCT(remove_node);
+       API_FCT(get_node);
+       API_FCT(get_node_or_nil);
+       API_FCT(get_node_light);
+       API_FCT(place_node);
+       API_FCT(dig_node);
+       API_FCT(punch_node);
+       API_FCT(get_node_max_level);
+       API_FCT(get_node_level);
+       API_FCT(set_node_level);
+       API_FCT(add_node_level);
+       API_FCT(add_entity);
+       API_FCT(get_meta);
+       API_FCT(get_node_timer);
+       API_FCT(get_player_by_name);
+       API_FCT(get_objects_inside_radius);
+       API_FCT(set_timeofday);
+       API_FCT(get_timeofday);
+       API_FCT(find_node_near);
+       API_FCT(find_nodes_in_area);
+       API_FCT(get_perlin);
+       API_FCT(get_perlin_map);
+       API_FCT(get_voxel_manip);
+       API_FCT(clear_objects);
+       API_FCT(spawn_tree);
+       API_FCT(find_path);
+       API_FCT(line_of_sight);
+       API_FCT(transforming_liquid_add);
+       API_FCT(get_heat);
+       API_FCT(get_humidity);
+}
index 4122fd037ebc5da868222fcdbe6ec93232312f0b..adb80a8a833dd7628aba62a9ff810f7cd9aaaa1d 100644 (file)
@@ -20,17 +20,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef L_ENV_H_
 #define L_ENV_H_
 
-extern "C" {
-#include <lua.h>
-#include <lauxlib.h>
-}
-
-#include "environment.h"
 #include "lua_api/l_base.h"
+#include "environment.h"
 
-class ModApiEnvMod
-       :public ModApiBase
-{
+class ModApiEnvMod : public ModApiBase {
 private:
        // minetest.set_node(pos, node)
        // pos = {x=num, y=num, z=num}
@@ -131,14 +124,6 @@ private:
        // returns world-specific voxel manipulator
        static int l_get_voxel_manip(lua_State *L);
        
-       // minetest.get_mapgen_object(objectname)
-       // returns the requested object used during map generation
-       static int l_get_mapgen_object(lua_State *L);
-       
-       // minetest.set_mapgen_params(params)
-       // set mapgen parameters
-       static int l_set_mapgen_params(lua_State *L);
-
        // minetest.clear_objects()
        // clear all objects in the environment
        static int l_clear_objects(lua_State *L);
@@ -159,10 +144,8 @@ private:
        static int l_get_heat(lua_State *L);
        static int l_get_humidity(lua_State *L);
        
-       static struct EnumString es_MapgenObject[];
-       
 public:
-       bool Initialize(lua_State *L, int top);
+       static void Initialize(lua_State *L, int top);
 };
 
 class LuaABM : public ActiveBlockModifier
diff --git a/src/script/lua_api/l_internal.h b/src/script/lua_api/l_internal.h
new file mode 100644 (file)
index 0000000..14215ee
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+/******************************************************************************/
+/******************************************************************************/
+/* WARNING!!!! do NOT add this header in any include file or any code file    */
+/*             not being a modapi file!!!!!!!!                                */
+/******************************************************************************/
+/******************************************************************************/
+
+#ifndef L_INTERNAL_H_
+#define L_INTERNAL_H_
+
+#include "common/c_internal.h"
+
+#define luamethod(class, name) {#name, class::l_##name}
+#define API_FCT(name) registerFunction(L,#name,l_##name,top)
+
+#if (defined(WIN32) || defined(_WIN32_WCE))
+#define NO_MAP_LOCK_REQUIRED
+#else
+#include "main.h"
+#include "profiler.h"
+#define NO_MAP_LOCK_REQUIRED ScopeProfiler nolocktime(g_profiler,"Scriptapi: unlockable time",SPT_ADD)
+#endif
+
+#endif /* L_INTERNAL_H_ */
index f57a4e8cd8561ab7ca6e01f1029661c22d646930..67b78bcafd444db8b942f7d7f42365985822205f 100644 (file)
@@ -17,15 +17,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "cpp_api/scriptapi.h"
-#include "common/c_converter.h"
-#include "common/c_content.h"
 #include "lua_api/l_inventory.h"
+#include "lua_api/l_internal.h"
 #include "lua_api/l_item.h"
-#include "common/c_internal.h"
+#include "common/c_converter.h"
+#include "common/c_content.h"
 #include "server.h"
-#include "log.h"
-#include "inventorymanager.h"
+#include "player.h"
 
 /*
        InvRef
@@ -40,7 +38,7 @@ InvRef* InvRef::checkobject(lua_State *L, int narg)
 
 Inventory* InvRef::getinv(lua_State *L, InvRef *ref)
 {
-       return STACK_TO_SERVER(L)->getInventory(ref->m_loc);
+       return getServer(L)->getInventory(ref->m_loc);
 }
 
 InventoryList* InvRef::getlist(lua_State *L, InvRef *ref,
@@ -56,7 +54,7 @@ InventoryList* InvRef::getlist(lua_State *L, InvRef *ref,
 void InvRef::reportInventoryChange(lua_State *L, InvRef *ref)
 {
        // Inform other things that the inventory has changed
-       STACK_TO_SERVER(L)->setInventoryModified(ref->m_loc);
+       getServer(L)->setInventoryModified(ref->m_loc);
 }
 
 // Exported functions
@@ -182,7 +180,7 @@ int InvRef::l_set_stack(lua_State *L)
        InvRef *ref = checkobject(L, 1);
        const char *listname = luaL_checkstring(L, 2);
        int i = luaL_checknumber(L, 3) - 1;
-       ItemStack newitem = read_item(L, 4,STACK_TO_SERVER(L));
+       ItemStack newitem = read_item(L, 4, getServer(L));
        InventoryList *list = getlist(L, ref, listname);
        if(list != NULL && i >= 0 && i < (int) list->getSize()){
                list->changeItem(i, newitem);
@@ -202,7 +200,7 @@ int InvRef::l_get_list(lua_State *L)
        const char *listname = luaL_checkstring(L, 2);
        Inventory *inv = getinv(L, ref);
        if(inv){
-               push_inventory_list(inv, listname, L);
+               push_inventory_list(L, inv, listname);
        } else {
                lua_pushnil(L);
        }
@@ -221,10 +219,10 @@ int InvRef::l_set_list(lua_State *L)
        }
        InventoryList *list = inv->getList(listname);
        if(list)
-               read_inventory_list(inv, listname, L, 3,
-                               STACK_TO_SERVER(L),list->getSize());
+               read_inventory_list(L, 3, inv, listname,
+                               getServer(L), list->getSize());
        else
-               read_inventory_list(inv, listname, L, 3,STACK_TO_SERVER(L));
+               read_inventory_list(L, 3, inv, listname, getServer(L));
        reportInventoryChange(L, ref);
        return 0;
 }
@@ -236,7 +234,7 @@ int InvRef::l_add_item(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        InvRef *ref = checkobject(L, 1);
        const char *listname = luaL_checkstring(L, 2);
-       ItemStack item = read_item(L, 3,STACK_TO_SERVER(L));
+       ItemStack item = read_item(L, 3, getServer(L));
        InventoryList *list = getlist(L, ref, listname);
        if(list){
                ItemStack leftover = list->addItem(item);
@@ -256,7 +254,7 @@ int InvRef::l_room_for_item(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        InvRef *ref = checkobject(L, 1);
        const char *listname = luaL_checkstring(L, 2);
-       ItemStack item = read_item(L, 3,STACK_TO_SERVER(L));
+       ItemStack item = read_item(L, 3, getServer(L));
        InventoryList *list = getlist(L, ref, listname);
        if(list){
                lua_pushboolean(L, list->roomForItem(item));
@@ -273,7 +271,7 @@ int InvRef::l_contains_item(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        InvRef *ref = checkobject(L, 1);
        const char *listname = luaL_checkstring(L, 2);
-       ItemStack item = read_item(L, 3, STACK_TO_SERVER(L));
+       ItemStack item = read_item(L, 3, getServer(L));
        InventoryList *list = getlist(L, ref, listname);
        if(list){
                lua_pushboolean(L, list->containsItem(item));
@@ -290,7 +288,7 @@ int InvRef::l_remove_item(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        InvRef *ref = checkobject(L, 1);
        const char *listname = luaL_checkstring(L, 2);
-       ItemStack item = read_item(L, 3,STACK_TO_SERVER(L));
+       ItemStack item = read_item(L, 3, getServer(L));
        InventoryList *list = getlist(L, ref, listname);
        if(list){
                ItemStack removed = list->removeItem(item);
@@ -473,20 +471,8 @@ int ModApiInventory::l_create_detached_inventory_raw(lua_State *L)
        return 1;
 }
 
-bool ModApiInventory::Initialize(lua_State *L, int top) {
-       bool retval = true;
-
-       retval &= API_FCT(create_detached_inventory_raw);
-       retval &= API_FCT(get_inventory);
-
-       InvRef::Register(L);
-
-       return retval;
-}
-
-ModApiInventory::ModApiInventory()
-       : ModApiBase() {
-
+void ModApiInventory::Initialize(lua_State *L, int top)
+{
+       API_FCT(create_detached_inventory_raw);
+       API_FCT(get_inventory);
 }
-
-ModApiInventory modapiinventory_prototype;
index 83e8039b85c1073c52a1b94901e2df38810facaf..ed3249e5fd51bfe817030d292e1f0151ebea581b 100644 (file)
@@ -20,23 +20,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef L_INVENTORY_H_
 #define L_INVENTORY_H_
 
-extern "C" {
-#include <lua.h>
-#include <lauxlib.h>
-}
+#include "lua_api/l_base.h"
 
-#include "inventorymanager.h"
-#include "player.h"
-#include "serverobject.h"
 #include "inventory.h"
+#include "inventorymanager.h"
+
+class Player;
 
-#include "lua_api/l_base.h"
 /*
        InvRef
 */
 
-class InvRef
-{
+class InvRef : public ModApiBase {
 private:
        InventoryLocation m_loc;
 
@@ -116,22 +111,19 @@ public:
        static void Register(lua_State *L);
 };
 
-class ModApiInventory
-       : public ModApiBase
-{
-public:
-       ModApiInventory();
-
-       bool Initialize(lua_State *L, int top);
-
+class ModApiInventory : public ModApiBase {
+private:
        static int l_create_detached_inventory_raw(lua_State *L);
+
        static int l_get_inventory(lua_State *L);
-private:
+
        static void inventory_set_list_from_lua(Inventory *inv, const char *name,
                        lua_State *L, int tableindex, int forcesize);
        static void inventory_get_list_to_lua(Inventory *inv, const char *name,
                        lua_State *L);
 
+public:
+       static void Initialize(lua_State *L, int top);
 };
 
 #endif /* L_INVENTORY_H_ */
index 6182c037b848c7b15dcbe56c59d58bcc4d5dd0e8..a43b2858f6bb3ae1055b016bddd3025ee2e9f57a 100644 (file)
@@ -18,11 +18,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "lua_api/l_item.h"
+#include "lua_api/l_internal.h"
 #include "common/c_converter.h"
 #include "common/c_content.h"
-#include "cpp_api/scriptapi.h"
+#include "itemdef.h"
+#include "nodedef.h"
 #include "server.h"
-#include "common/c_internal.h"
+#include "content_sao.h"
+#include "inventory.h"
+#include "log.h"
+
 
 // garbage collector
 int LuaItemStack::gc_object(lua_State *L)
@@ -97,7 +102,7 @@ int LuaItemStack::l_replace(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
        LuaItemStack *o = checkobject(L, 1);
-       o->m_stack = read_item(L,2,STACK_TO_SERVER(L));
+       o->m_stack = read_item(L,2,getServer(L));
        lua_pushboolean(L, true);
        return 1;
 }
@@ -143,7 +148,7 @@ int LuaItemStack::l_get_stack_max(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        LuaItemStack *o = checkobject(L, 1);
        ItemStack &item = o->m_stack;
-       lua_pushinteger(L, item.getStackMax(STACK_TO_SERVER(L)->idef()));
+       lua_pushinteger(L, item.getStackMax(getServer(L)->idef()));
        return 1;
 }
 
@@ -153,7 +158,7 @@ int LuaItemStack::l_get_free_space(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        LuaItemStack *o = checkobject(L, 1);
        ItemStack &item = o->m_stack;
-       lua_pushinteger(L, item.freeSpace(STACK_TO_SERVER(L)->idef()));
+       lua_pushinteger(L, item.freeSpace(getServer(L)->idef()));
        return 1;
 }
 
@@ -164,7 +169,7 @@ int LuaItemStack::l_is_known(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        LuaItemStack *o = checkobject(L, 1);
        ItemStack &item = o->m_stack;
-       bool is_known = item.isKnown(STACK_TO_SERVER(L)->idef());
+       bool is_known = item.isKnown(getServer(L)->idef());
        lua_pushboolean(L, is_known);
        return 1;
 }
@@ -200,7 +205,7 @@ int LuaItemStack::l_get_tool_capabilities(lua_State *L)
        LuaItemStack *o = checkobject(L, 1);
        ItemStack &item = o->m_stack;
        const ToolCapabilities &prop =
-               item.getToolCapabilities(STACK_TO_SERVER(L)->idef());
+               item.getToolCapabilities(getServer(L)->idef());
        push_tool_capabilities(L, prop);
        return 1;
 }
@@ -215,7 +220,7 @@ int LuaItemStack::l_add_wear(lua_State *L)
        LuaItemStack *o = checkobject(L, 1);
        ItemStack &item = o->m_stack;
        int amount = lua_tointeger(L, 2);
-       bool result = item.addWear(amount, STACK_TO_SERVER(L)->idef());
+       bool result = item.addWear(amount, getServer(L)->idef());
        lua_pushboolean(L, result);
        return 1;
 }
@@ -227,8 +232,8 @@ int LuaItemStack::l_add_item(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        LuaItemStack *o = checkobject(L, 1);
        ItemStack &item = o->m_stack;
-       ItemStack newitem = read_item(L,-1, STACK_TO_SERVER(L));
-       ItemStack leftover = item.addItem(newitem, STACK_TO_SERVER(L)->idef());
+       ItemStack newitem = read_item(L,-1, getServer(L));
+       ItemStack leftover = item.addItem(newitem, getServer(L)->idef());
        create(L, leftover);
        return 1;
 }
@@ -241,9 +246,9 @@ int LuaItemStack::l_item_fits(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        LuaItemStack *o = checkobject(L, 1);
        ItemStack &item = o->m_stack;
-       ItemStack newitem = read_item(L, 2 ,STACK_TO_SERVER(L));
+       ItemStack newitem = read_item(L, 2, getServer(L));
        ItemStack restitem;
-       bool fits = item.itemFits(newitem, &restitem, STACK_TO_SERVER(L)->idef());
+       bool fits = item.itemFits(newitem, &restitem, getServer(L)->idef());
        lua_pushboolean(L, fits);  // first return value
        create(L, restitem);       // second return value
        return 2;
@@ -300,7 +305,7 @@ ItemStack& LuaItemStack::getItem()
 int LuaItemStack::create_object(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
-       ItemStack item = read_item(L,1,STACK_TO_SERVER(L));
+       ItemStack item = read_item(L, 1, getServer(L));
        LuaItemStack *o = new LuaItemStack(item);
        *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
        luaL_getmetatable(L, className);
@@ -378,9 +383,6 @@ const luaL_reg LuaItemStack::methods[] = {
        {0,0}
 };
 
-ModApiItemMod::ModApiItemMod() {
-}
-
 /*
        ItemDefinition
 */
@@ -392,13 +394,11 @@ int ModApiItemMod::l_register_item_raw(lua_State *L)
        luaL_checktype(L, 1, LUA_TTABLE);
        int table = 1;
 
-       ScriptApi* scriptIface = get_scriptapi(L);
-
        // Get the writable item and node definition managers from the server
        IWritableItemDefManager *idef =
-                       scriptIface->getServer()->getWritableItemDefManager();
+                       getServer(L)->getWritableItemDefManager();
        IWritableNodeDefManager *ndef =
-                       scriptIface->getServer()->getWritableNodeDefManager();
+                       getServer(L)->getWritableNodeDefManager();
 
        // Check if name is defined
        std::string name;
@@ -455,7 +455,7 @@ int ModApiItemMod::l_register_alias_raw(lua_State *L)
 
        // Get the writable item definition manager from the server
        IWritableItemDefManager *idef =
-                       STACK_TO_SERVER(L)->getWritableItemDefManager();
+                       getServer(L)->getWritableItemDefManager();
 
        idef->registerAlias(name, convert_to);
 
@@ -468,7 +468,7 @@ int ModApiItemMod::l_get_content_id(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        std::string name = luaL_checkstring(L, 1);
 
-       INodeDefManager *ndef = STACK_TO_SERVER(L)->getNodeDefManager();
+       INodeDefManager *ndef = getServer(L)->getNodeDefManager();
        content_t c = ndef->getId(name);
        
        lua_pushinteger(L, c);
@@ -481,25 +481,17 @@ int ModApiItemMod::l_get_name_from_content_id(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
        content_t c = luaL_checkint(L, 1);
 
-       INodeDefManager *ndef = STACK_TO_SERVER(L)->getNodeDefManager();
+       INodeDefManager *ndef = getServer(L)->getNodeDefManager();
        const char *name = ndef->get(c).name.c_str();
        
        lua_pushstring(L, name);
        return 1; /* number of results */
 }
 
-bool ModApiItemMod::Initialize(lua_State *L,int top) {
-
-       bool retval = true;
-
-       retval &= API_FCT(register_item_raw);
-       retval &= API_FCT(register_alias_raw);
-       retval &= API_FCT(get_content_id);
-       retval &= API_FCT(get_name_from_content_id);
-
-       LuaItemStack::Register(L);
-
-       return retval;
+void ModApiItemMod::Initialize(lua_State *L, int top)
+{
+       API_FCT(register_item_raw);
+       API_FCT(register_alias_raw);
+       API_FCT(get_content_id);
+       API_FCT(get_name_from_content_id);
 }
-
-ModApiItemMod modapi_item_prototyp;
index bad517e0879c481b9cfe952f3fa97692e84ecca5..7c2e1b098578a233b675b3bb5acc5419856a21af 100644 (file)
@@ -20,24 +20,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef L_ITEM_H_
 #define L_ITEM_H_
 
-extern "C" {
-#include <lua.h>
-#include <lauxlib.h>
-}
-
-#include <vector>
-
-#include "itemdef.h"
-#include "content_sao.h"
-#include "util/pointedthing.h"
-#include "inventory.h"
-
 #include "lua_api/l_base.h"
+#include "inventory.h"  // ItemStack
 
-class ModApiInventory;
-
-class LuaItemStack
-{
+class LuaItemStack : public ModApiBase {
 private:
        ItemStack m_stack;
 
@@ -134,18 +120,14 @@ public:
 
 };
 
-class ModApiItemMod
-       :virtual public ModApiBase
-{
-public:
-       ModApiItemMod();
-
-       bool Initialize(lua_State *L, int top);
-
+class ModApiItemMod : public ModApiBase {
+private:
        static int l_register_item_raw(lua_State *L);
        static int l_register_alias_raw(lua_State *L);
        static int l_get_content_id(lua_State *L);
        static int l_get_name_from_content_id(lua_State *L);
+public:
+       static void Initialize(lua_State *L, int top);
 };
 
 
diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp
new file mode 100644 (file)
index 0000000..b3ae1f3
--- /dev/null
@@ -0,0 +1,1016 @@
+/*
+Minetest
+Copyright (C) 2013 sapier
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "lua_api/l_mainmenu.h"
+#include "lua_api/l_internal.h"
+#include "common/c_content.h"
+#include "guiEngine.h"
+#include "guiMainMenu.h"
+#include "guiKeyChangeMenu.h"
+#include "guiFileSelectMenu.h"
+#include "subgame.h"
+#include "porting.h"
+#include "filesys.h"
+#include "convert_json.h"
+#include "serverlist.h"
+#include "sound.h"
+#include "settings.h"
+#include "main.h" // for g_settings
+
+#include <IFileArchive.h>
+#include <IFileSystem.h>
+
+/******************************************************************************/
+std::string ModApiMainMenu::getTextData(lua_State *L, std::string name)
+{
+       lua_getglobal(L, "gamedata");
+
+       lua_getfield(L, -1, name.c_str());
+
+       if(lua_isnil(L, -1))
+               return "";
+
+       return luaL_checkstring(L, -1);
+}
+
+/******************************************************************************/
+int ModApiMainMenu::getIntegerData(lua_State *L, std::string name,bool& valid)
+{
+       lua_getglobal(L, "gamedata");
+
+       lua_getfield(L, -1, name.c_str());
+
+       if(lua_isnil(L, -1)) {
+               valid = false;
+               return -1;
+               }
+
+       valid = true;
+       return luaL_checkinteger(L, -1);
+}
+
+/******************************************************************************/
+int ModApiMainMenu::getBoolData(lua_State *L, std::string name,bool& valid)
+{
+       lua_getglobal(L, "gamedata");
+
+       lua_getfield(L, -1, name.c_str());
+
+       if(lua_isnil(L, -1)) {
+               valid = false;
+               return false;
+               }
+
+       valid = true;
+       return lua_toboolean(L, -1);
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_update_formspec(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       if (engine->m_startgame)
+               return 0;
+
+       //read formspec
+       std::string formspec(luaL_checkstring(L, 1));
+
+       if (engine->m_formspecgui != 0) {
+               engine->m_formspecgui->setForm(formspec);
+       }
+
+       return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_start(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       //update c++ gamedata from lua table
+
+       bool valid = false;
+
+
+       engine->m_data->selected_world          = getIntegerData(L, "selected_world",valid) -1;
+       engine->m_data->simple_singleplayer_mode = getBoolData(L,"singleplayer",valid);
+       engine->m_data->name                            = getTextData(L,"playername");
+       engine->m_data->password                        = getTextData(L,"password");
+       engine->m_data->address                         = getTextData(L,"address");
+       engine->m_data->port                            = getTextData(L,"port");
+       engine->m_data->serverdescription       = getTextData(L,"serverdescription");
+       engine->m_data->servername                      = getTextData(L,"servername");
+
+       //close menu next time
+       engine->m_startgame = true;
+       return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_close(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       engine->m_data->kill = true;
+
+       //close menu next time
+       engine->m_startgame = true;
+       engine->m_menu->quitMenu();
+       return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_set_background(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       std::string backgroundlevel(luaL_checkstring(L, 1));
+       std::string texturename(luaL_checkstring(L, 2));
+
+       bool retval = false;
+
+       if (backgroundlevel == "background") {
+               retval |= engine->setTexture(TEX_LAYER_BACKGROUND,texturename);
+       }
+
+       if (backgroundlevel == "overlay") {
+               retval |= engine->setTexture(TEX_LAYER_OVERLAY,texturename);
+       }
+
+       if (backgroundlevel == "header") {
+               retval |= engine->setTexture(TEX_LAYER_HEADER,texturename);
+       }
+
+       if (backgroundlevel == "footer") {
+               retval |= engine->setTexture(TEX_LAYER_FOOTER,texturename);
+       }
+
+       lua_pushboolean(L,retval);
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_set_clouds(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       bool value = lua_toboolean(L,1);
+
+       engine->m_clouds_enabled = value;
+
+       return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_textlist_index(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       std::string listboxname(luaL_checkstring(L, 1));
+
+       int selection = engine->m_menu->getListboxIndex(listboxname);
+
+       if (selection >= 0)
+               selection++;
+
+       lua_pushinteger(L, selection);
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_worlds(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       std::vector<WorldSpec> worlds = getAvailableWorlds();
+
+       lua_newtable(L);
+       int top = lua_gettop(L);
+       unsigned int index = 1;
+
+       for (unsigned int i = 0; i < worlds.size(); i++)
+       {
+               lua_pushnumber(L,index);
+
+               lua_newtable(L);
+               int top_lvl2 = lua_gettop(L);
+
+               lua_pushstring(L,"path");
+               lua_pushstring(L,worlds[i].path.c_str());
+               lua_settable(L, top_lvl2);
+
+               lua_pushstring(L,"name");
+               lua_pushstring(L,worlds[i].name.c_str());
+               lua_settable(L, top_lvl2);
+
+               lua_pushstring(L,"gameid");
+               lua_pushstring(L,worlds[i].gameid.c_str());
+               lua_settable(L, top_lvl2);
+
+               lua_settable(L, top);
+               index++;
+       }
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_games(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       std::vector<SubgameSpec> games = getAvailableGames();
+
+       lua_newtable(L);
+       int top = lua_gettop(L);
+       unsigned int index = 1;
+
+       for (unsigned int i = 0; i < games.size(); i++)
+       {
+               lua_pushnumber(L,index);
+               lua_newtable(L);
+               int top_lvl2 = lua_gettop(L);
+
+               lua_pushstring(L,"id");
+               lua_pushstring(L,games[i].id.c_str());
+               lua_settable(L, top_lvl2);
+
+               lua_pushstring(L,"path");
+               lua_pushstring(L,games[i].path.c_str());
+               lua_settable(L, top_lvl2);
+
+               lua_pushstring(L,"gamemods_path");
+               lua_pushstring(L,games[i].gamemods_path.c_str());
+               lua_settable(L, top_lvl2);
+
+               lua_pushstring(L,"name");
+               lua_pushstring(L,games[i].name.c_str());
+               lua_settable(L, top_lvl2);
+
+               lua_pushstring(L,"menuicon_path");
+               lua_pushstring(L,games[i].menuicon_path.c_str());
+               lua_settable(L, top_lvl2);
+
+               lua_pushstring(L,"addon_mods_paths");
+               lua_newtable(L);
+               int table2 = lua_gettop(L);
+               int internal_index=1;
+               for (std::set<std::string>::iterator iter = games[i].addon_mods_paths.begin();
+                               iter != games[i].addon_mods_paths.end(); iter++) {
+                       lua_pushnumber(L,internal_index);
+                       lua_pushstring(L,(*iter).c_str());
+                       lua_settable(L, table2);
+                       internal_index++;
+               }
+               lua_settable(L, top_lvl2);
+               lua_settable(L, top);
+               index++;
+       }
+       return 1;
+}
+/******************************************************************************/
+int ModApiMainMenu::l_get_modstore_details(lua_State *L)
+{
+       const char *modid       = luaL_checkstring(L, 1);
+
+       if (modid != 0) {
+               Json::Value details;
+               std::string url = "";
+               try{
+                       url = g_settings->get("modstore_details_url");
+               }
+               catch(SettingNotFoundException &e) {
+                       lua_pushnil(L);
+                       return 1;
+               }
+
+               size_t idpos = url.find("*");
+               url.erase(idpos,1);
+               url.insert(idpos,modid);
+
+               details = getModstoreUrl(url);
+
+               ModStoreModDetails current_mod = readModStoreModDetails(details);
+
+               if ( current_mod.valid) {
+                       lua_newtable(L);
+                       int top = lua_gettop(L);
+
+                       lua_pushstring(L,"id");
+                       lua_pushnumber(L,current_mod.id);
+                       lua_settable(L, top);
+
+                       lua_pushstring(L,"title");
+                       lua_pushstring(L,current_mod.title.c_str());
+                       lua_settable(L, top);
+
+                       lua_pushstring(L,"basename");
+                       lua_pushstring(L,current_mod.basename.c_str());
+                       lua_settable(L, top);
+
+                       lua_pushstring(L,"description");
+                       lua_pushstring(L,current_mod.description.c_str());
+                       lua_settable(L, top);
+
+                       lua_pushstring(L,"author");
+                       lua_pushstring(L,current_mod.author.username.c_str());
+                       lua_settable(L, top);
+
+                       lua_pushstring(L,"download_url");
+                       lua_pushstring(L,current_mod.versions[0].file.c_str());
+                       lua_settable(L, top);
+
+                       lua_pushstring(L,"screenshot_url");
+                       lua_pushstring(L,current_mod.titlepic.file.c_str());
+                       lua_settable(L, top);
+
+                       lua_pushstring(L,"license");
+                       lua_pushstring(L,current_mod.license.shortinfo.c_str());
+                       lua_settable(L, top);
+
+                       lua_pushstring(L,"rating");
+                       lua_pushnumber(L,current_mod.rating);
+                       lua_settable(L, top);
+
+                       //TODO depends
+
+                       //TODO softdepends
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_modstore_list(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       std::string listtype = "local";
+
+       if (!lua_isnone(L,1)) {
+               listtype = luaL_checkstring(L,1);
+       }
+       Json::Value mods;
+       std::string url = "";
+       try{
+               url = g_settings->get("modstore_listmods_url");
+       }
+       catch(SettingNotFoundException &e) {
+               lua_pushnil(L);
+               return 1;
+       }
+
+       mods = getModstoreUrl(url);
+
+       std::vector<ModStoreMod> moddata = readModStoreList(mods);
+
+       lua_newtable(L);
+       int top = lua_gettop(L);
+       unsigned int index = 1;
+
+       for (unsigned int i = 0; i < moddata.size(); i++)
+       {
+               if (moddata[i].valid) {
+                       lua_pushnumber(L,index);
+                       lua_newtable(L);
+
+                       int top_lvl2 = lua_gettop(L);
+
+                       lua_pushstring(L,"id");
+                       lua_pushnumber(L,moddata[i].id);
+                       lua_settable(L, top_lvl2);
+
+                       lua_pushstring(L,"title");
+                       lua_pushstring(L,moddata[i].title.c_str());
+                       lua_settable(L, top_lvl2);
+
+                       lua_pushstring(L,"basename");
+                       lua_pushstring(L,moddata[i].basename.c_str());
+                       lua_settable(L, top_lvl2);
+
+                       lua_settable(L, top);
+                       index++;
+               }
+       }
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_favorites(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       std::string listtype = "local";
+
+       if (!lua_isnone(L,1)) {
+               listtype = luaL_checkstring(L,1);
+       }
+
+       std::vector<ServerListSpec> servers;
+#if USE_CURL
+       if(listtype == "online") {
+               servers = ServerList::getOnline();
+       } else {
+               servers = ServerList::getLocal();
+       }
+#else
+       servers = ServerList::getLocal();
+#endif
+
+       lua_newtable(L);
+       int top = lua_gettop(L);
+       unsigned int index = 1;
+
+       for (unsigned int i = 0; i < servers.size(); i++)
+       {
+               lua_pushnumber(L,index);
+
+               lua_newtable(L);
+               int top_lvl2 = lua_gettop(L);
+
+               if (servers[i]["clients"].asString().size()) {
+
+                       const char* clients_raw = servers[i]["clients"].asString().c_str();
+                       char* endptr = 0;
+                       int numbervalue = strtol(clients_raw,&endptr,10);
+
+                       if ((*clients_raw != 0) && (*endptr == 0)) {
+                               lua_pushstring(L,"clients");
+                               lua_pushnumber(L,numbervalue);
+                               lua_settable(L, top_lvl2);
+                       }
+               }
+
+               if (servers[i]["clients_max"].asString().size()) {
+
+                       const char* clients_max_raw = servers[i]["clients_max"].asString().c_str();
+                       char* endptr = 0;
+                       int numbervalue = strtol(clients_max_raw,&endptr,10);
+
+                       if ((*clients_max_raw != 0) && (*endptr == 0)) {
+                               lua_pushstring(L,"clients_max");
+                               lua_pushnumber(L,numbervalue);
+                               lua_settable(L, top_lvl2);
+                       }
+               }
+
+               if (servers[i]["version"].asString().size()) {
+                       lua_pushstring(L,"version");
+                       lua_pushstring(L,servers[i]["version"].asString().c_str());
+                       lua_settable(L, top_lvl2);
+               }
+
+               if (servers[i]["password"].asString().size()) {
+                       lua_pushstring(L,"password");
+                       lua_pushboolean(L,true);
+                       lua_settable(L, top_lvl2);
+               }
+
+               if (servers[i]["creative"].asString().size()) {
+                       lua_pushstring(L,"creative");
+                       lua_pushboolean(L,true);
+                       lua_settable(L, top_lvl2);
+               }
+
+               if (servers[i]["damage"].asString().size()) {
+                       lua_pushstring(L,"damage");
+                       lua_pushboolean(L,true);
+                       lua_settable(L, top_lvl2);
+               }
+
+               if (servers[i]["pvp"].asString().size()) {
+                       lua_pushstring(L,"pvp");
+                       lua_pushboolean(L,true);
+                       lua_settable(L, top_lvl2);
+               }
+
+               if (servers[i]["description"].asString().size()) {
+                       lua_pushstring(L,"description");
+                       lua_pushstring(L,servers[i]["description"].asString().c_str());
+                       lua_settable(L, top_lvl2);
+               }
+
+               if (servers[i]["name"].asString().size()) {
+                       lua_pushstring(L,"name");
+                       lua_pushstring(L,servers[i]["name"].asString().c_str());
+                       lua_settable(L, top_lvl2);
+               }
+
+               if (servers[i]["address"].asString().size()) {
+                       lua_pushstring(L,"address");
+                       lua_pushstring(L,servers[i]["address"].asString().c_str());
+                       lua_settable(L, top_lvl2);
+               }
+
+               if (servers[i]["port"].asString().size()) {
+                       lua_pushstring(L,"port");
+                       lua_pushstring(L,servers[i]["port"].asString().c_str());
+                       lua_settable(L, top_lvl2);
+               }
+
+               lua_settable(L, top);
+               index++;
+       }
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_delete_favorite(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       std::vector<ServerListSpec> servers;
+
+       std::string listtype = "local";
+
+       if (!lua_isnone(L,2)) {
+               listtype = luaL_checkstring(L,2);
+       }
+
+       if ((listtype != "local") &&
+               (listtype != "online"))
+               return 0;
+
+#if USE_CURL
+       if(listtype == "online") {
+               servers = ServerList::getOnline();
+       } else {
+               servers = ServerList::getLocal();
+       }
+#else
+       servers = ServerList::getLocal();
+#endif
+
+       int fav_idx     = luaL_checkinteger(L,1) -1;
+
+       if ((fav_idx >= 0) &&
+                       (fav_idx < (int) servers.size())) {
+
+               ServerList::deleteEntry(servers[fav_idx]);
+       }
+
+       return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_show_keys_menu(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       GUIKeyChangeMenu *kmenu
+               = new GUIKeyChangeMenu( engine->m_device->getGUIEnvironment(),
+                                                               engine->m_parent,
+                                                               -1,
+                                                               engine->m_menumanager);
+       kmenu->drop();
+       return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_create_world(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       const char *name        = luaL_checkstring(L, 1);
+       int gameidx                     = luaL_checkinteger(L,2) -1;
+
+       std::string path = porting::path_user + DIR_DELIM
+                       "worlds" + DIR_DELIM
+                       + name;
+
+       std::vector<SubgameSpec> games = getAvailableGames();
+
+       if ((gameidx >= 0) &&
+                       (gameidx < (int) games.size())) {
+
+               // Create world if it doesn't exist
+               if(!initializeWorld(path, games[gameidx].id)){
+                       lua_pushstring(L, "Failed to initialize world");
+
+               }
+               else {
+               lua_pushnil(L);
+               }
+       }
+       else {
+               lua_pushstring(L, "Invalid game index");
+       }
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_delete_world(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       int worldidx    = luaL_checkinteger(L,1) -1;
+
+       std::vector<WorldSpec> worlds = getAvailableWorlds();
+
+       if ((worldidx >= 0) &&
+               (worldidx < (int) worlds.size())) {
+
+               WorldSpec spec = worlds[worldidx];
+
+               std::vector<std::string> paths;
+               paths.push_back(spec.path);
+               fs::GetRecursiveSubPaths(spec.path, paths);
+
+               // Delete files
+               if (!fs::DeletePaths(paths)) {
+                       lua_pushstring(L, "Failed to delete world");
+               }
+               else {
+                       lua_pushnil(L);
+               }
+       }
+       else {
+               lua_pushstring(L, "Invalid world index");
+       }
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_set_topleft_text(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       std::string text = "";
+
+       if (!lua_isnone(L,1) && !lua_isnil(L,1))
+               text = luaL_checkstring(L, 1);
+
+       engine->setTopleftText(text);
+       return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_modpath(lua_State *L)
+{
+       std::string modpath
+                       = fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "mods" + DIR_DELIM);
+       lua_pushstring(L, modpath.c_str());
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_gamepath(lua_State *L)
+{
+       std::string gamepath
+                       = fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "games" + DIR_DELIM);
+       lua_pushstring(L, gamepath.c_str());
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_texturepath(lua_State *L)
+{
+       std::string gamepath
+                       = fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "textures");
+       lua_pushstring(L, gamepath.c_str());
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_dirlist(lua_State *L)
+{
+       const char *path        = luaL_checkstring(L, 1);
+       bool dironly            = lua_toboolean(L, 2);
+
+       std::vector<fs::DirListNode> dirlist = fs::GetDirListing(path);
+
+       unsigned int index = 1;
+       lua_newtable(L);
+       int table = lua_gettop(L);
+
+       for (unsigned int i=0;i< dirlist.size(); i++) {
+               if ((dirlist[i].dir) || (dironly == false)) {
+                       lua_pushnumber(L,index);
+                       lua_pushstring(L,dirlist[i].name.c_str());
+                       lua_settable(L, table);
+                       index++;
+               }
+       }
+
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_create_dir(lua_State *L) {
+       const char *path        = luaL_checkstring(L, 1);
+
+       if (ModApiMainMenu::isMinetestPath(path)) {
+               lua_pushboolean(L,fs::CreateAllDirs(path));
+               return 1;
+       }
+       lua_pushboolean(L,false);
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_delete_dir(lua_State *L)
+{
+       const char *path        = luaL_checkstring(L, 1);
+
+       std::string absolute_path = fs::RemoveRelativePathComponents(path);
+
+       if (ModApiMainMenu::isMinetestPath(absolute_path)) {
+               lua_pushboolean(L,fs::RecursiveDelete(absolute_path));
+               return 1;
+       }
+       lua_pushboolean(L,false);
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_copy_dir(lua_State *L)
+{
+       const char *source      = luaL_checkstring(L, 1);
+       const char *destination = luaL_checkstring(L, 2);
+
+       bool keep_source = true;
+
+       if ((!lua_isnone(L,3)) &&
+                       (!lua_isnil(L,3))) {
+               keep_source = lua_toboolean(L,3);
+       }
+
+       std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
+       std::string absolute_source = fs::RemoveRelativePathComponents(source);
+
+       if ((ModApiMainMenu::isMinetestPath(absolute_source)) &&
+                       (ModApiMainMenu::isMinetestPath(absolute_destination))) {
+               bool retval = fs::CopyDir(absolute_source,absolute_destination);
+
+               if (retval && (!keep_source)) {
+
+                       retval &= fs::RecursiveDelete(absolute_source);
+               }
+               lua_pushboolean(L,retval);
+               return 1;
+       }
+       lua_pushboolean(L,false);
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_extract_zip(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       const char *zipfile     = luaL_checkstring(L, 1);
+       const char *destination = luaL_checkstring(L, 2);
+
+       std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
+
+       if (ModApiMainMenu::isMinetestPath(absolute_destination)) {
+               fs::CreateAllDirs(absolute_destination);
+
+               io::IFileSystem* fs = engine->m_device->getFileSystem();
+
+               fs->addFileArchive(zipfile,true,false,io::EFAT_ZIP);
+
+               assert(fs->getFileArchiveCount() > 0);
+
+               /**********************************************************************/
+               /* WARNING this is not threadsafe!!                                   */
+               /**********************************************************************/
+               io::IFileArchive* opened_zip =
+                       fs->getFileArchive(fs->getFileArchiveCount()-1);
+
+               const io::IFileList* files_in_zip = opened_zip->getFileList();
+
+               unsigned int number_of_files = files_in_zip->getFileCount();
+
+               for (unsigned int i=0; i < number_of_files;  i++) {
+                       std::string fullpath = destination;
+                       fullpath += DIR_DELIM;
+                       fullpath += files_in_zip->getFullFileName(i).c_str();
+
+                       if (files_in_zip->isDirectory(i)) {
+                               if (! fs::CreateAllDirs(fullpath) ) {
+                                       fs->removeFileArchive(fs->getFileArchiveCount()-1);
+                                       lua_pushboolean(L,false);
+                                       return 1;
+                               }
+                       }
+                       else {
+                               io::IReadFile* toread = opened_zip->createAndOpenFile(i);
+
+                               FILE *targetfile = fopen(fullpath.c_str(),"wb");
+
+                               if (targetfile == NULL) {
+                                       fs->removeFileArchive(fs->getFileArchiveCount()-1);
+                                       lua_pushboolean(L,false);
+                                       return 1;
+                               }
+
+                               char read_buffer[1024];
+                               unsigned int total_read = 0;
+
+                               while (total_read < toread->getSize()) {
+
+                                       unsigned int bytes_read =
+                                                       toread->read(read_buffer,sizeof(read_buffer));
+                                       unsigned int bytes_written;
+                                       if ((bytes_read < 0 ) ||
+                                               (bytes_written = fwrite(read_buffer, 1, bytes_read, targetfile) != bytes_read))
+                                       {
+                                               fclose(targetfile);
+                                               fs->removeFileArchive(fs->getFileArchiveCount()-1);
+                                               lua_pushboolean(L,false);
+                                               return 1;
+                                       }
+                                       total_read += bytes_read;
+                               }
+
+                               fclose(targetfile);
+                       }
+
+               }
+
+               fs->removeFileArchive(fs->getFileArchiveCount()-1);
+               lua_pushboolean(L,true);
+               return 1;
+       }
+
+       lua_pushboolean(L,false);
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_scriptdir(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       lua_pushstring(L,engine->getScriptDir().c_str());
+       return 1;
+}
+
+/******************************************************************************/
+bool ModApiMainMenu::isMinetestPath(std::string path)
+{
+       if (fs::PathStartsWith(path,fs::TempPath()))
+               return true;
+
+       /* games */
+       if (fs::PathStartsWith(path,fs::RemoveRelativePathComponents(porting::path_share + DIR_DELIM + "games")))
+               return true;
+
+       /* mods */
+       if (fs::PathStartsWith(path,fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "mods")))
+               return true;
+
+       /* worlds */
+       if (fs::PathStartsWith(path,fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM + "worlds")))
+               return true;
+
+
+       return false;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_show_file_open_dialog(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       const char *formname= luaL_checkstring(L, 1);
+       const char *title       = luaL_checkstring(L, 2);
+
+       GUIFileSelectMenu* fileOpenMenu =
+               new GUIFileSelectMenu(engine->m_device->getGUIEnvironment(),
+                                                               engine->m_parent,
+                                                               -1,
+                                                               engine->m_menumanager,
+                                                               title,
+                                                               formname);
+       fileOpenMenu->setTextDest(engine->m_buttonhandler);
+       fileOpenMenu->drop();
+       return 0;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_get_version(lua_State *L)
+{
+       lua_pushstring(L,VERSION_STRING);
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_sound_play(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+
+       SimpleSoundSpec spec;
+       read_soundspec(L, 1, spec);
+       bool looped = lua_toboolean(L, 2);
+
+       u32 handle = engine->playSound(spec, looped);
+
+       lua_pushinteger(L, handle);
+
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_sound_stop(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+
+       u32 handle = luaL_checkinteger(L, 1);
+       engine->stopSound(handle);
+
+       return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_download_file(lua_State *L)
+{
+       GUIEngine* engine = getGuiEngine(L);
+       assert(engine != 0);
+
+       const char *url    = luaL_checkstring(L, 1);
+       const char *target = luaL_checkstring(L, 2);
+
+       //check path
+       std::string absolute_destination = fs::RemoveRelativePathComponents(target);
+
+       if (ModApiMainMenu::isMinetestPath(absolute_destination)) {
+               if (engine->downloadFile(url,absolute_destination)) {
+                       lua_pushboolean(L,true);
+                       return 1;
+               }
+       }
+       lua_pushboolean(L,false);
+       return 1;
+}
+
+/******************************************************************************/
+void ModApiMainMenu::Initialize(lua_State *L, int top)
+{
+       API_FCT(update_formspec);
+       API_FCT(set_clouds);
+       API_FCT(get_textlist_index);
+       API_FCT(get_worlds);
+       API_FCT(get_games);
+       API_FCT(start);
+       API_FCT(close);
+       API_FCT(get_favorites);
+       API_FCT(show_keys_menu);
+       API_FCT(create_world);
+       API_FCT(delete_world);
+       API_FCT(delete_favorite);
+       API_FCT(set_background);
+       API_FCT(set_topleft_text);
+       API_FCT(get_modpath);
+       API_FCT(get_gamepath);
+       API_FCT(get_texturepath);
+       API_FCT(get_dirlist);
+       API_FCT(create_dir);
+       API_FCT(delete_dir);
+       API_FCT(copy_dir);
+       API_FCT(extract_zip);
+       API_FCT(get_scriptdir);
+       API_FCT(show_file_open_dialog);
+       API_FCT(get_version);
+       API_FCT(download_file);
+       API_FCT(get_modstore_details);
+       API_FCT(get_modstore_list);
+       API_FCT(sound_play);
+       API_FCT(sound_stop);
+}
diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h
new file mode 100644 (file)
index 0000000..21dd82c
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+Minetest
+Copyright (C) 2013 sapier
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef L_MAINMENU_H_
+#define L_MAINMENU_H_
+
+#include "lua_api/l_base.h"
+
+/** Implementation of lua api support for mainmenu */
+class ModApiMainMenu : public ModApiBase {
+
+private:
+       /**
+        * read a text variable from gamedata table within lua stack
+        * @param L stack to read variable from
+        * @param name name of variable to read
+        * @return string value of requested variable
+        */
+       static std::string getTextData(lua_State *L, std::string name);
+
+       /**
+        * read a integer variable from gamedata table within lua stack
+        * @param L stack to read variable from
+        * @param name name of variable to read
+        * @return integer value of requested variable
+        */
+       static int getIntegerData(lua_State *L, std::string name,bool& valid);
+
+       /**
+        * read a bool variable from gamedata table within lua stack
+        * @param L stack to read variable from
+        * @param name name of variable to read
+        * @return bool value of requested variable
+        */
+       static int getBoolData(lua_State *L, std::string name,bool& valid);
+
+       /**
+        * check if a path is within some of minetests folders
+        * @param path path to check
+        * @return true/false
+        */
+       static bool isMinetestPath(std::string path);
+
+       //api calls
+
+       static int l_start(lua_State *L);
+
+       static int l_close(lua_State *L);
+
+       static int l_create_world(lua_State *L);
+
+       static int l_delete_world(lua_State *L);
+
+       static int l_get_worlds(lua_State *L);
+
+       static int l_get_games(lua_State *L);
+
+       static int l_get_favorites(lua_State *L);
+
+       static int l_delete_favorite(lua_State *L);
+
+       static int l_get_version(lua_State *L);
+
+       static int l_sound_play(lua_State *L);
+
+       static int l_sound_stop(lua_State *L);
+
+       //gui
+
+       static int l_show_keys_menu(lua_State *L);
+
+       static int l_show_file_open_dialog(lua_State *L);
+
+       static int l_set_topleft_text(lua_State *L);
+
+       static int l_set_clouds(lua_State *L);
+
+       static int l_get_textlist_index(lua_State *L);
+
+       static int l_set_background(lua_State *L);
+
+       static int l_update_formspec(lua_State *L);
+
+       //filesystem
+
+       static int l_get_scriptdir(lua_State *L);
+
+       static int l_get_modpath(lua_State *L);
+
+       static int l_get_gamepath(lua_State *L);
+       
+       static int l_get_texturepath(lua_State *L);
+
+       static int l_get_dirlist(lua_State *L);
+
+       static int l_create_dir(lua_State *L);
+
+       static int l_delete_dir(lua_State *L);
+
+       static int l_copy_dir(lua_State *L);
+
+       static int l_extract_zip(lua_State *L);
+
+       static int l_get_modstore_details(lua_State *L);
+
+       static int l_get_modstore_list(lua_State *L);
+
+       static int l_download_file(lua_State *L);
+
+
+public:
+       /**
+        * initialize this API module
+        * @param L lua stack to initialize
+        * @param top index (in lua stack) of global API table
+        */
+       static void Initialize(lua_State *L, int top);
+
+};
+
+#endif /* L_MAINMENU_H_ */
diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp
new file mode 100644 (file)
index 0000000..14693b4
--- /dev/null
@@ -0,0 +1,574 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "lua_api/l_mapgen.h"
+#include "lua_api/l_internal.h"
+#include "lua_api/l_vmanip.h"
+#include "common/c_converter.h"
+#include "common/c_content.h"
+#include "server.h"
+#include "environment.h"
+#include "biome.h"
+#include "emerge.h"
+#include "mapgen_v7.h"
+
+
+struct EnumString ModApiMapgen::es_BiomeTerrainType[] =
+{
+       {BIOME_TERRAIN_NORMAL, "normal"},
+       {BIOME_TERRAIN_LIQUID, "liquid"},
+       {BIOME_TERRAIN_NETHER, "nether"},
+       {BIOME_TERRAIN_AETHER, "aether"},
+       {BIOME_TERRAIN_FLAT,   "flat"},
+       {0, NULL},
+};
+
+struct EnumString ModApiMapgen::es_DecorationType[] =
+{
+       {DECO_SIMPLE,    "simple"},
+       {DECO_SCHEMATIC, "schematic"},
+       {DECO_LSYSTEM,   "lsystem"},
+       {0, NULL},
+};
+
+struct EnumString ModApiMapgen::es_MapgenObject[] =
+{
+       {MGOBJ_VMANIP,    "voxelmanip"},
+       {MGOBJ_HEIGHTMAP, "heightmap"},
+       {MGOBJ_BIOMEMAP,  "biomemap"},
+       {MGOBJ_HEATMAP,   "heatmap"},
+       {MGOBJ_HUMIDMAP,  "humiditymap"},
+       {0, NULL},
+};
+
+struct EnumString ModApiMapgen::es_OreType[] =
+{
+       {ORE_SCATTER,  "scatter"},
+       {ORE_SHEET,    "sheet"},
+       {ORE_CLAYLIKE, "claylike"},
+       {0, NULL},
+};
+
+struct EnumString ModApiMapgen::es_Rotation[] =
+{
+       {ROTATE_0,    "0"},
+       {ROTATE_90,   "90"},
+       {ROTATE_180,  "180"},
+       {ROTATE_270,  "270"},
+       {ROTATE_RAND, "random"},
+       {0, NULL},
+};
+
+
+// minetest.get_mapgen_object(objectname)
+// returns the requested object used during map generation
+int ModApiMapgen::l_get_mapgen_object(lua_State *L)
+{
+       const char *mgobjstr = lua_tostring(L, 1);
+       
+       int mgobjint;
+       if (!string_to_enum(es_MapgenObject, mgobjint, mgobjstr ? mgobjstr : ""))
+               return 0;
+               
+       enum MapgenObject mgobj = (MapgenObject)mgobjint;
+
+       EmergeManager *emerge = getServer(L)->getEmergeManager();
+       Mapgen *mg = emerge->getCurrentMapgen();
+       if (!mg)
+               return 0;
+       
+       size_t maplen = mg->csize.X * mg->csize.Z;
+       
+       int nargs = 1;
+       
+       switch (mgobj) {
+               case MGOBJ_VMANIP: {
+                       ManualMapVoxelManipulator *vm = mg->vm;
+                       
+                       // VoxelManip object
+                       LuaVoxelManip *o = new LuaVoxelManip(vm, true);
+                       *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+                       luaL_getmetatable(L, "VoxelManip");
+                       lua_setmetatable(L, -2);
+                       
+                       // emerged min pos
+                       push_v3s16(L, vm->m_area.MinEdge);
+
+                       // emerged max pos
+                       push_v3s16(L, vm->m_area.MaxEdge);
+                       
+                       nargs = 3;
+                       
+                       break; }
+               case MGOBJ_HEIGHTMAP: {
+                       if (!mg->heightmap)
+                               return 0;
+                       
+                       lua_newtable(L);
+                       for (size_t i = 0; i != maplen; i++) {
+                               lua_pushinteger(L, mg->heightmap[i]);
+                               lua_rawseti(L, -2, i + 1);
+                       }
+                       break; }
+               case MGOBJ_BIOMEMAP: {
+                       if (!mg->biomemap)
+                               return 0;
+                       
+                       lua_newtable(L);
+                       for (size_t i = 0; i != maplen; i++) {
+                               lua_pushinteger(L, mg->biomemap[i]);
+                               lua_rawseti(L, -2, i + 1);
+                       }
+                       break; }
+               case MGOBJ_HEATMAP: { // Mapgen V7 specific objects
+               case MGOBJ_HUMIDMAP:
+                       if (strcmp(emerge->params->mg_name.c_str(), "v7"))
+                               return 0;
+                       
+                       MapgenV7 *mgv7 = (MapgenV7 *)mg;
+
+                       float *arr = (mgobj == MGOBJ_HEATMAP) ? 
+                               mgv7->noise_heat->result : mgv7->noise_humidity->result;
+                       if (!arr)
+                               return 0;
+                       
+                       lua_newtable(L);
+                       for (size_t i = 0; i != maplen; i++) {
+                               lua_pushnumber(L, arr[i]);
+                               lua_rawseti(L, -2, i + 1);
+                       }
+                       break; }
+       }
+       
+       return nargs;
+}
+
+// minetest.set_mapgen_params(params)
+// set mapgen parameters
+int ModApiMapgen::l_set_mapgen_params(lua_State *L)
+{
+       if (!lua_istable(L, 1))
+               return 0;
+
+       EmergeManager *emerge = getServer(L)->getEmergeManager();
+       if (emerge->mapgen.size())
+               return 0;
+       
+       MapgenParams *oparams = new MapgenParams;
+       u32 paramsmodified = 0;
+       u32 flagmask = 0;
+       
+       lua_getfield(L, 1, "mgname");
+       if (lua_isstring(L, -1)) {
+               oparams->mg_name = std::string(lua_tostring(L, -1));
+               paramsmodified |= MGPARAMS_SET_MGNAME;
+       }
+       
+       lua_getfield(L, 1, "seed");
+       if (lua_isnumber(L, -1)) {
+               oparams->seed = lua_tointeger(L, -1);
+               paramsmodified |= MGPARAMS_SET_SEED;
+       }
+       
+       lua_getfield(L, 1, "water_level");
+       if (lua_isnumber(L, -1)) {
+               oparams->water_level = lua_tointeger(L, -1);
+               paramsmodified |= MGPARAMS_SET_WATER_LEVEL;
+       }
+
+       lua_getfield(L, 1, "flags");
+       if (lua_isstring(L, -1)) {
+               std::string flagstr = std::string(lua_tostring(L, -1));
+               oparams->flags = readFlagString(flagstr, flagdesc_mapgen);
+               paramsmodified |= MGPARAMS_SET_FLAGS;
+       
+               lua_getfield(L, 1, "flagmask");
+               if (lua_isstring(L, -1)) {
+                       flagstr = std::string(lua_tostring(L, -1));
+                       flagmask = readFlagString(flagstr, flagdesc_mapgen);
+               }
+       }
+       
+       emerge->luaoverride_params          = oparams;
+       emerge->luaoverride_params_modified = paramsmodified;
+       emerge->luaoverride_flagmask        = flagmask;
+       
+       return 0;
+}
+
+// register_biome({lots of stuff})
+int ModApiMapgen::l_register_biome(lua_State *L)
+{
+       int index = 1;
+       luaL_checktype(L, index, LUA_TTABLE);
+
+       BiomeDefManager *bmgr = getServer(L)->getEmergeManager()->biomedef;
+       if (!bmgr) {
+               verbosestream << "register_biome: BiomeDefManager not active" << std::endl;
+               return 0;
+       }
+
+       enum BiomeTerrainType terrain = (BiomeTerrainType)getenumfield(L, index,
+                               "terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL);
+       Biome *b = bmgr->createBiome(terrain);
+
+       b->name         = getstringfield_default(L, index, "name",
+                                                                                               "<no name>");
+       b->nname_top    = getstringfield_default(L, index, "node_top",
+                                                                                               "mapgen_dirt_with_grass");
+       b->nname_filler = getstringfield_default(L, index, "node_filler",
+                                                                                               "mapgen_dirt");
+       b->nname_water  = getstringfield_default(L, index, "node_water",
+                                                                                               "mapgen_water_source");
+       b->nname_dust   = getstringfield_default(L, index, "node_dust",
+                                                                                               "air");
+       b->nname_dust_water = getstringfield_default(L, index, "node_dust_water",
+                                                                                               "mapgen_water_source");
+       
+       b->depth_top      = getintfield_default(L, index, "depth_top",    1);
+       b->depth_filler   = getintfield_default(L, index, "depth_filler", 3);
+       b->height_min     = getintfield_default(L, index, "height_min",   0);
+       b->height_max     = getintfield_default(L, index, "height_max",   0);
+       b->heat_point     = getfloatfield_default(L, index, "heat_point",     0.);
+       b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.);
+
+       b->flags        = 0; //reserved
+       b->c_top        = CONTENT_IGNORE;
+       b->c_filler     = CONTENT_IGNORE;
+       b->c_water      = CONTENT_IGNORE;
+       b->c_dust       = CONTENT_IGNORE;
+       b->c_dust_water = CONTENT_IGNORE;
+       
+       verbosestream << "register_biome: " << b->name << std::endl;
+       bmgr->addBiome(b);
+
+       return 0;
+}
+
+// register_decoration({lots of stuff})
+int ModApiMapgen::l_register_decoration(lua_State *L)
+{
+       int index = 1;
+       luaL_checktype(L, index, LUA_TTABLE);
+
+       EmergeManager *emerge = getServer(L)->getEmergeManager();
+       BiomeDefManager *bdef = emerge->biomedef;
+
+       enum DecorationType decotype = (DecorationType)getenumfield(L, index,
+                               "deco_type", es_DecorationType, -1);
+       if (decotype == -1) {
+               errorstream << "register_decoration: unrecognized "
+                       "decoration placement type";
+               return 0;
+       }
+       
+       Decoration *deco = createDecoration(decotype);
+       if (!deco) {
+               errorstream << "register_decoration: decoration placement type "
+                       << decotype << " not implemented";
+               return 0;
+       }
+
+       deco->c_place_on    = CONTENT_IGNORE;
+       deco->place_on_name = getstringfield_default(L, index, "place_on", "ignore");
+       deco->fill_ratio    = getfloatfield_default(L, index, "fill_ratio", 0.02);
+       deco->sidelen       = getintfield_default(L, index, "sidelen", 8);
+       if (deco->sidelen <= 0) {
+               errorstream << "register_decoration: sidelen must be "
+                       "greater than 0" << std::endl;
+               delete deco;
+               return 0;
+       }
+       
+       lua_getfield(L, index, "noise_params");
+       deco->np = read_noiseparams(L, -1);
+       lua_pop(L, 1);
+       
+       lua_getfield(L, index, "biomes");
+       if (lua_istable(L, -1)) {
+               lua_pushnil(L);
+               while (lua_next(L, -2)) {
+                       const char *s = lua_tostring(L, -1);
+                       u8 biomeid = bdef->getBiomeIdByName(s);
+                       if (biomeid)
+                               deco->biomes.insert(biomeid);
+
+                       lua_pop(L, 1);
+               }
+               lua_pop(L, 1);
+       }
+       
+       switch (decotype) {
+               case DECO_SIMPLE: {
+                       DecoSimple *dsimple = (DecoSimple *)deco;
+                       dsimple->c_deco     = CONTENT_IGNORE;
+                       dsimple->c_spawnby  = CONTENT_IGNORE;
+                       dsimple->spawnby_name    = getstringfield_default(L, index, "spawn_by", "air");
+                       dsimple->deco_height     = getintfield_default(L, index, "height", 1);
+                       dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0);
+                       dsimple->nspawnby        = getintfield_default(L, index, "num_spawn_by", -1);
+                       
+                       lua_getfield(L, index, "decoration");
+                       if (lua_istable(L, -1)) {
+                               lua_pushnil(L);
+                               while (lua_next(L, -2)) {
+                                       const char *s = lua_tostring(L, -1);
+                                       std::string str(s);
+                                       dsimple->decolist_names.push_back(str);
+
+                                       lua_pop(L, 1);
+                               }
+                       } else if (lua_isstring(L, -1)) {
+                               dsimple->deco_name = std::string(lua_tostring(L, -1));
+                       } else {
+                               dsimple->deco_name = std::string("air");
+                       }
+                       lua_pop(L, 1);
+                       
+                       if (dsimple->deco_height <= 0) {
+                               errorstream << "register_decoration: simple decoration height"
+                                       " must be greater than 0" << std::endl;
+                               delete dsimple;
+                               return 0;
+                       }
+
+                       break; }
+               case DECO_SCHEMATIC: {
+                       DecoSchematic *dschem = (DecoSchematic *)deco;
+                       dschem->flags    = getflagsfield(L, index, "flags", flagdesc_deco_schematic);
+                       dschem->rotation = (Rotation)getenumfield(L, index,
+                                                               "rotation", es_Rotation, ROTATE_0);
+
+                       lua_getfield(L, index, "replacements");
+                       if (lua_istable(L, -1)) {
+                               int i = lua_gettop(L);
+                               lua_pushnil(L);
+                               while (lua_next(L, i) != 0) {
+                                       // key at index -2 and value at index -1
+                                       lua_rawgeti(L, -1, 1);
+                                       std::string replace_from = lua_tostring(L, -1);
+                                       lua_pop(L, 1);
+                                       lua_rawgeti(L, -1, 2);
+                                       std::string replace_to = lua_tostring(L, -1);
+                                       lua_pop(L, 1);
+                                       dschem->replacements[replace_from] = replace_to;
+                                       // removes value, keeps key for next iteration
+                                       lua_pop(L, 1);
+                               }
+                       }
+                       lua_pop(L, 1);
+
+                       lua_getfield(L, index, "schematic");
+                       if (!read_schematic(L, -1, dschem, getServer(L))) {
+                               delete dschem;
+                               return 0;
+                       }
+                       lua_pop(L, -1);
+                       
+                       if (!dschem->filename.empty() && !dschem->loadSchematicFile()) {
+                               errorstream << "register_decoration: failed to load schematic file '"
+                                       << dschem->filename << "'" << std::endl;
+                               delete dschem;
+                               return 0;
+                       }
+                       break; }
+               case DECO_LSYSTEM: {
+                       //DecoLSystem *decolsystem = (DecoLSystem *)deco;
+               
+                       break; }
+       }
+
+       emerge->decorations.push_back(deco);
+
+       verbosestream << "register_decoration: decoration '" << deco->getName()
+               << "' registered" << std::endl;
+       return 0;
+}
+
+// register_ore({lots of stuff})
+int ModApiMapgen::l_register_ore(lua_State *L)
+{
+       int index = 1;
+       luaL_checktype(L, index, LUA_TTABLE);
+
+       EmergeManager *emerge = getServer(L)->getEmergeManager();
+
+       enum OreType oretype = (OreType)getenumfield(L, index,
+                               "ore_type", es_OreType, ORE_SCATTER);
+       Ore *ore = createOre(oretype);
+       if (!ore) {
+               errorstream << "register_ore: ore_type "
+                       << oretype << " not implemented";
+               return 0;
+       }
+
+       ore->ore_name       = getstringfield_default(L, index, "ore", "");
+       ore->ore_param2     = (u8)getintfield_default(L, index, "ore_param2", 0);
+       ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
+       ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
+       ore->clust_size     = getintfield_default(L, index, "clust_size", 0);
+       ore->height_min     = getintfield_default(L, index, "height_min", 0);
+       ore->height_max     = getintfield_default(L, index, "height_max", 0);
+       ore->flags          = getflagsfield(L, index, "flags", flagdesc_ore);
+       ore->nthresh        = getfloatfield_default(L, index, "noise_threshhold", 0.);
+
+       lua_getfield(L, index, "wherein");
+       if (lua_istable(L, -1)) {
+               int  i = lua_gettop(L);
+               lua_pushnil(L);
+               while(lua_next(L, i) != 0) {
+                       ore->wherein_names.push_back(lua_tostring(L, -1));
+                       lua_pop(L, 1);
+               }
+       } else if (lua_isstring(L, -1)) {
+               ore->wherein_names.push_back(lua_tostring(L, -1));
+       } else {
+               ore->wherein_names.push_back("");
+       }
+       lua_pop(L, 1);
+
+       lua_getfield(L, index, "noise_params");
+       ore->np = read_noiseparams(L, -1);
+       lua_pop(L, 1);
+
+       ore->noise = NULL;
+
+       if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) {
+               errorstream << "register_ore: clust_scarcity and clust_num_ores"
+                       "must be greater than 0" << std::endl;
+               delete ore;
+               return 0;
+       }
+
+       emerge->ores.push_back(ore);
+
+       verbosestream << "register_ore: ore '" << ore->ore_name
+               << "' registered" << std::endl;
+       return 0;
+}
+
+// create_schematic(p1, p2, probability_list, filename)
+int ModApiMapgen::l_create_schematic(lua_State *L)
+{
+       DecoSchematic dschem;
+
+       Map *map = &(getEnv(L)->getMap());
+       INodeDefManager *ndef = getServer(L)->getNodeDefManager();
+
+       v3s16 p1 = read_v3s16(L, 1);
+       v3s16 p2 = read_v3s16(L, 2);
+       sortBoxVerticies(p1, p2);
+       
+       std::vector<std::pair<v3s16, u8> > probability_list;
+       if (lua_istable(L, 3)) {
+               lua_pushnil(L);
+               while (lua_next(L, 3)) {
+                       if (lua_istable(L, -1)) {
+                               lua_getfield(L, -1, "pos");
+                               v3s16 pos = read_v3s16(L, -1);
+                               lua_pop(L, 1);
+                               
+                               u8 prob = getintfield_default(L, -1, "prob", 0xFF);
+                               probability_list.push_back(std::make_pair(pos, prob));
+                       }
+
+                       lua_pop(L, 1);
+               }
+       }
+       
+       dschem.filename = std::string(lua_tostring(L, 4));
+
+       if (!dschem.getSchematicFromMap(map, p1, p2)) {
+               errorstream << "create_schematic: failed to get schematic "
+                       "from map" << std::endl;
+               return 0;
+       }
+       
+       dschem.applyProbabilities(&probability_list, p1);
+       
+       dschem.saveSchematicFile(ndef);
+       actionstream << "create_schematic: saved schematic file '"
+               << dschem.filename << "'." << std::endl;
+
+       return 1;
+}
+
+
+// place_schematic(p, schematic, rotation, replacement)
+int ModApiMapgen::l_place_schematic(lua_State *L)
+{
+       DecoSchematic dschem;
+
+       Map *map = &(getEnv(L)->getMap());
+       INodeDefManager *ndef = getServer(L)->getNodeDefManager();
+
+       v3s16 p = read_v3s16(L, 1);
+       if (!read_schematic(L, 2, &dschem, getServer(L)))
+               return 0;
+               
+       Rotation rot = ROTATE_0;
+       if (lua_isstring(L, 3))
+               string_to_enum(es_Rotation, (int &)rot, std::string(lua_tostring(L, 3)));
+               
+       dschem.rotation = rot;
+
+       if (lua_istable(L, 4)) {
+               int index = 4;
+               lua_pushnil(L);
+               while (lua_next(L, index) != 0) {
+                       // key at index -2 and value at index -1
+                       lua_rawgeti(L, -1, 1);
+                       std::string replace_from = lua_tostring(L, -1);
+                       lua_pop(L, 1);
+                       lua_rawgeti(L, -1, 2);
+                       std::string replace_to = lua_tostring(L, -1);
+                       lua_pop(L, 1);
+                       dschem.replacements[replace_from] = replace_to;
+                       // removes value, keeps key for next iteration
+                       lua_pop(L, 1);
+               }
+       }
+
+       if (!dschem.filename.empty()) {
+               if (!dschem.loadSchematicFile()) {
+                       errorstream << "place_schematic: failed to load schematic file '"
+                               << dschem.filename << "'" << std::endl;
+                       return 0;
+               }
+               dschem.resolveNodeNames(ndef);
+       }
+       
+       dschem.placeStructure(map, p);
+
+       return 1;
+}
+
+void ModApiMapgen::Initialize(lua_State *L, int top)
+{
+       API_FCT(get_mapgen_object);
+
+       API_FCT(set_mapgen_params);
+
+       API_FCT(register_biome);
+       API_FCT(register_decoration);
+       API_FCT(register_ore);
+
+       API_FCT(create_schematic);
+       API_FCT(place_schematic);
+}
diff --git a/src/script/lua_api/l_mapgen.h b/src/script/lua_api/l_mapgen.h
new file mode 100644 (file)
index 0000000..d0da5bb
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef L_MAPGEN_H_
+#define L_MAPGEN_H_
+
+#include "lua_api/l_base.h"
+
+class ModApiMapgen : public ModApiBase {
+private:
+       // minetest.get_mapgen_object(objectname)
+       // returns the requested object used during map generation
+       static int l_get_mapgen_object(lua_State *L);
+
+       // minetest.set_mapgen_params(params)
+       // set mapgen parameters
+       static int l_set_mapgen_params(lua_State *L);
+
+       // register_biome({lots of stuff})
+       static int l_register_biome(lua_State *L);
+
+       // register_decoration({lots of stuff})
+       static int l_register_decoration(lua_State *L);
+
+       // register_ore({lots of stuff})
+       static int l_register_ore(lua_State *L);
+
+       // create_schematic(p1, p2, probability_list, filename)
+       static int l_create_schematic(lua_State *L);
+
+       // place_schematic(p, schematic, rotation, replacement)
+       static int l_place_schematic(lua_State *L);
+
+       static struct EnumString es_BiomeTerrainType[];
+       static struct EnumString es_DecorationType[];
+       static struct EnumString es_MapgenObject[];
+       static struct EnumString es_OreType[];
+       static struct EnumString es_Rotation[];
+
+public:
+       static void Initialize(lua_State *L, int top);
+};
+
+
+
+#endif /* L_MAPGEN_H_ */
index 511fb38ce298cfa94eb254f7ecf0975a4b297918..f9c8794d502d065e6b99cd42499949405e5dda6d 100644 (file)
@@ -17,13 +17,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "cpp_api/scriptapi.h"
+#include "lua_api/l_nodemeta.h"
+#include "lua_api/l_internal.h"
+#include "lua_api/l_inventory.h"
 #include "common/c_converter.h"
 #include "common/c_content.h"
+#include "environment.h"
 #include "map.h"
-#include "lua_api/l_nodemeta.h"
-#include "common/c_internal.h"
-#include "lua_api/l_inventory.h"
+#include "nodemetadata.h"
+
 
 
 /*
@@ -211,7 +213,7 @@ int NodeMetaRef::l_to_table(lua_State *L)
                std::vector<const InventoryList*> lists = inv->getLists();
                for(std::vector<const InventoryList*>::const_iterator
                                i = lists.begin(); i != lists.end(); i++){
-                       push_inventory_list(inv, (*i)->getName().c_str(), L);
+                       push_inventory_list(L, inv, (*i)->getName().c_str());
                        lua_setfield(L, -2, (*i)->getName().c_str());
                }
        }
@@ -257,7 +259,7 @@ int NodeMetaRef::l_from_table(lua_State *L)
        while(lua_next(L, inventorytable) != 0){
                // key at index -2 and value at index -1
                std::string name = lua_tostring(L, -2);
-               read_inventory_list(inv, name.c_str(), L, -1,STACK_TO_SERVER(L));
+               read_inventory_list(L, -1, inv, name.c_str(), getServer(L));
                lua_pop(L, 1); // removes value, keeps key for next iteration
        }
        reportMetadataChange(ref);
@@ -328,5 +330,3 @@ const luaL_reg NodeMetaRef::methods[] = {
        luamethod(NodeMetaRef, from_table),
        {0,0}
 };
-
-REGISTER_LUA_REF(NodeMetaRef);
index 23404a084d0bcaba811660dba37f759e4e61de09..ed06ff0fa56cd531efe1c3ca5f027ead3c049159 100644 (file)
@@ -19,20 +19,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef L_NODEMETA_H_
 #define L_NODEMETA_H_
 
-extern "C" {
-#include <lua.h>
-#include <lauxlib.h>
-}
+#include "lua_api/l_base.h"
+#include "irrlichttypes_bloated.h"
 
-#include "environment.h"
-#include "nodemetadata.h"
+class ServerEnvironment;
+class NodeMetadata;
 
 /*
        NodeMetaRef
 */
 
-class NodeMetaRef
-{
+class NodeMetaRef : public ModApiBase {
 private:
        v3s16 m_p;
        ServerEnvironment *m_env;
@@ -90,4 +87,4 @@ public:
        static void Register(lua_State *L);
 };
 
-#endif //L_NODEMETA_H_
+#endif /* L_NODEMETA_H_ */
index 60e4ec061e470013d6e54551c1c3d6d670643d7c..c81a7ebc978c9acbbf1a25eb5ba598ab5d0cebfe 100644 (file)
@@ -17,9 +17,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "cpp_api/scriptapi.h"
 #include "lua_api/l_nodetimer.h"
-#include "common/c_internal.h"
+#include "lua_api/l_internal.h"
+#include "environment.h"
 #include "map.h"
 
 
@@ -165,5 +165,3 @@ const luaL_reg NodeTimerRef::methods[] = {
        luamethod(NodeTimerRef, get_elapsed),
        {0,0}
 };
-
-REGISTER_LUA_REF(NodeTimerRef);
index f652b4900929e2cf1dd26142bb0ba93555419466..9f8dd21c8ccbfb42be883be7c15861fd3e488c7a 100644 (file)
@@ -20,15 +20,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef L_NODETIMER_H_
 #define L_NODETIMER_H_
 
-extern "C" {
-#include <lua.h>
-#include <lauxlib.h>
-}
+#include "lua_api/l_base.h"
+#include "irr_v3d.h"
 
-#include "environment.h"
+class ServerEnvironment;
 
-class NodeTimerRef
-{
+class NodeTimerRef : public ModApiBase {
 private:
        v3s16 m_p;
        ServerEnvironment *m_env;
index 43149e93c5942419164ec2256be70e0db1232dc1..ecbda9fadd5e39baba12656d2a47af6ae90934c2 100644 (file)
@@ -18,8 +18,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "lua_api/l_noise.h"
-#include "common/c_internal.h"
+#include "lua_api/l_internal.h"
 #include "common/c_converter.h"
+#include "common/c_content.h"
 #include "log.h"
 
 // garbage collector
@@ -412,7 +413,3 @@ const luaL_reg LuaPseudoRandom::methods[] = {
        luamethod(LuaPseudoRandom, next),
        {0,0}
 };
-
-REGISTER_LUA_REF(LuaPseudoRandom);
-REGISTER_LUA_REF(LuaPerlinNoiseMap);
-REGISTER_LUA_REF(LuaPerlinNoise);
index 6275ca472e64be2fe35e4dbc4ad7384873a86f68..65a9278825a0e98ed7b32141b4f52af32c38e204 100644 (file)
@@ -20,16 +20,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef L_NOISE_H_
 #define L_NOISE_H_
 
-extern "C" {
-#include <lua.h>
-#include <lauxlib.h>
-}
-
+#include "lua_api/l_base.h"
 #include "irr_v3d.h"
 #include "noise.h"
 
-class LuaPerlinNoise
-{
+/*
+       LuaPerlinNoise
+*/
+class LuaPerlinNoise : public ModApiBase {
 private:
        int seed;
        int octaves;
@@ -62,10 +60,9 @@ public:
 };
 
 /*
-  PerlinNoiseMap
- */
-class LuaPerlinNoiseMap
-{
+       LuaPerlinNoiseMap
+*/
+class LuaPerlinNoiseMap : public ModApiBase {
 private:
        Noise *noise;
        static const char className[];
@@ -95,10 +92,7 @@ public:
 /*
        LuaPseudoRandom
 */
-
-
-class LuaPseudoRandom
-{
+class LuaPseudoRandom : public ModApiBase {
 private:
        PseudoRandom m_pseudo;
 
@@ -130,6 +124,4 @@ public:
        static void Register(lua_State *L);
 };
 
-NoiseParams *read_noiseparams(lua_State *L, int index);
-
 #endif /* L_NOISE_H_ */
index ee24789c5a54e548ca9f9d4c77f4dd31c29549e8..c0da79c2991accef2bfd7f84fefce57f3cc6b7fd 100644 (file)
@@ -17,13 +17,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "cpp_api/scriptapi.h"
-#include "common/c_converter.h"
-#include "common/c_content.h"
 #include "lua_api/l_object.h"
-#include "common/c_internal.h"
+#include "lua_api/l_internal.h"
 #include "lua_api/l_inventory.h"
 #include "lua_api/l_item.h"
+#include "common/c_converter.h"
+#include "common/c_content.h"
 #include "log.h"
 #include "tool.h"
 #include "serverobject.h"
@@ -275,7 +274,7 @@ int ObjectRef::l_get_inventory(lua_State *L)
        if(co == NULL) return 0;
        // Do it
        InventoryLocation loc = co->getInventoryLocation();
-       if(STACK_TO_SERVER(L)->getInventory(loc) != NULL)
+       if(getServer(L)->getInventory(loc) != NULL)
                InvRef::create(L, loc);
        else
                lua_pushnil(L); // An object may have no inventory (nil)
@@ -330,7 +329,7 @@ int ObjectRef::l_set_wielded_item(lua_State *L)
        ServerActiveObject *co = getobject(ref);
        if(co == NULL) return 0;
        // Do it
-       ItemStack item = read_item(L, 2,STACK_TO_SERVER(L));
+       ItemStack item = read_item(L, 2, getServer(L));
        bool success = co->setWieldedItem(item);
        lua_pushboolean(L, success);
        return 1;
@@ -739,7 +738,7 @@ int ObjectRef::l_set_inventory_formspec(lua_State *L)
        std::string formspec = luaL_checkstring(L, 2);
 
        player->inventory_formspec = formspec;
-       STACK_TO_SERVER(L)->reportInventoryFormspecModified(player->getName());
+       getServer(L)->reportInventoryFormspecModified(player->getName());
        lua_pushboolean(L, true);
        return 1;
 }
@@ -841,7 +840,7 @@ int ObjectRef::l_hud_add(lua_State *L)
        elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
        lua_pop(L, 1);
 
-       u32 id = STACK_TO_SERVER(L)->hudAdd(player, elem);
+       u32 id = getServer(L)->hudAdd(player, elem);
        if (id == (u32)-1) {
                delete elem;
                return 0;
@@ -863,7 +862,7 @@ int ObjectRef::l_hud_remove(lua_State *L)
        if (!lua_isnil(L, 2))
                id = lua_tonumber(L, 2);
 
-       if (!STACK_TO_SERVER(L)->hudRemove(player, id))
+       if (!getServer(L)->hudRemove(player, id))
                return 0;
 
        lua_pushboolean(L, true);
@@ -929,7 +928,7 @@ int ObjectRef::l_hud_change(lua_State *L)
                        value = &e->offset;
        }
 
-       STACK_TO_SERVER(L)->hudChange(player, id, stat, value);
+       getServer(L)->hudChange(player, id, stat, value);
 
        lua_pushboolean(L, true);
        return 1;
@@ -999,7 +998,7 @@ int ObjectRef::l_hud_set_flags(lua_State *L)
                        mask  |= esp[i].num;
                }
        }
-       if (!STACK_TO_SERVER(L)->hudSetFlags(player, flags, mask))
+       if (!getServer(L)->hudSetFlags(player, flags, mask))
                return 0;
 
        lua_pushboolean(L, true);
@@ -1016,7 +1015,7 @@ int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L)
 
        s32 hotbar_itemcount = lua_tonumber(L, 2);
 
-       if (!STACK_TO_SERVER(L)->hudSetHotbarItemcount(player, hotbar_itemcount))
+       if (!getServer(L)->hudSetHotbarItemcount(player, hotbar_itemcount))
                return 0;
 
        lua_pushboolean(L, true);
@@ -1139,5 +1138,3 @@ const luaL_reg ObjectRef::methods[] = {
        luamethod(ObjectRef, hud_set_hotbar_itemcount),
        {0,0}
 };
-
-REGISTER_LUA_REF(ObjectRef)
index a826384421153a12f60662c767f2dc021c87fbfe..b6f5cd06f3bd24426c417de851ddaf2eec803206 100644 (file)
@@ -20,10 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef L_OBJECT_H_
 #define L_OBJECT_H_
 
-extern "C" {
-#include <lua.h>
-#include <lauxlib.h>
-}
+#include "lua_api/l_base.h"
+#include "irrlichttypes.h"
 
 class ServerActiveObject;
 class LuaEntitySAO;
@@ -34,8 +32,7 @@ class Player;
        ObjectRef
 */
 
-class ObjectRef
-{
+class ObjectRef : public ModApiBase {
 private:
        ServerActiveObject *m_object;
 
index c291cc21e375c4059c46a54ac2a9a43d2002b93b..6b009149e3e24ec9fcf09f1183dc226931ac92b5 100644 (file)
@@ -17,22 +17,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "cpp_api/scriptapi.h"
-#include "common/c_converter.h"
-#include "lua_api/l_base.h"
 #include "lua_api/l_particles.h"
+#include "lua_api/l_internal.h"
+#include "common/c_converter.h"
 #include "server.h"
-#include "common/c_internal.h"
-
-bool ModApiParticles::Initialize(lua_State *L, int top) {
-       bool retval = true;
-
-       retval &= API_FCT(add_particle);
-       retval &= API_FCT(add_particlespawner);
-       retval &= API_FCT(delete_particlespawner);
-
-       return retval;
-}
 
 // add_particle(pos, velocity, acceleration, expirationtime,
 //             size, collisiondetection, texture, player)
@@ -146,4 +134,10 @@ int ModApiParticles::l_delete_particlespawner(lua_State *L)
        return 1;
 }
 
-ModApiParticles modapiparticles_prototyp;
+void ModApiParticles::Initialize(lua_State *L, int top)
+{
+       API_FCT(add_particle);
+       API_FCT(add_particlespawner);
+       API_FCT(delete_particlespawner);
+}
+
index 3729f8761ed5637793786df7c5104d46fdedf533..c593f47e441bccaf2e00e86bbcde9841380cab78 100644 (file)
@@ -20,20 +20,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef L_PARTICLES_H_
 #define L_PARTICLES_H_
 
-extern "C" {
-#include <lua.h>
-#include <lauxlib.h>
-}
+#include "lua_api/l_base.h"
 
 class ModApiParticles : public ModApiBase {
-public:
-       bool Initialize(lua_State *L, int top);
 private:
        static int l_add_particle(lua_State *L);
        static int l_add_particlespawner(lua_State *L);
        static int l_delete_particlespawner(lua_State *L);
+
+public:
+       static void Initialize(lua_State *L, int top);
 };
 
 
 
-#endif // L_PARTICLES_H_
+#endif /* L_PARTICLES_H_ */
diff --git a/src/script/lua_api/l_rollback.cpp b/src/script/lua_api/l_rollback.cpp
new file mode 100644 (file)
index 0000000..6076399
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "lua_api/l_rollback.h"
+#include "lua_api/l_internal.h"
+#include "common/c_converter.h"
+#include "server.h"
+#include "rollback.h"
+
+
+// rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds
+int ModApiRollback::l_rollback_get_last_node_actor(lua_State *L)
+{
+       v3s16 p = read_v3s16(L, 1);
+       int range = luaL_checknumber(L, 2);
+       int seconds = luaL_checknumber(L, 3);
+       Server *server = getServer(L);
+       IRollbackManager *rollback = server->getRollbackManager();
+       v3s16 act_p;
+       int act_seconds = 0;
+       std::string actor = rollback->getLastNodeActor(p, range, seconds, &act_p, &act_seconds);
+       lua_pushstring(L, actor.c_str());
+       push_v3s16(L, act_p);
+       lua_pushnumber(L, act_seconds);
+       return 3;
+}
+
+// rollback_revert_actions_by(actor, seconds) -> bool, log messages
+int ModApiRollback::l_rollback_revert_actions_by(lua_State *L)
+{
+       std::string actor = luaL_checkstring(L, 1);
+       int seconds = luaL_checknumber(L, 2);
+       Server *server = getServer(L);
+       IRollbackManager *rollback = server->getRollbackManager();
+       std::list<RollbackAction> actions = rollback->getRevertActions(actor, seconds);
+       std::list<std::string> log;
+       bool success = server->rollbackRevertActions(actions, &log);
+       // Push boolean result
+       lua_pushboolean(L, success);
+       // Get the table insert function and push the log table
+       lua_getglobal(L, "table");
+       lua_getfield(L, -1, "insert");
+       int table_insert = lua_gettop(L);
+       lua_newtable(L);
+       int table = lua_gettop(L);
+       for(std::list<std::string>::const_iterator i = log.begin();
+                       i != log.end(); i++)
+       {
+               lua_pushvalue(L, table_insert);
+               lua_pushvalue(L, table);
+               lua_pushstring(L, i->c_str());
+               if(lua_pcall(L, 2, 0, 0))
+                       script_error(L, "error: %s", lua_tostring(L, -1));
+       }
+       lua_remove(L, -2); // Remove table
+       lua_remove(L, -2); // Remove insert
+       return 2;
+}
+
+void ModApiRollback::Initialize(lua_State *L, int top)
+{
+       API_FCT(rollback_get_last_node_actor);
+       API_FCT(rollback_revert_actions_by);
+}
diff --git a/src/script/lua_api/l_rollback.h b/src/script/lua_api/l_rollback.h
new file mode 100644 (file)
index 0000000..86992a4
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef L_ROLLBACK_H_
+#define L_ROLLBACK_H_
+
+#include "lua_api/l_base.h"
+
+class ModApiRollback : public ModApiBase {
+private:
+       // rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds
+       static int l_rollback_get_last_node_actor(lua_State *L);
+
+       // rollback_revert_actions_by(actor, seconds) -> bool, log messages
+       static int l_rollback_revert_actions_by(lua_State *L);
+
+public:
+       static void Initialize(lua_State *L, int top);
+};
+
+#endif /* L_ROLLBACK_H_ */
diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp
new file mode 100644 (file)
index 0000000..8e809c3
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "lua_api/l_server.h"
+#include "lua_api/l_internal.h"
+#include "common/c_converter.h"
+#include "common/c_content.h"
+#include "server.h"
+#include "environment.h"
+#include "player.h"
+
+// request_shutdown()
+int ModApiServer::l_request_shutdown(lua_State *L)
+{
+       getServer(L)->requestShutdown();
+       return 0;
+}
+
+// get_server_status()
+int ModApiServer::l_get_server_status(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       lua_pushstring(L, wide_to_narrow(getServer(L)->getStatusString()).c_str());
+       return 1;
+}
+
+// chat_send_all(text)
+int ModApiServer::l_chat_send_all(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char *text = luaL_checkstring(L, 1);
+       // Get server from registry
+       Server *server = getServer(L);
+       // Send
+       server->notifyPlayers(narrow_to_wide(text));
+       return 0;
+}
+
+// chat_send_player(name, text, prepend)
+int ModApiServer::l_chat_send_player(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char *name = luaL_checkstring(L, 1);
+       const char *text = luaL_checkstring(L, 2);
+       bool prepend = true;
+
+       if (lua_isboolean(L, 3))
+               prepend = lua_toboolean(L, 3);
+
+       // Get server from registry
+       Server *server = getServer(L);
+       // Send
+       server->notifyPlayer(name, narrow_to_wide(text), prepend);
+       return 0;
+}
+
+// get_player_privs(name, text)
+int ModApiServer::l_get_player_privs(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char *name = luaL_checkstring(L, 1);
+       // Get server from registry
+       Server *server = getServer(L);
+       // Do it
+       lua_newtable(L);
+       int table = lua_gettop(L);
+       std::set<std::string> privs_s = server->getPlayerEffectivePrivs(name);
+       for(std::set<std::string>::const_iterator
+                       i = privs_s.begin(); i != privs_s.end(); i++){
+               lua_pushboolean(L, true);
+               lua_setfield(L, table, i->c_str());
+       }
+       lua_pushvalue(L, table);
+       return 1;
+}
+
+// get_player_ip()
+int ModApiServer::l_get_player_ip(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char * name = luaL_checkstring(L, 1);
+       Player *player = getEnv(L)->getPlayer(name);
+       if(player == NULL)
+       {
+               lua_pushnil(L); // no such player
+               return 1;
+       }
+       try
+       {
+               Address addr = getServer(L)->getPeerAddress(getEnv(L)->getPlayer(name)->peer_id);
+               std::string ip_str = addr.serializeString();
+               lua_pushstring(L, ip_str.c_str());
+               return 1;
+       }
+       catch(con::PeerNotFoundException) // unlikely
+       {
+               dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
+               lua_pushnil(L); // error
+               return 1;
+       }
+}
+
+// get_ban_list()
+int ModApiServer::l_get_ban_list(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       lua_pushstring(L, getServer(L)->getBanDescription("").c_str());
+       return 1;
+}
+
+// get_ban_description()
+int ModApiServer::l_get_ban_description(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char * ip_or_name = luaL_checkstring(L, 1);
+       lua_pushstring(L, getServer(L)->getBanDescription(std::string(ip_or_name)).c_str());
+       return 1;
+}
+
+// ban_player()
+int ModApiServer::l_ban_player(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char * name = luaL_checkstring(L, 1);
+       Player *player = getEnv(L)->getPlayer(name);
+       if(player == NULL)
+       {
+               lua_pushboolean(L, false); // no such player
+               return 1;
+       }
+       try
+       {
+               Address addr = getServer(L)->getPeerAddress(getEnv(L)->getPlayer(name)->peer_id);
+               std::string ip_str = addr.serializeString();
+               getServer(L)->setIpBanned(ip_str, name);
+       }
+       catch(con::PeerNotFoundException) // unlikely
+       {
+               dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
+               lua_pushboolean(L, false); // error
+               return 1;
+       }
+       lua_pushboolean(L, true);
+       return 1;
+}
+
+// unban_player_or_ip()
+int ModApiServer::l_unban_player_or_ip(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char * ip_or_name = luaL_checkstring(L, 1);
+       getServer(L)->unsetIpBanned(ip_or_name);
+       lua_pushboolean(L, true);
+       return 1;
+}
+
+// show_formspec(playername,formname,formspec)
+int ModApiServer::l_show_formspec(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char *playername = luaL_checkstring(L, 1);
+       const char *formname = luaL_checkstring(L, 2);
+       const char *formspec = luaL_checkstring(L, 3);
+
+       if(getServer(L)->showFormspec(playername,formspec,formname))
+       {
+               lua_pushboolean(L, true);
+       }else{
+               lua_pushboolean(L, false);
+       }
+       return 1;
+}
+
+// get_current_modname()
+int ModApiServer::l_get_current_modname(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
+       return 1;
+}
+
+// get_modpath(modname)
+int ModApiServer::l_get_modpath(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       std::string modname = luaL_checkstring(L, 1);
+       // Do it
+       if(modname == "__builtin"){
+               std::string path = getServer(L)->getBuiltinLuaPath();
+               lua_pushstring(L, path.c_str());
+               return 1;
+       }
+       const ModSpec *mod = getServer(L)->getModSpec(modname);
+       if(!mod){
+               lua_pushnil(L);
+               return 1;
+       }
+       lua_pushstring(L, mod->path.c_str());
+       return 1;
+}
+
+// get_modnames()
+// the returned list is sorted alphabetically for you
+int ModApiServer::l_get_modnames(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       // Get a list of mods
+       std::list<std::string> mods_unsorted, mods_sorted;
+       getServer(L)->getModNames(mods_unsorted);
+
+       // Take unsorted items from mods_unsorted and sort them into
+       // mods_sorted; not great performance but the number of mods on a
+       // server will likely be small.
+       for(std::list<std::string>::iterator i = mods_unsorted.begin();
+               i != mods_unsorted.end(); ++i)
+       {
+               bool added = false;
+               for(std::list<std::string>::iterator x = mods_sorted.begin();
+                       x != mods_sorted.end(); ++x)
+               {
+                       // I doubt anybody using Minetest will be using
+                       // anything not ASCII based :)
+                       if((*i).compare(*x) <= 0)
+                       {
+                               mods_sorted.insert(x, *i);
+                               added = true;
+                               break;
+                       }
+               }
+               if(!added)
+                       mods_sorted.push_back(*i);
+       }
+
+       // Get the table insertion function from Lua.
+       lua_getglobal(L, "table");
+       lua_getfield(L, -1, "insert");
+       int insertion_func = lua_gettop(L);
+
+       // Package them up for Lua
+       lua_newtable(L);
+       int new_table = lua_gettop(L);
+       std::list<std::string>::iterator i = mods_sorted.begin();
+       while(i != mods_sorted.end())
+       {
+               lua_pushvalue(L, insertion_func);
+               lua_pushvalue(L, new_table);
+               lua_pushstring(L, (*i).c_str());
+               if(lua_pcall(L, 2, 0, 0) != 0)
+               {
+                       script_error(L, "error: %s", lua_tostring(L, -1));
+               }
+               ++i;
+       }
+       return 1;
+}
+
+// get_worldpath()
+int ModApiServer::l_get_worldpath(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       std::string worldpath = getServer(L)->getWorldPath();
+       lua_pushstring(L, worldpath.c_str());
+       return 1;
+}
+
+// sound_play(spec, parameters)
+int ModApiServer::l_sound_play(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       SimpleSoundSpec spec;
+       read_soundspec(L, 1, spec);
+       ServerSoundParams params;
+       read_server_sound_params(L, 2, params);
+       s32 handle = getServer(L)->playSound(spec, params);
+       lua_pushinteger(L, handle);
+       return 1;
+}
+
+// sound_stop(handle)
+int ModApiServer::l_sound_stop(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       int handle = luaL_checkinteger(L, 1);
+       getServer(L)->stopSound(handle);
+       return 0;
+}
+
+// is_singleplayer()
+int ModApiServer::l_is_singleplayer(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       lua_pushboolean(L, getServer(L)->isSingleplayer());
+       return 1;
+}
+
+// notify_authentication_modified(name)
+int ModApiServer::l_notify_authentication_modified(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       std::string name = "";
+       if(lua_isstring(L, 1))
+               name = lua_tostring(L, 1);
+       getServer(L)->reportPrivsModified(name);
+       return 0;
+}
+
+void ModApiServer::Initialize(lua_State *L, int top)
+{
+       API_FCT(request_shutdown);
+       API_FCT(get_server_status);
+       API_FCT(get_worldpath);
+       API_FCT(is_singleplayer);
+
+       API_FCT(get_current_modname);
+       API_FCT(get_modpath);
+       API_FCT(get_modnames);
+
+       API_FCT(chat_send_all);
+       API_FCT(chat_send_player);
+       API_FCT(show_formspec);
+       API_FCT(sound_play);
+       API_FCT(sound_stop);
+
+       API_FCT(get_player_privs);
+       API_FCT(get_player_ip);
+       API_FCT(get_ban_list);
+       API_FCT(get_ban_description);
+       API_FCT(ban_player);
+       API_FCT(unban_player_or_ip);
+       API_FCT(notify_authentication_modified);
+}
diff --git a/src/script/lua_api/l_server.h b/src/script/lua_api/l_server.h
new file mode 100644 (file)
index 0000000..21f3004
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef L_SERVER_H_
+#define L_SERVER_H_
+
+#include "lua_api/l_base.h"
+
+class ModApiServer : public ModApiBase {
+private:
+       // request_shutdown()
+       static int l_request_shutdown(lua_State *L);
+
+       // get_server_status()
+       static int l_get_server_status(lua_State *L);
+
+       // get_worldpath()
+       static int l_get_worldpath(lua_State *L);
+
+       // is_singleplayer()
+       static int l_is_singleplayer(lua_State *L);
+
+       // get_current_modname()
+       static int l_get_current_modname(lua_State *L);
+
+       // get_modpath(modname)
+       static int l_get_modpath(lua_State *L);
+
+       // get_modnames()
+       // the returned list is sorted alphabetically for you
+       static int l_get_modnames(lua_State *L);
+
+       // chat_send_all(text)
+       static int l_chat_send_all(lua_State *L);
+
+       // chat_send_player(name, text)
+       static int l_chat_send_player(lua_State *L);
+
+       // show_formspec(playername,formname,formspec)
+       static int l_show_formspec(lua_State *L);
+
+       // sound_play(spec, parameters)
+       static int l_sound_play(lua_State *L);
+
+       // sound_stop(handle)
+       static int l_sound_stop(lua_State *L);
+
+       // get_player_privs(name, text)
+       static int l_get_player_privs(lua_State *L);
+
+       // get_player_ip()
+       static int l_get_player_ip(lua_State *L);
+
+       // get_ban_list()
+       static int l_get_ban_list(lua_State *L);
+
+       // get_ban_description()
+       static int l_get_ban_description(lua_State *L);
+
+       // ban_player()
+       static int l_ban_player(lua_State *L);
+
+       // unban_player_or_ip()
+       static int l_unban_player_or_ip(lua_State *L);
+
+       // notify_authentication_modified(name)
+       static int l_notify_authentication_modified(lua_State *L);
+
+public:
+       static void Initialize(lua_State *L, int top);
+
+};
+
+#endif /* L_SERVER_H_ */
diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp
new file mode 100644 (file)
index 0000000..0e4de9e
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "lua_api/l_util.h"
+#include "lua_api/l_internal.h"
+#include "common/c_converter.h"
+#include "common/c_content.h"
+#include "debug.h"
+#include "log.h"
+#include "tool.h"
+#include "settings.h"
+#include "main.h"  //required for g_settings, g_settings_path
+
+// debug(...)
+// Writes a line to dstream
+int ModApiUtil::l_debug(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       // Handle multiple parameters to behave like standard lua print()
+       int n = lua_gettop(L);
+       lua_getglobal(L, "tostring");
+       for (int i = 1; i <= n; i++) {
+               /*
+                       Call tostring(i-th argument).
+                       This is what print() does, and it behaves a bit
+                       differently from directly calling lua_tostring.
+               */
+               lua_pushvalue(L, -1);  /* function to be called */
+               lua_pushvalue(L, i);   /* value to print */
+               lua_call(L, 1, 1);
+               const char *s = lua_tostring(L, -1);
+               if (i>1)
+                       dstream << "\t";
+               if (s)
+                       dstream << s;
+               lua_pop(L, 1);
+       }
+       dstream << std::endl;
+       return 0;
+}
+
+// log([level,] text)
+// Writes a line to the logger.
+// The one-argument version logs to infostream.
+// The two-argument version accept a log level: error, action, info, or verbose.
+int ModApiUtil::l_log(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       std::string text;
+       LogMessageLevel level = LMT_INFO;
+       if (lua_isnone(L, 2)) {
+               text = lua_tostring(L, 1);
+       }
+       else {
+               std::string levelname = luaL_checkstring(L, 1);
+               text = luaL_checkstring(L, 2);
+               if(levelname == "error")
+                       level = LMT_ERROR;
+               else if(levelname == "action")
+                       level = LMT_ACTION;
+               else if(levelname == "verbose")
+                       level = LMT_VERBOSE;
+       }
+       log_printline(level, text);
+       return 0;
+}
+
+// setting_set(name, value)
+int ModApiUtil::l_setting_set(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char *name = luaL_checkstring(L, 1);
+       const char *value = luaL_checkstring(L, 2);
+       g_settings->set(name, value);
+       return 0;
+}
+
+// setting_get(name)
+int ModApiUtil::l_setting_get(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char *name = luaL_checkstring(L, 1);
+       try{
+               std::string value = g_settings->get(name);
+               lua_pushstring(L, value.c_str());
+       } catch(SettingNotFoundException &e){
+               lua_pushnil(L);
+       }
+       return 1;
+}
+
+// setting_setbool(name)
+int ModApiUtil::l_setting_setbool(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char *name = luaL_checkstring(L, 1);
+       bool value = lua_toboolean(L, 2);
+       g_settings->setBool(name, value);
+       return 0;
+}
+
+// setting_getbool(name)
+int ModApiUtil::l_setting_getbool(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       const char *name = luaL_checkstring(L, 1);
+       try{
+               bool value = g_settings->getBool(name);
+               lua_pushboolean(L, value);
+       } catch(SettingNotFoundException &e){
+               lua_pushnil(L);
+       }
+       return 1;
+}
+
+// setting_save()
+int ModApiUtil::l_setting_save(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       if(g_settings_path != "")
+               g_settings->updateConfigFile(g_settings_path.c_str());
+       return 0;
+}
+
+// get_dig_params(groups, tool_capabilities[, time_from_last_punch])
+int ModApiUtil::l_get_dig_params(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       std::map<std::string, int> groups;
+       read_groups(L, 1, groups);
+       ToolCapabilities tp = read_tool_capabilities(L, 2);
+       if(lua_isnoneornil(L, 3))
+               push_dig_params(L, getDigParams(groups, &tp));
+       else
+               push_dig_params(L, getDigParams(groups, &tp,
+                                       luaL_checknumber(L, 3)));
+       return 1;
+}
+
+// get_hit_params(groups, tool_capabilities[, time_from_last_punch])
+int ModApiUtil::l_get_hit_params(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       std::map<std::string, int> groups;
+       read_groups(L, 1, groups);
+       ToolCapabilities tp = read_tool_capabilities(L, 2);
+       if(lua_isnoneornil(L, 3))
+               push_hit_params(L, getHitParams(groups, &tp));
+       else
+               push_hit_params(L, getHitParams(groups, &tp,
+                                       luaL_checknumber(L, 3)));
+       return 1;
+}
+
+// get_password_hash(name, raw_password)
+int ModApiUtil::l_get_password_hash(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+       std::string name = luaL_checkstring(L, 1);
+       std::string raw_password = luaL_checkstring(L, 2);
+       std::string hash = translatePassword(name,
+                       narrow_to_wide(raw_password));
+       lua_pushstring(L, hash.c_str());
+       return 1;
+}
+
+void ModApiUtil::Initialize(lua_State *L, int top)
+{
+       API_FCT(debug);
+       API_FCT(log);
+
+       API_FCT(setting_set);
+       API_FCT(setting_get);
+       API_FCT(setting_setbool);
+       API_FCT(setting_getbool);
+       API_FCT(setting_save);
+
+       API_FCT(get_dig_params);
+       API_FCT(get_hit_params);
+
+       API_FCT(get_password_hash);
+}
+
diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h
new file mode 100644 (file)
index 0000000..b102e31
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef L_UTIL_H_
+#define L_UTIL_H_
+
+#include "lua_api/l_base.h"
+
+class ModApiUtil : public ModApiBase {
+private:
+       /*
+               NOTE:
+               The functions in this module are available through
+               minetest.<function> in the in-game API as well as
+               engine.<function> in the mainmenu API
+
+               All functions that don't require either a Server or
+               GUIEngine instance should be in here.
+       */
+
+       // debug(text)
+       // Writes a line to dstream
+       static int l_debug(lua_State *L);
+
+       // log([level,] text)
+       // Writes a line to the logger.
+       // The one-argument version logs to infostream.
+       // The two-argument version accept a log level: error, action, info, or verbose.
+       static int l_log(lua_State *L);
+
+       // setting_set(name, value)
+       static int l_setting_set(lua_State *L);
+
+       // setting_get(name)
+       static int l_setting_get(lua_State *L);
+
+       // setting_setbool(name, value)
+       static int l_setting_setbool(lua_State *L);
+
+       // setting_getbool(name)
+       static int l_setting_getbool(lua_State *L);
+
+       // setting_save()
+       static int l_setting_save(lua_State *L);
+
+       // get_dig_params(groups, tool_capabilities[, time_from_last_punch])
+       static int l_get_dig_params(lua_State *L);
+
+       // get_hit_params(groups, tool_capabilities[, time_from_last_punch])
+       static int l_get_hit_params(lua_State *L);
+
+       // get_password_hash(name, raw_password)
+       static int l_get_password_hash(lua_State *L);
+
+public:
+       static void Initialize(lua_State *L, int top);
+
+};
+
+#endif /* L_UTIL_H_ */
index 195682579f7fa64ca5103096962da1ae314029ee..1e9cc350f432194f24e1f1f88245ebfb99e7e0ed 100644 (file)
@@ -18,16 +18,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 
-#include "lua_api/l_base.h"
 #include "lua_api/l_vmanip.h"
-
-///////
-
-#include "cpp_api/scriptapi.h"
+#include "lua_api/l_internal.h"
 #include "common/c_converter.h"
-#include "server.h"
 #include "emerge.h"
-#include "common/c_internal.h"
+#include "environment.h"
+#include "map.h"
+#include "server.h"
+#include "mapgen.h"
 
 // garbage collector
 int LuaVoxelManip::gc_object(lua_State *L)
@@ -111,9 +109,13 @@ int LuaVoxelManip::l_write_to_map(lua_State *L)
 int LuaVoxelManip::l_update_liquids(lua_State *L)
 {
        LuaVoxelManip *o = checkobject(L, 1);
-       
-       INodeDefManager *ndef = STACK_TO_SERVER(L)->getNodeDefManager();
-       Map *map = &(get_scriptapi(L)->getEnv()->getMap());
+
+       Environment *env = getEnv(L);
+       if (!env)
+               return 0;
+
+       Map *map = &(env->getMap());
+       INodeDefManager *ndef = getServer(L)->getNodeDefManager();
        ManualMapVoxelManipulator *vm = o->vm;
 
        Mapgen mg;
@@ -134,8 +136,8 @@ int LuaVoxelManip::l_calc_lighting(lua_State *L)
        if (!o->is_mapgen_vm)
                return 0;
                
-       INodeDefManager *ndef = STACK_TO_SERVER(L)->getNodeDefManager();
-       EmergeManager *emerge = STACK_TO_SERVER(L)->getEmergeManager();
+       INodeDefManager *ndef = getServer(L)->getNodeDefManager();
+       EmergeManager *emerge = getServer(L)->getEmergeManager();
        ManualMapVoxelManipulator *vm = o->vm;
 
        Mapgen mg;
@@ -182,13 +184,18 @@ int LuaVoxelManip::l_update_map(lua_State *L)
        if (o->is_mapgen_vm)
                return 0;
        
+       Environment *env = getEnv(L);
+       if (!env)
+               return 0;
+
+       Map *map = &(env->getMap());
+
        // TODO: Optimize this by using Mapgen::calcLighting() instead
        std::map<v3s16, MapBlock *> lighting_mblocks;
        std::map<v3s16, MapBlock *> *mblocks = &o->modified_blocks;
        
        lighting_mblocks.insert(mblocks->begin(), mblocks->end());
        
-       Map *map = &(get_scriptapi(L)->getEnv()->getMap());
        map->updateLighting(lighting_mblocks, *mblocks);
 
        MapEditEvent event;
@@ -228,7 +235,7 @@ int LuaVoxelManip::create_object(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
        
-       Environment *env = get_scriptapi(L)->getEnv();
+       Environment *env = getEnv(L);
        if (!env)
                return 0;
                
@@ -278,7 +285,7 @@ void LuaVoxelManip::Register(lua_State *L)
        luaL_openlib(L, 0, methods, 0);  // fill methodtable
        lua_pop(L, 1);  // drop methodtable
 
-       // Can be created from Lua (VoxelManip()
+       // Can be created from Lua (VoxelManip())
        lua_register(L, className, create_object);
 }
 
@@ -294,5 +301,3 @@ const luaL_reg LuaVoxelManip::methods[] = {
        luamethod(LuaVoxelManip, set_lighting),
        {0,0}
 };
-
-REGISTER_LUA_REF(LuaVoxelManip);
index a7791e56badac4f330b2d20d0364de689e8c3eb1..d2f035a3ee107e022feba391e5b3a309284d8130 100644 (file)
@@ -20,19 +20,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef L_VMANIP_H_
 #define L_VMANIP_H_
 
-extern "C" {
-#include <lua.h>
-#include <lauxlib.h>
-}
-
+#include "lua_api/l_base.h"
 #include "irr_v3d.h"
-#include "map.h"
+#include <map>
+
+class Map;
+class MapBlock;
+class ManualMapVoxelManipulator;
 
 /*
   VoxelManip
  */
-class LuaVoxelManip
-{
+class LuaVoxelManip : public ModApiBase {
 private:
        ManualMapVoxelManipulator *vm;
        std::map<v3s16, MapBlock *> modified_blocks;
@@ -67,4 +66,4 @@ public:
        static void Register(lua_State *L);
 };
 
-#endif // L_VMANIP_H_
+#endif /* L_VMANIP_H_ */
diff --git a/src/script/lua_api/luaapi.cpp b/src/script/lua_api/luaapi.cpp
deleted file mode 100644 (file)
index 26fb0c3..0000000
+++ /dev/null
@@ -1,955 +0,0 @@
-/*
-Minetest
-Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-extern "C" {
-#include "lua.h"
-#include "lauxlib.h"
-}
-
-#include "lua_api/l_base.h"
-#include "common/c_internal.h"
-#include "server.h"
-#include "common/c_converter.h"
-#include "common/c_content.h"
-#include "lua_api/luaapi.h"
-#include "settings.h"
-#include "tool.h"
-#include "rollback.h"
-#include "log.h"
-#include "emerge.h"
-#include "main.h"  //required for g_settings
-
-struct EnumString ModApiBasic::es_OreType[] =
-{
-       {ORE_SCATTER,  "scatter"},
-       {ORE_SHEET,    "sheet"},
-       {ORE_CLAYLIKE, "claylike"},
-       {0, NULL},
-};
-
-struct EnumString ModApiBasic::es_DecorationType[] =
-{
-       {DECO_SIMPLE,    "simple"},
-       {DECO_SCHEMATIC, "schematic"},
-       {DECO_LSYSTEM,   "lsystem"},
-       {0, NULL},
-};
-
-struct EnumString ModApiBasic::es_Rotation[] =
-{
-       {ROTATE_0,    "0"},
-       {ROTATE_90,   "90"},
-       {ROTATE_180,  "180"},
-       {ROTATE_270,  "270"},
-       {ROTATE_RAND, "random"},
-       {0, NULL},
-};
-
-
-ModApiBasic::ModApiBasic() : ModApiBase() {
-}
-
-bool ModApiBasic::Initialize(lua_State* L,int top) {
-
-       bool retval = true;
-
-       retval &= API_FCT(debug);
-       retval &= API_FCT(log);
-       retval &= API_FCT(request_shutdown);
-       retval &= API_FCT(get_server_status);
-
-       retval &= API_FCT(register_biome);
-
-       retval &= API_FCT(setting_set);
-       retval &= API_FCT(setting_get);
-       retval &= API_FCT(setting_getbool);
-       retval &= API_FCT(setting_save);
-
-       retval &= API_FCT(chat_send_all);
-       retval &= API_FCT(chat_send_player);
-       retval &= API_FCT(show_formspec);
-
-       retval &= API_FCT(get_player_privs);
-       retval &= API_FCT(get_player_ip);
-       retval &= API_FCT(get_ban_list);
-       retval &= API_FCT(get_ban_description);
-       retval &= API_FCT(ban_player);
-       retval &= API_FCT(unban_player_or_ip);
-       retval &= API_FCT(get_password_hash);
-       retval &= API_FCT(notify_authentication_modified);
-
-       retval &= API_FCT(get_dig_params);
-       retval &= API_FCT(get_hit_params);
-
-       retval &= API_FCT(get_current_modname);
-       retval &= API_FCT(get_modpath);
-       retval &= API_FCT(get_modnames);
-
-       retval &= API_FCT(get_worldpath);
-       retval &= API_FCT(is_singleplayer);
-       retval &= API_FCT(sound_play);
-       retval &= API_FCT(sound_stop);
-
-       retval &= API_FCT(rollback_get_last_node_actor);
-       retval &= API_FCT(rollback_revert_actions_by);
-
-       retval &= API_FCT(register_ore);
-       retval &= API_FCT(register_decoration);
-       retval &= API_FCT(create_schematic);
-       retval &= API_FCT(place_schematic);
-
-       return retval;
-}
-
-// debug(...)
-// Writes a line to dstream
-int ModApiBasic::l_debug(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       // Handle multiple parameters to behave like standard lua print()
-       int n = lua_gettop(L);
-       lua_getglobal(L, "tostring");
-       for(int i = 1; i <= n; i++){
-               /*
-                       Call tostring(i-th argument).
-                       This is what print() does, and it behaves a bit
-                       differently from directly calling lua_tostring.
-               */
-               lua_pushvalue(L, -1);  /* function to be called */
-               lua_pushvalue(L, i);   /* value to print */
-               lua_call(L, 1, 1);
-               const char *s = lua_tostring(L, -1);
-               if(i>1)
-                       dstream << "\t";
-               if(s)
-                       dstream << s;
-               lua_pop(L, 1);
-       }
-       dstream << std::endl;
-       return 0;
-}
-
-// log([level,] text)
-// Writes a line to the logger.
-// The one-argument version logs to infostream.
-// The two-argument version accept a log level: error, action, info, or verbose.
-int ModApiBasic::l_log(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       std::string text;
-       LogMessageLevel level = LMT_INFO;
-       if(lua_isnone(L, 2))
-       {
-               text = lua_tostring(L, 1);
-       }
-       else
-       {
-               std::string levelname = luaL_checkstring(L, 1);
-               text = luaL_checkstring(L, 2);
-               if(levelname == "error")
-                       level = LMT_ERROR;
-               else if(levelname == "action")
-                       level = LMT_ACTION;
-               else if(levelname == "verbose")
-                       level = LMT_VERBOSE;
-       }
-       log_printline(level, text);
-       return 0;
-}
-
-// request_shutdown()
-int ModApiBasic::l_request_shutdown(lua_State *L)
-{
-       getServer(L)->requestShutdown();
-       return 0;
-}
-
-// get_server_status()
-int ModApiBasic::l_get_server_status(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       lua_pushstring(L, wide_to_narrow(getServer(L)->getStatusString()).c_str());
-       return 1;
-}
-
-// register_biome({lots of stuff})
-int ModApiBasic::l_register_biome(lua_State *L)
-{
-       int index = 1;
-       luaL_checktype(L, index, LUA_TTABLE);
-
-       BiomeDefManager *bmgr = getServer(L)->getEmergeManager()->biomedef;
-       if (!bmgr) {
-               verbosestream << "register_biome: BiomeDefManager not active" << std::endl;
-               return 0;
-       }
-
-       enum BiomeTerrainType terrain = (BiomeTerrainType)getenumfield(L, index,
-                               "terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL);
-       Biome *b = bmgr->createBiome(terrain);
-
-       b->name         = getstringfield_default(L, index, "name",
-                                                                                               "<no name>");
-       b->nname_top    = getstringfield_default(L, index, "node_top",
-                                                                                               "mapgen_dirt_with_grass");
-       b->nname_filler = getstringfield_default(L, index, "node_filler",
-                                                                                               "mapgen_dirt");
-       b->nname_water  = getstringfield_default(L, index, "node_water",
-                                                                                               "mapgen_water_source");
-       b->nname_dust   = getstringfield_default(L, index, "node_dust",
-                                                                                               "air");
-       b->nname_dust_water = getstringfield_default(L, index, "node_dust_water",
-                                                                                               "mapgen_water_source");
-       
-       b->depth_top      = getintfield_default(L, index, "depth_top",    1);
-       b->depth_filler   = getintfield_default(L, index, "depth_filler", 3);
-       b->height_min     = getintfield_default(L, index, "height_min",   0);
-       b->height_max     = getintfield_default(L, index, "height_max",   0);
-       b->heat_point     = getfloatfield_default(L, index, "heat_point",     0.);
-       b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.);
-
-       b->flags        = 0; //reserved
-       b->c_top        = CONTENT_IGNORE;
-       b->c_filler     = CONTENT_IGNORE;
-       b->c_water      = CONTENT_IGNORE;
-       b->c_dust       = CONTENT_IGNORE;
-       b->c_dust_water = CONTENT_IGNORE;
-       
-       verbosestream << "register_biome: " << b->name << std::endl;
-       bmgr->addBiome(b);
-
-       return 0;
-}
-
-// setting_set(name, value)
-int ModApiBasic::l_setting_set(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       const char *name = luaL_checkstring(L, 1);
-       const char *value = luaL_checkstring(L, 2);
-       g_settings->set(name, value);
-       return 0;
-}
-
-// setting_get(name)
-int ModApiBasic::l_setting_get(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       const char *name = luaL_checkstring(L, 1);
-       try{
-               std::string value = g_settings->get(name);
-               lua_pushstring(L, value.c_str());
-       } catch(SettingNotFoundException &e){
-               lua_pushnil(L);
-       }
-       return 1;
-}
-
-// setting_getbool(name)
-int ModApiBasic::l_setting_getbool(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       const char *name = luaL_checkstring(L, 1);
-       try{
-               bool value = g_settings->getBool(name);
-               lua_pushboolean(L, value);
-       } catch(SettingNotFoundException &e){
-               lua_pushnil(L);
-       }
-       return 1;
-}
-
-// setting_save()
-int ModApiBasic::l_setting_save(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       getServer(L)->saveConfig();
-       return 0;
-}
-
-// chat_send_all(text)
-int ModApiBasic::l_chat_send_all(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       const char *text = luaL_checkstring(L, 1);
-       // Get server from registry
-       Server *server = getServer(L);
-       // Send
-       server->notifyPlayers(narrow_to_wide(text));
-       return 0;
-}
-
-// chat_send_player(name, text, prepend)
-int ModApiBasic::l_chat_send_player(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       const char *name = luaL_checkstring(L, 1);
-       const char *text = luaL_checkstring(L, 2);
-       bool prepend = true;
-
-       if (lua_isboolean(L, 3))
-               prepend = lua_toboolean(L, 3);
-
-       // Get server from registry
-       Server *server = getServer(L);
-       // Send
-       server->notifyPlayer(name, narrow_to_wide(text), prepend);
-       return 0;
-}
-
-// get_player_privs(name, text)
-int ModApiBasic::l_get_player_privs(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       const char *name = luaL_checkstring(L, 1);
-       // Get server from registry
-       Server *server = getServer(L);
-       // Do it
-       lua_newtable(L);
-       int table = lua_gettop(L);
-       std::set<std::string> privs_s = server->getPlayerEffectivePrivs(name);
-       for(std::set<std::string>::const_iterator
-                       i = privs_s.begin(); i != privs_s.end(); i++){
-               lua_pushboolean(L, true);
-               lua_setfield(L, table, i->c_str());
-       }
-       lua_pushvalue(L, table);
-       return 1;
-}
-
-// get_player_ip()
-int ModApiBasic::l_get_player_ip(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       const char * name = luaL_checkstring(L, 1);
-       Player *player = getEnv(L)->getPlayer(name);
-       if(player == NULL)
-       {
-               lua_pushnil(L); // no such player
-               return 1;
-       }
-       try
-       {
-               Address addr = getServer(L)->getPeerAddress(getEnv(L)->getPlayer(name)->peer_id);
-               std::string ip_str = addr.serializeString();
-               lua_pushstring(L, ip_str.c_str());
-               return 1;
-       }
-       catch(con::PeerNotFoundException) // unlikely
-       {
-               dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
-               lua_pushnil(L); // error
-               return 1;
-       }
-}
-
-// get_ban_list()
-int ModApiBasic::l_get_ban_list(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       lua_pushstring(L, getServer(L)->getBanDescription("").c_str());
-       return 1;
-}
-
-// get_ban_description()
-int ModApiBasic::l_get_ban_description(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       const char * ip_or_name = luaL_checkstring(L, 1);
-       lua_pushstring(L, getServer(L)->getBanDescription(std::string(ip_or_name)).c_str());
-       return 1;
-}
-
-// ban_player()
-int ModApiBasic::l_ban_player(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       const char * name = luaL_checkstring(L, 1);
-       Player *player = getEnv(L)->getPlayer(name);
-       if(player == NULL)
-       {
-               lua_pushboolean(L, false); // no such player
-               return 1;
-       }
-       try
-       {
-               Address addr = getServer(L)->getPeerAddress(getEnv(L)->getPlayer(name)->peer_id);
-               std::string ip_str = addr.serializeString();
-               getServer(L)->setIpBanned(ip_str, name);
-       }
-       catch(con::PeerNotFoundException) // unlikely
-       {
-               dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
-               lua_pushboolean(L, false); // error
-               return 1;
-       }
-       lua_pushboolean(L, true);
-       return 1;
-}
-
-// unban_player_or_ip()
-int ModApiBasic::l_unban_player_or_ip(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       const char * ip_or_name = luaL_checkstring(L, 1);
-       getServer(L)->unsetIpBanned(ip_or_name);
-       lua_pushboolean(L, true);
-       return 1;
-}
-
-// show_formspec(playername,formname,formspec)
-int ModApiBasic::l_show_formspec(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       const char *playername = luaL_checkstring(L, 1);
-       const char *formname = luaL_checkstring(L, 2);
-       const char *formspec = luaL_checkstring(L, 3);
-
-       if(getServer(L)->showFormspec(playername,formspec,formname))
-       {
-               lua_pushboolean(L, true);
-       }else{
-               lua_pushboolean(L, false);
-       }
-       return 1;
-}
-
-// get_dig_params(groups, tool_capabilities[, time_from_last_punch])
-int ModApiBasic::l_get_dig_params(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       std::map<std::string, int> groups;
-       read_groups(L, 1, groups);
-       ToolCapabilities tp = read_tool_capabilities(L, 2);
-       if(lua_isnoneornil(L, 3))
-               push_dig_params(L, getDigParams(groups, &tp));
-       else
-               push_dig_params(L, getDigParams(groups, &tp,
-                                       luaL_checknumber(L, 3)));
-       return 1;
-}
-
-// get_hit_params(groups, tool_capabilities[, time_from_last_punch])
-int ModApiBasic::l_get_hit_params(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       std::map<std::string, int> groups;
-       read_groups(L, 1, groups);
-       ToolCapabilities tp = read_tool_capabilities(L, 2);
-       if(lua_isnoneornil(L, 3))
-               push_hit_params(L, getHitParams(groups, &tp));
-       else
-               push_hit_params(L, getHitParams(groups, &tp,
-                                       luaL_checknumber(L, 3)));
-       return 1;
-}
-
-// get_current_modname()
-int ModApiBasic::l_get_current_modname(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       lua_getfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
-       return 1;
-}
-
-// get_modpath(modname)
-int ModApiBasic::l_get_modpath(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       std::string modname = luaL_checkstring(L, 1);
-       // Do it
-       if(modname == "__builtin"){
-               std::string path = getServer(L)->getBuiltinLuaPath();
-               lua_pushstring(L, path.c_str());
-               return 1;
-       }
-       const ModSpec *mod = getServer(L)->getModSpec(modname);
-       if(!mod){
-               lua_pushnil(L);
-               return 1;
-       }
-       lua_pushstring(L, mod->path.c_str());
-       return 1;
-}
-
-// get_modnames()
-// the returned list is sorted alphabetically for you
-int ModApiBasic::l_get_modnames(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       // Get a list of mods
-       std::list<std::string> mods_unsorted, mods_sorted;
-       getServer(L)->getModNames(mods_unsorted);
-
-       // Take unsorted items from mods_unsorted and sort them into
-       // mods_sorted; not great performance but the number of mods on a
-       // server will likely be small.
-       for(std::list<std::string>::iterator i = mods_unsorted.begin();
-               i != mods_unsorted.end(); ++i)
-       {
-               bool added = false;
-               for(std::list<std::string>::iterator x = mods_sorted.begin();
-                       x != mods_sorted.end(); ++x)
-               {
-                       // I doubt anybody using Minetest will be using
-                       // anything not ASCII based :)
-                       if((*i).compare(*x) <= 0)
-                       {
-                               mods_sorted.insert(x, *i);
-                               added = true;
-                               break;
-                       }
-               }
-               if(!added)
-                       mods_sorted.push_back(*i);
-       }
-
-       // Get the table insertion function from Lua.
-       lua_getglobal(L, "table");
-       lua_getfield(L, -1, "insert");
-       int insertion_func = lua_gettop(L);
-
-       // Package them up for Lua
-       lua_newtable(L);
-       int new_table = lua_gettop(L);
-       std::list<std::string>::iterator i = mods_sorted.begin();
-       while(i != mods_sorted.end())
-       {
-               lua_pushvalue(L, insertion_func);
-               lua_pushvalue(L, new_table);
-               lua_pushstring(L, (*i).c_str());
-               if(lua_pcall(L, 2, 0, 0) != 0)
-               {
-                       script_error(L, "error: %s", lua_tostring(L, -1));
-               }
-               ++i;
-       }
-       return 1;
-}
-
-// get_worldpath()
-int ModApiBasic::l_get_worldpath(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       std::string worldpath = getServer(L)->getWorldPath();
-       lua_pushstring(L, worldpath.c_str());
-       return 1;
-}
-
-// sound_play(spec, parameters)
-int ModApiBasic::l_sound_play(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       SimpleSoundSpec spec;
-       read_soundspec(L, 1, spec);
-       ServerSoundParams params;
-       read_server_sound_params(L, 2, params);
-       s32 handle = getServer(L)->playSound(spec, params);
-       lua_pushinteger(L, handle);
-       return 1;
-}
-
-// sound_stop(handle)
-int ModApiBasic::l_sound_stop(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       int handle = luaL_checkinteger(L, 1);
-       getServer(L)->stopSound(handle);
-       return 0;
-}
-
-// is_singleplayer()
-int ModApiBasic::l_is_singleplayer(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       lua_pushboolean(L, getServer(L)->isSingleplayer());
-       return 1;
-}
-
-// get_password_hash(name, raw_password)
-int ModApiBasic::l_get_password_hash(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       std::string name = luaL_checkstring(L, 1);
-       std::string raw_password = luaL_checkstring(L, 2);
-       std::string hash = translatePassword(name,
-                       narrow_to_wide(raw_password));
-       lua_pushstring(L, hash.c_str());
-       return 1;
-}
-
-// notify_authentication_modified(name)
-int ModApiBasic::l_notify_authentication_modified(lua_State *L)
-{
-       NO_MAP_LOCK_REQUIRED;
-       std::string name = "";
-       if(lua_isstring(L, 1))
-               name = lua_tostring(L, 1);
-       getServer(L)->reportPrivsModified(name);
-       return 0;
-}
-
-// rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds
-int ModApiBasic::l_rollback_get_last_node_actor(lua_State *L)
-{
-       v3s16 p = read_v3s16(L, 1);
-       int range = luaL_checknumber(L, 2);
-       int seconds = luaL_checknumber(L, 3);
-       Server *server = getServer(L);
-       IRollbackManager *rollback = server->getRollbackManager();
-       v3s16 act_p;
-       int act_seconds = 0;
-       std::string actor = rollback->getLastNodeActor(p, range, seconds, &act_p, &act_seconds);
-       lua_pushstring(L, actor.c_str());
-       push_v3s16(L, act_p);
-       lua_pushnumber(L, act_seconds);
-       return 3;
-}
-
-// rollback_revert_actions_by(actor, seconds) -> bool, log messages
-int ModApiBasic::l_rollback_revert_actions_by(lua_State *L)
-{
-       std::string actor = luaL_checkstring(L, 1);
-       int seconds = luaL_checknumber(L, 2);
-       Server *server = getServer(L);
-       IRollbackManager *rollback = server->getRollbackManager();
-       std::list<RollbackAction> actions = rollback->getRevertActions(actor, seconds);
-       std::list<std::string> log;
-       bool success = server->rollbackRevertActions(actions, &log);
-       // Push boolean result
-       lua_pushboolean(L, success);
-       // Get the table insert function and push the log table
-       lua_getglobal(L, "table");
-       lua_getfield(L, -1, "insert");
-       int table_insert = lua_gettop(L);
-       lua_newtable(L);
-       int table = lua_gettop(L);
-       for(std::list<std::string>::const_iterator i = log.begin();
-                       i != log.end(); i++)
-       {
-               lua_pushvalue(L, table_insert);
-               lua_pushvalue(L, table);
-               lua_pushstring(L, i->c_str());
-               if(lua_pcall(L, 2, 0, 0))
-                       script_error(L, "error: %s", lua_tostring(L, -1));
-       }
-       lua_remove(L, -2); // Remove table
-       lua_remove(L, -2); // Remove insert
-       return 2;
-}
-
-int ModApiBasic::l_register_ore(lua_State *L)
-{
-       int index = 1;
-       luaL_checktype(L, index, LUA_TTABLE);
-
-       EmergeManager *emerge = getServer(L)->getEmergeManager();
-
-       enum OreType oretype = (OreType)getenumfield(L, index,
-                               "ore_type", es_OreType, ORE_SCATTER);
-       Ore *ore = createOre(oretype);
-       if (!ore) {
-               errorstream << "register_ore: ore_type "
-                       << oretype << " not implemented";
-               return 0;
-       }
-
-       ore->ore_name       = getstringfield_default(L, index, "ore", "");
-       ore->ore_param2     = (u8)getintfield_default(L, index, "ore_param2", 0);
-       ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
-       ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
-       ore->clust_size     = getintfield_default(L, index, "clust_size", 0);
-       ore->height_min     = getintfield_default(L, index, "height_min", 0);
-       ore->height_max     = getintfield_default(L, index, "height_max", 0);
-       ore->flags          = getflagsfield(L, index, "flags", flagdesc_ore);
-       ore->nthresh        = getfloatfield_default(L, index, "noise_threshhold", 0.);
-
-       lua_getfield(L, index, "wherein");
-       if (lua_istable(L, -1)) {
-               int  i = lua_gettop(L);
-               lua_pushnil(L);
-               while(lua_next(L, i) != 0) {
-                       ore->wherein_names.push_back(lua_tostring(L, -1));
-                       lua_pop(L, 1);
-               }
-       } else if (lua_isstring(L, -1)) {
-               ore->wherein_names.push_back(lua_tostring(L, -1));
-       } else {
-               ore->wherein_names.push_back("");
-       }
-       lua_pop(L, 1);
-
-       lua_getfield(L, index, "noise_params");
-       ore->np = read_noiseparams(L, -1);
-       lua_pop(L, 1);
-
-       ore->noise = NULL;
-
-       if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) {
-               errorstream << "register_ore: clust_scarcity and clust_num_ores"
-                       "must be greater than 0" << std::endl;
-               delete ore;
-               return 0;
-       }
-
-       emerge->ores.push_back(ore);
-
-       verbosestream << "register_ore: ore '" << ore->ore_name
-               << "' registered" << std::endl;
-       return 0;
-}
-
-// register_decoration({lots of stuff})
-int ModApiBasic::l_register_decoration(lua_State *L)
-{
-       int index = 1;
-       luaL_checktype(L, index, LUA_TTABLE);
-
-       EmergeManager *emerge = getServer(L)->getEmergeManager();
-       BiomeDefManager *bdef = emerge->biomedef;
-
-       enum DecorationType decotype = (DecorationType)getenumfield(L, index,
-                               "deco_type", es_DecorationType, -1);
-       if (decotype == -1) {
-               errorstream << "register_decoration: unrecognized "
-                       "decoration placement type";
-               return 0;
-       }
-       
-       Decoration *deco = createDecoration(decotype);
-       if (!deco) {
-               errorstream << "register_decoration: decoration placement type "
-                       << decotype << " not implemented";
-               return 0;
-       }
-
-       deco->c_place_on    = CONTENT_IGNORE;
-       deco->place_on_name = getstringfield_default(L, index, "place_on", "ignore");
-       deco->fill_ratio    = getfloatfield_default(L, index, "fill_ratio", 0.02);
-       deco->sidelen       = getintfield_default(L, index, "sidelen", 8);
-       if (deco->sidelen <= 0) {
-               errorstream << "register_decoration: sidelen must be "
-                       "greater than 0" << std::endl;
-               delete deco;
-               return 0;
-       }
-       
-       lua_getfield(L, index, "noise_params");
-       deco->np = read_noiseparams(L, -1);
-       lua_pop(L, 1);
-       
-       lua_getfield(L, index, "biomes");
-       if (lua_istable(L, -1)) {
-               lua_pushnil(L);
-               while (lua_next(L, -2)) {
-                       const char *s = lua_tostring(L, -1);
-                       u8 biomeid = bdef->getBiomeIdByName(s);
-                       if (biomeid)
-                               deco->biomes.insert(biomeid);
-
-                       lua_pop(L, 1);
-               }
-               lua_pop(L, 1);
-       }
-       
-       switch (decotype) {
-               case DECO_SIMPLE: {
-                       DecoSimple *dsimple = (DecoSimple *)deco;
-                       dsimple->c_deco     = CONTENT_IGNORE;
-                       dsimple->c_spawnby  = CONTENT_IGNORE;
-                       dsimple->spawnby_name    = getstringfield_default(L, index, "spawn_by", "air");
-                       dsimple->deco_height     = getintfield_default(L, index, "height", 1);
-                       dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0);
-                       dsimple->nspawnby        = getintfield_default(L, index, "num_spawn_by", -1);
-                       
-                       lua_getfield(L, index, "decoration");
-                       if (lua_istable(L, -1)) {
-                               lua_pushnil(L);
-                               while (lua_next(L, -2)) {
-                                       const char *s = lua_tostring(L, -1);
-                                       std::string str(s);
-                                       dsimple->decolist_names.push_back(str);
-
-                                       lua_pop(L, 1);
-                               }
-                       } else if (lua_isstring(L, -1)) {
-                               dsimple->deco_name = std::string(lua_tostring(L, -1));
-                       } else {
-                               dsimple->deco_name = std::string("air");
-                       }
-                       lua_pop(L, 1);
-                       
-                       if (dsimple->deco_height <= 0) {
-                               errorstream << "register_decoration: simple decoration height"
-                                       " must be greater than 0" << std::endl;
-                               delete dsimple;
-                               return 0;
-                       }
-
-                       break; }
-               case DECO_SCHEMATIC: {
-                       DecoSchematic *dschem = (DecoSchematic *)deco;
-                       dschem->flags    = getflagsfield(L, index, "flags", flagdesc_deco_schematic);
-                       dschem->rotation = (Rotation)getenumfield(L, index,
-                                                               "rotation", es_Rotation, ROTATE_0);
-
-                       lua_getfield(L, index, "replacements");
-                       if (lua_istable(L, -1)) {
-                               int i = lua_gettop(L);
-                               lua_pushnil(L);
-                               while (lua_next(L, i) != 0) {
-                                       // key at index -2 and value at index -1
-                                       lua_rawgeti(L, -1, 1);
-                                       std::string replace_from = lua_tostring(L, -1);
-                                       lua_pop(L, 1);
-                                       lua_rawgeti(L, -1, 2);
-                                       std::string replace_to = lua_tostring(L, -1);
-                                       lua_pop(L, 1);
-                                       dschem->replacements[replace_from] = replace_to;
-                                       // removes value, keeps key for next iteration
-                                       lua_pop(L, 1);
-                               }
-                       }
-                       lua_pop(L, 1);
-
-                       lua_getfield(L, index, "schematic");
-                       if (!read_schematic(L, -1, dschem, getServer(L))) {
-                               delete dschem;
-                               return 0;
-                       }
-                       lua_pop(L, -1);
-                       
-                       if (!dschem->filename.empty() && !dschem->loadSchematicFile()) {
-                               errorstream << "register_decoration: failed to load schematic file '"
-                                       << dschem->filename << "'" << std::endl;
-                               delete dschem;
-                               return 0;
-                       }
-                       break; }
-               case DECO_LSYSTEM: {
-                       //DecoLSystem *decolsystem = (DecoLSystem *)deco;
-               
-                       break; }
-       }
-
-       emerge->decorations.push_back(deco);
-
-       verbosestream << "register_decoration: decoration '" << deco->getName()
-               << "' registered" << std::endl;
-       return 0;
-}
-
-// create_schematic(p1, p2, probability_list, filename)
-int ModApiBasic::l_create_schematic(lua_State *L)
-{
-       DecoSchematic dschem;
-
-       Map *map = &(getEnv(L)->getMap());
-       INodeDefManager *ndef = getServer(L)->getNodeDefManager();
-
-       v3s16 p1 = read_v3s16(L, 1);
-       v3s16 p2 = read_v3s16(L, 2);
-       sortBoxVerticies(p1, p2);
-       
-       std::vector<std::pair<v3s16, u8> > probability_list;
-       if (lua_istable(L, 3)) {
-               lua_pushnil(L);
-               while (lua_next(L, 3)) {
-                       if (lua_istable(L, -1)) {
-                               lua_getfield(L, -1, "pos");
-                               v3s16 pos = read_v3s16(L, -1);
-                               lua_pop(L, 1);
-                               
-                               u8 prob = getintfield_default(L, -1, "prob", 0xFF);
-                               probability_list.push_back(std::make_pair(pos, prob));
-                       }
-
-                       lua_pop(L, 1);
-               }
-       }
-       
-       dschem.filename = std::string(lua_tostring(L, 4));
-
-       if (!dschem.getSchematicFromMap(map, p1, p2)) {
-               errorstream << "create_schematic: failed to get schematic "
-                       "from map" << std::endl;
-               return 0;
-       }
-       
-       dschem.applyProbabilities(&probability_list, p1);
-       
-       dschem.saveSchematicFile(ndef);
-       actionstream << "create_schematic: saved schematic file '"
-               << dschem.filename << "'." << std::endl;
-
-       return 1;
-}
-
-
-// place_schematic(p, schematic, rotation, replacement)
-int ModApiBasic::l_place_schematic(lua_State *L)
-{
-       DecoSchematic dschem;
-
-       Map *map = &(getEnv(L)->getMap());
-       INodeDefManager *ndef = getServer(L)->getNodeDefManager();
-
-       v3s16 p = read_v3s16(L, 1);
-       if (!read_schematic(L, 2, &dschem, getServer(L)))
-               return 0;
-               
-       Rotation rot = ROTATE_0;
-       if (lua_isstring(L, 3))
-               string_to_enum(es_Rotation, (int &)rot, std::string(lua_tostring(L, 3)));
-               
-       dschem.rotation = rot;
-
-       if (lua_istable(L, 4)) {
-               int index = 4;
-               lua_pushnil(L);
-               while (lua_next(L, index) != 0) {
-                       // key at index -2 and value at index -1
-                       lua_rawgeti(L, -1, 1);
-                       std::string replace_from = lua_tostring(L, -1);
-                       lua_pop(L, 1);
-                       lua_rawgeti(L, -1, 2);
-                       std::string replace_to = lua_tostring(L, -1);
-                       lua_pop(L, 1);
-                       dschem.replacements[replace_from] = replace_to;
-                       // removes value, keeps key for next iteration
-                       lua_pop(L, 1);
-               }
-       }
-
-       if (!dschem.filename.empty()) {
-               if (!dschem.loadSchematicFile()) {
-                       errorstream << "place_schematic: failed to load schematic file '"
-                               << dschem.filename << "'" << std::endl;
-                       return 0;
-               }
-               dschem.resolveNodeNames(ndef);
-       }
-       
-       dschem.placeStructure(map, p);
-
-       return 1;
-}
-
-
-ModApiBasic modapibasic_prototype;
diff --git a/src/script/lua_api/luaapi.h b/src/script/lua_api/luaapi.h
deleted file mode 100644 (file)
index af73625..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
-Minetest
-Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef LUAAPI_H_
-#define LUAAPI_H_
-
-
-class ModApiBasic : public ModApiBase {
-
-public:
-       ModApiBasic();
-
-       bool Initialize(lua_State* L,int top);
-
-private:
-       // debug(text)
-       // Writes a line to dstream
-       static int l_debug(lua_State *L);
-
-       // log([level,] text)
-       // Writes a line to the logger.
-       // The one-argument version logs to infostream.
-       // The two-argument version accept a log level: error, action, info, or verbose.
-       static int l_log(lua_State *L);
-
-       // request_shutdown()
-       static int l_request_shutdown(lua_State *L);
-
-       // get_server_status()
-       static int l_get_server_status(lua_State *L);
-
-       // register_biome({lots of stuff})
-       static int l_register_biome(lua_State *L);
-
-       // setting_set(name, value)
-       static int l_setting_set(lua_State *L);
-
-       // setting_get(name)
-       static int l_setting_get(lua_State *L);
-
-       // setting_getbool(name)
-       static int l_setting_getbool(lua_State *L);
-
-       // setting_save()
-       static int l_setting_save(lua_State *L);
-
-       // chat_send_all(text)
-       static int l_chat_send_all(lua_State *L);
-
-       // chat_send_player(name, text)
-       static int l_chat_send_player(lua_State *L);
-
-       // get_player_privs(name, text)
-       static int l_get_player_privs(lua_State *L);
-
-       // get_player_ip()
-       static int l_get_player_ip(lua_State *L);
-
-       // get_ban_list()
-       static int l_get_ban_list(lua_State *L);
-
-       // get_ban_description()
-       static int l_get_ban_description(lua_State *L);
-
-       // ban_player()
-       static int l_ban_player(lua_State *L);
-
-       // unban_player_or_ip()
-       static int l_unban_player_or_ip(lua_State *L);
-
-       // show_formspec(playername,formname,formspec)
-       static int l_show_formspec(lua_State *L);
-
-       // get_dig_params(groups, tool_capabilities[, time_from_last_punch])
-       static int l_get_dig_params(lua_State *L);
-
-       // get_hit_params(groups, tool_capabilities[, time_from_last_punch])
-       static int l_get_hit_params(lua_State *L);
-
-       // get_current_modname()
-       static int l_get_current_modname(lua_State *L);
-
-       // get_modpath(modname)
-       static int l_get_modpath(lua_State *L);
-
-       // get_modnames()
-       // the returned list is sorted alphabetically for you
-       static int l_get_modnames(lua_State *L);
-
-       // get_worldpath()
-       static int l_get_worldpath(lua_State *L);
-
-       // sound_play(spec, parameters)
-       static int l_sound_play(lua_State *L);
-
-       // sound_stop(handle)
-       static int l_sound_stop(lua_State *L);
-
-       // is_singleplayer()
-       static int l_is_singleplayer(lua_State *L);
-
-       // get_password_hash(name, raw_password)
-       static int l_get_password_hash(lua_State *L);
-
-       // notify_authentication_modified(name)
-       static int l_notify_authentication_modified(lua_State *L);
-
-       // rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds
-       static int l_rollback_get_last_node_actor(lua_State *L);
-
-       // rollback_revert_actions_by(actor, seconds) -> bool, log messages
-       static int l_rollback_revert_actions_by(lua_State *L);
-
-       // register_ore(oredesc)
-       static int l_register_ore(lua_State *L);
-       
-       // register_decoration(deco)
-       static int l_register_decoration(lua_State *L);
-       
-       // create_schematic(p1, p2, filename)
-       static int l_create_schematic(lua_State *L);
-       
-       // place_schematic(p, filename, rotation)
-       static int l_place_schematic(lua_State *L);
-
-       static struct EnumString es_OreType[];
-       static struct EnumString es_DecorationType[];
-       static struct EnumString es_Rotation[];
-
-};
-
-
-
-#endif /* LUAAPI_H_ */
diff --git a/src/script/scripting_game.cpp b/src/script/scripting_game.cpp
new file mode 100644 (file)
index 0000000..dfbf471
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "scripting_game.h"
+#include "log.h"
+#include "cpp_api/s_internal.h"
+#include "lua_api/l_base.h"
+#include "lua_api/l_craft.h"
+#include "lua_api/l_env.h"
+#include "lua_api/l_inventory.h"
+#include "lua_api/l_item.h"
+#include "lua_api/l_mapgen.h"
+#include "lua_api/l_nodemeta.h"
+#include "lua_api/l_nodetimer.h"
+#include "lua_api/l_noise.h"
+#include "lua_api/l_object.h"
+#include "lua_api/l_particles.h"
+#include "lua_api/l_rollback.h"
+#include "lua_api/l_server.h"
+#include "lua_api/l_util.h"
+#include "lua_api/l_vmanip.h"
+
+extern "C" {
+#include "lualib.h"
+}
+
+GameScripting::GameScripting(Server* server)
+{
+       setServer(server);
+
+       // setEnv(env) is called by ScriptApiEnv::initializeEnvironment()
+       // once the environment has been created
+
+       //TODO add security
+
+       luaL_openlibs(getStack());
+
+       SCRIPTAPI_PRECHECKHEADER
+
+       // Create the main minetest table
+       lua_newtable(L);
+
+       lua_newtable(L);
+       lua_setfield(L, -2, "object_refs");
+
+       lua_newtable(L);
+       lua_setfield(L, -2, "luaentities");
+
+       lua_setglobal(L, "minetest");
+
+       // Initialize our lua_api modules
+       lua_getglobal(L, "minetest");
+       int top = lua_gettop(L);
+       InitializeModApi(L, top);
+       lua_pop(L, 1);
+
+       infostream << "SCRIPTAPI: initialized game modules" << std::endl;
+}
+
+void GameScripting::InitializeModApi(lua_State *L, int top)
+{
+       // Initialize mod api modules
+       ModApiCraft::Initialize(L, top);
+       ModApiEnvMod::Initialize(L, top);
+       ModApiInventory::Initialize(L, top);
+       ModApiItemMod::Initialize(L, top);
+       ModApiMapgen::Initialize(L, top);
+       ModApiParticles::Initialize(L, top);
+       ModApiRollback::Initialize(L, top);
+       ModApiServer::Initialize(L, top);
+       ModApiUtil::Initialize(L, top);
+
+       // Register reference classes (userdata)
+       InvRef::Register(L);
+       LuaItemStack::Register(L);
+       LuaPerlinNoise::Register(L);
+       LuaPerlinNoiseMap::Register(L);
+       LuaPseudoRandom::Register(L);
+       LuaVoxelManip::Register(L);
+       NodeMetaRef::Register(L);
+       NodeTimerRef::Register(L);
+       ObjectRef::Register(L);
+}
diff --git a/src/script/scripting_game.h b/src/script/scripting_game.h
new file mode 100644 (file)
index 0000000..ed65679
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef SCRIPTING_GAME_H_
+#define SCRIPTING_GAME_H_
+
+#include "cpp_api/s_base.h"
+#include "cpp_api/s_entity.h"
+#include "cpp_api/s_env.h"
+#include "cpp_api/s_inventory.h"
+#include "cpp_api/s_node.h"
+#include "cpp_api/s_player.h"
+#include "cpp_api/s_server.h"
+
+/*****************************************************************************/
+/* Scripting <-> Game Interface                                              */
+/*****************************************************************************/
+
+class GameScripting
+               : virtual public ScriptApiBase,
+                 public ScriptApiDetached,
+                 public ScriptApiEntity,
+                 public ScriptApiEnv,
+                 public ScriptApiNode,
+                 public ScriptApiPlayer,
+                 public ScriptApiServer
+{
+public:
+       GameScripting(Server* server);
+
+       // use ScriptApiBase::loadMod() to load mods
+
+private:
+       void InitializeModApi(lua_State *L, int top);
+};
+
+#endif /* SCRIPTING_GAME_H_ */
diff --git a/src/script/scripting_mainmenu.cpp b/src/script/scripting_mainmenu.cpp
new file mode 100644 (file)
index 0000000..47461e7
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "scripting_mainmenu.h"
+#include "log.h"
+#include "filesys.h"
+#include "cpp_api/s_internal.h"
+#include "lua_api/l_base.h"
+#include "lua_api/l_mainmenu.h"
+#include "lua_api/l_util.h"
+
+extern "C" {
+#include "lualib.h"
+}
+
+MainMenuScripting::MainMenuScripting(GUIEngine* guiengine)
+{
+       setGuiEngine(guiengine);
+
+       //TODO add security
+
+       luaL_openlibs(getStack());
+
+       SCRIPTAPI_PRECHECKHEADER
+
+       lua_pushstring(L, DIR_DELIM);
+       lua_setglobal(L, "DIR_DELIM");
+
+       lua_newtable(L);
+       lua_setglobal(L, "gamedata");
+
+       lua_newtable(L);
+       lua_setglobal(L, "engine");
+
+       // Initialize our lua_api modules
+       lua_getglobal(L, "engine");
+       int top = lua_gettop(L);
+       InitializeModApi(L, top);
+       lua_pop(L, 1);
+
+       infostream << "SCRIPTAPI: initialized mainmenu modules" << std::endl;
+}
+
+void MainMenuScripting::InitializeModApi(lua_State *L, int top)
+{
+       // Initialize mod api modules
+       ModApiMainMenu::Initialize(L, top);
+       ModApiUtil::Initialize(L, top);
+}
diff --git a/src/script/scripting_mainmenu.h b/src/script/scripting_mainmenu.h
new file mode 100644 (file)
index 0000000..7592c8e
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef SCRIPTING_MAINMENU_H_
+#define SCRIPTING_MAINMENU_H_
+
+#include "cpp_api/s_base.h"
+#include "cpp_api/s_mainmenu.h"
+
+/*****************************************************************************/
+/* Scripting <-> Main Menu Interface                                         */
+/*****************************************************************************/
+
+class MainMenuScripting
+               : virtual public ScriptApiBase,
+                 public ScriptApiMainMenu
+{
+public:
+       MainMenuScripting(GUIEngine* guiengine);
+
+       // use ScriptApiBase::loadMod() or ScriptApiBase::loadScript()
+       // to load scripts
+
+private:
+       void InitializeModApi(lua_State *L, int top);
+};
+
+
+#endif /* SCRIPTING_MAINMENU_H_ */
index 7926b879fb7815fa9185e57db7192bfd18e38f78..5ecdddcbc3019c57ce751f8c1e019c4be0c07ee7 100644 (file)
@@ -22,6 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <queue>
 #include <algorithm>
 #include "clientserver.h"
+#include "ban.h"
+#include "environment.h"
 #include "map.h"
 #include "jmutexautolock.h"
 #include "main.h"
@@ -34,7 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "settings.h"
 #include "profiler.h"
 #include "log.h"
-#include "script/cpp_api/scriptapi.h"
+#include "scripting_game.h"
 #include "nodedef.h"
 #include "itemdef.h"
 #include "craftdef.h"
@@ -58,6 +60,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/mathconstants.h"
 #include "rollback.h"
 #include "util/serialize.h"
+#include "util/thread.h"
 #include "defaultsettings.h"
 
 class ClientNotFoundException : public BaseException
@@ -68,6 +71,21 @@ public:
        {}
 };
 
+class ServerThread : public SimpleThread
+{
+       Server *m_server;
+
+public:
+
+       ServerThread(Server *server):
+               SimpleThread(),
+               m_server(server)
+       {
+       }
+
+       void * Thread();
+};
+
 void * ServerThread::Thread()
 {
        ThreadStarted();
@@ -613,46 +631,23 @@ void RemoteClient::SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks)
        }
 }
 
-/*
-       PlayerInfo
-*/
-
-PlayerInfo::PlayerInfo()
-{
-       name[0] = 0;
-       avg_rtt = 0;
-}
-
-void PlayerInfo::PrintLine(std::ostream *s)
-{
-       (*s)<<id<<": ";
-       (*s)<<"\""<<name<<"\" ("
-                       <<(position.X/10)<<","<<(position.Y/10)
-                       <<","<<(position.Z/10)<<") ";
-       address.print(s);
-       (*s)<<" avg_rtt="<<avg_rtt;
-       (*s)<<std::endl;
-}
-
 /*
        Server
 */
 
 Server::Server(
                const std::string &path_world,
-               const std::string &path_config,
                const SubgameSpec &gamespec,
                bool simple_singleplayer_mode
        ):
        m_path_world(path_world),
-       m_path_config(path_config),
        m_gamespec(gamespec),
        m_simple_singleplayer_mode(simple_singleplayer_mode),
        m_async_fatal_error(""),
        m_env(NULL),
        m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT,
              g_settings->getBool("enable_ipv6") && g_settings->getBool("ipv6_server"), this),
-       m_banmanager(path_world+DIR_DELIM+"ipban.txt"),
+       m_banmanager(NULL),
        m_rollback(NULL),
        m_rollback_sink_enabled(true),
        m_enable_rollback_recording(false),
@@ -662,7 +657,7 @@ Server::Server(
        m_nodedef(createNodeDefManager()),
        m_craftdef(createCraftDefManager()),
        m_event(new EventManager()),
-       m_thread(this),
+       m_thread(NULL),
        m_time_of_day_send_timer(0),
        m_uptime(0),
        m_shutdown_requested(false),
@@ -695,7 +690,6 @@ Server::Server(
        else
                infostream<<std::endl;
        infostream<<"- world:  "<<m_path_world<<std::endl;
-       infostream<<"- config: "<<m_path_config<<std::endl;
        infostream<<"- game:   "<<m_gamespec.path<<std::endl;
 
        // Initialize default settings and override defaults with those provided
@@ -704,10 +698,17 @@ Server::Server(
        Settings gamedefaults;
        getGameMinetestConfig(gamespec.path, gamedefaults);
        override_default_settings(g_settings, &gamedefaults);
-       
+
+       // Create server thread
+       m_thread = new ServerThread(this);
+
        // Create emerge manager
        m_emerge = new EmergeManager(this);
-       
+
+       // Create ban manager
+       std::string ban_path = m_path_world+DIR_DELIM+"ipban.txt";
+       m_banmanager = new BanManager(ban_path);
+
        // Create rollback manager
        std::string rollback_path = m_path_world+DIR_DELIM+"rollback.txt";
        m_rollback = createRollbackManager(rollback_path, this);
@@ -773,7 +774,7 @@ Server::Server(
 
        infostream<<"Server: Initializing Lua"<<std::endl;
 
-       m_script = new ScriptApi(this);
+       m_script = new GameScripting(this);
 
 
        // Load and run builtin.lua
@@ -816,7 +817,7 @@ Server::Server(
 
        // Initialize Environment
        ServerMap *servermap = new ServerMap(path_world, this, m_emerge);
-       m_env = new ServerEnvironment(servermap, m_script, this, this);
+       m_env = new ServerEnvironment(servermap, m_script, this, m_emerge);
        
        // Run some callbacks after the MG params have been set up but before activation
        MapgenParams *mgparams = servermap->getMapgenParams();
@@ -913,6 +914,7 @@ Server::~Server()
                Stop threads
        */
        stop();
+       delete m_thread;
 
        //shutdown all emerge threads first!
        delete m_emerge;
@@ -936,6 +938,7 @@ Server::~Server()
        // Delete things in the reverse order of creation
        delete m_env;
        delete m_rollback;
+       delete m_banmanager;
        delete m_event;
        delete m_itemdef;
        delete m_nodedef;
@@ -961,15 +964,15 @@ void Server::start(unsigned short port)
        infostream<<"Starting server on port "<<port<<"..."<<std::endl;
 
        // Stop thread if already running
-       m_thread.stop();
+       m_thread->stop();
 
        // Initialize connection
        m_con.SetTimeoutMs(30);
        m_con.Serve(port);
 
        // Start thread
-       m_thread.setRun(true);
-       m_thread.Start();
+       m_thread->setRun(true);
+       m_thread->Start();
 
        // ASCII art for the win!
        actionstream
@@ -991,9 +994,9 @@ void Server::stop()
        infostream<<"Server: Stopping and waiting threads"<<std::endl;
 
        // Stop threads (set run=false first so both start stopping)
-       m_thread.setRun(false);
+       m_thread->setRun(false);
        //m_emergethread.setRun(false);
-       m_thread.stop();
+       m_thread->stop();
        //m_emergethread.stop();
 
        infostream<<"Server: Threads stopped"<<std::endl;
@@ -1086,15 +1089,15 @@ void Server::AsyncRunStep()
                        //JMutexAutoLock envlock(m_env_mutex);
                        JMutexAutoLock conlock(m_con_mutex);
 
+                       u16 time = m_env->getTimeOfDay();
+                       float time_speed = g_settings->getFloat("time_speed");
+
                        for(std::map<u16, RemoteClient*>::iterator
                                i = m_clients.begin();
                                i != m_clients.end(); ++i)
                        {
                                RemoteClient *client = i->second;
-                               SharedBuffer<u8> data = makePacket_TOCLIENT_TIME_OF_DAY(
-                                               m_env->getTimeOfDay(), g_settings->getFloat("time_speed"));
-                               // Send as reliable
-                               m_con.Send(client->peer_id, 0, data, true);
+                               SendTimeOfDay(client->peer_id, time, time_speed);
                        }
                }
        }
@@ -1680,8 +1683,7 @@ void Server::AsyncRunStep()
                {
                        counter = 0.0;
 
-                       for (unsigned int i = 0; i != m_emerge->emergethread.size(); i++)
-                               m_emerge->emergethread[i]->trigger();
+                       m_emerge->triggerAllThreads();
 
                        // Update m_enable_rollback_recording here too
                        m_enable_rollback_recording =
@@ -1701,8 +1703,8 @@ void Server::AsyncRunStep()
                        ScopeProfiler sp(g_profiler, "Server: saving stuff");
 
                        //Ban stuff
-                       if(m_banmanager.isModified())
-                               m_banmanager.save();
+                       if(m_banmanager->isModified())
+                               m_banmanager->save();
 
                        // Save changed parts of map
                        m_env->getMap().save(MOD_STATE_WRITE_NEEDED);
@@ -1772,13 +1774,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                addr_s = address.serializeString();
 
                // drop player if is ip is banned
-               if(m_banmanager.isIpBanned(addr_s)){
+               if(m_banmanager->isIpBanned(addr_s)){
                        infostream<<"Server: A banned client tried to connect from "
                                        <<addr_s<<"; banned name was "
-                                       <<m_banmanager.getBanName(addr_s)<<std::endl;
+                                       <<m_banmanager->getBanName(addr_s)<<std::endl;
                        // This actually doesn't seem to transfer to the client
                        DenyAccess(peer_id, L"Your ip is banned. Banned name was "
-                                       +narrow_to_wide(m_banmanager.getBanName(addr_s)));
+                                       +narrow_to_wide(m_banmanager->getBanName(addr_s)));
                        m_con.DeletePeer(peer_id);
                        return;
                }
@@ -2159,9 +2161,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 
                // Send time of day
                {
-                       SharedBuffer<u8> data = makePacket_TOCLIENT_TIME_OF_DAY(
-                                       m_env->getTimeOfDay(), g_settings->getFloat("time_speed"));
-                       m_con.Send(peer_id, 0, data, true);
+                       u16 time = m_env->getTimeOfDay();
+                       float time_speed = g_settings->getFloat("time_speed");
+                       SendTimeOfDay(peer_id, time, time_speed);
                }
 
                // Note things in chat if not in simple singleplayer mode
@@ -3203,6 +3205,12 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
        }
 }
 
+void Server::setTimeOfDay(u32 time)
+{
+       m_env->setTimeOfDay(time);
+       m_time_of_day_send_timer = 0;
+}
+
 void Server::onMapEditEvent(MapEditEvent *event)
 {
        //infostream<<"Server::onMapEditEvent()"<<std::endl;
@@ -3293,48 +3301,6 @@ void Server::setInventoryModified(const InventoryLocation &loc)
        }
 }
 
-//std::list<PlayerInfo> Server::getPlayerInfo()
-//{
-//     DSTACK(__FUNCTION_NAME);
-//     JMutexAutoLock envlock(m_env_mutex);
-//     JMutexAutoLock conlock(m_con_mutex);
-//
-//     std::list<PlayerInfo> list;
-//
-//     std::list<Player*> players = m_env->getPlayers();
-//
-//     std::list<Player*>::iterator i;
-//     for(i = players.begin();
-//                     i != players.end(); ++i)
-//     {
-//             PlayerInfo info;
-//
-//             Player *player = *i;
-//
-//             try{
-//                     // Copy info from connection to info struct
-//                     info.id = player->peer_id;
-//                     info.address = m_con.GetPeerAddress(player->peer_id);
-//                     info.avg_rtt = m_con.GetPeerAvgRTT(player->peer_id);
-//             }
-//             catch(con::PeerNotFoundException &e)
-//             {
-//                     // Set dummy peer info
-//                     info.id = 0;
-//                     info.address = Address(0,0,0,0,0);
-//                     info.avg_rtt = 0.0;
-//             }
-//
-//             snprintf(info.name, PLAYERNAME_SIZE, "%s", player->getName());
-//             info.position = player->getPosition();
-//
-//             list.push_back(info);
-//     }
-//
-//     return list;
-//}
-
-
 void Server::peerAdded(con::Peer *peer)
 {
        DSTACK(__FUNCTION_NAME);
@@ -3841,6 +3807,20 @@ void Server::BroadcastChatMessage(const std::wstring &message)
        }
 }
 
+void Server::SendTimeOfDay(u16 peer_id, u16 time, f32 time_speed)
+{
+       DSTACK(__FUNCTION_NAME);
+
+       // Make packet
+       SharedBuffer<u8> data(2+2+4);
+       writeU16(&data[0], TOCLIENT_TIME_OF_DAY);
+       writeU16(&data[2], time);
+       writeF1000(&data[4], time_speed);
+
+       // Send as reliable
+       m_con.Send(peer_id, 0, data, true);
+}
+
 void Server::SendPlayerHP(u16 peer_id)
 {
        DSTACK(__FUNCTION_NAME);
@@ -4774,9 +4754,6 @@ void Server::DeleteClient(u16 peer_id, ClientDeletionReason reason)
        delete m_clients[peer_id];
        m_clients.erase(peer_id);
 
-       // Send player info to all remaining clients
-       //SendPlayerInfos();
-
        // Send leave chat message to all remaining clients
        if(message.length() != 0)
                BroadcastChatMessage(message);
@@ -4818,6 +4795,22 @@ RemoteClient* Server::getClientNoEx(u16 peer_id)
        return n->second;
 }
 
+std::string Server::getPlayerName(u16 peer_id)
+{
+       Player *player = m_env->getPlayer(peer_id);
+       if(player == NULL)
+               return "[id="+itos(peer_id)+"]";
+       return player->getName();
+}
+
+PlayerSAO* Server::getPlayerSAO(u16 peer_id)
+{
+       Player *player = m_env->getPlayer(peer_id);
+       if(player == NULL)
+               return NULL;
+       return player->getPlayerSAO();
+}
+
 std::wstring Server::getStatusString()
 {
        std::wostringstream os(std::ios_base::binary);
@@ -4906,11 +4899,19 @@ void Server::reportInventoryFormspecModified(const std::string &name)
        SendPlayerInventoryFormspec(player->peer_id);
 }
 
-// Saves g_settings to configpath given at initialization
-void Server::saveConfig()
+void Server::setIpBanned(const std::string &ip, const std::string &name)
 {
-       if(m_path_config != "")
-               g_settings->updateConfigFile(m_path_config.c_str());
+       m_banmanager->add(ip, name);
+}
+
+void Server::unsetIpBanned(const std::string &ip_or_name)
+{
+       m_banmanager->remove(ip_or_name);
+}
+
+std::string Server::getBanDescription(const std::string &ip_or_name)
+{
+       return m_banmanager->getBanDescription(ip_or_name);
 }
 
 void Server::notifyPlayer(const char *name, const std::wstring msg, const bool prepend = true)
@@ -4942,7 +4943,7 @@ u32 Server::hudAdd(Player *player, HudElement *form) {
        if (!player)
                return -1;
 
-       u32 id = hud_get_free_id(player);
+       u32 id = player->getFreeHudID();
        if (id < player->hud.size())
                player->hud[id] = form;
        else
@@ -5101,11 +5102,6 @@ void Server::deleteParticleSpawnerAll(u32 id)
        SendDeleteParticleSpawnerAll(id);
 }
 
-void Server::queueBlockEmerge(v3s16 blockpos, bool allow_generate)
-{
-       m_emerge->enqueueBlockEmerge(PEER_ID_INEXISTENT, blockpos, allow_generate);
-}
-
 Inventory* Server::createDetachedInventory(const std::string &name)
 {
        if(m_detached_inventories.count(name) > 0){
index d49ecdf7b8f6b69ec2bd7fa34f9ee7483b835b00..4e7675ecb2a70d7433ac803c34629a450f40779f 100644 (file)
@@ -21,37 +21,37 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define SERVER_HEADER
 
 #include "connection.h"
-#include "environment.h"
-#include "irrlichttypes_bloated.h"
-#include <string>
-#include "porting.h"
+#include "irr_v3d.h"
 #include "map.h"
-#include "inventory.h"
-#include "ban.h"
 #include "hud.h"
 #include "gamedef.h"
 #include "serialization.h" // For SER_FMT_VER_INVALID
 #include "mods.h"
 #include "inventorymanager.h"
 #include "subgame.h"
-#include "sound.h"
-#include "util/thread.h"
-#include "util/string.h"
 #include "rollback_interface.h" // Needed for rollbackRevertActions()
-#include <list> // Needed for rollbackRevertActions()
-#include <algorithm>
+#include "util/numeric.h"
+#include "util/thread.h"
+#include <string>
+#include <list>
+#include <map>
+#include <vector>
 
 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
 
 class IWritableItemDefManager;
 class IWritableNodeDefManager;
 class IWritableCraftDefManager;
+class BanManager;
 class EventManager;
+class Inventory;
+class Player;
 class PlayerSAO;
 class IRollbackManager;
 class EmergeManager;
-//struct HudElement; ?????????
-class ScriptApi;
+class GameScripting;
+class ServerEnvironment;
+struct SimpleSoundSpec;
 
 
 class ServerError : public std::exception
@@ -128,33 +128,7 @@ private:
 };
 
 class Server;
-
-class ServerThread : public SimpleThread
-{
-       Server *m_server;
-
-public:
-
-       ServerThread(Server *server):
-               SimpleThread(),
-               m_server(server)
-       {
-       }
-
-       void * Thread();
-};
-
-struct PlayerInfo
-{
-       u16 id;
-       char name[PLAYERNAME_SIZE];
-       v3f position;
-       Address address;
-       float avg_rtt;
-
-       PlayerInfo();
-       void PrintLine(std::ostream *s);
-};
+class ServerThread;
 
 /*
        Used for queueing and sorting block transfers in containers
@@ -362,8 +336,7 @@ private:
 };
 
 class Server : public con::PeerHandler, public MapEventReceiver,
-               public InventoryManager, public IGameDef,
-               public IBackgroundBlockEmerger
+               public InventoryManager, public IGameDef
 {
 public:
        /*
@@ -372,7 +345,6 @@ public:
 
        Server(
                const std::string &path_world,
-               const std::string &path_config,
                const SubgameSpec &gamespec,
                bool simple_singleplayer_mode
        );
@@ -387,14 +359,8 @@ public:
        void Receive();
        void ProcessData(u8 *data, u32 datasize, u16 peer_id);
 
-       //std::list<PlayerInfo> getPlayerInfo();
-
        // Environment must be locked when called
-       void setTimeOfDay(u32 time)
-       {
-               m_env->setTimeOfDay(time);
-               m_time_of_day_send_timer = 0;
-       }
+       void setTimeOfDay(u32 time);
 
        bool getShutdownRequested()
        {
@@ -433,25 +399,9 @@ public:
        void reportPrivsModified(const std::string &name=""); // ""=all
        void reportInventoryFormspecModified(const std::string &name);
 
-       // Saves g_settings to configpath given at initialization
-       void saveConfig();
-
-       void setIpBanned(const std::string &ip, const std::string &name)
-       {
-               m_banmanager.add(ip, name);
-               return;
-       }
-
-       void unsetIpBanned(const std::string &ip_or_name)
-       {
-               m_banmanager.remove(ip_or_name);
-               return;
-       }
-
-       std::string getBanDescription(const std::string &ip_or_name)
-       {
-               return m_banmanager.getBanDescription(ip_or_name);
-       }
+       void setIpBanned(const std::string &ip, const std::string &name);
+       void unsetIpBanned(const std::string &ip_or_name);
+       std::string getBanDescription(const std::string &ip_or_name);
 
        Address getPeerAddress(u16 peer_id)
        {
@@ -490,13 +440,11 @@ public:
        void deleteParticleSpawner(const char *playername, u32 id);
        void deleteParticleSpawnerAll(u32 id);
 
-       void queueBlockEmerge(v3s16 blockpos, bool allow_generate);
-
        // Creates or resets inventory
        Inventory* createDetachedInventory(const std::string &name);
 
        // Envlock and conlock should be locked when using scriptapi
-       ScriptApi *getScriptIface(){ return m_script; }
+       GameScripting *getScriptIface(){ return m_script; }
 
        // Envlock should be locked when using the rollback manager
        IRollbackManager *getRollbackManager(){ return m_rollback; }
@@ -581,6 +529,7 @@ private:
        void SendInventory(u16 peer_id);
        void SendChatMessage(u16 peer_id, const std::wstring &message);
        void BroadcastChatMessage(const std::wstring &message);
+       void SendTimeOfDay(u16 peer_id, u16 time, f32 time_speed);
        void SendPlayerHP(u16 peer_id);
        void SendPlayerBreath(u16 peer_id);
        void SendMovePlayer(u16 peer_id);
@@ -677,22 +626,8 @@ private:
        RemoteClient* getClientNoEx(u16 peer_id);
 
        // When called, environment mutex should be locked
-       std::string getPlayerName(u16 peer_id)
-       {
-               Player *player = m_env->getPlayer(peer_id);
-               if(player == NULL)
-                       return "[id="+itos(peer_id)+"]";
-               return player->getName();
-       }
-
-       // When called, environment mutex should be locked
-       PlayerSAO* getPlayerSAO(u16 peer_id)
-       {
-               Player *player = m_env->getPlayer(peer_id);
-               if(player == NULL)
-                       return NULL;
-               return player->getPlayerSAO();
-       }
+       std::string getPlayerName(u16 peer_id);
+       PlayerSAO* getPlayerSAO(u16 peer_id);
 
        /*
                Get a player from memory or creates one.
@@ -714,8 +649,6 @@ private:
 
        // World directory
        std::string m_path_world;
-       // Path to user's configuration file ("" = no configuration file)
-       std::string m_path_config;
        // Subgame specification
        SubgameSpec m_gamespec;
        // If true, do not allow multiple players and hide some multiplayer
@@ -750,7 +683,7 @@ private:
        u16 m_clients_number; //for announcing masterserver
 
        // Ban checking
-       BanManager m_banmanager;
+       BanManager *m_banmanager;
 
        // Rollback manager (behind m_env_mutex)
        IRollbackManager *m_rollback;
@@ -762,7 +695,7 @@ private:
 
        // Scripting
        // Envlock and conlock should be locked when using Lua
-       ScriptApi *m_script;
+       GameScripting *m_script;
 
        // Item definition manager
        IWritableItemDefManager *m_itemdef;
@@ -789,7 +722,7 @@ private:
        JMutex m_step_dtime_mutex;
 
        // The server mainly operates in this thread
-       ServerThread m_thread;
+       ServerThread *m_thread;
 
        /*
                Time related stuff
index a9e0faa40a59898fc793f0c327bcf54ef75f8d5b..62596f869c9010b9bf47d1ce2a9eeb31aa18743c 100644 (file)
@@ -21,8 +21,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define SETTINGS_HEADER
 
 #include "irrlichttypes_bloated.h"
+#include "exceptions.h"
 #include <string>
-#include <jthread.h>
 #include <jmutex.h>
 #include <jmutexautolock.h>
 #include "strfnd.h"
index 8505b24f75fdb72f25f6dffe922deb577762a532..1c07c44d5839e350b0913ef04bd7a6faec55b743 100644 (file)
@@ -56,6 +56,7 @@ typedef int socket_t;
 #include <string.h>
 #include <errno.h>
 #include <sstream>
+#include <iomanip>
 #include "util/string.h"
 #include "util/numeric.h"
 
@@ -392,9 +393,10 @@ void UDPSocket::Send(const Address & destination, const void * data, int size)
                for(int i = 0; i < size && i < 20; i++)
                {
                        if(i % 2 == 0)
-                               DEBUGPRINT(" ");
+                               dstream << " ";
                        unsigned int a = ((const unsigned char *) data)[i];
-                       DEBUGPRINT("%.2X", a);
+                       dstream << std::hex << std::setw(2) << std::setfill('0')
+                               << a;
                }
                
                if(size > 20)
@@ -494,9 +496,10 @@ int UDPSocket::Receive(Address & sender, void * data, int size)
                for(int i = 0; i < received && i < 20; i++)
                {
                        if(i % 2 == 0)
-                               DEBUGPRINT(" ");
+                               dstream << " ";
                        unsigned int a = ((const unsigned char *) data)[i];
-                       DEBUGPRINT("%.2X", a);
+                       dstream << std::hex << std::setw(2) << std::setfill('0')
+                               << a;
                }
                if(received > 20)
                        dstream << "...";
index 4a72edf3c50f474aa38e841ba15973a29c2772ff..3142cc10d180d6a9a919adb31ea8bbee0770764c 100644 (file)
@@ -22,8 +22,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include <string>
 
-std::string trim(const std::string &str);
-
 class Strfnd{
     std::string tek;
     unsigned int p;
@@ -174,43 +172,5 @@ public:
     }
 };
 
-inline std::string trim(const std::string &s)
-{
-       std::string str = s;
-    while( 
-            str.length()>0
-            &&
-            (
-             str.substr(0,               1)==" "     ||
-             str.substr(0,               1)=="\t"    ||
-             str.substr(0,               1)=="\r"    ||
-             str.substr(0,               1)=="\n"    ||
-             str.substr(str.length()-1,  1)==" "     ||
-             str.substr(str.length()-1,  1)=="\t"    ||
-             str.substr(str.length()-1,  1)=="\r"    ||
-             str.substr(str.length()-1,  1)=="\n"
-            )
-         )
-    {  
-        if      (str.substr(0,              1)==" ")
-                       str = str.substr(1,str.length()-1);
-        else if (str.substr(0,              1)=="\t")
-                       str = str.substr(1,str.length()-1);
-        else if (str.substr(0,              1)=="\r")
-                       str = str.substr(1,str.length()-1);
-        else if (str.substr(0,              1)=="\n")
-                       str = str.substr(1,str.length()-1);
-        else if (str.substr(str.length()-1, 1)==" ")
-                       str = str.substr(0,str.length()-1);
-        else if (str.substr(str.length()-1, 1)=="\t")
-                       str = str.substr(0,str.length()-1);
-        else if (str.substr(str.length()-1, 1)=="\r")
-                       str = str.substr(0,str.length()-1);
-        else if (str.substr(str.length()-1, 1)=="\n")
-                       str = str.substr(0,str.length()-1);
-    }
-    return str;
-}
-
 #endif
 
index fa7a82428182c604a960891f29f8d6c0c6717d16..5e025f2f5fb23164165a1b2ca80f97b871c279b6 100644 (file)
@@ -157,6 +157,8 @@ struct TestUtilities: public TestBase
                UASSERT(fabs(wrapDegrees(-0.5) - (-0.5)) < 0.001);
                UASSERT(fabs(wrapDegrees(-365.5) - (-5.5)) < 0.001);
                UASSERT(lowercase("Foo bAR") == "foo bar");
+               UASSERT(trim("\n \t\r  Foo bAR  \r\n\t\t  ") == "Foo bAR");
+               UASSERT(trim("\n \t\r    \r\n\t\t  ") == "");
                UASSERT(is_yes("YeS") == true);
                UASSERT(is_yes("") == false);
                UASSERT(is_yes("FAlse") == false);
index a3717a1def6a521937043f7b6c2fb48fda5e267b..18789cf0caca5b73d93549a97c50a974547d148a 100644 (file)
@@ -24,12 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #if (defined(WIN32) || defined(_WIN32_WCE))
 typedef DWORD threadid_t;
-#define __NORETURN __declspec(noreturn)
-#define __FUNCTION_NAME __FUNCTION__
 #else
 typedef pthread_t threadid_t;
-#define __NORETURN __attribute__ ((__noreturn__))
-#define __FUNCTION_NAME __PRETTY_FUNCTION__
 #endif
 
 inline threadid_t get_current_thread_id()
index 4d809e2c44ffc75e3e1e374a439004b19a2d8462..f3b3e656f8766d546e7d90a1d0abf758baa5bb57 100644 (file)
@@ -18,9 +18,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "tool.h"
-#include "itemdef.h" // For itemgroup_get()
+#include "itemgroup.h"
 #include "log.h"
 #include "inventory.h"
+#include "exceptions.h"
 #include "util/serialize.h"
 #include "util/numeric.h"
 
index 808cf916a386ada660edd03dff69297445cea4a2..6291567d56519719966bba7f1890513fc1aff4dc 100644 (file)
@@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "irr_v3d.h"
 #include <stack>
+#include "util/pointer.h"
 #include "util/numeric.h"
 #include "util/mathconstants.h"
 #include "map.h"
index 16c85cf0a301c079cce25c3e396fa2b37eefcb8a..55da6f9e5bd6e014fee2e3b92843406c20977084 100644 (file)
@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 class ManualMapVoxelManipulator;
 class INodeDefManager;
+class ServerEnvironment;
 
 
 namespace treegen {
index 84616d2dba88a3617a15b004f947086fb764de48..d5854909ac20fd7359616a3afffd21228185a895 100644 (file)
@@ -21,11 +21,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define UTIL_CONTAINER_HEADER
 
 #include "../irrlichttypes.h"
+#include "../exceptions.h"
 #include <jmutex.h>
 #include <jmutexautolock.h>
 #include "../porting.h" // For sleep_ms
 #include <list>
 #include <vector>
+#include <map>
 
 /*
        Queue with unique values with fast checking of value existence
index 076a08efc9d1bde6a52968af394744876e80b76e..b96c94faa70cad3a14cc89134ab09d7181c03623 100644 (file)
@@ -24,7 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "../irr_v2d.h"
 #include "../irr_v3d.h"
 #include "../irr_aabb3d.h"
-#include <irrList.h>
 #include <list>
 
 // Calculate the borders of a "d-radius" cube
index dc39e313a4b31d7eb0e8a116a78794a84c388114..cd13000b5302c71b40c1b3a5137cc5b320f28cf2 100644 (file)
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "pointedthing.h"
 
 #include "serialize.h"
+#include "../exceptions.h"
 #include <sstream>
 
 PointedThing::PointedThing():
index f3281355133e957dfa9b054f1f7ca5fd3937b8da..d6be5c487d8744753b15f7a28218d824c780da4e 100644 (file)
@@ -18,10 +18,112 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "serialize.h"
+#include "pointer.h"
+#include "../exceptions.h"
 
 #include <sstream>
 #include <iomanip>
 
+// Creates a string with the length as the first two bytes
+std::string serializeString(const std::string &plain)
+{
+       //assert(plain.size() <= 65535);
+       if(plain.size() > 65535)
+               throw SerializationError("String too long for serializeString");
+       char buf[2];
+       writeU16((u8*)&buf[0], plain.size());
+       std::string s;
+       s.append(buf, 2);
+       s.append(plain);
+       return s;
+}
+
+// Creates a string with the length as the first two bytes from wide string
+std::string serializeWideString(const std::wstring &plain)
+{
+       //assert(plain.size() <= 65535);
+       if(plain.size() > 65535)
+               throw SerializationError("String too long for serializeString");
+       char buf[2];
+       writeU16((u8*)buf, plain.size());
+       std::string s;
+       s.append(buf, 2);
+       for(u32 i=0; i<plain.size(); i++)
+       {
+               writeU16((u8*)buf, plain[i]);
+               s.append(buf, 2);
+       }
+       return s;
+}
+
+// Reads a string with the length as the first two bytes
+std::string deSerializeString(std::istream &is)
+{
+       char buf[2];
+       is.read(buf, 2);
+       if(is.gcount() != 2)
+               throw SerializationError("deSerializeString: size not read");
+       u16 s_size = readU16((u8*)buf);
+       if(s_size == 0)
+               return "";
+       Buffer<char> buf2(s_size);
+       is.read(&buf2[0], s_size);
+       std::string s;
+       s.reserve(s_size);
+       s.append(&buf2[0], s_size);
+       return s;
+}
+
+// Reads a wide string with the length as the first two bytes
+std::wstring deSerializeWideString(std::istream &is)
+{
+       char buf[2];
+       is.read(buf, 2);
+       if(is.gcount() != 2)
+               throw SerializationError("deSerializeString: size not read");
+       u16 s_size = readU16((u8*)buf);
+       if(s_size == 0)
+               return L"";
+       std::wstring s;
+       s.reserve(s_size);
+       for(u32 i=0; i<s_size; i++)
+       {
+               is.read(&buf[0], 2);
+               wchar_t c16 = readU16((u8*)buf);
+               s.append(&c16, 1);
+       }
+       return s;
+}
+
+// Creates a string with the length as the first four bytes
+std::string serializeLongString(const std::string &plain)
+{
+       char buf[4];
+       writeU32((u8*)&buf[0], plain.size());
+       std::string s;
+       s.append(buf, 4);
+       s.append(plain);
+       return s;
+}
+
+// Reads a string with the length as the first four bytes
+std::string deSerializeLongString(std::istream &is)
+{
+       char buf[4];
+       is.read(buf, 4);
+       if(is.gcount() != 4)
+               throw SerializationError("deSerializeLongString: size not read");
+       u32 s_size = readU32((u8*)buf);
+       if(s_size == 0)
+               return "";
+       Buffer<char> buf2(s_size);
+       is.read(&buf2[0], s_size);
+       std::string s;
+       s.reserve(s_size);
+       s.append(&buf2[0], s_size);
+       return s;
+}
+
 // Creates a string encoded in JSON format (almost equivalent to a C string literal)
 std::string serializeJsonString(const std::string &plain)
 {
index bb44c7f9647678734b9e98f02d9345abb17c276d..7a37cd70f10e72c9e78d4c5150e13d14d31d008d 100644 (file)
@@ -20,14 +20,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef UTIL_SERIALIZE_HEADER
 #define UTIL_SERIALIZE_HEADER
 
-#include "../irrlichttypes.h"
 #include "../irrlichttypes_bloated.h"
-#include "../irr_v2d.h"
-#include "../irr_v3d.h"
 #include <iostream>
 #include <string>
-#include "../exceptions.h"
-#include "pointer.h"
 
 inline void writeU64(u8 *data, u64 i)
 {
@@ -383,104 +378,22 @@ inline video::SColor readARGB8(std::istream &is)
 */
 
 // Creates a string with the length as the first two bytes
-inline std::string serializeString(const std::string &plain)
-{
-       //assert(plain.size() <= 65535);
-       if(plain.size() > 65535)
-               throw SerializationError("String too long for serializeString");
-       char buf[2];
-       writeU16((u8*)&buf[0], plain.size());
-       std::string s;
-       s.append(buf, 2);
-       s.append(plain);
-       return s;
-}
+std::string serializeString(const std::string &plain);
 
 // Creates a string with the length as the first two bytes from wide string
-inline std::string serializeWideString(const std::wstring &plain)
-{
-       //assert(plain.size() <= 65535);
-       if(plain.size() > 65535)
-               throw SerializationError("String too long for serializeString");
-       char buf[2];
-       writeU16((u8*)buf, plain.size());
-       std::string s;
-       s.append(buf, 2);
-       for(u32 i=0; i<plain.size(); i++)
-       {
-               writeU16((u8*)buf, plain[i]);
-               s.append(buf, 2);
-       }
-       return s;
-}
+std::string serializeWideString(const std::wstring &plain);
 
 // Reads a string with the length as the first two bytes
-inline std::string deSerializeString(std::istream &is)
-{
-       char buf[2];
-       is.read(buf, 2);
-       if(is.gcount() != 2)
-               throw SerializationError("deSerializeString: size not read");
-       u16 s_size = readU16((u8*)buf);
-       if(s_size == 0)
-               return "";
-       Buffer<char> buf2(s_size);
-       is.read(&buf2[0], s_size);
-       std::string s;
-       s.reserve(s_size);
-       s.append(&buf2[0], s_size);
-       return s;
-}
+std::string deSerializeString(std::istream &is);
 
 // Reads a wide string with the length as the first two bytes
-inline std::wstring deSerializeWideString(std::istream &is)
-{
-       char buf[2];
-       is.read(buf, 2);
-       if(is.gcount() != 2)
-               throw SerializationError("deSerializeString: size not read");
-       u16 s_size = readU16((u8*)buf);
-       if(s_size == 0)
-               return L"";
-       std::wstring s;
-       s.reserve(s_size);
-       for(u32 i=0; i<s_size; i++)
-       {
-               is.read(&buf[0], 2);
-               wchar_t c16 = readU16((u8*)buf);
-               s.append(&c16, 1);
-       }
-       return s;
-}
+std::wstring deSerializeWideString(std::istream &is);
 
 // Creates a string with the length as the first four bytes
-inline std::string serializeLongString(const std::string &plain)
-{
-       char buf[4];
-       writeU32((u8*)&buf[0], plain.size());
-       std::string s;
-       s.append(buf, 4);
-       s.append(plain);
-       return s;
-}
+std::string serializeLongString(const std::string &plain);
 
 // Reads a string with the length as the first four bytes
-inline std::string deSerializeLongString(std::istream &is)
-{
-       char buf[4];
-       is.read(buf, 4);
-       if(is.gcount() != 4)
-               throw SerializationError("deSerializeLongString: size not read");
-       u32 s_size = readU32((u8*)buf);
-       if(s_size == 0)
-               return "";
-       Buffer<char> buf2(s_size);
-       is.read(&buf2[0], s_size);
-       std::string s;
-       s.reserve(s_size);
-       s.append(&buf2[0], s_size);
-       return s;
-}
+std::string deSerializeLongString(std::istream &is);
 
 // Creates a string encoded in JSON format (almost equivalent to a C string literal)
 std::string serializeJsonString(const std::string &plain);
index 3bd8b7364d9239c27b51225dcdd191a3193ce965..2c1dea49706cb97f899a87b6c5dffc8660a4f91d 100644 (file)
@@ -18,11 +18,35 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "string.h"
+#include "pointer.h"
 
 #include "../sha1.h"
 #include "../base64.h"
 #include "../porting.h"
 
+std::wstring narrow_to_wide(const std::string& mbs)
+{
+       size_t wcl = mbs.size();
+       Buffer<wchar_t> wcs(wcl+1);
+       size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
+       if(l == (size_t)(-1))
+               return L"<invalid multibyte string>";
+       wcs[l] = 0;
+       return *wcs;
+}
+
+std::string wide_to_narrow(const std::wstring& wcs)
+{
+       size_t mbl = wcs.size()*4;
+       SharedBuffer<char> mbs(mbl+1);
+       size_t l = wcstombs(*mbs, wcs.c_str(), mbl);
+       if(l == (size_t)(-1))
+               mbs[0] = 0;
+       else
+               mbs[l] = 0;
+       return *mbs;
+}
+
 // Get an sha-1 hash of the player's name combined with
 // the password entered. That's what the server uses as
 // their password. (Exception : if the password field is
index d8cedc3e8ed7c938cc012717075b0a636ceb8dc2..1cb4ae8d8da6bbf2900a194a27cca3880568957d 100644 (file)
@@ -21,8 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define UTIL_STRING_HEADER
 
 #include "../irrlichttypes.h"
-#include "../strfnd.h" // For trim()
-#include "pointer.h"
+#include <stdlib.h>
 #include <string>
 #include <cstring>
 #include <vector>
@@ -33,6 +32,9 @@ struct FlagDesc {
        u32 flag;
 };
 
+std::wstring narrow_to_wide(const std::string& mbs);
+std::string wide_to_narrow(const std::wstring& wcs);
+
 static inline std::string padStringRight(std::string s, size_t len)
 {
        if(len > s.size())
@@ -95,29 +97,6 @@ inline bool str_starts_with(const std::wstring& str, const std::wstring& prefix,
        return true;
 }
 
-inline std::wstring narrow_to_wide(const std::string& mbs)
-{
-       size_t wcl = mbs.size();
-       Buffer<wchar_t> wcs(wcl+1);
-       size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
-       if(l == (size_t)(-1))
-               return L"<invalid multibyte string>";
-       wcs[l] = 0;
-       return *wcs;
-}
-
-inline std::string wide_to_narrow(const std::wstring& wcs)
-{
-       size_t mbl = wcs.size()*4;
-       SharedBuffer<char> mbs(mbl+1);
-       size_t l = wcstombs(*mbs, wcs.c_str(), mbl);
-       if(l == (size_t)(-1))
-               mbs[0] = 0;
-       else
-               mbs[l] = 0;
-       return *mbs;
-}
-
 // Split a string using the given delimiter. Returns a vector containing
 // the component parts.
 inline std::vector<std::wstring> str_split(const std::wstring &str, wchar_t delimiter)
@@ -143,6 +122,29 @@ inline std::string lowercase(const std::string &s)
        return s2;
 }
 
+inline std::string trim(const std::string &s)
+{
+       size_t front = 0;
+       while(s[front] == ' '    ||
+             s[front] == '\t'   ||
+             s[front] == '\r'   ||
+             s[front] == '\n'
+            )
+               ++front;
+
+       size_t back = s.size();
+       while(back > front &&
+             (s[back-1] == ' '  ||
+              s[back-1] == '\t' ||
+              s[back-1] == '\r' ||
+              s[back-1] == '\n'
+             )
+            )
+               --back;
+
+       return s.substr(front, back - front);
+}
+
 inline bool is_yes(const std::string &s)
 {
        std::string s2 = lowercase(trim(s));
index 58519ed5f2ec10406b45e4ed2598b54f7205457f..4b523b5960ce7235b843ac603c591710c0540da7 100644 (file)
@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "gettime.h"
 #include "nodedef.h"
 #include "util/timetaker.h"
+#include <string.h>  // memcpy, memset
 
 /*
        Debug stuff
index bed35b57e87a43acc9818995a4a24b91a07c37d9..fa459444ff5a539b0b19eab57398e8a29b8cd301 100644 (file)
@@ -22,12 +22,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "irrlichttypes.h"
 #include "irr_v3d.h"
-#include <irrList.h>
 #include <iostream>
 #include "debug.h"
+#include "exceptions.h"
 #include "mapnode.h"
 #include <set>
 #include <list>
+#include <map>
 
 class INodeDefManager;