* Send an error to the client, and close its connection. * @param error The error to disconnect for. * @param reason In case of kicking a client, specifies the reason for kicking the client. */
| 357 | * @param reason In case of kicking a client, specifies the reason for kicking the client. |
| 358 | */ |
| 359 | NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error, std::string_view reason) |
| 360 | { |
| 361 | Debug(net, 9, "client[{}] SendError(): error={}", this->client_id, error); |
| 362 | |
| 363 | auto p = std::make_unique<Packet>(this, PACKET_SERVER_ERROR); |
| 364 | |
| 365 | p->Send_uint8(error); |
| 366 | if (!reason.empty()) p->Send_string(reason); |
| 367 | this->SendPacket(std::move(p)); |
| 368 | |
| 369 | StringID strid = GetNetworkErrorMsg(error); |
| 370 | |
| 371 | /* Only send when the current client was in game */ |
| 372 | if (this->status >= STATUS_AUTHORIZED) { |
| 373 | std::string client_name = this->GetClientName(); |
| 374 | |
| 375 | Debug(net, 1, "'{}' made an error and has been disconnected: {}", client_name, GetString(strid)); |
| 376 | |
| 377 | if (error == NETWORK_ERROR_KICKED && !reason.empty()) { |
| 378 | NetworkTextMessage(NETWORK_ACTION_KICKED, CC_DEFAULT, false, client_name, reason, strid); |
| 379 | } else { |
| 380 | NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", strid); |
| 381 | } |
| 382 | |
| 383 | for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { |
| 384 | if (new_cs->status >= STATUS_AUTHORIZED && new_cs != this) { |
| 385 | /* Some errors we filter to a more general error. Clients don't have to know the real |
| 386 | * reason a joining failed. */ |
| 387 | if (error == NETWORK_ERROR_NOT_AUTHORIZED || error == NETWORK_ERROR_NOT_EXPECTED || error == NETWORK_ERROR_WRONG_REVISION) { |
| 388 | error = NETWORK_ERROR_ILLEGAL_PACKET; |
| 389 | } |
| 390 | new_cs->SendErrorQuit(this->client_id, error); |
| 391 | } |
| 392 | } |
| 393 | |
| 394 | NetworkAdminClientError(this->client_id, error); |
| 395 | } else { |
| 396 | Debug(net, 1, "Client {} made an error and has been disconnected: {}", this->client_id, GetString(strid)); |
| 397 | } |
| 398 | |
| 399 | /* The client made a mistake, so drop the connection now! */ |
| 400 | return this->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR); |
| 401 | } |
| 402 | |
| 403 | /** Send the check for the NewGRFs. */ |
| 404 | NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck() |
no test coverage detected