#include "mapsector.h"
#include "mapblock_mesh.h"
#include "mapblock.h"
+#include "settings.h"
+#include "profiler.h"
+#include "log.h"
/*
QueuedMeshUpdate
{
ThreadStarted();
+ log_register_thread("MeshUpdateThread");
+
DSTACK(__FUNCTION_NAME);
BEGIN_DEBUG_EXCEPTION_HANDLER
continue;
}
- ScopeProfiler sp(&g_profiler, "mesh make");
+ ScopeProfiler sp(g_profiler, "mesh make");
scene::SMesh *mesh_new = NULL;
mesh_new = makeMapBlockMesh(q->data);
r.mesh = mesh_new;
r.ack_block_to_server = q->ack_block_to_server;
- /*dstream<<"MeshUpdateThread: Processed "
+ /*infostream<<"MeshUpdateThread: Processed "
<<"("<<q->p.X<<","<<q->p.Y<<","<<q->p.Z<<")"
<<std::endl;*/
delete q;
}
- END_DEBUG_EXCEPTION_HANDLER
+ END_DEBUG_EXCEPTION_HANDLER(errorstream)
return NULL;
}
),
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
m_device(device),
- camera_position(0,0,0),
- camera_direction(0,0,1),
m_server_ser_ver(SER_FMT_VER_INVALID),
m_inventory_updated(false),
m_time_of_day(0),
else
m_ignore_damage_timer = 0.0;
- //dstream<<"Client steps "<<dtime<<std::endl;
+ //infostream<<"Client steps "<<dtime<<std::endl;
{
//TimeTaker timer("ReceiveAll()", m_device);
{
counter = 20.0;
- dout_client<<"Client packetcounter (20s):"<<std::endl;
- m_packetcounter.print(dout_client);
+ infostream<<"Client packetcounter (20s):"<<std::endl;
+ m_packetcounter.print(infostream);
m_packetcounter.clear();
}
}
core::list<v3s16> deleted_blocks;
float delete_unused_sectors_timeout =
- g_settings.getFloat("client_delete_unused_sectors_timeout");
+ g_settings->getFloat("client_delete_unused_sectors_timeout");
// Delete sector blocks
/*u32 num = m_env.getMap().unloadUnusedData
if(deleted_blocks.size() > 0)
{
- /*dstream<<DTIME<<"Client: Deleted blocks of "<<num
+ /*infostream<<"Client: Deleted blocks of "<<num
<<" unused sectors"<<std::endl;*/
- /*dstream<<DTIME<<"Client: Deleted "<<num
+ /*infostream<<"Client: Deleted "<<num
<<" unused sectors"<<std::endl;*/
/*
memset((char*)&data[3], 0, PLAYERNAME_SIZE);
snprintf((char*)&data[3], PLAYERNAME_SIZE, "%s", myplayer->getName());
- /*dstream<<"Client: sending initial password hash: \""<<m_password<<"\""
+ /*infostream<<"Client: sending initial password hash: \""<<m_password<<"\""
<<std::endl;*/
memset((char*)&data[23], 0, PASSWORD_SIZE);
snprintf((char*)&data[23], PASSWORD_SIZE, "%s", m_password.c_str());
// This should be incremented in each version
- writeU16(&data[51], 1);
+ writeU16(&data[51], 3);
// Send as unreliable
Send(0, data, false);
const float map_timer_and_unload_dtime = 5.25;
if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime))
{
- ScopeProfiler sp(&g_profiler, "Client: map timer and unload");
+ ScopeProfiler sp(g_profiler, "Client: map timer and unload");
core::list<v3s16> deleted_blocks;
m_env.getMap().timerUpdate(map_timer_and_unload_dtime,
- g_settings.getFloat("client_unload_unused_data_timeout"),
+ g_settings->getFloat("client_unload_unused_data_timeout"),
&deleted_blocks);
/*if(deleted_blocks.size() > 0)
- dstream<<"Client: Unloaded "<<deleted_blocks.size()
+ infostream<<"Client: Unloaded "<<deleted_blocks.size()
<<" unused blocks"<<std::endl;*/
/*
// Step environment
m_env.step(dtime);
- /*
- Handle active blocks
- NOTE: These old objects are DEPRECATED. TODO: Remove
- */
- for(core::map<v3s16, bool>::Iterator
- i = m_active_blocks.getIterator();
- i.atEnd() == false; i++)
- {
- v3s16 p = i.getNode()->getKey();
-
- MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(p);
- if(block == NULL)
- continue;
-
- // Step MapBlockObjects
- block->stepObjects(dtime, false, m_env.getDayNightRatio());
- }
-
/*
Get events
*/
//JMutexAutoLock lock(m_con_mutex); //bulk comment-out
// connectedAndInitialized() is true, peer exists.
con::Peer *peer = m_con.GetPeer(PEER_ID_SERVER);
- dstream<<DTIME<<"Client: avg_rtt="<<peer->avg_rtt<<std::endl;
+ infostream<<"Client: avg_rtt="<<peer->avg_rtt<<std::endl;
}
}
//TimeTaker timer("** Processing mesh update result queue");
// 0ms
- /*dstream<<"Mesh update result queue size is "
+ /*infostream<<"Mesh update result queue size is "
<<m_mesh_update_thread.m_queue_out.size()
<<std::endl;*/
}
if(r.ack_block_to_server)
{
- /*dstream<<"Client: ACK block ("<<r.p.X<<","<<r.p.Y
+ /*infostream<<"Client: ACK block ("<<r.p.X<<","<<r.p.Y
<<","<<r.p.Z<<")"<<std::endl;*/
/*
Acknowledge block
// Virtual methods from con::PeerHandler
void Client::peerAdded(con::Peer *peer)
{
- derr_client<<"Client::peerAdded(): peer->id="
+ infostream<<"Client::peerAdded(): peer->id="
<<peer->id<<std::endl;
}
void Client::deletingPeer(con::Peer *peer, bool timeout)
{
- derr_client<<"Client::deletingPeer(): "
+ infostream<<"Client::deletingPeer(): "
"Server Peer is getting deleted "
<<"(timeout="<<timeout<<")"<<std::endl;
}
}
catch(con::InvalidIncomingDataException &e)
{
- dout_client<<DTIME<<"Client::ReceiveAll(): "
+ infostream<<"Client::ReceiveAll(): "
"InvalidIncomingDataException: what()="
<<e.what()<<std::endl;
}
ToClientCommand command = (ToClientCommand)readU16(&data[0]);
- //dstream<<"Client: received command="<<command<<std::endl;
+ //infostream<<"Client: received command="<<command<<std::endl;
m_packetcounter.add((u16)command);
/*
*/
if(sender_peer_id != PEER_ID_SERVER)
{
- dout_client<<DTIME<<"Client::ProcessData(): Discarding data not "
+ infostream<<"Client::ProcessData(): Discarding data not "
"coming from server: peer_id="<<sender_peer_id
<<std::endl;
return;
u8 ser_version = m_server_ser_ver;
- //dstream<<"Client received command="<<(int)command<<std::endl;
+ //infostream<<"Client received command="<<(int)command<<std::endl;
if(command == TOCLIENT_INIT)
{
u8 deployed = data[2];
- dout_client<<DTIME<<"Client: TOCLIENT_INIT received with "
+ infostream<<"Client: TOCLIENT_INIT received with "
"deployed="<<((int)deployed&0xff)<<std::endl;
if(deployed < SER_FMT_VER_LOWEST
|| deployed > SER_FMT_VER_HIGHEST)
{
- derr_client<<DTIME<<"Client: TOCLIENT_INIT: Server sent "
+ infostream<<"Client: TOCLIENT_INIT: Server sent "
<<"unsupported ser_fmt_ver"<<std::endl;
return;
}
{
// Get map seed
m_map_seed = readU64(&data[2+1+6]);
- dstream<<"Client: received map seed: "<<m_map_seed<<std::endl;
+ infostream<<"Client: received map seed: "<<m_map_seed<<std::endl;
}
// Reply to server
if(ser_version == SER_FMT_VER_INVALID)
{
- dout_client<<DTIME<<"WARNING: Client: Server serialization"
+ infostream<<"Client: Server serialization"
" format invalid or not initialized."
" Skipping incoming command="<<command<<std::endl;
return;
p.Y = readS16(&data[4]);
p.Z = readS16(&data[6]);
- /*dout_client<<DTIME<<"Client: Thread: BLOCKDATA for ("
+ /*infostream<<"Client: Thread: BLOCKDATA for ("
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
- /*dstream<<DTIME<<"Client: Thread: BLOCKDATA for ("
+ /*infostream<<"Client: Thread: BLOCKDATA for ("
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
std::string datastring((char*)&data[8], datasize-8);
/*
Update an existing block
*/
- //dstream<<"Updating"<<std::endl;
+ //infostream<<"Updating"<<std::endl;
block->deSerialize(istr, ser_version);
}
else
/*
Create a new block
*/
- //dstream<<"Creating new"<<std::endl;
+ //infostream<<"Creating new"<<std::endl;
block = new MapBlock(&m_env.getMap(), p);
block->deSerialize(istr, ser_version);
sector->insertBlock(block);
/*
Add it to mesh update queue and set it to be acknowledged after update.
*/
- //std::cerr<<"Adding mesh update task for received block"<<std::endl;
+ //infostream<<"Adding mesh update task for received block"<<std::endl;
addUpdateMeshTaskWithEdge(p, true);
}
else if(command == TOCLIENT_PLAYERPOS)
{
- dstream<<"WARNING: Received deprecated TOCLIENT_PLAYERPOS"
+ infostream<<"Received deprecated TOCLIENT_PLAYERPOS"
<<std::endl;
/*u16 our_peer_id;
{
}
// Cancel if we don't have a peer id
if(our_peer_id == PEER_ID_INEXISTENT){
- dout_client<<DTIME<<"TOCLIENT_PLAYERPOS cancelled: "
+ infostream<<"TOCLIENT_PLAYERPOS cancelled: "
"we have no peer id"
<<std::endl;
return;
v3s32 ss = readV3S32(&data[start+2+12]);
s32 pitch_i = readS32(&data[start+2+12+12]);
s32 yaw_i = readS32(&data[start+2+12+12+4]);
- /*dstream<<"Client: got "
+ /*infostream<<"Client: got "
<<"pitch_i="<<pitch_i
<<" yaw_i="<<yaw_i<<std::endl;*/
f32 pitch = (f32)pitch_i / 100.0;
player->setPitch(pitch);
player->setYaw(yaw);
- /*dstream<<"Client: player "<<peer_id
+ /*infostream<<"Client: player "<<peer_id
<<" pitch="<<pitch
<<" yaw="<<yaw<<std::endl;*/
}
// Cancel if we don't have a peer id
if(our_peer_id == PEER_ID_INEXISTENT){
- dout_client<<DTIME<<"TOCLIENT_PLAYERINFO cancelled: "
+ infostream<<"TOCLIENT_PLAYERINFO cancelled: "
"we have no peer id"
<<std::endl;
return;
}
- //dstream<<DTIME<<"Client: Server reports players:"<<std::endl;
+ //infostream<<"Client: Server reports players:"<<std::endl;
{ //envlock
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
players_alive.push_back(peer_id);
- /*dstream<<DTIME<<"peer_id="<<peer_id
+ /*infostream<<"peer_id="<<peer_id
<<" name="<<((char*)&data[start+2])<<std::endl;*/
// Don't update the info of the local player
-1);
player->peer_id = peer_id;
m_env.addPlayer(player);
- dout_client<<DTIME<<"Client: Adding new player "
+ infostream<<"Client: Adding new player "
<<peer_id<<std::endl;
}
Remove those players from the environment that
weren't listed by the server.
*/
- //dstream<<DTIME<<"Removing dead players"<<std::endl;
+ //infostream<<"Removing dead players"<<std::endl;
core::list<Player*> players = m_env.getPlayers();
core::list<Player*>::Iterator ip;
for(ip=players.begin(); ip!=players.end(); ip++)
// Warn about a special case
if((*ip)->peer_id == 0)
{
- dstream<<DTIME<<"WARNING: Client: Removing "
+ infostream<<"Client: Removing "
"dead player with id=0"<<std::endl;
}
break;
}
}
- /*dstream<<DTIME<<"peer_id="<<((*ip)->peer_id)
+ /*infostream<<"peer_id="<<((*ip)->peer_id)
<<" is_alive="<<is_alive<<std::endl;*/
if(is_alive)
continue;
- dstream<<DTIME<<"Removing dead player "<<(*ip)->peer_id
+ infostream<<"Removing dead player "<<(*ip)->peer_id
<<std::endl;
m_env.removePlayer((*ip)->peer_id);
}
}
else if(command == TOCLIENT_SECTORMETA)
{
- dstream<<"Client received DEPRECATED TOCLIENT_SECTORMETA"<<std::endl;
+ infostream<<"Client received DEPRECATED TOCLIENT_SECTORMETA"<<std::endl;
#if 0
/*
[0] u16 command
if(datasize < 3)
return;
- //dstream<<"Client received TOCLIENT_SECTORMETA"<<std::endl;
+ //infostream<<"Client received TOCLIENT_SECTORMETA"<<std::endl;
{ //envlock
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
is.read((char*)buf, 1);
u16 sector_count = readU8(buf);
- //dstream<<"sector_count="<<sector_count<<std::endl;
+ //infostream<<"sector_count="<<sector_count<<std::endl;
for(u16 i=0; i<sector_count; i++)
{
// Read position
is.read((char*)buf, 4);
v2s16 pos = readV2S16(buf);
- /*dstream<<"Client: deserializing sector at "
+ /*infostream<<"Client: deserializing sector at "
<<"("<<pos.X<<","<<pos.Y<<")"<<std::endl;*/
// Create sector
assert(m_env.getMap().mapType() == MAPTYPE_CLIENT);
std::istringstream is(datastring, std::ios_base::binary);
//t3.stop();
- //m_env.printPlayers(dstream);
+ //m_env.printPlayers(infostream);
//TimeTaker t4("player get", m_device);
Player *player = m_env.getLocalPlayer();
m_inventory_updated = true;
- //dstream<<"Client got player inventory:"<<std::endl;
- //player->inventory.print(dstream);
+ //infostream<<"Client got player inventory:"<<std::endl;
+ //player->inventory.print(infostream);
}
}
//DEBUG
else if(command == TOCLIENT_OBJECTDATA)
- //else if(0)
{
// Strip command word and create a stringstream
std::string datastring((char*)&data[2], datasize-2);
std::istringstream is(datastring, std::ios_base::binary);
- { //envlock
-
- //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
-
u8 buf[12];
/*
/*
Read block objects
- NOTE: Deprecated stuff here, TODO: Remove
+ NOTE: Deprecated stuff
*/
// Read active block count
- is.read((char*)buf, 2);
- u16 blockcount = readU16(buf);
-
- // Initialize delete queue with all active blocks
- core::map<v3s16, bool> abs_to_delete;
- for(core::map<v3s16, bool>::Iterator
- i = m_active_blocks.getIterator();
- i.atEnd() == false; i++)
- {
- v3s16 p = i.getNode()->getKey();
- /*dstream<<"adding "
- <<"("<<p.x<<","<<p.y<<","<<p.z<<") "
- <<" to abs_to_delete"
- <<std::endl;*/
- abs_to_delete.insert(p, true);
- }
-
- /*dstream<<"Initial delete queue size: "<<abs_to_delete.size()
- <<std::endl;*/
-
- for(u16 i=0; i<blockcount; i++)
- {
- // Read blockpos
- is.read((char*)buf, 6);
- v3s16 p = readV3S16(buf);
- // Get block from somewhere
- MapBlock *block = NULL;
- try{
- block = m_env.getMap().getBlockNoCreate(p);
- }
- catch(InvalidPositionException &e)
- {
- //TODO: Create a dummy block?
- }
- if(block == NULL)
- {
- dstream<<"WARNING: "
- <<"Could not get block at blockpos "
- <<"("<<p.X<<","<<p.Y<<","<<p.Z<<") "
- <<"in TOCLIENT_OBJECTDATA. Ignoring "
- <<"following block object data."
- <<std::endl;
- return;
- }
-
- /*dstream<<"Client updating objects for block "
- <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
- <<std::endl;*/
-
- // Insert to active block list
- m_active_blocks.insert(p, true);
-
- // Remove from deletion queue
- if(abs_to_delete.find(p) != NULL)
- abs_to_delete.remove(p);
-
- /*
- Update objects of block
-
- NOTE: Be sure this is done in the main thread.
- */
- block->updateObjects(is, m_server_ser_ver,
- m_device->getSceneManager(), m_env.getDayNightRatio());
- }
-
- /*dstream<<"Final delete queue size: "<<abs_to_delete.size()
- <<std::endl;*/
-
- // Delete objects of blocks in delete queue
- for(core::map<v3s16, bool>::Iterator
- i = abs_to_delete.getIterator();
- i.atEnd() == false; i++)
- {
- v3s16 p = i.getNode()->getKey();
- try
- {
- MapBlock *block = m_env.getMap().getBlockNoCreate(p);
-
- // Clear objects
- block->clearObjects();
- // Remove from active blocks list
- m_active_blocks.remove(p);
- }
- catch(InvalidPositionException &e)
- {
- dstream<<"WARNAING: Client: "
- <<"Couldn't clear objects of active->inactive"
- <<" block "
- <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
- <<" because block was not found"
- <<std::endl;
- // Ignore
- }
+ u16 blockcount = readU16(is);
+ if(blockcount != 0){
+ infostream<<"TOCLIENT_OBJECTDATA: blockcount != 0 "
+ "not supported"<<std::endl;
+ return;
}
-
- } //envlock
}
else if(command == TOCLIENT_TIME_OF_DAY)
{
u16 time_of_day = readU16(&data[2]);
time_of_day = time_of_day % 24000;
- //dstream<<"Client: time_of_day="<<time_of_day<<std::endl;
+ //infostream<<"Client: time_of_day="<<time_of_day<<std::endl;
/*
time_of_day:
u32 dr = m_env.getDayNightRatio();
- dstream<<"Client: time_of_day="<<time_of_day
+ infostream<<"Client: time_of_day="<<time_of_day
<<", dr="<<dr
<<std::endl;
}
message += (wchar_t)readU16(buf);
}
- /*dstream<<"Client received chat message: "
+ /*infostream<<"Client received chat message: "
<<wide_to_narrow(message)<<std::endl;*/
m_chat_queue.push_back(message);
}
else if(command == TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD)
{
- //if(g_settings.getBool("enable_experimental"))
+ //if(g_settings->getBool("enable_experimental"))
{
/*
u16 command
for all added objects {
u16 id
u8 type
- u16 initialization data length
+ u32 initialization data length
string initialization data
}
*/
}
else if(command == TOCLIENT_ACTIVE_OBJECT_MESSAGES)
{
- //if(g_settings.getBool("enable_experimental"))
+ //if(g_settings->getBool("enable_experimental"))
{
/*
u16 command
/*player->setPitch(pitch);
player->setYaw(yaw);*/
- dstream<<"Client got TOCLIENT_MOVE_PLAYER"
+ infostream<<"Client got TOCLIENT_MOVE_PLAYER"
<<" pos=("<<pos.X<<","<<pos.Y<<","<<pos.Z<<")"
<<" pitch="<<pitch
<<" yaw="<<yaw
// get damage from falling on ground
m_ignore_damage_timer = 3.0;
}
+ else if(command == TOCLIENT_PLAYERITEM)
+ {
+ std::string datastring((char*)&data[2], datasize-2);
+ std::istringstream is(datastring, std::ios_base::binary);
+
+ u16 count = readU16(is);
+
+ for (u16 i = 0; i < count; ++i) {
+ u16 peer_id = readU16(is);
+ Player *player = m_env.getPlayer(peer_id);
+
+ if (player == NULL)
+ {
+ infostream<<"Client: ignoring player item "
+ << deSerializeString(is)
+ << " for non-existing peer id " << peer_id
+ << std::endl;
+ continue;
+ } else if (player->isLocal()) {
+ infostream<<"Client: ignoring player item "
+ << deSerializeString(is)
+ << " for local player" << std::endl;
+ continue;
+ } else {
+ InventoryList *inv = player->inventory.getList("main");
+ std::string itemstring(deSerializeString(is));
+ if (itemstring.empty()) {
+ inv->deleteItem(0);
+ infostream
+ <<"Client: empty player item for peer "
+ << peer_id << std::endl;
+ } else {
+ std::istringstream iss(itemstring);
+ delete inv->changeItem(0, InventoryItem::deSerialize(iss));
+ infostream<<"Client: player item for peer " << peer_id << ": ";
+ player->getWieldItem()->serialize(infostream);
+ infostream<<std::endl;
+ }
+ }
+ }
+ }
+ else if(command == TOCLIENT_DEATHSCREEN)
+ {
+ std::string datastring((char*)&data[2], datasize-2);
+ std::istringstream is(datastring, std::ios_base::binary);
+
+ bool set_camera_point_target = readU8(is);
+ v3f camera_point_target = readV3F1000(is);
+
+ ClientEvent event;
+ event.type = CE_DEATHSCREEN;
+ event.deathscreen.set_camera_point_target = set_camera_point_target;
+ event.deathscreen.camera_point_target_x = camera_point_target.X;
+ event.deathscreen.camera_point_target_y = camera_point_target.Y;
+ event.deathscreen.camera_point_target_z = camera_point_target.Z;
+ m_client_event_queue.push_back(event);
+ }
else
{
- dout_client<<DTIME<<"WARNING: Client: Ignoring unknown command "
+ infostream<<"Client: Ignoring unknown command "
<<command<<std::endl;
}
}
v3s16 nodepos_oversurface, u16 item)
{
if(connectedAndInitialized() == false){
- dout_client<<DTIME<<"Client::groundAction() "
+ infostream<<"Client::groundAction() "
"cancelled (not connected)"
<<std::endl;
return;
Send(0, data, true);
}
-void Client::clickObject(u8 button, v3s16 blockpos, s16 id, u16 item)
+void Client::clickActiveObject(u8 button, u16 id, u16 item_i)
{
if(connectedAndInitialized() == false){
- dout_client<<DTIME<<"Client::clickObject() "
+ infostream<<"Client::clickActiveObject() "
"cancelled (not connected)"
<<std::endl;
return;
}
-
- /*
- [0] u16 command=TOSERVER_CLICK_OBJECT
- [2] u8 button (0=left, 1=right)
- [3] v3s16 block
- [9] s16 id
- [11] u16 item
- */
- u8 datasize = 2 + 1 + 6 + 2 + 2;
- SharedBuffer<u8> data(datasize);
- writeU16(&data[0], TOSERVER_CLICK_OBJECT);
- writeU8(&data[2], button);
- writeV3S16(&data[3], blockpos);
- writeS16(&data[9], id);
- writeU16(&data[11], item);
- Send(0, data, true);
-}
-void Client::clickActiveObject(u8 button, u16 id, u16 item)
-{
- if(connectedAndInitialized() == false){
- dout_client<<DTIME<<"Client::clickActiveObject() "
- "cancelled (not connected)"
- <<std::endl;
+ Player *player = m_env.getLocalPlayer();
+ if(player == NULL)
return;
+
+ ClientActiveObject *obj = m_env.getActiveObject(id);
+ if(obj){
+ if(button == 0){
+ ToolItem *titem = NULL;
+ std::string toolname = "";
+
+ InventoryList *mlist = player->inventory.getList("main");
+ if(mlist != NULL)
+ {
+ InventoryItem *item = mlist->getItem(item_i);
+ if(item && (std::string)item->getName() == "ToolItem")
+ {
+ titem = (ToolItem*)item;
+ toolname = titem->getToolName();
+ }
+ }
+
+ v3f playerpos = player->getPosition();
+ v3f objpos = obj->getPosition();
+ v3f dir = (objpos - playerpos).normalize();
+
+ bool disable_send = obj->directReportPunch(toolname, dir);
+
+ if(disable_send)
+ return;
+ }
}
/*
writeU16(&data[0], TOSERVER_CLICK_ACTIVEOBJECT);
writeU8(&data[2], button);
writeU16(&data[3], id);
- writeU16(&data[5], item);
+ writeU16(&data[5], item_i);
Send(0, data, true);
}
-void Client::sendSignText(v3s16 blockpos, s16 id, std::string text)
-{
- /*
- u16 command
- v3s16 blockpos
- s16 id
- u16 textlen
- textdata
- */
- std::ostringstream os(std::ios_base::binary);
- u8 buf[12];
-
- // Write command
- writeU16(buf, TOSERVER_SIGNTEXT);
- os.write((char*)buf, 2);
-
- // Write blockpos
- writeV3S16(buf, blockpos);
- os.write((char*)buf, 6);
-
- // Write id
- writeS16(buf, id);
- os.write((char*)buf, 2);
-
- u16 textlen = text.size();
- // Write text length
- writeS16(buf, textlen);
- os.write((char*)buf, 2);
-
- // Write text
- os.write((char*)text.c_str(), textlen);
-
- // Make data buffer
- std::string s = os.str();
- SharedBuffer<u8> data((u8*)s.c_str(), s.size());
- // Send as reliable
- Send(0, data, true);
-}
-
void Client::sendSignNodeText(v3s16 p, std::string text)
{
/*
Send(0, data, true);
}
+void Client::sendRespawn()
+{
+ DSTACK(__FUNCTION_NAME);
+ std::ostringstream os(std::ios_base::binary);
+
+ writeU16(os, TOSERVER_RESPAWN);
+
+ // Make data buffer
+ std::string s = os.str();
+ SharedBuffer<u8> data((u8*)s.c_str(), s.size());
+ // Send as reliable
+ Send(0, data, true);
+}
+
void Client::sendPlayerPos()
{
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
Send(0, data, false);
}
+void Client::sendPlayerItem(u16 item)
+{
+ Player *myplayer = m_env.getLocalPlayer();
+ if(myplayer == NULL)
+ return;
+
+ u16 our_peer_id = m_con.GetPeerID();
+
+ // Set peer id if not set already
+ if(myplayer->peer_id == PEER_ID_INEXISTENT)
+ myplayer->peer_id = our_peer_id;
+ // Check that an existing peer_id is the same as the connection's
+ assert(myplayer->peer_id == our_peer_id);
+
+ SharedBuffer<u8> data(2+2);
+ writeU16(&data[0], TOSERVER_PLAYERITEM);
+ writeU16(&data[2], item);
+
+ // Send as reliable
+ Send(0, data, true);
+}
+
void Client::removeNode(v3s16 p)
{
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
try
{
//TimeTaker timer3("Client::addNode(): addNodeAndUpdate");
- m_env.getMap().addNodeAndUpdate(p, n, modified_blocks);
+ std::string st = std::string("");
+ m_env.getMap().addNodeAndUpdate(p, n, modified_blocks, st);
}
catch(InvalidPositionException &e)
{}
}
}
-void Client::updateCamera(v3f pos, v3f dir)
+void Client::updateCamera(v3f pos, v3f dir, f32 fov)
{
- m_env.getClientMap().updateCamera(pos, dir);
- camera_position = pos;
- camera_direction = dir;
+ m_env.getClientMap().updateCamera(pos, dir, fov);
+}
+
+void Client::renderPostFx()
+{
+ m_env.getClientMap().renderPostFx();
}
MapNode Client::getNode(v3s16 p)
return m_env.getMap().getNodeMetadata(p);
}
-v3f Client::getPlayerPosition()
+LocalPlayer* Client::getLocalPlayer()
{
- //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
- LocalPlayer *player = m_env.getLocalPlayer();
- assert(player != NULL);
- return player->getPosition();
+ return m_env.getLocalPlayer();
}
void Client::setPlayerControl(PlayerControl &control)
player->control = control;
}
+void Client::selectPlayerItem(u16 item)
+{
+ LocalPlayer *player = m_env.getLocalPlayer();
+ assert(player != NULL);
+
+ player->wieldItem(item);
+
+ sendPlayerItem(item);
+}
+
// Returns true if the inventory of the local player has been
// updated from the server. If it is true, it is set to false.
bool Client::getLocalInventoryUpdated()
NodeMetadata* meta = getNodeMetadata(p);
if(meta)
return meta->getInventory();
- dstream<<"nodemeta at ("<<p.X<<","<<p.Y<<","<<p.Z<<"): "
+ infostream<<"nodemeta at ("<<p.X<<","<<p.Y<<","<<p.Z<<"): "
<<"no metadata found"<<std::endl;
return NULL;
}
- dstream<<__FUNCTION_NAME<<": unknown id "<<id<<std::endl;
+ infostream<<__FUNCTION_NAME<<": unknown id "<<id<<std::endl;
return NULL;
}
void Client::inventoryAction(InventoryAction *a)
sendInventoryAction(a);
}
-MapBlockObject * Client::getSelectedObject(
- f32 max_d,
- v3f from_pos_f_on_map,
- core::line3d<f32> shootline_on_map
- )
-{
- //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
-
- core::array<DistanceSortedObject> objects;
-
- for(core::map<v3s16, bool>::Iterator
- i = m_active_blocks.getIterator();
- i.atEnd() == false; i++)
- {
- v3s16 p = i.getNode()->getKey();
-
- MapBlock *block = NULL;
- try
- {
- block = m_env.getMap().getBlockNoCreate(p);
- }
- catch(InvalidPositionException &e)
- {
- continue;
- }
-
- // Calculate from_pos relative to block
- v3s16 block_pos_i_on_map = block->getPosRelative();
- v3f block_pos_f_on_map = intToFloat(block_pos_i_on_map, BS);
- v3f from_pos_f_on_block = from_pos_f_on_map - block_pos_f_on_map;
-
- block->getObjects(from_pos_f_on_block, max_d, objects);
- //block->getPseudoObjects(from_pos_f_on_block, max_d, objects);
- }
-
- //dstream<<"Collected "<<objects.size()<<" nearby objects"<<std::endl;
-
- // Sort them.
- // After this, the closest object is the first in the array.
- objects.sort();
-
- for(u32 i=0; i<objects.size(); i++)
- {
- MapBlockObject *obj = objects[i].obj;
- MapBlock *block = obj->getBlock();
-
- // Calculate shootline relative to block
- v3s16 block_pos_i_on_map = block->getPosRelative();
- v3f block_pos_f_on_map = intToFloat(block_pos_i_on_map, BS);
- core::line3d<f32> shootline_on_block(
- shootline_on_map.start - block_pos_f_on_map,
- shootline_on_map.end - block_pos_f_on_map
- );
-
- if(obj->isSelected(shootline_on_block))
- {
- //dstream<<"Returning selected object"<<std::endl;
- return obj;
- }
- }
-
- //dstream<<"No object selected; returning NULL."<<std::endl;
- return NULL;
-}
-
ClientActiveObject * Client::getSelectedActiveObject(
f32 max_d,
v3f from_pos_f_on_map,
m_env.getActiveObjects(from_pos_f_on_map, max_d, objects);
- //dstream<<"Collected "<<objects.size()<<" nearby objects"<<std::endl;
+ //infostream<<"Collected "<<objects.size()<<" nearby objects"<<std::endl;
// Sort them.
// After this, the closest object is the first in the array.
if(offsetted_box.intersectsWithLine(shootline_on_map))
{
- //dstream<<"Returning selected object"<<std::endl;
+ //infostream<<"Returning selected object"<<std::endl;
return obj;
}
}
- //dstream<<"No object selected; returning NULL."<<std::endl;
+ //infostream<<"No object selected; returning NULL."<<std::endl;
return NULL;
}
void Client::addUpdateMeshTask(v3s16 p, bool ack_to_server)
{
- /*dstream<<"Client::addUpdateMeshTask(): "
+ /*infostream<<"Client::addUpdateMeshTask(): "
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
<<std::endl;*/
// Add task to queue
m_mesh_update_thread.m_queue_in.addBlock(p, data, ack_to_server);
- /*dstream<<"Mesh update input queue size is "
+ /*infostream<<"Mesh update input queue size is "
<<m_mesh_update_thread.m_queue_in.size()
<<std::endl;*/
{
/*{
v3s16 p = blockpos;
- dstream<<"Client::addUpdateMeshTaskWithEdge(): "
+ infostream<<"Client::addUpdateMeshTaskWithEdge(): "
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
<<std::endl;
}*/
return m_client_event_queue.pop_front();
}
+float Client::getRTT(void)
+{
+ con::Peer *peer = m_con.GetPeerNoEx(PEER_ID_SERVER);
+ if(!peer)
+ return 0.0;
+ return peer->avg_rtt;
+}