mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-11 17:51:04 +00:00
mainly work on object scripting api
This commit is contained in:
parent
eef7bc3570
commit
9778347c7f
19 changed files with 962 additions and 430 deletions
289
src/server.cpp
289
src/server.cpp
|
@ -893,7 +893,7 @@ u32 PIChecksum(core::list<PlayerInfo> &l)
|
|||
Server::Server(
|
||||
std::string mapsavedir
|
||||
):
|
||||
m_env(new ServerMap(mapsavedir)),
|
||||
m_env(new ServerMap(mapsavedir), this),
|
||||
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
|
||||
m_thread(this),
|
||||
m_emergethread(this),
|
||||
|
@ -902,9 +902,10 @@ Server::Server(
|
|||
m_time_of_day_send_timer(0),
|
||||
m_uptime(0),
|
||||
m_mapsavedir(mapsavedir),
|
||||
m_shutdown_requested(false)
|
||||
m_shutdown_requested(false),
|
||||
m_ignore_map_edit_events(false),
|
||||
m_ignore_map_edit_events_peer_id(0)
|
||||
{
|
||||
//m_flowwater_timer = 0.0;
|
||||
m_liquid_transform_timer = 0.0;
|
||||
m_print_info_timer = 0.0;
|
||||
m_objectdata_timer = 0.0;
|
||||
|
@ -916,6 +917,8 @@ Server::Server(
|
|||
m_step_dtime_mutex.Init();
|
||||
m_step_dtime = 0.0;
|
||||
|
||||
m_env.getMap().addEventReceiver(this);
|
||||
|
||||
// Load players
|
||||
m_env.deSerializePlayers(m_mapsavedir);
|
||||
}
|
||||
|
@ -1191,12 +1194,18 @@ void Server::AsyncRunStep()
|
|||
}
|
||||
}
|
||||
|
||||
if(g_settings.getBool("enable_experimental"))
|
||||
{
|
||||
|
||||
/*
|
||||
Check added and deleted active objects
|
||||
*/
|
||||
{
|
||||
JMutexAutoLock envlock(m_env_mutex);
|
||||
JMutexAutoLock conlock(m_con_mutex);
|
||||
|
||||
// Radius inside which objects are active
|
||||
s16 radius = 32;
|
||||
|
||||
for(core::map<u16, RemoteClient*>::Iterator
|
||||
i = m_clients.getIterator();
|
||||
|
@ -1204,8 +1213,9 @@ void Server::AsyncRunStep()
|
|||
{
|
||||
RemoteClient *client = i.getNode()->getValue();
|
||||
Player *player = m_env.getPlayer(client->peer_id);
|
||||
if(player==NULL)
|
||||
continue;
|
||||
v3s16 pos = floatToInt(player->getPosition(), BS);
|
||||
s16 radius = 32;
|
||||
|
||||
core::map<u16, bool> removed_objects;
|
||||
core::map<u16, bool> added_objects;
|
||||
|
@ -1407,8 +1417,44 @@ void Server::AsyncRunStep()
|
|||
}
|
||||
}
|
||||
|
||||
} // enable_experimental
|
||||
|
||||
/*
|
||||
Send queued-for-sending map edit events.
|
||||
*/
|
||||
{
|
||||
while(m_unsent_map_edit_queue.size() != 0)
|
||||
{
|
||||
MapEditEvent* event = m_unsent_map_edit_queue.pop_front();
|
||||
|
||||
if(event->type == MEET_ADDNODE)
|
||||
{
|
||||
dstream<<"Server: MEET_ADDNODE"<<std::endl;
|
||||
sendAddNode(event->p, event->n, event->already_known_by_peer);
|
||||
}
|
||||
else if(event->type == MEET_REMOVENODE)
|
||||
{
|
||||
dstream<<"Server: MEET_REMOVENODE"<<std::endl;
|
||||
sendRemoveNode(event->p, event->already_known_by_peer);
|
||||
}
|
||||
else if(event->type == MEET_OTHER)
|
||||
{
|
||||
dstream<<"WARNING: Server: MEET_OTHER not implemented"
|
||||
<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
dstream<<"WARNING: Server: Unknown MapEditEvent "
|
||||
<<((u32)event->type)<<std::endl;
|
||||
}
|
||||
|
||||
delete event;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Send object positions
|
||||
TODO: Get rid of MapBlockObjects
|
||||
*/
|
||||
{
|
||||
float &counter = m_objectdata_timer;
|
||||
|
@ -1964,32 +2010,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
/*
|
||||
Send the removal to all other clients
|
||||
*/
|
||||
|
||||
// Create packet
|
||||
u32 replysize = 8;
|
||||
SharedBuffer<u8> reply(replysize);
|
||||
writeU16(&reply[0], TOCLIENT_REMOVENODE);
|
||||
writeS16(&reply[2], p_under.X);
|
||||
writeS16(&reply[4], p_under.Y);
|
||||
writeS16(&reply[6], p_under.Z);
|
||||
|
||||
for(core::map<u16, RemoteClient*>::Iterator
|
||||
i = m_clients.getIterator();
|
||||
i.atEnd() == false; i++)
|
||||
{
|
||||
// Get client and check that it is valid
|
||||
RemoteClient *client = i.getNode()->getValue();
|
||||
assert(client->peer_id == i.getNode()->getKey());
|
||||
if(client->serialization_version == SER_FMT_VER_INVALID)
|
||||
continue;
|
||||
|
||||
// Don't send if it's the same one
|
||||
if(peer_id == client->peer_id)
|
||||
continue;
|
||||
|
||||
// Send as reliable
|
||||
m_con.Send(client->peer_id, 0, reply, true);
|
||||
}
|
||||
sendRemoveNode(p_over, peer_id);
|
||||
|
||||
/*
|
||||
Update and send inventory
|
||||
|
@ -2063,33 +2084,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
Remove the node
|
||||
(this takes some time so it is done after the quick stuff)
|
||||
*/
|
||||
m_ignore_map_edit_events = true;
|
||||
m_env.getMap().removeNodeAndUpdate(p_under, modified_blocks);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
Update water
|
||||
*/
|
||||
|
||||
// Update water pressure around modification
|
||||
// This also adds it to m_flow_active_nodes if appropriate
|
||||
|
||||
MapVoxelManipulator v(&m_env.getMap());
|
||||
v.m_disable_water_climb =
|
||||
g_settings.getBool("disable_water_climb");
|
||||
|
||||
VoxelArea area(p_under-v3s16(1,1,1), p_under+v3s16(1,1,1));
|
||||
|
||||
try
|
||||
{
|
||||
v.updateAreaWaterPressure(area, m_flow_active_nodes);
|
||||
}
|
||||
catch(ProcessingLimitException &e)
|
||||
{
|
||||
dstream<<"Processing limit reached (1)"<<std::endl;
|
||||
}
|
||||
|
||||
v.blitBack(modified_blocks);
|
||||
#endif
|
||||
m_ignore_map_edit_events = false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2150,17 +2147,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
n.d = mitem->getMaterial();
|
||||
if(content_features(n.d).wall_mounted)
|
||||
n.dir = packDir(p_under - p_over);
|
||||
|
||||
// Create packet
|
||||
u32 replysize = 8 + MapNode::serializedLength(peer_ser_ver);
|
||||
SharedBuffer<u8> reply(replysize);
|
||||
writeU16(&reply[0], TOCLIENT_ADDNODE);
|
||||
writeS16(&reply[2], p_over.X);
|
||||
writeS16(&reply[4], p_over.Y);
|
||||
writeS16(&reply[6], p_over.Z);
|
||||
n.serialize(&reply[8], peer_ser_ver);
|
||||
// Send as reliable
|
||||
m_con.SendToAll(0, reply, true);
|
||||
|
||||
/*
|
||||
Send to all players
|
||||
*/
|
||||
sendAddNode(p_over, n, 0);
|
||||
|
||||
/*
|
||||
Handle inventory
|
||||
|
@ -2183,7 +2174,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
This takes some time so it is done after the quick stuff
|
||||
*/
|
||||
core::map<v3s16, MapBlock*> modified_blocks;
|
||||
m_ignore_map_edit_events = true;
|
||||
m_env.getMap().addNodeAndUpdate(p_over, n, modified_blocks);
|
||||
m_ignore_map_edit_events = false;
|
||||
|
||||
/*
|
||||
Calculate special events
|
||||
|
@ -2595,41 +2588,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
}
|
||||
}
|
||||
|
||||
/*void Server::Send(u16 peer_id, u16 channelnum,
|
||||
SharedBuffer<u8> data, bool reliable)
|
||||
void Server::onMapEditEvent(MapEditEvent *event)
|
||||
{
|
||||
JMutexAutoLock lock(m_con_mutex);
|
||||
m_con.Send(peer_id, channelnum, data, reliable);
|
||||
}*/
|
||||
|
||||
void Server::SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver)
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
/*
|
||||
Create a packet with the block in the right format
|
||||
*/
|
||||
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
block->serialize(os, ver);
|
||||
std::string s = os.str();
|
||||
SharedBuffer<u8> blockdata((u8*)s.c_str(), s.size());
|
||||
|
||||
u32 replysize = 8 + blockdata.getSize();
|
||||
SharedBuffer<u8> reply(replysize);
|
||||
v3s16 p = block->getPos();
|
||||
writeU16(&reply[0], TOCLIENT_BLOCKDATA);
|
||||
writeS16(&reply[2], p.X);
|
||||
writeS16(&reply[4], p.Y);
|
||||
writeS16(&reply[6], p.Z);
|
||||
memcpy(&reply[8], *blockdata, blockdata.getSize());
|
||||
|
||||
/*dstream<<"Sending block ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
||||
<<": \tpacket size: "<<replysize<<std::endl;*/
|
||||
|
||||
/*
|
||||
Send packet
|
||||
*/
|
||||
m_con.Send(peer_id, 1, reply, true);
|
||||
dstream<<"Server::onMapEditEvent()"<<std::endl;
|
||||
if(m_ignore_map_edit_events)
|
||||
return;
|
||||
MapEditEvent *e = event->clone();
|
||||
m_unsent_map_edit_queue.push_back(e);
|
||||
}
|
||||
|
||||
core::list<PlayerInfo> Server::getPlayerInfo()
|
||||
|
@ -2759,6 +2724,10 @@ void Server::SendPlayerInfos()
|
|||
m_con.SendToAll(0, data, true);
|
||||
}
|
||||
|
||||
/*
|
||||
Craft checking system
|
||||
*/
|
||||
|
||||
enum ItemSpecType
|
||||
{
|
||||
ITEM_NONE,
|
||||
|
@ -3109,6 +3078,97 @@ void Server::BroadcastChatMessage(const std::wstring &message)
|
|||
}
|
||||
}
|
||||
|
||||
void Server::sendRemoveNode(v3s16 p, u16 ignore_id)
|
||||
{
|
||||
JMutexAutoLock conlock(m_con_mutex);
|
||||
|
||||
// Create packet
|
||||
u32 replysize = 8;
|
||||
SharedBuffer<u8> reply(replysize);
|
||||
writeU16(&reply[0], TOCLIENT_REMOVENODE);
|
||||
writeS16(&reply[2], p.X);
|
||||
writeS16(&reply[4], p.Y);
|
||||
writeS16(&reply[6], p.Z);
|
||||
|
||||
for(core::map<u16, RemoteClient*>::Iterator
|
||||
i = m_clients.getIterator();
|
||||
i.atEnd() == false; i++)
|
||||
{
|
||||
// Get client and check that it is valid
|
||||
RemoteClient *client = i.getNode()->getValue();
|
||||
assert(client->peer_id == i.getNode()->getKey());
|
||||
if(client->serialization_version == SER_FMT_VER_INVALID)
|
||||
continue;
|
||||
|
||||
// Don't send if it's the same one
|
||||
if(client->peer_id == ignore_id)
|
||||
continue;
|
||||
|
||||
// Send as reliable
|
||||
m_con.Send(client->peer_id, 0, reply, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id)
|
||||
{
|
||||
for(core::map<u16, RemoteClient*>::Iterator
|
||||
i = m_clients.getIterator();
|
||||
i.atEnd() == false; i++)
|
||||
{
|
||||
// Get client and check that it is valid
|
||||
RemoteClient *client = i.getNode()->getValue();
|
||||
assert(client->peer_id == i.getNode()->getKey());
|
||||
if(client->serialization_version == SER_FMT_VER_INVALID)
|
||||
continue;
|
||||
|
||||
// Don't send if it's the same one
|
||||
if(client->peer_id == ignore_id)
|
||||
continue;
|
||||
|
||||
// Create packet
|
||||
u32 replysize = 8 + MapNode::serializedLength(client->serialization_version);
|
||||
SharedBuffer<u8> reply(replysize);
|
||||
writeU16(&reply[0], TOCLIENT_ADDNODE);
|
||||
writeS16(&reply[2], p.X);
|
||||
writeS16(&reply[4], p.Y);
|
||||
writeS16(&reply[6], p.Z);
|
||||
n.serialize(&reply[8], client->serialization_version);
|
||||
|
||||
// Send as reliable
|
||||
m_con.Send(client->peer_id, 0, reply, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Server::SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver)
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
/*
|
||||
Create a packet with the block in the right format
|
||||
*/
|
||||
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
block->serialize(os, ver);
|
||||
std::string s = os.str();
|
||||
SharedBuffer<u8> blockdata((u8*)s.c_str(), s.size());
|
||||
|
||||
u32 replysize = 8 + blockdata.getSize();
|
||||
SharedBuffer<u8> reply(replysize);
|
||||
v3s16 p = block->getPos();
|
||||
writeU16(&reply[0], TOCLIENT_BLOCKDATA);
|
||||
writeS16(&reply[2], p.X);
|
||||
writeS16(&reply[4], p.Y);
|
||||
writeS16(&reply[6], p.Z);
|
||||
memcpy(&reply[8], *blockdata, blockdata.getSize());
|
||||
|
||||
/*dstream<<"Sending block ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
||||
<<": \tpacket size: "<<replysize<<std::endl;*/
|
||||
|
||||
/*
|
||||
Send packet
|
||||
*/
|
||||
m_con.Send(peer_id, 1, reply, true);
|
||||
}
|
||||
|
||||
void Server::SendBlocks(float dtime)
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
|
@ -3316,16 +3376,16 @@ Player *Server::emergePlayer(const char *name, const char *password,
|
|||
<<player->getName()<<"\""<<std::endl;
|
||||
|
||||
v2s16 nodepos;
|
||||
#if 1
|
||||
#if 0
|
||||
player->setPosition(intToFloat(v3s16(
|
||||
0,
|
||||
45, //64,
|
||||
0
|
||||
), BS));
|
||||
#endif
|
||||
#if 0
|
||||
f32 groundheight = 0;
|
||||
#if 0
|
||||
#if 1
|
||||
s16 groundheight = 0;
|
||||
#if 1
|
||||
// Try to find a good place a few times
|
||||
for(s32 i=0; i<500; i++)
|
||||
{
|
||||
|
@ -3334,12 +3394,20 @@ Player *Server::emergePlayer(const char *name, const char *password,
|
|||
nodepos = v2s16(-range + (myrand()%(range*2)),
|
||||
-range + (myrand()%(range*2)));
|
||||
v2s16 sectorpos = getNodeSectorPos(nodepos);
|
||||
/*
|
||||
Ignore position if it is near a chunk edge.
|
||||
Otherwise it would cause excessive loading time at
|
||||
initial generation
|
||||
*/
|
||||
{
|
||||
if(m_env.getServerMap().sector_to_chunk(sectorpos+v2s16(1,1))
|
||||
!= m_env.getServerMap().sector_to_chunk(sectorpos+v2s16(-1,-1)))
|
||||
continue;
|
||||
}
|
||||
// Get sector
|
||||
m_env.getMap().emergeSector(sectorpos);
|
||||
// Get ground height at point
|
||||
groundheight = m_env.getMap().getGroundHeight(nodepos, true);
|
||||
// The sector should have been generated -> groundheight exists
|
||||
assert(groundheight > GROUNDHEIGHT_VALID_MINVALUE);
|
||||
groundheight = m_env.getServerMap().findGroundLevel(nodepos);
|
||||
// Don't go underwater
|
||||
if(groundheight < WATER_LEVEL)
|
||||
{
|
||||
|
@ -3384,10 +3452,9 @@ Player *Server::emergePlayer(const char *name, const char *password,
|
|||
|
||||
player->setPosition(intToFloat(v3s16(
|
||||
nodepos.X,
|
||||
//groundheight + 1,
|
||||
groundheight + 15,
|
||||
groundheight + 1,
|
||||
nodepos.Y
|
||||
)));
|
||||
), BS));
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue