summaryrefslogtreecommitdiff
path: root/src/network/core/game_info.h
blob: 95073f6c21825cffd24a73bd8501f6ba56b2d2de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
 * This file is part of OpenTTD.
 * 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.
 * 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.
 * 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/>.
 */

/**
 * @file game_info.h Convert NetworkGameInfo to Packet and back.
 */

#ifndef NETWORK_CORE_GAME_INFO_H
#define NETWORK_CORE_GAME_INFO_H

#include "config.h"
#include "core.h"
#include "../../newgrf_config.h"
#include "../../date_type.h"

#include <unordered_map>

/*
 * NetworkGameInfo has several revisions which we still need to support on the
 * wire. The table below shows the version and size for each field of the
 * serialized NetworkGameInfo.
 *
 * Version: Bytes:  Description:
 *   all      1       the version of this packet's structure
 *
 *   6+       1       type of storage for the NewGRFs below:
 *                      0 = NewGRF ID and MD5 checksum.
 *                          Used as default for version 5 and below, and for
 *                          later game updates to the Game Coordinator.
 *                      1 = NewGRF ID, MD5 checksum and name.
 *                          Used for direct requests and the first game
 *                          update to Game Coordinator.
 *                      2 = Index in NewGRF lookup table.
 *                          Used for sending server listing from the Game
 *                          Coordinator to the clients.
 *
 *   5+       4       version number of the Game Script (-1 is case none is selected).
 *   5+       var     string with the name of the Game Script.
 *
 *   4+       1       number of GRFs attached (n).
 *   4+       n * var identifiers for GRF files. Consists of:
 *                    Note: the 'vN' refers to packet version and 'type'
 *                    refers to the v6+ type of storage for the NewGRFs.
 *                     - 4 byte variable with the GRF ID.
 *                       For v4, v5, and v6+ in case of type 0 and/or type 1.
 *                     - 16 bytes with the MD5 checksum of the GRF.
 *                       For v4, v5, and v6+ in case of type 0 and/or type 1.
 *                     - string with name of NewGRF.
 *                       For v6+ in case of type 1.
 *                     - 4 byte lookup table index.
 *                       For v6+ in case of type 2.
 *
 *   3+       4       current game date in days since 1-1-0 (DMY)
 *   3+       4       game introduction date in days since 1-1-0 (DMY)
 *
 *   2+       1       maximum number of companies allowed on the server
 *   2+       1       number of companies on the server
 *   2+       1       maximum number of spectators allowed on the server
 *
 *   1+       var     string with the name of the server
 *   1+       var     string with the revision of the server
 *   1 - 5    1       the language run on the server
 *                    (0 = any, 1 = English, 2 = German, 3 = French)
 *   1+       1       whether the server uses a password (0 = no, 1 = yes)
 *   1+       1       maximum number of clients allowed on the server
 *   1+       1       number of clients on the server
 *   1+       1       number of spectators on the server
 *   1 & 2    2       current game date in days since 1-1-1920 (DMY)
 *   1 & 2    2       game introduction date in days since 1-1-1920 (DMY)
 *   1 - 5    var     string with the name of the map
 *   1+       2       width of the map in tiles
 *   1+       2       height of the map in tiles
 *   1+       1       type of map:
 *                    (0 = temperate, 1 = arctic, 2 = desert, 3 = toyland)
 *   1+       1       whether the server is dedicated (0 = no, 1 = yes)
 */

/** The different types/ways a NewGRF can be serialized in the GameInfo since version 6. */
enum NewGRFSerializationType {
	NST_GRFID_MD5      = 0, ///< Unique GRF ID and MD5 checksum.
	NST_GRFID_MD5_NAME = 1, ///< Unique GRF ID, MD5 checksum and name.
	NST_LOOKUP_ID      = 2, ///< Unique ID into a lookup table that is sent before.
	NST_END                 ///< The end of the list (period).
};

/**
 * The game information that is sent from the server to the client.
 */
struct NetworkServerGameInfo {
	GRFConfig *grfconfig;        ///< List of NewGRF files used
	Date start_date;             ///< When the game started
	Date game_date;              ///< Current date
	uint16 map_width;            ///< Map width
	uint16 map_height;           ///< Map height
	std::string server_name;     ///< Server name
	std::string server_revision; ///< The version number the server is using (e.g.: 'r304' or 0.5.0)
	bool dedicated;              ///< Is this a dedicated server?
	bool use_password;           ///< Is this server passworded?
	byte clients_on;             ///< Current count of clients on server
	byte clients_max;            ///< Max clients allowed on server
	byte companies_on;           ///< How many started companies do we have
	byte companies_max;          ///< Max companies allowed on server
	byte spectators_on;          ///< How many spectators do we have?
	byte landscape;              ///< The used landscape
	int gamescript_version;      ///< Version of the gamescript.
	std::string gamescript_name; ///< Name of the gamescript.
};

/**
 * The game information that is sent from the server to the clients
 * with extra information only required at the client side.
 */
struct NetworkGameInfo : NetworkServerGameInfo {
	bool version_compatible;                        ///< Can we connect to this server or not? (based on server_revision)
	bool compatible;                                ///< Can we connect to this server or not? (based on server_revision _and_ grf_match
};

/**
 * Container to hold the GRF identifier (GRF ID + MD5 checksum) and the name
 * associated with that NewGRF.
 */
struct NamedGRFIdentifier {
	GRFIdentifier ident; ///< The unique identifier of the NewGRF.
	std::string name;    ///< The name of the NewGRF.
};
/** Lookup table for the GameInfo in case of #NST_LOOKUP_ID. */
typedef std::unordered_map<uint32, NamedGRFIdentifier> GameInfoNewGRFLookupTable;

extern NetworkServerGameInfo _network_game_info;

std::string_view GetNetworkRevisionString();
bool IsNetworkCompatibleVersion(std::string_view other);
void CheckGameCompatibility(NetworkGameInfo &ngi);

void FillStaticNetworkServerGameInfo();
const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo();

void DeserializeGRFIdentifier(Packet *p, GRFIdentifier *grf);
void DeserializeGRFIdentifierWithName(Packet *p, NamedGRFIdentifier *grf);
void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf);

void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfoNewGRFLookupTable *newgrf_lookup_table = nullptr);
void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info, bool send_newgrf_names = true);

#endif /* NETWORK_CORE_GAME_INFO_H */