+print = engine.debug
+math.randomseed(os.time())
os.setlocale("C", "numeric")
local scriptpath = engine.get_scriptdir()
--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")
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
}
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
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"
# 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/
base64.cpp
ban.cpp
biome.cpp
- clientserver.cpp
staticobject.cpp
serverlist.cpp
pathfinder.cpp
convert_json.cpp
- ${SCRIPT_SRCS}
+ ${common_SCRIPT_SRCS}
${UTIL_SRCS}
)
game.cpp
main.cpp
guiEngine.cpp
- guiLuaApi.cpp
guiFileSelectMenu.cpp
convert_json.cpp
+ ${minetest_SCRIPT_SRCS}
)
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}
#ifndef ACTIVEOBJECT_HEADER
#define ACTIVEOBJECT_HEADER
-#include "irrlichttypes_bloated.h"
+#include "irr_aabb3d.h"
#include <string>
#define ACTIVEOBJECT_TYPE_INVALID 0
#include <sstream>
#include <set>
#include "strfnd.h"
+#include "util/string.h"
#include "log.h"
#include "filesys.h"
#include "chat.h"
#include "debug.h"
-#include <cassert>
+#include "strfnd.h"
#include <cctype>
#include <sstream>
#include "util/string.h"
#ifndef CHAT_HEADER
#define CHAT_HEADER
-#include "irrlichttypes_bloated.h"
+#include "irrlichttypes.h"
#include <string>
#include <vector>
#include <list>
#include "jmutexautolock.h"
#include "main.h"
#include <sstream>
+#include "filesys.h"
#include "porting.h"
#include "mapsector.h"
#include "mapblock_mesh.h"
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);
#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"
};
};
+/*
+ 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:
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);
+++ /dev/null
-/*
-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;
-}
-
#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:
[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:
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.
// 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
#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<<")"
*/
#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
#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
#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"
LuaEntitySAO::~LuaEntitySAO()
{
if(m_registered){
- ENV_TO_SA(m_env)->luaentity_Remove(m_id);
+ m_env->getScriptIface()->luaentity_Remove(m_id);
}
}
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);
}
}
}
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)
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);
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;
// 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)
#include "inventory.h"
#include "util/serialize.h"
#include "strfnd.h"
+#include "exceptions.h"
// Check if input matches recipe
// Takes recipe groups into account
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)
{
#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)
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);
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;
#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
#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.
#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:
private:
};
-extern Debugbuf debugbuf;
extern std::ostream dstream;
extern std::ostream dstream_no_stderr;
extern Nullstream dummyout;
#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:
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
*/
#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);
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");
*/
+#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"
#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"
#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) {
}
+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;
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));
}
#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
{ 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;
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;
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);
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
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"
#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
#endif
#include "daynightratio.h"
#include "map.h"
+#include "emerge.h"
#include "util/serialize.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
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");
ServerEnvironment
*/
-ServerEnvironment::ServerEnvironment(ServerMap *map, ScriptApi *scriptIface,
+ServerEnvironment::ServerEnvironment(ServerMap *map,
+ GameScripting *scriptIface,
IGameDef *gamedef, IBackgroundBlockEmerger *emerger):
m_map(map),
m_script(scriptIface),
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;
}
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;
}
/*
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
#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"
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
{
Player * getNearestConnectedPlayer(v3f pos);
std::list<Player*> getPlayers();
std::list<Player*> getPlayers(bool ignore_disconnected);
- void printPlayers(std::ostream &o);
u32 getDayNightRatio();
private:
};
-class IBackgroundBlockEmerger
-{
-public:
- virtual void queueBlockEmerge(v3s16 blockpos, bool allow_generate)=0;
-};
-
/*
The server-side environment.
class ServerEnvironment : public Environment
{
public:
- ServerEnvironment(ServerMap *map, ScriptApi *iface, IGameDef *gamedef,
+ ServerEnvironment(ServerMap *map, GameScripting *scriptIface,
+ IGameDef *gamedef,
IBackgroundBlockEmerger *emerger);
~ServerEnvironment();
ServerMap & getServerMap();
//TODO find way to remove this fct!
- ScriptApi* getScriptIface()
+ GameScripting* getScriptIface()
{ return m_script; }
IGameDef *getGameDef()
// 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;
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;
{}
};
+// Only used on Windows (SEH)
+class FatalSystemException : public BaseException
+{
+public:
+ FatalSystemException(const char *s):
+ BaseException(s)
+ {}
+};
+
/*
Some "old-style" interrupts:
*/
#include <iostream>
#include <fstream>
#include <sstream>
+#include <stdlib.h>
bool FileCache::loadByPath(const std::string &path, std::ostream &os)
{
*/
#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"
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
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);
}
*/
{
TimeTaker timer("endScene");
- endSceneX(driver);
+ driver->endScene();
endscenetime = timer.stop(true);
}
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
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"
#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)
{
/******************************************************************************/
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");
}
/******************************************************************************/
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),
// 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
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;
}
/******************************************************************************/
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));
}
/******************************************************************************/
//TODO: clean up m_menu here
- lua_close(m_engineluastack);
+ infostream<<"GUIEngine: Deinitializing scripting"<<std::endl;
+ delete m_script;
m_irr_toplefttext->setText(L"");
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;
#include "irrlichttypes.h"
#include "modalMenu.h"
#include "clouds.h"
-#include "guiLuaApi.h"
#include "guiFormSpecMenu.h"
#include "sound.h"
/* forward declarations */
/******************************************************************************/
class GUIEngine;
+class MainMenuScripting;
struct MainMenuData;
struct SimpleSoundSpec;
{
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
/** 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
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 */
/** 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;
/** 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);
+
+
};
#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"
}
-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
*/
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
+++ /dev/null
-/*
-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;
-}
+++ /dev/null
-/*
-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
#include <IGUIStaticText.h>
#include <IGUIFont.h>
#include "main.h"
+#include "settings.h"
#include "gettext.h"
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,
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);
+ }
+}
+
#define HUD_HEADER
#include "irrlichttypes_extrabloated.h"
+#include <string>
#define HUD_DIR_LEFT_RIGHT 0
#define HUD_DIR_RIGHT_LEFT 1
#define HUD_HOTBAR_ITEMCOUNT_DEFAULT 8
#define HUD_HOTBAR_ITEMCOUNT_MAX 23
-class Player;
-
enum HudElementType {
HUD_ELEM_IMAGE = 0,
HUD_ELEM_TEXT = 1,
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:
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
#define INVENTORY_HEADER
#include <iostream>
-#include <sstream>
#include <string>
#include <vector>
-#include "irrlichttypes_bloated.h"
+#include "irrlichttypes.h"
#include "debug.h"
#include "itemdef.h"
#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"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
+#define PLAYER_TO_SA(p) p->getEnv()->getScriptIface()
+
/*
InventoryLocation
*/
#include "irr_v3d.h"
#include "irr_aabb3d.h"
-#include <irrMap.h>
-#include <irrList.h>
-#include <irrArray.h>
#include <SColor.h>
#endif
#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
#ifndef ITEMGROUP_HEADER
#define ITEMGROUP_HEADER
-#include "irrlichttypes_extrabloated.h"
#include <string>
#include <map>
#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
*/
Settings main_settings;
Settings *g_settings = &main_settings;
+std::string g_settings_path;
// Global profiler
Profiler main_profiler;
*/
// Path of configuration file in use
- std::string configpath = "";
+ g_settings_path = "";
if(cmd_args.exists("config"))
{
<<cmd_args.get("config")<<"\""<<std::endl;
return 1;
}
- configpath = cmd_args.get("config");
+ g_settings_path = cmd_args.get("config");
}
else
{
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
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
}
+ if(menudata.errormessage != ""){
+ error_message = narrow_to_wide(menudata.errormessage);
+ continue;
+ }
+
//update worldspecs (necessary as new world may have been created)
worldspecs = getAvailableWorlds();
// 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;
}
current_address,
current_port,
error_message,
- configpath,
chat_backend,
gamespec,
simple_singleplayer_mode
#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
{
#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;
#include "filesys.h"
#include "voxel.h"
#include "porting.h"
+#include "serialization.h"
#include "nodemetadata.h"
#include "settings.h"
#include "log.h"
#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<<")"
#ifndef MAP_HEADER
#define MAP_HEADER
-#include <jmutex.h>
-#include <jmutexautolock.h>
-#include <jthread.h>
#include <iostream>
#include <sstream>
#include <set>
#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"
class IGameDef;
class IRollbackReportSink;
class EmergeManager;
+class ServerEnvironment;
struct BlockMakeData;
+struct MapgenParams;
/*
#include <sstream>
#include "map.h"
-// For g_settings
-#include "main.h"
#include "light.h"
#include "nodedef.h"
#include "nodemetadata.h"
#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
#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"
class NodeMetadataList;
class IGameDef;
class MapBlockMesh;
+class VoxelManipulator;
#define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff
#ifndef SERVER // Only on client
MapBlockMesh *mesh;
- //JMutex mesh_mutex;
#endif
NodeMetadataList m_node_metadata;
#include "treegen.h"
#include "mapgen_v6.h"
#include "mapgen_v7.h"
+#include "serialization.h"
#include "util/serialize.h"
#include "filesys.h"
#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"
#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
#include "irr_v3d.h"
#include "irr_aabb3d.h"
#include "light.h"
+#include <string>
#include <vector>
class INodeDefManager;
*/
#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),
#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>
*/
#include "mesh.h"
+#include "debug.h"
#include "log.h"
-#include <cassert>
#include <iostream>
#include <IAnimatedMesh.h>
#include <SAnimatedMesh.h>
#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"
// 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;
};
*/
#include "nameidmapping.h"
+#include "exceptions.h"
#include "util/serialize.h"
void NameIdMapping::serialize(std::ostream &os) const
#ifndef NODEMETADATA_HEADER
#define NODEMETADATA_HEADER
-#include "irrlichttypes_bloated.h"
+#include "irr_v3d.h"
#include <string>
#include <iostream>
#include <map>
#include "nodetimer.h"
#include "log.h"
+#include "serialization.h"
#include "util/serialize.h"
#include "constants.h" // MAP_BLOCKSIZE
#ifndef NODETIMER_HEADER
#define NODETIMER_HEADER
-#include "irrlichttypes_bloated.h"
+#include "irr_v3d.h"
#include <iostream>
#include <map>
#include <math.h>
#include "noise.h"
#include <iostream>
+#include <string.h> // memset
#include "debug.h"
#include "util/numeric.h"
#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<<")"
/******************************************************************************/
#include "pathfinder.h"
+#include "environment.h"
+#include "map.h"
+#include "log.h"
#ifdef PATHFINDER_DEBUG
#include <iomanip>
/******************************************************************************/
#include <vector>
-#include "server.h"
#include "irr_v3d.h"
+/******************************************************************************/
+/* Forward declarations */
+/******************************************************************************/
+
+class ServerEnvironment;
+
/******************************************************************************/
/* Typedefs and macros */
/******************************************************************************/
#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"
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()
#include "debug.h"
#include "constants.h"
#include "gettime.h"
+#include "threads.h"
#ifdef _MSC_VER
#define SWPRINTF_CHARSTRING L"%S"
#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
#include "nodedef.h"
#include "util/serialize.h"
#include "util/string.h"
-#include "strfnd.h"
#include "util/numeric.h"
#include "inventorymanager.h" // deserializing InventoryLocations
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)
-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)
#include "server.h"
#include "log.h"
#include "tool.h"
-#include "server.h"
+#include "serverobject.h"
#include "mapgen.h"
struct EnumString es_TileAnimationType[] =
}
/******************************************************************************/
-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){
}
/******************************************************************************/
-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;
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);
*/
#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)
{
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);
+ }
+ }
+}
+
#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_ */
}
};
-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:
-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
${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)
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()
{
}
}
-void ScriptApiBase::scriptError(const char *fmt, ...)
+void ScriptApiBase::scriptError(const char *fmt, ...)
{
va_list argp;
va_start(argp, 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)
#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;
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_ */
*/
#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
*/
#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)
{
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)
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)
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)
--- /dev/null
+/*
+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_ */
*/
#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"
*/
#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)
--- /dev/null
+/*
+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));
+}
--- /dev/null
+/*
+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_ */
*/
#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[] =
*/
#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,
*/
#include "cpp_api/s_player.h"
+#include "cpp_api/s_internal.h"
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)
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)
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;
}
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)
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,
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,
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() {
}
#ifndef S_PLAYER_H_
#define S_PLAYER_H_
+#include <map>
+
#include "cpp_api/s_base.h"
--- /dev/null
+/*
+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);
+}
+
--- /dev/null
+/*
+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_ */
+++ /dev/null
-/*
-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;
+++ /dev/null
-/*
-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_ */
-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)
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);
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},
-};
#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_ */
#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[] =
{
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;
#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);
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_ */
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_State* L = scriptIface->getStack();
+ lua_State *L = scriptIface->getStack();
assert(lua_checkstack(L, 20));
StackUnroller stack_unroller(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);
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;
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;
}
{
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
}
// 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;
}
{
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
}
// 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;
}
if(objectid == 0)
return 0;
// Return ObjectRef
- get_scriptapi(L)->objectrefGetOrCreate(obj);
+ getScriptApiBase(L)->objectrefGetOrCreate(obj);
return 1;
}
return 1;
}
// Put player on stack
- get_scriptapi(L)->objectrefGetOrCreate(sao);
+ getScriptApiBase(L)->objectrefGetOrCreate(sao);
return 1;
}
// 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));
}
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)
}
-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);
+}
#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}
// 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);
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
--- /dev/null
+/*
+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_ */
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
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,
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
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);
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);
}
}
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;
}
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);
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));
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));
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);
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;
#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;
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_ */
*/
#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)
{
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
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);
{0,0}
};
-ModApiItemMod::ModApiItemMod() {
-}
-
/*
ItemDefinition
*/
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;
// Get the writable item definition manager from the server
IWritableItemDefManager *idef =
- STACK_TO_SERVER(L)->getWritableItemDefManager();
+ getServer(L)->getWritableItemDefManager();
idef->registerAlias(name, convert_to);
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);
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;
#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;
};
-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);
};
--- /dev/null
+/*
+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);
+}
--- /dev/null
+/*
+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_ */
--- /dev/null
+/*
+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);
+}
--- /dev/null
+/*
+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_ */
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"
+
/*
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());
}
}
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);
luamethod(NodeMetaRef, from_table),
{0,0}
};
-
-REGISTER_LUA_REF(NodeMetaRef);
#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;
static void Register(lua_State *L);
};
-#endif //L_NODEMETA_H_
+#endif /* L_NODEMETA_H_ */
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"
luamethod(NodeTimerRef, get_elapsed),
{0,0}
};
-
-REGISTER_LUA_REF(NodeTimerRef);
#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;
*/
#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
luamethod(LuaPseudoRandom, next),
{0,0}
};
-
-REGISTER_LUA_REF(LuaPseudoRandom);
-REGISTER_LUA_REF(LuaPerlinNoiseMap);
-REGISTER_LUA_REF(LuaPerlinNoise);
#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;
};
/*
- PerlinNoiseMap
- */
-class LuaPerlinNoiseMap
-{
+ LuaPerlinNoiseMap
+*/
+class LuaPerlinNoiseMap : public ModApiBase {
private:
Noise *noise;
static const char className[];
/*
LuaPseudoRandom
*/
-
-
-class LuaPseudoRandom
-{
+class LuaPseudoRandom : public ModApiBase {
private:
PseudoRandom m_pseudo;
static void Register(lua_State *L);
};
-NoiseParams *read_noiseparams(lua_State *L, int index);
-
#endif /* L_NOISE_H_ */
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"
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)
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;
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;
}
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;
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);
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;
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);
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);
luamethod(ObjectRef, hud_set_hotbar_itemcount),
{0,0}
};
-
-REGISTER_LUA_REF(ObjectRef)
#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;
ObjectRef
*/
-class ObjectRef
-{
+class ObjectRef : public ModApiBase {
private:
ServerActiveObject *m_object;
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)
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);
+}
+
#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_ */
--- /dev/null
+/*
+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);
+}
--- /dev/null
+/*
+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_ */
--- /dev/null
+/*
+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);
+}
--- /dev/null
+/*
+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_ */
--- /dev/null
+/*
+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);
+}
+
--- /dev/null
+/*
+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_ */
*/
-#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)
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;
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;
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;
{
NO_MAP_LOCK_REQUIRED;
- Environment *env = get_scriptapi(L)->getEnv();
+ Environment *env = getEnv(L);
if (!env)
return 0;
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);
}
luamethod(LuaVoxelManip, set_lighting),
{0,0}
};
-
-REGISTER_LUA_REF(LuaVoxelManip);
#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;
static void Register(lua_State *L);
};
-#endif // L_VMANIP_H_
+#endif /* L_VMANIP_H_ */
+++ /dev/null
-/*
-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;
+++ /dev/null
-/*
-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_ */
--- /dev/null
+/*
+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);
+}
--- /dev/null
+/*
+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_ */
--- /dev/null
+/*
+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);
+}
--- /dev/null
+/*
+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_ */
#include <queue>
#include <algorithm>
#include "clientserver.h"
+#include "ban.h"
+#include "environment.h"
#include "map.h"
#include "jmutexautolock.h"
#include "main.h"
#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"
#include "util/mathconstants.h"
#include "rollback.h"
#include "util/serialize.h"
+#include "util/thread.h"
#include "defaultsettings.h"
class ClientNotFoundException : public BaseException
{}
};
+class ServerThread : public SimpleThread
+{
+ Server *m_server;
+
+public:
+
+ ServerThread(Server *server):
+ SimpleThread(),
+ m_server(server)
+ {
+ }
+
+ void * Thread();
+};
+
void * ServerThread::Thread()
{
ThreadStarted();
}
}
-/*
- 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),
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),
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
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);
infostream<<"Server: Initializing Lua"<<std::endl;
- m_script = new ScriptApi(this);
+ m_script = new GameScripting(this);
// Load and run builtin.lua
// 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();
Stop threads
*/
stop();
+ delete m_thread;
//shutdown all emerge threads first!
delete m_emerge;
// 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;
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
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;
//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);
}
}
}
{
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 =
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);
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;
}
// 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
}
}
+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;
}
}
-//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);
}
}
+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);
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);
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);
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)
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
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){
#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
};
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
};
class Server : public con::PeerHandler, public MapEventReceiver,
- public InventoryManager, public IGameDef,
- public IBackgroundBlockEmerger
+ public InventoryManager, public IGameDef
{
public:
/*
Server(
const std::string &path_world,
- const std::string &path_config,
const SubgameSpec &gamespec,
bool simple_singleplayer_mode
);
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()
{
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)
{
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; }
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);
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.
// 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
u16 m_clients_number; //for announcing masterserver
// Ban checking
- BanManager m_banmanager;
+ BanManager *m_banmanager;
// Rollback manager (behind m_env_mutex)
IRollbackManager *m_rollback;
// Scripting
// Envlock and conlock should be locked when using Lua
- ScriptApi *m_script;
+ GameScripting *m_script;
// Item definition manager
IWritableItemDefManager *m_itemdef;
JMutex m_step_dtime_mutex;
// The server mainly operates in this thread
- ServerThread m_thread;
+ ServerThread *m_thread;
/*
Time related stuff
#define SETTINGS_HEADER
#include "irrlichttypes_bloated.h"
+#include "exceptions.h"
#include <string>
-#include <jthread.h>
#include <jmutex.h>
#include <jmutexautolock.h>
#include "strfnd.h"
#include <string.h>
#include <errno.h>
#include <sstream>
+#include <iomanip>
#include "util/string.h"
#include "util/numeric.h"
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)
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 << "...";
#include <string>
-std::string trim(const std::string &str);
-
class Strfnd{
std::string tek;
unsigned int p;
}
};
-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
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);
#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()
*/
#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"
#include "irr_v3d.h"
#include <stack>
+#include "util/pointer.h"
#include "util/numeric.h"
#include "util/mathconstants.h"
#include "map.h"
class ManualMapVoxelManipulator;
class INodeDefManager;
+class ServerEnvironment;
namespace treegen {
#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
#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
#include "pointedthing.h"
#include "serialize.h"
+#include "../exceptions.h"
#include <sstream>
PointedThing::PointedThing():
*/
#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)
{
#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)
{
*/
// 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);
*/
#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
#define UTIL_STRING_HEADER
#include "../irrlichttypes.h"
-#include "../strfnd.h" // For trim()
-#include "pointer.h"
+#include <stdlib.h>
#include <string>
#include <cstring>
#include <vector>
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())
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)
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));
#include "gettime.h"
#include "nodedef.h"
#include "util/timetaker.h"
+#include <string.h> // memcpy, memset
/*
Debug stuff
#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;