aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/common_irrlicht.h29
-rw-r--r--src/content_cao.cpp149
-rw-r--r--src/content_cao.h40
-rw-r--r--src/content_inventory.cpp6
-rw-r--r--src/content_inventory.h2
-rw-r--r--src/content_object.h2
-rw-r--r--src/content_sao.cpp154
-rw-r--r--src/content_sao.h46
-rw-r--r--src/environment.cpp39
-rw-r--r--src/environment.h17
-rw-r--r--src/inventory.cpp4
-rw-r--r--src/irrlichttypes.h52
-rw-r--r--src/porting.cpp10
-rw-r--r--src/script.cpp130
-rw-r--r--src/script.h33
-rw-r--r--src/scriptapi.cpp422
-rw-r--r--src/scriptapi.h43
-rw-r--r--src/server.cpp187
-rw-r--r--src/server.h15
-rw-r--r--src/serverobject.cpp11
-rw-r--r--src/serverobject.h6
22 files changed, 1212 insertions, 187 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f75c182bd..b41fc4a6c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -94,6 +94,8 @@ configure_file(
)
set(common_SRCS
+ scriptapi.cpp
+ script.cpp
log.cpp
content_sao.cpp
mapgen.cpp
diff --git a/src/common_irrlicht.h b/src/common_irrlicht.h
index f4c2f76ec..379c2d15a 100644
--- a/src/common_irrlicht.h
+++ b/src/common_irrlicht.h
@@ -23,13 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define endSceneX(d){d->draw2DLine(v2s32(0,0),v2s32(1,0),\
video::SColor(255,30,30,30));d->endScene();}
-#include <irrTypes.h>
-#include <vector2d.h>
-#include <vector3d.h>
-#include <irrMap.h>
-#include <irrList.h>
-#include <irrArray.h>
-#include <aabbox3d.h>
+#include "irrlichttypes.h"
+
#ifndef SERVER
#include <SColor.h>
#include <IMesh.h>
@@ -43,26 +38,6 @@ video::SColor(255,30,30,30));d->endScene();}
#include <IGUIElement.h>
#include <IGUIEnvironment.h>
#endif
-using namespace irr;
-typedef core::vector3df v3f;
-typedef core::vector3d<s16> v3s16;
-typedef core::vector3d<s32> v3s32;
-
-typedef core::vector2d<f32> v2f;
-typedef core::vector2d<s16> v2s16;
-typedef core::vector2d<s32> v2s32;
-typedef core::vector2d<u32> v2u32;
-typedef core::vector2d<f32> v2f32;
-
-#ifdef _MSC_VER
- // Windows
- typedef unsigned long long u64;
-#else
- // Posix
- #include <stdint.h>
- typedef uint64_t u64;
- //typedef unsigned long long u64;
-#endif
#endif
diff --git a/src/content_cao.cpp b/src/content_cao.cpp
index 6cb2cee38..157a51886 100644
--- a/src/content_cao.cpp
+++ b/src/content_cao.cpp
@@ -1264,3 +1264,152 @@ void MobV2CAO::setLooks(const std::string &looks)
selection_size.X);
}
+/*
+ LuaEntityCAO
+*/
+
+// Prototype
+LuaEntityCAO proto_LuaEntityCAO;
+
+LuaEntityCAO::LuaEntityCAO():
+ ClientActiveObject(0),
+ m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.),
+ m_node(NULL),
+ m_position(v3f(0,10*BS,0))
+{
+ ClientActiveObject::registerType(getType(), create);
+}
+
+LuaEntityCAO::~LuaEntityCAO()
+{
+}
+
+ClientActiveObject* LuaEntityCAO::create()
+{
+ return new LuaEntityCAO();
+}
+
+void LuaEntityCAO::addToScene(scene::ISceneManager *smgr)
+{
+ if(m_node != NULL)
+ return;
+
+ video::IVideoDriver* driver = smgr->getVideoDriver();
+
+ scene::SMesh *mesh = new scene::SMesh();
+ scene::IMeshBuffer *buf = new scene::SMeshBuffer();
+ video::SColor c(255,255,255,255);
+ video::S3DVertex vertices[4] =
+ {
+ /*video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
+ video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
+ video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
+ video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),*/
+ video::S3DVertex(BS/3.,0,0, 0,0,0, c, 0,1),
+ video::S3DVertex(-BS/3.,0,0, 0,0,0, c, 1,1),
+ video::S3DVertex(-BS/3.,0+BS*2./3.,0, 0,0,0, c, 1,0),
+ video::S3DVertex(BS/3.,0+BS*2./3.,0, 0,0,0, c, 0,0),
+ };
+ u16 indices[] = {0,1,2,2,3,0};
+ buf->append(vertices, 4, indices, 6);
+ // Set material
+ buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
+ buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
+ //buf->getMaterial().setTexture(0, NULL);
+ // Initialize with the stick texture
+ buf->getMaterial().setTexture
+ (0, driver->getTexture(getTexturePath("mese.png").c_str()));
+ buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
+ buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
+ buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
+ // Add to mesh
+ mesh->addMeshBuffer(buf);
+ buf->drop();
+ m_node = smgr->addMeshSceneNode(mesh, NULL);
+ mesh->drop();
+ // Set it to use the materials of the meshbuffers directly.
+ // This is needed for changing the texture in the future
+ m_node->setReadOnlyMaterials(true);
+ updateNodePos();
+}
+
+void LuaEntityCAO::removeFromScene()
+{
+ if(m_node == NULL)
+ return;
+
+ m_node->remove();
+ m_node = NULL;
+}
+
+void LuaEntityCAO::updateLight(u8 light_at_pos)
+{
+ if(m_node == NULL)
+ return;
+
+ u8 li = decode_light(light_at_pos);
+ video::SColor color(255,li,li,li);
+ setMeshVerticesColor(m_node->getMesh(), color);
+}
+
+v3s16 LuaEntityCAO::getLightPosition()
+{
+ return floatToInt(m_position, BS);
+}
+
+void LuaEntityCAO::updateNodePos()
+{
+ if(m_node == NULL)
+ return;
+
+ m_node->setPosition(m_position);
+}
+
+void LuaEntityCAO::step(float dtime, ClientEnvironment *env)
+{
+ if(m_node)
+ {
+ /*v3f rot = m_node->getRotation();
+ rot.Y += dtime * 120;
+ m_node->setRotation(rot);*/
+ LocalPlayer *player = env->getLocalPlayer();
+ assert(player);
+ v3f rot = m_node->getRotation();
+ rot.Y = 180.0 - (player->getYaw());
+ m_node->setRotation(rot);
+ }
+}
+
+void LuaEntityCAO::processMessage(const std::string &data)
+{
+ infostream<<"LuaEntityCAO: Got message"<<std::endl;
+ std::istringstream is(data, std::ios::binary);
+ // command
+ u8 cmd = readU8(is);
+ if(cmd == 0)
+ {
+ // pos
+ m_position = readV3F1000(is);
+ updateNodePos();
+ }
+}
+
+void LuaEntityCAO::initialize(const std::string &data)
+{
+ infostream<<"LuaEntityCAO: Got init data"<<std::endl;
+
+ {
+ std::istringstream is(data, std::ios::binary);
+ // version
+ u8 version = readU8(is);
+ // check version
+ if(version != 0)
+ return;
+ // pos
+ m_position = readV3F1000(is);
+ }
+
+ updateNodePos();
+}
+
+
diff --git a/src/content_cao.h b/src/content_cao.h
index 963e1a488..c8554e737 100644
--- a/src/content_cao.h
+++ b/src/content_cao.h
@@ -376,6 +376,46 @@ private:
Settings *m_properties;
};
+/*
+ LuaEntityCAO
+*/
+
+class LuaEntityCAO : public ClientActiveObject
+{
+public:
+ LuaEntityCAO();
+ virtual ~LuaEntityCAO();
+
+ u8 getType() const
+ {
+ return ACTIVEOBJECT_TYPE_LUAENTITY;
+ }
+
+ static ClientActiveObject* create();
+
+ void addToScene(scene::ISceneManager *smgr);
+ void removeFromScene();
+ void updateLight(u8 light_at_pos);
+ v3s16 getLightPosition();
+ void updateNodePos();
+
+ void step(float dtime, ClientEnvironment *env);
+
+ void processMessage(const std::string &data);
+
+ void initialize(const std::string &data);
+
+ core::aabbox3d<f32>* getSelectionBox()
+ {return &m_selection_box;}
+ v3f getPosition()
+ {return m_position;}
+
+private:
+ core::aabbox3d<f32> m_selection_box;
+ scene::IMeshSceneNode *m_node;
+ v3f m_position;
+};
+
#endif
diff --git a/src/content_inventory.cpp b/src/content_inventory.cpp
index 413ae8505..1d5c6b355 100644
--- a/src/content_inventory.cpp
+++ b/src/content_inventory.cpp
@@ -80,16 +80,16 @@ std::string item_craft_get_image_name(const std::string &subname)
}
ServerActiveObject* item_craft_create_object(const std::string &subname,
- ServerEnvironment *env, u16 id, v3f pos)
+ ServerEnvironment *env, v3f pos)
{
if(subname == "rat")
{
- ServerActiveObject *obj = new RatSAO(env, id, pos);
+ ServerActiveObject *obj = new RatSAO(env, pos);
return obj;
}
else if(subname == "firefly")
{
- ServerActiveObject *obj = new FireflySAO(env, id, pos);
+ ServerActiveObject *obj = new FireflySAO(env, pos);
return obj;
}
diff --git a/src/content_inventory.h b/src/content_inventory.h
index 91550bb9a..9fd4cb03b 100644
--- a/src/content_inventory.h
+++ b/src/content_inventory.h
@@ -33,7 +33,7 @@ InventoryItem* item_material_create_cook_result(content_t content);
std::string item_craft_get_image_name(const std::string &subname);
ServerActiveObject* item_craft_create_object(const std::string &subname,
- ServerEnvironment *env, u16 id, v3f pos);
+ ServerEnvironment *env, v3f pos);
s16 item_craft_get_drop_count(const std::string &subname);
bool item_craft_is_cookable(const std::string &subname);
InventoryItem* item_craft_create_cook_result(const std::string &subname);
diff --git a/src/content_object.h b/src/content_object.h
index a5fea7163..f092b2789 100644
--- a/src/content_object.h
+++ b/src/content_object.h
@@ -27,5 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define ACTIVEOBJECT_TYPE_FIREFLY 5
#define ACTIVEOBJECT_TYPE_MOBV2 6
+#define ACTIVEOBJECT_TYPE_LUAENTITY 7
+
#endif
diff --git a/src/content_sao.cpp b/src/content_sao.cpp
index f22637185..d51e92a8c 100644
--- a/src/content_sao.cpp
+++ b/src/content_sao.cpp
@@ -49,20 +49,20 @@ void accelerate_xz(v3f &speed, v3f target_speed, f32 max_increase)
*/
// Prototype
-TestSAO proto_TestSAO(NULL, 0, v3f(0,0,0));
+TestSAO proto_TestSAO(NULL, v3f(0,0,0));
-TestSAO::TestSAO(ServerEnvironment *env, u16 id, v3f pos):
- ServerActiveObject(env, id, pos),
+TestSAO::TestSAO(ServerEnvironment *env, v3f pos):
+ ServerActiveObject(env, pos),
m_timer1(0),
m_age(0)
{
ServerActiveObject::registerType(getType(), create);
}
-ServerActiveObject* TestSAO::create(ServerEnvironment *env, u16 id, v3f pos,
+ServerActiveObject* TestSAO::create(ServerEnvironment *env, v3f pos,
const std::string &data)
{
- return new TestSAO(env, id, pos);
+ return new TestSAO(env, pos);
}
void TestSAO::step(float dtime, bool send_recommended)
@@ -107,11 +107,11 @@ void TestSAO::step(float dtime, bool send_recommended)
*/
// Prototype
-ItemSAO proto_ItemSAO(NULL, 0, v3f(0,0,0), "");
+ItemSAO proto_ItemSAO(NULL, v3f(0,0,0), "");
-ItemSAO::ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
+ItemSAO::ItemSAO(ServerEnvironment *env, v3f pos,
const std::string inventorystring):
- ServerActiveObject(env, id, pos),
+ ServerActiveObject(env, pos),
m_inventorystring(inventorystring),
m_speed_f(0,0,0),
m_last_sent_position(0,0,0)
@@ -119,7 +119,7 @@ ItemSAO::ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
ServerActiveObject::registerType(getType(), create);
}
-ServerActiveObject* ItemSAO::create(ServerEnvironment *env, u16 id, v3f pos,
+ServerActiveObject* ItemSAO::create(ServerEnvironment *env, v3f pos,
const std::string &data)
{
std::istringstream is(data, std::ios::binary);
@@ -133,7 +133,7 @@ ServerActiveObject* ItemSAO::create(ServerEnvironment *env, u16 id, v3f pos,
std::string inventorystring = deSerializeString(is);
infostream<<"ItemSAO::create(): Creating item \""
<<inventorystring<<"\""<<std::endl;
- return new ItemSAO(env, id, pos, inventorystring);
+ return new ItemSAO(env, pos, inventorystring);
}
void ItemSAO::step(float dtime, bool send_recommended)
@@ -260,10 +260,10 @@ void ItemSAO::rightClick(Player *player)
*/
// Prototype
-RatSAO proto_RatSAO(NULL, 0, v3f(0,0,0));
+RatSAO proto_RatSAO(NULL, v3f(0,0,0));
-RatSAO::RatSAO(ServerEnvironment *env, u16 id, v3f pos):
- ServerActiveObject(env, id, pos),
+RatSAO::RatSAO(ServerEnvironment *env, v3f pos):
+ ServerActiveObject(env, pos),
m_is_active(false),
m_speed_f(0,0,0)
{
@@ -278,7 +278,7 @@ RatSAO::RatSAO(ServerEnvironment *env, u16 id, v3f pos):
m_touching_ground = false;
}
-ServerActiveObject* RatSAO::create(ServerEnvironment *env, u16 id, v3f pos,
+ServerActiveObject* RatSAO::create(ServerEnvironment *env, v3f pos,
const std::string &data)
{
std::istringstream is(data, std::ios::binary);
@@ -289,7 +289,7 @@ ServerActiveObject* RatSAO::create(ServerEnvironment *env, u16 id, v3f pos,
// check if version is supported
if(version != 0)
return NULL;
- return new RatSAO(env, id, pos);
+ return new RatSAO(env, pos);
}
void RatSAO::step(float dtime, bool send_recommended)
@@ -447,10 +447,10 @@ InventoryItem* RatSAO::createPickedUpItem()
*/
// Prototype
-Oerkki1SAO proto_Oerkki1SAO(NULL, 0, v3f(0,0,0));
+Oerkki1SAO proto_Oerkki1SAO(NULL, v3f(0,0,0));
-Oerkki1SAO::Oerkki1SAO(ServerEnvironment *env, u16 id, v3f pos):
- ServerActiveObject(env, id, pos),
+Oerkki1SAO::Oerkki1SAO(ServerEnvironment *env, v3f pos):
+ ServerActiveObject(env, pos),
m_is_active(false),
m_speed_f(0,0,0)
{
@@ -467,7 +467,7 @@ Oerkki1SAO::Oerkki1SAO(ServerEnvironment *env, u16 id, v3f pos):
m_after_jump_timer = 0;
}
-ServerActiveObject* Oerkki1SAO::create(ServerEnvironment *env, u16 id, v3f pos,
+ServerActiveObject* Oerkki1SAO::create(ServerEnvironment *env, v3f pos,
const std::string &data)
{
std::istringstream is(data, std::ios::binary);
@@ -478,7 +478,7 @@ ServerActiveObject* Oerkki1SAO::create(ServerEnvironment *env, u16 id, v3f pos,
// check if version is supported
if(version != 0)
return NULL;
- Oerkki1SAO *o = new Oerkki1SAO(env, id, pos);
+ Oerkki1SAO *o = new Oerkki1SAO(env, pos);
o->m_hp = hp;
return o;
}
@@ -739,10 +739,10 @@ void Oerkki1SAO::doDamage(u16 d)
*/
// Prototype
-FireflySAO proto_FireflySAO(NULL, 0, v3f(0,0,0));
+FireflySAO proto_FireflySAO(NULL, v3f(0,0,0));
-FireflySAO::FireflySAO(ServerEnvironment *env, u16 id, v3f pos):
- ServerActiveObject(env, id, pos),
+FireflySAO::FireflySAO(ServerEnvironment *env, v3f pos):
+ ServerActiveObject(env, pos),
m_is_active(false),
m_speed_f(0,0,0)
{
@@ -757,7 +757,7 @@ FireflySAO::FireflySAO(ServerEnvironment *env, u16 id, v3f pos):
m_touching_ground = false;
}
-ServerActiveObject* FireflySAO::create(ServerEnvironment *env, u16 id, v3f pos,
+ServerActiveObject* FireflySAO::create(ServerEnvironment *env, v3f pos,
const std::string &data)
{
std::istringstream is(data, std::ios::binary);
@@ -768,7 +768,7 @@ ServerActiveObject* FireflySAO::create(ServerEnvironment *env, u16 id, v3f pos,
// check if version is supported
if(version != 0)
return NULL;
- return new FireflySAO(env, id, pos);
+ return new FireflySAO(env, pos);
}
void FireflySAO::step(float dtime, bool send_recommended)
@@ -918,11 +918,11 @@ InventoryItem* FireflySAO::createPickedUpItem()
*/
// Prototype
-MobV2SAO proto_MobV2SAO(NULL, 0, v3f(0,0,0), NULL);
+MobV2SAO proto_MobV2SAO(NULL, v3f(0,0,0), NULL);
-MobV2SAO::MobV2SAO(ServerEnvironment *env, u16 id, v3f pos,
+MobV2SAO::MobV2SAO(ServerEnvironment *env, v3f pos,
Settings *init_properties):
- ServerActiveObject(env, id, pos),
+ ServerActiveObject(env, pos),
m_move_type("ground_nodes"),
m_speed(0,0,0),
m_last_sent_position(0,0,0),
@@ -961,13 +961,13 @@ MobV2SAO::~MobV2SAO()
delete m_properties;
}
-ServerActiveObject* MobV2SAO::create(ServerEnvironment *env, u16 id, v3f pos,
+ServerActiveObject* MobV2SAO::create(ServerEnvironment *env, v3f pos,
const std::string &data)
{
std::istringstream is(data, std::ios::binary);
Settings properties;
properties.parseConfigLines(is, "MobArgsEnd");
- MobV2SAO *o = new MobV2SAO(env, id, pos, &properties);
+ MobV2SAO *o = new MobV2SAO(env, pos, &properties);
return o;
}
@@ -1174,7 +1174,7 @@ void MobV2SAO::step(float dtime, bool send_recommended)
properties.set("player_hit_damage", "9");
properties.set("player_hit_distance", "2");
properties.set("player_hit_interval", "1");
- ServerActiveObject *obj = new MobV2SAO(m_env, 0,
+ ServerActiveObject *obj = new MobV2SAO(m_env,
pos, &properties);
//m_env->addActiveObjectAsStatic(obj);
m_env->addActiveObject(obj);
@@ -1490,3 +1490,95 @@ void MobV2SAO::doDamage(u16 d)
}
+/*
+ LuaEntitySAO
+*/
+
+#include "scriptapi.h"
+
+// Prototype
+LuaEntitySAO proto_LuaEntitySAO(NULL, v3f(0,0,0), "_prototype", "");
+
+LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
+ const std::string &name, const std::string &state):
+ ServerActiveObject(env, pos),
+ m_init_name(name),
+ m_init_state(state),
+ m_registered(false)
+{
+ if(env == NULL){
+ ServerActiveObject::registerType(getType(), create);
+ return;
+ }
+}
+
+LuaEntitySAO::~LuaEntitySAO()
+{
+ if(m_registered){
+ lua_State *L = m_env->getLua();
+ scriptapi_luaentity_deregister(L, m_id);
+ }
+}
+
+void LuaEntitySAO::addedToEnvironment(u16 id)
+{
+ ServerActiveObject::addedToEnvironment(id);
+
+ // Create entity by name and state
+ m_registered = true;
+ lua_State *L = m_env->getLua();
+ scriptapi_luaentity_register(L, id, m_init_name.c_str(), m_init_state.c_str());
+}
+
+ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos,
+ const std::string &data)
+{
+ std::istringstream is(data, std::ios::binary);
+ // read version
+ u8 version = readU8(is);
+ // check if version is supported
+ if(version != 0)
+ return NULL;
+ // read name
+ std::string name = deSerializeString(is);
+ // read state
+ std::string state = deSerializeLongString(is);
+ // create object
+ infostream<<"LuaEntitySAO::create(name=\""<<name<<"\" state=\""
+ <<state<<"\")"<<std::endl;
+ return new LuaEntitySAO(env, pos, name, state);
+}
+
+void LuaEntitySAO::step(float dtime, bool send_recommended)
+{
+ if(m_registered){
+ lua_State *L = m_env->getLua();
+ scriptapi_luaentity_step(L, m_id, dtime, send_recommended);
+ }
+}
+
+std::string LuaEntitySAO::getClientInitializationData()
+{
+ std::ostringstream os(std::ios::binary);
+ // version
+ writeU8(os, 0);
+ // pos
+ writeV3F1000(os, m_base_position);
+ return os.str();
+}
+
+std::string LuaEntitySAO::getStaticData()
+{
+ infostream<<__FUNCTION_NAME<<std::endl;
+ std::ostringstream os(std::ios::binary);
+ // version
+ writeU8(os, 0);
+ // name
+ os<<serializeString(m_init_name);
+ // state
+ std::string state = scriptapi_luaentity_get_state(L, m_id);
+ os<<serializeString(state);
+ return os.str();
+}
+
+
diff --git a/src/content_sao.h b/src/content_sao.h
index f0ebf4f6f..44c0b7172 100644
--- a/src/content_sao.h
+++ b/src/content_sao.h
@@ -26,10 +26,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class TestSAO : public ServerActiveObject
{
public:
- TestSAO(ServerEnvironment *env, u16 id, v3f pos);
+ TestSAO(ServerEnvironment *env, v3f pos);
u8 getType() const
{return ACTIVEOBJECT_TYPE_TEST;}
- static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
+ static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
const std::string &data);
void step(float dtime, bool send_recommended);
private:
@@ -40,11 +40,11 @@ private:
class ItemSAO : public ServerActiveObject
{
public:
- ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
+ ItemSAO(ServerEnvironment *env, v3f pos,
const std::string inventorystring);
u8 getType() const
{return ACTIVEOBJECT_TYPE_ITEM;}
- static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
+ static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
const std::string &data);
void step(float dtime, bool send_recommended);
std::string getClientInitializationData();
@@ -62,10 +62,10 @@ private:
class RatSAO : public ServerActiveObject
{
public:
- RatSAO(ServerEnvironment *env, u16 id, v3f pos);
+ RatSAO(ServerEnvironment *env, v3f po std::map<int, scene::IMesh*>::iterator it = m_extrusion_meshes.lower_bound(maxdim); if (it == m_extrusion_meshes.end()) { // no viable resolution found; use largest one it = m_extrusion_meshes.find(MAX_EXTRUSION_MESH_RESOLUTION); sanity_check(it != m_extrusion_meshes.end()); } scene::IMesh *mesh = it->second; mesh->grab(); return mesh; } // Returns a 1x1x1 cube mesh with one meshbuffer (material) per face // Caller must drop the returned pointer scene::IMesh* createCube() { m_cube->grab(); return m_cube; } private: std::map<int, scene::IMesh*> m_extrusion_meshes; scene::IMesh *m_cube; }; ExtrusionMeshCache *g_extrusion_mesh_cache = NULL; WieldMeshSceneNode::WieldMeshSceneNode( scene::ISceneNode *parent, scene::ISceneManager *mgr, s32 id, bool lighting ): scene::ISceneNode(parent, mgr, id), m_meshnode(NULL), m_material_type(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF), m_lighting(lighting), m_bounding_box(0.0, 0.0, 0.0, 0.0, 0.0, 0.0) { m_enable_shaders = g_settings->getBool("enable_shaders"); m_anisotropic_filter = g_settings->getBool("anisotropic_filter"); m_bilinear_filter = g_settings->getBool("bilinear_filter"); m_trilinear_filter = g_settings->getBool("trilinear_filter"); // If this is the first wield mesh scene node, create a cache // for extrusion meshes (and a cube mesh), otherwise reuse it if (g_extrusion_mesh_cache == NULL) g_extrusion_mesh_cache = new ExtrusionMeshCache(); else g_extrusion_mesh_cache->grab(); // Disable bounding box culling for this scene node // since we won't calculate the bounding box. setAutomaticCulling(scene::EAC_OFF); // Create the child scene node scene::IMesh *dummymesh = g_extrusion_mesh_cache->createCube(); m_meshnode = SceneManager->addMeshSceneNode(dummymesh, this, -1); m_meshnode->setReadOnlyMaterials(false); m_meshnode->setVisible(false); dummymesh->drop(); // m_meshnode grabbed it } WieldMeshSceneNode::~WieldMeshSceneNode() { sanity_check(g_extrusion_mesh_cache); if (g_extrusion_mesh_cache->drop()) g_extrusion_mesh_cache = NULL; } void WieldMeshSceneNode::setCube(const TileSpec tiles[6], v3f wield_scale, ITextureSource *tsrc) { scene::IMesh *cubemesh = g_extrusion_mesh_cache->createCube(); changeToMesh(cubemesh); cubemesh->drop(); m_meshnode->setScale(wield_scale * WIELD_SCALE_FACTOR); // Customize materials for (u32 i = 0; i < m_meshnode->getMaterialCount(); ++i) { assert(i < 6); video::SMaterial &material = m_meshnode->getMaterial(i); if (tiles[i].animation_frame_count == 1) { material.setTexture(0, tiles[i].texture); } else { FrameSpec animation_frame = tiles[i].frames[0]; material.setTexture(0, animation_frame.texture); } tiles[i].applyMaterialOptions(material); } } void WieldMeshSceneNode::setExtruded(const std::string &imagename, v3f wield_scale, ITextureSource *tsrc, u8 num_frames) { video::ITexture *texture = tsrc->getTexture(imagename); if (!texture) { changeToMesh(NULL); return; } core::dimension2d<u32> dim = texture->getSize(); // Detect animation texture and pull off top frame instead of using entire thing if (num_frames > 1) { u32 frame_height = dim.Height / num_frames; dim = core::dimension2d<u32>(dim.Width, frame_height); } scene::IMesh *mesh = g_extrusion_mesh_cache->create(dim); changeToMesh(mesh); mesh->drop(); m_meshnode->setScale(wield_scale * WIELD_SCALE_FACTOR_EXTRUDED); // Customize material video::SMaterial &material = m_meshnode->getMaterial(0); material.setTexture(0, tsrc->getTextureForMesh(imagename)); material.MaterialType = m_material_type; material.setFlag(video::EMF_BACK_FACE_CULLING, true); // Enable bi/trilinear filtering only for high resolution textures if (dim.Width > 32) { material.setFlag(video::EMF_BILINEAR_FILTER, m_bilinear_filter); material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter); } else { material.setFlag(video::EMF_BILINEAR_FILTER, false); material.setFlag(video::EMF_TRILINEAR_FILTER, false); } material.setFlag(video::EMF_ANISOTROPIC_FILTER, m_anisotropic_filter); // mipmaps cause "thin black line" artifacts #if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2 material.setFlag(video::EMF_USE_MIP_MAPS, false); #endif #if 0 //// TODO(RealBadAngel): Reactivate when shader is added for wield items if (m_enable_shaders) material.setTexture(2, tsrc->getTexture("disable_img.png")); #endif } void WieldMeshSceneNode::setItem(const ItemStack &item, IGameDef *gamedef) { ITextureSource *tsrc = gamedef->getTextureSource(); IItemDefManager *idef = gamedef->getItemDefManager(); //IShaderSource *shdrsrc = gamedef->getShaderSource(); INodeDefManager *ndef = gamedef->getNodeDefManager(); const ItemDefinition &def = item.getDefinition(idef); const ContentFeatures &f = ndef->get(def.name); content_t id = ndef->getId(def.name); #if 0 //// TODO(RealBadAngel): Reactivate when shader is added for wield items if (m_enable_shaders) { u32 shader_id = shdrsrc->getShader("nodes_shader", TILE_MATERIAL_BASIC, NDT_NORMAL); m_material_type = shdrsrc->getShaderInfo(shader_id).material; } #endif // If wield_image is defined, it overrides everything else if (def.wield_image != "") { setExtruded(def.wield_image, def.wield_scale, tsrc, 1); return; } // Handle nodes // See also CItemDefManager::createClientCached() else if (def.type == ITEM_NODE) { if (f.mesh_ptr[0]) { // e.g. mesh nodes and nodeboxes changeToMesh(f.mesh_ptr[0]); // mesh_ptr[0] is pre-scaled by BS * f->visual_scale m_meshnode->setScale( def.wield_scale * WIELD_SCALE_FACTOR / (BS * f.visual_scale)); } else if (f.drawtype == NDT_AIRLIKE) { changeToMesh(NULL); } else if (f.drawtype == NDT_PLANTLIKE) { setExtruded(tsrc->getTextureName(f.tiles[0].texture_id), def.wield_scale, tsrc, f.tiles[0].animation_frame_count); } else if (f.drawtype == NDT_NORMAL || f.drawtype == NDT_ALLFACES) { setCube(f.tiles, def.wield_scale, tsrc); } else { //// TODO: Change false in the following constructor args to //// appropriate value when shader is added for wield items (if applicable) MeshMakeData mesh_make_data(gamedef, false); MapNode mesh_make_node(id, 255, 0); mesh_make_data.fillSingleNode(&mesh_make_node); MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); changeToMesh(mapblock_mesh.getMesh()); translateMesh(m_meshnode->getMesh(), v3f(-BS, -BS, -BS)); m_meshnode->setScale( def.wield_scale * WIELD_SCALE_FACTOR / (BS * f.visual_scale)); } u32 material_count = m_meshnode->getMaterialCount(); if (material_count > 6) { errorstream << "WieldMeshSceneNode::setItem: Invalid material " "count " << material_count << ", truncating to 6" << std::endl; material_count = 6; } for (u32 i = 0; i < material_count; ++i) { video::SMaterial &material = m_meshnode->getMaterial(i); material.setFlag(video::EMF_BACK_FACE_CULLING, true); material.setFlag(video::EMF_BILINEAR_FILTER, m_bilinear_filter); material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter); bool animated = (f.tiles[i].animation_frame_count > 1); if (animated) { FrameSpec animation_frame = f.tiles[i].frames[0]; material.setTexture(0, animation_frame.texture); } else { material.setTexture(0, f.tiles[i].texture); } material.MaterialType = m_material_type; #if 0 //// TODO(RealBadAngel): Reactivate when shader is added for wield items if (m_enable_shaders) { if (f.tiles[i].normal_texture) { if (animated) { FrameSpec animation_frame = f.tiles[i].frames[0]; material.setTexture(1, animation_frame.normal_texture); } else { material.setTexture(1, f.tiles[i].normal_texture); } material.setTexture(2, tsrc->getTexture("enable_img.png")); } else { material.setTexture(2, tsrc->getTexture("disable_img.png")); } } #endif } return; } else if (def.inventory_image != "") { setExtruded(def.inventory_image, def.wield_scale, tsrc, 1); return; } // no wield mesh found changeToMesh(NULL); } void WieldMeshSceneNode::setColor(video::SColor color) { assert(!m_lighting); setMeshColor(m_meshnode->getMesh(), color); } void WieldMeshSceneNode::render() { // note: if this method is changed to actually do something, // you probably should implement OnRegisterSceneNode as well } void WieldMeshSceneNode::changeToMesh(scene::IMesh *mesh) { if (mesh == NULL) { scene::IMesh *dummymesh = g_extrusion_mesh_cache->createCube(); m_meshnode->setVisible(false); m_meshnode->setMesh(dummymesh); dummymesh->drop(); // m_meshnode grabbed it } else { if (m_lighting) { m_meshnode->setMesh(mesh); } else { /* Lighting is disabled, this means the caller can (and probably will) call setColor later. We therefore need to clone the mesh so that setColor will only modify this scene node's mesh, not others'. */ scene::IMeshManipulator *meshmanip = SceneManager->getMeshManipulator(); scene::IMesh *new_mesh = meshmanip->createMeshCopy(mesh); m_meshnode->setMesh(new_mesh); new_mesh->drop(); // m_meshnode grabbed it } } m_meshnode->setMaterialFlag(video::EMF_LIGHTING, m_lighting); // need to normalize normals when lighting is enabled (because of setScale()) m_meshnode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, m_lighting); m_meshnode->setVisible(true); }
'add'>+ //infostream<<"ObjectRef::create: o="<<o<<std::endl;
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+ }
+
+ static void set_null(lua_State *L)
+ {
+ ObjectRef *o = checkobject(L, -1);
+ ServerActiveObject *co = o->m_object;
+ if(co == NULL)
+ return;
+ o->m_object = NULL;
+ }
+
+ static void Register(lua_State *L)
+ {
+ lua_newtable(L);
+ int methodtable = lua_gettop(L);
+ luaL_newmetatable(L, className);
+ int metatable = lua_gettop(L);
+
+ lua_pushliteral(L, "__metatable");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable); // hide metatable from Lua getmetatable()
+
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__gc");
+ lua_pushcfunction(L, gc_object);
+ lua_settable(L, metatable);
+
+ lua_pop(L, 1); // drop metatable
+
+ luaL_openlib(L, 0, methods, 0); // fill methodtable
+ lua_pop(L, 1); // drop methodtable
+
+ // Cannot be created from Lua
+ //lua_register(L, className, create_object);
+ }
+};
+
+const char ObjectRef::className[] = "ObjectRef";
+
+#define method(class, name) {#name, class::l_##name}
+
+const luaL_reg ObjectRef::methods[] = {
+ method(ObjectRef, remove),
+ {0,0}
+};
+
+void scriptapi_export(lua_State *L, Server *server)
+{
+ realitycheck(L);
+ assert(lua_checkstack(L, 20));
+ infostream<<"scriptapi_export"<<std::endl;
+
+ // Register global functions in table minetest
+ lua_newtable(L);
+ luaL_register(L, NULL, minetest_f);
+ lua_setglobal(L, "minetest");
+
+ // Get the main minetest table
+ lua_getglobal(L, "minetest");
+
+ // Add registered_objects table in minetest
+ lua_newtable(L);
+ lua_setfield(L, -2, "registered_objects");
+
+ // Add object_refs table in minetest
+ lua_newtable(L);
+ lua_setfield(L, -2, "object_refs");
+
+ // Add luaentities table in minetest
+ lua_newtable(L);
+ lua_setfield(L, -2, "luaentities");
+
+ // Load and run some base Lua stuff
+ /*script_load(L, (porting::path_data + DIR_DELIM + "scripts"
+ + DIR_DELIM + "base.lua").c_str());*/
+
+ // Create entity reference metatable
+ luaL_newmetatable(L, "minetest.entity_reference");
+ lua_pop(L, 1);
+
+ // Create entity prototype
+ luaL_newmetatable(L, "minetest.entity");
+ // metatable.__index = metatable
+ lua_pushvalue(L, -1); // Duplicate metatable
+ lua_setfield(L, -2, "__index");
+ // Put functions in metatable
+ luaL_register(L, NULL, minetest_entity_m);
+ // Put other stuff in metatable
+
+ // Entity C reference
+ ObjectRef::Register(L);
+}
+
+void scriptapi_luaentity_register(lua_State *L, u16 id, const char *name,
+ const char *init_state)
+{
+ realitycheck(L);
+ assert(lua_checkstack(L, 20));
+ infostream<<"scriptapi_luaentity_register: id="<<id<<std::endl;
+
+ // Create object as a dummy string (TODO: Create properly)
+ lua_pushstring(L, "dummy object string");
+ int object = lua_gettop(L);
+
+ // Get minetest.luaentities table
+ lua_getglobal(L, "minetest");
+ lua_getfield(L, -1, "luaentities");
+ luaL_checktype(L, -1, LUA_TTABLE);
+ int objectstable = lua_gettop(L);
+
+ // luaentities[id] = object
+ lua_pushnumber(L, id); // Push id
+ lua_pushvalue(L, object); // Copy object to top of stack
+ lua_settable(L, objectstable);
+
+ lua_pop(L, 3); // pop luaentities, minetest and the object
+}
+
+void scriptapi_luaentity_deregister(lua_State *L, u16 id)
+{
+ realitycheck(L);
+ assert(lua_checkstack(L, 20));
+ infostream<<"scriptapi_luaentity_deregister: id="<<id<<std::endl;
+
+ // Get minetest.luaentities table
+ lua_getglobal(L, "minetest");
+ lua_getfield(L, -1, "luaentities");
+ luaL_checktype(L, -1, LUA_TTABLE);
+ int objectstable = lua_gettop(L);
+
+ /*// Get luaentities[id]
+ lua_pushnumber(L, cobj->getId()); // Push id
+ lua_gettable(L, objectstable);
+ // Object is at stack top
+ lua_pop(L, 1); // pop object*/
+
+ // Set luaentities[id] = nil
+ lua_pushnumber(L, cobj->getId()); // Push id
+ lua_pushnil(L);
+ lua_settable(L, objectstable);
+
+ lua_pop(L, 2); // pop luaentities, minetest
+}
+
+void scriptapi_luaentity_step(lua_State *L, u16 id,
+ float dtime, bool send_recommended)
+{
+ realitycheck(L);
+ assert(lua_checkstack(L, 20));
+ infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
+
+ // Get minetest.luaentities table
+ lua_getglobal(L, "minetest");
+ lua_getfield(L, -1, "luaentities");
+ luaL_checktype(L, -1, LUA_TTABLE);
+ int objectstable = lua_gettop(L);
+
+ // Get luaentities[id]
+ lua_pushnumber(L, cobj->getId()); // Push id
+ lua_gettable(L, objectstable);
+
+ // TODO: Call step function
+
+ lua_pop(L, 1); // pop object
+ lua_pop(L, 2); // pop luaentities, minetest
+}
+
+std::string scriptapi_luaentity_get_state(lua_State *L, u16 id)
+{
+ realitycheck(L);
+ assert(lua_checkstack(L, 20));
+ infostream<<"scriptapi_luaentity_get_state: id="<<id<<std::endl;
+
+ return "";
+}
+
+void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj)
+{
+ realitycheck(L);
+ assert(lua_checkstack(L, 20));
+ infostream<<"scriptapi_add_object_reference: id="<<cobj->getId()<<std::endl;
+
+ // Create object on stack
+ ObjectRef::create(L, cobj); // Puts ObjectRef (as userdata) on stack
+ int object = lua_gettop(L);
+
+ // Get minetest.object_refs table
+ lua_getglobal(L, "minetest");
+ lua_getfield(L, -1, "object_refs");
+ luaL_checktype(L, -1, LUA_TTABLE);
+ int objectstable = lua_gettop(L);
+
+ // object_refs[id] = object
+ lua_pushnumber(L, cobj->getId()); // Push id
+ lua_pushvalue(L, object); // Copy object to top of stack
+ lua_settable(L, objectstable);
+
+ // pop object_refs, minetest and the object
+ lua_pop(L, 3);
+}
+
+void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
+{
+ realitycheck(L);
+ assert(lua_checkstack(L, 20));
+ infostream<<"scriptapi_rm_object_reference: id="<<cobj->getId()<<std::endl;
+
+ // Get minetest.object_refs table
+ lua_getglobal(L, "minetest");
+ lua_getfield(L, -1, "object_refs");
+ luaL_checktype(L, -1, LUA_TTABLE);
+ int objectstable = lua_gettop(L);
+
+ // Get object_refs[id]
+ lua_pushnumber(L, cobj->getId()); // Push id
+ lua_gettable(L, objectstable);
+ // Set object reference to NULL
+ ObjectRef::set_null(L);
+ lua_pop(L, 1); // pop object
+
+ // Set object_refs[id] = nil
+ lua_pushnumber(L, cobj->getId()); // Push id
+ lua_pushnil(L);
+ lua_settable(L, objectstable);
+
+ // pop object_refs, minetest
+ lua_pop(L, 2);
+}
+
diff --git a/src/scriptapi.h b/src/scriptapi.h
new file mode 100644
index 000000000..a97d707a8
--- /dev/null
+++ b/src/scriptapi.h
@@ -0,0 +1,43 @@
+/*
+Minetest-c55
+Copyright (C) 2011 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 General Public License as published by
+the Free Software Foundation; either version 2 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef SCRIPTAPI_HEADER
+#define SCRIPTAPI_HEADER
+
+#include "irrlichttypes.h"
+#include <string>
+
+class Server;
+class ServerActiveObject;
+typedef struct lua_State lua_State;
+
+void scriptapi_export(lua_State *L, Server *server);
+
+void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj);
+void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj);
+
+void scriptapi_luaentity_register(lua_State *L, u16 id, const char *name,
+ const char *init_state);
+void scriptapi_luaentity_deregister(lua_State *L, u16 id);
+void scriptapi_luaentity_step(lua_State *L, u16 id,
+ float dtime, bool send_recommended);
+std::string scriptapi_luaentity_get_state(lua_State *L, u16 id);
+
+#endif
+
diff --git a/src/server.cpp b/src/server.cpp
index e7cfc9afc..1c5d8d937 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -39,6 +39,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "profiler.h"
#include "log.h"
+#include "script.h"
+#include "scriptapi.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
@@ -185,7 +187,7 @@ void * EmergeThread::Thread()
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<") "
<<"only_from_disk="<<only_from_disk<<std::endl;
- ServerMap &map = ((ServerMap&)m_server->m_env.getMap());
+ ServerMap &map = ((ServerMap&)m_server->m_env->getMap());
//core::map<v3s16, MapBlock*> changed_blocks;
//core::map<v3s16, MapBlock*> lighting_invalidated_blocks;
@@ -250,7 +252,7 @@ void * EmergeThread::Thread()
MapEditEventIgnorer ign(&m_server->m_ignore_map_edit_events);
// Activate objects and stuff
- m_server->m_env.activateBlock(block, 3600);
+ m_server->m_env->activateBlock(block, 3600);
}
}
else
@@ -371,7 +373,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
//TimeTaker timer("RemoteClient::GetNextBlocks");
- Player *player = server->m_env.getPlayer(peer_id);
+ Player *player = server->m_env->getPlayer(peer_id);
assert(player != NULL);
@@ -572,7 +574,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
MAP_BLOCKSIZE*p.Z);
// Get ground height in nodes
- s16 gh = server->m_env.getServerMap().findGroundLevel(
+ s16 gh = server->m_env->getServerMap().findGroundLevel(
p2d_nodes_center);
// If differs a lot, don't generate
@@ -611,7 +613,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
/*
Check if map has this block
*/
- MapBlock *block = server->m_env.getMap().getBlockNoCreateNoEx(p);
+ MapBlock *block = server->m_env->getMap().getBlockNoCreateNoEx(p);
bool surely_not_found_on_disk = false;
bool block_is_invalid = false;
@@ -640,7 +642,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
#if 0
v2s16 p2d(p.X, p.Z);
- ServerMap *map = (ServerMap*)(&server->m_env.getMap());
+ ServerMap *map = (ServerMap*)(&server->m_env->getMap());
v2s16 chunkpos = map->sector_to_chunk(p2d);
if(map->chunkNonVolatile(chunkpos) == false)
block_is_invalid = true;
@@ -802,7 +804,7 @@ void RemoteClient::SendObjectData(
*/
// Get connected players
- core::list<Player*> players = server->m_env.getPlayers(true);
+ core::list<Player*> players = server->m_env->getPlayers(true);
// Write player count
u16 playercount = players.size();
@@ -948,10 +950,12 @@ Server::Server(
std::string mapsavedir,
std::string configpath
):
- m_env(new ServerMap(mapsavedir), this),
+ m_env(NULL),
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
m_authmanager(mapsavedir+DIR_DELIM+"auth.txt"),
m_banmanager(mapsavedir+DIR_DELIM+"ipban.txt"),
+ m_lua(NULL),
+ //m_scriptapi(NULL),
m_thread(this),
m_emergethread(this),
m_time_counter(0),
@@ -973,20 +977,38 @@ Server::Server(
m_con_mutex.Init();
m_step_dtime_mutex.Init();
m_step_dtime = 0.0;
+
+ JMutexAutoLock envlock(m_env_mutex);
+ JMutexAutoLock conlock(m_con_mutex);
+
+ // Initialize scripting
+
+ infostream<<"Server: Initializing scripting"<<std::endl;
+ m_lua = script_init();
+ assert(m_lua);
+ // Export API
+ scriptapi_export(m_lua, this);
+ // Load and run scripts
+ script_load(m_lua, (porting::path_data + DIR_DELIM + "scripts"
+ + DIR_DELIM + "default.lua").c_str());
+
+ // Initialize Environment
+
+ m_env = new ServerEnvironment(new ServerMap(mapsavedir), m_lua);
// Register us to receive map edit events
- m_env.getMap().addEventReceiver(this);
+ m_env->getMap().addEventReceiver(this);
// If file exists, load environment metadata
if(fs::PathExists(m_mapsavedir+DIR_DELIM+"env_meta.txt"))
{
infostream<<"Server: Loading environment metadata"<<std::endl;
- m_env.loadMeta(m_mapsavedir);
+ m_env->loadMeta(m_mapsavedir);
}
// Load players
infostream<<"Server: Loading players"<<std::endl;
- m_env.deSerializePlayers(m_mapsavedir);
+ m_env->deSerializePlayers(m_mapsavedir);
}
Server::~Server()
@@ -1029,13 +1051,13 @@ Server::~Server()
Save players
*/
infostream<<"Server: Saving players"<<std::endl;
- m_env.serializePlayers(m_mapsavedir);
+ m_env->serializePlayers(m_mapsavedir);
/*
Save environment metadata
*/
infostream<<"Server: Saving environment metadata"<<std::endl;
- m_env.saveMeta(m_mapsavedir);
+ m_env->saveMeta(m_mapsavedir);
}
/*
@@ -1058,13 +1080,20 @@ Server::~Server()
{
u16 peer_id = i.getNode()->getKey();
JMutexAutoLock envlock(m_env_mutex);
- m_env.removePlayer(peer_id);
+ m_env->removePlayer(peer_id);
}*/
// Delete client
delete i.getNode()->getValue();
}
}
+
+ // Delete Environment
+ delete m_env;
+
+ // Deinitialize scripting
+ infostream<<"Server: Deinitializing scripting"<<std::endl;
+ script_deinit(m_lua);
}
void Server::start(unsigned short port)
@@ -1173,7 +1202,7 @@ void Server::AsyncRunStep()
u32 units = (u32)(m_time_counter*speed);
m_time_counter -= (f32)units / speed;
- m_env.setTimeOfDay((m_env.getTimeOfDay() + units) % 24000);
+ m_env->setTimeOfDay((m_env->getTimeOfDay() + units) % 24000);
//infostream<<"Server: m_time_of_day = "<<m_time_of_day.get()<<std::endl;
@@ -1194,10 +1223,10 @@ void Server::AsyncRunStep()
i.atEnd() == false; i++)
{
RemoteClient *client = i.getNode()->getValue();
- //Player *player = m_env.getPlayer(client->peer_id);
+ //Player *player = m_env->getPlayer(client->peer_id);
SharedBuffer<u8> data = makePacket_TOCLIENT_TIME_OF_DAY(
- m_env.getTimeOfDay());
+ m_env->getTimeOfDay());
// Send as reliable
m_con.Send(client->peer_id, 0, data, true);
}
@@ -1209,7 +1238,7 @@ void Server::AsyncRunStep()
// Step environment
ScopeProfiler sp(g_profiler, "SEnv step");
ScopeProfiler sp2(g_profiler, "SEnv step avg", SPT_AVG);
- m_env.step(dtime);
+ m_env->step(dtime);
}
const float map_timer_and_unload_dtime = 5.15;
@@ -1218,7 +1247,7 @@ void Server::AsyncRunStep()
JMutexAutoLock lock(m_env_mutex);
// Run Map's timers and unload unused data
ScopeProfiler sp(g_profiler, "Server: map timer and unload");
- m_env.getMap().timerUpdate(map_timer_and_unload_dtime,
+ m_env->getMap().timerUpdate(map_timer_and_unload_dtime,
g_settings->getFloat("server_unload_unused_data_timeout"));
}
@@ -1239,13 +1268,13 @@ void Server::AsyncRunStep()
ScopeProfiler sp(g_profiler, "Server: liquid transform");
core::map<v3s16, MapBlock*> modified_blocks;
- m_env.getMap().transformLiquids(modified_blocks);
+ m_env->getMap().transformLiquids(modified_blocks);
#if 0
/*
Update lighting
*/
core::map<v3s16, MapBlock*> lighting_modified_blocks;
- ServerMap &map = ((ServerMap&)m_env.getMap());
+ ServerMap &map = ((ServerMap&)m_env->getMap());
map.updateLighting(modified_blocks, lighting_modified_blocks);
// Add blocks modified by lighting to modified_blocks
@@ -1295,7 +1324,7 @@ void Server::AsyncRunStep()
{
//u16 peer_id = i.getNode()->getKey();
RemoteClient *client = i.getNode()->getValue();
- Player *player = m_env.getPlayer(client->peer_id);
+ Player *player = m_env->getPlayer(client->peer_id);
if(player==NULL)
continue;
infostream<<"* "<<player->getName()<<"\t";
@@ -1326,7 +1355,7 @@ void Server::AsyncRunStep()
i.atEnd() == false; i++)
{
RemoteClient *client = i.getNode()->getValue();
- Player *player = m_env.getPlayer(client->peer_id);
+ Player *player = m_env->getPlayer(client->peer_id);
if(player==NULL)
{
// This can happen if the client timeouts somehow
@@ -1339,9 +1368,9 @@ void Server::AsyncRunStep()
core::map<u16, bool> removed_objects;
core::map<u16, bool> added_objects;
- m_env.getRemovedActiveObjects(pos, radius,
+ m_env->getRemovedActiveObjects(pos, radius,
client->m_known_objects, removed_objects);
- m_env.getAddedActiveObjects(pos, radius,
+ m_env->getAddedActiveObjects(pos, radius,
client->m_known_objects, added_objects);
// Ignore if nothing happened
@@ -1364,7 +1393,7 @@ void Server::AsyncRunStep()
{
// Get object
u16 id = i.getNode()->getKey();
- ServerActiveObject* obj = m_env.getActiveObject(id);
+ ServerActiveObject* obj = m_env->getActiveObject(id);
// Add to data buffer for sending
writeU16((u8*)buf, i.getNode()->getKey());
@@ -1386,7 +1415,7 @@ void Server::AsyncRunStep()
{
// Get object
u16 id = i.getNode()->getKey();
- ServerActiveObject* obj = m_env.getActiveObject(id);
+ ServerActiveObject* obj = m_env->getActiveObject(id);
// Get object type
u8 type = ACTIVEOBJECT_TYPE_INVALID;
@@ -1452,7 +1481,7 @@ void Server::AsyncRunStep()
}
}
- m_env.setKnownActiveObjects(whatever);
+ m_env->setKnownActiveObjects(whatever);
#endif
}
@@ -1473,7 +1502,7 @@ void Server::AsyncRunStep()
// Get active object messages from environment
for(;;)
{
- ActiveObjectMessage aom = m_env.getActiveObjectMessage();
+ ActiveObjectMessage aom = m_env->getActiveObjectMessage();
if(aom.id == 0)
break;
@@ -1662,7 +1691,7 @@ void Server::AsyncRunStep()
{
v3s16 p = i.getNode()->getKey();
modified_blocks2.insert(p,
- m_env.getMap().getBlockNoCreateNoEx(p));
+ m_env->getMap().getBlockNoCreateNoEx(p));
}
// Set blocks not sent
for(core::list<u16>::Iterator
@@ -1749,15 +1778,15 @@ void Server::AsyncRunStep()
JMutexAutoLock lock(m_env_mutex);
/*// Unload unused data (delete from memory)
- m_env.getMap().unloadUnusedData(
+ m_env->getMap().unloadUnusedData(
g_settings->getFloat("server_unload_unused_sectors_timeout"));
*/
- /*u32 deleted_count = m_env.getMap().unloadUnusedData(
+ /*u32 deleted_count = m_env->getMap().unloadUnusedData(
g_settings->getFloat("server_unload_unused_sectors_timeout"));
*/
// Save only changed parts
- m_env.getMap().save(true);
+ m_env->getMap().save(true);
/*if(deleted_count > 0)
{
@@ -1766,10 +1795,10 @@ void Server::AsyncRunStep()
}*/
// Save players
- m_env.serializePlayers(m_mapsavedir);
+ m_env->serializePlayers(m_mapsavedir);
// Save environment metadata
- m_env.saveMeta(m_mapsavedir);
+ m_env->saveMeta(m_mapsavedir);
}
}
}
@@ -1811,7 +1840,7 @@ void Server::Receive()
<<" has apparently closed connection. "
<<"Removing player."<<std::endl;
- m_env.removePlayer(peer_id);*/
+ m_env->removePlayer(peer_id);*/
}
}
@@ -2026,7 +2055,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
writeU16(&reply[0], TOCLIENT_INIT);
writeU8(&reply[2], deployed);
writeV3S16(&reply[2+1], floatToInt(player->getPosition()+v3f(0,BS/2,0), BS));
- writeU64(&reply[2+1+6], m_env.getServerMap().getSeed());
+ writeU64(&reply[2+1+6], m_env->getServerMap().getSeed());
// Send as reliable
m_con.Send(peer_id, 0, reply, true);
@@ -2063,7 +2092,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Send player items to all players
SendPlayerItems();
- Player *player = m_env.getPlayer(peer_id);
+ Player *player = m_env->getPlayer(peer_id);
// Send HP
SendPlayerHP(player);
@@ -2071,7 +2100,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Send time of day
{
SharedBuffer<u8> data = makePacket_TOCLIENT_TIME_OF_DAY(
- m_env.getTimeOfDay());
+ m_env->getTimeOfDay());
m_con.Send(peer_id, 0, data, true);
}
@@ -2081,7 +2110,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Send information about joining in chat
{
std::wstring name = L"unknown";
- Player *player = m_env.getPlayer(peer_id);
+ Player *player = m_env->getPlayer(peer_id);
if(player != NULL)
name = narrow_to_wide(player->getName());
@@ -2117,7 +2146,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if(client->serialization_version == SER_FMT_VER_INVALID)
continue;
// Get player
- Player *player = m_env.getPlayer(client->peer_id);
+ Player *player = m_env->getPlayer(client->peer_id);
if(!player)
continue;
// Get name of player
@@ -2139,7 +2168,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
return;
}
- Player *player = m_env.getPlayer(peer_id);
+ Player *player = m_env->getPlayer(peer_id);
if(player == NULL){
infostream<<"Server::ProcessData(): Cancelling: "
@@ -2247,7 +2276,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
u16 id = readS16(&data[3]);
u16 item_i = readU16(&data[5]);
- ServerActiveObject *obj = m_env.getActiveObject(id);
+ ServerActiveObject *obj = m_env->getActiveObject(id);
if(obj == NULL)
{
@@ -2421,7 +2450,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
try
{
- MapNode n = m_env.getMap().getNode(p_under);
+ MapNode n = m_env->getMap().getNode(p_under);
// Get mineral
mineral = n.getMineral();
// Get material at position
@@ -2442,7 +2471,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if(cannot_remove_node == false)
{
// Get node metadata
- NodeMetadata *meta = m_env.getMap().getNodeMetadata(p_under);
+ NodeMetadata *meta = m_env->getMap().getNodeMetadata(p_under);
if(meta && meta->nodeRemovalDisabled() == true)
{
infostream<<"Server: Not finishing digging: "
@@ -2608,7 +2637,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
{
MapEditEventIgnorer ign(&m_ignore_map_edit_events);
- m_env.getMap().removeNodeAndUpdate(p_under, modified_blocks);
+ m_env->getMap().removeNodeAndUpdate(p_under, modified_blocks);
}
/*
Set blocks not sent to far players
@@ -2649,7 +2678,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
{
try{
// Don't add a node if this is not a free space
- MapNode n2 = m_env.getMap().getNode(p_over);
+ MapNode n2 = m_env->getMap().getNode(p_over);
bool no_enough_privs =
((getPlayerPrivs(player) & PRIV_BUILD)==0);
if(no_enough_privs)
@@ -2750,7 +2779,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
MapEditEventIgnorer ign(&m_ignore_map_edit_events);
std::string p_name = std::string(player->getName());
- m_env.getMap().addNodeAndUpdate(p_over, n, modified_blocks, p_name);
+ m_env->getMap().addNodeAndUpdate(p_over, n, modified_blocks, p_name);
}
/*
Set blocks not sent to far players
@@ -2792,7 +2821,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
Check that the block is loaded so that the item
can properly be added to the static list too
*/
- MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(blockpos);
+ MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos);
if(block==NULL)
{
infostream<<"Error while placing object: "
@@ -2823,7 +2852,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
/*
Create the object
*/
- ServerActiveObject *obj = item->createSAO(&m_env, 0, pos);
+ ServerActiveObject *obj = item->createSAO(m_env, 0, pos);
if(obj == NULL)
{
@@ -2837,7 +2866,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
<<" at "<<PP(p_over)<<std::endl;
// Add the object to the environment
- m_env.addActiveObject(obj);
+ m_env->addActiveObject(obj);
infostream<<"Placed object"<<std::endl;
@@ -2924,7 +2953,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
text += (char)buf[0];
}
- NodeMetadata *meta = m_env.getMap().getNodeMetadata(p);
+ NodeMetadata *meta = m_env->getMap().getNodeMetadata(p);
if(!meta)
return;
if(meta->typeId() != CONTENT_SIGN_WALL)
@@ -2936,7 +2965,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
<<" at "<<PP(p)<<std::endl;
v3s16 blockpos = getNodeBlockPos(p);
- MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(blockpos);
+ MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos);
if(block)
{
block->setChangedFlag();
@@ -3052,7 +3081,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
p.X = stoi(fn.next(","));
p.Y = stoi(fn.next(","));
p.Z = stoi(fn.next(","));
- NodeMetadata *meta = m_env.getMap().getNodeMetadata(p);
+ NodeMetadata *meta = m_env->getMap().getNodeMetadata(p);
if(meta && meta->typeId() == CONTENT_LOCKABLE_CHEST) {
LockingChestNodeMetadata *lcm = (LockingChestNodeMetadata*)meta;
if (lcm->getOwner() != player->getName())
@@ -3070,7 +3099,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
p.X = stoi(fn.next(","));
p.Y = stoi(fn.next(","));
p.Z = stoi(fn.next(","));
- NodeMetadata *meta = m_env.getMap().getNodeMetadata(p);
+ NodeMetadata *meta = m_env->getMap().getNodeMetadata(p);
if(meta && meta->typeId() == CONTENT_LOCKABLE_CHEST) {
LockingChestNodeMetadata *lcm = (LockingChestNodeMetadata*)meta;
if (lcm->getOwner() != player->getName())
@@ -3153,7 +3182,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
str_split(message, L' '),
paramstring,
this,
- &m_env,
+ m_env,
player,
privs);
@@ -3356,7 +3385,7 @@ Inventory* Server::getInventory(InventoryContext *c, std::string id)
p.X = stoi(fn.next(","));
p.Y = stoi(fn.next(","));
p.Z = stoi(fn.next(","));
- NodeMetadata *meta = m_env.getMap().getNodeMetadata(p);
+ NodeMetadata *meta = m_env->getMap().getNodeMetadata(p);
if(meta)
return meta->getInventory();
infostream<<"nodemeta at ("<<p.X<<","<<p.Y<<","<<p.Z<<"): "
@@ -3389,7 +3418,7 @@ void Server::inventoryModified(InventoryContext *c, std::string id)
p.Z = stoi(fn.next(","));
v3s16 blockpos = getNodeBlockPos(p);
- NodeMetadata *meta = m_env.getMap().getNodeMetadata(p);
+ NodeMetadata *meta = m_env->getMap().getNodeMetadata(p);
if(meta)
meta->inventoryModified();
@@ -3415,7 +3444,7 @@ core::list<PlayerInfo> Server::getPlayerInfo()
core::list<PlayerInfo> list;
- core::list<Player*> players = m_env.getPlayers();
+ core::list<Player*> players = m_env->getPlayers();
core::list<Player*>::Iterator i;
for(i = players.begin();
@@ -3559,7 +3588,7 @@ void Server::SendPlayerInfos()
//JMutexAutoLock envlock(m_env_mutex);
// Get connected players
- core::list<Player*> players = m_env.getPlayers(true);
+ core::list<Player*> players = m_env->getPlayers(true);
u32 player_count = players.getSize();
u32 datasize = 2+(2+PLAYERNAME_SIZE)*player_count;
@@ -3593,7 +3622,7 @@ void Server::SendInventory(u16 peer_id)
{
DSTACK(__FUNCTION_NAME);
- Player* player = m_env.getPlayer(peer_id);
+ Player* player = m_env->getPlayer(peer_id);
assert(player);
/*
@@ -3650,7 +3679,7 @@ void Server::SendPlayerItems()
DSTACK(__FUNCTION_NAME);
std::ostringstream os(std::ios_base::binary);
- core::list<Player *> players = m_env.getPlayers(true);
+ core::list<Player *> players = m_env->getPlayers(true);
writeU16(os, TOCLIENT_PLAYERITEM);
writeU16(os, players.size());
@@ -3779,7 +3808,7 @@ void Server::sendRemoveNode(v3s16 p, u16 ignore_id,
if(far_players)
{
// Get player
- Player *player = m_env.getPlayer(client->peer_id);
+ Player *player = m_env->getPlayer(client->peer_id);
if(player)
{
// If player is far away, only set modified blocks not sent
@@ -3820,7 +3849,7 @@ void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id,
if(far_players)
{
// Get player
- Player *player = m_env.getPlayer(client->peer_id);
+ Player *player = m_env->getPlayer(client->peer_id);
if(player)
{
// If player is far away, only set modified blocks not sent
@@ -3960,7 +3989,7 @@ void Server::SendBlocks(float dtime)
MapBlock *block = NULL;
try
{
- block = m_env.getMap().getBlockNoCreate(q.pos);
+ block = m_env->getMap().getBlockNoCreate(q.pos);
}
catch(InvalidPositionException &e)
{
@@ -4019,7 +4048,7 @@ void Server::HandlePlayerHP(Player *player, s16 damage)
void Server::RespawnPlayer(Player *player)
{
- v3f pos = findSpawnPos(m_env.getServerMap());
+ v3f pos = findSpawnPos(m_env->getServerMap());
player->setPosition(pos);
player->hp = 20;
SendMovePlayer(player);
@@ -4030,7 +4059,7 @@ void Server::UpdateCrafting(u16 peer_id)
{
DSTACK(__FUNCTION_NAME);
- Player* player = m_env.getPlayer(peer_id);
+ Player* player = m_env->getPlayer(peer_id);
assert(player);
/*
@@ -4096,7 +4125,7 @@ std::wstring Server::getStatusString()
if(client->serialization_version == SER_FMT_VER_INVALID)
continue;
// Get player
- Player *player = m_env.getPlayer(client->peer_id);
+ Player *player = m_env->getPlayer(client->peer_id);
// Get name of player
std::wstring name = L"unknown";
if(player != NULL)
@@ -4105,7 +4134,7 @@ std::wstring Server::getStatusString()
os<<name<<L",";
}
os<<L"}";
- if(((ServerMap*)(&m_env.getMap()))->isSavingEnabled() == false)
+ if(((ServerMap*)(&m_env->getMap()))->isSavingEnabled() == false)
os<<std::endl<<L"# Server: "<<" WARNING: Map saving is disabled.";
if(g_settings->get("motd") != "")
os<<std::endl<<L"# Server: "<<narrow_to_wide(g_settings->get("motd"));
@@ -4121,7 +4150,7 @@ void Server::saveConfig()
void Server::notifyPlayer(const char *name, const std::wstring msg)
{
- Player *player = m_env.getPlayer(name);
+ Player *player = m_env->getPlayer(name);
if(!player)
return;
SendChatMessage(player->peer_id, std::wstring(L"Server: -!- ")+msg);
@@ -4200,7 +4229,7 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id
/*
Try to get an existing player
*/
- Player *player = m_env.getPlayer(name);
+ Player *player = m_env->getPlayer(name);
if(player != NULL)
{
// If player is already connected, cancel
@@ -4230,7 +4259,7 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id
/*
If player with the wanted peer_id already exists, cancel.
*/
- if(m_env.getPlayer(peer_id) != NULL)
+ if(m_env->getPlayer(peer_id) != NULL)
{
infostream<<"emergePlayer(): Player with wrong name but same"
" peer_id already exists"<<std::endl;
@@ -4258,7 +4287,7 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id
infostream<<"Server: Finding spawn place for player \""
<<player->getName()<<"\""<<std::endl;
- v3f pos = findSpawnPos(m_env.getServerMap());
+ v3f pos = findSpawnPos(m_env->getServerMap());
player->setPosition(pos);
@@ -4266,7 +4295,7 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id
Add player to environment
*/
- m_env.addPlayer(player);
+ m_env->addPlayer(player);
/*
Add stuff to inventory
@@ -4337,7 +4366,7 @@ void Server::handlePeerChange(PeerChange &c)
{
// Get object
u16 id = i.getNode()->getKey();
- ServerActiveObject* obj = m_env.getActiveObject(id);
+ ServerActiveObject* obj = m_env->getActiveObject(id);
if(obj && obj->m_known_by_count > 0)
obj->m_known_by_count--;
@@ -4346,7 +4375,7 @@ void Server::handlePeerChange(PeerChange &c)
// Collect information about leaving in chat
std::wstring message;
{
- Player *player = m_env.getPlayer(c.peer_id);
+ Player *player = m_env->getPlayer(c.peer_id);
if(player != NULL)
{
std::wstring name = narrow_to_wide(player->getName());
@@ -4360,12 +4389,12 @@ void Server::handlePeerChange(PeerChange &c)
/*// Delete player
{
- m_env.removePlayer(c.peer_id);
+ m_env->removePlayer(c.peer_id);
}*/
// Set player client disconnected
{
- Player *player = m_env.getPlayer(c.peer_id);
+ Player *player = m_env->getPlayer(c.peer_id);
if(player != NULL)
player->peer_id = 0;
@@ -4384,7 +4413,7 @@ void Server::handlePeerChange(PeerChange &c)
if(client->serialization_version == SER_FMT_VER_INVALID)
continue;
// Get player
- Player *player = m_env.getPlayer(client->peer_id);
+ Player *player = m_env->getPlayer(client->peer_id);
if(!player)
continue;
// Get name of player
diff --git a/src/server.h b/src/server.h
index b238bec26..ab8c31a00 100644
--- a/src/server.h
+++ b/src/server.h
@@ -29,6 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "inventory.h"
#include "auth.h"
#include "ban.h"
+struct LuaState;
+typedef struct lua_State lua_State;
/*
Some random functions
@@ -391,7 +393,7 @@ public:
// Environment must be locked when called
void setTimeOfDay(u32 time)
{
- m_env.setTimeOfDay(time);
+ m_env->setTimeOfDay(time);
m_time_of_day_send_timer = 0;
}
@@ -476,6 +478,9 @@ public:
// Envlock and conlock should be locked when calling this
void notifyPlayer(const char *name, const std::wstring msg);
void notifyPlayers(const std::wstring msg);
+
+ // Envlock and conlock should be locked when using Lua
+ lua_State *getLua(){ return m_lua; }
private:
@@ -543,7 +548,7 @@ private:
// When called, environment mutex should be locked
std::string getPlayerName(u16 peer_id)
{
- Player *player = m_env.getPlayer(peer_id);
+ Player *player = m_env->getPlayer(peer_id);
if(player == NULL)
return "[id="+itos(peer_id);
return player->getName();
@@ -582,7 +587,7 @@ private:
// environment shall be locked first.
// Environment
- ServerEnvironment m_env;
+ ServerEnvironment *m_env;
JMutex m_env_mutex;
// Connection
@@ -596,6 +601,10 @@ private:
// Bann checking
BanManager m_banmanager;
+
+ // Scripting
+ // Envlock and conlock should be locked when using Lua
+ lua_State *m_lua;
/*
Threads
diff --git a/src/serverobject.cpp b/src/serverobject.cpp
index ce19ea34f..2a007bda5 100644
--- a/src/serverobject.cpp
+++ b/src/serverobject.cpp
@@ -21,8 +21,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <fstream>
#include "inventory.h"
-ServerActiveObject::ServerActiveObject(ServerEnvironment *env, u16 id, v3f pos):
- ActiveObject(id),
+ServerActiveObject::ServerActiveObject(ServerEnvironment *env, v3f pos):
+ ActiveObject(0),
m_known_by_count(0),
m_removed(false),
m_pending_deactivation(false),
@@ -37,6 +37,11 @@ ServerActiveObject::~ServerActiveObject()
{
}
+void ServerActiveObject::addedToEnvironment(u16 id)
+{
+ setId(id);
+}
+
ServerActiveObject* ServerActiveObject::create(u8 type,
ServerEnvironment *env, u16 id, v3f pos,
const std::string &data)
@@ -53,7 +58,7 @@ ServerActiveObject* ServerActiveObject::create(u8 type,
}
Factory f = n->getValue();
- ServerActiveObject *object = (*f)(env, id, pos, data);
+ ServerActiveObject *object = (*f)(env, pos, data);
return object;
}
diff --git a/src/serverobject.h b/src/serverobject.h
index cbb50949c..8d6bfd6e8 100644
--- a/src/serverobject.h
+++ b/src/serverobject.h
@@ -51,9 +51,11 @@ public:
NOTE: m_env can be NULL, but step() isn't called if it is.
Prototypes are used that way.
*/
- ServerActiveObject(ServerEnvironment *env, u16 id, v3f pos);
+ ServerActiveObject(ServerEnvironment *env, v3f pos);
virtual ~ServerActiveObject();
+ virtual void addedToEnvironment(u16 id);
+
// Create a certain type of ServerActiveObject
static ServerActiveObject* create(u8 type,
ServerEnvironment *env, u16 id, v3f pos,
@@ -160,7 +162,7 @@ public:
protected:
// Used for creating objects based on type
typedef ServerActiveObject* (*Factory)
- (ServerEnvironment *env, u16 id, v3f pos,
+ (ServerEnvironment *env, v3f pos,
const std::string &data);
static void registerType(u16 type, Factory f);