Omnicleanup: header cleanup, add ModApiUtil shared between game and mainmenu

This commit is contained in:
Kahrl 2013-08-11 04:09:45 +02:00
parent 6228d634fb
commit 4e1f50035e
153 changed files with 3725 additions and 3625 deletions

@ -1,3 +1,5 @@
print = engine.debug
math.randomseed(os.time())
os.setlocale("C", "numeric") os.setlocale("C", "numeric")
local scriptpath = engine.get_scriptdir() local scriptpath = engine.get_scriptdir()
@ -9,6 +11,7 @@ mt_color_dark_green = "#003300"
--for all other colors ask sfan5 to complete his worK! --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 .. "filterlist.lua")
dofile(scriptpath .. DIR_DELIM .. "modmgr.lua") dofile(scriptpath .. DIR_DELIM .. "modmgr.lua")
dofile(scriptpath .. DIR_DELIM .. "modstore.lua") dofile(scriptpath .. DIR_DELIM .. "modstore.lua")

@ -1167,6 +1167,7 @@ minetest.register_authentication_handler(handler)
Setting-related: Setting-related:
minetest.setting_set(name, value) minetest.setting_set(name, value)
minetest.setting_get(name) -> string or nil minetest.setting_get(name) -> string or nil
minetest.setting_setbool(name, value)
minetest.setting_getbool(name) -> boolean value or nil minetest.setting_getbool(name) -> boolean value or nil
minetest.setting_get_pos(name) -> position or nil minetest.setting_get_pos(name) -> position or nil
minetest.setting_save() -> nil, save all settings to config file minetest.setting_save() -> nil, save all settings to config file

@ -127,11 +127,19 @@ engine.get_favorites(location) -> list of favorites
} }
engine.delete_favorite(id, location) -> success 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: Settings:
engine.setting_set(name, value) engine.setting_set(name, value)
engine.setting_get(name) -> string or nil engine.setting_get(name) -> string or nil
engine.setting_setbool(name, value) engine.setting_setbool(name, value)
engine.setting_getbool(name) -> bool or nil engine.setting_getbool(name) -> bool or nil
engine.setting_save() -> nil, save all settings to config file
Worlds: Worlds:
engine.get_worlds() -> list of worlds engine.get_worlds() -> list of worlds

@ -383,6 +383,7 @@
# to IPv6 clients, depending on system configuration. # to IPv6 clients, depending on system configuration.
#ipv6_server = false #ipv6_server = false
#main_menu_script =
#main_menu_game_mgr = 0 #main_menu_game_mgr = 0
#main_menu_mod_mgr = 1 #main_menu_mod_mgr = 1
#modstore_download_url = https://forum.minetest.net/media/ #modstore_download_url = https://forum.minetest.net/media/

