diff options
Diffstat (limited to 'src/server.cpp')
-rw-r--r-- | src/server.cpp | 118 |
1 files changed, 87 insertions, 31 deletions
diff --git a/src/server.cpp b/src/server.cpp index 2da9cbe24..a793c6e2a 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -54,6 +54,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/pointedthing.h" #include "util/mathconstants.h" #include "rollback.h" +#include "util/serialize.h" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" @@ -1111,7 +1112,17 @@ Server::~Server() {} } } - + + { + JMutexAutoLock envlock(m_env_mutex); + JMutexAutoLock conlock(m_con_mutex); + + /* + Execute script shutdown hooks + */ + scriptapi_on_shutdown(m_lua); + } + { JMutexAutoLock envlock(m_env_mutex); @@ -1143,14 +1154,6 @@ Server::~Server() i = m_clients.getIterator(); i.atEnd() == false; i++) { - /*// Delete player - // NOTE: These are removed by env destructor - { - u16 peer_id = i.getNode()->getKey(); - JMutexAutoLock envlock(m_env_mutex); - m_env->removePlayer(peer_id); - }*/ - // Delete client delete i.getNode()->getValue(); } @@ -1371,9 +1374,9 @@ void Server::AsyncRunStep() /* Send player inventories and HPs if necessary */ - if(playersao->m_teleported){ + if(playersao->m_moved){ SendMovePlayer(client->peer_id); - playersao->m_teleported = false; + playersao->m_moved = false; } if(playersao->m_inventory_not_sent){ UpdateCrafting(client->peer_id); @@ -1567,7 +1570,7 @@ void Server::AsyncRunStep() if(obj) data_buffer.append(serializeLongString( - obj->getClientInitializationData())); + obj->getClientInitializationData(client->net_proto_version))); else data_buffer.append(serializeLongString("")); @@ -2037,40 +2040,74 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) Read and check network protocol version */ - u16 net_proto_version = 0; + u16 min_net_proto_version = 0; if(datasize >= 2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2) + min_net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE]); + + // Use same version as minimum and maximum if maximum version field + // doesn't exist (backwards compatibility) + u16 max_net_proto_version = min_net_proto_version; + if(datasize >= 2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2+2) + max_net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2]); + + // Start with client's maximum version + u16 net_proto_version = max_net_proto_version; + + // Figure out a working version if it is possible at all + if(max_net_proto_version >= SERVER_PROTOCOL_VERSION_MIN || + min_net_proto_version <= SERVER_PROTOCOL_VERSION_MAX) { - net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE]); + // If maximum is larger than our maximum, go with our maximum + if(max_net_proto_version > SERVER_PROTOCOL_VERSION_MAX) + net_proto_version = SERVER_PROTOCOL_VERSION_MAX; + // Else go with client's maximum + else + net_proto_version = max_net_proto_version; } + verbosestream<<"Server: "<<peer_id<<" Protocol version: min: " + <<min_net_proto_version<<", max: "<<max_net_proto_version + <<", chosen: "<<net_proto_version<<std::endl; + getClient(peer_id)->net_proto_version = net_proto_version; - if(net_proto_version == 0) + if(net_proto_version < SERVER_PROTOCOL_VERSION_MIN || + net_proto_version > SERVER_PROTOCOL_VERSION_MAX) { - actionstream<<"Server: An old tried to connect from "<<addr_s + actionstream<<"Server: A mismatched client tried to connect from "<<addr_s <<std::endl; SendAccessDenied(m_con, peer_id, std::wstring( L"Your client's version is not supported.\n" L"Server version is ") - + narrow_to_wide(VERSION_STRING) + L"." + + narrow_to_wide(VERSION_STRING) + L",\n" + + L"server's PROTOCOL_VERSION is " + + narrow_to_wide(itos(SERVER_PROTOCOL_VERSION_MIN)) + + L"..." + + narrow_to_wide(itos(SERVER_PROTOCOL_VERSION_MAX)) + + L", client's PROTOCOL_VERSION is " + + narrow_to_wide(itos(min_net_proto_version)) + + L"..." + + narrow_to_wide(itos(max_net_proto_version)) ); return; } if(g_settings->getBool("strict_protocol_version_checking")) { - if(net_proto_version != PROTOCOL_VERSION) + if(net_proto_version != LATEST_PROTOCOL_VERSION) { - actionstream<<"Server: A mismatched client tried to connect" - <<" from "<<addr_s<<std::endl; + actionstream<<"Server: A mismatched (strict) client tried to " + <<"connect from "<<addr_s<<std::endl; SendAccessDenied(m_con, peer_id, std::wstring( L"Your client's version is not supported.\n" L"Server version is ") + narrow_to_wide(VERSION_STRING) + L",\n" - + L"server's PROTOCOL_VERSION is " - + narrow_to_wide(itos(PROTOCOL_VERSION)) + + L"server's PROTOCOL_VERSION (strict) is " + + narrow_to_wide(itos(LATEST_PROTOCOL_VERSION)) + L", client's PROTOCOL_VERSION is " - + narrow_to_wide(itos(net_proto_version)) + + narrow_to_wide(itos(min_net_proto_version)) + + L"..." + + narrow_to_wide(itos(max_net_proto_version)) ); return; } @@ -2212,11 +2249,12 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) Answer with a TOCLIENT_INIT */ { - SharedBuffer<u8> reply(2+1+6+8); + SharedBuffer<u8> reply(2+1+6+8+4); writeU16(&reply[0], TOCLIENT_INIT); writeU8(&reply[2], deployed); writeV3S16(&reply[2+1], floatToInt(playersao->getPlayer()->getPosition()+v3f(0,BS/2,0), BS)); writeU64(&reply[2+1+6], m_env->getServerMap().getSeed()); + writeF1000(&reply[2+1+6+8], g_settings->getFloat("dedicated_server_step")); // Send as reliable m_con.Send(peer_id, 0, reply, true); @@ -2242,8 +2280,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) return; } - getClient(peer_id)->serialization_version - = getClient(peer_id)->pending_serialization_version; + RemoteClient *client = getClient(peer_id); + client->serialization_version = + getClient(peer_id)->pending_serialization_version; /* Send some initialization data @@ -2256,7 +2295,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) SendItemDef(m_con, peer_id, m_itemdef); // Send node definitions - SendNodeDef(m_con, peer_id, m_nodedef); + SendNodeDef(m_con, peer_id, m_nodedef, client->net_proto_version); // Send media announcement sendMediaAnnouncement(peer_id); @@ -2310,9 +2349,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) } // Warnings about protocol version can be issued here - if(getClient(peer_id)->net_proto_version < PROTOCOL_VERSION) + if(getClient(peer_id)->net_proto_version < LATEST_PROTOCOL_VERSION) { - SendChatMessage(peer_id, L"# Server: WARNING: YOUR CLIENT IS OLD AND MAY WORK PROPERLY WITH THIS SERVER!"); + SendChatMessage(peer_id, L"# Server: WARNING: YOUR CLIENT'S " + L"VERSION MAY NOT BE FULLY COMPATIBLE WITH THIS SERVER!"); } /* @@ -2377,6 +2417,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) v3s32 ss = readV3S32(&data[start+2+12]); f32 pitch = (f32)readS32(&data[2+12+12]) / 100.0; f32 yaw = (f32)readS32(&data[2+12+12+4]) / 100.0; + u32 keyPressed = 0; + if(datasize >= 2+12+12+4+4+4) + keyPressed = (u32)readU32(&data[2+12+12+4+4]); v3f position((f32)ps.X/100., (f32)ps.Y/100., (f32)ps.Z/100.); v3f speed((f32)ss.X/100., (f32)ss.Y/100., (f32)ss.Z/100.); pitch = wrapDegrees(pitch); @@ -2386,6 +2429,16 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) player->setSpeed(speed); player->setPitch(pitch); player->setYaw(yaw); + player->keyPressed=keyPressed; + player->control.up = (bool)(keyPressed&1); + player->control.down = (bool)(keyPressed&2); + player->control.left = (bool)(keyPressed&4); + player->control.right = (bool)(keyPressed&8); + player->control.jump = (bool)(keyPressed&16); + player->control.aux1 = (bool)(keyPressed&32); + player->control.sneak = (bool)(keyPressed&64); + player->control.LMB = (bool)(keyPressed&128); + player->control.RMB = (bool)(keyPressed&256); /*infostream<<"Server::ProcessData(): Moved player "<<peer_id<<" to " <<"("<<position.X<<","<<position.Y<<","<<position.Z<<")" @@ -3166,6 +3219,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) } } // action == 4 + /* Catch invalid actions @@ -3496,7 +3550,7 @@ void Server::SendItemDef(con::Connection &con, u16 peer_id, } void Server::SendNodeDef(con::Connection &con, u16 peer_id, - INodeDefManager *nodedef) + INodeDefManager *nodedef, u16 protocol_version) { DSTACK(__FUNCTION_NAME); std::ostringstream os(std::ios_base::binary); @@ -3508,7 +3562,7 @@ void Server::SendNodeDef(con::Connection &con, u16 peer_id, */ writeU16(os, TOCLIENT_NODEDEF); std::ostringstream tmp_os(std::ios::binary); - nodedef->serialize(tmp_os); + nodedef->serialize(tmp_os, protocol_version); std::ostringstream tmp_os2(std::ios::binary); compressZlib(tmp_os.str(), tmp_os2); os<<serializeLongString(tmp_os2.str()); @@ -4029,6 +4083,7 @@ void Server::fillMediaCache() paths.push_back(mod.path + DIR_DELIM + "textures"); paths.push_back(mod.path + DIR_DELIM + "sounds"); paths.push_back(mod.path + DIR_DELIM + "media"); + paths.push_back(mod.path + DIR_DELIM + "models"); } std::string path_all = "textures"; paths.push_back(path_all + DIR_DELIM + "all"); @@ -4054,6 +4109,7 @@ void Server::fillMediaCache() ".png", ".jpg", ".bmp", ".tga", ".pcx", ".ppm", ".psd", ".wal", ".rgb", ".ogg", + ".x", ".b3d", ".md2", ".obj", NULL }; if(removeStringEnd(filename, supported_ext) == ""){ |