Merge branch 'openttd'

This commit is contained in:
dP
2023-07-31 19:33:31 +04:00
48 changed files with 687 additions and 252 deletions
+8 -7
View File
@@ -47,7 +47,13 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet *p)
{
PacketAdminType type = (PacketAdminType)p->Recv_uint8();
switch (this->HasClientQuit() ? INVALID_ADMIN_PACKET : type) {
if (this->HasClientQuit()) {
Debug(net, 0, "[tcp/admin] Received invalid packet from '{}' ({})", this->admin_name, this->admin_version);
this->CloseConnection();
return NETWORK_RECV_STATUS_MALFORMED_PACKET;
}
switch (type) {
case ADMIN_PACKET_ADMIN_JOIN: return this->Receive_ADMIN_JOIN(p);
case ADMIN_PACKET_ADMIN_QUIT: return this->Receive_ADMIN_QUIT(p);
case ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY: return this->Receive_ADMIN_UPDATE_FREQUENCY(p);
@@ -87,12 +93,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet *p)
case ADMIN_PACKET_SERVER_PONG: return this->Receive_SERVER_PONG(p);
default:
if (this->HasClientQuit()) {
Debug(net, 0, "[tcp/admin] Received invalid packet type {} from '{}' ({})", type, this->admin_name, this->admin_version);
} else {
Debug(net, 0, "[tcp/admin] Received illegal packet from '{}' ({})", this->admin_name, this->admin_version);
}
Debug(net, 0, "[tcp/admin] Received invalid packet type {} from '{}' ({})", type, this->admin_name, this->admin_version);
this->CloseConnection();
return NETWORK_RECV_STATUS_MALFORMED_PACKET;
}
+22 -7
View File
@@ -20,6 +20,8 @@
#include "../../safeguards.h"
static std::vector<std::unique_ptr<NetworkGameSocketHandler>> _deferred_deletions;
/**
* Create a new socket for the game connection.
* @param s The socket to connect with.
@@ -64,9 +66,15 @@ NetworkRecvStatus NetworkGameSocketHandler::HandlePacket(Packet *p)
{
PacketGameType type = (PacketGameType)p->Recv_uint8();
if (this->HasClientQuit()) {
Debug(net, 0, "[tcp/game] Received invalid packet from client {}", this->client_id);
this->CloseConnection();
return NETWORK_RECV_STATUS_MALFORMED_PACKET;
}
this->last_packet = std::chrono::steady_clock::now();
switch (this->HasClientQuit() ? PACKET_END : type) {
switch (type) {
case PACKET_SERVER_FULL: return this->Receive_SERVER_FULL(p);
case PACKET_SERVER_BANNED: return this->Receive_SERVER_BANNED(p);
case PACKET_CLIENT_JOIN: return this->Receive_CLIENT_JOIN(p);
@@ -113,13 +121,8 @@ NetworkRecvStatus NetworkGameSocketHandler::HandlePacket(Packet *p)
case PACKET_SERVER_CONFIG_UPDATE: return this->Receive_SERVER_CONFIG_UPDATE(p);
default:
Debug(net, 0, "[tcp/game] Received invalid packet type {} from client {}", type, this->client_id);
this->CloseConnection();
if (this->HasClientQuit()) {
Debug(net, 0, "[tcp/game] Received invalid packet type {} from client {}", type, this->client_id);
} else {
Debug(net, 0, "[tcp/game] Received illegal packet from client {}", this->client_id);
}
return NETWORK_RECV_STATUS_MALFORMED_PACKET;
}
}
@@ -198,3 +201,15 @@ NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_MOVE(Packet *p) { ret
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_MOVE(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_MOVE); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_COMPANY_UPDATE(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_COMPANY_UPDATE); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_CONFIG_UPDATE(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_CONFIG_UPDATE); }
void NetworkGameSocketHandler::DeferDeletion()
{
_deferred_deletions.emplace_back(this);
this->is_pending_deletion = true;
}
/* static */ void NetworkGameSocketHandler::ProcessDeferredDeletions()
{
/* Calls deleter on all items */
_deferred_deletions.clear();
}
+7 -1
View File
@@ -154,7 +154,8 @@ public:
class NetworkGameSocketHandler : public NetworkTCPSocketHandler {
/* TODO: rewrite into a proper class */
private:
NetworkClientInfo *info; ///< Client info related to this socket
NetworkClientInfo *info; ///< Client info related to this socket
bool is_pending_deletion = false; ///< Whether this socket is pending deletion
protected:
NetworkRecvStatus ReceiveInvalidPacket(PacketGameType type);
@@ -543,6 +544,11 @@ public:
const char *ReceiveCommand(Packet *p, CommandPacket *cp);
void SendCommand(Packet *p, const CommandPacket *cp);
bool IsPendingDeletion() const { return this->is_pending_deletion; }
void DeferDeletion();
static void ProcessDeferredDeletions();
};
#endif /* NETWORK_CORE_TCP_GAME_H */
+8 -2
View File
@@ -599,6 +599,7 @@ void NetworkClose(bool close_admins)
_network_coordinator_client.CloseAllConnections();
}
NetworkGameSocketHandler::ProcessDeferredDeletions();
TCPConnecter::KillAll();
@@ -996,12 +997,15 @@ void NetworkUpdateServerGameType()
*/
static bool NetworkReceive()
{
bool result;
if (_network_server) {
ServerNetworkAdminSocketHandler::Receive();
return ServerNetworkGameSocketHandler::Receive();
result = ServerNetworkGameSocketHandler::Receive();
} else {
return ClientNetworkGameSocketHandler::Receive();
result = ClientNetworkGameSocketHandler::Receive();
}
NetworkGameSocketHandler::ProcessDeferredDeletions();
return result;
}
/* This sends all buffered commands (if possible) */
@@ -1013,6 +1017,7 @@ static void NetworkSend()
} else {
ClientNetworkGameSocketHandler::Send();
}
NetworkGameSocketHandler::ProcessDeferredDeletions();
}
/**
@@ -1027,6 +1032,7 @@ void NetworkBackgroundLoop()
TCPConnecter::CheckCallbacks();
NetworkHTTPSocketHandler::HTTPReceive();
QueryNetworkGameSocketHandler::SendReceive();
NetworkGameSocketHandler::ProcessDeferredDeletions();
NetworkBackgroundUDPLoop();
}
+5 -1
View File
@@ -160,6 +160,8 @@ ClientNetworkGameSocketHandler::~ClientNetworkGameSocketHandler()
NetworkRecvStatus ClientNetworkGameSocketHandler::CloseConnection(NetworkRecvStatus status)
{
assert(status != NETWORK_RECV_STATUS_OKAY);
if (this->IsPendingDeletion()) return status;
assert(this->sock != INVALID_SOCKET);
if (!this->HasClientQuit()) {
@@ -174,7 +176,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::CloseConnection(NetworkRecvSta
CSleep(3 * MILLISECONDS_PER_TICK);
}
delete this;
this->DeferDeletion();
return status;
}
@@ -185,6 +187,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::CloseConnection(NetworkRecvSta
*/
void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
{
if (this->IsPendingDeletion()) return;
/* First, send a CLIENT_ERROR to the server, so it knows we are
* disconnected (and why!) */
NetworkErrorCode errorno;
+4 -3
View File
@@ -224,6 +224,8 @@ ServerNetworkGameSocketHandler::ServerNetworkGameSocketHandler(SOCKET s) : Netwo
*/
ServerNetworkGameSocketHandler::~ServerNetworkGameSocketHandler()
{
delete this->GetInfo();
if (_redirect_console_to_client == this->client_id) _redirect_console_to_client = INVALID_CLIENT_ID;
OrderBackup::ResetUser(this->client_id);
@@ -256,7 +258,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvSta
* connection. This handles that case gracefully without having to make
* that code any more complex or more aware of the validity of the socket.
*/
if (this->sock == INVALID_SOCKET) return status;
if (this->IsPendingDeletion() || this->sock == INVALID_SOCKET) return status;
if (status != NETWORK_RECV_STATUS_CLIENT_QUIT && status != NETWORK_RECV_STATUS_SERVER_ERROR && !this->HasClientQuit() && this->status >= STATUS_AUTHORIZED) {
/* We did not receive a leave message from this client... */
@@ -292,8 +294,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvSta
this->SendPackets(true);
delete this->GetInfo();
delete this;
this->DeferDeletion();
InvalidateWindowData(WC_CLIENT_LIST, 0);