OpenTTD Source  20241121-master-g67a0fccfad
network_query.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "../stdafx.h"
11 #include "core/network_game_info.h"
12 #include "network_query.h"
13 #include "network_gamelist.h"
14 #include "../error.h"
15 
16 #include "table/strings.h"
17 
18 #include "../safeguards.h"
19 
20 std::vector<std::unique_ptr<QueryNetworkGameSocketHandler>> QueryNetworkGameSocketHandler::queries = {};
21 
23 {
24  assert(status != NETWORK_RECV_STATUS_OKAY);
25  assert(this->sock != INVALID_SOCKET);
26 
27  /* Connection is closed, but we never received a packet. Must be offline. */
29  if (item->refreshing) {
30  item->status = NGLS_OFFLINE;
31  item->refreshing = false;
32 
34  }
35 
36  return status;
37 }
38 
43 {
44  std::chrono::steady_clock::duration lag = std::chrono::steady_clock::now() - this->last_packet;
45 
46  /* If there was no response in 5 seconds, terminate the query. */
47  if (lag > std::chrono::seconds(5)) {
48  Debug(net, 0, "Timeout while waiting for response from {}", this->connection_string);
50  return false;
51  }
52 
53  return true;
54 }
55 
62 {
63  if (this->CanSendReceive()) {
64  NetworkRecvStatus res = this->ReceivePackets();
65  if (res != NETWORK_RECV_STATUS_OKAY) {
66  this->CloseConnection(res);
67  return false;
68  }
69  }
70  return true;
71 }
72 
75 {
76  this->SendPackets();
77 }
78 
83 {
84  Debug(net, 9, "Query::SendGameInfo()");
85 
86  this->SendPacket(std::make_unique<Packet>(this, PACKET_CLIENT_GAME_INFO));
88 }
89 
91 {
92  Debug(net, 9, "Query::Receive_SERVER_FULL()");
93 
95  item->status = NGLS_FULL;
96  item->refreshing = false;
97 
99 
101 }
102 
104 {
105  Debug(net, 9, "Query::Receive_SERVER_BANNED()");
106 
108  item->status = NGLS_BANNED;
109  item->refreshing = false;
110 
112 
114 }
115 
117 {
118  Debug(net, 9, "Query::Receive_SERVER_GAME_INFO()");
119 
121 
122  /* Clear any existing GRFConfig chain. */
124  /* Retrieve the NetworkGameInfo from the packet. */
125  DeserializeNetworkGameInfo(p, item->info);
126  /* Check for compatability with the client. */
127  CheckGameCompatibility(item->info);
128  /* Ensure we consider the server online. */
129  item->status = NGLS_ONLINE;
130  item->refreshing = false;
131 
133 
135 }
136 
138 {
140 
141  Debug(net, 9, "Query::Receive_SERVER_ERROR(): error={}", error);
142 
144 
145  if (error == NETWORK_ERROR_NOT_EXPECTED) {
146  /* If we query a server that is 1.11.1 or older, we get an
147  * NETWORK_ERROR_NOT_EXPECTED on requesting the game info. Show to the
148  * user this server is too old to query.
149  */
150  item->status = NGLS_TOO_OLD;
151  } else {
152  item->status = NGLS_OFFLINE;
153  }
154  item->refreshing = false;
155 
157 
159 }
160 
165 {
166  for (auto it = QueryNetworkGameSocketHandler::queries.begin(); it != QueryNetworkGameSocketHandler::queries.end(); /* nothing */) {
167  if (!(*it)->Receive()) {
169  } else if (!(*it)->CheckConnection()) {
171  } else {
172  it++;
173  }
174  }
175 
176  for (auto &query : QueryNetworkGameSocketHandler::queries) {
177  query->Send();
178  }
179 }
NetworkRecvStatus ReceivePackets()
Do the actual receiving of packets.
Definition: tcp_game.cpp:134
std::chrono::steady_clock::time_point last_packet
Time we received the last frame.
Definition: tcp_game.h:490
SOCKET sock
The socket currently connected to.
Definition: tcp.h:38
virtual void SendPacket(std::unique_ptr< Packet > &&packet)
This function puts the packet in the send-queue and it is send as soon as possible.
Definition: tcp.cpp:68
SendPacketsState SendPackets(bool closing_down=false)
Sends all the buffered packets out for this client.
Definition: tcp.cpp:86
bool CanSendReceive()
Check whether this socket can send or receive something.
Definition: tcp.cpp:204
static std::vector< std::unique_ptr< QueryNetworkGameSocketHandler > > queries
Pending queries.
Definition: network_query.h:18
void Send()
Send the packets of this socket handler.
NetworkRecvStatus Receive_SERVER_FULL(Packet &p) override
Notification that the server is full.
std::string connection_string
Address we are connected to.
Definition: network_query.h:19
static void SendReceive()
Check if any query needs to send or receive.
NetworkRecvStatus Receive_SERVER_ERROR(Packet &p) override
The client made an error: uint8_t Error code caused (see NetworkErrorCode).
NetworkRecvStatus Receive_SERVER_BANNED(Packet &p) override
Notification that the client trying to join is banned.
NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override
Close the network connection due to the given status.
bool Receive()
Check whether we received/can send some data from/to the server and when that's the case handle it ap...
NetworkRecvStatus Receive_SERVER_GAME_INFO(Packet &p) override
Sends information about the game.
NetworkRecvStatus SendGameInfo()
Query the server for server information.
bool CheckConnection()
Check the connection's state, i.e.
NetworkRecvStatus
Status of a network client; reasons why a client has quit.
Definition: core.h:23
@ NETWORK_RECV_STATUS_CLOSE_QUERY
Done querying the server.
Definition: core.h:33
@ NETWORK_RECV_STATUS_OKAY
Everything is okay.
Definition: core.h:24
@ NETWORK_RECV_STATUS_CONNECTION_LOST
The connection is lost unexpectedly.
Definition: core.h:34
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
NetworkGameList * NetworkGameListAddItem(const std::string &connection_string)
Add a new item to the linked gamelist.
Handling of the list of games.
@ NGLS_ONLINE
Server is online.
@ NGLS_FULL
Server is full and cannot be queried.
@ NGLS_TOO_OLD
Server is too old to query.
@ NGLS_OFFLINE
Server is offline (or cannot be queried).
@ NGLS_BANNED
You are banned from this server.
void UpdateNetworkGameWindow()
Update the network new window because a new server is found on the network.
Definition: network_gui.cpp:66
Query part of the network protocol.
NetworkErrorCode
The error codes we send around in the protocols.
Definition: network_type.h:110
void ClearGRFConfigList(GRFConfig **config)
Clear a GRF Config list, freeing all nodes.
Structure with information shown in the game list (GUI)
bool refreshing
Whether this server is being queried.
NetworkGameListStatus status
Stats of the server.
NetworkGameInfo info
The game information of this server.
GRFConfig * grfconfig
List of NewGRF files used.
Internal entity of a packet.
Definition: packet.h:42
uint8_t Recv_uint8()
Read a 8 bits integer from the packet.
Definition: packet.cpp:318
@ PACKET_CLIENT_GAME_INFO
Request information about the server.
Definition: tcp_game.h:46