@ -267,12 +267,11 @@ set(common_SRCS
base64.cpp base64.cpp
ban.cpp ban.cpp
biome.cpp biome.cpp
clientserver.cpp
staticobject.cpp staticobject.cpp
serverlist.cpp serverlist.cpp
pathfinder.cpp pathfinder.cpp
convert_json.cpp convert_json.cpp
${SCRIPT_SRCS} ${common_SCRIPT_SRCS}
${UTIL_SRCS} ${UTIL_SRCS}
) )
@ -329,9 +328,9 @@ set(minetest_SRCS
game.cpp game.cpp
main.cpp main.cpp
guiEngine.cpp guiEngine.cpp
guiLuaApi.cpp
guiFileSelectMenu.cpp guiFileSelectMenu.cpp
convert_json.cpp convert_json.cpp
${minetest_SCRIPT_SRCS}
) )
if(USE_FREETYPE) if(USE_FREETYPE)
@ -341,11 +340,14 @@ if(USE_FREETYPE)
) )
endif(USE_FREETYPE) endif(USE_FREETYPE)
list(SORT minetest_SRCS)
# Server sources # Server sources
set(minetestserver_SRCS set(minetestserver_SRCS
${common_SRCS} ${common_SRCS}
main.cpp main.cpp
) )
list(SORT minetestserver_SRCS)
include_directories( include_directories(
${PROJECT_BINARY_DIR} ${PROJECT_BINARY_DIR}

@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef ACTIVEOBJECT_HEADER #ifndef ACTIVEOBJECT_HEADER
#define ACTIVEOBJECT_HEADER #define ACTIVEOBJECT_HEADER
#include "irrlichttypes_bloated.h" #include "irr_aabb3d.h"
#include <string> #include <string>
#define ACTIVEOBJECT_TYPE_INVALID 0 #define ACTIVEOBJECT_TYPE_INVALID 0

@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <sstream> #include <sstream>
#include <set> #include <set>
#include "strfnd.h" #include "strfnd.h"
#include "util/string.h"
#include "log.h" #include "log.h"
#include "filesys.h" #include "filesys.h"

@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "chat.h" #include "chat.h"
#include "debug.h" #include "debug.h"
#include <cassert> #include "strfnd.h"
#include <cctype> #include <cctype>
#include <sstream> #include <sstream>
#include "util/string.h" #include "util/string.h"

@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CHAT_HEADER #ifndef CHAT_HEADER
#define CHAT_HEADER #define CHAT_HEADER
#include "irrlichttypes_bloated.h" #include "irrlichttypes.h"
#include <string> #include <string>
#include <vector> #include <vector>
#include <list> #include <list>

@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "jmutexautolock.h" #include "jmutexautolock.h"
#include "main.h" #include "main.h"
#include <sstream> #include <sstream>
#include "filesys.h"
#include "porting.h" #include "porting.h"
#include "mapsector.h" #include "mapsector.h"
#include "mapblock_mesh.h" #include "mapblock_mesh.h"
@ -1356,8 +1357,6 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
std::istringstream is(datastring, std::ios_base::binary); std::istringstream is(datastring, std::ios_base::binary);
//t3.stop(); //t3.stop();
//m_env.printPlayers(infostream);
//TimeTaker t4("player get", m_device); //TimeTaker t4("player get", m_device);
Player *player = m_env.getLocalPlayer(); Player *player = m_env.getLocalPlayer();
assert(player != NULL); assert(player != NULL);

@ -25,12 +25,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irrlichttypes_extrabloated.h" #include "irrlichttypes_extrabloated.h"
#include "jmutex.h" #include "jmutex.h"
#include <ostream> #include <ostream>
#include <map>
#include <set> #include <set>
#include <vector> #include <vector>
#include "clientobject.h" #include "clientobject.h"
#include "gamedef.h" #include "gamedef.h"
#include "inventorymanager.h" #include "inventorymanager.h"
#include "filesys.h"
#include "filecache.h" #include "filecache.h"
#include "localplayer.h" #include "localplayer.h"
#include "server.h" #include "server.h"
@ -246,6 +246,57 @@ struct ClientEvent
}; };
}; };
/*
Packet counter
*/
class PacketCounter
{
public:
PacketCounter()
{
}
void add(u16 command)
{
std::map<u16, u16>::iterator n = m_packets.find(command);
if(n == m_packets.end())
{
m_packets[command] = 1;
}
else
{
n->second++;
}
}
void clear()
{
for(std::map<u16, u16>::iterator
i = m_packets.begin();
i != m_packets.end(); ++i)
{
i->second = 0;
}
}
void print(std::ostream &o)
{
for(std::map<u16, u16>::iterator
i = m_packets.begin();
i != m_packets.end(); ++i)
{
o<<"cmd "<<i->first
<<" count "<<i->second
<<std::endl;
}
}
private:
// command, count
std::map<u16, u16> m_packets;
};
class Client : public con::PeerHandler, public InventoryManager, public IGameDef class Client : public con::PeerHandler, public InventoryManager, public IGameDef
{ {
public: public:
@ -419,8 +470,6 @@ private:
void Receive(); void Receive();
void sendPlayerPos(); 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 // Send the item number 'item' as player item to the server
void sendPlayerItem(u16 item); void sendPlayerItem(u16 item);

@ -20,10 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CLIENTSERVER_HEADER #ifndef CLIENTSERVER_HEADER
#define 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: changes by PROTOCOL_VERSION:

@ -191,15 +191,14 @@ TODO: Should we have a receiver_peer_id also?
[6] u8 channel [6] u8 channel
sender_peer_id: sender_peer_id:
Unique to each peer. Unique to each peer.
value 0 is reserved for making new connections value 0 (PEER_ID_INEXISTENT) is reserved for making new connections
value 1 is reserved for server value 1 (PEER_ID_SERVER) is reserved for server
these constants are defined in constants.h
channel: channel:
The lower the number, the higher the priority is. The lower the number, the higher the priority is.
Only channels 0, 1 and 2 exist. Only channels 0, 1 and 2 exist.
*/ */
#define BASE_HEADER_SIZE 7 #define BASE_HEADER_SIZE 7
#define PEER_ID_INEXISTENT 0
#define PEER_ID_SERVER 1
#define CHANNEL_COUNT 3 #define CHANNEL_COUNT 3
/* /*
Packet types: Packet types:

@ -32,6 +32,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
Connection Connection
*/ */
#define PEER_ID_INEXISTENT 0
#define PEER_ID_SERVER 1
// Define for simulating the quirks of sending through internet. // Define for simulating the quirks of sending through internet.
// Causes the socket class to deliberately drop random packets. // Causes the socket class to deliberately drop random packets.
// This disables unit testing of socket and connection. // This disables unit testing of socket and connection.
@ -83,12 +86,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
// Size of player's main inventory // Size of player's main inventory
#define PLAYER_INVENTORY_SIZE (8*4) #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 // Maximum hit points of a player
#define PLAYER_MAX_HP 20 #define PLAYER_MAX_HP 20

@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "treegen.h" // For treegen::make_tree #include "treegen.h" // For treegen::make_tree
#include "main.h" // for g_settings #include "main.h" // for g_settings
#include "map.h" #include "map.h"
#include "cpp_api/scriptapi.h" #include "scripting_game.h"
#include "log.h" #include "log.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"

@ -18,8 +18,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "content_nodemeta.h" #include "content_nodemeta.h"
#include "nodemetadata.h"
#include "nodetimer.h"
#include "inventory.h" #include "inventory.h"
#include "log.h" #include "log.h"
#include "serialization.h"
#include "util/serialize.h" #include "util/serialize.h"
#include "util/string.h" #include "util/string.h"
#include "constants.h" // MAP_BLOCKSIZE #include "constants.h" // MAP_BLOCKSIZE

@ -20,8 +20,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef CONTENT_NODEMETA_HEADER #ifndef CONTENT_NODEMETA_HEADER
#define CONTENT_NODEMETA_HEADER #define CONTENT_NODEMETA_HEADER
#include "nodemetadata.h" #include <iostream>
#include "nodetimer.h"
class NodeMetadataList;
class NodeTimerList;
class IGameDef;
/* /*
Legacy nodemeta definitions Legacy nodemeta definitions

@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "tool.h" // For ToolCapabilities #include "tool.h" // For ToolCapabilities
#include "gamedef.h" #include "gamedef.h"
#include "player.h" #include "player.h"
#include "cpp_api/scriptapi.h" #include "scripting_game.h"
#include "genericobject.h" #include "genericobject.h"
#include "util/serialize.h" #include "util/serialize.h"
#include "util/mathconstants.h" #include "util/mathconstants.h"
@ -399,7 +399,7 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
LuaEntitySAO::~LuaEntitySAO() LuaEntitySAO::~LuaEntitySAO()
{ {
if(m_registered){ if(m_registered){
ENV_TO_SA(m_env)->luaentity_Remove(m_id); m_env->getScriptIface()->luaentity_Remove(m_id);
} }
} }
@ -408,15 +408,18 @@ void LuaEntitySAO::addedToEnvironment(u32 dtime_s)
ServerActiveObject::addedToEnvironment(dtime_s); ServerActiveObject::addedToEnvironment(dtime_s);
// Create entity from name // 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){ if(m_registered){
// Get properties // 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 // Initialize HP from properties
m_hp = m_prop.hp_max; m_hp = m_prop.hp_max;
// Activate entity, supplying serialized state // Activate entity, supplying serialized state
ENV_TO_SA(m_env)->luaentity_Activate(m_id, m_init_state.c_str(), dtime_s); m_env->getScriptIface()->
luaentity_Activate(m_id, m_init_state.c_str(), dtime_s);
} }
} }
@ -530,7 +533,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
} }
if(m_registered){ 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) if(send_recommended == false)
@ -640,7 +643,8 @@ std::string LuaEntitySAO::getStaticData()
os<<serializeString(m_init_name); os<<serializeString(m_init_name);
// state // state
if(m_registered){ 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); os<<serializeLongString(state);
} else { } else {
os<<serializeLongString(m_init_state); os<<serializeLongString(m_init_state);
@ -707,7 +711,7 @@ int LuaEntitySAO::punch(v3f dir,
m_removed = true; 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); time_from_last_punch, toolcap, dir);
return result.wear; return result.wear;
@ -720,7 +724,7 @@ void LuaEntitySAO::rightClick(ServerActiveObject *clicker)
// It's best that attachments cannot be clicked // It's best that attachments cannot be clicked
if(isAttached()) if(isAttached())
return; return;
ENV_TO_SA(m_env)->luaentity_Rightclick(m_id, clicker); m_env->getScriptIface()->luaentity_Rightclick(m_id, clicker);
} }
void LuaEntitySAO::setPos(v3f pos) void LuaEntitySAO::setPos(v3f pos)

@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "inventory.h" #include "inventory.h"
#include "util/serialize.h" #include "util/serialize.h"
#include "strfnd.h" #include "strfnd.h"
#include "exceptions.h"
// Check if input matches recipe // Check if input matches recipe
// Takes recipe groups into account // Takes recipe groups into account
@ -150,23 +151,6 @@ static bool craftGetBounds(const std::vector<std::string> &items, unsigned int w
return success; 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 // Removes 1 from each item stack
static void craftDecrementInput(CraftInput &input, IGameDef *gamedef) static void craftDecrementInput(CraftInput &input, IGameDef *gamedef)
{ {

@ -19,16 +19,34 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "debug.h" #include "debug.h"
#include "exceptions.h"
#include "threads.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <cstring> #include <cstring>
#include <map>
#include <jmutex.h>
#include <jmutexautolock.h>
/* /*
Debug output Debug output
*/ */
#define DEBUGSTREAM_COUNT 2
FILE *g_debugstreams[DEBUGSTREAM_COUNT] = {stderr, NULL}; 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) void debugstreams_init(bool disable_stderr, const char *filename)
{ {
if(disable_stderr) if(disable_stderr)
@ -53,6 +71,47 @@ void debugstreams_deinit()
fclose(g_debugstreams[1]); 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); Debugbuf debugbuf(false);
std::ostream dstream(&debugbuf); std::ostream dstream(&debugbuf);
Debugbuf debugbuf_no_stderr(true); Debugbuf debugbuf_no_stderr(true);
@ -83,6 +142,18 @@ void assert_fail(const char *assertion, const char *file,
DebugStack 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) DebugStack::DebugStack(threadid_t id)
{ {
threadid = id; threadid = id;

@ -20,18 +20,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef DEBUG_HEADER #ifndef DEBUG_HEADER
#define DEBUG_HEADER #define DEBUG_HEADER
#include <stdio.h>
#include <jmutex.h>
#include <jmutexautolock.h>
#include <iostream> #include <iostream>
#include "irrlichttypes.h" #include <exception>
#include <irrMap.h>
#include "threads.h"
#include "gettime.h" #include "gettime.h"
#include "exceptions.h"
#include <map>
#ifdef _WIN32 #if (defined(WIN32) || defined(_WIN32_WCE))
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#ifndef _WIN32_WINNT #ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 #define _WIN32_WINNT 0x0501
@ -40,7 +33,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifdef _MSC_VER #ifdef _MSC_VER
#include <eh.h> #include <eh.h>
#endif #endif
#define __NORETURN __declspec(noreturn)
#define __FUNCTION_NAME __FUNCTION__
#else #else
#define __NORETURN __attribute__ ((__noreturn__))
#define __FUNCTION_NAME __PRETTY_FUNCTION__
#endif #endif
// Whether to catch all std::exceptions. // Whether to catch all std::exceptions.
@ -58,65 +55,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define DTIME (getTimestamp()+": ") #define 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_init(bool disable_stderr, const char *filename);
extern void debugstreams_deinit(); 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 // This is used to redirect output to /dev/null
class Nullstream : public std::ostream { class Nullstream : public std::ostream {
public: public:
@ -127,7 +68,6 @@ public:
private: private:
}; };
extern Debugbuf debugbuf;
extern std::ostream dstream; extern std::ostream dstream;
extern std::ostream dstream_no_stderr; extern std::ostream dstream_no_stderr;
extern Nullstream dummyout; extern Nullstream dummyout;
@ -154,25 +94,11 @@ __NORETURN extern void assert_fail(
#define DEBUG_STACK_SIZE 50 #define DEBUG_STACK_SIZE 50
#define DEBUG_STACK_TEXT_SIZE 300 #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_init();
extern void debug_stacks_print_to(std::ostream &os); extern void debug_stacks_print_to(std::ostream &os);
extern void debug_stacks_print(); extern void debug_stacks_print();
struct DebugStack;
class DebugStacker class DebugStacker
{ {
public: public:
@ -193,57 +119,6 @@ private:
DEBUG_STACK_TEXT_SIZE, __VA_ARGS__);\ DEBUG_STACK_TEXT_SIZE, __VA_ARGS__);\
DebugStacker __debug_stacker(__buf); 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 These should be put into every thread
*/ */
@ -259,14 +134,6 @@ private:
#ifdef _WIN32 // Windows #ifdef _WIN32 // Windows
#ifdef _MSC_VER // MSVC #ifdef _MSC_VER // MSVC
void se_trans_func(unsigned int, EXCEPTION_POINTERS*); void se_trans_func(unsigned int, EXCEPTION_POINTERS*);
class FatalSystemException : public BaseException
{
public:
FatalSystemException(const char *s):
BaseException(s)
{}
};
#define BEGIN_DEBUG_EXCEPTION_HANDLER \ #define BEGIN_DEBUG_EXCEPTION_HANDLER \
BEGIN_PORTABLE_DEBUG_EXCEPTION_HANDLER\ BEGIN_PORTABLE_DEBUG_EXCEPTION_HANDLER\
_set_se_translator(se_trans_func); _set_se_translator(se_trans_func);

@ -273,6 +273,7 @@ void set_default_settings(Settings *settings)
settings->setDefault("enable_ipv6", "true"); settings->setDefault("enable_ipv6", "true");
settings->setDefault("ipv6_server", "false"); settings->setDefault("ipv6_server", "false");
settings->setDefault("main_menu_script","");
settings->setDefault("main_menu_mod_mgr","1"); settings->setDefault("main_menu_mod_mgr","1");
settings->setDefault("old_style_mod_selection","true"); settings->setDefault("old_style_mod_selection","true");
settings->setDefault("main_menu_game_mgr","0"); settings->setDefault("main_menu_game_mgr","0");

@ -19,12 +19,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "emerge.h"
#include "server.h" #include "server.h"
#include <iostream> #include <iostream>
#include <queue> #include <queue>
#include "clientserver.h"
#include "map.h" #include "map.h"
#include "jmutexautolock.h" #include "environment.h"
#include "util/container.h"
#include "util/thread.h"
#include "main.h" #include "main.h"
#include "constants.h" #include "constants.h"
#include "voxel.h" #include "voxel.h"
@ -32,12 +34,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapblock.h" #include "mapblock.h"
#include "serverobject.h" #include "serverobject.h"
#include "settings.h" #include "settings.h"
#include "cpp_api/scriptapi.h" #include "scripting_game.h"
#include "profiler.h" #include "profiler.h"
#include "log.h" #include "log.h"
#include "nodedef.h" #include "nodedef.h"
#include "biome.h" #include "biome.h"
#include "emerge.h"
#include "mapgen_v6.h" #include "mapgen_v6.h"
#include "mapgen_v7.h" #include "mapgen_v7.h"
#include "mapgen_indev.h" #include "mapgen_indev.h"
@ -45,6 +46,46 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapgen_math.h" #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 //////////////////////////////// /////////////////////////////// Emerge Manager ////////////////////////////////
EmergeManager::EmergeManager(IGameDef *gamedef) { EmergeManager::EmergeManager(IGameDef *gamedef) {
@ -183,6 +224,11 @@ Mapgen *EmergeManager::getCurrentMapgen() {
} }
void EmergeManager::triggerAllThreads() {
for (unsigned int i = 0; i != emergethread.size(); i++)
emergethread[i]->trigger();
}
bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate) { bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate) {
std::map<v3s16, BlockEmergeData *>::const_iterator iter; std::map<v3s16, BlockEmergeData *>::const_iterator iter;
BlockEmergeData *bedata; BlockEmergeData *bedata;
@ -466,7 +512,8 @@ void *EmergeThread::Thread() {
ign(&m_server->m_ignore_map_edit_events_area, ign(&m_server->m_ignore_map_edit_events_area,
VoxelArea(minp, maxp)); VoxelArea(minp, maxp));
{ // takes about 90ms with -O1 on an e3-1230v2 { // 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)); minp, maxp, emerge->getBlockSeed(minp));
} }

@ -21,8 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define EMERGE_HEADER #define EMERGE_HEADER
#include <map> #include <map>
#include <queue> #include "irr_v3d.h"
#include "util/thread.h" #include "util/container.h"
#include "map.h" // for ManualMapVoxelManipulator
#define MGPARAMS_SET_MGNAME 1 #define MGPARAMS_SET_MGNAME 1
#define MGPARAMS_SET_SEED 2 #define MGPARAMS_SET_SEED 2
@ -35,15 +36,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{ if (enable_mapgen_debug_info) \ { if (enable_mapgen_debug_info) \
infostream << "EmergeThread: " x << std::endl; } infostream << "EmergeThread: " x << std::endl; }
class EmergeThread;
class Mapgen; class Mapgen;
struct MapgenParams; struct MapgenParams;
struct MapgenFactory; struct MapgenFactory;
class Biome; class Biome;
class BiomeDefManager; class BiomeDefManager;
class EmergeThread; class Decoration;
class ManualMapVoxelManipulator; class Ore;
class INodeDefManager;
#include "server.h" class Settings;
struct BlockMakeData { struct BlockMakeData {
ManualMapVoxelManipulator *vmanip; ManualMapVoxelManipulator *vmanip;
@ -68,7 +70,14 @@ struct BlockEmergeData {
u8 flags; u8 flags;
}; };
class EmergeManager { class IBackgroundBlockEmerger
{
public:
virtual bool enqueueBlockEmerge(u16 peer_id, v3s16 p,
bool allow_generate) = 0;
};
class EmergeManager : public IBackgroundBlockEmerger {
public: public:
INodeDefManager *ndef; INodeDefManager *ndef;
@ -106,6 +115,7 @@ public:
Mapgen *createMapgen(std::string mgname, int mgid, Mapgen *createMapgen(std::string mgname, int mgid,
MapgenParams *mgparams); MapgenParams *mgparams);
MapgenParams *createMapgenParams(std::string mgname); MapgenParams *createMapgenParams(std::string mgname);
void triggerAllThreads();
bool enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate); bool enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate);
void registerMapgen(std::string name, MapgenFactory *mgfactory); void registerMapgen(std::string name, MapgenFactory *mgfactory);
@ -119,43 +129,4 @@ public:
u32 getBlockSeed(v3s16 p); 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 #endif

@ -17,9 +17,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include <set>
#include <list>
#include <map>
#include "environment.h" #include "environment.h"
#include "filesys.h" #include "filesys.h"
#include "porting.h" #include "porting.h"
@ -31,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h" #include "settings.h"
#include "log.h" #include "log.h"
#include "profiler.h" #include "profiler.h"
#include "cpp_api/scriptapi.h" #include "scripting_game.h"
#include "nodedef.h" #include "nodedef.h"
#include "nodemetadata.h" #include "nodemetadata.h"
#include "main.h" // For g_settings, g_profiler #include "main.h" // For g_settings, g_profiler
@ -43,6 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#endif #endif
#include "daynightratio.h" #include "daynightratio.h"
#include "map.h" #include "map.h"
#include "emerge.h"
#include "util/serialize.h" #include "util/serialize.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
@ -190,17 +188,6 @@ std::list<Player*> Environment::getPlayers(bool ignore_disconnected)
return newlist; 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() u32 Environment::getDayNightRatio()
{ {
bool smooth = g_settings->getBool("enable_shaders"); bool smooth = g_settings->getBool("enable_shaders");
@ -320,7 +307,8 @@ void ActiveBlockList::update(std::list<v3s16> &active_positions,
ServerEnvironment ServerEnvironment
*/ */
ServerEnvironment::ServerEnvironment(ServerMap *map, ScriptApi *scriptIface, ServerEnvironment::ServerEnvironment(ServerMap *map,
GameScripting *scriptIface,
IGameDef *gamedef, IBackgroundBlockEmerger *emerger): IGameDef *gamedef, IBackgroundBlockEmerger *emerger):
m_map(map), m_map(map),
m_script(scriptIface), m_script(scriptIface),
@ -1149,7 +1137,8 @@ void ServerEnvironment::step(float dtime)
MapBlock *block = m_map->getBlockNoCreateNoEx(p); MapBlock *block = m_map->getBlockNoCreateNoEx(p);
if(block==NULL){ if(block==NULL){
// Block needs to be fetched first // 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); m_active_blocks.m_list.erase(p);
continue; continue;
} }
@ -1505,7 +1494,9 @@ ActiveObjectMessage ServerEnvironment::getActiveObjectMessage()
if(m_active_object_messages.empty()) if(m_active_object_messages.empty())
return ActiveObjectMessage(0); return ActiveObjectMessage(0);
return m_active_object_messages.pop_front(); ActiveObjectMessage message = m_active_object_messages.front();
m_active_object_messages.pop_front();
return message;
} }
/* /*
@ -2574,13 +2565,14 @@ void ClientEnvironment::getActiveObjects(v3f origin, f32 max_d,
ClientEnvEvent ClientEnvironment::getClientEvent() ClientEnvEvent ClientEnvironment::getClientEvent()
{ {
ClientEnvEvent event;
if(m_client_event_queue.empty()) if(m_client_event_queue.empty())
{
ClientEnvEvent event;
event.type = CEE_NONE; 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 #endif // #ifndef SERVER

@ -32,11 +32,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <set> #include <set>
#include <list> #include <list>
#include "irrlichttypes_extrabloated.h" #include <map>
#include "player.h" #include "irr_v3d.h"
#include <ostream>
#include "activeobject.h" #include "activeobject.h"
#include "util/container.h"
#include "util/numeric.h" #include "util/numeric.h"
#include "mapnode.h" #include "mapnode.h"
#include "mapblock.h" #include "mapblock.h"
@ -44,13 +42,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class ServerEnvironment; class ServerEnvironment;
class ActiveBlockModifier; class ActiveBlockModifier;
class ServerActiveObject; class ServerActiveObject;
typedef struct lua_State lua_State;
class ITextureSource; class ITextureSource;
class IGameDef; class IGameDef;
class IBackgroundBlockEmerger;
class Map; class Map;
class ServerMap; class ServerMap;
class ClientMap; class ClientMap;
class ScriptApi; class GameScripting;
class Player;
class Environment class Environment
{ {
@ -77,7 +76,6 @@ public:
Player * getNearestConnectedPlayer(v3f pos); Player * getNearestConnectedPlayer(v3f pos);
std::list<Player*> getPlayers(); std::list<Player*> getPlayers();
std::list<Player*> getPlayers(bool ignore_disconnected); std::list<Player*> getPlayers(bool ignore_disconnected);
void printPlayers(std::ostream &o);
u32 getDayNightRatio(); u32 getDayNightRatio();
@ -176,12 +174,6 @@ public:
private: private:
}; };
class IBackgroundBlockEmerger
{
public:
virtual void queueBlockEmerge(v3s16 blockpos, bool allow_generate)=0;
};
/* /*
The server-side environment. The server-side environment.
@ -191,7 +183,8 @@ public:
class ServerEnvironment : public Environment class ServerEnvironment : public Environment
{ {
public: public:
ServerEnvironment(ServerMap *map, ScriptApi *iface, IGameDef *gamedef, ServerEnvironment(ServerMap *map, GameScripting *scriptIface,
IGameDef *gamedef,
IBackgroundBlockEmerger *emerger); IBackgroundBlockEmerger *emerger);
~ServerEnvironment(); ~ServerEnvironment();
@ -200,7 +193,7 @@ public:
ServerMap & getServerMap(); ServerMap & getServerMap();
//TODO find way to remove this fct! //TODO find way to remove this fct!
ScriptApi* getScriptIface() GameScripting* getScriptIface()
{ return m_script; } { return m_script; }
IGameDef *getGameDef() IGameDef *getGameDef()
@ -354,15 +347,15 @@ private:
// The map // The map
ServerMap *m_map; ServerMap *m_map;
// Lua state // Lua state
ScriptApi* m_script; GameScripting* m_script;
// Game definition // Game definition
IGameDef *m_gamedef; IGameDef *m_gamedef;
// Background block emerger (the server, in practice) // Background block emerger (the EmergeManager, in practice)
IBackgroundBlockEmerger *m_emerger; IBackgroundBlockEmerger *m_emerger;
// Active object list // Active object list
std::map<u16, ServerActiveObject*> m_active_objects; std::map<u16, ServerActiveObject*> m_active_objects;
// Outgoing network message buffer for active objects // Outgoing network message buffer for active objects
Queue<ActiveObjectMessage> m_active_object_messages; std::list<ActiveObjectMessage> m_active_object_messages;
// Some timers // Some timers
float m_random_spawn_timer; // used for experimental code float m_random_spawn_timer; // used for experimental code
float m_send_recommended_timer; float m_send_recommended_timer;
@ -503,7 +496,7 @@ private:
IrrlichtDevice *m_irr; IrrlichtDevice *m_irr;
std::map<u16, ClientActiveObject*> m_active_objects; std::map<u16, ClientActiveObject*> m_active_objects;
std::list<ClientSimpleObject*> m_simple_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_active_object_light_update_interval;
IntervalLimiter m_lava_hurt_interval; IntervalLimiter m_lava_hurt_interval;
IntervalLimiter m_drowning_interval; IntervalLimiter m_drowning_interval;

@ -140,6 +140,15 @@ public:
{} {}
}; };
// Only used on Windows (SEH)
class FatalSystemException : public BaseException
{
public:
FatalSystemException(const char *s):
BaseException(s)
{}
};
/* /*
Some "old-style" interrupts: Some "old-style" interrupts:
*/ */

@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include <stdlib.h>
bool FileCache::loadByPath(const std::string &path, std::ostream &os) bool FileCache::loadByPath(const std::string &path, std::ostream &os)
{ {

@ -18,12 +18,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "filesys.h" #include "filesys.h"
#include "strfnd.h" #include "util/string.h"
#include <iostream> #include <iostream>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <sstream>
#include <fstream> #include <fstream>
#include "log.h" #include "log.h"

@ -915,7 +915,6 @@ void the_game(
std::string address, // If "", local server is used std::string address, // If "", local server is used
u16 port, u16 port,
std::wstring &error_message, std::wstring &error_message,
std::string configpath,
ChatBackend &chat_backend, ChatBackend &chat_backend,
const SubgameSpec &gamespec, // Used for local game, const SubgameSpec &gamespec, // Used for local game,
bool simple_singleplayer_mode bool simple_singleplayer_mode
@ -1001,7 +1000,7 @@ void the_game(
draw_load_screen(text, device, font,0,25); draw_load_screen(text, device, font,0,25);
delete[] text; delete[] text;
infostream<<"Creating server"<<std::endl; infostream<<"Creating server"<<std::endl;
server = new Server(map_dir, configpath, gamespec, server = new Server(map_dir, gamespec,
simple_singleplayer_mode); simple_singleplayer_mode);
server->start(port); server->start(port);
} }
@ -3340,7 +3339,7 @@ void the_game(
*/ */
{ {
TimeTaker timer("endScene"); TimeTaker timer("endScene");
endSceneX(driver); driver->endScene();
endscenetime = timer.stop(true); endscenetime = timer.stop(true);
} }

@ -137,7 +137,6 @@ void the_game(
std::string address, // If "", local server is used std::string address, // If "", local server is used
u16 port, u16 port,
std::wstring &error_message, std::wstring &error_message,
std::string configpath,
ChatBackend &chat_backend, ChatBackend &chat_backend,
const SubgameSpec &gamespec, // Used for local game const SubgameSpec &gamespec, // Used for local game
bool simple_singleplayer_mode bool simple_singleplayer_mode

@ -17,14 +17,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
extern "C" { #include "guiEngine.h"
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
#include "irrlicht.h"
#include "scripting_mainmenu.h"
#include "config.h"
#include "porting.h" #include "porting.h"
#include "filesys.h" #include "filesys.h"
#include "main.h" #include "main.h"
@ -33,30 +29,13 @@ extern "C" {
#include "sound.h" #include "sound.h"
#include "sound_openal.h" #include "sound_openal.h"
#include "guiEngine.h" #include <IGUIStaticText.h>
#include <ICameraSceneNode.h>
#if USE_CURL #if USE_CURL
#include <curl/curl.h> #include <curl/curl.h>
#endif #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) TextDestGuiEngine::TextDestGuiEngine(GUIEngine* engine)
{ {
@ -66,13 +45,33 @@ TextDestGuiEngine::TextDestGuiEngine(GUIEngine* engine)
/******************************************************************************/ /******************************************************************************/
void TextDestGuiEngine::gotText(std::map<std::string, std::string> fields) 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) void TextDestGuiEngine::gotText(std::wstring text)
{ {
m_engine->handleEvent(wide_to_narrow(text)); m_engine->getScriptIface()->handleMainMenuEvent(wide_to_narrow(text));
}
/******************************************************************************/
void MenuMusicFetcher::fetchSounds(const std::string &name,
std::set<std::string> &dst_paths,
std::set<std::string> &dst_datas)
{
if(m_fetched.count(name))
return;
m_fetched.insert(name);
std::string base;
base = porting::path_share + DIR_DELIM + "sounds";
dst_paths.insert(base + DIR_DELIM + name + ".ogg");
int i;
for(i=0; i<10; i++)
dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
base = porting::path_user + DIR_DELIM + "sounds";
dst_paths.insert(base + DIR_DELIM + name + ".ogg");
for(i=0; i<10; i++)
dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
} }
/******************************************************************************/ /******************************************************************************/
@ -91,8 +90,7 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
m_buttonhandler(0), m_buttonhandler(0),
m_menu(0), m_menu(0),
m_startgame(false), m_startgame(false),
m_engineluastack(0), m_script(0),
m_luaerrorhandler(-1),
m_scriptdir(""), m_scriptdir(""),
m_irr_toplefttext(0), m_irr_toplefttext(0),
m_clouds_enabled(true), m_clouds_enabled(true),
@ -105,26 +103,6 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
// is deleted by guiformspec! // is deleted by guiformspec!
m_buttonhandler = new TextDestGuiEngine(this); 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 //create soundmanager
MenuMusicFetcher soundfetcher; MenuMusicFetcher soundfetcher;
#if USE_SOUND #if USE_SOUND
@ -160,68 +138,76 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
m_menu->setTextDest(m_buttonhandler); m_menu->setTextDest(m_buttonhandler);
m_menu->useGettext(true); m_menu->useGettext(true);
std::string builtin_helpers // Initialize scripting
= porting::path_share + DIR_DELIM + "builtin"
+ DIR_DELIM + "misc_helpers.lua";
if (!runScript(builtin_helpers)) { infostream<<"GUIEngine: Initializing Lua"<<std::endl;
errorstream
<< "GUIEngine::GUIEngine unable to load builtin helper script"
<< std::endl;
return;
}
std::string menuscript = ""; m_script = new MainMenuScripting(this);
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";
lua_pushcfunction(m_engineluastack, menuscript_ErrorHandler); try {
m_luaerrorhandler = lua_gettop(m_engineluastack); if (m_data->errormessage != "")
{
m_scriptdir = menuscript.substr(0,menuscript.find_last_of(DIR_DELIM)-1); m_script->setMainMenuErrorMessage(m_data->errormessage);
if((menuscript == "") || (!runScript(menuscript))) { m_data->errormessage = "";
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;
assert("no future without mainmenu" == 0);
} }
if (!loadMainMenuScript())
assert("no future without mainmenu" == 0);
run();
}
catch(LuaError &e) {
errorstream << "MAINMENU ERROR: " << e.what() << std::endl;
m_data->errormessage = e.what();
} }
run(); m_menu->quitMenu();
m_menumanager->deletingMenu(m_menu);
m_menu->drop(); m_menu->drop();
m_menu = 0; m_menu = 0;
} }
/******************************************************************************/ /******************************************************************************/
bool GUIEngine::runScript(std::string script) { bool GUIEngine::loadMainMenuScript()
{
// Try custom menu script (main_menu_script)
int ret = luaL_loadfile(m_engineluastack, script.c_str()) || std::string menuscript = g_settings->get("main_menu_script");
lua_pcall(m_engineluastack, 0, 0, m_luaerrorhandler); if(menuscript != "") {
if(ret){ m_scriptdir = fs::RemoveLastPathComponent(menuscript);
errorstream<<"========== ERROR FROM LUA WHILE CREATING MAIN MENU ==========="<<std::endl;
errorstream<<"Failed to load and run script from "<<std::endl; if(m_script->loadMod(menuscript, "__custommenu")) {
errorstream<<script<<":"<<std::endl; // custom menu script loaded
errorstream<<std::endl; return true;
errorstream<<lua_tostring(m_engineluastack, -1)<<std::endl; }
errorstream<<std::endl; else {
errorstream<<"=================== END OF ERROR FROM LUA ===================="<<std::endl; infostream
lua_pop(m_engineluastack, 1); // Pop error message from stack << "GUIEngine: execution of custom menu failed!"
lua_pop(m_engineluastack, 1); // Pop the error handler from stack << std::endl
return false; << "\tfalling back to builtin menu"
<< std::endl;
}
} }
return true;
// Try builtin menu script (main_menu_script)
std::string builtin_menuscript =
porting::path_share + DIR_DELIM + "builtin"
+ DIR_DELIM + "mainmenu.lua";
m_scriptdir = fs::RemoveRelativePathComponents(
fs::RemoveLastPathComponent(builtin_menuscript));
if(m_script->loadMod(builtin_menuscript, "__builtinmenu")) {
// builtin menu script loaded
return true;
}
else {
errorstream
<< "GUIEngine: unable to load builtin menu"
<< std::endl;
}
return false;
} }
/******************************************************************************/ /******************************************************************************/
@ -257,52 +243,6 @@ void GUIEngine::run()
else else
sleep_ms(25); sleep_ms(25);
} }
m_menu->quitMenu();
}
/******************************************************************************/
void GUIEngine::handleEvent(std::string text)
{
lua_getglobal(m_engineluastack, "engine");
lua_getfield(m_engineluastack, -1, "event_handler");
if(lua_isnil(m_engineluastack, -1))
return;
luaL_checktype(m_engineluastack, -1, LUA_TFUNCTION);
lua_pushstring(m_engineluastack, text.c_str());
if(lua_pcall(m_engineluastack, 1, 0, m_luaerrorhandler))
scriptError("error: %s", lua_tostring(m_engineluastack, -1));
}
/******************************************************************************/
void GUIEngine::handleButtons(std::map<std::string, std::string> fields)
{
lua_getglobal(m_engineluastack, "engine");
lua_getfield(m_engineluastack, -1, "button_handler");
if(lua_isnil(m_engineluastack, -1))
return;
luaL_checktype(m_engineluastack, -1, LUA_TFUNCTION);
lua_newtable(m_engineluastack);
for(std::map<std::string, std::string>::const_iterator
i = fields.begin(); i != fields.end(); i++){
const std::string &name = i->first;
const std::string &value = i->second;
lua_pushstring(m_engineluastack, name.c_str());
lua_pushlstring(m_engineluastack, value.c_str(), value.size());
lua_settable(m_engineluastack, -3);
}
if(lua_pcall(m_engineluastack, 1, 0, m_luaerrorhandler))
scriptError("error: %s", lua_tostring(m_engineluastack, -1));
} }
/******************************************************************************/ /******************************************************************************/
@ -318,7 +258,8 @@ GUIEngine::~GUIEngine()
//TODO: clean up m_menu here //TODO: clean up m_menu here
lua_close(m_engineluastack); infostream<<"GUIEngine: Deinitializing scripting"<<std::endl;
delete m_script;
m_irr_toplefttext->setText(L""); m_irr_toplefttext->setText(L"");
@ -565,17 +506,6 @@ bool GUIEngine::downloadFile(std::string url,std::string target) {
return false; 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) { void GUIEngine::setTopleftText(std::string append) {
std::string toset = "Minetest " VERSION_STRING; std::string toset = "Minetest " VERSION_STRING;

@ -26,7 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irrlichttypes.h" #include "irrlichttypes.h"
#include "modalMenu.h" #include "modalMenu.h"
#include "clouds.h" #include "clouds.h"
#include "guiLuaApi.h"
#include "guiFormSpecMenu.h" #include "guiFormSpecMenu.h"
#include "sound.h" #include "sound.h"
@ -50,6 +49,7 @@ typedef enum {
/* forward declarations */ /* forward declarations */
/******************************************************************************/ /******************************************************************************/
class GUIEngine; class GUIEngine;
class MainMenuScripting;
struct MainMenuData; struct MainMenuData;
struct SimpleSoundSpec; struct SimpleSoundSpec;
@ -86,35 +86,17 @@ class MenuMusicFetcher: public OnDemandSoundFetcher
{ {
std::set<std::string> m_fetched; std::set<std::string> m_fetched;
public: public:
void fetchSounds(const std::string &name, void fetchSounds(const std::string &name,
std::set<std::string> &dst_paths, std::set<std::string> &dst_paths,
std::set<std::string> &dst_datas) 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");
}
}; };
/** implementation of main menu based uppon formspecs */ /** implementation of main menu based uppon formspecs */
class GUIEngine { class GUIEngine {
public: /** grant ModApiMainMenu access to private members */
/** TextDestGuiEngine needs to transfer data to engine */ friend class ModApiMainMenu;
friend class TextDestGuiEngine;
/** guiLuaApi is used to initialize contained stack */
friend class guiLuaApi;
public:
/** /**
* default constructor * default constructor
* @param dev device to draw at * @param dev device to draw at
@ -132,20 +114,12 @@ public:
/** default destructor */ /** default destructor */
virtual ~GUIEngine(); virtual ~GUIEngine();
s32 playSound(SimpleSoundSpec spec, bool looped);
void stopSound(s32 handle);
protected:
/** /**
* process field data recieved from formspec * return MainMenuScripting interface
* @param fields data in field format
*/ */
void handleButtons(std::map<std::string, std::string> fields); MainMenuScripting* getScriptIface() {
/** return m_script;
* process events received from formspec }
* @param text events in textual form
*/
void handleEvent(std::string text);
/** /**
* return dir of current menuscript * return dir of current menuscript
@ -156,7 +130,10 @@ protected:
private: private:
/* run main menu loop */ /** find and run the main menu script */
bool loadMainMenuScript();
/** run main menu loop */
void run(); void run();
/** handler to limit frame rate within main menu */ /** handler to limit frame rate within main menu */
@ -185,27 +162,8 @@ private:
/** variable used to abort menu and return back to main game handling */ /** variable used to abort menu and return back to main game handling */
bool m_startgame; bool m_startgame;
/** /** scripting interface */
* initialize lua stack MainMenuScripting* m_script;
* @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;
/** script basefolder */ /** script basefolder */
std::string m_scriptdir; std::string m_scriptdir;
@ -284,6 +242,12 @@ private:
/** data used to draw clouds */ /** data used to draw clouds */
clouddata m_cloud; 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);
}; };

@ -39,6 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <IGUIComboBox.h> #include <IGUIComboBox.h>
#include "log.h" #include "log.h"
#include "tile.h" // ITextureSource #include "tile.h" // ITextureSource
#include "hud.h" // drawItemStack
#include "util/string.h" #include "util/string.h"
#include "util/numeric.h" #include "util/numeric.h"
#include "filesys.h" #include "filesys.h"
@ -61,92 +62,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
} }
void drawItemStack(video::IVideoDriver *driver,
gui::IGUIFont *font,
const ItemStack &item,
const core::rect<s32> &rect,
const core::rect<s32> *clip,
IGameDef *gamedef)
{
if(item.empty())
return;
const ItemDefinition &def = item.getDefinition(gamedef->idef());
video::ITexture *texture = gamedef->idef()->getInventoryTexture(def.name, gamedef);
// Draw the inventory texture
if(texture != NULL)
{
const video::SColor color(255,255,255,255);
const video::SColor colors[] = {color,color,color,color};
driver->draw2DImage(texture, rect,
core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())),
clip, colors, true);
}
if(def.type == ITEM_TOOL && item.wear != 0)
{
// Draw a progressbar
float barheight = rect.getHeight()/16;
float barpad_x = rect.getWidth()/16;
float barpad_y = rect.getHeight()/16;
core::rect<s32> progressrect(
rect.UpperLeftCorner.X + barpad_x,
rect.LowerRightCorner.Y - barpad_y - barheight,
rect.LowerRightCorner.X - barpad_x,
rect.LowerRightCorner.Y - barpad_y);
// Shrink progressrect by amount of tool damage
float wear = item.wear / 65535.0;
int progressmid =
wear * progressrect.UpperLeftCorner.X +
(1-wear) * progressrect.LowerRightCorner.X;
// Compute progressbar color
// wear = 0.0: green
// wear = 0.5: yellow
// wear = 1.0: red
video::SColor color(255,255,255,255);
int wear_i = MYMIN(floor(wear * 600), 511);
wear_i = MYMIN(wear_i + 10, 511);
if(wear_i <= 255)
color.set(255, wear_i, 255, 0);
else
color.set(255, 255, 511-wear_i, 0);
core::rect<s32> progressrect2 = progressrect;
progressrect2.LowerRightCorner.X = progressmid;
driver->draw2DRectangle(color, progressrect2, clip);
color = video::SColor(255,0,0,0);
progressrect2 = progressrect;
progressrect2.UpperLeftCorner.X = progressmid;
driver->draw2DRectangle(color, progressrect2, clip);
}
if(font != NULL && item.count >= 2)
{
// Get the item count as a string
std::string text = itos(item.count);
v2u32 dim = font->getDimension(narrow_to_wide(text).c_str());
v2s32 sdim(dim.X,dim.Y);
core::rect<s32> rect2(
/*rect.UpperLeftCorner,
core::dimension2d<u32>(rect.getWidth(), 15)*/
rect.LowerRightCorner - sdim,
sdim
);
video::SColor bgcolor(128,0,0,0);
driver->draw2DRectangle(bgcolor, rect2, clip);
video::SColor color(255,255,255,255);
font->draw(text.c_str(), rect2, color, false, false, clip);
}
}
/* /*
GUIFormSpecMenu GUIFormSpecMenu
*/ */

@ -57,13 +57,6 @@ public:
virtual std::string resolveText(std::string str){ return str; } 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 class GUIFormSpecMenu : public GUIModalMenu
{ {
struct ItemSpec struct ItemSpec

@ -27,6 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <IGUIStaticText.h> #include <IGUIStaticText.h>
#include <IGUIFont.h> #include <IGUIFont.h>
#include "main.h" #include "main.h"
#include "settings.h"
#include "gettext.h" #include "gettext.h"

@ -19,14 +19,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include <IGUIStaticText.h> #include "hud.h"
#include "guiFormSpecMenu.h"
#include "main.h" #include "main.h"
#include "settings.h"
#include "util/numeric.h" #include "util/numeric.h"
#include "log.h" #include "log.h"
#include "client.h" #include "gamedef.h"
#include "hud.h" #include "itemdef.h"
#include "inventory.h"
#include "tile.h"
#include "localplayer.h"
#include <IGUIStaticText.h>
Hud::Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv, Hud::Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv,
@ -339,3 +343,90 @@ void Hud::resizeHotbar() {
else else
hotbar_imagesize = 64; 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);
}
}

@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define HUD_HEADER #define HUD_HEADER
#include "irrlichttypes_extrabloated.h" #include "irrlichttypes_extrabloated.h"
#include <string>
#define HUD_DIR_LEFT_RIGHT 0 #define HUD_DIR_LEFT_RIGHT 0
#define HUD_DIR_RIGHT_LEFT 1 #define HUD_DIR_RIGHT_LEFT 1
@ -42,8 +43,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define HUD_HOTBAR_ITEMCOUNT_DEFAULT 8 #define HUD_HOTBAR_ITEMCOUNT_DEFAULT 8
#define HUD_HOTBAR_ITEMCOUNT_MAX 23 #define HUD_HOTBAR_ITEMCOUNT_MAX 23
class Player;
enum HudElementType { enum HudElementType {
HUD_ELEM_IMAGE = 0, HUD_ELEM_IMAGE = 0,
HUD_ELEM_TEXT = 1, HUD_ELEM_TEXT = 1,
@ -76,23 +75,18 @@ struct HudElement {
v2f offset; 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 #ifndef SERVER
#include <vector>
#include <IGUIFont.h> #include <IGUIFont.h>
#include "irr_aabb3d.h"
#include "gamedef.h" class IGameDef;
#include "inventory.h" class ITextureSource;
#include "localplayer.h" class Inventory;
class InventoryList;
class LocalPlayer;
struct ItemStack;
class Hud { class Hud {
public: public:
@ -130,6 +124,14 @@ public:
void drawSelectionBoxes(std::vector<aabb3f> &hilightboxes); 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
#endif #endif

@ -21,10 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define INVENTORY_HEADER #define INVENTORY_HEADER
#include <iostream> #include <iostream>
#include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
#include "irrlichttypes_bloated.h" #include "irrlichttypes.h"
#include "debug.h" #include "debug.h"
#include "itemdef.h" #include "itemdef.h"

@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "inventorymanager.h" #include "inventorymanager.h"
#include "log.h" #include "log.h"
#include "environment.h" #include "environment.h"
#include "cpp_api/scriptapi.h" #include "scripting_game.h"
#include "serverobject.h" #include "serverobject.h"
#include "main.h" // for g_settings #include "main.h" // for g_settings
#include "settings.h" #include "settings.h"
@ -29,6 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
#define PLAYER_TO_SA(p) p->getEnv()->getScriptIface()
/* /*
InventoryLocation InventoryLocation
*/ */

@ -26,9 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irr_v3d.h" #include "irr_v3d.h"
#include "irr_aabb3d.h" #include "irr_aabb3d.h"
#include <irrMap.h>
#include <irrList.h>
#include <irrArray.h>
#include <SColor.h> #include <SColor.h>
#endif #endif

@ -20,9 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef IRRLICHTTYPES_EXTRABLOATED_HEADER #ifndef IRRLICHTTYPES_EXTRABLOATED_HEADER
#define 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" #include "irrlichttypes_bloated.h"
#ifndef SERVER #ifndef SERVER

@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef ITEMGROUP_HEADER #ifndef ITEMGROUP_HEADER
#define ITEMGROUP_HEADER #define ITEMGROUP_HEADER
#include "irrlichttypes_extrabloated.h"
#include <string> #include <string>
#include <map> #include <map>

@ -21,16 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define LIGHT_HEADER #define LIGHT_HEADER
#include "irrlichttypes.h" #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 Lower level lighting stuff

@ -84,6 +84,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
Settings main_settings; Settings main_settings;
Settings *g_settings = &main_settings; Settings *g_settings = &main_settings;
std::string g_settings_path;
// Global profiler // Global profiler
Profiler main_profiler; Profiler main_profiler;
@ -913,7 +914,7 @@ int main(int argc, char *argv[])
*/ */
// Path of configuration file in use // Path of configuration file in use
std::string configpath = ""; g_settings_path = "";
if(cmd_args.exists("config")) if(cmd_args.exists("config"))
{ {
@ -924,7 +925,7 @@ int main(int argc, char *argv[])
<<cmd_args.get("config")<<"\""<<std::endl; <<cmd_args.get("config")<<"\""<<std::endl;
return 1; return 1;
} }
configpath = cmd_args.get("config"); g_settings_path = cmd_args.get("config");
} }
else else
{ {
@ -946,14 +947,14 @@ int main(int argc, char *argv[])
bool r = g_settings->readConfigFile(filenames[i].c_str()); bool r = g_settings->readConfigFile(filenames[i].c_str());
if(r) if(r)
{ {
configpath = filenames[i]; g_settings_path = filenames[i];
break; break;
} }
} }
// If no path found, use the first one (menu creates the file) // If no path found, use the first one (menu creates the file)
if(configpath == "") if(g_settings_path == "")
configpath = filenames[0]; g_settings_path = filenames[0];
} }
// Initialize debug streams // Initialize debug streams
@ -1193,7 +1194,7 @@ int main(int argc, char *argv[])
verbosestream<<_("Using gameid")<<" ["<<gamespec.id<<"]"<<std::endl; verbosestream<<_("Using gameid")<<" ["<<gamespec.id<<"]"<<std::endl;
// Create server // Create server
Server server(world_path, configpath, gamespec, false); Server server(world_path, gamespec, false);
server.start(port); server.start(port);
// Run server // Run server
@ -1573,6 +1574,11 @@ int main(int argc, char *argv[])
} }
if(menudata.errormessage != ""){
error_message = narrow_to_wide(menudata.errormessage);
continue;
}
//update worldspecs (necessary as new world may have been created) //update worldspecs (necessary as new world may have been created)
worldspecs = getAvailableWorlds(); worldspecs = getAvailableWorlds();
@ -1675,7 +1681,10 @@ int main(int argc, char *argv[])
// Break out of menu-game loop to shut down cleanly // Break out of menu-game loop to shut down cleanly
if(device->run() == false || kill == true) { 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; break;
} }
@ -1694,7 +1703,6 @@ int main(int argc, char *argv[])
current_address, current_address,
current_port, current_port,
error_message, error_message,
configpath,
chat_backend, chat_backend,
gamespec, gamespec,
simple_singleplayer_mode simple_singleplayer_mode
@ -1749,8 +1757,8 @@ int main(int argc, char *argv[])
#endif // !SERVER #endif // !SERVER
// Update configuration file // Update configuration file
if(configpath != "") if(g_settings_path != "")
g_settings->updateConfigFile(configpath.c_str()); g_settings->updateConfigFile(g_settings_path.c_str());
// Print modified quicktune values // Print modified quicktune values
{ {

@ -20,9 +20,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef MAIN_HEADER #ifndef MAIN_HEADER
#define MAIN_HEADER #define MAIN_HEADER
#include <string>
// Settings // Settings
class Settings; class Settings;
extern Settings *g_settings; extern Settings *g_settings;
extern std::string g_settings_path;
// Global profiler // Global profiler
class Profiler; class Profiler;

@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "filesys.h" #include "filesys.h"
#include "voxel.h" #include "voxel.h"
#include "porting.h" #include "porting.h"
#include "serialization.h"
#include "nodemetadata.h" #include "nodemetadata.h"
#include "settings.h" #include "settings.h"
#include "log.h" #include "log.h"
@ -33,9 +34,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/directiontables.h" #include "util/directiontables.h"
#include "util/mathconstants.h" #include "util/mathconstants.h"
#include "rollback_interface.h" #include "rollback_interface.h"
#include "environment.h"
#include "emerge.h" #include "emerge.h"
#include "mapgen_v6.h" #include "mapgen_v6.h"
#include "mapgen_indev.h"
#include "biome.h" #include "biome.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"

@ -20,9 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef MAP_HEADER #ifndef MAP_HEADER
#define MAP_HEADER #define MAP_HEADER
#include <jmutex.h>
#include <jmutexautolock.h>
#include <jthread.h>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <set> #include <set>
@ -33,11 +30,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapnode.h" #include "mapnode.h"
#include "constants.h" #include "constants.h"
#include "voxel.h" #include "voxel.h"
#include "mapgen.h" //for MapgenParams
#include "modifiedstate.h" #include "modifiedstate.h"
#include "util/container.h" #include "util/container.h"
#include "nodetimer.h" #include "nodetimer.h"
#include "environment.h"
extern "C" { extern "C" {
#include "sqlite3.h" #include "sqlite3.h"
@ -51,7 +46,9 @@ class NodeMetadata;
class IGameDef; class IGameDef;
class IRollbackReportSink; class IRollbackReportSink;
class EmergeManager; class EmergeManager;
class ServerEnvironment;
struct BlockMakeData; struct BlockMakeData;
struct MapgenParams;
/* /*

@ -21,8 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <sstream> #include <sstream>
#include "map.h" #include "map.h"
// For g_settings
#include "main.h"
#include "light.h" #include "light.h"
#include "nodedef.h" #include "nodedef.h"
#include "nodemetadata.h" #include "nodemetadata.h"
@ -31,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "nameidmapping.h" #include "nameidmapping.h"
#include "content_mapnode.h" // For legacy name-id mapping #include "content_mapnode.h" // For legacy name-id mapping
#include "content_nodemeta.h" // For legacy deserialization #include "content_nodemeta.h" // For legacy deserialization
#include "serialization.h"
#ifndef SERVER #ifndef SERVER
#include "mapblock_mesh.h" #include "mapblock_mesh.h"
#endif #endif

@ -20,19 +20,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef MAPBLOCK_HEADER #ifndef MAPBLOCK_HEADER
#define MAPBLOCK_HEADER #define MAPBLOCK_HEADER
#include <jmutex.h>
#include <jmutexautolock.h>
#include <exception>
#include <set> #include <set>
#include "debug.h" #include "debug.h"
#include "irrlichttypes.h"
#include "irr_v3d.h" #include "irr_v3d.h"
#include "irr_aabb3d.h"
#include "mapnode.h" #include "mapnode.h"
#include "exceptions.h" #include "exceptions.h"
#include "serialization.h"
#include "constants.h" #include "constants.h"
#include "voxel.h"
#include "staticobject.h" #include "staticobject.h"
#include "nodemetadata.h" #include "nodemetadata.h"
#include "nodetimer.h" #include "nodetimer.h"
@ -43,6 +36,7 @@ class Map;
class NodeMetadataList; class NodeMetadataList;
class IGameDef; class IGameDef;
class MapBlockMesh; class MapBlockMesh;
class VoxelManipulator;
#define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff #define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff
@ -514,7 +508,6 @@ public:
#ifndef SERVER // Only on client #ifndef SERVER // Only on client
MapBlockMesh *mesh; MapBlockMesh *mesh;
//JMutex mesh_mutex;
#endif #endif
NodeMetadataList m_node_metadata; NodeMetadataList m_node_metadata;

@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "treegen.h" #include "treegen.h"
#include "mapgen_v6.h" #include "mapgen_v6.h"
#include "mapgen_v7.h" #include "mapgen_v7.h"
#include "serialization.h"
#include "util/serialize.h" #include "util/serialize.h"
#include "filesys.h" #include "filesys.h"

@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef MAPGEN_HEADER #ifndef MAPGEN_HEADER
#define MAPGEN_HEADER #define MAPGEN_HEADER
#include "irrlichttypes_extrabloated.h" #include "irrlichttypes_bloated.h"
#include "util/container.h" // UniqueQueue #include "util/container.h" // UniqueQueue
#include "gamedef.h" #include "gamedef.h"
#include "nodedef.h" #include "nodedef.h"

@ -25,8 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "nodedef.h" #include "nodedef.h"
#include "voxelalgorithms.h" #include "voxelalgorithms.h"
#include "profiler.h" #include "profiler.h"
#include "settings.h" // For g_settings
#include "main.h" // For g_profiler
#include "emerge.h" #include "emerge.h"
//////////////////////// Mapgen Singlenode parameter read/write //////////////////////// Mapgen Singlenode parameter read/write

@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irr_v3d.h" #include "irr_v3d.h"
#include "irr_aabb3d.h" #include "irr_aabb3d.h"
#include "light.h" #include "light.h"
#include <string>
#include <vector> #include <vector>
class INodeDefManager; class INodeDefManager;

@ -18,12 +18,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "mapsector.h" #include "mapsector.h"
#include "jmutexautolock.h"
#ifndef SERVER
#include "client.h"
#endif
#include "exceptions.h" #include "exceptions.h"
#include "mapblock.h" #include "mapblock.h"
#include "serialization.h"
MapSector::MapSector(Map *parent, v2s16 pos, IGameDef *gamedef): MapSector::MapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
differs_from_disk(false), differs_from_disk(false),

@ -20,9 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef MAPSECTOR_HEADER #ifndef MAPSECTOR_HEADER
#define MAPSECTOR_HEADER #define MAPSECTOR_HEADER
#include <jmutex.h> #include "irrlichttypes.h"
#include "irrlichttypes_bloated.h" #include "irr_v2d.h"
#include "exceptions.h"
#include <ostream> #include <ostream>
#include <map> #include <map>
#include <list> #include <list>

@ -18,8 +18,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "mesh.h" #include "mesh.h"
#include "debug.h"
#include "log.h" #include "log.h"
#include <cassert>
#include <iostream> #include <iostream>
#include <IAnimatedMesh.h> #include <IAnimatedMesh.h>
#include <SAnimatedMesh.h> #include <SAnimatedMesh.h>

@ -21,14 +21,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define MODS_HEADER #define MODS_HEADER
#include "irrlichttypes.h" #include "irrlichttypes.h"
#include <irrList.h>
#include <list> #include <list>
#include <set> #include <set>
#include <vector> #include <vector>
#include <string> #include <string>
#include <map> #include <map>
#include <exception> #include <exception>
#include <list>
#include "json/json.h" #include "json/json.h"
#include "config.h" #include "config.h"
@ -152,10 +150,9 @@ private:
// exists. A name conflict happens when two or more mods // exists. A name conflict happens when two or more mods
// at the same level have the same name but different paths. // at the same level have the same name but different paths.
// Levels (mods in higher levels override mods in lower levels): // Levels (mods in higher levels override mods in lower levels):
// 1. common mod in modpack; 2. common mod; // 1. game mod in modpack; 2. game mod;
// 3. game mod in modpack; 4. game mod; // 3. world mod in modpack; 4. world mod;
// 5. world mod in modpack; 6. world mod; // 5. addon mod in modpack; 6. addon mod.
// 7. addon mod in modpack; 8. addon mod.
std::set<std::string> m_name_conflicts; std::set<std::string> m_name_conflicts;
}; };

@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "nameidmapping.h" #include "nameidmapping.h"
#include "exceptions.h"
#include "util/serialize.h" #include "util/serialize.h"
void NameIdMapping::serialize(std::ostream &os) const void NameIdMapping::serialize(std::ostream &os) const

@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef NODEMETADATA_HEADER #ifndef NODEMETADATA_HEADER
#define NODEMETADATA_HEADER #define NODEMETADATA_HEADER
#include "irrlichttypes_bloated.h" #include "irr_v3d.h"
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <map> #include <map>

@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "nodetimer.h" #include "nodetimer.h"
#include "log.h" #include "log.h"
#include "serialization.h"
#include "util/serialize.h" #include "util/serialize.h"
#include "constants.h" // MAP_BLOCKSIZE #include "constants.h" // MAP_BLOCKSIZE

@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef NODETIMER_HEADER #ifndef NODETIMER_HEADER
#define NODETIMER_HEADER #define NODETIMER_HEADER
#include "irrlichttypes_bloated.h" #include "irr_v3d.h"
#include <iostream> #include <iostream>
#include <map> #include <map>

@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <math.h> #include <math.h>
#include "noise.h" #include "noise.h"
#include <iostream> #include <iostream>
#include <string.h> // memset
#include "debug.h" #include "debug.h"
#include "util/numeric.h" #include "util/numeric.h"

@ -19,9 +19,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "object_properties.h" #include "object_properties.h"
#include "irrlichttypes_bloated.h" #include "irrlichttypes_bloated.h"
#include "exceptions.h"
#include "util/serialize.h" #include "util/serialize.h"
#include <sstream> #include <sstream>
#include <map>
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
#define PP2(x) "("<<(x).X<<","<<(x).Y<<")" #define PP2(x) "("<<(x).X<<","<<(x).Y<<")"

@ -22,6 +22,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
/******************************************************************************/ /******************************************************************************/
#include "pathfinder.h" #include "pathfinder.h"
#include "environment.h"
#include "map.h"
#include "log.h"
#ifdef PATHFINDER_DEBUG #ifdef PATHFINDER_DEBUG
#include <iomanip> #include <iomanip>

@ -25,10 +25,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
/******************************************************************************/ /******************************************************************************/
#include <vector> #include <vector>
#include "server.h"
#include "irr_v3d.h" #include "irr_v3d.h"
/******************************************************************************/
/* Forward declarations */
/******************************************************************************/
class ServerEnvironment;
/******************************************************************************/ /******************************************************************************/
/* Typedefs and macros */ /* Typedefs and macros */
/******************************************************************************/ /******************************************************************************/

@ -21,7 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "hud.h" #include "hud.h"
#include "constants.h" #include "constants.h"
#include "gamedef.h" #include "gamedef.h"
#include "connection.h" // PEER_ID_INEXISTENT
#include "settings.h" #include "settings.h"
#include "content_sao.h" #include "content_sao.h"
#include "util/numeric.h" #include "util/numeric.h"

@ -194,6 +194,15 @@ public:
return m_collisionbox; 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 virtual bool isLocal() const
{ return false; } { return false; }
virtual PlayerSAO *getPlayerSAO() virtual PlayerSAO *getPlayerSAO()

@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "debug.h" #include "debug.h"
#include "constants.h" #include "constants.h"
#include "gettime.h" #include "gettime.h"
#include "threads.h"
#ifdef _MSC_VER #ifdef _MSC_VER
#define SWPRINTF_CHARSTRING L"%S" #define SWPRINTF_CHARSTRING L"%S"

@ -20,13 +20,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef PROFILER_HEADER #ifndef PROFILER_HEADER
#define PROFILER_HEADER #define PROFILER_HEADER
#include "irrlichttypes_bloated.h" #include "irrlichttypes.h"
#include <string> #include <string>
#include <jmutex.h> #include <jmutex.h>
#include <jmutexautolock.h> #include <jmutexautolock.h>
#include <map> #include <map>
#include "util/timetaker.h" #include "util/timetaker.h"
#include "util/numeric.h" // paging() #include "util/numeric.h" // paging()
#include "debug.h" // assert()
/* /*
Time profiler Time profiler

@ -27,7 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "nodedef.h" #include "nodedef.h"
#include "util/serialize.h" #include "util/serialize.h"
#include "util/string.h" #include "util/string.h"
#include "strfnd.h"
#include "util/numeric.h" #include "util/numeric.h"
#include "inventorymanager.h" // deserializing InventoryLocations #include "inventorymanager.h" // deserializing InventoryLocations

@ -2,8 +2,18 @@ add_subdirectory(common)
add_subdirectory(cpp_api) add_subdirectory(cpp_api)
add_subdirectory(lua_api) add_subdirectory(lua_api)
set(SCRIPT_SRCS # Used by server and client
${SCRIPT_COMMON_SRCS} set(common_SCRIPT_SRCS
${SCRIPT_CPP_API_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/scripting_game.cpp
${SCRIPT_LUA_API_SRCS} ${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) PARENT_SCOPE)

@ -1,6 +1,11 @@
set(SCRIPT_COMMON_SRCS # Used by server and client
set(common_SCRIPT_COMMON_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/c_content.cpp ${CMAKE_CURRENT_SOURCE_DIR}/c_content.cpp
${CMAKE_CURRENT_SOURCE_DIR}/c_converter.cpp ${CMAKE_CURRENT_SOURCE_DIR}/c_converter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/c_types.cpp ${CMAKE_CURRENT_SOURCE_DIR}/c_types.cpp
${CMAKE_CURRENT_SOURCE_DIR}/c_internal.cpp ${CMAKE_CURRENT_SOURCE_DIR}/c_internal.cpp
PARENT_SCOPE) PARENT_SCOPE)
# Used by client only
set(minetest_SCRIPT_COMMON_SRCS
PARENT_SCOPE)

@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "server.h" #include "server.h"
#include "log.h" #include "log.h"
#include "tool.h" #include "tool.h"
#include "server.h" #include "serverobject.h"
#include "mapgen.h" #include "mapgen.h"
struct EnumString es_TileAnimationType[] = struct EnumString es_TileAnimationType[] =
@ -694,8 +694,7 @@ void push_tool_capabilities(lua_State *L,
} }
/******************************************************************************/ /******************************************************************************/
void push_inventory_list(Inventory *inv, const char *name, void push_inventory_list(lua_State *L, Inventory *inv, const char *name)
lua_State *L)
{ {
InventoryList *invlist = inv->getList(name); InventoryList *invlist = inv->getList(name);
if(invlist == NULL){ if(invlist == NULL){
@ -709,8 +708,8 @@ void push_inventory_list(Inventory *inv, const char *name,
} }
/******************************************************************************/ /******************************************************************************/
void read_inventory_list(Inventory *inv, const char *name, void read_inventory_list(lua_State *L, int tableindex,
lua_State *L, int tableindex, Server* srv,int forcesize) Inventory *inv, const char *name, Server* srv, int forcesize)
{ {
if(tableindex < 0) if(tableindex < 0)
tableindex = lua_gettop(L) + 1 + tableindex; tableindex = lua_gettop(L) + 1 + tableindex;

@ -87,14 +87,13 @@ void read_object_properties (lua_State *L,
int index, int index,
ObjectProperties *prop); ObjectProperties *prop);
//TODO fix parameter oreder! void push_inventory_list (lua_State *L,
void push_inventory_list (Inventory *inv, Inventory *inv,
const char *name, const char *name);
lua_State *L); void read_inventory_list (lua_State *L,
void read_inventory_list (Inventory *inv,
const char *name,
lua_State *L,
int tableindex, int tableindex,
Inventory *inv,
const char *name,
Server* srv, Server* srv,
int forcesize=-1); int forcesize=-1);

@ -18,17 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "common/c_internal.h" #include "common/c_internal.h"
#include "server.h" #include "debug.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;
}
std::string script_get_backtrace(lua_State *L) std::string script_get_backtrace(lua_State *L)
{ {
@ -51,15 +41,108 @@ std::string script_get_backtrace(lua_State *L)
return s; return s;
} }
void script_error(lua_State* L,const char *fmt, ...) void script_error(lua_State *L, const char *fmt, ...)
{ {
va_list argp; va_list argp;
va_start(argp, fmt); va_start(argp, fmt);
char buf[10000]; char buf[10000];
vsnprintf(buf, 10000, fmt, argp); vsnprintf(buf, 10000, fmt, argp);
va_end(argp); va_end(argp);
//errorstream<<"SCRIPT ERROR: "<<buf;
throw LuaError(L, 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);
}
}
}

@ -27,34 +27,46 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef C_INTERNAL_H_ #ifndef C_INTERNAL_H_
#define C_INTERNAL_H_ #define C_INTERNAL_H_
class Server;
class ScriptApi;
#include <iostream>
#include "lua_api/l_base.h"
extern "C" { extern "C" {
#include "lua.h" #include <lua.h>
#include <lauxlib.h>
} }
#define luamethod(class, name) {#name, class::l_##name} #include "common/c_types.h"
#define STACK_TO_SERVER(L) get_scriptapi(L)->getServer()
#define API_FCT(name) registerFunction(L,#name,l_##name,top)
#define REGISTER_LUA_REF(cln) \ // What script_run_callbacks does with the return values of callbacks.
class ModApi_##cln : public ModApiBase { \ // Regardless of the mode, if only one callback is defined,
public: \ // its return value is the total return value.
ModApi_##cln() : ModApiBase() {}; \ // Modes only affect the case where 0 or >= 2 callbacks are defined.
bool Initialize(lua_State* L, int top) { \ enum RunCallbacksMode
cln::Register(L); \ {
return true; \ // Returns the return value of the first callback
}; \ // Returns nil if list of callbacks is empty
}; \ RUN_CALLBACKS_MODE_FIRST,
ModApi_##cln macro_generated_prototype__##cln; // 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); std::string script_get_backtrace (lua_State *L);
void script_error (lua_State *L, const char *fmt, ...); void script_error (lua_State *L, const char *fmt, ...);
void script_run_callbacks (lua_State *L, int nargs,
RunCallbacksMode mode);
#endif /* C_INTERNAL_H_ */ #endif /* C_INTERNAL_H_ */

@ -50,26 +50,6 @@ public:
} }
}; };
class ModNameStorer
{
private:
lua_State *L;
public:
ModNameStorer(lua_State *L_, const std::string modname):
L(L_)
{
// Store current modname in registry
lua_pushstring(L, modname.c_str());
lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
}
~ModNameStorer()
{
// Clear current modname in registry
lua_pushnil(L);
lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
}
};
class LuaError : public std::exception class LuaError : public std::exception
{ {
public: public:

@ -1,4 +1,5 @@
set(SCRIPT_CPP_API_SRCS # Used by server and client
set(common_SCRIPT_CPP_API_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/s_base.cpp ${CMAKE_CURRENT_SOURCE_DIR}/s_base.cpp
${CMAKE_CURRENT_SOURCE_DIR}/s_entity.cpp ${CMAKE_CURRENT_SOURCE_DIR}/s_entity.cpp
${CMAKE_CURRENT_SOURCE_DIR}/s_env.cpp ${CMAKE_CURRENT_SOURCE_DIR}/s_env.cpp
@ -7,5 +8,10 @@ set(SCRIPT_CPP_API_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/s_node.cpp ${CMAKE_CURRENT_SOURCE_DIR}/s_node.cpp
${CMAKE_CURRENT_SOURCE_DIR}/s_nodemeta.cpp ${CMAKE_CURRENT_SOURCE_DIR}/s_nodemeta.cpp
${CMAKE_CURRENT_SOURCE_DIR}/s_player.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) PARENT_SCOPE)

@ -17,31 +17,142 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 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 <stdio.h>
#include <cstdarg> #include <cstdarg>
extern "C" {
#include "lua.h"
#include "lauxlib.h"
}
#include "cpp_api/s_base.h" class ModNameStorer
#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)
{ {
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;
} }
/*
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::realityCheck()
{ {
int top = lua_gettop(m_luastack); int top = lua_gettop(m_luastack);
@ -52,7 +163,7 @@ void ScriptApiBase::realityCheck()
} }
} }
void ScriptApiBase::scriptError(const char *fmt, ...) void ScriptApiBase::scriptError(const char *fmt, ...)
{ {
va_list argp; va_list argp;
va_start(argp, fmt); va_start(argp, fmt);
@ -65,130 +176,34 @@ void ScriptApiBase::scriptError(const char *fmt, ...)
void ScriptApiBase::stackDump(std::ostream &o) void ScriptApiBase::stackDump(std::ostream &o)
{ {
int i; int i;
int top = lua_gettop(m_luastack); int top = lua_gettop(m_luastack);
for (i = 1; i <= top; i++) { /* repeat for each level */ for (i = 1; i <= top; i++) { /* repeat for each level */
int t = lua_type(m_luastack, i); int t = lua_type(m_luastack, i);
switch (t) { switch (t) {
case LUA_TSTRING: /* strings */ case LUA_TSTRING: /* strings */
o<<"\""<<lua_tostring(m_luastack, i)<<"\""; o<<"\""<<lua_tostring(m_luastack, i)<<"\"";
break; break;
case LUA_TBOOLEAN: /* booleans */ case LUA_TBOOLEAN: /* booleans */
o<<(lua_toboolean(m_luastack, i) ? "true" : "false"); o<<(lua_toboolean(m_luastack, i) ? "true" : "false");
break; break;
case LUA_TNUMBER: /* numbers */ { case LUA_TNUMBER: /* numbers */ {
char buf[10]; char buf[10];
snprintf(buf, 10, "%g", lua_tonumber(m_luastack, i)); snprintf(buf, 10, "%g", lua_tonumber(m_luastack, i));
o<<buf; o<<buf;
break; } break; }
default: /* other values */ default: /* other values */
o<<lua_typename(m_luastack, t); o<<lua_typename(m_luastack, t);
break; 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 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))
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);
}
// 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);
} }
o<<" ";
} }
o<<std::endl;
} }
void ScriptApiBase::addObjectReference(ServerActiveObject *cobj) void ScriptApiBase::addObjectReference(ServerActiveObject *cobj)

@ -21,67 +21,37 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define S_BASE_H_ #define S_BASE_H_
#include <iostream> #include <iostream>
#include <string>
extern "C" {
#include <lua.h>
}
#include "irrlichttypes.h" #include "irrlichttypes.h"
#include "jmutex.h" #include "jmutex.h"
#include "jmutexautolock.h" #include "jmutexautolock.h"
#include "common/c_types.h" #include "common/c_types.h"
#include "debug.h"
#define LOCK_DEBUG #define SCRIPTAPI_LOCK_DEBUG
class Server; class Server;
class Environment; class Environment;
class GUIEngine;
class ServerActiveObject; 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 { class ScriptApiBase {
public: public:
ScriptApiBase();
virtual ~ScriptApiBase();
bool loadMod(const std::string &scriptpath, const std::string &modname);
bool loadScript(const std::string &scriptpath);
/* object */ /* object */
void addObjectReference(ServerActiveObject *cobj); void addObjectReference(ServerActiveObject *cobj);
void removeObjectReference(ServerActiveObject *cobj); void removeObjectReference(ServerActiveObject *cobj);
ScriptApiBase();
protected: protected:
friend class LuaABM; friend class LuaABM;
friend class InvRef; friend class InvRef;
@ -91,78 +61,35 @@ protected:
friend class ModApiEnvMod; friend class ModApiEnvMod;
friend class LuaVoxelManip; friend class LuaVoxelManip;
lua_State* getStack()
inline lua_State* getStack()
{ return m_luastack; } { return m_luastack; }
bool setStack(lua_State* stack) {
if (m_luastack == 0) {
m_luastack = stack;
return true;
}
return false;
}
void realityCheck(); void realityCheck();
void scriptError(const char *fmt, ...); void scriptError(const char *fmt, ...);
void stackDump(std::ostream &o); 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; } void setServer(Server* server) { m_server = server; }
Environment* getEnv() { return m_environment; } Environment* getEnv() { return m_environment; }
void setEnv(Environment* env) { m_environment = env; } void setEnv(Environment* env) { m_environment = env; }
GUIEngine* getGuiEngine() { return m_guiengine; }
void setGuiEngine(GUIEngine* guiengine) { m_guiengine = guiengine; }
void objectrefGetOrCreate(ServerActiveObject *cobj); void objectrefGetOrCreate(ServerActiveObject *cobj);
void objectrefGet(u16 id); void objectrefGet(u16 id);
JMutex m_luastackmutex; JMutex m_luastackmutex;
#ifdef LOCK_DEBUG #ifdef SCRIPTAPI_LOCK_DEBUG
bool m_locked; bool m_locked;
#endif #endif
private: private:
lua_State* m_luastack; lua_State* m_luastack;
Server* m_server; Server* m_server;
Environment* m_environment; Environment* m_environment;
GUIEngine* m_guiengine;
}; };
#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;
};
#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_ */ #endif /* S_BASE_H_ */

