diff --git a/src/network/core/tcp_game.cpp b/src/network/core/tcp_game.cpp index 4ecfe7347c..0904a54017 100644 --- a/src/network/core/tcp_game.cpp +++ b/src/network/core/tcp_game.cpp @@ -25,7 +25,7 @@ * @param s The socket to connect with. */ NetworkGameSocketHandler::NetworkGameSocketHandler(SOCKET s) : info(nullptr), client_id(INVALID_CLIENT_ID), - last_frame(_frame_counter), last_frame_server(_frame_counter) + last_frame(_frame_counter), last_frame_server(_frame_counter), last_pkt_type(PACKET_END) { this->sock = s; this->last_packet = std::chrono::steady_clock::now(); @@ -67,6 +67,7 @@ NetworkRecvStatus NetworkGameSocketHandler::HandlePacket(Packet *p) PacketGameType type = (PacketGameType)p->Recv_uint8(); this->last_packet = std::chrono::steady_clock::now(); + this->last_pkt_type = type; DEBUG(net, 3, "[tcp/game] received packet type %d from client %d, %s", type, this->client_id, this->GetDebugInfo().c_str()); diff --git a/src/network/core/tcp_game.h b/src/network/core/tcp_game.h index aa0925d8f1..4f9277cafa 100644 --- a/src/network/core/tcp_game.h +++ b/src/network/core/tcp_game.h @@ -548,6 +548,7 @@ public: uint32 last_frame_server; ///< Last frame the server has executed CommandQueue incoming_queue; ///< The command-queue awaiting handling std::chrono::steady_clock::time_point last_packet; ///< Time we received the last frame. + PacketGameType last_pkt_type;///< Last received packet type NetworkRecvStatus CloseConnection(bool error = true) override; diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 05c1f6bf49..81fe1a2af3 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -253,7 +253,7 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res) this->CloseConnection(res); } else { /* This means we as client made a boo-boo. */ - SendError(errorno); + SendError(errorno, res); /* Close connection before we make an emergency save, as the save can * take a bit of time; better that the server doesn't stall while we @@ -547,11 +547,14 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendChat(NetworkAction action, } /** Send an error-packet over the network */ -NetworkRecvStatus ClientNetworkGameSocketHandler::SendError(NetworkErrorCode errorno) +NetworkRecvStatus ClientNetworkGameSocketHandler::SendError(NetworkErrorCode errorno, NetworkRecvStatus recvstatus) { Packet *p = new Packet(PACKET_CLIENT_ERROR, SHRT_MAX); p->Send_uint8(errorno); + p->Send_uint8(recvstatus); + p->Send_uint8(my_client->status); + p->Send_uint8(my_client->last_pkt_type); my_client->SendPacket(p); return NETWORK_RECV_STATUS_OKAY; } diff --git a/src/network/network_client.h b/src/network/network_client.h index f5ecded70b..fe18c49ecc 100644 --- a/src/network/network_client.h +++ b/src/network/network_client.h @@ -92,7 +92,7 @@ public: static NetworkRecvStatus SendJoin(); static NetworkRecvStatus SendCommand(const CommandPacket *cp); - static NetworkRecvStatus SendError(NetworkErrorCode errorno); + static NetworkRecvStatus SendError(NetworkErrorCode errorno, NetworkRecvStatus recvstatus = NETWORK_RECV_STATUS_OKAY); static NetworkRecvStatus SendDesyncLog(const std::string &log); static NetworkRecvStatus SendDesyncMessage(const char *msg); static NetworkRecvStatus SendQuit(); diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 0064d048e1..57285dee5e 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -1191,9 +1191,14 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p char str[100]; char client_name[NETWORK_CLIENT_NAME_LENGTH]; NetworkErrorCode errorno = (NetworkErrorCode)p->Recv_uint8(); + NetworkRecvStatus rx_status = p->CanReadFromPacket(1) ? (NetworkRecvStatus)p->Recv_uint8() : NETWORK_RECV_STATUS_OKAY; + int8 status = p->CanReadFromPacket(1) ? (int8)p->Recv_uint8() : -1; + PacketGameType last_pkt_type = p->CanReadFromPacket(1) ? (PacketGameType)p->Recv_uint8() : PACKET_END; /* The client was never joined.. thank the client for the packet, but ignore it */ if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) { + if (_debug_net_level >= 2) GetString(str, GetNetworkErrorMsg(errorno), lastof(str)); + DEBUG(net, 2, "non-joined client %d reported an error and is closing its connection (%s) (%d, %d, %d)", this->client_id, str, rx_status, status, last_pkt_type); return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST); } @@ -1202,7 +1207,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p StringID strid = GetNetworkErrorMsg(errorno); GetString(str, strid, lastof(str)); - DEBUG(net, 2, "'%s' reported an error and is closing its connection (%s)", client_name, str); + DEBUG(net, 2, "'%s' reported an error and is closing its connection (%s) (%d, %d, %d)", client_name, str, rx_status, status, last_pkt_type); NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, nullptr, strid);