3 Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "serverobject.h"
22 #include "environment.h"
24 ServerActiveObject::ServerActiveObject(ServerEnvironment *env, u16 id, v3f pos):
33 ServerActiveObject::~ServerActiveObject()
41 TestSAO::TestSAO(ServerEnvironment *env, u16 id, v3f pos):
42 ServerActiveObject(env, id, pos),
48 void TestSAO::step(float dtime, Queue<ActiveObjectMessage> &messages)
57 m_base_position.Y += dtime * BS * 2;
58 if(m_base_position.Y > 8*BS)
59 m_base_position.Y = 2*BS;
65 //dstream<<"TestSAO: id="<<getId()<<" sending data"<<std::endl;
69 data += itos(0); // 0 = position
71 data += itos(m_base_position.X);
73 data += itos(m_base_position.Y);
75 data += itos(m_base_position.Z);
77 ActiveObjectMessage aom(getId(), false, data);
78 messages.push_back(aom);
91 Functions for calling from script:
93 object_set_base_position(self, x,y,z)
94 x,y,z = object_get_base_position(self)
95 object_add_message(self, data)
96 n = object_get_node(self, x,y,z)
102 get_client_init_data(self)
103 get_server_init_data(self)
104 initialize(self, data)
108 object_set_base_position(self, x, y, z)
110 static int lf_object_set_base_position(lua_State *L)
113 lua_Number z = lua_tonumber(L, -1);
116 lua_Number y = lua_tonumber(L, -1);
119 lua_Number x = lua_tonumber(L, -1);
122 LuaSAO *self = (LuaSAO*)lua_touserdata(L, -1);
127 self->setBasePosition(v3f(x*BS,y*BS,z*BS));
129 return 0; // Number of return values
133 object_get_base_position(self)
135 static int lf_object_get_base_position(lua_State *L)
138 LuaSAO *self = (LuaSAO*)lua_touserdata(L, -1);
143 v3f pos = self->getBasePosition();
145 lua_pushnumber(L, pos.X/BS);
146 lua_pushnumber(L, pos.Y/BS);
147 lua_pushnumber(L, pos.Z/BS);
148 return 3; // Number of return values
152 object_add_message(self, string data)
155 static int lf_object_add_message(lua_State *L)
159 const char *data_c = lua_tolstring(L, -1, &datalen);
162 LuaSAO *self = (LuaSAO*)lua_touserdata(L, -1);
168 std::string data(data_c, datalen);
169 //dstream<<"object_add_message: data="<<data<<std::endl;
171 // Create message and add to queue
172 ActiveObjectMessage aom(self->getId());
174 aom.datastring = data;
175 self->m_message_queue.push_back(aom);
177 return 0; // Number of return values
181 object_get_node(self, x,y,z)
183 static int lf_object_get_node(lua_State *L)
186 lua_Number z = lua_tonumber(L, -1);
189 lua_Number y = lua_tonumber(L, -1);
192 lua_Number x = lua_tonumber(L, -1);
195 LuaSAO *self = (LuaSAO*)lua_touserdata(L, -1);
200 v3s16 pos = floatToInt(v3f(x,y,z), 1.0);
202 /*dstream<<"Checking node from pos=("<<pos.X<<","<<pos.Y<<","<<pos.Z
206 MapNode n(CONTENT_IGNORE);
207 n = self->getEnv()->getMap().getNodeNoEx(pos);
209 // Create a table with some data about the node
211 lua_pushstring(L, "content");
212 lua_pushinteger(L, n.d);
214 lua_pushstring(L, "param1");
215 lua_pushinteger(L, n.param);
217 lua_pushstring(L, "param2");
218 lua_pushinteger(L, n.param2);
220 lua_pushstring(L, "walkable");
221 lua_pushboolean(L, content_features(n.d).walkable);
230 object_set_node(self, x,y,z, n)
232 static int lf_object_set_node(lua_State *L)
237 // Get fields of table
239 lua_pushinteger(L, "content");
241 n.d = lua_tonumber(L, -1);
244 lua_pushinteger(L, "param1");
246 n.param = lua_tonumber(L, -1);
249 lua_pushinteger(L, "param2");
251 n.param2 = lua_tonumber(L, -1);
256 lua_Number z = lua_tonumber(L, -1);
259 lua_Number y = lua_tonumber(L, -1);
262 lua_Number x = lua_tonumber(L, -1);
265 LuaSAO *self = (LuaSAO*)lua_touserdata(L, -1);
270 v3s16 pos = floatToInt(v3f(x,y,z), 1.0);
272 /*dstream<<"Checking node from pos=("<<pos.X<<","<<pos.Y<<","<<pos.Z
276 MapNode n(CONTENT_IGNORE);
277 n = self->getEnv()->getMap().getNodeNoEx(pos);
279 // Create a table with some data about the node
281 lua_pushstring(L, "content");
282 lua_pushinteger(L, n.d);
284 lua_pushstring(L, "walkable");
285 lua_pushboolean(L, content_features(n.d).walkable);
296 static int lf_object_remove(lua_State *L)
299 LuaSAO *self = (LuaSAO*)lua_touserdata(L, -1);
304 self->m_removed = true;
309 LuaSAO::LuaSAO(ServerEnvironment *env, u16 id, v3f pos):
310 ServerActiveObject(env, id, pos),
313 dstream<<"LuaSAO::LuaSAO(): id="<<id<<std::endl;
324 //lua_pushlightuserdata(L, this);
325 //lua_setglobal(L, "self");
327 // Register functions
328 lua_register(L, "object_set_base_position", lf_object_set_base_position);
329 lua_register(L, "object_get_base_position", lf_object_get_base_position);
330 lua_register(L, "object_add_message", lf_object_add_message);
331 lua_register(L, "object_get_node", lf_object_get_node);
332 lua_register(L, "object_remove", lf_object_remove);
340 std::string LuaSAO::getClientInitializationData()
343 Read client-side script from file
346 std::string relative_path;
347 relative_path += "luaobjects/";
348 relative_path += m_script_name;
349 relative_path += "/client.lua";
350 std::string full_path = porting::getDataPath(relative_path.c_str());
352 std::ifstream file(full_path.c_str(), std::ios::binary | std::ios::ate);
353 int size = file.tellg();
354 SharedBuffer<char> buf(size);
355 file.seekg(0, std::ios::beg);
356 file.read(&buf[0], size);
365 std::string script_string(&buf[0], buf.getSize());
366 data += serializeLongString(script_string);
369 Get data from server-side script for inclusion
371 std::string other_data;
375 const char *funcname = "get_client_init_data";
376 lua_getglobal(L, funcname);
377 if(!lua_isfunction(L,-1))
380 dstream<<"WARNING: LuaSAO: Function not found: "
381 <<funcname<<std::endl;
387 lua_pushlightuserdata(L, this);
389 // Call (1 parameters, 1 result)
390 if(lua_pcall(L, 1, 1, 0))
392 dstream<<"WARNING: LuaSAO: Error running function "
394 <<lua_tostring(L,-1)<<std::endl;
399 if(!lua_isstring(L,-1))
401 dstream<<"WARNING: LuaSAO: Function "<<funcname
402 <<" didn't return a string"<<std::endl;
407 const char *cs = lua_tolstring(L, -1, &cs_len);
410 other_data = std::string(cs, cs_len);
414 data += serializeLongString(other_data);
419 std::string LuaSAO::getServerInitializationData()
424 data.append(serializeString(m_script_name));
427 Get data from server-side script for inclusion
429 std::string other_data;
433 const char *funcname = "get_server_init_data";
434 lua_getglobal(L, funcname);
435 if(!lua_isfunction(L,-1))
438 dstream<<"WARNING: LuaSAO: Function not found: "
439 <<funcname<<std::endl;
445 lua_pushlightuserdata(L, this);
447 // Call (1 parameters, 1 result)
448 if(lua_pcall(L, 1, 1, 0))
450 dstream<<"WARNING: LuaSAO: Error running function "
452 <<lua_tostring(L,-1)<<std::endl;
457 if(!lua_isstring(L,-1))
459 dstream<<"WARNING: LuaSAO: Function "<<funcname
460 <<" didn't return a string"<<std::endl;
465 const char *cs = lua_tolstring(L, -1, &cs_len);
468 other_data = std::string(cs, cs_len);
472 data += serializeLongString(other_data);
477 void LuaSAO::initialize(const std::string &data)
479 std::istringstream is(data, std::ios::binary);
480 std::string script_name = deSerializeString(is);
481 std::string other = deSerializeLongString(is);
483 loadScripts(script_name);
486 Call initialize(self, data) in the script
489 const char *funcname = "initialize";
490 lua_getglobal(L, funcname);
491 if(!lua_isfunction(L,-1))
494 dstream<<"WARNING: LuaSAO: Function not found: "
495 <<funcname<<std::endl;
501 lua_pushlightuserdata(L, this);
503 lua_pushlstring(L, other.c_str(), other.size());
505 // Call (2 parameters, 0 result)
506 if(lua_pcall(L, 2, 0, 0))
508 dstream<<"WARNING: LuaSAO: Error running function "
510 <<lua_tostring(L,-1)<<std::endl;
515 void LuaSAO::loadScripts(const std::string &script_name)
517 m_script_name = script_name;
519 std::string relative_path;
520 relative_path += "luaobjects/";
521 relative_path += script_name;
522 std::string server_file = relative_path + "/server.lua";
523 std::string server_path = porting::getDataPath(server_file.c_str());
527 ret = luaL_loadfile(L, server_path.c_str());
530 const char *message = lua_tostring(L, -1);
532 dstream<<"LuaSAO::loadScript(): lua_loadfile failed: "
533 <<message<<std::endl;
537 ret = lua_pcall(L, 0, 0, 0);
540 const char *message = lua_tostring(L, -1);
542 dstream<<"LuaSAO::loadScript(): lua_pcall failed: "
543 <<message<<std::endl;
549 void LuaSAO::step(float dtime, Queue<ActiveObjectMessage> &messages)
551 lua_getglobal(L, "step");
552 if(!lua_isfunction(L,-1))
555 dstream<<"WARNING: LuaSAO::step(): step function not found"<<std::endl;
561 lua_pushlightuserdata(L, this);
563 lua_pushnumber(L, dtime);
565 // Call (2 parameters, 0 result)
566 if(lua_pcall(L, 2, 0, 0))
568 dstream<<"WARNING: LuaSAO::step(): Error running function step(): "
569 <<lua_tostring(L,-1)<<std::endl;
574 while(m_message_queue.size() != 0)
576 messages.push_back(m_message_queue.pop_front());