@ -18,15 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "cpp_api/s_entity.h" #include "cpp_api/s_entity.h"
#include "cpp_api/s_internal.h"
#include "log.h" #include "log.h"
#include "object_properties.h" #include "object_properties.h"
#include "common/c_converter.h" #include "common/c_converter.h"
#include "common/c_content.h" #include "common/c_content.h"
extern "C" {
#include "lauxlib.h"
}
bool ScriptApiEntity::luaentity_Add(u16 id, const char *name) bool ScriptApiEntity::luaentity_Add(u16 id, const char *name)
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER

@ -18,16 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "cpp_api/s_env.h" #include "cpp_api/s_env.h"
#include "cpp_api/s_internal.h"
#include "common/c_converter.h" #include "common/c_converter.h"
#include "log.h" #include "log.h"
#include "environment.h" #include "environment.h"
#include "mapgen.h" #include "mapgen.h"
#include "lua_api/l_env.h" #include "lua_api/l_env.h"
extern "C" {
#include "lauxlib.h"
}
void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp, void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp,
u32 blockseed) u32 blockseed)
{ {
@ -40,7 +37,7 @@ void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp,
push_v3s16(L, minp); push_v3s16(L, minp);
push_v3s16(L, maxp); push_v3s16(L, maxp);
lua_pushnumber(L, blockseed); 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) void ScriptApiEnv::environment_Step(float dtime)
@ -53,7 +50,7 @@ void ScriptApiEnv::environment_Step(float dtime)
lua_getfield(L, -1, "registered_globalsteps"); lua_getfield(L, -1, "registered_globalsteps");
// Call callbacks // Call callbacks
lua_pushnumber(L, dtime); 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) void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams)
@ -80,7 +77,7 @@ void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams)
lua_pushstring(L, flagstr.c_str()); lua_pushstring(L, flagstr.c_str());
lua_setfield(L, -2, "flags"); 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) void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)

