mirror of
https://github.com/minetest/minetest.git
synced 2024-09-12 00:26:50 +02:00
Scripting WIP
This commit is contained in:
parent
ee8b6d3444
commit
bfc68d3151
@ -94,6 +94,8 @@ configure_file(
|
||||
)
|
||||
|
||||
set(common_SRCS
|
||||
scriptapi.cpp
|
||||
script.cpp
|
||||
log.cpp
|
||||
content_sao.cpp
|
||||
mapgen.cpp
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 pos);
|
||||
u8 getType() const
|
||||
{return ACTIVEOBJECT_TYPE_RAT;}
|
||||
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();
|
||||
@ -87,10 +87,10 @@ private:
|
||||
class Oerkki1SAO : public ServerActiveObject
|
||||
{
|
||||
public:
|
||||
Oerkki1SAO(ServerEnvironment *env, u16 id, v3f pos);
|
||||
Oerkki1SAO(ServerEnvironment *env, v3f pos);
|
||||
u8 getType() const
|
||||
{return ACTIVEOBJECT_TYPE_OERKKI1;}
|
||||
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();
|
||||
@ -119,10 +119,10 @@ private:
|
||||
class FireflySAO : public ServerActiveObject
|
||||
{
|
||||
public:
|
||||
FireflySAO(ServerEnvironment *env, u16 id, v3f pos);
|
||||
FireflySAO(ServerEnvironment *env, v3f pos);
|
||||
u8 getType() const
|
||||
{return ACTIVEOBJECT_TYPE_FIREFLY;}
|
||||
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();
|
||||
@ -146,12 +146,12 @@ class Settings;
|
||||
class MobV2SAO : public ServerActiveObject
|
||||
{
|
||||
public:
|
||||
MobV2SAO(ServerEnvironment *env, u16 id, v3f pos,
|
||||
MobV2SAO(ServerEnvironment *env, v3f pos,
|
||||
Settings *init_properties);
|
||||
virtual ~MobV2SAO();
|
||||
u8 getType() const
|
||||
{return ACTIVEOBJECT_TYPE_MOBV2;}
|
||||
static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
|
||||
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
|
||||
const std::string &data);
|
||||
std::string getStaticData();
|
||||
std::string getClientInitializationData();
|
||||
@ -195,5 +195,27 @@ private:
|
||||
Settings *m_properties;
|
||||
};
|
||||
|
||||
struct LuaState;
|
||||
|
||||
class LuaEntitySAO : public ServerActiveObject
|
||||
{
|
||||
public:
|
||||
LuaEntitySAO(ServerEnvironment *env, v3f pos,
|
||||
const std::string &name, const std::string &state);
|
||||
~LuaEntitySAO();
|
||||
u8 getType() const
|
||||
{return ACTIVEOBJECT_TYPE_LUAENTITY;}
|
||||
virtual void addedToEnvironment(u16 id);
|
||||
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
|
||||
const std::string &data);
|
||||
void step(float dtime, bool send_recommended);
|
||||
std::string getClientInitializationData();
|
||||
std::string getStaticData();
|
||||
private:
|
||||
std::string m_init_name;
|
||||
std::string m_init_state;
|
||||
bool m_registered;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "settings.h"
|
||||
#include "log.h"
|
||||
#include "profiler.h"
|
||||
#include "scriptapi.h"
|
||||
|
||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||
|
||||
@ -267,9 +268,9 @@ void ActiveBlockList::update(core::list<v3s16> &active_positions,
|
||||
ServerEnvironment
|
||||
*/
|
||||
|
||||
ServerEnvironment::ServerEnvironment(ServerMap *map, Server *server):
|
||||
ServerEnvironment::ServerEnvironment(ServerMap *map, lua_State *L):
|
||||
m_map(map),
|
||||
m_server(server),
|
||||
m_lua(L),
|
||||
m_random_spawn_timer(3),
|
||||
m_send_recommended_timer(0),
|
||||
m_game_time(0),
|
||||
@ -674,6 +675,8 @@ void ServerEnvironment::clearAllObjects()
|
||||
obj->m_removed = true;
|
||||
continue;
|
||||
}
|
||||
// Deregister in scripting api
|
||||
scriptapi_rm_object_reference(m_lua, obj);
|
||||
// Delete active object
|
||||
delete obj;
|
||||
// Id to be removed from m_active_objects
|
||||
@ -1043,7 +1046,7 @@ void ServerEnvironment::step(float dtime)
|
||||
n1.getContent() == CONTENT_AIR)
|
||||
{
|
||||
v3f pos = intToFloat(p1, BS);
|
||||
ServerActiveObject *obj = new RatSAO(this, 0, pos);
|
||||
ServerActiveObject *obj = new RatSAO(this, pos);
|
||||
addActiveObject(obj);
|
||||
}
|
||||
}
|
||||
@ -1071,21 +1074,21 @@ void ServerEnvironment::step(float dtime)
|
||||
Settings properties;
|
||||
getMob_dungeon_master(properties);
|
||||
ServerActiveObject *obj = new MobV2SAO(
|
||||
this, 0, pos, &properties);
|
||||
this, pos, &properties);
|
||||
addActiveObject(obj);
|
||||
} else if(i == 2 || i == 3){
|
||||
actionstream<<"Rats spawn at "
|
||||
<<PP(p1)<<std::endl;
|
||||
for(int j=0; j<3; j++){
|
||||
ServerActiveObject *obj = new RatSAO(
|
||||
this, 0, pos);
|
||||
this, pos);
|
||||
addActiveObject(obj);
|
||||
}
|
||||
} else {
|
||||
actionstream<<"An oerkki spawns at "
|
||||
<<PP(p1)<<std::endl;
|
||||
ServerActiveObject *obj = new Oerkki1SAO(
|
||||
this, 0, pos);
|
||||
this, pos);
|
||||
addActiveObject(obj);
|
||||
}
|
||||
}
|
||||
@ -1228,18 +1231,18 @@ void ServerEnvironment::step(float dtime)
|
||||
Create a ServerActiveObject
|
||||
*/
|
||||
|
||||
//TestSAO *obj = new TestSAO(this, 0, pos);
|
||||
//ServerActiveObject *obj = new ItemSAO(this, 0, pos, "CraftItem Stick 1");
|
||||
//ServerActiveObject *obj = new RatSAO(this, 0, pos);
|
||||
//ServerActiveObject *obj = new Oerkki1SAO(this, 0, pos);
|
||||
//ServerActiveObject *obj = new FireflySAO(this, 0, pos);
|
||||
//TestSAO *obj = new TestSAO(this, pos);
|
||||
//ServerActiveObject *obj = new ItemSAO(this, pos, "CraftItem Stick 1");
|
||||
//ServerActiveObject *obj = new RatSAO(this, pos);
|
||||
//ServerActiveObject *obj = new Oerkki1SAO(this, pos);
|
||||
//ServerActiveObject *obj = new FireflySAO(this, pos);
|
||||
|
||||
infostream<<"Server: Spawning MobV2SAO at "
|
||||
<<"("<<pos.X<<","<<pos.Y<<","<<pos.Z<<")"<<std::endl;
|
||||
|
||||
Settings properties;
|
||||
getMob_dungeon_master(properties);
|
||||
ServerActiveObject *obj = new MobV2SAO(this, 0, pos, &properties);
|
||||
ServerActiveObject *obj = new MobV2SAO(this, pos, &properties);
|
||||
addActiveObject(obj);
|
||||
}
|
||||
#endif
|
||||
@ -1494,6 +1497,11 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
|
||||
<<" statically"<<std::endl;
|
||||
}
|
||||
|
||||
// Post-initialize object
|
||||
object->addedToEnvironment(object->getId());
|
||||
// Register reference in scripting api
|
||||
scriptapi_add_object_reference(m_lua, object);
|
||||
|
||||
return object->getId();
|
||||
}
|
||||
|
||||
@ -1544,6 +1552,9 @@ void ServerEnvironment::removeRemovedObjects()
|
||||
if(obj->m_known_by_count > 0)
|
||||
continue;
|
||||
|
||||
// Deregister in scripting api
|
||||
scriptapi_rm_object_reference(m_lua, obj);
|
||||
|
||||
// Delete
|
||||
delete obj;
|
||||
// Id to be removed from m_active_objects
|
||||
@ -1815,6 +1826,10 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
||||
verbosestream<<"ServerEnvironment::deactivateFarObjects(): "
|
||||
<<"object id="<<id<<" is not known by clients"
|
||||
<<"; deleting"<<std::endl;
|
||||
|
||||
// Deregister in scripting api
|
||||
scriptapi_rm_object_reference(m_lua, obj);
|
||||
|
||||
// Delete active object
|
||||
delete obj;
|
||||
// Id to be removed from m_active_objects
|
||||
|
@ -41,6 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
class Server;
|
||||
class ActiveBlockModifier;
|
||||
class ServerActiveObject;
|
||||
typedef struct lua_State lua_State;
|
||||
|
||||
class Environment
|
||||
{
|
||||
@ -126,7 +127,7 @@ private:
|
||||
class ServerEnvironment : public Environment
|
||||
{
|
||||
public:
|
||||
ServerEnvironment(ServerMap *map, Server *server);
|
||||
ServerEnvironment(ServerMap *map, lua_State *L);
|
||||
~ServerEnvironment();
|
||||
|
||||
Map & getMap()
|
||||
@ -139,13 +140,11 @@ public:
|
||||
return *m_map;
|
||||
}
|
||||
|
||||
Server * getServer()
|
||||
lua_State* getLua()
|
||||
{
|
||||
return m_server;
|
||||
return m_lua;
|
||||
}
|
||||
|
||||
void step(f32 dtime);
|
||||
|
||||
/*
|
||||
Save players
|
||||
*/
|
||||
@ -223,6 +222,8 @@ public:
|
||||
// Clear all objects, loading and going through every MapBlock
|
||||
void clearAllObjects();
|
||||
|
||||
void step(f32 dtime);
|
||||
|
||||
private:
|
||||
|
||||
/*
|
||||
@ -269,8 +270,8 @@ private:
|
||||
|
||||
// The map
|
||||
ServerMap *m_map;
|
||||
// Pointer to server (which is handling this environment)
|
||||
Server *m_server;
|
||||
// Lua state
|
||||
lua_State *m_lua;
|
||||
// Active object list
|
||||
core::map<u16, ServerActiveObject*> m_active_objects;
|
||||
// Outgoing network message buffer for active objects
|
||||
|
@ -136,7 +136,7 @@ ServerActiveObject* InventoryItem::createSAO(ServerEnvironment *env, u16 id, v3f
|
||||
Create an ItemSAO
|
||||
*/
|
||||
// Create object
|
||||
ServerActiveObject *obj = new ItemSAO(env, 0, pos, getItemString());
|
||||
ServerActiveObject *obj = new ItemSAO(env, pos, getItemString());
|
||||
return obj;
|
||||
}
|
||||
|
||||
@ -174,7 +174,7 @@ video::ITexture * CraftItem::getImage() const
|
||||
ServerActiveObject* CraftItem::createSAO(ServerEnvironment *env, u16 id, v3f pos)
|
||||
{
|
||||
// Special cases
|
||||
ServerActiveObject *obj = item_craft_create_object(m_subname, env, id, pos);
|
||||
ServerActiveObject *obj = item_craft_create_object(m_subname, env, pos);
|
||||
if(obj)
|
||||
return obj;
|
||||
// Default
|
||||
|
52
src/irrlichttypes.h
Normal file
52
src/irrlichttypes.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2010-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 IRRLICHTTYPES_HEADER
|
||||
#define IRRLICHTTYPES_HEADER
|
||||
|
||||
#include <irrTypes.h>
|
||||
#include <vector2d.h>
|
||||
#include <vector3d.h>
|
||||
#include <irrMap.h>
|
||||
#include <irrList.h>
|
||||
#include <irrArray.h>
|
||||
#include <aabbox3d.h>
|
||||
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
|
||||
|
@ -56,9 +56,10 @@ void sigint_handler(int sig)
|
||||
dstream<<DTIME<<"INFO: sigint_handler(): "
|
||||
<<"Ctrl-C pressed, shutting down."<<std::endl;
|
||||
|
||||
dstream<<DTIME<<"INFO: sigint_handler(): "
|
||||
// Comment out for less clutter when testing scripts
|
||||
/*dstream<<DTIME<<"INFO: sigint_handler(): "
|
||||
<<"Printing debug stacks"<<std::endl;
|
||||
debug_stacks_print();
|
||||
debug_stacks_print();*/
|
||||
|
||||
g_killed = true;
|
||||
}
|
||||
@ -91,9 +92,10 @@ void signal_handler_init(void)
|
||||
{
|
||||
dstream<<DTIME<<"INFO: event_handler(): "
|
||||
<<"Ctrl+C, Close Event, Logoff Event or Shutdown Event, shutting down."<<std::endl;
|
||||
dstream<<DTIME<<"INFO: event_handler(): "
|
||||
// Comment out for less clutter when testing scripts
|
||||
/*dstream<<DTIME<<"INFO: event_handler(): "
|
||||
<<"Printing debug stacks"<<std::endl;
|
||||
debug_stacks_print();
|
||||
debug_stacks_print();*/
|
||||
|
||||
g_killed = true;
|
||||
}
|
||||
|
130
src/script.cpp
Normal file
130
src/script.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "script.h"
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include "log.h"
|
||||
#include <iostream>
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
void script_error(lua_State *L, const char *fmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
vfprintf(stderr, fmt, argp);
|
||||
va_end(argp);
|
||||
lua_close(L);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void script_call_va(lua_State *L, const char *func, const char *sig, ...)
|
||||
{
|
||||
va_list vl;
|
||||
int narg, nres; /* number of arguments and results */
|
||||
|
||||
va_start(vl, sig);
|
||||
lua_getglobal(L, func); /* push function */
|
||||
|
||||
for (narg = 0; *sig; narg++) {
|
||||
/* repeat for each argument */
|
||||
/* check stack space */
|
||||
luaL_checkstack(L, 1, "too many arguments");
|
||||
switch (*sig++) {
|
||||
case 'd': /* double argument */
|
||||
lua_pushnumber(L, va_arg(vl, double));
|
||||
break;
|
||||
case 'i': /* int argument */
|
||||
lua_pushinteger(L, va_arg(vl, int));
|
||||
break;
|
||||
case 's': /* string argument */
|
||||
lua_pushstring(L, va_arg(vl, char *));
|
||||
break;
|
||||
case '>': /* end of arguments */
|
||||
goto endargs;
|
||||
default:
|
||||
script_error(L, "invalid option (%c)", *(sig - 1));
|
||||
}
|
||||
}
|
||||
endargs:
|
||||
|
||||
nres = strlen(sig); /* number of expected results */
|
||||
|
||||
if (lua_pcall(L, narg, nres, 0) != 0) /* do the call */
|
||||
script_error(L, "error calling '%s': %s", func, lua_tostring(L, -1));
|
||||
|
||||
nres = -nres; /* stack index of first result */
|
||||
while (*sig) { /* repeat for each result */
|
||||
switch (*sig++) {
|
||||
case 'd': /* double result */
|
||||
if (!lua_isnumber(L, nres))
|
||||
script_error(L, "wrong result type");
|
||||
*va_arg(vl, double *) = lua_tonumber(L, nres);
|
||||
break;
|
||||
case 'i': /* int result */
|
||||
if (!lua_isnumber(L, nres))
|
||||
script_error(L, "wrong result type");
|
||||
*va_arg(vl, int *) = lua_tointeger(L, nres);
|
||||
break;
|
||||
case 's': /* string result */
|
||||
if (!lua_isstring(L, nres))
|
||||
script_error(L, "wrong result type");
|
||||
*va_arg(vl, const char **) = lua_tostring(L, nres);
|
||||
break;
|
||||
default:
|
||||
script_error(L, "invalid option (%c)", *(sig - 1));
|
||||
}
|
||||
nres++;
|
||||
}
|
||||
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
bool script_load(lua_State *L, const char *path)
|
||||
{
|
||||
infostream<<"Loading and running script from "<<path<<std::endl;
|
||||
int ret = luaL_loadfile(L, path) || lua_pcall(L, 0, 0, 0);
|
||||
if(ret){
|
||||
errorstream<<"Failed to load and run script from "<<path<<": "<<lua_tostring(L, -1)<<std::endl;
|
||||
lua_pop(L, 1); // Pop error message from stack
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
lua_State* script_init()
|
||||
{
|
||||
lua_State *L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
return L;
|
||||
}
|
||||
|
||||
lua_State* script_deinit(lua_State *L)
|
||||
{
|
||||
lua_close(L);
|
||||
}
|
||||
|
||||
|
33
src/script.h
Normal file
33
src/script.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
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 SCRIPT_HEADER
|
||||
#define SCRIPT_HEADER
|
||||
|
||||
typedef struct lua_State lua_State;
|
||||
//#include <string>
|
||||
|
||||
lua_State* script_init();
|
||||
lua_State* script_deinit(lua_State *L);
|
||||
void script_error(lua_State *L, const char *fmt, ...);
|
||||
void script_call_va(lua_State *L, const char *func, const char *sig, ...);
|
||||
bool script_load(lua_State *L, const char *path);
|
||||
|
||||
#endif
|
||||
|
422
src/scriptapi.cpp
Normal file
422
src/scriptapi.cpp
Normal file
@ -0,0 +1,422 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "scriptapi.h"
|
||||
|
||||
#include <iostream>
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
#include "log.h"
|
||||
#include "server.h"
|
||||
#include "porting.h"
|
||||
#include "filesys.h"
|
||||
#include "serverobject.h"
|
||||
#include "script.h"
|
||||
//#include "luna.h"
|
||||
|
||||
static void stackDump(lua_State *L, std::ostream &o)
|
||||
{
|
||||
int i;
|
||||
int top = lua_gettop(L);
|
||||
for (i = 1; i <= top; i++) { /* repeat for each level */
|
||||
int t = lua_type(L, i);
|
||||
switch (t) {
|
||||
|
||||
case LUA_TSTRING: /* strings */
|
||||
o<<"\""<<lua_tostring(L, i)<<"\"";
|
||||
break;
|
||||
|
||||
case LUA_TBOOLEAN: /* booleans */
|
||||
o<<(lua_toboolean(L, i) ? "true" : "false");
|
||||
break;
|
||||
|
||||
case LUA_TNUMBER: /* numbers */ {
|
||||
char buf[10];
|
||||
snprintf(buf, 10, "%g", lua_tonumber(L, i));
|
||||
o<<buf;
|
||||
break; }
|
||||
|
||||
default: /* other values */
|
||||
o<<lua_typename(L, t);
|
||||
break;
|
||||
|
||||
}
|
||||
o<<" ";
|
||||
}
|
||||
o<<std::endl;
|
||||
}
|
||||
|
||||
static void realitycheck(lua_State *L)
|
||||
{
|
||||
int top = lua_gettop(L);
|
||||
if(top >= 30){
|
||||
dstream<<"Stack is over 30:"<<std::endl;
|
||||
stackDump(L, dstream);
|
||||
script_error(L, "Stack is over 30 (reality check)");
|
||||
}
|
||||
}
|
||||
|
||||
// Register new object prototype (must be based on entity)
|
||||
static int l_register_object(lua_State *L)
|
||||
{
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
luaL_checkany(L, 2);
|
||||
infostream<<"register_object: "<<name<<std::endl;
|
||||
// Get the minetest table
|
||||
lua_getglobal(L, "minetest");
|
||||
// Get field "registered_objects"
|
||||
lua_getfield(L, -1, "registered_objects");
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
int objectstable = lua_gettop(L);
|
||||
// Object is in param 2
|
||||
lua_pushvalue(L, 2); // Copy object to top of stack
|
||||
lua_setfield(L, objectstable, name); // registered_objects[name] = object
|
||||
|
||||
return 0; /* number of results */
|
||||
}
|
||||
|
||||
static int l_new_entity(lua_State *L)
|
||||
{
|
||||
/* o = o or {}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o */
|
||||
if(lua_isnil(L, -1))
|
||||
lua_newtable(L);
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
luaL_getmetatable(L, "minetest.entity");
|
||||
lua_pushvalue(L, -1); // duplicate metatable
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_setmetatable(L, -2);
|
||||
// return table
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg minetest_f [] = {
|
||||
{"register_object", l_register_object},
|
||||
{"new_entity", l_new_entity},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static int l_entity_set_deleted(lua_State *L)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg minetest_entity_m [] = {
|
||||
{"set_deleted", l_entity_set_deleted},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
class ObjectRef
|
||||
{
|
||||
private:
|
||||
ServerActiveObject *m_object;
|
||||
|
||||
static const char className[];
|
||||
static const luaL_reg methods[];
|
||||
|
||||
static ObjectRef *checkobject(lua_State *L, int narg)
|
||||
{
|
||||
luaL_checktype(L, narg, LUA_TUSERDATA);
|
||||
void *ud = luaL_checkudata(L, narg, className);
|
||||
if(!ud) luaL_typerror(L, narg, className);
|
||||
return *(ObjectRef**)ud; // unbox pointer
|
||||
}
|
||||
|
||||
// Exported functions
|
||||
|
||||
static int l_remove(lua_State *L)
|
||||
{
|
||||
ObjectRef *o = checkobject(L, 1);
|
||||
ServerActiveObject *co = o->m_object;
|
||||
if(co == NULL) return 0;
|
||||
infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
|
||||
co->m_removed = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gc_object(lua_State *L) {
|
||||
//ObjectRef *o = checkobject(L, 1);
|
||||
ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
|
||||
//infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
|
||||
delete o;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
ObjectRef(ServerActiveObject *object):
|
||||
m_object(object)
|
||||
{
|
||||
infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
|
||||
}
|
||||
|
||||
~ObjectRef()
|
||||
{
|
||||
if(m_object)
|
||||
infostream<<"ObjectRef destructing for id="<<m_object->getId()<<std::endl;
|
||||
else
|
||||
infostream<<"ObjectRef destructing for id=unknown"<<std::endl;
|
||||
}
|
||||
|
||||
// Creates an ObjectRef and leaves it on top of stack
|
||||
// Not callable from Lua; all references are created on the C side.
|
||||
static void create(lua_State *L, ServerActiveObject *object)
|
||||
{
|
||||
ObjectRef *o = new ObjectRef(object);
|
||||
//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);
|
||||
}
|
||||
|
43
src/scriptapi.h
Normal file
43
src/scriptapi.h
Normal file
@ -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
|
||||
|
187
src/server.cpp
187
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),
|
||||
@ -974,19 +978,37 @@ Server::Server(
|
||||
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
|
||||
|
15
src/server.h
15
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;
|
||||
}
|
||||
|
||||
@ -477,6 +479,9 @@ public:
|
||||
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:
|
||||
|
||||
// con::PeerHandler implementation.
|
||||
@ -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
|
||||
@ -597,6 +602,10 @@ private:
|
||||
// Bann checking
|
||||
BanManager m_banmanager;
|
||||
|
||||
// Scripting
|
||||
// Envlock and conlock should be locked when using Lua
|
||||
lua_State *m_lua;
|
||||
|
||||
/*
|
||||
Threads
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user