OpenTTD Source: src/network/network_query.cpp Source File

OpenTTD Source 15.3

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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "../stdafx.h"
11
12#include "core/network_game_info.h"
13#include "network_query.h"
14#include "network_gamelist.h"
15
16#include "../safeguards.h"
17
18std::vector<std::unique_ptr<QueryNetworkGameSocketHandler>> QueryNetworkGameSocketHandler::queries = {};
19
20 NetworkRecvStatus QueryNetworkGameSocketHandler::CloseConnection(NetworkRecvStatus status)
21{
22 assert(status != NETWORK_RECV_STATUS_OKAY);
23 assert(this->sock != INVALID_SOCKET);
24
25 /* Connection is closed, but we never received a packet. Must be offline. */
26 NetworkGame *item = NetworkGameListAddItem(this->connection_string);
27 if (item->refreshing) {
28 item->status = NGLS_OFFLINE;
29 item->refreshing = false;
30
31 UpdateNetworkGameWindow();
32 }
33
34 return status;
35}
36
40 bool QueryNetworkGameSocketHandler::CheckConnection()
41{
42 std::chrono::steady_clock::duration lag = std::chrono::steady_clock::now() - this->last_packet;
43
44 /* If there was no response in 5 seconds, terminate the query. */
45 if (lag > std::chrono::seconds(5)) {
46 Debug(net, 0, "Timeout while waiting for response from {}", this->connection_string);
47 this->CloseConnection(NETWORK_RECV_STATUS_CONNECTION_LOST);
48 return false;
49 }
50
51 return true;
52}
53
59 bool QueryNetworkGameSocketHandler::Receive()
60{
61 if (this->CanSendReceive()) {
62 NetworkRecvStatus res = this->ReceivePackets();
63 if (res != NETWORK_RECV_STATUS_OKAY) {
64 this->CloseConnection(res);
65 return false;
66 }
67 }
68 return true;
69}
70
72 void QueryNetworkGameSocketHandler::Send()
73{
74 this->SendPackets();
75}
76
80 NetworkRecvStatus QueryNetworkGameSocketHandler::SendGameInfo()
81{
82 Debug(net, 9, "Query::SendGameInfo()");
83
84 this->SendPacket(std::make_unique<Packet>(this, PACKET_CLIENT_GAME_INFO));
85 return NETWORK_RECV_STATUS_OKAY;
86}
87
88 NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_FULL(Packet &)
89{
90 Debug(net, 9, "Query::Receive_SERVER_FULL()");
91
92 NetworkGame *item = NetworkGameListAddItem(this->connection_string);
93 item->status = NGLS_FULL;
94 item->refreshing = false;
95
96 UpdateNetworkGameWindow();
97
98 return NETWORK_RECV_STATUS_CLOSE_QUERY;
99}
100
101 NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_BANNED(Packet &)
102{
103 Debug(net, 9, "Query::Receive_SERVER_BANNED()");
104
105 NetworkGame *item = NetworkGameListAddItem(this->connection_string);
106 item->status = NGLS_BANNED;
107 item->refreshing = false;
108
109 UpdateNetworkGameWindow();
110
111 return NETWORK_RECV_STATUS_CLOSE_QUERY;
112}
113
114 NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_GAME_INFO(Packet &p)
115{
116 Debug(net, 9, "Query::Receive_SERVER_GAME_INFO()");
117
118 NetworkGame *item = NetworkGameListAddItem(this->connection_string);
119
120 /* Clear any existing GRFConfig chain. */
121 ClearGRFConfigList(item->info.grfconfig);
122 /* Retrieve the NetworkGameInfo from the packet. */
123 DeserializeNetworkGameInfo(p, item->info);
124 /* Check for compatibility with the client. */
125 CheckGameCompatibility(item->info);
126 /* Ensure we consider the server online. */
127 item->status = NGLS_ONLINE;
128 item->refreshing = false;
129
130 UpdateNetworkGameWindow();
131
132 return NETWORK_RECV_STATUS_CLOSE_QUERY;
133}
134
135 NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet &p)
136{
137 NetworkErrorCode error = (NetworkErrorCode)p.Recv_uint8();
138
139 Debug(net, 9, "Query::Receive_SERVER_ERROR(): error={}", error);
140
141 NetworkGame *item = NetworkGameListAddItem(this->connection_string);
142
143 if (error == NETWORK_ERROR_NOT_EXPECTED) {
144 /* If we query a server that is 1.11.1 or older, we get an
145 * NETWORK_ERROR_NOT_EXPECTED on requesting the game info. Show to the
146 * user this server is too old to query.
147 */
148 item->status = NGLS_TOO_OLD;
149 } else {
150 item->status = NGLS_OFFLINE;
151 }
152 item->refreshing = false;
153
154 UpdateNetworkGameWindow();
155
156 return NETWORK_RECV_STATUS_CLOSE_QUERY;
157}
158
162/* static */ void QueryNetworkGameSocketHandler::SendReceive()
163{
164 for (auto it = QueryNetworkGameSocketHandler::queries.begin(); it != QueryNetworkGameSocketHandler::queries.end(); /* nothing */) {
165 if (!(*it)->Receive()) {
166 it = QueryNetworkGameSocketHandler::queries.erase(it);
167 } else if (!(*it)->CheckConnection()) {
168 it = QueryNetworkGameSocketHandler::queries.erase(it);
169 } else {
170 it++;
171 }
172 }
173
174 for (auto &query : QueryNetworkGameSocketHandler::queries) {
175 query->Send();
176 }
177}
NetworkGameSocketHandler::ReceivePackets
NetworkRecvStatus ReceivePackets()
Do the actual receiving of packets.
Definition tcp_game.cpp:131
NetworkGameSocketHandler::last_packet
std::chrono::steady_clock::time_point last_packet
Time we received the last frame.
Definition tcp_game.h:489
NetworkTCPSocketHandler::sock
SOCKET sock
The socket currently connected to.
Definition tcp.h:38
NetworkTCPSocketHandler::SendPacket
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:58
NetworkTCPSocketHandler::SendPackets
SendPacketsState SendPackets(bool closing_down=false)
Sends all the buffered packets out for this client.
Definition tcp.cpp:76
NetworkTCPSocketHandler::CanSendReceive
bool CanSendReceive()
Check whether this socket can send or receive something.
Definition tcp.cpp:194
QueryNetworkGameSocketHandler::queries
static std::vector< std::unique_ptr< QueryNetworkGameSocketHandler > > queries
Pending queries.
Definition network_query.h:18
QueryNetworkGameSocketHandler::Send
void Send()
Send the packets of this socket handler.
Definition network_query.cpp:72
QueryNetworkGameSocketHandler::Receive_SERVER_FULL
NetworkRecvStatus Receive_SERVER_FULL(Packet &p) override
Notification that the server is full.
Definition network_query.cpp:88
QueryNetworkGameSocketHandler::connection_string
std::string connection_string
Address we are connected to.
Definition network_query.h:19
QueryNetworkGameSocketHandler::SendReceive
static void SendReceive()
Check if any query needs to send or receive.
Definition network_query.cpp:162
QueryNetworkGameSocketHandler::Receive_SERVER_ERROR
NetworkRecvStatus Receive_SERVER_ERROR(Packet &p) override
The client made an error: uint8_t Error code caused (see NetworkErrorCode).
Definition network_query.cpp:135
QueryNetworkGameSocketHandler::Receive_SERVER_BANNED
NetworkRecvStatus Receive_SERVER_BANNED(Packet &p) override
Notification that the client trying to join is banned.
Definition network_query.cpp:101
QueryNetworkGameSocketHandler::CloseConnection
NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override
Close the network connection due to the given status.
Definition network_query.cpp:20
QueryNetworkGameSocketHandler::Receive
bool Receive()
Check whether we received/can send some data from/to the server and when that's the case handle it ap...
Definition network_query.cpp:59
QueryNetworkGameSocketHandler::Receive_SERVER_GAME_INFO
NetworkRecvStatus Receive_SERVER_GAME_INFO(Packet &p) override
Sends information about the game.
Definition network_query.cpp:114
QueryNetworkGameSocketHandler::SendGameInfo
NetworkRecvStatus SendGameInfo()
Query the server for server information.
Definition network_query.cpp:80
QueryNetworkGameSocketHandler::CheckConnection
bool CheckConnection()
Check the connection's state, i.e.
Definition network_query.cpp:40
NetworkRecvStatus
NetworkRecvStatus
Status of a network client; reasons why a client has quit.
Definition core.h:23
NETWORK_RECV_STATUS_CLOSE_QUERY
@ NETWORK_RECV_STATUS_CLOSE_QUERY
Done querying the server.
Definition core.h:33
NETWORK_RECV_STATUS_OKAY
@ NETWORK_RECV_STATUS_OKAY
Everything is okay.
Definition core.h:24
NETWORK_RECV_STATUS_CONNECTION_LOST
@ NETWORK_RECV_STATUS_CONNECTION_LOST
The connection is lost unexpectedly.
Definition core.h:34
Debug
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
NetworkGameListAddItem
NetworkGame * NetworkGameListAddItem(std::string_view connection_string)
Add a new item to the linked gamelist.
Definition network_gamelist.cpp:30
network_gamelist.h
Handling of the list of games.
NGLS_ONLINE
@ NGLS_ONLINE
Server is online.
Definition network_gamelist.h:20
NGLS_FULL
@ NGLS_FULL
Server is full and cannot be queried.
Definition network_gamelist.h:21
NGLS_TOO_OLD
@ NGLS_TOO_OLD
Server is too old to query.
Definition network_gamelist.h:23
NGLS_OFFLINE
@ NGLS_OFFLINE
Server is offline (or cannot be queried).
Definition network_gamelist.h:19
NGLS_BANNED
@ NGLS_BANNED
You are banned from this server.
Definition network_gamelist.h:22
UpdateNetworkGameWindow
void UpdateNetworkGameWindow()
Update the network new window because a new server is found on the network.
Definition network_gui.cpp:66
network_query.h
Query part of the network protocol.
NetworkErrorCode
NetworkErrorCode
The error codes we send around in the protocols.
Definition network_type.h:99
ClearGRFConfigList
void ClearGRFConfigList(GRFConfigList &config)
Clear a GRF Config list, freeing all nodes.
Definition newgrf_config.cpp:324
NetworkGame
Structure with information shown in the game list (GUI)
Definition network_gamelist.h:27
NetworkGame::refreshing
bool refreshing
Whether this server is being queried.
Definition network_gamelist.h:34
NetworkGame::info
NetworkGameInfo info
The game information of this server.
Definition network_gamelist.h:30
NetworkGame::status
NetworkGameStatus status
Stats of the server.
Definition network_gamelist.h:32
NetworkServerGameInfo::grfconfig
GRFConfigList grfconfig
List of NewGRF files used.
Definition network_game_info.h:98
Packet
Internal entity of a packet.
Definition packet.h:43
Packet::Recv_uint8
uint8_t Recv_uint8()
Read a 8 bits integer from the packet.
Definition packet.cpp:318
PACKET_CLIENT_GAME_INFO
@ PACKET_CLIENT_GAME_INFO
Request information about the server.
Definition tcp_game.h:45