@ -0,0 +1,63 @@
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/******************************************************************************/
/******************************************************************************/
/* WARNING!!!! do NOT add this header in any include file or any code file */
/* not being a modapi file!!!!!!!! */
/******************************************************************************/
/******************************************************************************/
#ifndef S_INTERNAL_H_
#define S_INTERNAL_H_
#include "common/c_internal.h"
#include "cpp_api/s_base.h"
#ifdef SCRIPTAPI_LOCK_DEBUG
#include "debug.h" // assert()
class LockChecker {
public:
LockChecker(bool* variable) {
assert(*variable == false);
m_variable = variable;
*m_variable = true;
}
~LockChecker() {
*m_variable = false;
}
private:
bool* m_variable;
};
#define SCRIPTAPI_LOCK_CHECK LockChecker(&(this->m_locked))
#else
#define SCRIPTAPI_LOCK_CHECK while(0)
#endif
#define SCRIPTAPI_PRECHECKHEADER \
JMutexAutoLock(this->m_luastackmutex); \
SCRIPTAPI_LOCK_CHECK; \
realityCheck(); \
lua_State *L = getStack(); \
assert(lua_checkstack(L, 20)); \
StackUnroller stack_unroller(L);
#endif /* S_INTERNAL_H_ */

@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "cpp_api/s_inventory.h" #include "cpp_api/s_inventory.h"
#include "cpp_api/s_internal.h"
#include "inventorymanager.h" #include "inventorymanager.h"
#include "lua_api/l_inventory.h" #include "lua_api/l_inventory.h"
#include "lua_api/l_item.h" #include "lua_api/l_item.h"

