OpenTTD Source  1.11.2
game_info.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 
12 #include "../../stdafx.h"
13 #include "game_info.h"
14 #include "../../core/bitmath_func.hpp"
15 #include "../../company_base.h"
16 #include "../../date_func.h"
17 #include "../../debug.h"
18 #include "../../map_func.h"
19 #include "../../settings_type.h"
20 #include "../../string_func.h"
21 #include "../../rev.h"
22 #include "../network_func.h"
23 #include "../network.h"
24 #include "packet.h"
25 
26 #include "../../safeguards.h"
27 
28 
33 static const uint GITHASH_SUFFIX_LEN = 12;
34 
36 
42 {
43  /* This will be allocated on heap and never free'd, but only once so not a "real" leak. */
44  static char *network_revision = nullptr;
45 
46  if (!network_revision) {
47  /* Start by taking a chance on the full revision string. */
48  network_revision = stredup(_openttd_revision);
49  /* Ensure it's not longer than the packet buffer length. */
50  if (strlen(network_revision) >= NETWORK_REVISION_LENGTH) network_revision[NETWORK_REVISION_LENGTH - 1] = '\0';
51 
52  /* Tag names are not mangled further. */
53  if (_openttd_revision_tagged) {
54  DEBUG(net, 1, "Network revision name is '%s'", network_revision);
55  return network_revision;
56  }
57 
58  /* Prepare a prefix of the git hash.
59  * Size is length + 1 for terminator, +2 for -g prefix. */
60  assert(_openttd_revision_modified < 3);
61  char githash_suffix[GITHASH_SUFFIX_LEN + 1] = "-";
62  githash_suffix[1] = "gum"[_openttd_revision_modified];
63  for (uint i = 2; i < GITHASH_SUFFIX_LEN; i++) {
64  githash_suffix[i] = _openttd_revision_hash[i-2];
65  }
66 
67  /* Where did the hash start in the original string?
68  * Overwrite from that position, unless that would go past end of packet buffer length. */
69  ptrdiff_t hashofs = strrchr(_openttd_revision, '-') - _openttd_revision;
70  if (hashofs + strlen(githash_suffix) + 1 > NETWORK_REVISION_LENGTH) hashofs = strlen(network_revision) - strlen(githash_suffix);
71  /* Replace the git hash in revision string. */
72  strecpy(network_revision + hashofs, githash_suffix, network_revision + NETWORK_REVISION_LENGTH);
73  assert(strlen(network_revision) < NETWORK_REVISION_LENGTH); // strlen does not include terminator, constant does, hence strictly less than
74  DEBUG(net, 1, "Network revision name is '%s'", network_revision);
75  }
76 
77  return network_revision;
78 }
79 
85 static const char *ExtractNetworkRevisionHash(const char *revstr)
86 {
87  return strrchr(revstr, '-');
88 }
89 
95 bool IsNetworkCompatibleVersion(const char *other)
96 {
97  if (strncmp(GetNetworkRevisionString(), other, NETWORK_REVISION_LENGTH - 1) == 0) return true;
98 
99  /* If this version is tagged, then the revision string must be a complete match,
100  * since there is no git hash suffix in it.
101  * This is needed to avoid situations like "1.9.0-beta1" comparing equal to "2.0.0-beta1". */
102  if (_openttd_revision_tagged) return false;
103 
105  const char *hash2 = ExtractNetworkRevisionHash(other);
106  return hash1 != nullptr && hash2 != nullptr && strncmp(hash1, hash2, GITHASH_SUFFIX_LEN) == 0;
107 }
108 
114 {
115  /* Update some game_info */
118 
122  ngi.companies_on = (byte)Company::GetNumItems();
124  ngi.spectators_on = NetworkSpectatorCount();
126  ngi.game_date = _date;
127  ngi.map_width = MapSizeX();
128  ngi.map_height = MapSizeY();
131  ngi.grfconfig = _grfconfig;
132 
136 }
137 
146 {
147  /* Find the matching GRF file */
148  const GRFConfig *f = FindGRFConfig(config->ident.grfid, FGCM_EXACT, config->ident.md5sum);
149  if (f == nullptr) {
150  /* Don't know the GRF, so mark game incompatible and the (possibly)
151  * already resolved name for this GRF (another server has sent the
152  * name of the GRF already */
153  config->name = FindUnknownGRFName(config->ident.grfid, config->ident.md5sum, true);
154  config->status = GCS_NOT_FOUND;
155  } else {
156  config->filename = f->filename;
157  config->name = f->name;
158  config->info = f->info;
159  config->url = f->url;
160  }
161  SetBit(config->flags, GCF_COPY);
162 }
163 
170 {
172 
173  /*
174  * Please observe the order.
175  * The parts must be read in the same order as they are sent!
176  */
177 
178  /* Update the documentation in game_info.h on changes
179  * to the NetworkGameInfo wire-protocol! */
180 
181  /* NETWORK_GAME_INFO_VERSION = 4 */
182  {
183  /* Only send the GRF Identification (GRF_ID and MD5 checksum) of
184  * the GRFs that are needed, i.e. the ones that the server has
185  * selected in the NewGRF GUI and not the ones that are used due
186  * to the fact that they are in [newgrf-static] in openttd.cfg */
187  const GRFConfig *c;
188  uint count = 0;
189 
190  /* Count number of GRFs to send information about */
191  for (c = info->grfconfig; c != nullptr; c = c->next) {
192  if (!HasBit(c->flags, GCF_STATIC)) count++;
193  }
194  p->Send_uint8 (count); // Send number of GRFs
195 
196  /* Send actual GRF Identifications */
197  for (c = info->grfconfig; c != nullptr; c = c->next) {
199  }
200  }
201 
202  /* NETWORK_GAME_INFO_VERSION = 3 */
203  p->Send_uint32(info->game_date);
204  p->Send_uint32(info->start_date);
205 
206  /* NETWORK_GAME_INFO_VERSION = 2 */
207  p->Send_uint8 (info->companies_max);
208  p->Send_uint8 (info->companies_on);
209  p->Send_uint8 (info->spectators_max);
210 
211  /* NETWORK_GAME_INFO_VERSION = 1 */
212  p->Send_string(info->server_name);
213  p->Send_string(info->server_revision);
214  p->Send_uint8 (info->server_lang);
215  p->Send_bool (info->use_password);
216  p->Send_uint8 (info->clients_max);
217  p->Send_uint8 (info->clients_on);
218  p->Send_uint8 (info->spectators_on);
219  p->Send_string(info->map_name);
220  p->Send_uint16(info->map_width);
221  p->Send_uint16(info->map_height);
222  p->Send_uint8 (info->map_set);
223  p->Send_bool (info->dedicated);
224 }
225 
232 {
233  static const Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11
234 
235  info->game_info_version = p->Recv_uint8();
236 
237  /*
238  * Please observe the order.
239  * The parts must be read in the same order as they are sent!
240  */
241 
242  /* Update the documentation in game_info.h on changes
243  * to the NetworkGameInfo wire-protocol! */
244 
245  switch (info->game_info_version) {
246  case 4: {
247  GRFConfig **dst = &info->grfconfig;
248  uint i;
249  uint num_grfs = p->Recv_uint8();
250 
251  /* Broken/bad data. It cannot have that many NewGRFs. */
252  if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
253 
254  for (i = 0; i < num_grfs; i++) {
255  GRFConfig *c = new GRFConfig();
258 
259  /* Append GRFConfig to the list */
260  *dst = c;
261  dst = &c->next;
262  }
263  FALLTHROUGH;
264  }
265 
266  case 3:
267  info->game_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
268  info->start_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
269  FALLTHROUGH;
270 
271  case 2:
272  info->companies_max = p->Recv_uint8 ();
273  info->companies_on = p->Recv_uint8 ();
274  info->spectators_max = p->Recv_uint8 ();
275  FALLTHROUGH;
276 
277  case 1:
278  p->Recv_string(info->server_name, sizeof(info->server_name));
279  p->Recv_string(info->server_revision, sizeof(info->server_revision));
280  info->server_lang = p->Recv_uint8 ();
281  info->use_password = p->Recv_bool ();
282  info->clients_max = p->Recv_uint8 ();
283  info->clients_on = p->Recv_uint8 ();
284  info->spectators_on = p->Recv_uint8 ();
285  if (info->game_info_version < 3) { // 16 bits dates got scrapped and are read earlier
288  }
289  p->Recv_string(info->map_name, sizeof(info->map_name));
290  info->map_width = p->Recv_uint16();
291  info->map_height = p->Recv_uint16();
292  info->map_set = p->Recv_uint8 ();
293  info->dedicated = p->Recv_bool ();
294 
295  if (info->server_lang >= NETWORK_NUM_LANGUAGES) info->server_lang = 0;
296  if (info->map_set >= NETWORK_NUM_LANDSCAPES) info->map_set = 0;
297  }
298 }
299 
306 {
307  uint j;
308  p->Send_uint32(grf->grfid);
309  for (j = 0; j < sizeof(grf->md5sum); j++) {
310  p->Send_uint8(grf->md5sum[j]);
311  }
312 }
313 
320 {
321  uint j;
322  grf->grfid = p->Recv_uint32();
323  for (j = 0; j < sizeof(grf->md5sum); j++) {
324  grf->md5sum[j] = p->Recv_uint8();
325  }
326 }
NetworkGameInfo
The game information that is sent from the server to the clients.
Definition: game_info.h:71
GRFConfig::info
GRFTextWrapper info
NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
Definition: newgrf_config.h:161
GITHASH_SUFFIX_LEN
static const uint GITHASH_SUFFIX_LEN
How many hex digits of the git hash to include in network revision string.
Definition: game_info.cpp:33
Packet::Recv_string
void Recv_string(char *buffer, size_t size, StringValidationSettings settings=SVS_REPLACE_WITH_QUESTION_MARK)
Reads a string till it finds a '\0' in the stream.
Definition: packet.cpp:286
NetworkSettings::max_spectators
uint8 max_spectators
maximum amount of spectators
Definition: settings_type.h:280
SerializeGRFIdentifier
void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf)
Serializes the GRFIdentifier (GRF ID and MD5 checksum) to the packet.
Definition: game_info.cpp:305
FindGRFConfig
const GRFConfig * FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 *md5sum, uint32 desired_version)
Find a NewGRF in the scanned list.
Definition: newgrf_config.cpp:738
NetworkGameInfo::companies_max
byte companies_max
Max companies allowed on server.
Definition: game_info.h:88
DeserializeNetworkGameInfo
void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info)
Deserializes the NetworkGameInfo struct from the packet.
Definition: game_info.cpp:231
GameCreationSettings::landscape
byte landscape
the landscape we're currently in
Definition: settings_type.h:308
NetworkSettings::max_clients
uint8 max_clients
maximum amount of clients
Definition: settings_type.h:279
NetworkSettings::server_lang
uint8 server_lang
language of the server
Definition: settings_type.h:283
NETWORK_NUM_LANDSCAPES
static const uint NETWORK_NUM_LANDSCAPES
The number of landscapes in OpenTTD.
Definition: config.h:70
DeserializeGRFIdentifier
void DeserializeGRFIdentifier(Packet *p, GRFIdentifier *grf)
Deserializes the GRFIdentifier (GRF ID and MD5 checksum) from the packet.
Definition: game_info.cpp:319
NETWORK_NUM_LANGUAGES
static const uint NETWORK_NUM_LANGUAGES
Number of known languages (to the network protocol) + 1 for 'any'.
Definition: config.h:60
NetworkServerGameInfo::map_name
char map_name[NETWORK_NAME_LENGTH]
Map which is played ["random" for a randomized map].
Definition: game_info.h:64
HasBit
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Definition: bitmath_func.hpp:103
NetworkGameInfo::use_password
bool use_password
Is this server passworded?
Definition: game_info.h:83
NetworkServerGameInfo
The game information that is not generated on-the-fly and has to be sent to the clients.
Definition: game_info.h:63
GCS_NOT_FOUND
@ GCS_NOT_FOUND
GRF file was not found in the local cache.
Definition: newgrf_config.h:37
NetworkGameInfo::game_info_version
byte game_info_version
Version of the game info.
Definition: game_info.h:84
GRFConfig::ident
GRFIdentifier ident
grfid and md5sum to uniquely identify newgrfs
Definition: newgrf_config.h:157
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:79
GCF_COPY
@ GCF_COPY
The data is copied from a grf in _all_grfs.
Definition: newgrf_config.h:27
GRFConfig::status
GRFStatus status
NOSAVE: GRFStatus, enum.
Definition: newgrf_config.h:168
NetworkGameInfo::map_width
uint16 map_width
Map width.
Definition: game_info.h:75
_network_game_info
NetworkServerGameInfo _network_game_info
Information about our game.
Definition: game_info.cpp:35
Packet::Send_uint8
void Send_uint8(uint8 data)
Package a 8 bits integer in the packet.
Definition: packet.cpp:96
GRFIdentifier::md5sum
uint8 md5sum[16]
MD5 checksum of file to distinguish files with the same GRF ID (eg. newer version of GRF)
Definition: newgrf_config.h:85
GRFIdentifier::grfid
uint32 grfid
GRF ID (defined by Action 0x08)
Definition: newgrf_config.h:84
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition: settings_type.h:564
Packet::Send_uint32
void Send_uint32(uint32 data)
Package a 32 bits integer in the packet.
Definition: packet.cpp:117
MapSizeX
static uint MapSizeX()
Get the size of the map along the X.
Definition: map_func.h:72
NETWORK_MAX_GRF_COUNT
static const uint NETWORK_MAX_GRF_COUNT
Maximum number of GRFs that can be sent.
Definition: config.h:58
GRFIdentifier
Basic data to distinguish a GRF.
Definition: newgrf_config.h:83
FillNetworkGameInfo
void FillNetworkGameInfo(NetworkGameInfo &ngi)
Fill a NetworkGameInfo structure with the latest information of the server.
Definition: game_info.cpp:113
NetworkGameInfo::start_date
Date start_date
When the game started.
Definition: game_info.h:73
NetworkGameInfo::server_lang
byte server_lang
Language of the server (we should make a nice table for this)
Definition: game_info.h:85
Packet::Recv_uint32
uint32 Recv_uint32()
Read a 32 bits integer from the packet.
Definition: packet.cpp:246
NetworkSettings::server_password
char server_password[NETWORK_PASSWORD_LENGTH]
password for joining this server
Definition: settings_type.h:266
_date
Date _date
Current date in days (day counter)
Definition: date.cpp:28
IsNetworkCompatibleVersion
bool IsNetworkCompatibleVersion(const char *other)
Checks whether the given version string is compatible with our version.
Definition: game_info.cpp:95
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition: newgrf_config.h:152
NetworkGameInfo::companies_on
byte companies_on
How many started companies do we have.
Definition: game_info.h:87
DEBUG
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:35
Packet::Send_string
void Send_string(const char *data)
Sends a string over the network.
Definition: packet.cpp:148
GRFConfig::flags
uint8 flags
NOSAVE: GCF_Flags, bitset.
Definition: newgrf_config.h:167
ConvertYMDToDate
Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
Definition: date.cpp:149
Date
int32 Date
The type to store our dates in.
Definition: date_type.h:14
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:80
HandleIncomingNetworkGameInfoGRFConfig
static void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config)
Function that is called for every GRFConfig that is read when receiving a NetworkGameInfo.
Definition: game_info.cpp:145
Packet::Send_uint16
void Send_uint16(uint16 data)
Package a 16 bits integer in the packet.
Definition: packet.cpp:106
StrEmpty
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:60
MapSizeY
static uint MapSizeY()
Get the size of the map along the Y.
Definition: map_func.h:82
NetworkSettings::server_name
char server_name[NETWORK_NAME_LENGTH]
name of the server
Definition: settings_type.h:265
_network_dedicated
bool _network_dedicated
are we a dedicated server?
Definition: network.cpp:55
Packet
Internal entity of a packet.
Definition: packet.h:40
NetworkGameInfo::server_name
char server_name[NETWORK_NAME_LENGTH]
Server name.
Definition: game_info.h:77
NETWORK_REVISION_LENGTH
static const uint NETWORK_REVISION_LENGTH
The maximum length of the revision, in bytes including '\0'.
Definition: config.h:44
Packet::Send_bool
void Send_bool(bool data)
Package a boolean in the packet.
Definition: packet.cpp:87
Clamp
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:77
GRFConfig::name
GRFTextWrapper name
NOSAVE: GRF name (Action 0x08)
Definition: newgrf_config.h:160
NetworkGameInfo::clients_max
byte clients_max
Max clients allowed on server.
Definition: game_info.h:86
Pool::PoolItem<&_company_pool >::GetNumItems
static size_t GetNumItems()
Returns number of valid items in the pool.
Definition: pool_type.hpp:359
Packet::Recv_bool
bool Recv_bool()
Read a boolean from the packet.
Definition: packet.cpp:208
packet.h
GRFConfig::next
struct GRFConfig * next
NOSAVE: Next item in the linked list.
Definition: newgrf_config.h:177
game_info.h
GameCreationSettings::starting_year
Year starting_year
starting date
Definition: settings_type.h:293
GRFConfig::url
GRFTextWrapper url
NOSAVE: URL belonging to this GRF.
Definition: newgrf_config.h:162
Packet::Recv_uint8
uint8 Recv_uint8()
Read a 8 bits integer from the packet.
Definition: packet.cpp:217
GetNetworkRevisionString
const char * GetNetworkRevisionString()
Get the network version string used by this build.
Definition: game_info.cpp:41
SerializeNetworkGameInfo
void SerializeNetworkGameInfo(Packet *p, const NetworkGameInfo *info)
Serializes the NetworkGameInfo struct to the packet.
Definition: game_info.cpp:169
NetworkGameInfo::game_date
Date game_date
Current date.
Definition: game_info.h:74
stredup
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Definition: string.cpp:137
_grfconfig
GRFConfig * _grfconfig
First item in list of current GRF set up.
Definition: newgrf_config.cpp:171
ExtractNetworkRevisionHash
static const char * ExtractNetworkRevisionHash(const char *revstr)
Extract the git hash from the revision string.
Definition: game_info.cpp:85
SetBit
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
Definition: bitmath_func.hpp:121
NetworkGameInfo::server_revision
char server_revision[NETWORK_REVISION_LENGTH]
The version number the server is using (e.g.: 'r304' or 0.5.0)
Definition: game_info.h:79
ClientSettings::network
NetworkSettings network
settings related to the network
Definition: settings_type.h:582
NetworkGameInfo::spectators_on
byte spectators_on
How many spectators do we have?
Definition: game_info.h:89
FGCM_EXACT
@ FGCM_EXACT
Only find Grfs matching md5sum.
Definition: newgrf_config.h:193
NETWORK_GAME_INFO_VERSION
static const byte NETWORK_GAME_INFO_VERSION
What version of game-info do we use?
Definition: config.h:36
GRFConfig::filename
char * filename
Filename - either with or without full path.
Definition: newgrf_config.h:159
NetworkGameInfo::map_height
uint16 map_height
Map height.
Definition: game_info.h:76
NetworkServerGameInfo::clients_on
byte clients_on
Current count of clients on server.
Definition: game_info.h:65
FindUnknownGRFName
GRFTextWrapper FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create)
Finds the name of a NewGRF in the list of names for unknown GRFs.
Definition: newgrf_config.cpp:785
strecpy
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
Definition: string.cpp:112
NetworkGameInfo::grfconfig
GRFConfig * grfconfig
List of NewGRF files used.
Definition: game_info.h:72
lastof
#define lastof(x)
Get the last element of an fixed size array.
Definition: stdafx.h:385
GCF_STATIC
@ GCF_STATIC
GRF file is used statically (can be used in any MP game)
Definition: newgrf_config.h:25
NetworkGameInfo::dedicated
bool dedicated
Is this a dedicated server?
Definition: game_info.h:80
Packet::Recv_uint16
uint16 Recv_uint16()
Read a 16 bits integer from the packet.
Definition: packet.cpp:231
DAYS_TILL_ORIGINAL_BASE_YEAR
#define DAYS_TILL_ORIGINAL_BASE_YEAR
The offset in days from the '_date == 0' till 'ConvertYMDToDate(ORIGINAL_BASE_YEAR,...
Definition: date_type.h:80
NetworkGameInfo::spectators_max
byte spectators_max
Max spectators allowed on server.
Definition: game_info.h:90
NetworkSettings::max_companies
uint8 max_companies
maximum amount of companies
Definition: settings_type.h:278
MAX_YEAR
static const Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date,...
Definition: date_type.h:94
NetworkGameInfo::map_set
byte map_set
Graphical set.
Definition: game_info.h:91