summaryrefslogtreecommitdiff
path: root/src/client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/client.cpp')
-rw-r--r--src/client.cpp191
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 << "'";