diff options
Diffstat (limited to 'src/client.cpp')
-rw-r--r-- | src/client.cpp | 191 |
1 files changed, 88 insertions, 103 deletions
diff --git a/src/client.cpp b/src/client.cpp index 946f4f1c4..4ffcec6ba 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <algorithm> #include <sstream> #include <IFileSystem.h> -#include "jthread/jmutexautolock.h" +#include "threading/mutex_auto_lock.h" #include "util/auth.h" #include "util/directiontables.h" #include "util/pointedthing.h" @@ -82,11 +82,11 @@ MeshUpdateQueue::MeshUpdateQueue() MeshUpdateQueue::~MeshUpdateQueue() { - JMutexAutoLock lock(m_mutex); + MutexAutoLock lock(m_mutex); for(std::vector<QueuedMeshUpdate*>::iterator i = m_queue.begin(); - i != m_queue.end(); i++) + i != m_queue.end(); ++i) { QueuedMeshUpdate *q = *i; delete q; @@ -98,11 +98,11 @@ MeshUpdateQueue::~MeshUpdateQueue() */ void MeshUpdateQueue::addBlock(v3s16 p, MeshMakeData *data, bool ack_block_to_server, bool urgent) { - DSTACK(__FUNCTION_NAME); + DSTACK(FUNCTION_NAME); assert(data); // pre-condition - JMutexAutoLock lock(m_mutex); + MutexAutoLock lock(m_mutex); if(urgent) m_urgents.insert(p); @@ -113,7 +113,7 @@ void MeshUpdateQueue::addBlock(v3s16 p, MeshMakeData *data, bool ack_block_to_se */ for(std::vector<QueuedMeshUpdate*>::iterator i = m_queue.begin(); - i != m_queue.end(); i++) + i != m_queue.end(); ++i) { QueuedMeshUpdate *q = *i; if(q->p == p) @@ -141,12 +141,12 @@ void MeshUpdateQueue::addBlock(v3s16 p, MeshMakeData *data, bool ack_block_to_se // Returns NULL if queue is empty QueuedMeshUpdate *MeshUpdateQueue::pop() { - JMutexAutoLock lock(m_mutex); + MutexAutoLock lock(m_mutex); bool must_be_urgent = !m_urgents.empty(); for(std::vector<QueuedMeshUpdate*>::iterator i = m_queue.begin(); - i != m_queue.end(); i++) + i != m_queue.end(); ++i) { QueuedMeshUpdate *q = *i; if(must_be_urgent && m_urgents.count(q->p) == 0) @@ -228,17 +228,17 @@ Client::Client( m_particle_manager(&m_env), m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, ipv6, this), m_device(device), + m_camera(NULL), + m_minimap_disabled_by_server(false), m_server_ser_ver(SER_FMT_VER_INVALID), m_proto_ver(0), m_playeritem(0), m_inventory_updated(false), m_inventory_from_server(NULL), m_inventory_from_server_age(0.0), - m_show_highlighted(false), m_animation_time(0), m_crack_level(-1), m_crack_pos(0,0,0), - m_highlighted_pos(0,0,0), m_map_seed(0), m_password(password), m_chosen_auth_mech(AUTH_MECHANISM_NONE), @@ -264,12 +264,15 @@ Client::Client( m_cache_smooth_lighting = g_settings->getBool("smooth_lighting"); m_cache_enable_shaders = g_settings->getBool("enable_shaders"); + m_cache_use_tangent_vertices = m_cache_enable_shaders && ( + g_settings->getBool("enable_bumpmapping") || + g_settings->getBool("enable_parallax_occlusion")); } void Client::Stop() { //request all client managed threads to stop - m_mesh_update_thread.Stop(); + m_mesh_update_thread.stop(); // Save local server map if (m_localdb) { infostream << "Local map saving ended." << std::endl; @@ -280,7 +283,7 @@ void Client::Stop() bool Client::isShutdown() { - if (!m_mesh_update_thread.IsRunning()) return true; + if (!m_mesh_update_thread.isRunning()) return true; return false; } @@ -289,8 +292,8 @@ Client::~Client() { m_con.Disconnect(); - m_mesh_update_thread.Stop(); - m_mesh_update_thread.Wait(); + m_mesh_update_thread.stop(); + m_mesh_update_thread.wait(); while (!m_mesh_update_thread.m_queue_out.empty()) { MeshUpdateResult r = m_mesh_update_thread.m_queue_out.pop_frontNoEx(); delete r.mesh; @@ -322,7 +325,7 @@ void Client::connect(Address address, const std::string &address_name, bool is_local_server) { - DSTACK(__FUNCTION_NAME); + DSTACK(FUNCTION_NAME); initLocalMapSaving(address, address_name, is_local_server); @@ -332,7 +335,7 @@ void Client::connect(Address address, void Client::step(float dtime) { - DSTACK(__FUNCTION_NAME); + DSTACK(FUNCTION_NAME); // Limit a bit if(dtime > 2.0) @@ -383,25 +386,30 @@ void Client::step(float dtime) Player *myplayer = m_env.getLocalPlayer(); FATAL_ERROR_IF(myplayer == NULL, "Local player not found in environment."); - // Send TOSERVER_INIT_LEGACY - // [0] u16 TOSERVER_INIT_LEGACY - // [2] u8 SER_FMT_VER_HIGHEST_READ - // [3] u8[20] player_name - // [23] u8[28] password (new in some version) - // [51] u16 minimum supported network protocol version (added sometime) - // [53] u16 maximum supported network protocol version (added later than the previous one) - - char pName[PLAYERNAME_SIZE]; - char pPassword[PASSWORD_SIZE]; - memset(pName, 0, PLAYERNAME_SIZE * sizeof(char)); - memset(pPassword, 0, PASSWORD_SIZE * sizeof(char)); - - std::string hashed_password = translatePassword(myplayer->getName(), m_password); - snprintf(pName, PLAYERNAME_SIZE, "%s", myplayer->getName()); - snprintf(pPassword, PASSWORD_SIZE, "%s", hashed_password.c_str()); - - sendLegacyInit(pName, pPassword); - if (LATEST_PROTOCOL_VERSION >= 25) + u16 proto_version_min = g_settings->getFlag("send_pre_v25_init") ? + CLIENT_PROTOCOL_VERSION_MIN_LEGACY : CLIENT_PROTOCOL_VERSION_MIN; + + if (proto_version_min < 25) { + // Send TOSERVER_INIT_LEGACY + // [0] u16 TOSERVER_INIT_LEGACY + // [2] u8 SER_FMT_VER_HIGHEST_READ + // [3] u8[20] player_name + // [23] u8[28] password (new in some version) + // [51] u16 minimum supported network protocol version (added sometime) + // [53] u16 maximum supported network protocol version (added later than the previous one) + + char pName[PLAYERNAME_SIZE]; + char pPassword[PASSWORD_SIZE]; + memset(pName, 0, PLAYERNAME_SIZE * sizeof(char)); + memset(pPassword, 0, PASSWORD_SIZE * sizeof(char)); + + std::string hashed_password = translate_password(myplayer->getName(), m_password); + snprintf(pName, PLAYERNAME_SIZE, "%s", myplayer->getName()); + snprintf(pPassword, PASSWORD_SIZE, "%s", hashed_password.c_str()); + + sendLegacyInit(pName, pPassword); + } + if (CLIENT_PROTOCOL_VERSION_MAX >= 25) sendInit(myplayer->getName()); } @@ -617,7 +625,7 @@ void Client::step(float dtime) { for(std::map<int, u16>::iterator i = m_sounds_to_objects.begin(); - i != m_sounds_to_objects.end(); i++) + i != m_sounds_to_objects.end(); ++i) { int client_id = i->first; u16 object_id = i->second; @@ -642,7 +650,7 @@ void Client::step(float dtime) i != m_sounds_server_to_client.end();) { s32 server_id = i->first; int client_id = i->second; - i++; + ++i; if(!m_sound->soundExists(client_id)) { m_sounds_server_to_client.erase(server_id); m_sounds_client_to_server.erase(client_id); @@ -823,7 +831,7 @@ void Client::initLocalMapSaving(const Address &address, void Client::ReceiveAll() { - DSTACK(__FUNCTION_NAME); + DSTACK(FUNCTION_NAME); u32 start_ms = porting::getTimeMs(); for(;;) { @@ -849,7 +857,7 @@ void Client::ReceiveAll() void Client::Receive() { - DSTACK(__FUNCTION_NAME); + DSTACK(FUNCTION_NAME); NetworkPacket pkt; m_con.Receive(&pkt); ProcessData(&pkt); @@ -866,7 +874,7 @@ inline void Client::handleCommand(NetworkPacket* pkt) */ void Client::ProcessData(NetworkPacket *pkt) { - DSTACK(__FUNCTION_NAME); + DSTACK(FUNCTION_NAME); ToClientCommand command = (ToClientCommand) pkt->getCommand(); u32 sender_peer_id = pkt->getPeerId(); @@ -945,6 +953,7 @@ void Client::interact(u8 action, const PointedThing& pointed) 2: digging completed 3: place block or item (to abovesurface) 4: use item + 5: perform secondary action of item */ NetworkPacket pkt(TOSERVER_INTERACT, 1 + 2 + 0); @@ -999,10 +1008,13 @@ void Client::sendLegacyInit(const char* playerName, const char* playerPassword) NetworkPacket pkt(TOSERVER_INIT_LEGACY, 1 + PLAYERNAME_SIZE + PASSWORD_SIZE + 2 + 2); + u16 proto_version_min = g_settings->getFlag("send_pre_v25_init") ? + CLIENT_PROTOCOL_VERSION_MIN_LEGACY : CLIENT_PROTOCOL_VERSION_MIN; + pkt << (u8) SER_FMT_VER_HIGHEST_READ; pkt.putRawString(playerName,PLAYERNAME_SIZE); pkt.putRawString(playerPassword, PASSWORD_SIZE); - pkt << (u16) CLIENT_PROTOCOL_VERSION_MIN << (u16) CLIENT_PROTOCOL_VERSION_MAX; + pkt << (u16) proto_version_min << (u16) CLIENT_PROTOCOL_VERSION_MAX; Send(&pkt); } @@ -1013,8 +1025,12 @@ void Client::sendInit(const std::string &playerName) // we don't support network compression yet u16 supp_comp_modes = NETPROTO_COMPRESSION_NONE; + + u16 proto_version_min = g_settings->getFlag("send_pre_v25_init") ? + CLIENT_PROTOCOL_VERSION_MIN_LEGACY : CLIENT_PROTOCOL_VERSION_MIN; + pkt << (u8) SER_FMT_VER_HIGHEST_READ << (u16) supp_comp_modes; - pkt << (u16) CLIENT_PROTOCOL_VERSION_MIN << (u16) CLIENT_PROTOCOL_VERSION_MAX; + pkt << (u16) proto_version_min << (u16) CLIENT_PROTOCOL_VERSION_MAX; pkt << playerName; Send(&pkt); @@ -1027,18 +1043,14 @@ void Client::startAuth(AuthMechanism chosen_auth_mechanism) switch (chosen_auth_mechanism) { case AUTH_MECHANISM_FIRST_SRP: { // send srp verifier to server + std::string verifier; + std::string salt; + generate_srp_verifier_and_salt(getPlayerName(), m_password, + &verifier, &salt); + NetworkPacket resp_pkt(TOSERVER_FIRST_SRP, 0); - char *salt, *bytes_v; - std::size_t len_salt, len_v; - salt = NULL; - getSRPVerifier(getPlayerName(), m_password, - &salt, &len_salt, &bytes_v, &len_v); - resp_pkt - << std::string((char*)salt, len_salt) - << std::string((char*)bytes_v, len_v) - << (u8)((m_password == "") ? 1 : 0); - free(salt); - free(bytes_v); + resp_pkt << salt << verifier << (u8)((m_password == "") ? 1 : 0); + Send(&resp_pkt); break; } @@ -1047,7 +1059,7 @@ void Client::startAuth(AuthMechanism chosen_auth_mechanism) u8 based_on = 1; if (chosen_auth_mechanism == AUTH_MECHANISM_LEGACY_PASSWORD) { - m_password = translatePassword(getPlayerName(), m_password); + m_password = translate_password(getPlayerName(), m_password); based_on = 0; } @@ -1058,8 +1070,10 @@ void Client::startAuth(AuthMechanism chosen_auth_mechanism) m_password.length(), NULL, NULL); char *bytes_A = 0; size_t len_A = 0; - srp_user_start_authentication((struct SRPUser *) m_auth_data, - NULL, NULL, 0, (unsigned char **) &bytes_A, &len_A); + SRP_Result res = srp_user_start_authentication( + (struct SRPUser *) m_auth_data, NULL, NULL, 0, + (unsigned char **) &bytes_A, &len_A); + FATAL_ERROR_IF(res != SRP_OK, "Creating local SRP user failed."); NetworkPacket resp_pkt(TOSERVER_SRP_BYTES_A, 0); resp_pkt << std::string(bytes_A, len_A) << based_on; @@ -1105,7 +1119,7 @@ void Client::sendRemovedSounds(std::vector<s32> &soundList) pkt << (u16) (server_ids & 0xFFFF); for(std::vector<s32>::iterator i = soundList.begin(); - i != soundList.end(); i++) + i != soundList.end(); ++i) pkt << *i; Send(&pkt); @@ -1191,8 +1205,8 @@ void Client::sendChangePassword(const std::string &oldpassword, m_new_password = newpassword; startAuth(choseAuthMech(m_sudo_auth_methods)); } else { - std::string oldpwd = translatePassword(playername, oldpassword); - std::string newpwd = translatePassword(playername, newpassword); + std::string oldpwd = translate_password(playername, oldpassword); + std::string newpwd = translate_password(playername, newpassword); NetworkPacket pkt(TOSERVER_PASSWORD_LEGACY, 2 * PASSWORD_SIZE); @@ -1210,7 +1224,7 @@ void Client::sendChangePassword(const std::string &oldpassword, void Client::sendDamage(u8 damage) { - DSTACK(__FUNCTION_NAME); + DSTACK(FUNCTION_NAME); NetworkPacket pkt(TOSERVER_DAMAGE, sizeof(u8)); pkt << damage; @@ -1219,7 +1233,7 @@ void Client::sendDamage(u8 damage) void Client::sendBreath(u16 breath) { - DSTACK(__FUNCTION_NAME); + DSTACK(FUNCTION_NAME); NetworkPacket pkt(TOSERVER_BREATH, sizeof(u16)); pkt << breath; @@ -1228,7 +1242,7 @@ void Client::sendBreath(u16 breath) void Client::sendRespawn() { - DSTACK(__FUNCTION_NAME); + DSTACK(FUNCTION_NAME); NetworkPacket pkt(TOSERVER_RESPAWN, 0); Send(&pkt); @@ -1236,7 +1250,7 @@ void Client::sendRespawn() void Client::sendReady() { - DSTACK(__FUNCTION_NAME); + DSTACK(FUNCTION_NAME); NetworkPacket pkt(TOSERVER_CLIENT_READY, 1 + 1 + 1 + 1 + 2 + sizeof(char) * strlen(g_version_hash)); @@ -1270,7 +1284,7 @@ void Client::sendPlayerPos() u16 our_peer_id; { - //JMutexAutoLock lock(m_con_mutex); //bulk comment-out + //MutexAutoLock lock(m_con_mutex); //bulk comment-out our_peer_id = m_con.GetPeerID(); } @@ -1469,13 +1483,13 @@ ClientActiveObject * Client::getSelectedActiveObject( { ClientActiveObject *obj = objects[i].obj; - core::aabbox3d<f32> *selection_box = obj->getSelectionBox(); + aabb3f *selection_box = obj->getSelectionBox(); if(selection_box == NULL) continue; v3f pos = obj->getPosition(); - core::aabbox3d<f32> offsetted_box( + aabb3f offsetted_box( selection_box->MinEdge + pos, selection_box->MaxEdge + pos ); @@ -1504,15 +1518,6 @@ int Client::getCrackLevel() return m_crack_level; } -void Client::setHighlighted(v3s16 pos, bool show_highlighted) -{ - m_show_highlighted = show_highlighted; - v3s16 old_highlighted_pos = m_highlighted_pos; - m_highlighted_pos = pos; - addUpdateMeshTaskForNode(old_highlighted_pos, false, true); - addUpdateMeshTaskForNode(m_highlighted_pos, false, true); -} - void Client::setCrack(int level, v3s16 pos) { int old_crack_level = m_crack_level; @@ -1589,7 +1594,8 @@ void Client::addUpdateMeshTask(v3s16 p, bool ack_to_server, bool urgent) Create a task to update the mesh of the block */ - MeshMakeData *data = new MeshMakeData(this, m_cache_enable_shaders); + MeshMakeData *data = new MeshMakeData(this, m_cache_enable_shaders, + m_cache_use_tangent_vertices); { //TimeTaker timer("data fill"); @@ -1597,7 +1603,6 @@ void Client::addUpdateMeshTask(v3s16 p, bool ack_to_server, bool urgent) // Debug: 1-6ms, avg=2ms data->fill(b); data->setCrack(m_crack_level, m_crack_pos); - data->setHighlighted(m_highlighted_pos, m_show_highlighted); data->setSmoothLighting(m_cache_smooth_lighting); } @@ -1769,32 +1774,9 @@ void Client::afterContentReceived(IrrlichtDevice *device) m_nodedef->updateTextures(this, texture_update_progress, &tu_args); delete[] tu_args.text_base; - // Preload item textures and meshes if configured to - if(g_settings->getBool("preload_item_visuals")) - { - verbosestream<<"Updating item textures and meshes"<<std::endl; - text = wgettext("Item textures..."); - draw_load_screen(text, device, guienv, 0, 0); - std::set<std::string> names = m_itemdef->getAll(); - size_t size = names.size(); - size_t count = 0; - int percent = 0; - for(std::set<std::string>::const_iterator - i = names.begin(); i != names.end(); ++i) - { - // Asking for these caches the result - m_itemdef->getInventoryTexture(*i, this); - m_itemdef->getWieldMesh(*i, this); - count++; - percent = (count * 100 / size * 0.2) + 80; - draw_load_screen(text, device, guienv, 0, percent); - } - delete[] text; - } - // Start mesh update thread after setting up content definitions infostream<<"- Starting mesh update thread"<<std::endl; - m_mesh_update_thread.Start(); + m_mesh_update_thread.start(); m_state = LC_Ready; sendReady(); @@ -1839,9 +1821,12 @@ void Client::makeScreenshot(IrrlichtDevice *device) + DIR_DELIM + std::string("screenshot_") + std::string(timetstamp_c); - std::string filename_ext = ".png"; + std::string filename_ext = "." + g_settings->get("screenshot_format"); std::string filename; + u32 quality = (u32)g_settings->getS32("screenshot_quality"); + quality = MYMIN(MYMAX(quality, 0), 100) / 100.0 * 255; + // Try to find a unique filename unsigned serial = 0; @@ -1863,7 +1848,7 @@ void Client::makeScreenshot(IrrlichtDevice *device) raw_image->copyTo(image); std::ostringstream sstr; - if (driver->writeImageToFile(image, filename.c_str())) { + if (driver->writeImageToFile(image, filename.c_str(), quality)) { sstr << "Saved screenshot to '" << filename << "'"; } else { sstr << "Failed to save screenshot '" << filename << "'"; |