mirror of https://github.com/minetest/minetest.git
New packet handling, a more proper way
This commit is contained in:
parent
32ca9c8b38
commit
a9da5e8a44
214
src/client.cpp
214
src/client.cpp
|
@ -1001,40 +1001,100 @@ void Client::Receive()
|
||||||
ProcessData(*data, datasize, sender_peer_id);
|
ProcessData(*data, datasize, sender_peer_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
struct ToClientCommandHandler
|
||||||
sender_peer_id given to this shall be quaranteed to be a valid peer
|
|
||||||
*/
|
|
||||||
void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
char const* name;
|
||||||
|
void (Client::*handler)(u8 *data, u32 datasize, u16 sender_peer_id);
|
||||||
|
};
|
||||||
|
|
||||||
// Ignore packets that don't even fit a command
|
ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] =
|
||||||
if(datasize < 2)
|
|
||||||
{
|
{
|
||||||
m_packetcounter.add(60000);
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
return;
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
}
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_INIT", &Client::handleCommand_Init }, // 0x10
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_ACCESS_DENIED", &Client::handleCommand_AccessDenied }, // 0x35
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
{ "TOCLIENT_NULL", &Client::handleCommand_Null },
|
||||||
|
};
|
||||||
|
|
||||||
ToClientCommand command = (ToClientCommand)readU16(&data[0]);
|
void Client::handleCommand_Init(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
|
|
||||||
//infostream<<"Client: received command="<<command<<std::endl;
|
|
||||||
m_packetcounter.add((u16)command);
|
|
||||||
|
|
||||||
/*
|
|
||||||
If this check is removed, be sure to change the queue
|
|
||||||
system to know the ids
|
|
||||||
*/
|
|
||||||
if(sender_peer_id != PEER_ID_SERVER)
|
|
||||||
{
|
|
||||||
infostream<<"Client::ProcessData(): Discarding data not "
|
|
||||||
"coming from server: peer_id="<<sender_peer_id
|
|
||||||
<<std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 ser_version = m_server_ser_ver;
|
|
||||||
|
|
||||||
if(command == TOCLIENT_INIT)
|
|
||||||
{
|
{
|
||||||
if(datasize < 3)
|
if(datasize < 3)
|
||||||
return;
|
return;
|
||||||
|
@ -1088,11 +1148,9 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
m_con.Send(PEER_ID_SERVER, 1, reply, true);
|
m_con.Send(PEER_ID_SERVER, 1, reply, true);
|
||||||
|
|
||||||
m_state = LC_Init;
|
m_state = LC_Init;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(command == TOCLIENT_ACCESS_DENIED)
|
void Client::handleCommand_AccessDenied(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
{
|
{
|
||||||
// The server didn't like our password. Note, this needs
|
// The server didn't like our password. Note, this needs
|
||||||
// to be processed even if the serialisation format has
|
// to be processed even if the serialisation format has
|
||||||
|
@ -1105,37 +1163,24 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
std::istringstream is(datastring, std::ios_base::binary);
|
std::istringstream is(datastring, std::ios_base::binary);
|
||||||
m_access_denied_reason = deSerializeWideString(is);
|
m_access_denied_reason = deSerializeWideString(is);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ser_version == SER_FMT_VER_INVALID)
|
void Client::handleCommand_RemoveNode(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
{
|
|
||||||
infostream<<"Client: Server serialization"
|
|
||||||
" format invalid or not initialized."
|
|
||||||
" Skipping incoming command="<<command<<std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Handle runtime commands
|
|
||||||
*/
|
|
||||||
// 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)
|
if(datasize < 8)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
v3s16 p;
|
v3s16 p;
|
||||||
p.X = readS16(&data[2]);
|
p.X = readS16(&data[2]);
|
||||||
p.Y = readS16(&data[4]);
|
p.Y = readS16(&data[4]);
|
||||||
p.Z = readS16(&data[6]);
|
p.Z = readS16(&data[6]);
|
||||||
removeNode(p);
|
removeNode(p);
|
||||||
}
|
}
|
||||||
else if(command == TOCLIENT_ADDNODE)
|
|
||||||
|
void Client::handleCommand_AddNode(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
{
|
{
|
||||||
|
u8 ser_version = m_server_ser_ver;
|
||||||
|
|
||||||
if(datasize < 8 + MapNode::serializedLength(ser_version))
|
if(datasize < 8 + MapNode::serializedLength(ser_version))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1155,7 +1200,70 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
|
|
||||||
addNode(p, n, remove_metadata);
|
addNode(p, n, remove_metadata);
|
||||||
}
|
}
|
||||||
else if(command == TOCLIENT_BLOCKDATA)
|
/*
|
||||||
|
sender_peer_id given to this shall be quaranteed to be a valid peer
|
||||||
|
*/
|
||||||
|
void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
||||||
|
{
|
||||||
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
||||||
|
// Ignore packets that don't even fit a command
|
||||||
|
if(datasize < 2)
|
||||||
|
{
|
||||||
|
m_packetcounter.add(60000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ToClientCommand command = (ToClientCommand)readU16(&data[0]);
|
||||||
|
|
||||||
|
//infostream<<"Client: received command="<<command<<std::endl;
|
||||||
|
m_packetcounter.add((u16)command);
|
||||||
|
|
||||||
|
/*
|
||||||
|
If this check is removed, be sure to change the queue
|
||||||
|
system to know the ids
|
||||||
|
*/
|
||||||
|
if(sender_peer_id != PEER_ID_SERVER)
|
||||||
|
{
|
||||||
|
infostream<<"Client::ProcessData(): Discarding data not "
|
||||||
|
"coming from server: peer_id="<<sender_peer_id
|
||||||
|
<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 ser_version = m_server_ser_ver;
|
||||||
|
|
||||||
|
if(command == TOCLIENT_INIT || command == TOCLIENT_ACCESS_DENIED)
|
||||||
|
{
|
||||||
|
ToClientCommandHandler& opHandle = toClientCommandTable[command];
|
||||||
|
(this->*opHandle.handler)(data, datasize, sender_peer_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ser_version == SER_FMT_VER_INVALID)
|
||||||
|
{
|
||||||
|
infostream<<"Client: Server serialization"
|
||||||
|
" format invalid or not initialized."
|
||||||
|
" Skipping incoming command="<<command<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Handle runtime commands
|
||||||
|
*/
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Handle present here because or m_server_ser_ver (temp i think)
|
||||||
|
if (command == TOCLIENT_REMOVENODE || command == TOCLIENT_ADDNODE) {
|
||||||
|
ToClientCommandHandler& opHandle = toClientCommandTable[command];
|
||||||
|
(this->*opHandle.handler)(data, datasize, sender_peer_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(command == TOCLIENT_BLOCKDATA)
|
||||||
{
|
{
|
||||||
// Ignore too small packet
|
// Ignore too small packet
|
||||||
if(datasize < 8)
|
if(datasize < 8)
|
||||||
|
|
11
src/client.h
11
src/client.h
|
@ -339,7 +339,18 @@ public:
|
||||||
*/
|
*/
|
||||||
void step(float dtime);
|
void step(float dtime);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Command Handler
|
||||||
|
*/
|
||||||
|
|
||||||
|
void handleCommand_Null(u8 *data, u32 datasize, u16 sender_peer_id) {}
|
||||||
|
void handleCommand_Init(u8 *data, u32 datasize, u16 sender_peer_id);
|
||||||
|
void handleCommand_AccessDenied(u8 *data, u32 datasize, u16 sender_peer_id);
|
||||||
|
void handleCommand_RemoveNode(u8 *data, u32 datasize, u16 sender_peer_id);
|
||||||
|
void handleCommand_AddNode(u8 *data, u32 datasize, u16 sender_peer_id);
|
||||||
|
|
||||||
void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
|
void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
|
||||||
|
|
||||||
// Returns true if something was received
|
// Returns true if something was received
|
||||||
bool AsyncProcessPacket();
|
bool AsyncProcessPacket();
|
||||||
bool AsyncProcessData();
|
bool AsyncProcessData();
|
||||||
|
|
|
@ -556,6 +556,8 @@ enum ToClientCommand
|
||||||
v3f1000 first
|
v3f1000 first
|
||||||
v3f1000 third
|
v3f1000 third
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
TOCLIENT_NUM_MSG_TYPES = 0x53,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ToServerCommand
|
enum ToServerCommand
|
||||||
|
|
Loading…
Reference in New Issue