@ -18,10 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "cpp_api/s_item.h" #include "cpp_api/s_item.h"
#include "cpp_api/s_internal.h"
#include "common/c_converter.h" #include "common/c_converter.h"
#include "common/c_content.h" #include "common/c_content.h"
#include "lua_api/l_item.h" #include "lua_api/l_item.h"
#include "server.h" #include "server.h"
#include "log.h"
#include "util/pointedthing.h"
bool ScriptApiItem::item_OnDrop(ItemStack &item, bool ScriptApiItem::item_OnDrop(ItemStack &item,
ServerActiveObject *dropper, v3f pos) ServerActiveObject *dropper, v3f pos)

@ -0,0 +1,80 @@
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "cpp_api/s_mainmenu.h"
#include "cpp_api/s_internal.h"
#include "common/c_converter.h"
void ScriptApiMainMenu::setMainMenuErrorMessage(std::string errormessage)
{
SCRIPTAPI_PRECHECKHEADER
lua_getglobal(L, "gamedata");
int gamedata_idx = lua_gettop(L);
lua_pushstring(L, "errormessage");
lua_pushstring(L, errormessage.c_str());
lua_settable(L, gamedata_idx);
lua_pop(L, 1);
}
void ScriptApiMainMenu::handleMainMenuEvent(std::string text)
{
SCRIPTAPI_PRECHECKHEADER
// Get handler function
lua_getglobal(L, "engine");
lua_getfield(L, -1, "event_handler");
if(lua_isnil(L, -1))
return;
luaL_checktype(L, -1, LUA_TFUNCTION);
// Call it
lua_pushstring(L, text.c_str());
if(lua_pcall(L, 1, 0, 0))
scriptError("error running function engine.event_handler: %s\n",
lua_tostring(L, -1));
}
void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> fields)
{
SCRIPTAPI_PRECHECKHEADER
// Get handler function
lua_getglobal(L, "engine");
lua_getfield(L, -1, "button_handler");
if(lua_isnil(L, -1))
return;
luaL_checktype(L, -1, LUA_TFUNCTION);
// Convert fields to lua table
lua_newtable(L);
for(std::map<std::string, std::string>::const_iterator
i = fields.begin(); i != fields.end(); i++){
const std::string &name = i->first;
const std::string &value = i->second;
lua_pushstring(L, name.c_str());
lua_pushlstring(L, value.c_str(), value.size());
lua_settable(L, -3);
}
// Call it
if(lua_pcall(L, 1, 0, 0))
scriptError("error running function engine.button_handler: %s\n",
lua_tostring(L, -1));
}

