Improve loading screen and protocol
parent
cde35d1606
commit
7696a38543
|
@ -211,7 +211,11 @@ Client::Client(
|
||||||
m_time_of_day(0),
|
m_time_of_day(0),
|
||||||
m_map_seed(0),
|
m_map_seed(0),
|
||||||
m_password(password),
|
m_password(password),
|
||||||
m_access_denied(false)
|
m_access_denied(false),
|
||||||
|
m_texture_receive_progress(0),
|
||||||
|
m_textures_received(false),
|
||||||
|
m_tooldef_received(false),
|
||||||
|
m_nodedef_received(false)
|
||||||
{
|
{
|
||||||
m_packetcounter_timer = 0.0;
|
m_packetcounter_timer = 0.0;
|
||||||
//m_delete_unused_sectors_timer = 0.0;
|
//m_delete_unused_sectors_timer = 0.0;
|
||||||
|
@ -661,8 +665,14 @@ void Client::deletingPeer(con::Peer *peer, bool timeout)
|
||||||
void Client::ReceiveAll()
|
void Client::ReceiveAll()
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
u32 start_ms = porting::getTimeMs();
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
|
// Limit time even if there would be huge amounts of data to
|
||||||
|
// process
|
||||||
|
if(porting::getTimeMs() > start_ms + 100)
|
||||||
|
break;
|
||||||
|
|
||||||
try{
|
try{
|
||||||
Receive();
|
Receive();
|
||||||
}
|
}
|
||||||
|
@ -1505,24 +1515,6 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
event.deathscreen.camera_point_target_z = camera_point_target.Z;
|
event.deathscreen.camera_point_target_z = camera_point_target.Z;
|
||||||
m_client_event_queue.push_back(event);
|
m_client_event_queue.push_back(event);
|
||||||
}
|
}
|
||||||
else if(command == TOCLIENT_TOOLDEF)
|
|
||||||
{
|
|
||||||
infostream<<"Client: Received tool definitions: packet size: "
|
|
||||||
<<datasize<<std::endl;
|
|
||||||
|
|
||||||
std::string datastring((char*)&data[2], datasize-2);
|
|
||||||
std::istringstream is(datastring, std::ios_base::binary);
|
|
||||||
|
|
||||||
// Stop threads while updating content definitions
|
|
||||||
m_mesh_update_thread.stop();
|
|
||||||
|
|
||||||
std::istringstream tmp_is(deSerializeLongString(is), std::ios::binary);
|
|
||||||
m_tooldef->deSerialize(tmp_is);
|
|
||||||
|
|
||||||
// Resume threads
|
|
||||||
m_mesh_update_thread.setRun(true);
|
|
||||||
m_mesh_update_thread.Start();
|
|
||||||
}
|
|
||||||
else if(command == TOCLIENT_TEXTURES)
|
else if(command == TOCLIENT_TEXTURES)
|
||||||
{
|
{
|
||||||
infostream<<"Client: Received textures: packet size: "<<datasize
|
infostream<<"Client: Received textures: packet size: "<<datasize
|
||||||
|
@ -1539,7 +1531,9 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
u16 command
|
u16 command
|
||||||
u32 number of textures
|
u16 total number of texture bunches
|
||||||
|
u16 index of this bunch
|
||||||
|
u32 number of textures in this bunch
|
||||||
for each texture {
|
for each texture {
|
||||||
u16 length of name
|
u16 length of name
|
||||||
string name
|
string name
|
||||||
|
@ -1547,6 +1541,11 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
int num_bunches = readU16(is);
|
||||||
|
int bunch_i = readU16(is);
|
||||||
|
m_texture_receive_progress = (float)bunch_i / (float)(num_bunches - 1);
|
||||||
|
if(bunch_i == num_bunches - 1)
|
||||||
|
m_textures_received = true;
|
||||||
int num_textures = readU32(is);
|
int num_textures = readU32(is);
|
||||||
infostream<<"Client: Received textures: count: "<<num_textures
|
infostream<<"Client: Received textures: count: "<<num_textures
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
|
@ -1572,15 +1571,17 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
rfile->drop();
|
rfile->drop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rebuild inherited images and recreate textures
|
if(m_nodedef_received && m_textures_received){
|
||||||
m_tsrc->rebuildImagesAndTextures();
|
// Rebuild inherited images and recreate textures
|
||||||
|
m_tsrc->rebuildImagesAndTextures();
|
||||||
|
|
||||||
// Update texture atlas
|
// Update texture atlas
|
||||||
if(g_settings->getBool("enable_texture_atlas"))
|
if(g_settings->getBool("enable_texture_atlas"))
|
||||||
m_tsrc->buildMainAtlas(this);
|
m_tsrc->buildMainAtlas(this);
|
||||||
|
|
||||||
// Update node textures
|
// Update node textures
|
||||||
m_nodedef->updateTextures(m_tsrc);
|
m_nodedef->updateTextures(m_tsrc);
|
||||||
|
}
|
||||||
|
|
||||||
// Resume threads
|
// Resume threads
|
||||||
m_mesh_update_thread.setRun(true);
|
m_mesh_update_thread.setRun(true);
|
||||||
|
@ -1590,6 +1591,26 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
event.type = CE_TEXTURES_UPDATED;
|
event.type = CE_TEXTURES_UPDATED;
|
||||||
m_client_event_queue.push_back(event);
|
m_client_event_queue.push_back(event);
|
||||||
}
|
}
|
||||||
|
else if(command == TOCLIENT_TOOLDEF)
|
||||||
|
{
|
||||||
|
infostream<<"Client: Received tool definitions: packet size: "
|
||||||
|
<<datasize<<std::endl;
|
||||||
|
|
||||||
|
std::string datastring((char*)&data[2], datasize-2);
|
||||||
|
std::istringstream is(datastring, std::ios_base::binary);
|
||||||
|
|
||||||
|
m_tooldef_received = true;
|
||||||
|
|
||||||
|
// Stop threads while updating content definitions
|
||||||
|
m_mesh_update_thread.stop();
|
||||||
|
|
||||||
|
std::istringstream tmp_is(deSerializeLongString(is), std::ios::binary);
|
||||||
|
m_tooldef->deSerialize(tmp_is);
|
||||||
|
|
||||||
|
// Resume threads
|
||||||
|
m_mesh_update_thread.setRun(true);
|
||||||
|
m_mesh_update_thread.Start();
|
||||||
|
}
|
||||||
else if(command == TOCLIENT_NODEDEF)
|
else if(command == TOCLIENT_NODEDEF)
|
||||||
{
|
{
|
||||||
infostream<<"Client: Received node definitions: packet size: "
|
infostream<<"Client: Received node definitions: packet size: "
|
||||||
|
@ -1598,18 +1619,22 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
std::string datastring((char*)&data[2], datasize-2);
|
std::string datastring((char*)&data[2], datasize-2);
|
||||||
std::istringstream is(datastring, std::ios_base::binary);
|
std::istringstream is(datastring, std::ios_base::binary);
|
||||||
|
|
||||||
|
m_nodedef_received = true;
|
||||||
|
|
||||||
// Stop threads while updating content definitions
|
// Stop threads while updating content definitions
|
||||||
m_mesh_update_thread.stop();
|
m_mesh_update_thread.stop();
|
||||||
|
|
||||||
std::istringstream tmp_is(deSerializeLongString(is), std::ios::binary);
|
std::istringstream tmp_is(deSerializeLongString(is), std::ios::binary);
|
||||||
m_nodedef->deSerialize(tmp_is, this);
|
m_nodedef->deSerialize(tmp_is, this);
|
||||||
|
|
||||||
// Update texture atlas
|
if(m_textures_received){
|
||||||
if(g_settings->getBool("enable_texture_atlas"))
|
// Update texture atlas
|
||||||
m_tsrc->buildMainAtlas(this);
|
if(g_settings->getBool("enable_texture_atlas"))
|
||||||
|
m_tsrc->buildMainAtlas(this);
|
||||||
// Update node textures
|
|
||||||
m_nodedef->updateTextures(m_tsrc);
|
// Update node textures
|
||||||
|
m_nodedef->updateTextures(m_tsrc);
|
||||||
|
}
|
||||||
|
|
||||||
// Resume threads
|
// Resume threads
|
||||||
m_mesh_update_thread.setRun(true);
|
m_mesh_update_thread.setRun(true);
|
||||||
|
|
18
src/client.h
18
src/client.h
|
@ -305,11 +305,21 @@ public:
|
||||||
// Get event from queue. CE_NONE is returned if queue is empty.
|
// Get event from queue. CE_NONE is returned if queue is empty.
|
||||||
ClientEvent getClientEvent();
|
ClientEvent getClientEvent();
|
||||||
|
|
||||||
inline bool accessDenied()
|
bool accessDenied()
|
||||||
{ return m_access_denied; }
|
{ return m_access_denied; }
|
||||||
|
|
||||||
inline std::wstring accessDeniedReason()
|
std::wstring accessDeniedReason()
|
||||||
{ return m_access_denied_reason; }
|
{ return m_access_denied_reason; }
|
||||||
|
|
||||||
|
float textureReceiveProgress()
|
||||||
|
{ return m_texture_receive_progress; }
|
||||||
|
|
||||||
|
bool texturesReceived()
|
||||||
|
{ return m_textures_received; }
|
||||||
|
bool tooldefReceived()
|
||||||
|
{ return m_tooldef_received; }
|
||||||
|
bool nodedefReceived()
|
||||||
|
{ return m_nodedef_received; }
|
||||||
|
|
||||||
float getRTT(void);
|
float getRTT(void);
|
||||||
|
|
||||||
|
@ -367,6 +377,10 @@ private:
|
||||||
std::wstring m_access_denied_reason;
|
std::wstring m_access_denied_reason;
|
||||||
InventoryContext m_inventory_context;
|
InventoryContext m_inventory_context;
|
||||||
Queue<ClientEvent> m_client_event_queue;
|
Queue<ClientEvent> m_client_event_queue;
|
||||||
|
float m_texture_receive_progress;
|
||||||
|
bool m_textures_received;
|
||||||
|
bool m_tooldef_received;
|
||||||
|
bool m_nodedef_received;
|
||||||
friend class FarMesh;
|
friend class FarMesh;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
PROTOCOL_VERSION 3:
|
PROTOCOL_VERSION 3:
|
||||||
Base for writing changes here
|
Base for writing changes here
|
||||||
PROTOCOL_VERSION 4:
|
PROTOCOL_VERSION 4:
|
||||||
Add TOCLIENT_TOOLDEF
|
|
||||||
Add TOCLIENT_TEXTURES
|
Add TOCLIENT_TEXTURES
|
||||||
|
Add TOCLIENT_TOOLDEF
|
||||||
Add TOCLIENT_NODEDEF
|
Add TOCLIENT_NODEDEF
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -195,17 +195,12 @@ enum ToClientCommand
|
||||||
v3f1000 camera point target (to point the death cause or whatever)
|
v3f1000 camera point target (to point the death cause or whatever)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TOCLIENT_TOOLDEF = 0x38,
|
TOCLIENT_TEXTURES = 0x38,
|
||||||
/*
|
/*
|
||||||
u16 command
|
u16 command
|
||||||
u32 length of the next item
|
u16 total number of texture bunches
|
||||||
serialized ToolDefManager
|
u16 index of this bunch
|
||||||
*/
|
u32 number of textures in this bunch
|
||||||
|
|
||||||
TOCLIENT_TEXTURES = 0x39,
|
|
||||||
/*
|
|
||||||
u16 command
|
|
||||||
u32 number of textures
|
|
||||||
for each texture {
|
for each texture {
|
||||||
u16 length of name
|
u16 length of name
|
||||||
string name
|
string name
|
||||||
|
@ -214,18 +209,19 @@ enum ToClientCommand
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
TOCLIENT_TOOLDEF = 0x39,
|
||||||
|
/*
|
||||||
|
u16 command
|
||||||
|
u32 length of the next item
|
||||||
|
serialized ToolDefManager
|
||||||
|
*/
|
||||||
|
|
||||||
TOCLIENT_NODEDEF = 0x3a,
|
TOCLIENT_NODEDEF = 0x3a,
|
||||||
/*
|
/*
|
||||||
u16 command
|
u16 command
|
||||||
u32 length of the next item
|
u32 length of the next item
|
||||||
serialized NodeDefManager
|
serialized NodeDefManager
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//TOCLIENT_CONTENT_SENDING_MODE = 0x38,
|
|
||||||
/*
|
|
||||||
u16 command
|
|
||||||
u8 mode (0 = off, 1 = on)
|
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ToServerCommand
|
enum ToServerCommand
|
||||||
|
|
110
src/game.cpp
110
src/game.cpp
|
@ -632,21 +632,18 @@ void the_game(
|
||||||
/*
|
/*
|
||||||
Draw "Loading" screen
|
Draw "Loading" screen
|
||||||
*/
|
*/
|
||||||
/*gui::IGUIStaticText *gui_loadingtext = */
|
|
||||||
//draw_load_screen(L"Loading and connecting...", driver, font);
|
|
||||||
|
|
||||||
draw_load_screen(L"Loading...", driver, font);
|
draw_load_screen(L"Loading...", driver, font);
|
||||||
|
|
||||||
// Create tool definition manager
|
|
||||||
IWritableToolDefManager *tooldef = createToolDefManager();
|
|
||||||
// Create texture source
|
// Create texture source
|
||||||
IWritableTextureSource *tsrc = createTextureSource(device);
|
IWritableTextureSource *tsrc = createTextureSource(device);
|
||||||
|
|
||||||
|
// These will be filled by data received from the server
|
||||||
|
// Create tool definition manager
|
||||||
|
IWritableToolDefManager *tooldef = createToolDefManager();
|
||||||
// Create node definition manager
|
// Create node definition manager
|
||||||
IWritableNodeDefManager *nodedef = createNodeDefManager();
|
IWritableNodeDefManager *nodedef = createNodeDefManager();
|
||||||
|
|
||||||
// Fill node feature table with default definitions
|
|
||||||
//content_mapnode_init(nodedef);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create server.
|
Create server.
|
||||||
SharedPtr will delete it when it goes out of scope.
|
SharedPtr will delete it when it goes out of scope.
|
||||||
|
@ -702,54 +699,51 @@ void the_game(
|
||||||
connect_address.print(&infostream);
|
connect_address.print(&infostream);
|
||||||
infostream<<std::endl;
|
infostream<<std::endl;
|
||||||
client.connect(connect_address);
|
client.connect(connect_address);
|
||||||
|
|
||||||
bool could_connect = false;
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Wait for server to accept connection
|
||||||
|
*/
|
||||||
|
bool could_connect = false;
|
||||||
try{
|
try{
|
||||||
|
float frametime = 0.033;
|
||||||
|
const float timeout = 10.0;
|
||||||
float time_counter = 0.0;
|
float time_counter = 0.0;
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
if(client.connectedAndInitialized())
|
// Update client and server
|
||||||
{
|
client.step(frametime);
|
||||||
|
if(server != NULL)
|
||||||
|
server->step(frametime);
|
||||||
|
|
||||||
|
// End condition
|
||||||
|
if(client.connectedAndInitialized()){
|
||||||
could_connect = true;
|
could_connect = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Break conditions
|
||||||
if(client.accessDenied())
|
if(client.accessDenied())
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
if(time_counter >= timeout)
|
||||||
// Wait for 10 seconds
|
|
||||||
if(time_counter >= 10.0)
|
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
|
// Display status
|
||||||
std::wostringstream ss;
|
std::wostringstream ss;
|
||||||
ss<<L"Connecting to server... (timeout in ";
|
ss<<L"Connecting to server... (timeout in ";
|
||||||
ss<<(int)(10.0 - time_counter + 1.0);
|
ss<<(int)(timeout - time_counter + 1.0);
|
||||||
ss<<L" seconds)";
|
ss<<L" seconds)";
|
||||||
draw_load_screen(ss.str(), driver, font);
|
draw_load_screen(ss.str(), driver, font);
|
||||||
|
|
||||||
/*// Update screen
|
|
||||||
driver->beginScene(true, true, video::SColor(255,0,0,0));
|
|
||||||
guienv->drawAll();
|
|
||||||
driver->endScene();*/
|
|
||||||
|
|
||||||
// Update client and server
|
|
||||||
|
|
||||||
client.step(0.1);
|
|
||||||
|
|
||||||
if(server != NULL)
|
|
||||||
server->step(0.1);
|
|
||||||
|
|
||||||
// Delay a bit
|
// Delay a bit
|
||||||
sleep_ms(100);
|
sleep_ms(1000*frametime);
|
||||||
time_counter += 0.1;
|
time_counter += frametime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(con::PeerNotFoundException &e)
|
catch(con::PeerNotFoundException &e)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Handle failure to connect
|
||||||
|
*/
|
||||||
if(could_connect == false)
|
if(could_connect == false)
|
||||||
{
|
{
|
||||||
if(client.accessDenied())
|
if(client.accessDenied())
|
||||||
|
@ -766,6 +760,56 @@ void the_game(
|
||||||
//gui_loadingtext->remove();
|
//gui_loadingtext->remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Wait until content has been received
|
||||||
|
*/
|
||||||
|
bool got_content = false;
|
||||||
|
{
|
||||||
|
float frametime = 0.033;
|
||||||
|
const float timeout = 5.0;
|
||||||
|
float time_counter = 0.0;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
// Update client and server
|
||||||
|
client.step(frametime);
|
||||||
|
if(server != NULL)
|
||||||
|
server->step(frametime);
|
||||||
|
|
||||||
|
// End condition
|
||||||
|
if(client.texturesReceived() &&
|
||||||
|
client.tooldefReceived() &&
|
||||||
|
client.nodedefReceived()){
|
||||||
|
got_content = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Break conditions
|
||||||
|
if(!client.connectedAndInitialized())
|
||||||
|
break;
|
||||||
|
if(time_counter >= timeout)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Display status
|
||||||
|
std::wostringstream ss;
|
||||||
|
ss<<L"Waiting content... (continuing anyway in ";
|
||||||
|
ss<<(int)(timeout - time_counter + 1.0);
|
||||||
|
ss<<L" seconds)\n";
|
||||||
|
|
||||||
|
ss<<(client.tooldefReceived()?L"[X]":L"[ ]");
|
||||||
|
ss<<L" Tool definitions\n";
|
||||||
|
ss<<(client.nodedefReceived()?L"[X]":L"[ ]");
|
||||||
|
ss<<L" Node definitions\n";
|
||||||
|
//ss<<(client.texturesReceived()?L"[X]":L"[ ]");
|
||||||
|
ss<<L"["<<(int)(client.textureReceiveProgress()*100+0.5)<<L"%] ";
|
||||||
|
ss<<L" Textures\n";
|
||||||
|
|
||||||
|
draw_load_screen(ss.str(), driver, font);
|
||||||
|
|
||||||
|
// Delay a bit
|
||||||
|
sleep_ms(1000*frametime);
|
||||||
|
time_counter += frametime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create skybox
|
Create skybox
|
||||||
|
|
|
@ -2139,15 +2139,15 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
Send some initialization data
|
Send some initialization data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Send textures
|
|
||||||
SendTextures(peer_id);
|
|
||||||
|
|
||||||
// Send tool definitions
|
// Send tool definitions
|
||||||
SendToolDef(m_con, peer_id, m_toolmgr);
|
SendToolDef(m_con, peer_id, m_toolmgr);
|
||||||
|
|
||||||
// Send node definitions
|
// Send node definitions
|
||||||
SendNodeDef(m_con, peer_id, m_nodemgr);
|
SendNodeDef(m_con, peer_id, m_nodemgr);
|
||||||
|
|
||||||
|
// Send textures
|
||||||
|
SendTextures(peer_id);
|
||||||
|
|
||||||
// Send player info to all players
|
// Send player info to all players
|
||||||
SendPlayerInfos();
|
SendPlayerInfos();
|
||||||
|
|
||||||
|
@ -4160,7 +4160,13 @@ void Server::SendTextures(u16 peer_id)
|
||||||
|
|
||||||
/* Read textures */
|
/* Read textures */
|
||||||
|
|
||||||
core::list<SendableTexture> textures;
|
// Put 5kB in one bunch (this is not accurate)
|
||||||
|
u32 bytes_per_bunch = 5000;
|
||||||
|
|
||||||
|
core::array< core::list<SendableTexture> > texture_bunches;
|
||||||
|
texture_bunches.push_back(core::list<SendableTexture>());
|
||||||
|
|
||||||
|
u32 texture_size_bunch_total = 0;
|
||||||
core::list<ModSpec> mods = getMods(m_modspaths);
|
core::list<ModSpec> mods = getMods(m_modspaths);
|
||||||
for(core::list<ModSpec>::Iterator i = mods.begin();
|
for(core::list<ModSpec>::Iterator i = mods.begin();
|
||||||
i != mods.end(); i++){
|
i != mods.end(); i++){
|
||||||
|
@ -4186,6 +4192,7 @@ void Server::SendTextures(u16 peer_id)
|
||||||
fis.read(buf, 1024);
|
fis.read(buf, 1024);
|
||||||
std::streamsize len = fis.gcount();
|
std::streamsize len = fis.gcount();
|
||||||
tmp_os.write(buf, len);
|
tmp_os.write(buf, len);
|
||||||
|
texture_size_bunch_total += len;
|
||||||
if(fis.eof())
|
if(fis.eof())
|
||||||
break;
|
break;
|
||||||
if(!fis.good()){
|
if(!fis.good()){
|
||||||
|
@ -4201,40 +4208,57 @@ void Server::SendTextures(u16 peer_id)
|
||||||
errorstream<<"Server::SendTextures(): Loaded \""
|
errorstream<<"Server::SendTextures(): Loaded \""
|
||||||
<<tname<<"\""<<std::endl;
|
<<tname<<"\""<<std::endl;
|
||||||
// Put in list
|
// Put in list
|
||||||
textures.push_back(SendableTexture(tname, tpath, tmp_os.str()));
|
texture_bunches[texture_bunches.size()-1].push_back(
|
||||||
|
SendableTexture(tname, tpath, tmp_os.str()));
|
||||||
|
|
||||||
|
// Start next bunch if got enough data
|
||||||
|
if(texture_size_bunch_total >= bytes_per_bunch){
|
||||||
|
texture_bunches.push_back(core::list<SendableTexture>());
|
||||||
|
texture_size_bunch_total = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create and send packet */
|
/* Create and send packets */
|
||||||
|
|
||||||
|
u32 num_bunches = texture_bunches.size();
|
||||||
|
for(u32 i=0; i<num_bunches; i++)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
u16 command
|
||||||
|
u16 total number of texture bunches
|
||||||
|
u16 index of this bunch
|
||||||
|
u32 number of textures in this bunch
|
||||||
|
for each texture {
|
||||||
|
u16 length of name
|
||||||
|
string name
|
||||||
|
u32 length of data
|
||||||
|
data
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
std::ostringstream os(std::ios_base::binary);
|
||||||
|
|
||||||
/*
|
writeU16(os, TOCLIENT_TEXTURES);
|
||||||
u16 command
|
writeU16(os, num_bunches);
|
||||||
u32 number of textures
|
writeU16(os, i);
|
||||||
for each texture {
|
writeU32(os, texture_bunches[i].size());
|
||||||
u16 length of name
|
|
||||||
string name
|
for(core::list<SendableTexture>::Iterator
|
||||||
u32 length of data
|
j = texture_bunches[i].begin();
|
||||||
data
|
j != texture_bunches[i].end(); j++){
|
||||||
|
os<<serializeString(j->name);
|
||||||
|
os<<serializeLongString(j->data);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
std::ostringstream os(std::ios_base::binary);
|
// Make data buffer
|
||||||
|
std::string s = os.str();
|
||||||
writeU16(os, TOCLIENT_TEXTURES);
|
infostream<<"Server::SendTextures(): number of textures in bunch["
|
||||||
writeU32(os, textures.size());
|
<<i<<"]: "<<texture_bunches[i].size()
|
||||||
|
<<", size: "<<s.size()<<std::endl;
|
||||||
for(core::list<SendableTexture>::Iterator i = textures.begin();
|
SharedBuffer<u8> data((u8*)s.c_str(), s.size());
|
||||||
i != textures.end(); i++){
|
// Send as reliable
|
||||||
os<<serializeString(i->name);
|
m_con.Send(peer_id, 0, data, true);
|
||||||
os<<serializeLongString(i->data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make data buffer
|
|
||||||
std::string s = os.str();
|
|
||||||
infostream<<"Server::SendTextures(): number of textures: "
|
|
||||||
<<textures.size()<<", data size: "<<s.size()<<std::endl;
|
|
||||||
SharedBuffer<u8> data((u8*)s.c_str(), s.size());
|
|
||||||
// Send as reliable
|
|
||||||
m_con.Send(peer_id, 0, data, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue