- // there's no sane reason why we shouldn't have a player and
- // almost everyone needs a player reference
- Player *player = m_env.getLocalPlayer();
- assert(player != NULL);
-
- if(command == TOCLIENT_REMOVENODE)
- {
- if(datasize < 8)
- return;
- v3s16 p;
- p.X = readS16(&data[2]);
- p.Y = readS16(&data[4]);
- p.Z = readS16(&data[6]);
- removeNode(p);
- }
- else if(command == TOCLIENT_ADDNODE)
- {
- if(datasize < 8 + MapNode::serializedLength(ser_version))
- return;
-
- v3s16 p;
- p.X = readS16(&data[2]);
- p.Y = readS16(&data[4]);
- p.Z = readS16(&data[6]);
-
- MapNode n;
- n.deSerialize(&data[8], ser_version);
-
- bool remove_metadata = true;
- u32 index = 8 + MapNode::serializedLength(ser_version);
- if ((datasize >= index+1) && data[index]){
- remove_metadata = false;
- }
-
- addNode(p, n, remove_metadata);
- }
- else if(command == TOCLIENT_BLOCKDATA)
- {
- // Ignore too small packet
- if(datasize < 8)
- return;
-
- v3s16 p;
- p.X = readS16(&data[2]);
- p.Y = readS16(&data[4]);
- p.Z = readS16(&data[6]);
-
- std::string datastring((char*)&data[8], datasize-8);
- std::istringstream istr(datastring, std::ios_base::binary);
-
- MapSector *sector;
- MapBlock *block;
-
- v2s16 p2d(p.X, p.Z);
- sector = m_env.getMap().emergeSector(p2d);
-
- assert(sector->getPos() == p2d);
-
- block = sector->getBlockNoCreateNoEx(p.Y);
- if(block)
- {
- /*
- Update an existing block
- */
- block->deSerialize(istr, ser_version, false);
- block->deSerializeNetworkSpecific(istr);
- }
- else
- {
- /*
- Create a new block
- */
- block = new MapBlock(&m_env.getMap(), p, this);
- block->deSerialize(istr, ser_version, false);
- block->deSerializeNetworkSpecific(istr);
- sector->insertBlock(block);
- }
-
- if (localdb != NULL) {
- ((ServerMap&) localserver->getMap()).saveBlock(block, localdb);
- }
-
- /*
- Add it to mesh update queue and set it to be acknowledged after update.
- */
- addUpdateMeshTaskWithEdge(p, true);
- }
- else if(command == TOCLIENT_INVENTORY)
- {
- if(datasize < 3)
- return;
-
- std::string datastring((char*)&data[2], datasize-2);
- std::istringstream is(datastring, std::ios_base::binary);
-
- player->inventory.deSerialize(is);
-
- m_inventory_updated = true;
-
- delete m_inventory_from_server;
- m_inventory_from_server = new Inventory(player->inventory);
- m_inventory_from_server_age = 0.0;
-
- }
- else if(command == TOCLIENT_TIME_OF_DAY)
- {
- if(datasize < 4)
- return;
-
- u16 time_of_day = readU16(&data[2]);
- time_of_day = time_of_day % 24000;
- float time_speed = 0;
-
- if(datasize >= 2 + 2 + 4)
- {
- time_speed = readF1000(&data[4]);
- }
- else {
- // Old message; try to approximate speed of time by ourselves
- float time_of_day_f = (float)time_of_day / 24000.0;
- float tod_diff_f = 0;
-
- if(time_of_day_f < 0.2 && m_last_time_of_day_f > 0.8)
- tod_diff_f = time_of_day_f - m_last_time_of_day_f + 1.0;
- else
- tod_diff_f = time_of_day_f - m_last_time_of_day_f;
-
- m_last_time_of_day_f = time_of_day_f;
- float time_diff = m_time_of_day_update_timer;
- m_time_of_day_update_timer = 0;
-
- if(m_time_of_day_set){
- time_speed = (3600.0*24.0) * tod_diff_f / time_diff;
- infostream<<"Client: Measured time_of_day speed (old format): "
- <<time_speed<<" tod_diff_f="<<tod_diff_f
- <<" time_diff="<<time_diff<<std::endl;
- }
- }
-
- // Update environment
- m_env.setTimeOfDay(time_of_day);
- m_env.setTimeOfDaySpeed(time_speed);
- m_time_of_day_set = true;
-
- u32 dr = m_env.getDayNightRatio();
- infostream<<"Client: time_of_day="<<time_of_day
- <<" time_speed="<<time_speed
- <<" dr="<<dr<<std::endl;
- }
- else if(command == TOCLIENT_CHAT_MESSAGE)
- {
- /*
- u16 command
- u16 length
- wstring message
- */
- u8 buf[6];
- std::string datastring((char*)&data[2], datasize-2);
- std::istringstream is(datastring, std::ios_base::binary);
-
- // Read stuff
- is.read((char*) buf, 2);
- u16 len = readU16(buf);
-
- std::wstring message;
- for(unsigned int i=0; i<len; i++)
- {
- is.read((char*)buf, 2);
- message += (wchar_t)readU16(buf);
- }
-
- m_chat_queue.push_back(message);
- }
- else if(command == TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD)
- {
- /*
- u16 command
- u16 count of removed objects
- for all removed objects {
- u16 id
- }
- u16 count of added objects
- for all added objects {
- u16 id
- u8 type
- u32 initialization data length
- string initialization data
- }
- */
-
- char buf[6];
- // Get all data except the command number
- std::string datastring((char*)&data[2], datasize-2);
- // Throw them in an istringstream
- std::istringstream is(datastring, std::ios_base::binary);
-
- // Read removed objects
- is.read(buf, 2);
- u16 removed_count = readU16((u8*)buf);
- for(unsigned int i=0; i<removed_count; i++)
- {
- is.read(buf, 2);
- u16 id = readU16((u8*)buf);
- m_env.removeActiveObject(id);
- }
-
- // Read added objects
- is.read(buf, 2);
- u16 added_count = readU16((u8*)buf);
- for(unsigned int i=0; i<added_count; i++)
- {
- is.read(buf, 2);
- u16 id = readU16((u8*)buf);
- is.read(buf, 1);
- u8 type = readU8((u8*)buf);
- std::string data = deSerializeLongString(is);
- // Add it
- m_env.addActiveObject(id, type, data);
- }
- }
- else if(command == TOCLIENT_ACTIVE_OBJECT_MESSAGES)
- {
- /*
- u16 command
- for all objects
- {
- u16 id
- u16 message length
- string message
- }
- */
- char buf[6];
- // Get all data except the command number
- std::string datastring((char*)&data[2], datasize-2);
- // Throw them in an istringstream
- std::istringstream is(datastring, std::ios_base::binary);
-
- while(is.eof() == false)
- {
- is.read(buf, 2);
- u16 id = readU16((u8*)buf);
- if(is.eof())
- break;
- is.read(buf, 2);
- size_t message_size = readU16((u8*)buf);
- std::string message;
- message.reserve(message_size);
- for(unsigned int i=0; i<message_size; i++)
- {
- is.read(buf, 1);
- message.append(buf, 1);
- }
- // Pass on to the environment
- m_env.processActiveObjectMessage(id, message);
- }
- }
- else if(command == TOCLIENT_MOVEMENT)
- {
- std::string datastring((char*)&data[2], datasize-2);
- std::istringstream is(datastring, std::ios_base::binary);
-
- player->movement_acceleration_default = readF1000(is) * BS;
- player->movement_acceleration_air = readF1000(is) * BS;
- player->movement_acceleration_fast = readF1000(is) * BS;
- player->movement_speed_walk = readF1000(is) * BS;
- player->movement_speed_crouch = readF1000(is) * BS;
- player->movement_speed_fast = readF1000(is) * BS;
- player->movement_speed_climb = readF1000(is) * BS;
- player->movement_speed_jump = readF1000(is) * BS;
- player->movement_liquid_fluidity = readF1000(is) * BS;
- player->movement_liquid_fluidity_smooth = readF1000(is) * BS;
- player->movement_liquid_sink = readF1000(is) * BS;
- player->movement_gravity = readF1000(is) * BS;
- }
- else if(command == TOCLIENT_HP)
- {
- std::string datastring((char*)&data[2], datasize-2);
- std::istringstream is(datastring, std::ios_base::binary);