@ -0,0 +1,49 @@
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef S_MAINMENU_H_
#define S_MAINMENU_H_
#include "cpp_api/s_base.h"
#include <map>
class ScriptApiMainMenu
: virtual public ScriptApiBase
{
public:
/**
* set gamedata.errormessage to inform lua of an error
* @param errormessage the error message
*/
void setMainMenuErrorMessage(std::string errormessage);
/**
* process events received from formspec
* @param text events in textual form
*/
void handleMainMenuEvent(std::string text);
/**
* process field data recieved from formspec
* @param fields data in field format
*/
void handleMainMenuButtons(std::map<std::string, std::string> fields);
};
#endif /* S_MAINMENU_H_ */

@ -18,10 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "cpp_api/s_node.h" #include "cpp_api/s_node.h"
#include "cpp_api/s_internal.h"
#include "common/c_converter.h" #include "common/c_converter.h"
#include "common/c_content.h" #include "common/c_content.h"
#include "nodedef.h" #include "nodedef.h"
#include "server.h" #include "server.h"
#include "environment.h"
struct EnumString ScriptApiNode::es_DrawType[] = struct EnumString ScriptApiNode::es_DrawType[] =

@ -18,16 +18,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "cpp_api/s_nodemeta.h" #include "cpp_api/s_nodemeta.h"
#include "cpp_api/s_internal.h"
#include "common/c_converter.h" #include "common/c_converter.h"
#include "nodedef.h" #include "nodedef.h"
#include "mapnode.h" #include "mapnode.h"
#include "server.h" #include "server.h"
#include "environment.h"
#include "lua_api/l_item.h" #include "lua_api/l_item.h"
extern "C" {
#include "lauxlib.h"
}
// Return number of accepted items to be moved // Return number of accepted items to be moved
int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p, int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
const std::string &from_list, int from_index, const std::string &from_list, int from_index,

