|
|
/*
|
|
|
* 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.cpp Functions to convert NetworkGameInfo to Packet and back.
|
|
|
*/
|
|
|
|
|
|
#include "../../stdafx.h"
|
|
|
#include "game_info.h"
|
|
|
#include "../../core/bitmath_func.hpp"
|
|
|
#include "../../company_base.h"
|
|
|
#include "../../date_func.h"
|
|
|
#include "../../debug.h"
|
|
|
#include "../../map_func.h"
|
|
|
#include "../../game/game.hpp"
|
|
|
#include "../../game/game_info.hpp"
|
|
|
#include "../../settings_type.h"
|
|
|
#include "../../string_func.h"
|
|
|
#include "../../rev.h"
|
|
|
#include "../network_func.h"
|
|
|
#include "../network.h"
|
|
|
#include "packet.h"
|
|
|
|
|
|
#include "../../safeguards.h"
|
|
|
|
|
|
|
|
|
/**
|
|
|
* How many hex digits of the git hash to include in network revision string.
|
|
|
* Determined as 10 hex digits + 2 characters for -g/-u/-m prefix.
|
|
|
*/
|
|
|
static const uint GITHASH_SUFFIX_LEN = 12;
|
|
|
|
|
|
NetworkServerGameInfo _network_game_info; ///< Information about our game.
|
|
|
|
|
|
/**
|
|
|
* Get the network version string used by this build.
|
|
|
* The returned string is guaranteed to be at most NETWORK_REVISON_LENGTH bytes including '\0' terminator.
|
|
|
*/
|
|
|
std::string_view GetNetworkRevisionString()
|
|
|
{
|
|
@@ -174,48 +176,53 @@ static void HandleIncomingNetworkGameInf
|
|
|
config->name = f->name;
|
|
|
config->info = f->info;
|
|
|
config->url = f->url;
|
|
|
}
|
|
|
SetBit(config->flags, GCF_COPY);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Serializes the NetworkGameInfo struct to the packet.
|
|
|
* @param p the packet to write the data to.
|
|
|
* @param info the NetworkGameInfo struct to serialize from.
|
|
|
*/
|
|
|
void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info)
|
|
|
{
|
|
|
p->Send_uint8 (NETWORK_GAME_INFO_VERSION);
|
|
|
|
|
|
/*
|
|
|
* Please observe the order.
|
|
|
* The parts must be read in the same order as they are sent!
|
|
|
*/
|
|
|
|
|
|
/* Update the documentation in game_info.h on changes
|
|
|
* to the NetworkGameInfo wire-protocol! */
|
|
|
|
|
|
/* NETWORK_GAME_INFO_VERSION = 5 */
|
|
|
GameInfo *game_info = Game::GetInfo();
|
|
|
p->Send_uint32(game_info == nullptr ? -1 : (uint32)game_info->GetVersion());
|
|
|
p->Send_string(game_info == nullptr ? "" : game_info->GetName());
|
|
|
|
|
|
/* NETWORK_GAME_INFO_VERSION = 4 */
|
|
|
{
|
|
|
/* Only send the GRF Identification (GRF_ID and MD5 checksum) of
|
|
|
* the GRFs that are needed, i.e. the ones that the server has
|
|
|
* selected in the NewGRF GUI and not the ones that are used due
|
|
|
* to the fact that they are in [newgrf-static] in openttd.cfg */
|
|
|
const GRFConfig *c;
|
|
|
uint count = 0;
|
|
|
|
|
|
/* Count number of GRFs to send information about */
|
|
|
for (c = info->grfconfig; c != nullptr; c = c->next) {
|
|
|
if (!HasBit(c->flags, GCF_STATIC)) count++;
|
|
|
}
|
|
|
p->Send_uint8 (count); // Send number of GRFs
|
|
|
|
|
|
/* Send actual GRF Identifications */
|
|
|
for (c = info->grfconfig; c != nullptr; c = c->next) {
|
|
|
if (!HasBit(c->flags, GCF_STATIC)) SerializeGRFIdentifier(p, &c->ident);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* NETWORK_GAME_INFO_VERSION = 3 */
|
|
|
p->Send_uint32(info->game_date);
|
|
|
p->Send_uint32(info->start_date);
|
|
@@ -239,48 +246,54 @@ void SerializeNetworkGameInfo(Packet *p,
|
|
|
p->Send_uint8 (info->landscape);
|
|
|
p->Send_bool (info->dedicated);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Deserializes the NetworkGameInfo struct from the packet.
|
|
|
* @param p the packet to read the data from.
|
|
|
* @param info the NetworkGameInfo to deserialize into.
|
|
|
*/
|
|
|
void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info)
|
|
|
{
|
|
|
static const Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11
|
|
|
|
|
|
byte game_info_version = p->Recv_uint8();
|
|
|
|
|
|
/*
|
|
|
* Please observe the order.
|
|
|
* The parts must be read in the same order as they are sent!
|
|
|
*/
|
|
|
|
|
|
/* Update the documentation in game_info.h on changes
|
|
|
* to the NetworkGameInfo wire-protocol! */
|
|
|
|
|
|
switch (game_info_version) {
|
|
|
case 5: {
|
|
|
info->gamescript_version = (int)p->Recv_uint32();
|
|
|
info->gamescript_name = p->Recv_string(NETWORK_NAME_LENGTH);
|
|
|
FALLTHROUGH;
|
|
|
}
|
|
|
|
|
|
case 4: {
|
|
|
GRFConfig **dst = &info->grfconfig;
|
|
|
uint i;
|
|
|
uint num_grfs = p->Recv_uint8();
|
|
|
|
|
|
/* Broken/bad data. It cannot have that many NewGRFs. */
|
|
|
if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
|
|
|
|
|
|
for (i = 0; i < num_grfs; i++) {
|
|
|
GRFConfig *c = new GRFConfig();
|
|
|
DeserializeGRFIdentifier(p, &c->ident);
|
|
|
HandleIncomingNetworkGameInfoGRFConfig(c);
|
|
|
|
|
|
/* Append GRFConfig to the list */
|
|
|
*dst = c;
|
|
|
dst = &c->next;
|
|
|
}
|
|
|
FALLTHROUGH;
|
|
|
}
|
|
|
|
|
|
case 3:
|
|
|
info->game_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
|
|
|
info->start_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
|
|
|
FALLTHROUGH;
|