forked from Mirrorlandia_minetest/minetest
Omnicleanup: header cleanup, add ModApiUtil shared between game and mainmenu
This commit is contained in:
parent
6228d634fb
commit
4e1f50035e
@ -1,3 +1,5 @@
|
||||
print = engine.debug
|
||||
math.randomseed(os.time())
|
||||
os.setlocale("C", "numeric")
|
||||
|
||||
local scriptpath = engine.get_scriptdir()
|
||||
@ -9,6 +11,7 @@ mt_color_dark_green = "#003300"
|
||||
|
||||
--for all other colors ask sfan5 to complete his worK!
|
||||
|
||||
dofile(scriptpath .. DIR_DELIM .. "misc_helpers.lua")
|
||||
dofile(scriptpath .. DIR_DELIM .. "filterlist.lua")
|
||||
dofile(scriptpath .. DIR_DELIM .. "modmgr.lua")
|
||||
dofile(scriptpath .. DIR_DELIM .. "modstore.lua")
|
||||
|
@ -1167,6 +1167,7 @@ minetest.register_authentication_handler(handler)
|
||||
Setting-related:
|
||||
minetest.setting_set(name, value)
|
||||
minetest.setting_get(name) -> string or nil
|
||||
minetest.setting_setbool(name, value)
|
||||
minetest.setting_getbool(name) -> boolean value or nil
|
||||
minetest.setting_get_pos(name) -> position or nil
|
||||
minetest.setting_save() -> nil, save all settings to config file
|
||||
|
@ -127,11 +127,19 @@ engine.get_favorites(location) -> list of favorites
|
||||
}
|
||||
engine.delete_favorite(id, location) -> success
|
||||
|
||||
Logging:
|
||||
engine.debug(line)
|
||||
^ Always printed to stderr and logfile (print() is redirected here)
|
||||
engine.log(line)
|
||||
engine.log(loglevel, line)
|
||||
^ loglevel one of "error", "action", "info", "verbose"
|
||||
|
||||
Settings:
|
||||
engine.setting_set(name, value)
|
||||
engine.setting_get(name) -> string or nil
|
||||
engine.setting_setbool(name, value)
|
||||
engine.setting_getbool(name) -> bool or nil
|
||||
engine.setting_save() -> nil, save all settings to config file
|
||||
|
||||
Worlds:
|
||||
engine.get_worlds() -> list of worlds
|
||||
|
@ -383,6 +383,7 @@
|
||||
# to IPv6 clients, depending on system configuration.
|
||||
#ipv6_server = false
|
||||
|
||||
#main_menu_script =
|
||||
#main_menu_game_mgr = 0
|
||||
#main_menu_mod_mgr = 1
|
||||
#modstore_download_url = https://forum.minetest.net/media/
|
||||
|
@ -267,12 +267,11 @@ set(common_SRCS
|
||||
base64.cpp
|
||||
ban.cpp
|
||||
biome.cpp
|
||||
clientserver.cpp
|
||||
staticobject.cpp
|
||||
serverlist.cpp
|
||||
pathfinder.cpp
|
||||
convert_json.cpp
|
||||
${SCRIPT_SRCS}
|
||||
${common_SCRIPT_SRCS}
|
||||
${UTIL_SRCS}
|
||||
)
|
||||
|
||||
@ -329,9 +328,9 @@ set(minetest_SRCS
|
||||
game.cpp
|
||||
main.cpp
|
||||
guiEngine.cpp
|
||||
guiLuaApi.cpp
|
||||
guiFileSelectMenu.cpp
|
||||
convert_json.cpp
|
||||
${minetest_SCRIPT_SRCS}
|
||||
)
|
||||
|
||||
if(USE_FREETYPE)
|
||||
@ -341,11 +340,14 @@ if(USE_FREETYPE)
|
||||
)
|
||||
endif(USE_FREETYPE)
|
||||
|
||||
list(SORT minetest_SRCS)
|
||||
|
||||
# Server sources
|
||||
set(minetestserver_SRCS
|
||||
${common_SRCS}
|
||||
main.cpp
|
||||
)
|
||||
list(SORT minetestserver_SRCS)
|
||||
|
||||
include_directories(
|
||||
${PROJECT_BINARY_DIR}
|
||||
|
@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef ACTIVEOBJECT_HEADER
|
||||
#define ACTIVEOBJECT_HEADER
|
||||
|
||||
#include "irrlichttypes_bloated.h"
|
||||
#include "irr_aabb3d.h"
|
||||
#include <string>
|
||||
|
||||
#define ACTIVEOBJECT_TYPE_INVALID 0
|
||||
|
@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
#include "strfnd.h"
|
||||
#include "util/string.h"
|
||||
#include "log.h"
|
||||
#include "filesys.h"
|
||||
|
||||
|
@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#include "chat.h"
|
||||
#include "debug.h"
|
||||
#include <cassert>
|
||||
#include "strfnd.h"
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
#include "util/string.h"
|
||||
|
@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef CHAT_HEADER
|
||||
#define CHAT_HEADER
|
||||
|
||||
#include "irrlichttypes_bloated.h"
|
||||
#include "irrlichttypes.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "jmutexautolock.h"
|
||||
#include "main.h"
|
||||
#include <sstream>
|
||||
#include "filesys.h"
|
||||
#include "porting.h"
|
||||
#include "mapsector.h"
|
||||
#include "mapblock_mesh.h"
|
||||
@ -1356,8 +1357,6 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||
std::istringstream is(datastring, std::ios_base::binary);
|
||||
//t3.stop();
|
||||
|
||||
//m_env.printPlayers(infostream);
|
||||
|
||||
//TimeTaker t4("player get", m_device);
|
||||
Player *player = m_env.getLocalPlayer();
|
||||
assert(player != NULL);
|
||||
|
55
src/client.h
55
src/client.h
@ -25,12 +25,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "irrlichttypes_extrabloated.h"
|
||||
#include "jmutex.h"
|
||||
#include <ostream>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include "clientobject.h"
|
||||
#include "gamedef.h"
|
||||
#include "inventorymanager.h"
|
||||
#include "filesys.h"
|
||||
#include "filecache.h"
|
||||
#include "localplayer.h"
|
||||
#include "server.h"
|
||||
@ -246,6 +246,57 @@ struct ClientEvent
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
Packet counter
|
||||
*/
|
||||
|
||||
class PacketCounter
|
||||
{
|
||||
public:
|
||||
PacketCounter()
|
||||
{
|
||||
}
|
||||
|
||||
void add(u16 command)
|
||||
{
|
||||
std::map<u16, u16>::iterator n = m_packets.find(command);
|
||||
if(n == m_packets.end())
|
||||
{
|
||||
m_packets[command] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
n->second++;
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
for(std::map<u16, u16>::iterator
|
||||
i = m_packets.begin();
|
||||
i != m_packets.end(); ++i)
|
||||
{
|
||||
i->second = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void print(std::ostream &o)
|
||||
{
|
||||
for(std::map<u16, u16>::iterator
|
||||
i = m_packets.begin();
|
||||
i != m_packets.end(); ++i)
|
||||
{
|
||||
o<<"cmd "<<i->first
|
||||
<<" count "<<i->second
|
||||
<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// command, count
|
||||
std::map<u16, u16> m_packets;
|
||||
};
|
||||
|
||||
class Client : public con::PeerHandler, public InventoryManager, public IGameDef
|
||||
{
|
||||
public:
|
||||
@ -419,8 +470,6 @@ private:
|
||||
void Receive();
|
||||
|
||||
void sendPlayerPos();
|
||||
// This sends the player's current name etc to the server
|
||||
void sendPlayerInfo();
|
||||
// Send the item number 'item' as player item to the server
|
||||
void sendPlayerItem(u16 item);
|
||||
|
||||
|
@ -20,10 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef CLIENTSERVER_HEADER
|
||||
#define CLIENTSERVER_HEADER
|
||||
|
||||
#include "util/pointer.h"
|
||||
|
||||
SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time, float time_speed);
|
||||
|
||||
/*
|
||||
changes by PROTOCOL_VERSION:
|
||||
|
||||
|
@ -191,15 +191,14 @@ TODO: Should we have a receiver_peer_id also?
|
||||
[6] u8 channel
|
||||
sender_peer_id:
|
||||
Unique to each peer.
|
||||
value 0 is reserved for making new connections
|
||||
value 1 is reserved for server
|
||||
value 0 (PEER_ID_INEXISTENT) is reserved for making new connections
|
||||
value 1 (PEER_ID_SERVER) is reserved for server
|
||||
these constants are defined in constants.h
|
||||
channel:
|
||||
The lower the number, the higher the priority is.
|
||||
Only channels 0, 1 and 2 exist.
|
||||
*/
|
||||
#define BASE_HEADER_SIZE 7
|
||||
#define PEER_ID_INEXISTENT 0
|
||||
#define PEER_ID_SERVER 1
|
||||
#define CHANNEL_COUNT 3
|
||||
/*
|
||||
Packet types:
|
||||
|
@ -32,6 +32,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
Connection
|
||||
*/
|
||||
|
||||
#define PEER_ID_INEXISTENT 0
|
||||
#define PEER_ID_SERVER 1
|
||||
|
||||
// Define for simulating the quirks of sending through internet.
|
||||
// Causes the socket class to deliberately drop random packets.
|
||||
// This disables unit testing of socket and connection.
|
||||
@ -83,12 +86,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// Size of player's main inventory
|
||||
#define PLAYER_INVENTORY_SIZE (8*4)
|
||||
|
||||
/*
|
||||
This is good to be a bit different than 0 so that water level is not
|
||||
between two MapBlocks
|
||||
*/
|
||||
#define WATER_LEVEL 1
|
||||
|
||||
// Maximum hit points of a player
|
||||
#define PLAYER_MAX_HP 20
|
||||
|
||||
|
@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "treegen.h" // For treegen::make_tree
|
||||
#include "main.h" // for g_settings
|
||||
#include "map.h"
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "scripting_game.h"
|
||||
#include "log.h"
|
||||
|
||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||
|
@ -18,8 +18,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
|
||||
#include "content_nodemeta.h"
|
||||
#include "nodemetadata.h"
|
||||
#include "nodetimer.h"
|
||||
#include "inventory.h"
|
||||
#include "log.h"
|
||||
#include "serialization.h"
|
||||
#include "util/serialize.h"
|
||||
#include "util/string.h"
|
||||
#include "constants.h" // MAP_BLOCKSIZE
|
||||
|
@ -20,8 +20,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef CONTENT_NODEMETA_HEADER
|
||||
#define CONTENT_NODEMETA_HEADER
|
||||
|
||||
#include "nodemetadata.h"
|
||||
#include "nodetimer.h"
|
||||
#include <iostream>
|
||||
|
||||
class NodeMetadataList;
|
||||
class NodeTimerList;
|
||||
class IGameDef;
|
||||
|
||||
/*
|
||||
Legacy nodemeta definitions
|
||||
|
@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "tool.h" // For ToolCapabilities
|
||||
#include "gamedef.h"
|
||||
#include "player.h"
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "scripting_game.h"
|
||||
#include "genericobject.h"
|
||||
#include "util/serialize.h"
|
||||
#include "util/mathconstants.h"
|
||||
@ -399,7 +399,7 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
|
||||
LuaEntitySAO::~LuaEntitySAO()
|
||||
{
|
||||
if(m_registered){
|
||||
ENV_TO_SA(m_env)->luaentity_Remove(m_id);
|
||||
m_env->getScriptIface()->luaentity_Remove(m_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,15 +408,18 @@ void LuaEntitySAO::addedToEnvironment(u32 dtime_s)
|
||||
ServerActiveObject::addedToEnvironment(dtime_s);
|
||||
|
||||
// Create entity from name
|
||||
m_registered = ENV_TO_SA(m_env)->luaentity_Add(m_id, m_init_name.c_str());
|
||||
m_registered = m_env->getScriptIface()->
|
||||
luaentity_Add(m_id, m_init_name.c_str());
|
||||
|
||||
if(m_registered){
|
||||
// Get properties
|
||||
ENV_TO_SA(m_env)->luaentity_GetProperties(m_id, &m_prop);
|
||||
m_env->getScriptIface()->
|
||||
luaentity_GetProperties(m_id, &m_prop);
|
||||
// Initialize HP from properties
|
||||
m_hp = m_prop.hp_max;
|
||||
// Activate entity, supplying serialized state
|
||||
ENV_TO_SA(m_env)->luaentity_Activate(m_id, m_init_state.c_str(), dtime_s);
|
||||
m_env->getScriptIface()->
|
||||
luaentity_Activate(m_id, m_init_state.c_str(), dtime_s);
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,7 +533,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
||||
}
|
||||
|
||||
if(m_registered){
|
||||
ENV_TO_SA(m_env)->luaentity_Step(m_id, dtime);
|
||||
m_env->getScriptIface()->luaentity_Step(m_id, dtime);
|
||||
}
|
||||
|
||||
if(send_recommended == false)
|
||||
@ -640,7 +643,8 @@ std::string LuaEntitySAO::getStaticData()
|
||||
os<<serializeString(m_init_name);
|
||||
// state
|
||||
if(m_registered){
|
||||
std::string state = ENV_TO_SA(m_env)->luaentity_GetStaticdata(m_id);
|
||||
std::string state = m_env->getScriptIface()->
|
||||
luaentity_GetStaticdata(m_id);
|
||||
os<<serializeLongString(state);
|
||||
} else {
|
||||
os<<serializeLongString(m_init_state);
|
||||
@ -707,7 +711,7 @@ int LuaEntitySAO::punch(v3f dir,
|
||||
m_removed = true;
|
||||
}
|
||||
|
||||
ENV_TO_SA(m_env)->luaentity_Punch(m_id, puncher,
|
||||
m_env->getScriptIface()->luaentity_Punch(m_id, puncher,
|
||||
time_from_last_punch, toolcap, dir);
|
||||
|
||||
return result.wear;
|
||||
@ -720,7 +724,7 @@ void LuaEntitySAO::rightClick(ServerActiveObject *clicker)
|
||||
// It's best that attachments cannot be clicked
|
||||
if(isAttached())
|
||||
return;
|
||||
ENV_TO_SA(m_env)->luaentity_Rightclick(m_id, clicker);
|
||||
m_env->getScriptIface()->luaentity_Rightclick(m_id, clicker);
|
||||
}
|
||||
|
||||
void LuaEntitySAO::setPos(v3f pos)
|
||||
|
@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "inventory.h"
|
||||
#include "util/serialize.h"
|
||||
#include "strfnd.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
// Check if input matches recipe
|
||||
// Takes recipe groups into account
|
||||
@ -150,23 +151,6 @@ static bool craftGetBounds(const std::vector<std::string> &items, unsigned int w
|
||||
return success;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// This became useless when group support was added to shapeless recipes
|
||||
// Convert a list of item names to a multiset
|
||||
static std::multiset<std::string> craftMakeMultiset(const std::vector<std::string> &names)
|
||||
{
|
||||
std::multiset<std::string> set;
|
||||
for(std::vector<std::string>::const_iterator
|
||||
i = names.begin();
|
||||
i != names.end(); i++)
|
||||
{
|
||||
if(*i != "")
|
||||
set.insert(*i);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Removes 1 from each item stack
|
||||
static void craftDecrementInput(CraftInput &input, IGameDef *gamedef)
|
||||
{
|
||||
|
@ -19,16 +19,34 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
|
||||
#include "debug.h"
|
||||
#include "exceptions.h"
|
||||
#include "threads.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <jmutex.h>
|
||||
#include <jmutexautolock.h>
|
||||
|
||||
/*
|
||||
Debug output
|
||||
*/
|
||||
|
||||
#define DEBUGSTREAM_COUNT 2
|
||||
|
||||
FILE *g_debugstreams[DEBUGSTREAM_COUNT] = {stderr, NULL};
|
||||
|
||||
#define DEBUGPRINT(...)\
|
||||
{\
|
||||
for(int i=0; i<DEBUGSTREAM_COUNT; i++)\
|
||||
{\
|
||||
if(g_debugstreams[i] != NULL){\
|
||||
fprintf(g_debugstreams[i], __VA_ARGS__);\
|
||||
fflush(g_debugstreams[i]);\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
void debugstreams_init(bool disable_stderr, const char *filename)
|
||||
{
|
||||
if(disable_stderr)
|
||||
@ -53,6 +71,47 @@ void debugstreams_deinit()
|
||||
fclose(g_debugstreams[1]);
|
||||
}
|
||||
|
||||
class Debugbuf : public std::streambuf
|
||||
{
|
||||
public:
|
||||
Debugbuf(bool disable_stderr)
|
||||
{
|
||||
m_disable_stderr = disable_stderr;
|
||||
}
|
||||
|
||||
int overflow(int c)
|
||||
{
|
||||
for(int i=0; i<DEBUGSTREAM_COUNT; i++)
|
||||
{
|
||||
if(g_debugstreams[i] == stderr && m_disable_stderr)
|
||||
continue;
|
||||
if(g_debugstreams[i] != NULL)
|
||||
(void)fwrite(&c, 1, 1, g_debugstreams[i]);
|
||||
//TODO: Is this slow?
|
||||
fflush(g_debugstreams[i]);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
std::streamsize xsputn(const char *s, std::streamsize n)
|
||||
{
|
||||
for(int i=0; i<DEBUGSTREAM_COUNT; i++)
|
||||
{
|
||||
if(g_debugstreams[i] == stderr && m_disable_stderr)
|
||||
continue;
|
||||
if(g_debugstreams[i] != NULL)
|
||||
(void)fwrite(s, 1, n, g_debugstreams[i]);
|
||||
//TODO: Is this slow?
|
||||
fflush(g_debugstreams[i]);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_disable_stderr;
|
||||
};
|
||||
|
||||
Debugbuf debugbuf(false);
|
||||
std::ostream dstream(&debugbuf);
|
||||
Debugbuf debugbuf_no_stderr(true);
|
||||
@ -83,6 +142,18 @@ void assert_fail(const char *assertion, const char *file,
|
||||
DebugStack
|
||||
*/
|
||||
|
||||
struct DebugStack
|
||||
{
|
||||
DebugStack(threadid_t id);
|
||||
void print(FILE *file, bool everything);
|
||||
void print(std::ostream &os, bool everything);
|
||||
|
||||
threadid_t threadid;
|
||||
char stack[DEBUG_STACK_SIZE][DEBUG_STACK_TEXT_SIZE];
|
||||
int stack_i; // Points to the lowest empty position
|
||||
int stack_max_i; // Highest i that was seen
|
||||
};
|
||||
|
||||
DebugStack::DebugStack(threadid_t id)
|
||||
{
|
||||
threadid = id;
|
||||
|
147
src/debug.h
147
src/debug.h
@ -20,18 +20,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef DEBUG_HEADER
|
||||
#define DEBUG_HEADER
|
||||
|
||||
#include <stdio.h>
|
||||
#include <jmutex.h>
|
||||
#include <jmutexautolock.h>
|
||||
#include <iostream>
|
||||
#include "irrlichttypes.h"
|
||||
#include <irrMap.h>
|
||||
#include "threads.h"
|
||||
#include <exception>
|
||||
#include "gettime.h"
|
||||
#include "exceptions.h"
|
||||
#include <map>
|
||||
|
||||
#ifdef _WIN32
|
||||
#if (defined(WIN32) || defined(_WIN32_WCE))
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501
|
||||
@ -40,7 +33,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifdef _MSC_VER
|
||||
#include <eh.h>
|
||||
#endif
|
||||
#define __NORETURN __declspec(noreturn)
|
||||
#define __FUNCTION_NAME __FUNCTION__
|
||||
#else
|
||||
#define __NORETURN __attribute__ ((__noreturn__))
|
||||
#define __FUNCTION_NAME __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
// Whether to catch all std::exceptions.
|
||||
@ -58,65 +55,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#define DTIME (getTimestamp()+": ")
|
||||
|
||||
#define DEBUGSTREAM_COUNT 2
|
||||
|
||||
extern FILE *g_debugstreams[DEBUGSTREAM_COUNT];
|
||||
|
||||
extern void debugstreams_init(bool disable_stderr, const char *filename);
|
||||
extern void debugstreams_deinit();
|
||||
|
||||
#define DEBUGPRINT(...)\
|
||||
{\
|
||||
for(int i=0; i<DEBUGSTREAM_COUNT; i++)\
|
||||
{\
|
||||
if(g_debugstreams[i] != NULL){\
|
||||
fprintf(g_debugstreams[i], __VA_ARGS__);\
|
||||
fflush(g_debugstreams[i]);\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
class Debugbuf : public std::streambuf
|
||||
{
|
||||
public:
|
||||
Debugbuf(bool disable_stderr)
|
||||
{
|
||||
m_disable_stderr = disable_stderr;
|
||||
}
|
||||
|
||||
int overflow(int c)
|
||||
{
|
||||
for(int i=0; i<DEBUGSTREAM_COUNT; i++)
|
||||
{
|
||||
if(g_debugstreams[i] == stderr && m_disable_stderr)
|
||||
continue;
|
||||
if(g_debugstreams[i] != NULL)
|
||||
(void)fwrite(&c, 1, 1, g_debugstreams[i]);
|
||||
//TODO: Is this slow?
|
||||
fflush(g_debugstreams[i]);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
std::streamsize xsputn(const char *s, std::streamsize n)
|
||||
{
|
||||
for(int i=0; i<DEBUGSTREAM_COUNT; i++)
|
||||
{
|
||||
if(g_debugstreams[i] == stderr && m_disable_stderr)
|
||||
continue;
|
||||
if(g_debugstreams[i] != NULL)
|
||||
(void)fwrite(s, 1, n, g_debugstreams[i]);
|
||||
//TODO: Is this slow?
|
||||
fflush(g_debugstreams[i]);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_disable_stderr;
|
||||
};
|
||||
|
||||
// This is used to redirect output to /dev/null
|
||||
class Nullstream : public std::ostream {
|
||||
public:
|
||||
@ -127,7 +68,6 @@ public:
|
||||
private:
|
||||
};
|
||||
|
||||
extern Debugbuf debugbuf;
|
||||
extern std::ostream dstream;
|
||||
extern std::ostream dstream_no_stderr;
|
||||
extern Nullstream dummyout;
|
||||
@ -154,25 +94,11 @@ __NORETURN extern void assert_fail(
|
||||
#define DEBUG_STACK_SIZE 50
|
||||
#define DEBUG_STACK_TEXT_SIZE 300
|
||||
|
||||
struct DebugStack
|
||||
{
|
||||
DebugStack(threadid_t id);
|
||||
void print(FILE *file, bool everything);
|
||||
void print(std::ostream &os, bool everything);
|
||||
|
||||
threadid_t threadid;
|
||||
char stack[DEBUG_STACK_SIZE][DEBUG_STACK_TEXT_SIZE];
|
||||
int stack_i; // Points to the lowest empty position
|
||||
int stack_max_i; // Highest i that was seen
|
||||
};
|
||||
|
||||
extern std::map<threadid_t, DebugStack*> g_debug_stacks;
|
||||
extern JMutex g_debug_stacks_mutex;
|
||||
|
||||
extern void debug_stacks_init();
|
||||
extern void debug_stacks_print_to(std::ostream &os);
|
||||
extern void debug_stacks_print();
|
||||
|
||||
struct DebugStack;
|
||||
class DebugStacker
|
||||
{
|
||||
public:
|
||||
@ -193,57 +119,6 @@ private:
|
||||
DEBUG_STACK_TEXT_SIZE, __VA_ARGS__);\
|
||||
DebugStacker __debug_stacker(__buf);
|
||||
|
||||
/*
|
||||
Packet counter
|
||||
*/
|
||||
|
||||
class PacketCounter
|
||||
{
|
||||
public:
|
||||
PacketCounter()
|
||||
{
|
||||
}
|
||||
|
||||
void add(u16 command)
|
||||
{
|
||||
std::map<u16, u16>::iterator n = m_packets.find(command);
|
||||
if(n == m_packets.end())
|
||||
{
|
||||
m_packets[command] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
n->second++;
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
for(std::map<u16, u16>::iterator
|
||||
i = m_packets.begin();
|
||||
i != m_packets.end(); ++i)
|
||||
{
|
||||
i->second = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void print(std::ostream &o)
|
||||
{
|
||||
for(std::map<u16, u16>::iterator
|
||||
i = m_packets.begin();
|
||||
i != m_packets.end(); ++i)
|
||||
{
|
||||
o<<"cmd "<<i->first
|
||||
<<" count "<<i->second
|
||||
<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// command, count
|
||||
std::map<u16, u16> m_packets;
|
||||
};
|
||||
|
||||
/*
|
||||
These should be put into every thread
|
||||
*/
|
||||
@ -259,14 +134,6 @@ private:
|
||||
#ifdef _WIN32 // Windows
|
||||
#ifdef _MSC_VER // MSVC
|
||||
void se_trans_func(unsigned int, EXCEPTION_POINTERS*);
|
||||
|
||||
class FatalSystemException : public BaseException
|
||||
{
|
||||
public:
|
||||
FatalSystemException(const char *s):
|
||||
BaseException(s)
|
||||
{}
|
||||
};
|
||||
#define BEGIN_DEBUG_EXCEPTION_HANDLER \
|
||||
BEGIN_PORTABLE_DEBUG_EXCEPTION_HANDLER\
|
||||
_set_se_translator(se_trans_func);
|
||||
|
@ -273,6 +273,7 @@ void set_default_settings(Settings *settings)
|
||||
settings->setDefault("enable_ipv6", "true");
|
||||
settings->setDefault("ipv6_server", "false");
|
||||
|
||||
settings->setDefault("main_menu_script","");
|
||||
settings->setDefault("main_menu_mod_mgr","1");
|
||||
settings->setDefault("old_style_mod_selection","true");
|
||||
settings->setDefault("main_menu_game_mgr","0");
|
||||
|
@ -19,12 +19,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
|
||||
|
||||
#include "emerge.h"
|
||||
#include "server.h"
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include "clientserver.h"
|
||||
#include "map.h"
|
||||
#include "jmutexautolock.h"
|
||||
#include "environment.h"
|
||||
#include "util/container.h"
|
||||
#include "util/thread.h"
|
||||
#include "main.h"
|
||||
#include "constants.h"
|
||||
#include "voxel.h"
|
||||
@ -32,12 +34,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "mapblock.h"
|
||||
#include "serverobject.h"
|
||||
#include "settings.h"
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "scripting_game.h"
|
||||
#include "profiler.h"
|
||||
#include "log.h"
|
||||
#include "nodedef.h"
|
||||
#include "biome.h"
|
||||
#include "emerge.h"
|
||||
#include "mapgen_v6.h"
|
||||
#include "mapgen_v7.h"
|
||||
#include "mapgen_indev.h"
|
||||
@ -45,6 +46,46 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "mapgen_math.h"
|
||||
|
||||
|
||||
class EmergeThread : public SimpleThread
|
||||
{
|
||||
public:
|
||||
Server *m_server;
|
||||
ServerMap *map;
|
||||
EmergeManager *emerge;
|
||||
Mapgen *mapgen;
|
||||
bool enable_mapgen_debug_info;
|
||||
int id;
|
||||
|
||||
Event qevent;
|
||||
std::queue<v3s16> blockqueue;
|
||||
|
||||
EmergeThread(Server *server, int ethreadid):
|
||||
SimpleThread(),
|
||||
m_server(server),
|
||||
map(NULL),
|
||||
emerge(NULL),
|
||||
mapgen(NULL),
|
||||
id(ethreadid)
|
||||
{
|
||||
}
|
||||
|
||||
void *Thread();
|
||||
|
||||
void trigger()
|
||||
{
|
||||
setRun(true);
|
||||
if(IsRunning() == false)
|
||||
{
|
||||
Start();
|
||||
}
|
||||
}
|
||||
|
||||
bool popBlockEmerge(v3s16 *pos, u8 *flags);
|
||||
bool getBlockOrStartGen(v3s16 p, MapBlock **b,
|
||||
BlockMakeData *data, bool allow_generate);
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////// Emerge Manager ////////////////////////////////
|
||||
|
||||
EmergeManager::EmergeManager(IGameDef *gamedef) {
|
||||
@ -183,6 +224,11 @@ Mapgen *EmergeManager::getCurrentMapgen() {
|
||||
}
|
||||
|
||||
|
||||
void EmergeManager::triggerAllThreads() {
|
||||
for (unsigned int i = 0; i != emergethread.size(); i++)
|
||||
emergethread[i]->trigger();
|
||||
}
|
||||
|
||||
bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate) {
|
||||
std::map<v3s16, BlockEmergeData *>::const_iterator iter;
|
||||
BlockEmergeData *bedata;
|
||||
@ -466,7 +512,8 @@ void *EmergeThread::Thread() {
|
||||
ign(&m_server->m_ignore_map_edit_events_area,
|
||||
VoxelArea(minp, maxp));
|
||||
{ // takes about 90ms with -O1 on an e3-1230v2
|
||||
SERVER_TO_SA(m_server)->environment_OnGenerated(
|
||||
m_server->getScriptIface()->
|
||||
environment_OnGenerated(
|
||||
minp, maxp, emerge->getBlockSeed(minp));
|
||||
}
|
||||
|
||||
|
63
src/emerge.h
63
src/emerge.h
@ -21,8 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#define EMERGE_HEADER
|
||||
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include "util/thread.h"
|
||||
#include "irr_v3d.h"
|
||||
#include "util/container.h"
|
||||
#include "map.h" // for ManualMapVoxelManipulator
|
||||
|
||||
#define MGPARAMS_SET_MGNAME 1
|
||||
#define MGPARAMS_SET_SEED 2
|
||||
@ -35,15 +36,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
{ if (enable_mapgen_debug_info) \
|
||||
infostream << "EmergeThread: " x << std::endl; }
|
||||
|
||||
class EmergeThread;
|
||||
class Mapgen;
|
||||
struct MapgenParams;
|
||||
struct MapgenFactory;
|
||||
class Biome;
|
||||
class BiomeDefManager;
|
||||
class EmergeThread;
|
||||
class ManualMapVoxelManipulator;
|
||||
|
||||
#include "server.h"
|
||||
class Decoration;
|
||||
class Ore;
|
||||
class INodeDefManager;
|
||||
class Settings;
|
||||
|
||||
struct BlockMakeData {
|
||||
ManualMapVoxelManipulator *vmanip;
|
||||
@ -68,7 +70,14 @@ struct BlockEmergeData {
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
class EmergeManager {
|
||||
class IBackgroundBlockEmerger
|
||||
{
|
||||
public:
|
||||
virtual bool enqueueBlockEmerge(u16 peer_id, v3s16 p,
|
||||
bool allow_generate) = 0;
|
||||
};
|
||||
|
||||
class EmergeManager : public IBackgroundBlockEmerger {
|
||||
public:
|
||||
INodeDefManager *ndef;
|
||||
|
||||
@ -106,6 +115,7 @@ public:
|
||||
Mapgen *createMapgen(std::string mgname, int mgid,
|
||||
MapgenParams *mgparams);
|
||||
MapgenParams *createMapgenParams(std::string mgname);
|
||||
void triggerAllThreads();
|
||||
bool enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate);
|
||||
|
||||
void registerMapgen(std::string name, MapgenFactory *mgfactory);
|
||||
@ -119,43 +129,4 @@ public:
|
||||
u32 getBlockSeed(v3s16 p);
|
||||
};
|
||||
|
||||
class EmergeThread : public SimpleThread
|
||||
{
|
||||
public:
|
||||
Server *m_server;
|
||||
ServerMap *map;
|
||||
EmergeManager *emerge;
|
||||
Mapgen *mapgen;
|
||||
bool enable_mapgen_debug_info;
|
||||
int id;
|
||||
|
||||
Event qevent;
|
||||
std::queue<v3s16> blockqueue;
|
||||
|
||||
EmergeThread(Server *server, int ethreadid):
|
||||
SimpleThread(),
|
||||
m_server(server),
|
||||
map(NULL),
|
||||
emerge(NULL),
|
||||
mapgen(NULL),
|
||||
id(ethreadid)
|
||||
{
|
||||
}
|
||||
|
||||
void *Thread();
|
||||
|
||||
void trigger()
|
||||
{
|
||||
setRun(true);
|
||||
if(IsRunning() == false)
|
||||
{
|
||||
Start();
|
||||
}
|
||||
}
|
||||
|
||||
bool popBlockEmerge(v3s16 *pos, u8 *flags);
|
||||
bool getBlockOrStartGen(v3s16 p, MapBlock **b,
|
||||
BlockMakeData *data, bool allow_generate);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -17,9 +17,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include "environment.h"
|
||||
#include "filesys.h"
|
||||
#include "porting.h"
|
||||
@ -31,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "settings.h"
|
||||
#include "log.h"
|
||||
#include "profiler.h"
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "scripting_game.h"
|
||||
#include "nodedef.h"
|
||||
#include "nodemetadata.h"
|
||||
#include "main.h" // For g_settings, g_profiler
|
||||
@ -43,6 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#endif
|
||||
#include "daynightratio.h"
|
||||
#include "map.h"
|
||||
#include "emerge.h"
|
||||
#include "util/serialize.h"
|
||||
|
||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||
@ -190,17 +188,6 @@ std::list<Player*> Environment::getPlayers(bool ignore_disconnected)
|
||||
return newlist;
|
||||
}
|
||||
|
||||
void Environment::printPlayers(std::ostream &o)
|
||||
{
|
||||
o<<"Players in environment:"<<std::endl;
|
||||
for(std::list<Player*>::iterator i = m_players.begin();
|
||||
i != m_players.end(); i++)
|
||||
{
|
||||
Player *player = *i;
|
||||
o<<"Player peer_id="<<player->peer_id<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
u32 Environment::getDayNightRatio()
|
||||
{
|
||||
bool smooth = g_settings->getBool("enable_shaders");
|
||||
@ -320,7 +307,8 @@ void ActiveBlockList::update(std::list<v3s16> &active_positions,
|
||||
ServerEnvironment
|
||||
*/
|
||||
|
||||
ServerEnvironment::ServerEnvironment(ServerMap *map, ScriptApi *scriptIface,
|
||||
ServerEnvironment::ServerEnvironment(ServerMap *map,
|
||||
GameScripting *scriptIface,
|
||||
IGameDef *gamedef, IBackgroundBlockEmerger *emerger):
|
||||
m_map(map),
|
||||
m_script(scriptIface),
|
||||
@ -1149,7 +1137,8 @@ void ServerEnvironment::step(float dtime)
|
||||
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
||||
if(block==NULL){
|
||||
// Block needs to be fetched first
|
||||
m_emerger->queueBlockEmerge(p, false);
|
||||
m_emerger->enqueueBlockEmerge(
|
||||
PEER_ID_INEXISTENT, p, false);
|
||||
m_active_blocks.m_list.erase(p);
|
||||
continue;
|
||||
}
|
||||
@ -1505,7 +1494,9 @@ ActiveObjectMessage ServerEnvironment::getActiveObjectMessage()
|
||||
if(m_active_object_messages.empty())
|
||||
return ActiveObjectMessage(0);
|
||||
|
||||
return m_active_object_messages.pop_front();
|
||||
ActiveObjectMessage message = m_active_object_messages.front();
|
||||
m_active_object_messages.pop_front();
|
||||
return message;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2574,13 +2565,14 @@ void ClientEnvironment::getActiveObjects(v3f origin, f32 max_d,
|
||||
|
||||
ClientEnvEvent ClientEnvironment::getClientEvent()
|
||||
{
|
||||
ClientEnvEvent event;
|
||||
if(m_client_event_queue.empty())
|
||||
{
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_NONE;
|
||||
return event;
|
||||
else {
|
||||
event = m_client_event_queue.front();
|
||||
m_client_event_queue.pop_front();
|
||||
}
|
||||
return m_client_event_queue.pop_front();
|
||||
return event;
|
||||
}
|
||||
|
||||
#endif // #ifndef SERVER
|
||||
|
@ -32,11 +32,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include "irrlichttypes_extrabloated.h"
|
||||
#include "player.h"
|
||||
#include <ostream>
|
||||
#include <map>
|
||||
#include "irr_v3d.h"
|
||||
#include "activeobject.h"
|
||||
#include "util/container.h"
|
||||
#include "util/numeric.h"
|
||||
#include "mapnode.h"
|
||||
#include "mapblock.h"
|
||||
@ -44,13 +42,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
class ServerEnvironment;
|
||||
class ActiveBlockModifier;
|
||||
class ServerActiveObject;
|
||||
typedef struct lua_State lua_State;
|
||||
class ITextureSource;
|
||||
class IGameDef;
|
||||
class IBackgroundBlockEmerger;
|
||||
class Map;
|
||||
class ServerMap;
|
||||
class ClientMap;
|
||||
class ScriptApi;
|
||||
class GameScripting;
|
||||
class Player;
|
||||
|
||||
class Environment
|
||||
{
|
||||
@ -77,7 +76,6 @@ public:
|
||||
Player * getNearestConnectedPlayer(v3f pos);
|
||||
std::list<Player*> getPlayers();
|
||||
std::list<Player*> getPlayers(bool ignore_disconnected);
|
||||
void printPlayers(std::ostream &o);
|
||||
|
||||
u32 getDayNightRatio();
|
||||
|
||||
@ -176,12 +174,6 @@ public:
|
||||
private:
|
||||
};
|
||||
|
||||
class IBackgroundBlockEmerger
|
||||
{
|
||||
public:
|
||||
virtual void queueBlockEmerge(v3s16 blockpos, bool allow_generate)=0;
|
||||
};
|
||||
|
||||
/*
|
||||
The server-side environment.
|
||||
|
||||
@ -191,7 +183,8 @@ public:
|
||||
class ServerEnvironment : public Environment
|
||||
{
|
||||
public:
|
||||
ServerEnvironment(ServerMap *map, ScriptApi *iface, IGameDef *gamedef,
|
||||
ServerEnvironment(ServerMap *map, GameScripting *scriptIface,
|
||||
IGameDef *gamedef,
|
||||
IBackgroundBlockEmerger *emerger);
|
||||
~ServerEnvironment();
|
||||
|
||||
@ -200,7 +193,7 @@ public:
|
||||
ServerMap & getServerMap();
|
||||
|
||||
//TODO find way to remove this fct!
|
||||
ScriptApi* getScriptIface()
|
||||
GameScripting* getScriptIface()
|
||||
{ return m_script; }
|
||||
|
||||
IGameDef *getGameDef()
|
||||
@ -354,15 +347,15 @@ private:
|
||||
// The map
|
||||
ServerMap *m_map;
|
||||
// Lua state
|
||||
ScriptApi* m_script;
|
||||
GameScripting* m_script;
|
||||
// Game definition
|
||||
IGameDef *m_gamedef;
|
||||
// Background block emerger (the server, in practice)
|
||||
// Background block emerger (the EmergeManager, in practice)
|
||||
IBackgroundBlockEmerger *m_emerger;
|
||||
// Active object list
|
||||
std::map<u16, ServerActiveObject*> m_active_objects;
|
||||
// Outgoing network message buffer for active objects
|
||||
Queue<ActiveObjectMessage> m_active_object_messages;
|
||||
std::list<ActiveObjectMessage> m_active_object_messages;
|
||||
// Some timers
|
||||
float m_random_spawn_timer; // used for experimental code
|
||||
float m_send_recommended_timer;
|
||||
@ -503,7 +496,7 @@ private:
|
||||
IrrlichtDevice *m_irr;
|
||||
std::map<u16, ClientActiveObject*> m_active_objects;
|
||||
std::list<ClientSimpleObject*> m_simple_objects;
|
||||
Queue<ClientEnvEvent> m_client_event_queue;
|
||||
std::list<ClientEnvEvent> m_client_event_queue;
|
||||
IntervalLimiter m_active_object_light_update_interval;
|
||||
IntervalLimiter m_lava_hurt_interval;
|
||||
IntervalLimiter m_drowning_interval;
|
||||
|
@ -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:
|
||||
*/
|
||||
|
@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
|
||||
bool FileCache::loadByPath(const std::string &path, std::ostream &os)
|
||||
{
|
||||
|
@ -18,12 +18,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
|
||||
#include "filesys.h"
|
||||
#include "strfnd.h"
|
||||
#include "util/string.h"
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include "log.h"
|
||||
|
||||
|
@ -915,7 +915,6 @@ void the_game(
|
||||
std::string address, // If "", local server is used
|
||||
u16 port,
|
||||
std::wstring &error_message,
|
||||
std::string configpath,
|
||||
ChatBackend &chat_backend,
|
||||
const SubgameSpec &gamespec, // Used for local game,
|
||||
bool simple_singleplayer_mode
|
||||
@ -1001,7 +1000,7 @@ void the_game(
|
||||
draw_load_screen(text, device, font,0,25);
|
||||
delete[] text;
|
||||
infostream<<"Creating server"<<std::endl;
|
||||
server = new Server(map_dir, configpath, gamespec,
|
||||
server = new Server(map_dir, gamespec,
|
||||
simple_singleplayer_mode);
|
||||
server->start(port);
|
||||
}
|
||||
@ -3340,7 +3339,7 @@ void the_game(
|
||||
*/
|
||||
{
|
||||
TimeTaker timer("endScene");
|
||||
endSceneX(driver);
|
||||
driver->endScene();
|
||||
endscenetime = timer.stop(true);
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,6 @@ void the_game(
|
||||
std::string address, // If "", local server is used
|
||||
u16 port,
|
||||
std::wstring &error_message,
|
||||
std::string configpath,
|
||||
ChatBackend &chat_backend,
|
||||
const SubgameSpec &gamespec, // Used for local game
|
||||
bool simple_singleplayer_mode
|
||||
|
@ -17,14 +17,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include "irrlicht.h"
|
||||
#include "guiEngine.h"
|
||||
|
||||
#include "scripting_mainmenu.h"
|
||||
#include "config.h"
|
||||
#include "porting.h"
|
||||
#include "filesys.h"
|
||||
#include "main.h"
|
||||
@ -33,30 +29,13 @@ extern "C" {
|
||||
#include "sound.h"
|
||||
#include "sound_openal.h"
|
||||
|
||||
#include "guiEngine.h"
|
||||
#include <IGUIStaticText.h>
|
||||
#include <ICameraSceneNode.h>
|
||||
|
||||
#if USE_CURL
|
||||
#include <curl/curl.h>
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
int menuscript_ErrorHandler(lua_State *L) {
|
||||
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
|
||||
if (!lua_istable(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
lua_getfield(L, -1, "traceback");
|
||||
if (!lua_isfunction(L, -1)) {
|
||||
lua_pop(L, 2);
|
||||
return 1;
|
||||
}
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushinteger(L, 2);
|
||||
lua_call(L, 2, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
TextDestGuiEngine::TextDestGuiEngine(GUIEngine* engine)
|
||||
{
|
||||
@ -66,13 +45,33 @@ TextDestGuiEngine::TextDestGuiEngine(GUIEngine* engine)
|
||||
/******************************************************************************/
|
||||
void TextDestGuiEngine::gotText(std::map<std::string, std::string> fields)
|
||||
{
|
||||
m_engine->handleButtons(fields);
|
||||
m_engine->getScriptIface()->handleMainMenuButtons(fields);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void TextDestGuiEngine::gotText(std::wstring text)
|
||||
{
|
||||
m_engine->handleEvent(wide_to_narrow(text));
|
||||
m_engine->getScriptIface()->handleMainMenuEvent(wide_to_narrow(text));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void MenuMusicFetcher::fetchSounds(const std::string &name,
|
||||
std::set<std::string> &dst_paths,
|
||||
std::set<std::string> &dst_datas)
|
||||
{
|
||||
if(m_fetched.count(name))
|
||||
return;
|
||||
m_fetched.insert(name);
|
||||
std::string base;
|
||||
base = porting::path_share + DIR_DELIM + "sounds";
|
||||
dst_paths.insert(base + DIR_DELIM + name + ".ogg");
|
||||
int i;
|
||||
for(i=0; i<10; i++)
|
||||
dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
|
||||
base = porting::path_user + DIR_DELIM + "sounds";
|
||||
dst_paths.insert(base + DIR_DELIM + name + ".ogg");
|
||||
for(i=0; i<10; i++)
|
||||
dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@ -91,8 +90,7 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
|
||||
m_buttonhandler(0),
|
||||
m_menu(0),
|
||||
m_startgame(false),
|
||||
m_engineluastack(0),
|
||||
m_luaerrorhandler(-1),
|
||||
m_script(0),
|
||||
m_scriptdir(""),
|
||||
m_irr_toplefttext(0),
|
||||
m_clouds_enabled(true),
|
||||
@ -105,26 +103,6 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
|
||||
// is deleted by guiformspec!
|
||||
m_buttonhandler = new TextDestGuiEngine(this);
|
||||
|
||||
//create luastack
|
||||
m_engineluastack = luaL_newstate();
|
||||
|
||||
//load basic lua modules
|
||||
luaL_openlibs(m_engineluastack);
|
||||
|
||||
//init
|
||||
guiLuaApi::initialize(m_engineluastack,this);
|
||||
|
||||
//push errorstring
|
||||
if (m_data->errormessage != "")
|
||||
{
|
||||
lua_getglobal(m_engineluastack, "gamedata");
|
||||
int gamedata_idx = lua_gettop(m_engineluastack);
|
||||
lua_pushstring(m_engineluastack, "errormessage");
|
||||
lua_pushstring(m_engineluastack,m_data->errormessage.c_str());
|
||||
lua_settable(m_engineluastack, gamedata_idx);
|
||||
m_data->errormessage = "";
|
||||
}
|
||||
|
||||
//create soundmanager
|
||||
MenuMusicFetcher soundfetcher;
|
||||
#if USE_SOUND
|
||||
@ -160,68 +138,76 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
|
||||
m_menu->setTextDest(m_buttonhandler);
|
||||
m_menu->useGettext(true);
|
||||
|
||||
std::string builtin_helpers
|
||||
= porting::path_share + DIR_DELIM + "builtin"
|
||||
+ DIR_DELIM + "misc_helpers.lua";
|
||||
// Initialize scripting
|
||||
|
||||
if (!runScript(builtin_helpers)) {
|
||||
errorstream
|
||||
<< "GUIEngine::GUIEngine unable to load builtin helper script"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
infostream<<"GUIEngine: Initializing Lua"<<std::endl;
|
||||
|
||||
std::string menuscript = "";
|
||||
if (g_settings->exists("main_menu_script"))
|
||||
menuscript = g_settings->get("main_menu_script");
|
||||
std::string builtin_menuscript =
|
||||
porting::path_share + DIR_DELIM + "builtin"
|
||||
+ DIR_DELIM + "mainmenu.lua";
|
||||
m_script = new MainMenuScripting(this);
|
||||
|
||||
lua_pushcfunction(m_engineluastack, menuscript_ErrorHandler);
|
||||
m_luaerrorhandler = lua_gettop(m_engineluastack);
|
||||
|
||||
m_scriptdir = menuscript.substr(0,menuscript.find_last_of(DIR_DELIM)-1);
|
||||
if((menuscript == "") || (!runScript(menuscript))) {
|
||||
infostream
|
||||
<< "GUIEngine::GUIEngine execution of custom menu failed!"
|
||||
<< std::endl
|
||||
<< "\tfalling back to builtin menu"
|
||||
<< std::endl;
|
||||
m_scriptdir = fs::RemoveRelativePathComponents(porting::path_share + DIR_DELIM + "builtin"+ DIR_DELIM);
|
||||
if(!runScript(builtin_menuscript)) {
|
||||
errorstream
|
||||
<< "GUIEngine::GUIEngine unable to load builtin menu"
|
||||
<< std::endl;
|
||||
assert("no future without mainmenu" == 0);
|
||||
try {
|
||||
if (m_data->errormessage != "")
|
||||
{
|
||||
m_script->setMainMenuErrorMessage(m_data->errormessage);
|
||||
m_data->errormessage = "";
|
||||
}
|
||||
|
||||
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_menumanager->deletingMenu(m_menu);
|
||||
m_menu->quitMenu();
|
||||
m_menu->drop();
|
||||
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()) ||
|
||||
lua_pcall(m_engineluastack, 0, 0, m_luaerrorhandler);
|
||||
if(ret){
|
||||
errorstream<<"========== ERROR FROM LUA WHILE CREATING MAIN MENU ==========="<<std::endl;
|
||||
errorstream<<"Failed to load and run script from "<<std::endl;
|
||||
errorstream<<script<<":"<<std::endl;
|
||||
errorstream<<std::endl;
|
||||
errorstream<<lua_tostring(m_engineluastack, -1)<<std::endl;
|
||||
errorstream<<std::endl;
|
||||
errorstream<<"=================== END OF ERROR FROM LUA ===================="<<std::endl;
|
||||
lua_pop(m_engineluastack, 1); // Pop error message from stack
|
||||
lua_pop(m_engineluastack, 1); // Pop the error handler from stack
|
||||
return false;
|
||||
std::string menuscript = g_settings->get("main_menu_script");
|
||||
if(menuscript != "") {
|
||||
m_scriptdir = fs::RemoveLastPathComponent(menuscript);
|
||||
|
||||
if(m_script->loadMod(menuscript, "__custommenu")) {
|
||||
// custom menu script loaded
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
infostream
|
||||
<< "GUIEngine: execution of custom menu failed!"
|
||||
<< std::endl
|
||||
<< "\tfalling back to builtin menu"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
// Try builtin menu script (main_menu_script)
|
||||
|
||||
std::string builtin_menuscript =
|
||||
porting::path_share + DIR_DELIM + "builtin"
|
||||
+ DIR_DELIM + "mainmenu.lua";
|
||||
|
||||
m_scriptdir = fs::RemoveRelativePathComponents(
|
||||
fs::RemoveLastPathComponent(builtin_menuscript));
|
||||
|
||||
if(m_script->loadMod(builtin_menuscript, "__builtinmenu")) {
|
||||
// builtin menu script loaded
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
errorstream
|
||||
<< "GUIEngine: unable to load builtin menu"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@ -257,52 +243,6 @@ void GUIEngine::run()
|
||||
else
|
||||
sleep_ms(25);
|
||||
}
|
||||
|
||||
m_menu->quitMenu();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void GUIEngine::handleEvent(std::string text)
|
||||
{
|
||||
lua_getglobal(m_engineluastack, "engine");
|
||||
|
||||
lua_getfield(m_engineluastack, -1, "event_handler");
|
||||
|
||||
if(lua_isnil(m_engineluastack, -1))
|
||||
return;
|
||||
|
||||
luaL_checktype(m_engineluastack, -1, LUA_TFUNCTION);
|
||||
|
||||
lua_pushstring(m_engineluastack, text.c_str());
|
||||
|
||||
if(lua_pcall(m_engineluastack, 1, 0, m_luaerrorhandler))
|
||||
scriptError("error: %s", lua_tostring(m_engineluastack, -1));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void GUIEngine::handleButtons(std::map<std::string, std::string> fields)
|
||||
{
|
||||
lua_getglobal(m_engineluastack, "engine");
|
||||
|
||||
lua_getfield(m_engineluastack, -1, "button_handler");
|
||||
|
||||
if(lua_isnil(m_engineluastack, -1))
|
||||
return;
|
||||
|
||||
luaL_checktype(m_engineluastack, -1, LUA_TFUNCTION);
|
||||
|
||||
lua_newtable(m_engineluastack);
|
||||
for(std::map<std::string, std::string>::const_iterator
|
||||
i = fields.begin(); i != fields.end(); i++){
|
||||
const std::string &name = i->first;
|
||||
const std::string &value = i->second;
|
||||
lua_pushstring(m_engineluastack, name.c_str());
|
||||
lua_pushlstring(m_engineluastack, value.c_str(), value.size());
|
||||
lua_settable(m_engineluastack, -3);
|
||||
}
|
||||
|
||||
if(lua_pcall(m_engineluastack, 1, 0, m_luaerrorhandler))
|
||||
scriptError("error: %s", lua_tostring(m_engineluastack, -1));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@ -318,7 +258,8 @@ GUIEngine::~GUIEngine()
|
||||
|
||||
//TODO: clean up m_menu here
|
||||
|
||||
lua_close(m_engineluastack);
|
||||
infostream<<"GUIEngine: Deinitializing scripting"<<std::endl;
|
||||
delete m_script;
|
||||
|
||||
m_irr_toplefttext->setText(L"");
|
||||
|
||||
@ -565,17 +506,6 @@ bool GUIEngine::downloadFile(std::string url,std::string target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void GUIEngine::scriptError(const char *fmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
char buf[10000];
|
||||
vsnprintf(buf, 10000, fmt, argp);
|
||||
va_end(argp);
|
||||
errorstream<<"MAINMENU ERROR: "<<buf;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void GUIEngine::setTopleftText(std::string append) {
|
||||
std::string toset = "Minetest " VERSION_STRING;
|
||||
|
@ -26,7 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "irrlichttypes.h"
|
||||
#include "modalMenu.h"
|
||||
#include "clouds.h"
|
||||
#include "guiLuaApi.h"
|
||||
#include "guiFormSpecMenu.h"
|
||||
#include "sound.h"
|
||||
|
||||
@ -50,6 +49,7 @@ typedef enum {
|
||||
/* forward declarations */
|
||||
/******************************************************************************/
|
||||
class GUIEngine;
|
||||
class MainMenuScripting;
|
||||
struct MainMenuData;
|
||||
struct SimpleSoundSpec;
|
||||
|
||||
@ -86,35 +86,17 @@ class MenuMusicFetcher: public OnDemandSoundFetcher
|
||||
{
|
||||
std::set<std::string> m_fetched;
|
||||
public:
|
||||
|
||||
void fetchSounds(const std::string &name,
|
||||
std::set<std::string> &dst_paths,
|
||||
std::set<std::string> &dst_datas)
|
||||
{
|
||||
if(m_fetched.count(name))
|
||||
return;
|
||||
m_fetched.insert(name);
|
||||
std::string base;
|
||||
base = porting::path_share + DIR_DELIM + "sounds";
|
||||
dst_paths.insert(base + DIR_DELIM + name + ".ogg");
|
||||
int i;
|
||||
for(i=0; i<10; i++)
|
||||
dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
|
||||
base = porting::path_user + DIR_DELIM + "sounds";
|
||||
dst_paths.insert(base + DIR_DELIM + name + ".ogg");
|
||||
for(i=0; i<10; i++)
|
||||
dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
|
||||
}
|
||||
std::set<std::string> &dst_datas);
|
||||
};
|
||||
|
||||
/** implementation of main menu based uppon formspecs */
|
||||
class GUIEngine {
|
||||
public:
|
||||
/** TextDestGuiEngine needs to transfer data to engine */
|
||||
friend class TextDestGuiEngine;
|
||||
/** guiLuaApi is used to initialize contained stack */
|
||||
friend class guiLuaApi;
|
||||
/** grant ModApiMainMenu access to private members */
|
||||
friend class ModApiMainMenu;
|
||||
|
||||
public:
|
||||
/**
|
||||
* default constructor
|
||||
* @param dev device to draw at
|
||||
@ -132,20 +114,12 @@ public:
|
||||
/** default destructor */
|
||||
virtual ~GUIEngine();
|
||||
|
||||
s32 playSound(SimpleSoundSpec spec, bool looped);
|
||||
void stopSound(s32 handle);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* process field data recieved from formspec
|
||||
* @param fields data in field format
|
||||
* return MainMenuScripting interface
|
||||
*/
|
||||
void handleButtons(std::map<std::string, std::string> fields);
|
||||
/**
|
||||
* process events received from formspec
|
||||
* @param text events in textual form
|
||||
*/
|
||||
void handleEvent(std::string text);
|
||||
MainMenuScripting* getScriptIface() {
|
||||
return m_script;
|
||||
}
|
||||
|
||||
/**
|
||||
* return dir of current menuscript
|
||||
@ -156,7 +130,10 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
/* run main menu loop */
|
||||
/** find and run the main menu script */
|
||||
bool loadMainMenuScript();
|
||||
|
||||
/** run main menu loop */
|
||||
void run();
|
||||
|
||||
/** handler to limit frame rate within main menu */
|
||||
@ -185,27 +162,8 @@ private:
|
||||
/** variable used to abort menu and return back to main game handling */
|
||||
bool m_startgame;
|
||||
|
||||
/**
|
||||
* initialize lua stack
|
||||
* @param L stack to initialize
|
||||
*/
|
||||
void initalize_api(lua_State * L);
|
||||
|
||||
/**
|
||||
* run a lua script
|
||||
* @param script full path to script to run
|
||||
*/
|
||||
bool runScript(std::string script);
|
||||
|
||||
/**
|
||||
* script error handler to process errors within lua
|
||||
*/
|
||||
void scriptError(const char *fmt, ...);
|
||||
|
||||
/** lua stack */
|
||||
lua_State* m_engineluastack;
|
||||
/** lua internal stack number of error handler*/
|
||||
int m_luaerrorhandler;
|
||||
/** scripting interface */
|
||||
MainMenuScripting* m_script;
|
||||
|
||||
/** script basefolder */
|
||||
std::string m_scriptdir;
|
||||
@ -284,6 +242,12 @@ private:
|
||||
/** data used to draw clouds */
|
||||
clouddata m_cloud;
|
||||
|
||||
/** start playing a sound and return handle */
|
||||
s32 playSound(SimpleSoundSpec spec, bool looped);
|
||||
/** stop playing a sound started with playSound() */
|
||||
void stopSound(s32 handle);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -39,6 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include <IGUIComboBox.h>
|
||||
#include "log.h"
|
||||
#include "tile.h" // ITextureSource
|
||||
#include "hud.h" // drawItemStack
|
||||
#include "util/string.h"
|
||||
#include "util/numeric.h"
|
||||
#include "filesys.h"
|
||||
@ -61,92 +62,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
}
|
||||
|
||||
|
||||
void drawItemStack(video::IVideoDriver *driver,
|
||||
gui::IGUIFont *font,
|
||||
const ItemStack &item,
|
||||
const core::rect<s32> &rect,
|
||||
const core::rect<s32> *clip,
|
||||
IGameDef *gamedef)
|
||||
{
|
||||
if(item.empty())
|
||||
return;
|
||||
|
||||
const ItemDefinition &def = item.getDefinition(gamedef->idef());
|
||||
video::ITexture *texture = gamedef->idef()->getInventoryTexture(def.name, gamedef);
|
||||
|
||||
// Draw the inventory texture
|
||||
if(texture != NULL)
|
||||
{
|
||||
const video::SColor color(255,255,255,255);
|
||||
const video::SColor colors[] = {color,color,color,color};
|
||||
driver->draw2DImage(texture, rect,
|
||||
core::rect<s32>(core::position2d<s32>(0,0),
|
||||
core::dimension2di(texture->getOriginalSize())),
|
||||
clip, colors, true);
|
||||
}
|
||||
|
||||
if(def.type == ITEM_TOOL && item.wear != 0)
|
||||
{
|
||||
// Draw a progressbar
|
||||
float barheight = rect.getHeight()/16;
|
||||
float barpad_x = rect.getWidth()/16;
|
||||
float barpad_y = rect.getHeight()/16;
|
||||
core::rect<s32> progressrect(
|
||||
rect.UpperLeftCorner.X + barpad_x,
|
||||
rect.LowerRightCorner.Y - barpad_y - barheight,
|
||||
rect.LowerRightCorner.X - barpad_x,
|
||||
rect.LowerRightCorner.Y - barpad_y);
|
||||
|
||||
// Shrink progressrect by amount of tool damage
|
||||
float wear = item.wear / 65535.0;
|
||||
int progressmid =
|
||||
wear * progressrect.UpperLeftCorner.X +
|
||||
(1-wear) * progressrect.LowerRightCorner.X;
|
||||
|
||||
// Compute progressbar color
|
||||
// wear = 0.0: green
|
||||
// wear = 0.5: yellow
|
||||
// wear = 1.0: red
|
||||
video::SColor color(255,255,255,255);
|
||||
int wear_i = MYMIN(floor(wear * 600), 511);
|
||||
wear_i = MYMIN(wear_i + 10, 511);
|
||||
if(wear_i <= 255)
|
||||
color.set(255, wear_i, 255, 0);
|
||||
else
|
||||
color.set(255, 255, 511-wear_i, 0);
|
||||
|
||||
core::rect<s32> progressrect2 = progressrect;
|
||||
progressrect2.LowerRightCorner.X = progressmid;
|
||||
driver->draw2DRectangle(color, progressrect2, clip);
|
||||
|
||||
color = video::SColor(255,0,0,0);
|
||||
progressrect2 = progressrect;
|
||||
progressrect2.UpperLeftCorner.X = progressmid;
|
||||
driver->draw2DRectangle(color, progressrect2, clip);
|
||||
}
|
||||
|
||||
if(font != NULL && item.count >= 2)
|
||||
{
|
||||
// Get the item count as a string
|
||||
std::string text = itos(item.count);
|
||||
v2u32 dim = font->getDimension(narrow_to_wide(text).c_str());
|
||||
v2s32 sdim(dim.X,dim.Y);
|
||||
|
||||
core::rect<s32> rect2(
|
||||
/*rect.UpperLeftCorner,
|
||||
core::dimension2d<u32>(rect.getWidth(), 15)*/
|
||||
rect.LowerRightCorner - sdim,
|
||||
sdim
|
||||
);
|
||||
|
||||
video::SColor bgcolor(128,0,0,0);
|
||||
driver->draw2DRectangle(bgcolor, rect2, clip);
|
||||
|
||||
video::SColor color(255,255,255,255);
|
||||
font->draw(text.c_str(), rect2, color, false, false, clip);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
GUIFormSpecMenu
|
||||
*/
|
||||
|
@ -57,13 +57,6 @@ public:
|
||||
virtual std::string resolveText(std::string str){ return str; }
|
||||
};
|
||||
|
||||
void drawItemStack(video::IVideoDriver *driver,
|
||||
gui::IGUIFont *font,
|
||||
const ItemStack &item,
|
||||
const core::rect<s32> &rect,
|
||||
const core::rect<s32> *clip,
|
||||
IGameDef *gamedef);
|
||||
|
||||
class GUIFormSpecMenu : public GUIModalMenu
|
||||
{
|
||||
struct ItemSpec
|
||||
|
@ -27,6 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#include <IGUIStaticText.h>
|
||||
#include <IGUIFont.h>
|
||||
#include "main.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include "gettext.h"
|
||||
|
||||
|
101
src/hud.cpp
101
src/hud.cpp
@ -19,14 +19,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <IGUIStaticText.h>
|
||||
|
||||
#include "guiFormSpecMenu.h"
|
||||
#include "hud.h"
|
||||
#include "main.h"
|
||||
#include "settings.h"
|
||||
#include "util/numeric.h"
|
||||
#include "log.h"
|
||||
#include "client.h"
|
||||
#include "hud.h"
|
||||
#include "gamedef.h"
|
||||
#include "itemdef.h"
|
||||
#include "inventory.h"
|
||||
#include "tile.h"
|
||||
#include "localplayer.h"
|
||||
|
||||
#include <IGUIStaticText.h>
|
||||
|
||||
|
||||
Hud::Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv,
|
||||
@ -339,3 +343,90 @@ void Hud::resizeHotbar() {
|
||||
else
|
||||
hotbar_imagesize = 64;
|
||||
}
|
||||
|
||||
void drawItemStack(video::IVideoDriver *driver,
|
||||
gui::IGUIFont *font,
|
||||
const ItemStack &item,
|
||||
const core::rect<s32> &rect,
|
||||
const core::rect<s32> *clip,
|
||||
IGameDef *gamedef)
|
||||
{
|
||||
if(item.empty())
|
||||
return;
|
||||
|
||||
const ItemDefinition &def = item.getDefinition(gamedef->idef());
|
||||
video::ITexture *texture = gamedef->idef()->getInventoryTexture(def.name, gamedef);
|
||||
|
||||
// Draw the inventory texture
|
||||
if(texture != NULL)
|
||||
{
|
||||
const video::SColor color(255,255,255,255);
|
||||
const video::SColor colors[] = {color,color,color,color};
|
||||
driver->draw2DImage(texture, rect,
|
||||
core::rect<s32>(core::position2d<s32>(0,0),
|
||||
core::dimension2di(texture->getOriginalSize())),
|
||||
clip, colors, true);
|
||||
}
|
||||
|
||||
if(def.type == ITEM_TOOL && item.wear != 0)
|
||||
{
|
||||
// Draw a progressbar
|
||||
float barheight = rect.getHeight()/16;
|
||||
float barpad_x = rect.getWidth()/16;
|
||||
float barpad_y = rect.getHeight()/16;
|
||||
core::rect<s32> progressrect(
|
||||
rect.UpperLeftCorner.X + barpad_x,
|
||||
rect.LowerRightCorner.Y - barpad_y - barheight,
|
||||
rect.LowerRightCorner.X - barpad_x,
|
||||
rect.LowerRightCorner.Y - barpad_y);
|
||||
|
||||
// Shrink progressrect by amount of tool damage
|
||||
float wear = item.wear / 65535.0;
|
||||
int progressmid =
|
||||
wear * progressrect.UpperLeftCorner.X +
|
||||
(1-wear) * progressrect.LowerRightCorner.X;
|
||||
|
||||
// Compute progressbar color
|
||||
// wear = 0.0: green
|
||||
// wear = 0.5: yellow
|
||||
// wear = 1.0: red
|
||||
video::SColor color(255,255,255,255);
|
||||
int wear_i = MYMIN(floor(wear * 600), 511);
|
||||
wear_i = MYMIN(wear_i + 10, 511);
|
||||
if(wear_i <= 255)
|
||||
color.set(255, wear_i, 255, 0);
|
||||
else
|
||||
color.set(255, 255, 511-wear_i, 0);
|
||||
|
||||
core::rect<s32> progressrect2 = progressrect;
|
||||
progressrect2.LowerRightCorner.X = progressmid;
|
||||
driver->draw2DRectangle(color, progressrect2, clip);
|
||||
|
||||
color = video::SColor(255,0,0,0);
|
||||
progressrect2 = progressrect;
|
||||
progressrect2.UpperLeftCorner.X = progressmid;
|
||||
driver->draw2DRectangle(color, progressrect2, clip);
|
||||
}
|
||||
|
||||
if(font != NULL && item.count >= 2)
|
||||
{
|
||||
// Get the item count as a string
|
||||
std::string text = itos(item.count);
|
||||
v2u32 dim = font->getDimension(narrow_to_wide(text).c_str());
|
||||
v2s32 sdim(dim.X,dim.Y);
|
||||
|
||||
core::rect<s32> rect2(
|
||||
/*rect.UpperLeftCorner,
|
||||
core::dimension2d<u32>(rect.getWidth(), 15)*/
|
||||
rect.LowerRightCorner - sdim,
|
||||
sdim
|
||||
);
|
||||
|
||||
video::SColor bgcolor(128,0,0,0);
|
||||
driver->draw2DRectangle(bgcolor, rect2, clip);
|
||||
|
||||
video::SColor color(255,255,255,255);
|
||||
font->draw(text.c_str(), rect2, color, false, false, clip);
|
||||
}
|
||||
}
|
||||
|
||||
|
32
src/hud.h
32
src/hud.h
@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#define HUD_HEADER
|
||||
|
||||
#include "irrlichttypes_extrabloated.h"
|
||||
#include <string>
|
||||
|
||||
#define HUD_DIR_LEFT_RIGHT 0
|
||||
#define HUD_DIR_RIGHT_LEFT 1
|
||||
@ -42,8 +43,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#define HUD_HOTBAR_ITEMCOUNT_DEFAULT 8
|
||||
#define HUD_HOTBAR_ITEMCOUNT_MAX 23
|
||||
|
||||
class Player;
|
||||
|
||||
enum HudElementType {
|
||||
HUD_ELEM_IMAGE = 0,
|
||||
HUD_ELEM_TEXT = 1,
|
||||
@ -76,23 +75,18 @@ struct HudElement {
|
||||
v2f offset;
|
||||
};
|
||||
|
||||
|
||||
inline u32 hud_get_free_id(Player *player) {
|
||||
size_t size = player->hud.size();
|
||||
for (size_t i = 0; i != size; i++) {
|
||||
if (!player->hud[i])
|
||||
return i;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
#ifndef SERVER
|
||||
|
||||
#include <vector>
|
||||
#include <IGUIFont.h>
|
||||
#include "irr_aabb3d.h"
|
||||
|
||||
#include "gamedef.h"
|
||||
#include "inventory.h"
|
||||
#include "localplayer.h"
|
||||
class IGameDef;
|
||||
class ITextureSource;
|
||||
class Inventory;
|
||||
class InventoryList;
|
||||
class LocalPlayer;
|
||||
struct ItemStack;
|
||||
|
||||
class Hud {
|
||||
public:
|
||||
@ -130,6 +124,14 @@ public:
|
||||
void drawSelectionBoxes(std::vector<aabb3f> &hilightboxes);
|
||||
};
|
||||
|
||||
void drawItemStack(video::IVideoDriver *driver,
|
||||
gui::IGUIFont *font,
|
||||
const ItemStack &item,
|
||||
const core::rect<s32> &rect,
|
||||
const core::rect<s32> *clip,
|
||||
IGameDef *gamedef);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -21,10 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#define INVENTORY_HEADER
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "irrlichttypes_bloated.h"
|
||||
#include "irrlichttypes.h"
|
||||
#include "debug.h"
|
||||
#include "itemdef.h"
|
||||
|
||||
|
@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "inventorymanager.h"
|
||||
#include "log.h"
|
||||
#include "environment.h"
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "scripting_game.h"
|
||||
#include "serverobject.h"
|
||||
#include "main.h" // for g_settings
|
||||
#include "settings.h"
|
||||
@ -29,6 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||
|
||||
#define PLAYER_TO_SA(p) p->getEnv()->getScriptIface()
|
||||
|
||||
/*
|
||||
InventoryLocation
|
||||
*/
|
||||
|
@ -26,9 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "irr_v3d.h"
|
||||
#include "irr_aabb3d.h"
|
||||
|
||||
#include <irrMap.h>
|
||||
#include <irrList.h>
|
||||
#include <irrArray.h>
|
||||
#include <SColor.h>
|
||||
|
||||
#endif
|
||||
|
@ -20,9 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef IRRLICHTTYPES_EXTRABLOATED_HEADER
|
||||
#define IRRLICHTTYPES_EXTRABLOATED_HEADER
|
||||
|
||||
#define endSceneX(d){d->draw2DLine(v2s32(0,0),v2s32(1,0),\
|
||||
video::SColor(255,30,30,30));d->endScene();}
|
||||
|
||||
#include "irrlichttypes_bloated.h"
|
||||
|
||||
#ifndef SERVER
|
||||
|
@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef ITEMGROUP_HEADER
|
||||
#define ITEMGROUP_HEADER
|
||||
|
||||
#include "irrlichttypes_extrabloated.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
|
10
src/light.h
10
src/light.h
@ -21,16 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#define LIGHT_HEADER
|
||||
|
||||
#include "irrlichttypes.h"
|
||||
#include "debug.h"
|
||||
|
||||
/*
|
||||
Day/night cache:
|
||||
Meshes are cached for different day-to-night transition values
|
||||
*/
|
||||
|
||||
/*#define DAYNIGHT_CACHE_COUNT 3
|
||||
// First one is day, last one is night.
|
||||
extern u32 daynight_cache_ratios[DAYNIGHT_CACHE_COUNT];*/
|
||||
|
||||
/*
|
||||
Lower level lighting stuff
|
||||
|
28
src/main.cpp
28
src/main.cpp
@ -84,6 +84,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
Settings main_settings;
|
||||
Settings *g_settings = &main_settings;
|
||||
std::string g_settings_path;
|
||||
|
||||
// Global profiler
|
||||
Profiler main_profiler;
|
||||
@ -913,7 +914,7 @@ int main(int argc, char *argv[])
|
||||
*/
|
||||
|
||||
// Path of configuration file in use
|
||||
std::string configpath = "";
|
||||
g_settings_path = "";
|
||||
|
||||
if(cmd_args.exists("config"))
|
||||
{
|
||||
@ -924,7 +925,7 @@ int main(int argc, char *argv[])
|
||||
<<cmd_args.get("config")<<"\""<<std::endl;
|
||||
return 1;
|
||||
}
|
||||
configpath = cmd_args.get("config");
|
||||
g_settings_path = cmd_args.get("config");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -946,14 +947,14 @@ int main(int argc, char *argv[])
|
||||
bool r = g_settings->readConfigFile(filenames[i].c_str());
|
||||
if(r)
|
||||
{
|
||||
configpath = filenames[i];
|
||||
g_settings_path = filenames[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no path found, use the first one (menu creates the file)
|
||||
if(configpath == "")
|
||||
configpath = filenames[0];
|
||||
if(g_settings_path == "")
|
||||
g_settings_path = filenames[0];
|
||||
}
|
||||
|
||||
// Initialize debug streams
|
||||
@ -1193,7 +1194,7 @@ int main(int argc, char *argv[])
|
||||
verbosestream<<_("Using gameid")<<" ["<<gamespec.id<<"]"<<std::endl;
|
||||
|
||||
// Create server
|
||||
Server server(world_path, configpath, gamespec, false);
|
||||
Server server(world_path, gamespec, false);
|
||||
server.start(port);
|
||||
|
||||
// Run server
|
||||
@ -1573,6 +1574,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
}
|
||||
|
||||
if(menudata.errormessage != ""){
|
||||
error_message = narrow_to_wide(menudata.errormessage);
|
||||
continue;
|
||||
}
|
||||
|
||||
//update worldspecs (necessary as new world may have been created)
|
||||
worldspecs = getAvailableWorlds();
|
||||
|
||||
@ -1675,7 +1681,10 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Break out of menu-game loop to shut down cleanly
|
||||
if(device->run() == false || kill == true) {
|
||||
g_settings->updateConfigFile(configpath.c_str());
|
||||
if(g_settings_path != "") {
|
||||
g_settings->updateConfigFile(
|
||||
g_settings_path.c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1694,7 +1703,6 @@ int main(int argc, char *argv[])
|
||||
current_address,
|
||||
current_port,
|
||||
error_message,
|
||||
configpath,
|
||||
chat_backend,
|
||||
gamespec,
|
||||
simple_singleplayer_mode
|
||||
@ -1749,8 +1757,8 @@ int main(int argc, char *argv[])
|
||||
#endif // !SERVER
|
||||
|
||||
// Update configuration file
|
||||
if(configpath != "")
|
||||
g_settings->updateConfigFile(configpath.c_str());
|
||||
if(g_settings_path != "")
|
||||
g_settings->updateConfigFile(g_settings_path.c_str());
|
||||
|
||||
// Print modified quicktune values
|
||||
{
|
||||
|
@ -20,9 +20,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef MAIN_HEADER
|
||||
#define MAIN_HEADER
|
||||
|
||||
#include <string>
|
||||
|
||||
// Settings
|
||||
class Settings;
|
||||
extern Settings *g_settings;
|
||||
extern std::string g_settings_path;
|
||||
|
||||
// Global profiler
|
||||
class Profiler;
|
||||
|
@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "filesys.h"
|
||||
#include "voxel.h"
|
||||
#include "porting.h"
|
||||
#include "serialization.h"
|
||||
#include "nodemetadata.h"
|
||||
#include "settings.h"
|
||||
#include "log.h"
|
||||
@ -33,9 +34,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "util/directiontables.h"
|
||||
#include "util/mathconstants.h"
|
||||
#include "rollback_interface.h"
|
||||
#include "environment.h"
|
||||
#include "emerge.h"
|
||||
#include "mapgen_v6.h"
|
||||
#include "mapgen_indev.h"
|
||||
#include "biome.h"
|
||||
|
||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||
|
@ -20,9 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef MAP_HEADER
|
||||
#define MAP_HEADER
|
||||
|
||||
#include <jmutex.h>
|
||||
#include <jmutexautolock.h>
|
||||
#include <jthread.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
@ -33,11 +30,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "mapnode.h"
|
||||
#include "constants.h"
|
||||
#include "voxel.h"
|
||||
#include "mapgen.h" //for MapgenParams
|
||||
#include "modifiedstate.h"
|
||||
#include "util/container.h"
|
||||
#include "nodetimer.h"
|
||||
#include "environment.h"
|
||||
|
||||
extern "C" {
|
||||
#include "sqlite3.h"
|
||||
@ -51,7 +46,9 @@ class NodeMetadata;
|
||||
class IGameDef;
|
||||
class IRollbackReportSink;
|
||||
class EmergeManager;
|
||||
class ServerEnvironment;
|
||||
struct BlockMakeData;
|
||||
struct MapgenParams;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -21,8 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#include <sstream>
|
||||
#include "map.h"
|
||||
// For g_settings
|
||||
#include "main.h"
|
||||
#include "light.h"
|
||||
#include "nodedef.h"
|
||||
#include "nodemetadata.h"
|
||||
@ -31,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "nameidmapping.h"
|
||||
#include "content_mapnode.h" // For legacy name-id mapping
|
||||
#include "content_nodemeta.h" // For legacy deserialization
|
||||
#include "serialization.h"
|
||||
#ifndef SERVER
|
||||
#include "mapblock_mesh.h"
|
||||
#endif
|
||||
|
@ -20,19 +20,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef MAPBLOCK_HEADER
|
||||
#define MAPBLOCK_HEADER
|
||||
|
||||
#include <jmutex.h>
|
||||
#include <jmutexautolock.h>
|
||||
#include <exception>
|
||||
#include <set>
|
||||
#include "debug.h"
|
||||
#include "irrlichttypes.h"
|
||||
#include "irr_v3d.h"
|
||||
#include "irr_aabb3d.h"
|
||||
#include "mapnode.h"
|
||||
#include "exceptions.h"
|
||||
#include "serialization.h"
|
||||
#include "constants.h"
|
||||
#include "voxel.h"
|
||||
#include "staticobject.h"
|
||||
#include "nodemetadata.h"
|
||||
#include "nodetimer.h"
|
||||
@ -43,6 +36,7 @@ class Map;
|
||||
class NodeMetadataList;
|
||||
class IGameDef;
|
||||
class MapBlockMesh;
|
||||
class VoxelManipulator;
|
||||
|
||||
#define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff
|
||||
|
||||
@ -514,7 +508,6 @@ public:
|
||||
|
||||
#ifndef SERVER // Only on client
|
||||
MapBlockMesh *mesh;
|
||||
//JMutex mesh_mutex;
|
||||
#endif
|
||||
|
||||
NodeMetadataList m_node_metadata;
|
||||
|
@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "treegen.h"
|
||||
#include "mapgen_v6.h"
|
||||
#include "mapgen_v7.h"
|
||||
#include "serialization.h"
|
||||
#include "util/serialize.h"
|
||||
#include "filesys.h"
|
||||
|
||||
|
@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef MAPGEN_HEADER
|
||||
#define MAPGEN_HEADER
|
||||
|
||||
#include "irrlichttypes_extrabloated.h"
|
||||
#include "irrlichttypes_bloated.h"
|
||||
#include "util/container.h" // UniqueQueue
|
||||
#include "gamedef.h"
|
||||
#include "nodedef.h"
|
||||
|
@ -25,8 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "nodedef.h"
|
||||
#include "voxelalgorithms.h"
|
||||
#include "profiler.h"
|
||||
#include "settings.h" // For g_settings
|
||||
#include "main.h" // For g_profiler
|
||||
#include "emerge.h"
|
||||
|
||||
//////////////////////// Mapgen Singlenode parameter read/write
|
||||
|
@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "irr_v3d.h"
|
||||
#include "irr_aabb3d.h"
|
||||
#include "light.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class INodeDefManager;
|
||||
|
@ -18,12 +18,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
|
||||
#include "mapsector.h"
|
||||
#include "jmutexautolock.h"
|
||||
#ifndef SERVER
|
||||
#include "client.h"
|
||||
#endif
|
||||
#include "exceptions.h"
|
||||
#include "mapblock.h"
|
||||
#include "serialization.h"
|
||||
|
||||
MapSector::MapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
|
||||
differs_from_disk(false),
|
||||
|
@ -20,9 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef MAPSECTOR_HEADER
|
||||
#define MAPSECTOR_HEADER
|
||||
|
||||
#include <jmutex.h>
|
||||
#include "irrlichttypes_bloated.h"
|
||||
#include "exceptions.h"
|
||||
#include "irrlichttypes.h"
|
||||
#include "irr_v2d.h"
|
||||
#include <ostream>
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
@ -18,8 +18,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
|
||||
#include "mesh.h"
|
||||
#include "debug.h"
|
||||
#include "log.h"
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <IAnimatedMesh.h>
|
||||
#include <SAnimatedMesh.h>
|
||||
|
@ -21,14 +21,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#define MODS_HEADER
|
||||
|
||||
#include "irrlichttypes.h"
|
||||
#include <irrList.h>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <exception>
|
||||
#include <list>
|
||||
#include "json/json.h"
|
||||
#include "config.h"
|
||||
|
||||
@ -152,10 +150,9 @@ private:
|
||||
// exists. A name conflict happens when two or more mods
|
||||
// at the same level have the same name but different paths.
|
||||
// Levels (mods in higher levels override mods in lower levels):
|
||||
// 1. common mod in modpack; 2. common mod;
|
||||
// 3. game mod in modpack; 4. game mod;
|
||||
// 5. world mod in modpack; 6. world mod;
|
||||
// 7. addon mod in modpack; 8. addon mod.
|
||||
// 1. game mod in modpack; 2. game mod;
|
||||
// 3. world mod in modpack; 4. world mod;
|
||||
// 5. addon mod in modpack; 6. addon mod.
|
||||
std::set<std::string> m_name_conflicts;
|
||||
|
||||
};
|
||||
|
@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
|
||||
#include "nameidmapping.h"
|
||||
#include "exceptions.h"
|
||||
#include "util/serialize.h"
|
||||
|
||||
void NameIdMapping::serialize(std::ostream &os) const
|
||||
|
@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef NODEMETADATA_HEADER
|
||||
#define NODEMETADATA_HEADER
|
||||
|
||||
#include "irrlichttypes_bloated.h"
|
||||
#include "irr_v3d.h"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#include "nodetimer.h"
|
||||
#include "log.h"
|
||||
#include "serialization.h"
|
||||
#include "util/serialize.h"
|
||||
#include "constants.h" // MAP_BLOCKSIZE
|
||||
|
||||
|
@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef NODETIMER_HEADER
|
||||
#define NODETIMER_HEADER
|
||||
|
||||
#include "irrlichttypes_bloated.h"
|
||||
#include "irr_v3d.h"
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
|
@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include <math.h>
|
||||
#include "noise.h"
|
||||
#include <iostream>
|
||||
#include <string.h> // memset
|
||||
#include "debug.h"
|
||||
#include "util/numeric.h"
|
||||
|
||||
|
@ -19,9 +19,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#include "object_properties.h"
|
||||
#include "irrlichttypes_bloated.h"
|
||||
#include "exceptions.h"
|
||||
#include "util/serialize.h"
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||
#define PP2(x) "("<<(x).X<<","<<(x).Y<<")"
|
||||
|
@ -22,6 +22,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
/******************************************************************************/
|
||||
|
||||
#include "pathfinder.h"
|
||||
#include "environment.h"
|
||||
#include "map.h"
|
||||
#include "log.h"
|
||||
|
||||
#ifdef PATHFINDER_DEBUG
|
||||
#include <iomanip>
|
||||
|
@ -25,10 +25,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
/******************************************************************************/
|
||||
#include <vector>
|
||||
|
||||
#include "server.h"
|
||||
#include "irr_v3d.h"
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Forward declarations */
|
||||
/******************************************************************************/
|
||||
|
||||
class ServerEnvironment;
|
||||
|
||||
/******************************************************************************/
|
||||
/* Typedefs and macros */
|
||||
/******************************************************************************/
|
||||
|
@ -21,7 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "hud.h"
|
||||
#include "constants.h"
|
||||
#include "gamedef.h"
|
||||
#include "connection.h" // PEER_ID_INEXISTENT
|
||||
#include "settings.h"
|
||||
#include "content_sao.h"
|
||||
#include "util/numeric.h"
|
||||
|
@ -194,6 +194,15 @@ public:
|
||||
return m_collisionbox;
|
||||
}
|
||||
|
||||
u32 getFreeHudID() const {
|
||||
size_t size = hud.size();
|
||||
for (size_t i = 0; i != size; i++) {
|
||||
if (!hud[i])
|
||||
return i;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
virtual bool isLocal() const
|
||||
{ return false; }
|
||||
virtual PlayerSAO *getPlayerSAO()
|
||||
|
@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "debug.h"
|
||||
#include "constants.h"
|
||||
#include "gettime.h"
|
||||
#include "threads.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define SWPRINTF_CHARSTRING L"%S"
|
||||
|
@ -20,13 +20,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef PROFILER_HEADER
|
||||
#define PROFILER_HEADER
|
||||
|
||||
#include "irrlichttypes_bloated.h"
|
||||
#include "irrlichttypes.h"
|
||||
#include <string>
|
||||
#include <jmutex.h>
|
||||
#include <jmutexautolock.h>
|
||||
#include <map>
|
||||
#include "util/timetaker.h"
|
||||
#include "util/numeric.h" // paging()
|
||||
#include "debug.h" // assert()
|
||||
|
||||
/*
|
||||
Time profiler
|
||||
|
@ -27,7 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "nodedef.h"
|
||||
#include "util/serialize.h"
|
||||
#include "util/string.h"
|
||||
#include "strfnd.h"
|
||||
#include "util/numeric.h"
|
||||
#include "inventorymanager.h" // deserializing InventoryLocations
|
||||
|
||||
|
@ -2,8 +2,18 @@ add_subdirectory(common)
|
||||
add_subdirectory(cpp_api)
|
||||
add_subdirectory(lua_api)
|
||||
|
||||
set(SCRIPT_SRCS
|
||||
${SCRIPT_COMMON_SRCS}
|
||||
${SCRIPT_CPP_API_SRCS}
|
||||
${SCRIPT_LUA_API_SRCS}
|
||||
# Used by server and client
|
||||
set(common_SCRIPT_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scripting_game.cpp
|
||||
${common_SCRIPT_COMMON_SRCS}
|
||||
${common_SCRIPT_CPP_API_SRCS}
|
||||
${common_SCRIPT_LUA_API_SRCS}
|
||||
PARENT_SCOPE)
|
||||
|
||||
# Used by client only
|
||||
set(minetest_SCRIPT_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scripting_mainmenu.cpp
|
||||
${minetest_SCRIPT_COMMON_SRCS}
|
||||
${minetest_SCRIPT_CPP_API_SRCS}
|
||||
${minetest_SCRIPT_LUA_API_SRCS}
|
||||
PARENT_SCOPE)
|
||||
|
@ -1,6 +1,11 @@
|
||||
set(SCRIPT_COMMON_SRCS
|
||||
# Used by server and client
|
||||
set(common_SCRIPT_COMMON_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/c_content.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/c_converter.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/c_types.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/c_internal.cpp
|
||||
PARENT_SCOPE)
|
||||
|
||||
# Used by client only
|
||||
set(minetest_SCRIPT_COMMON_SRCS
|
||||
PARENT_SCOPE)
|
||||
|
@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "server.h"
|
||||
#include "log.h"
|
||||
#include "tool.h"
|
||||
#include "server.h"
|
||||
#include "serverobject.h"
|
||||
#include "mapgen.h"
|
||||
|
||||
struct EnumString es_TileAnimationType[] =
|
||||
@ -694,8 +694,7 @@ void push_tool_capabilities(lua_State *L,
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void push_inventory_list(Inventory *inv, const char *name,
|
||||
lua_State *L)
|
||||
void push_inventory_list(lua_State *L, Inventory *inv, const char *name)
|
||||
{
|
||||
InventoryList *invlist = inv->getList(name);
|
||||
if(invlist == NULL){
|
||||
@ -709,8 +708,8 @@ void push_inventory_list(Inventory *inv, const char *name,
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void read_inventory_list(Inventory *inv, const char *name,
|
||||
lua_State *L, int tableindex, Server* srv,int forcesize)
|
||||
void read_inventory_list(lua_State *L, int tableindex,
|
||||
Inventory *inv, const char *name, Server* srv, int forcesize)
|
||||
{
|
||||
if(tableindex < 0)
|
||||
tableindex = lua_gettop(L) + 1 + tableindex;
|
||||
|
@ -87,14 +87,13 @@ void read_object_properties (lua_State *L,
|
||||
int index,
|
||||
ObjectProperties *prop);
|
||||
|
||||
//TODO fix parameter oreder!
|
||||
void push_inventory_list (Inventory *inv,
|
||||
const char *name,
|
||||
lua_State *L);
|
||||
void read_inventory_list (Inventory *inv,
|
||||
const char *name,
|
||||
lua_State *L,
|
||||
void push_inventory_list (lua_State *L,
|
||||
Inventory *inv,
|
||||
const char *name);
|
||||
void read_inventory_list (lua_State *L,
|
||||
int tableindex,
|
||||
Inventory *inv,
|
||||
const char *name,
|
||||
Server* srv,
|
||||
int forcesize=-1);
|
||||
|
||||
|
@ -18,17 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
|
||||
#include "common/c_internal.h"
|
||||
#include "server.h"
|
||||
#include "cpp_api/scriptapi.h"
|
||||
|
||||
ScriptApi* get_scriptapi(lua_State *L)
|
||||
{
|
||||
// Get server from registry
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "scriptapi");
|
||||
ScriptApi* sapi_ptr = (ScriptApi*) lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return sapi_ptr;
|
||||
}
|
||||
#include "debug.h"
|
||||
|
||||
std::string script_get_backtrace(lua_State *L)
|
||||
{
|
||||
@ -51,15 +41,108 @@ std::string script_get_backtrace(lua_State *L)
|
||||
return s;
|
||||
}
|
||||
|
||||
void script_error(lua_State* L,const char *fmt, ...)
|
||||
void script_error(lua_State *L, const char *fmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
char buf[10000];
|
||||
vsnprintf(buf, 10000, fmt, argp);
|
||||
va_end(argp);
|
||||
//errorstream<<"SCRIPT ERROR: "<<buf;
|
||||
throw LuaError(L, buf);
|
||||
}
|
||||
|
||||
// Push the list of callbacks (a lua table).
|
||||
// Then push nargs arguments.
|
||||
// Then call this function, which
|
||||
// - runs the callbacks
|
||||
// - removes the table and arguments from the lua stack
|
||||
// - pushes the return value, computed depending on mode
|
||||
void script_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode)
|
||||
{
|
||||
// Insert the return value into the lua stack, below the table
|
||||
assert(lua_gettop(L) >= nargs + 1);
|
||||
lua_pushnil(L);
|
||||
lua_insert(L, -(nargs + 1) - 1);
|
||||
// Stack now looks like this:
|
||||
// ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n>
|
||||
|
||||
int rv = lua_gettop(L) - nargs - 1;
|
||||
int table = rv + 1;
|
||||
int arg = table + 1;
|
||||
|
||||
luaL_checktype(L, table, LUA_TTABLE);
|
||||
|
||||
// Foreach
|
||||
lua_pushnil(L);
|
||||
bool first_loop = true;
|
||||
while(lua_next(L, table) != 0){
|
||||
// key at index -2 and value at index -1
|
||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||
// Call function
|
||||
for(int i = 0; i < nargs; i++)
|
||||
lua_pushvalue(L, arg+i);
|
||||
if(lua_pcall(L, nargs, 1, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
|
||||
// Move return value to designated space in stack
|
||||
// Or pop it
|
||||
if(first_loop){
|
||||
// Result of first callback is always moved
|
||||
lua_replace(L, rv);
|
||||
first_loop = false;
|
||||
} else {
|
||||
// Otherwise, what happens depends on the mode
|
||||
if(mode == RUN_CALLBACKS_MODE_FIRST)
|
||||
lua_pop(L, 1);
|
||||
else if(mode == RUN_CALLBACKS_MODE_LAST)
|
||||
lua_replace(L, rv);
|
||||
else if(mode == RUN_CALLBACKS_MODE_AND ||
|
||||
mode == RUN_CALLBACKS_MODE_AND_SC){
|
||||
if((bool)lua_toboolean(L, rv) == true &&
|
||||
(bool)lua_toboolean(L, -1) == false)
|
||||
lua_replace(L, rv);
|
||||
else
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else if(mode == RUN_CALLBACKS_MODE_OR ||
|
||||
mode == RUN_CALLBACKS_MODE_OR_SC){
|
||||
if((bool)lua_toboolean(L, rv) == false &&
|
||||
(bool)lua_toboolean(L, -1) == true)
|
||||
lua_replace(L, rv);
|
||||
else
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
|
||||
// Handle short circuit modes
|
||||
if(mode == RUN_CALLBACKS_MODE_AND_SC &&
|
||||
(bool)lua_toboolean(L, rv) == false)
|
||||
break;
|
||||
else if(mode == RUN_CALLBACKS_MODE_OR_SC &&
|
||||
(bool)lua_toboolean(L, rv) == true)
|
||||
break;
|
||||
|
||||
// value removed, keep key for next iteration
|
||||
}
|
||||
|
||||
// Remove stuff from stack, leaving only the return value
|
||||
lua_settop(L, rv);
|
||||
|
||||
// Fix return value in case no callbacks were called
|
||||
if(first_loop){
|
||||
if(mode == RUN_CALLBACKS_MODE_AND ||
|
||||
mode == RUN_CALLBACKS_MODE_AND_SC){
|
||||
lua_pop(L, 1);
|
||||
lua_pushboolean(L, true);
|
||||
}
|
||||
else if(mode == RUN_CALLBACKS_MODE_OR ||
|
||||
mode == RUN_CALLBACKS_MODE_OR_SC){
|
||||
lua_pop(L, 1);
|
||||
lua_pushboolean(L, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,34 +27,46 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef C_INTERNAL_H_
|
||||
#define C_INTERNAL_H_
|
||||
|
||||
class Server;
|
||||
class ScriptApi;
|
||||
#include <iostream>
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
#define luamethod(class, name) {#name, class::l_##name}
|
||||
#define STACK_TO_SERVER(L) get_scriptapi(L)->getServer()
|
||||
#define API_FCT(name) registerFunction(L,#name,l_##name,top)
|
||||
#include "common/c_types.h"
|
||||
|
||||
#define REGISTER_LUA_REF(cln) \
|
||||
class ModApi_##cln : public ModApiBase { \
|
||||
public: \
|
||||
ModApi_##cln() : ModApiBase() {}; \
|
||||
bool Initialize(lua_State* L, int top) { \
|
||||
cln::Register(L); \
|
||||
return true; \
|
||||
}; \
|
||||
}; \
|
||||
ModApi_##cln macro_generated_prototype__##cln;
|
||||
// What script_run_callbacks does with the return values of callbacks.
|
||||
// Regardless of the mode, if only one callback is defined,
|
||||
// its return value is the total return value.
|
||||
// Modes only affect the case where 0 or >= 2 callbacks are defined.
|
||||
enum RunCallbacksMode
|
||||
{
|
||||
// Returns the return value of the first callback
|
||||
// Returns nil if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_FIRST,
|
||||
// Returns the return value of the last callback
|
||||
// Returns nil if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_LAST,
|
||||
// If any callback returns a false value, the first such is returned
|
||||
// Otherwise, the first callback's return value (trueish) is returned
|
||||
// Returns true if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_AND,
|
||||
// Like above, but stops calling callbacks (short circuit)
|
||||
// after seeing the first false value
|
||||
RUN_CALLBACKS_MODE_AND_SC,
|
||||
// If any callback returns a true value, the first such is returned
|
||||
// Otherwise, the first callback's return value (falseish) is returned
|
||||
// Returns false if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_OR,
|
||||
// Like above, but stops calling callbacks (short circuit)
|
||||
// after seeing the first true value
|
||||
RUN_CALLBACKS_MODE_OR_SC,
|
||||
// Note: "a true value" and "a false value" refer to values that
|
||||
// are converted by lua_toboolean to true or false, respectively.
|
||||
};
|
||||
|
||||
|
||||
ScriptApi* get_scriptapi (lua_State *L);
|
||||
std::string script_get_backtrace (lua_State *L);
|
||||
void script_error (lua_State *L, const char *fmt, ...);
|
||||
void script_run_callbacks (lua_State *L, int nargs,
|
||||
RunCallbacksMode mode);
|
||||
|
||||
#endif /* C_INTERNAL_H_ */
|
||||
|
@ -50,26 +50,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class ModNameStorer
|
||||
{
|
||||
private:
|
||||
lua_State *L;
|
||||
public:
|
||||
ModNameStorer(lua_State *L_, const std::string modname):
|
||||
L(L_)
|
||||
{
|
||||
// Store current modname in registry
|
||||
lua_pushstring(L, modname.c_str());
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
|
||||
}
|
||||
~ModNameStorer()
|
||||
{
|
||||
// Clear current modname in registry
|
||||
lua_pushnil(L);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
|
||||
}
|
||||
};
|
||||
|
||||
class LuaError : public std::exception
|
||||
{
|
||||
public:
|
||||
|
@ -1,4 +1,5 @@
|
||||
set(SCRIPT_CPP_API_SRCS
|
||||
# Used by server and client
|
||||
set(common_SCRIPT_CPP_API_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_base.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_entity.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_env.cpp
|
||||
@ -7,5 +8,10 @@ set(SCRIPT_CPP_API_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_node.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_nodemeta.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_player.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scriptapi.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_server.cpp
|
||||
PARENT_SCOPE)
|
||||
|
||||
# Used by client only
|
||||
set(minetest_SCRIPT_CPP_API_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/s_mainmenu.cpp
|
||||
PARENT_SCOPE)
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
#include "cpp_api/s_base.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "lua_api/l_object.h"
|
||||
#include "serverobject.h"
|
||||
#include "debug.h"
|
||||
#include "log.h"
|
||||
#include "mods.h"
|
||||
#include "util/string.h"
|
||||
|
||||
|
||||
extern "C" {
|
||||
#include "lualib.h"
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstdarg>
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
#include "cpp_api/s_base.h"
|
||||
#include "lua_api/l_object.h"
|
||||
#include "serverobject.h"
|
||||
|
||||
ScriptApiBase::ScriptApiBase() :
|
||||
m_luastackmutex(),
|
||||
#ifdef LOCK_DEBUG
|
||||
m_locked(false),
|
||||
#endif
|
||||
m_luastack(0),
|
||||
m_server(0),
|
||||
m_environment(0)
|
||||
class ModNameStorer
|
||||
{
|
||||
private:
|
||||
lua_State *L;
|
||||
public:
|
||||
ModNameStorer(lua_State *L_, const std::string modname):
|
||||
L(L_)
|
||||
{
|
||||
// Store current modname in registry
|
||||
lua_pushstring(L, modname.c_str());
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
|
||||
}
|
||||
~ModNameStorer()
|
||||
{
|
||||
// Clear current modname in registry
|
||||
lua_pushnil(L);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "minetest_current_modname");
|
||||
}
|
||||
};
|
||||
|
||||
static int loadScript_ErrorHandler(lua_State *L) {
|
||||
lua_getfield(L, LUA_GLOBALSINDEX, "debug");
|
||||
if (!lua_istable(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
lua_getfield(L, -1, "traceback");
|
||||
if (!lua_isfunction(L, -1)) {
|
||||
lua_pop(L, 2);
|
||||
return 1;
|
||||
}
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushinteger(L, 2);
|
||||
lua_call(L, 2, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
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()
|
||||
{
|
||||
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_start(argp, fmt);
|
||||
@ -65,130 +176,34 @@ void ScriptApiBase::scriptError(const char *fmt, ...)
|
||||
|
||||
void ScriptApiBase::stackDump(std::ostream &o)
|
||||
{
|
||||
int i;
|
||||
int top = lua_gettop(m_luastack);
|
||||
for (i = 1; i <= top; i++) { /* repeat for each level */
|
||||
int t = lua_type(m_luastack, i);
|
||||
switch (t) {
|
||||
int i;
|
||||
int top = lua_gettop(m_luastack);
|
||||
for (i = 1; i <= top; i++) { /* repeat for each level */
|
||||
int t = lua_type(m_luastack, i);
|
||||
switch (t) {
|
||||
|
||||
case LUA_TSTRING: /* strings */
|
||||
o<<"\""<<lua_tostring(m_luastack, i)<<"\"";
|
||||
break;
|
||||
case LUA_TSTRING: /* strings */
|
||||
o<<"\""<<lua_tostring(m_luastack, i)<<"\"";
|
||||
break;
|
||||
|
||||
case LUA_TBOOLEAN: /* booleans */
|
||||
o<<(lua_toboolean(m_luastack, i) ? "true" : "false");
|
||||
break;
|
||||
case LUA_TBOOLEAN: /* booleans */
|
||||
o<<(lua_toboolean(m_luastack, i) ? "true" : "false");
|
||||
break;
|
||||
|
||||
case LUA_TNUMBER: /* numbers */ {
|
||||
char buf[10];
|
||||
snprintf(buf, 10, "%g", lua_tonumber(m_luastack, i));
|
||||
o<<buf;
|
||||
break; }
|
||||
case LUA_TNUMBER: /* numbers */ {
|
||||
char buf[10];
|
||||
snprintf(buf, 10, "%g", lua_tonumber(m_luastack, i));
|
||||
o<<buf;
|
||||
break; }
|
||||
|
||||
default: /* other values */
|
||||
o<<lua_typename(m_luastack, t);
|
||||
break;
|
||||
default: /* other values */
|
||||
o<<lua_typename(m_luastack, t);
|
||||
break;
|
||||
|
||||
}
|
||||
o<<" ";
|
||||
}
|
||||
o<<std::endl;
|
||||
}
|
||||
|
||||
// Push the list of callbacks (a lua table).
|
||||
// Then push nargs arguments.
|
||||
// Then call this function, which
|
||||
// - runs the callbacks
|
||||
// - removes the table and arguments from the lua stack
|
||||
// - pushes the return value, computed depending on mode
|
||||
void ScriptApiBase::runCallbacks(int nargs,RunCallbacksMode mode)
|
||||
{
|
||||
lua_State *L = getStack();
|
||||
|
||||
// Insert the return value into the lua stack, below the table
|
||||
assert(lua_gettop(L) >= nargs + 1);
|
||||
lua_pushnil(L);
|
||||
lua_insert(L, -(nargs + 1) - 1);
|
||||
// Stack now looks like this:
|
||||
// ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n>
|
||||
|
||||
int 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)
|
||||
|
@ -21,67 +21,37 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#define S_BASE_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
}
|
||||
|
||||
#include "irrlichttypes.h"
|
||||
#include "jmutex.h"
|
||||
#include "jmutexautolock.h"
|
||||
#include "common/c_types.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define LOCK_DEBUG
|
||||
#define SCRIPTAPI_LOCK_DEBUG
|
||||
|
||||
class Server;
|
||||
class Environment;
|
||||
class GUIEngine;
|
||||
class ServerActiveObject;
|
||||
class LuaABM;
|
||||
class InvRef;
|
||||
class ModApiBase;
|
||||
class ModApiEnvMod;
|
||||
class ObjectRef;
|
||||
class NodeMetaRef;
|
||||
|
||||
|
||||
/* definitions */
|
||||
// What scriptapi_run_callbacks does with the return values of callbacks.
|
||||
// Regardless of the mode, if only one callback is defined,
|
||||
// its return value is the total return value.
|
||||
// Modes only affect the case where 0 or >= 2 callbacks are defined.
|
||||
enum RunCallbacksMode
|
||||
{
|
||||
// Returns the return value of the first callback
|
||||
// Returns nil if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_FIRST,
|
||||
// Returns the return value of the last callback
|
||||
// Returns nil if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_LAST,
|
||||
// If any callback returns a false value, the first such is returned
|
||||
// Otherwise, the first callback's return value (trueish) is returned
|
||||
// Returns true if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_AND,
|
||||
// Like above, but stops calling callbacks (short circuit)
|
||||
// after seeing the first false value
|
||||
RUN_CALLBACKS_MODE_AND_SC,
|
||||
// If any callback returns a true value, the first such is returned
|
||||
// Otherwise, the first callback's return value (falseish) is returned
|
||||
// Returns false if list of callbacks is empty
|
||||
RUN_CALLBACKS_MODE_OR,
|
||||
// Like above, but stops calling callbacks (short circuit)
|
||||
// after seeing the first true value
|
||||
RUN_CALLBACKS_MODE_OR_SC,
|
||||
// Note: "a true value" and "a false value" refer to values that
|
||||
// are converted by lua_toboolean to true or false, respectively.
|
||||
};
|
||||
|
||||
|
||||
class ScriptApiBase {
|
||||
public:
|
||||
|
||||
ScriptApiBase();
|
||||
virtual ~ScriptApiBase();
|
||||
|
||||
bool loadMod(const std::string &scriptpath, const std::string &modname);
|
||||
bool loadScript(const std::string &scriptpath);
|
||||
|
||||
/* object */
|
||||
void addObjectReference(ServerActiveObject *cobj);
|
||||
void removeObjectReference(ServerActiveObject *cobj);
|
||||
|
||||
ScriptApiBase();
|
||||
|
||||
protected:
|
||||
friend class LuaABM;
|
||||
friend class InvRef;
|
||||
@ -91,78 +61,35 @@ protected:
|
||||
friend class ModApiEnvMod;
|
||||
friend class LuaVoxelManip;
|
||||
|
||||
|
||||
inline lua_State* getStack()
|
||||
lua_State* getStack()
|
||||
{ return m_luastack; }
|
||||
|
||||
bool setStack(lua_State* stack) {
|
||||
if (m_luastack == 0) {
|
||||
m_luastack = stack;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void realityCheck();
|
||||
void scriptError(const char *fmt, ...);
|
||||
void stackDump(std::ostream &o);
|
||||
void runCallbacks(int nargs,RunCallbacksMode mode);
|
||||
|
||||
inline Server* getServer() { return m_server; }
|
||||
Server* getServer() { return m_server; }
|
||||
void setServer(Server* server) { m_server = server; }
|
||||
|
||||
Environment* getEnv() { return m_environment; }
|
||||
void setEnv(Environment* env) { m_environment = env; }
|
||||
|
||||
GUIEngine* getGuiEngine() { return m_guiengine; }
|
||||
void setGuiEngine(GUIEngine* guiengine) { m_guiengine = guiengine; }
|
||||
|
||||
void objectrefGetOrCreate(ServerActiveObject *cobj);
|
||||
void objectrefGet(u16 id);
|
||||
|
||||
JMutex m_luastackmutex;
|
||||
#ifdef LOCK_DEBUG
|
||||
JMutex m_luastackmutex;
|
||||
#ifdef SCRIPTAPI_LOCK_DEBUG
|
||||
bool m_locked;
|
||||
#endif
|
||||
private:
|
||||
lua_State* m_luastack;
|
||||
|
||||
Server* m_server;
|
||||
Environment* m_environment;
|
||||
|
||||
|
||||
Server* m_server;
|
||||
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_ */
|
||||
|
@ -18,15 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
|
||||
#include "cpp_api/s_entity.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "log.h"
|
||||
#include "object_properties.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
bool ScriptApiEntity::luaentity_Add(u16 id, const char *name)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
@ -18,16 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
|
||||
#include "cpp_api/s_env.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "log.h"
|
||||
#include "environment.h"
|
||||
#include "mapgen.h"
|
||||
#include "lua_api/l_env.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp,
|
||||
u32 blockseed)
|
||||
{
|
||||
@ -40,7 +37,7 @@ void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp,
|
||||
push_v3s16(L, minp);
|
||||
push_v3s16(L, maxp);
|
||||
lua_pushnumber(L, blockseed);
|
||||
runCallbacks(3, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 3, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
void ScriptApiEnv::environment_Step(float dtime)
|
||||
@ -53,7 +50,7 @@ void ScriptApiEnv::environment_Step(float dtime)
|
||||
lua_getfield(L, -1, "registered_globalsteps");
|
||||
// Call callbacks
|
||||
lua_pushnumber(L, dtime);
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams)
|
||||
@ -80,7 +77,7 @@ void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams)
|
||||
lua_pushstring(L, flagstr.c_str());
|
||||
lua_setfield(L, -2, "flags");
|
||||
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
|
||||
|
63
src/script/cpp_api/s_internal.h
Normal file
63
src/script/cpp_api/s_internal.h
Normal file
@ -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_internal.h"
|
||||
#include "inventorymanager.h"
|
||||
#include "lua_api/l_inventory.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_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "lua_api/l_item.h"
|
||||
#include "server.h"
|
||||
#include "log.h"
|
||||
#include "util/pointedthing.h"
|
||||
|
||||
bool ScriptApiItem::item_OnDrop(ItemStack &item,
|
||||
ServerActiveObject *dropper, v3f pos)
|
||||
|
80
src/script/cpp_api/s_mainmenu.cpp
Normal file
80
src/script/cpp_api/s_mainmenu.cpp
Normal file
@ -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));
|
||||
}
|
49
src/script/cpp_api/s_mainmenu.h
Normal file
49
src/script/cpp_api/s_mainmenu.h
Normal file
@ -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_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "nodedef.h"
|
||||
#include "server.h"
|
||||
#include "environment.h"
|
||||
|
||||
|
||||
struct EnumString ScriptApiNode::es_DrawType[] =
|
||||
|
@ -18,16 +18,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
|
||||
#include "cpp_api/s_nodemeta.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "nodedef.h"
|
||||
#include "mapnode.h"
|
||||
#include "server.h"
|
||||
#include "environment.h"
|
||||
#include "lua_api/l_item.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
// Return number of accepted items to be moved
|
||||
int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
|
||||
const std::string &from_list, int from_index,
|
||||
|
@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
|
||||
#include "cpp_api/s_player.h"
|
||||
#include "cpp_api/s_internal.h"
|
||||
|
||||
void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
|
||||
{
|
||||
@ -28,7 +29,7 @@ void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
|
||||
lua_getfield(L, -1, "registered_on_newplayers");
|
||||
// Call callbacks
|
||||
objectrefGetOrCreate(player);
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player)
|
||||
@ -40,7 +41,7 @@ void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player)
|
||||
lua_getfield(L, -1, "registered_on_dieplayers");
|
||||
// Call callbacks
|
||||
objectrefGetOrCreate(player);
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
|
||||
@ -52,7 +53,7 @@ bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
|
||||
lua_getfield(L, -1, "registered_on_respawnplayers");
|
||||
// Call callbacks
|
||||
objectrefGetOrCreate(player);
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_OR);
|
||||
script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_OR);
|
||||
bool positioning_handled_by_some = lua_toboolean(L, -1);
|
||||
return positioning_handled_by_some;
|
||||
}
|
||||
@ -66,7 +67,7 @@ void ScriptApiPlayer::on_joinplayer(ServerActiveObject *player)
|
||||
lua_getfield(L, -1, "registered_on_joinplayers");
|
||||
// Call callbacks
|
||||
objectrefGetOrCreate(player);
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player)
|
||||
@ -78,7 +79,7 @@ void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player)
|
||||
lua_getfield(L, -1, "registered_on_leaveplayers");
|
||||
// Call callbacks
|
||||
objectrefGetOrCreate(player);
|
||||
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 1, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
void ScriptApiPlayer::on_cheat(ServerActiveObject *player,
|
||||
@ -94,7 +95,7 @@ void ScriptApiPlayer::on_cheat(ServerActiveObject *player,
|
||||
lua_newtable(L);
|
||||
lua_pushlstring(L, cheat_type.c_str(), cheat_type.size());
|
||||
lua_setfield(L, -2, "type");
|
||||
runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
|
||||
script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_FIRST);
|
||||
}
|
||||
|
||||
void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player,
|
||||
@ -121,7 +122,7 @@ void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player,
|
||||
lua_pushlstring(L, value.c_str(), value.size());
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
runCallbacks(3, RUN_CALLBACKS_MODE_OR_SC);
|
||||
script_run_callbacks(L, 3, RUN_CALLBACKS_MODE_OR_SC);
|
||||
}
|
||||
ScriptApiPlayer::~ScriptApiPlayer() {
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef S_PLAYER_H_
|
||||
#define S_PLAYER_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "cpp_api/s_base.h"
|
||||
|
||||
|
||||
|
151
src/script/cpp_api/s_server.cpp
Normal file
151
src/script/cpp_api/s_server.cpp
Normal file
@ -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);
|
||||
}
|
||||
|
52
src/script/cpp_api/s_server.h
Normal file
52
src/script/cpp_api/s_server.h
Normal file
@ -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_craft.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_env.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_inventory.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_item.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/luaapi.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_mapgen.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_nodemeta.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_nodetimer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_noise.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_object.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_particles.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_rollback.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_server.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_util.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_vmanip.cpp
|
||||
PARENT_SCOPE)
|
||||
|
||||
# Used by client only
|
||||
set(minetest_SCRIPT_LUA_API_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/l_mainmenu.cpp
|
||||
PARENT_SCOPE)
|
||||
|
@ -17,32 +17,35 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "cpp_api/scriptapi.h"
|
||||
#include "lua_api/l_base.h"
|
||||
#include "common/c_internal.h"
|
||||
#include "log.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "cpp_api/s_base.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
ScriptApiBase* ModApiBase::getScriptApiBase(lua_State *L) {
|
||||
// Get server from registry
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "scriptapi");
|
||||
ScriptApiBase *sapi_ptr = (ScriptApiBase*) lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return sapi_ptr;
|
||||
}
|
||||
|
||||
ModApiBase::ModApiBase() {
|
||||
ScriptApi::registerModApiModule(this);
|
||||
Server* ModApiBase::getServer(lua_State *L) {
|
||||
return getScriptApiBase(L)->getServer();
|
||||
}
|
||||
|
||||
Server* ModApiBase::getServer(lua_State* L) {
|
||||
return get_scriptapi(L)->getServer();
|
||||
Environment* ModApiBase::getEnv(lua_State *L) {
|
||||
return getScriptApiBase(L)->getEnv();
|
||||
}
|
||||
|
||||
Environment* ModApiBase::getEnv(lua_State* L) {
|
||||
return get_scriptapi(L)->getEnv();
|
||||
GUIEngine* ModApiBase::getGuiEngine(lua_State *L) {
|
||||
return getScriptApiBase(L)->getGuiEngine();
|
||||
}
|
||||
|
||||
bool ModApiBase::registerFunction( lua_State* L,
|
||||
const char* name,
|
||||
lua_CFunction fct,
|
||||
int top
|
||||
) {
|
||||
bool ModApiBase::registerFunction(lua_State *L,
|
||||
const char *name,
|
||||
lua_CFunction fct,
|
||||
int top
|
||||
) {
|
||||
//TODO check presence first!
|
||||
|
||||
lua_pushstring(L,name);
|
||||
@ -51,13 +54,3 @@ bool ModApiBase::registerFunction( lua_State* L,
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct EnumString es_BiomeTerrainType[] =
|
||||
{
|
||||
{BIOME_TERRAIN_NORMAL, "normal"},
|
||||
{BIOME_TERRAIN_LIQUID, "liquid"},
|
||||
{BIOME_TERRAIN_NETHER, "nether"},
|
||||
{BIOME_TERRAIN_AETHER, "aether"},
|
||||
{BIOME_TERRAIN_FLAT, "flat"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
@ -20,44 +20,43 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef L_BASE_H_
|
||||
#define L_BASE_H_
|
||||
|
||||
#include "biome.h"
|
||||
#include "common/c_types.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
extern struct EnumString es_BiomeTerrainType[];
|
||||
|
||||
class ScriptApi;
|
||||
class ScriptApiBase;
|
||||
class Server;
|
||||
class Environment;
|
||||
class GUIEngine;
|
||||
|
||||
typedef class ModApiBase {
|
||||
|
||||
public:
|
||||
ModApiBase();
|
||||
|
||||
virtual bool Initialize(lua_State* L, int top) = 0;
|
||||
virtual ~ModApiBase() {};
|
||||
class ModApiBase {
|
||||
|
||||
protected:
|
||||
static Server* getServer( lua_State* L);
|
||||
static Environment* getEnv( lua_State* L);
|
||||
static bool registerFunction( lua_State* L,
|
||||
const char* name,
|
||||
lua_CFunction fct,
|
||||
int top
|
||||
);
|
||||
} ModApiBase;
|
||||
static ScriptApiBase* getScriptApiBase(lua_State *L);
|
||||
static Server* getServer(lua_State *L);
|
||||
static Environment* getEnv(lua_State *L);
|
||||
static GUIEngine* getGuiEngine(lua_State *L);
|
||||
|
||||
#if (defined(WIN32) || defined(_WIN32_WCE))
|
||||
#define NO_MAP_LOCK_REQUIRED
|
||||
#else
|
||||
#include "main.h"
|
||||
#include "profiler.h"
|
||||
#define NO_MAP_LOCK_REQUIRED ScopeProfiler nolocktime(g_profiler,"Scriptapi: unlockable time",SPT_ADD)
|
||||
//#define NO_ENVLOCK_REQUIRED assert(getServer(L).m_env_mutex.IsLocked() == false)
|
||||
#endif
|
||||
// Get an arbitrary subclass of ScriptApiBase
|
||||
// by using dynamic_cast<> on getScriptApiBase()
|
||||
template<typename T>
|
||||
static T* getScriptApi(lua_State *L) {
|
||||
ScriptApiBase *scriptIface = getScriptApiBase(L);
|
||||
T *scriptIfaceDowncast = dynamic_cast<T*>(scriptIface);
|
||||
if (!scriptIfaceDowncast) {
|
||||
throw LuaError(L, "Requested unavailable ScriptApi - core engine bug!");
|
||||
}
|
||||
return scriptIfaceDowncast;
|
||||
}
|
||||
|
||||
static bool registerFunction(lua_State *L,
|
||||
const char* name,
|
||||
lua_CFunction fct,
|
||||
int top
|
||||
);
|
||||
};
|
||||
|
||||
#endif /* L_BASE_H_ */
|
||||
|
@ -19,20 +19,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
|
||||
#include "lua_api/l_craft.h"
|
||||
#include "common/c_internal.h"
|
||||
#include "lua_api/l_internal.h"
|
||||
#include "lua_api/l_item.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "server.h"
|
||||
#include "lua_api/l_item.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
ModApiCraft::ModApiCraft()
|
||||
: ModApiBase() {
|
||||
|
||||
}
|
||||
#include "craftdef.h"
|
||||
|
||||
struct EnumString ModApiCraft::es_CraftMethod[] =
|
||||
{
|
||||
@ -463,15 +455,10 @@ int ModApiCraft::l_get_all_craft_recipes(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool ModApiCraft::Initialize(lua_State* L, int top) {
|
||||
bool retval = true;
|
||||
|
||||
retval &= API_FCT(get_all_craft_recipes);
|
||||
retval &= API_FCT(get_craft_recipe);
|
||||
retval &= API_FCT(get_craft_result);
|
||||
retval &= API_FCT(register_craft);
|
||||
|
||||
return retval;
|
||||
void ModApiCraft::Initialize(lua_State *L, int top)
|
||||
{
|
||||
API_FCT(get_all_craft_recipes);
|
||||
API_FCT(get_craft_recipe);
|
||||
API_FCT(get_craft_result);
|
||||
API_FCT(register_craft);
|
||||
}
|
||||
|
||||
ModApiCraft modapicraft_prototype;
|
||||
|
@ -20,19 +20,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#ifndef L_CRAFT_H_
|
||||
#define L_CRAFT_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
}
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
#include "craftdef.h"
|
||||
|
||||
struct CraftReplacements;
|
||||
|
||||
class ModApiCraft : public ModApiBase {
|
||||
public:
|
||||
ModApiCraft();
|
||||
bool Initialize(lua_State* L, int top);
|
||||
private:
|
||||
static int l_register_craft(lua_State *L);
|
||||
static int l_get_craft_recipe(lua_State *L);
|
||||
@ -47,6 +42,9 @@ private:
|
||||
int &width, std::vector<std::string> &recipe);
|
||||
|
||||
static struct EnumString es_CraftMethod[];
|
||||
|
||||
public:
|
||||
static void Initialize(lua_State *L, int top);
|
||||
};
|
||||
|
||||
#endif /* L_CRAFT_H_ */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user