@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "cpp_api/s_player.h" #include "cpp_api/s_player.h"
#include "cpp_api/s_internal.h"
void ScriptApiPlayer::on_newplayer(ServerActiveObject *player) void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
{ {
@ -28,7 +29,7 @@ void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
lua_getfield(L, -1, "registered_on_newplayers"); lua_getfield(L, -1, "registered_on_newplayers");
// Call callbacks // Call callbacks
objectrefGetOrCreate(player); objectrefGetOrCreate(player);
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
} }
void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player) void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player)
@ -40,7 +41,7 @@ void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player)
lua_getfield(L, -1, "registered_on_dieplayers"); lua_getfield(L, -1, "registered_on_dieplayers");
// Call callbacks // Call callbacks
objectrefGetOrCreate(player); objectrefGetOrCreate(player);
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
} }
bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player) bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
@ -52,7 +53,7 @@ bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
lua_getfield(L, -1, "registered_on_respawnplayers"); lua_getfield(L, -1, "registered_on_respawnplayers");
// Call callbacks // Call callbacks
objectrefGetOrCreate(player); 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); bool positioning_handled_by_some = lua_toboolean(L, -1);
return positioning_handled_by_some; return positioning_handled_by_some;
} }
@ -66,7 +67,7 @@ void ScriptApiPlayer::on_joinplayer(ServerActiveObject *player)
lua_getfield(L, -1, "registered_on_joinplayers"); lua_getfield(L, -1, "registered_on_joinplayers");
// Call callbacks // Call callbacks
objectrefGetOrCreate(player); objectrefGetOrCreate(player);
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
} }
void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player) void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player)
@ -78,7 +79,7 @@ void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player)
lua_getfield(L, -1, "registered_on_leaveplayers"); lua_getfield(L, -1, "registered_on_leaveplayers");
// Call callbacks // Call callbacks
objectrefGetOrCreate(player); objectrefGetOrCreate(player);
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST); script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
} }
void ScriptApiPlayer::on_cheat(ServerActiveObject *player, void ScriptApiPlayer::on_cheat(ServerActiveObject *player,
@ -94,7 +95,7 @@ void ScriptApiPlayer::on_cheat(ServerActiveObject *player,
lua_newtable(L); lua_newtable(L);
lua_pushlstring(L, cheat_type.c_str(), cheat_type.size()); lua_pushlstring(L, cheat_type.c_str(), cheat_type.size());
lua_setfield(L, -2, "type"); 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, void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player,
@ -121,7 +122,7 @@ void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player,
lua_pushlstring(L, value.c_str(), value.size()); lua_pushlstring(L, value.c_str(), value.size());
lua_settable(L, -3); lua_settable(L, -3);
} }
runCallbacks(3, RUN_CALLBACKS_MODE_OR_SC); script_run_callbacks(L, 3, RUN_CALLBACKS_MODE_OR_SC);
} }
ScriptApiPlayer::~ScriptApiPlayer() { ScriptApiPlayer::~ScriptApiPlayer() {
} }

@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef S_PLAYER_H_ #ifndef S_PLAYER_H_
#define S_PLAYER_H_ #define S_PLAYER_H_
#include <map>
#include "cpp_api/s_base.h" #include "cpp_api/s_base.h"

@ -0,0 +1,151 @@
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "cpp_api/s_server.h"
#include "cpp_api/s_internal.h"
#include "common/c_converter.h"
bool ScriptApiServer::getAuth(const std::string &playername,
std::string *dst_password,
std::set<std::string> *dst_privs)
{
SCRIPTAPI_PRECHECKHEADER
getAuthHandler();
lua_getfield(L, -1, "get_auth");
if(lua_type(L, -1) != LUA_TFUNCTION)
throw LuaError(L, "Authentication handler missing get_auth");
lua_pushstring(L, playername.c_str());
if(lua_pcall(L, 1, 1, 0))
scriptError("error: %s", lua_tostring(L, -1));
// nil = login not allowed
if(lua_isnil(L, -1))
return false;
luaL_checktype(L, -1, LUA_TTABLE);
std::string password;
bool found = getstringfield(L, -1, "password", password);
if(!found)
throw LuaError(L, "Authentication handler didn't return password");
if(dst_password)
*dst_password = password;
lua_getfield(L, -1, "privileges");
if(!lua_istable(L, -1))
throw LuaError(L,
"Authentication handler didn't return privilege table");
if(dst_privs)
readPrivileges(-1, *dst_privs);
lua_pop(L, 1);
return true;
}
void ScriptApiServer::getAuthHandler()
{
lua_State *L = getStack();
lua_getglobal(L, "minetest");
lua_getfield(L, -1, "registered_auth_handler");
if(lua_isnil(L, -1)){
lua_pop(L, 1);
lua_getfield(L, -1, "builtin_auth_handler");
}
if(lua_type(L, -1) != LUA_TTABLE)
throw LuaError(L, "Authentication handler table not valid");
}
void ScriptApiServer::readPrivileges(int index, std::set<std::string> &result)
{
lua_State *L = getStack();
result.clear();
lua_pushnil(L);
if(index < 0)
index -= 1;
while(lua_next(L, index) != 0){
// key at index -2 and value at index -1
std::string key = luaL_checkstring(L, -2);
bool value = lua_toboolean(L, -1);
if(value)
result.insert(key);
// removes value, keeps key for next iteration
lua_pop(L, 1);
}
}
void ScriptApiServer::createAuth(const std::string &playername,
const std::string &password)
{
SCRIPTAPI_PRECHECKHEADER
getAuthHandler();
lua_getfield(L, -1, "create_auth");
if(lua_type(L, -1) != LUA_TFUNCTION)
throw LuaError(L, "Authentication handler missing create_auth");
lua_pushstring(L, playername.c_str());
lua_pushstring(L, password.c_str());
if(lua_pcall(L, 2, 0, 0))
scriptError("error: %s", lua_tostring(L, -1));
}
bool ScriptApiServer::setPassword(const std::string &playername,
const std::string &password)
{
SCRIPTAPI_PRECHECKHEADER
getAuthHandler();
lua_getfield(L, -1, "set_password");
if(lua_type(L, -1) != LUA_TFUNCTION)
throw LuaError(L, "Authentication handler missing set_password");
lua_pushstring(L, playername.c_str());
lua_pushstring(L, password.c_str());
if(lua_pcall(L, 2, 1, 0))
scriptError("error: %s", lua_tostring(L, -1));
return lua_toboolean(L, -1);
}
bool ScriptApiServer::on_chat_message(const std::string &name,
const std::string &message)
{
SCRIPTAPI_PRECHECKHEADER
// Get minetest.registered_on_chat_messages
lua_getglobal(L, "minetest");
lua_getfield(L, -1, "registered_on_chat_messages");
// Call callbacks
lua_pushstring(L, name.c_str());
lua_pushstring(L, message.c_str());
script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_OR_SC);
bool ate = lua_toboolean(L, -1);
return ate;
}
void ScriptApiServer::on_shutdown()
{
SCRIPTAPI_PRECHECKHEADER
// Get registered shutdown hooks
lua_getglobal(L, "minetest");
lua_getfield(L, -1, "registered_on_shutdown");
// Call callbacks
script_run_callbacks(L, 0, RUN_CALLBACKS_MODE_FIRST);
}

@ -0,0 +1,52 @@
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef S_SERVER_H_
#define S_SERVER_H_
#include "cpp_api/s_base.h"
#include <set>
class ScriptApiServer
: virtual public ScriptApiBase
{
public:
// Calls on_chat_message handlers
// Returns true if script handled message
bool on_chat_message(const std::string &name, const std::string &message);
// Calls on_shutdown handlers
void on_shutdown();
/* auth */
bool getAuth(const std::string &playername,
std::string *dst_password,
std::set<std::string> *dst_privs);
void createAuth(const std::string &playername,
const std::string &password);
bool setPassword(const std::string &playername,
const std::string &password);
private:
void getAuthHandler();
void readPrivileges(int index, std::set<std::string> &result);
};
#endif /* S_SERVER_H_ */

@ -1,291 +0,0 @@
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
#include "scriptapi.h"
#include "common/c_converter.h"
#include "lua_api/l_base.h"
#include "log.h"
#include "mods.h"
int script_ErrorHandler(lua_State *L) {
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
return 1;
}
lua_getfield(L, -1, "traceback");
if (!lua_isfunction(L, -1)) {
lua_pop(L, 2);
return 1;
}
lua_pushvalue(L, 1);
lua_pushinteger(L, 2);
lua_call(L, 2, 1);
return 1;
}
bool ScriptApi::getAuth(const std::string &playername,
std::string *dst_password, std::set<std::string> *dst_privs)
{
SCRIPTAPI_PRECHECKHEADER
getAuthHandler();
lua_getfield(L, -1, "get_auth");
if(lua_type(L, -1) != LUA_TFUNCTION)
throw LuaError(L, "Authentication handler missing get_auth");
lua_pushstring(L, playername.c_str());
if(lua_pcall(L, 1, 1, 0))
scriptError("error: %s", lua_tostring(L, -1));
// nil = login not allowed
if(lua_isnil(L, -1))
return false;
luaL_checktype(L, -1, LUA_TTABLE);
std::string password;
bool found = getstringfield(L, -1, "password", password);
if(!found)
throw LuaError(L, "Authentication handler didn't return password");
if(dst_password)
*dst_password = password;
lua_getfield(L, -1, "privileges");
if(!lua_istable(L, -1))
throw LuaError(L,
"Authentication handler didn't return privilege table");
if(dst_privs)
readPrivileges(-1, *dst_privs);
lua_pop(L, 1);
return true;
}
void ScriptApi::getAuthHandler()
{
lua_State *L = getStack();
lua_getglobal(L, "minetest");
lua_getfield(L, -1, "registered_auth_handler");
if(lua_isnil(L, -1)){
lua_pop(L, 1);
lua_getfield(L, -1, "builtin_auth_handler");
}
if(lua_type(L, -1) != LUA_TTABLE)
throw LuaError(L, "Authentication handler table not valid");
}
void ScriptApi::readPrivileges(int index,std::set<std::string> &result)
{
lua_State *L = getStack();
result.clear();
lua_pushnil(L);
if(index < 0)
index -= 1;
while(lua_next(L, index) != 0){
// key at index -2 and value at index -1
std::string key = luaL_checkstring(L, -2);
bool value = lua_toboolean(L, -1);
if(value)
result.insert(key);
// removes value, keeps key for next iteration
lua_pop(L, 1);
}
}
void ScriptApi::createAuth(const std::string &playername,
const std::string &password)
{
SCRIPTAPI_PRECHECKHEADER
getAuthHandler();
lua_getfield(L, -1, "create_auth");
if(lua_type(L, -1) != LUA_TFUNCTION)
throw LuaError(L, "Authentication handler missing create_auth");
lua_pushstring(L, playername.c_str());
lua_pushstring(L, password.c_str());
if(lua_pcall(L, 2, 0, 0))
scriptError("error: %s", lua_tostring(L, -1));
}
bool ScriptApi::setPassword(const std::string &playername,
const std::string &password)
{
SCRIPTAPI_PRECHECKHEADER
getAuthHandler();
lua_getfield(L, -1, "set_password");
if(lua_type(L, -1) != LUA_TFUNCTION)
throw LuaError(L, "Authentication handler missing set_password");
lua_pushstring(L, playername.c_str());
lua_pushstring(L, password.c_str());
if(lua_pcall(L, 2, 1, 0))
scriptError("error: %s", lua_tostring(L, -1));
return lua_toboolean(L, -1);
}
bool ScriptApi::on_chat_message(const std::string &name,
const std::string &message)
{
SCRIPTAPI_PRECHECKHEADER
// Get minetest.registered_on_chat_messages
lua_getglobal(L, "minetest");
lua_getfield(L, -1, "registered_on_chat_messages");
// Call callbacks
lua_pushstring(L, name.c_str());
lua_pushstring(L, message.c_str());
runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC);
bool ate = lua_toboolean(L, -1);
return ate;
}
void ScriptApi::on_shutdown()
{
SCRIPTAPI_PRECHECKHEADER
// Get registered shutdown hooks
lua_getglobal(L, "minetest");
lua_getfield(L, -1, "registered_on_shutdown");
// Call callbacks
runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
}
bool ScriptApi::loadMod(const std::string &scriptpath,const std::string &modname)
{
ModNameStorer modnamestorer(getStack(), modname);
if(!string_allowed(modname, MODNAME_ALLOWED_CHARS)){
errorstream<<"Error loading mod \""<<modname
<<"\": modname does not follow naming conventions: "
<<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
return false;
}
bool success = false;
try{
success = scriptLoad(scriptpath.c_str());
}
catch(LuaError &e){
errorstream<<"Error loading mod \""<<modname
<<"\": "<<e.what()<<std::endl;
}
return success;
}
ScriptApi::ScriptApi() {
assert("Invalid call to default constructor of scriptapi!" == 0);
}
ScriptApi::ScriptApi(Server* server)
{
setServer(server);
setStack(luaL_newstate());
assert(getStack());
//TODO add security
luaL_openlibs(getStack());
SCRIPTAPI_PRECHECKHEADER
lua_pushlightuserdata(L, this);
lua_setfield(L, LUA_REGISTRYINDEX, "scriptapi");
lua_newtable(L);
lua_setglobal(L, "minetest");
for (std::vector<ModApiBase*>::iterator i = m_mod_api_modules->begin();
i != m_mod_api_modules->end(); i++) {
//initializers are called within minetest global table!
lua_getglobal(L, "minetest");
int top = lua_gettop(L);
bool ModInitializedSuccessfull = (*i)->Initialize(L,top);
assert(ModInitializedSuccessfull);
}
infostream << "SCRIPTAPI: initialized " << m_mod_api_modules->size()
<< " modules" << std::endl;
// Get the main minetest table
lua_getglobal(L, "minetest");
// Add tables to minetest
lua_newtable(L);
lua_setfield(L, -2, "object_refs");
lua_newtable(L);
lua_setfield(L, -2, "luaentities");
}
ScriptApi::~ScriptApi() {
lua_close(getStack());
}
bool ScriptApi::scriptLoad(const char *path)
{
lua_State* L = getStack();
setStack(0);
verbosestream<<"Loading and running script from "<<path<<std::endl;
lua_pushcfunction(L, script_ErrorHandler);
int errorhandler = lua_gettop(L);
int ret = luaL_loadfile(L, path) || lua_pcall(L, 0, 0, errorhandler);
if(ret){
errorstream<<"========== ERROR FROM LUA ==========="<<std::endl;
errorstream<<"Failed to load and run script from "<<std::endl;
errorstream<<path<<":"<<std::endl;
errorstream<<std::endl;
errorstream<<lua_tostring(L, -1)<<std::endl;
errorstream<<std::endl;
errorstream<<"=======END OF ERROR FROM LUA ========"<<std::endl;
lua_pop(L, 1); // Pop error message from stack
lua_pop(L, 1); // Pop the error handler from stack
return false;
}
lua_pop(L, 1); // Pop the error handler from stack
return true;
}
bool ScriptApi::registerModApiModule(ModApiBase* ptr) {
if (ScriptApi::m_mod_api_modules == 0)
ScriptApi::m_mod_api_modules = new std::vector<ModApiBase*>();
assert(ScriptApi::m_mod_api_modules != 0);
ScriptApi::m_mod_api_modules->push_back(ptr);
return true;
}
std::vector<ModApiBase*>* ScriptApi::m_mod_api_modules = 0;

@ -1,14 +1,23 @@
set(SCRIPT_LUA_API_SRCS # Used by server and client
set(common_SCRIPT_LUA_API_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/l_base.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_base.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_craft.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_craft.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_env.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_env.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_inventory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_inventory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_item.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_nodemeta.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_nodetimer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_nodetimer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_noise.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_noise.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_object.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_object.cpp
${CMAKE_CURRENT_SOURCE_DIR}/l_particles.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 ${CMAKE_CURRENT_SOURCE_DIR}/l_vmanip.cpp
PARENT_SCOPE) PARENT_SCOPE)
# Used by client only
set(minetest_SCRIPT_LUA_API_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/l_mainmenu.cpp
PARENT_SCOPE)

@ -17,32 +17,35 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 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_base.h"
#include "common/c_internal.h" #include "lua_api/l_internal.h"
#include "log.h" #include "cpp_api/s_base.h"
extern "C" { ScriptApiBase* ModApiBase::getScriptApiBase(lua_State *L) {
#include "lua.h" // 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() { Server* ModApiBase::getServer(lua_State *L) {
ScriptApi::registerModApiModule(this); return getScriptApiBase(L)->getServer();
} }
Server* ModApiBase::getServer(lua_State* L) { Environment* ModApiBase::getEnv(lua_State *L) {
return get_scriptapi(L)->getServer(); return getScriptApiBase(L)->getEnv();
} }
Environment* ModApiBase::getEnv(lua_State* L) { GUIEngine* ModApiBase::getGuiEngine(lua_State *L) {
return get_scriptapi(L)->getEnv(); return getScriptApiBase(L)->getGuiEngine();
} }
bool ModApiBase::registerFunction( lua_State* L, bool ModApiBase::registerFunction(lua_State *L,
const char* name, const char *name,
lua_CFunction fct, lua_CFunction fct,
int top int top
) { ) {
//TODO check presence first! //TODO check presence first!
lua_pushstring(L,name); lua_pushstring(L,name);
@ -51,13 +54,3 @@ bool ModApiBase::registerFunction( lua_State* L,
return true; 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},
};

@ -20,44 +20,43 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef L_BASE_H_ #ifndef L_BASE_H_
#define L_BASE_H_ #define L_BASE_H_
#include "biome.h"
#include "common/c_types.h" #include "common/c_types.h"
extern "C" { extern "C" {
#include "lua.h" #include <lua.h>
#include <lauxlib.h>
} }
extern struct EnumString es_BiomeTerrainType[]; class ScriptApiBase;
class ScriptApi;
class Server; class Server;
class Environment; class Environment;
class GUIEngine;
typedef class ModApiBase { class ModApiBase {
public:
ModApiBase();
virtual bool Initialize(lua_State* L, int top) = 0;
virtual ~ModApiBase() {};
protected: protected:
static Server* getServer( lua_State* L); static ScriptApiBase* getScriptApiBase(lua_State *L);
static Environment* getEnv( lua_State* L); static Server* getServer(lua_State *L);
static bool registerFunction( lua_State* L, static Environment* getEnv(lua_State *L);
const char* name, static GUIEngine* getGuiEngine(lua_State *L);
lua_CFunction fct,
int top
);
} ModApiBase;
#if (defined(WIN32) || defined(_WIN32_WCE)) // Get an arbitrary subclass of ScriptApiBase
#define NO_MAP_LOCK_REQUIRED // by using dynamic_cast<> on getScriptApiBase()
#else template<typename T>
#include "main.h" static T* getScriptApi(lua_State *L) {
#include "profiler.h" ScriptApiBase *scriptIface = getScriptApiBase(L);
#define NO_MAP_LOCK_REQUIRED ScopeProfiler nolocktime(g_profiler,"Scriptapi: unlockable time",SPT_ADD) T *scriptIfaceDowncast = dynamic_cast<T*>(scriptIface);
//#define NO_ENVLOCK_REQUIRED assert(getServer(L).m_env_mutex.IsLocked() == false) if (!scriptIfaceDowncast) {
#endif 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_ */ #endif /* L_BASE_H_ */

@ -19,20 +19,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_craft.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_converter.h"
#include "common/c_content.h" #include "common/c_content.h"
#include "server.h" #include "server.h"
#include "lua_api/l_item.h" #include "craftdef.h"
extern "C" {
#include "lauxlib.h"
}
ModApiCraft::ModApiCraft()
: ModApiBase() {
}
struct EnumString ModApiCraft::es_CraftMethod[] = struct EnumString ModApiCraft::es_CraftMethod[] =
{ {
@ -463,15 +455,10 @@ int ModApiCraft::l_get_all_craft_recipes(lua_State *L)
return 1; return 1;
} }
bool ModApiCraft::Initialize(lua_State* L, int top) { void ModApiCraft::Initialize(lua_State *L, int top)
bool retval = true; {
API_FCT(get_all_craft_recipes);
retval &= API_FCT(get_all_craft_recipes); API_FCT(get_craft_recipe);
retval &= API_FCT(get_craft_recipe); API_FCT(get_craft_result);
retval &= API_FCT(get_craft_result); API_FCT(register_craft);
retval &= API_FCT(register_craft);
return retval;
} }
ModApiCraft modapicraft_prototype;

@ -20,19 +20,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef L_CRAFT_H_ #ifndef L_CRAFT_H_
#define L_CRAFT_H_ #define L_CRAFT_H_
#include <string>
#include <vector> #include <vector>
extern "C" {
#include <lua.h>
}
#include "lua_api/l_base.h" #include "lua_api/l_base.h"
#include "craftdef.h"
struct CraftReplacements;
class ModApiCraft : public ModApiBase { class ModApiCraft : public ModApiBase {
public:
ModApiCraft();
bool Initialize(lua_State* L, int top);
private: private:
static int l_register_craft(lua_State *L); static int l_register_craft(lua_State *L);
static int l_get_craft_recipe(lua_State *L); static int l_get_craft_recipe(lua_State *L);
@ -47,6 +42,9 @@ private:
int &width, std::vector<std::string> &recipe); int &width, std::vector<std::string> &recipe);
static struct EnumString es_CraftMethod[]; static struct EnumString es_CraftMethod[];
public:
static void Initialize(lua_State *L, int top);
}; };
#endif /* L_CRAFT_H_ */ #endif /* L_CRAFT_H_ */

Some files were not shown because too many files have changed in this diff Show More