Merge branch 'master' into jgrpp-beta

# Conflicts:
#	src/network/core/game_info.h
#	src/network/core/udp.cpp
#	src/network/core/udp.h
#	src/network/network.cpp
#	src/network/network_client.cpp
#	src/network/network_client.h
#	src/network/network_internal.h
#	src/network/network_udp.cpp
This commit is contained in:
Jonathan G Rennison
2021-09-17 23:04:54 +01:00
26 changed files with 696 additions and 476 deletions

View File

@@ -13,13 +13,10 @@
#include "../../date_func.h"
#include "../../debug.h"
#include "../../core/random_func.hpp"
#include "../../fios.h"
#include "udp.h"
#include "../../safeguards.h"
extern const uint8 _out_of_band_grf_md5[16];
/**
* Create an UDP socket but don't listen yet.
* @param bind the addresses to bind to.
@@ -186,258 +183,6 @@ void NetworkUDPSocketHandler::ReceivePackets()
}
}
/**
* Serializes the NetworkGameInfo struct to the packet
* @param p the packet to write the data to
* @param info the NetworkGameInfo struct to serialize
*/
void NetworkUDPSocketHandler::SendNetworkGameInfo(Packet *p, const NetworkGameInfo *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 udp.h on changes
* to the NetworkGameInfo wire-protocol! */
/* 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(std::min<uint>(count, NETWORK_MAX_GRF_COUNT)); // Send number of GRFs
/* Send actual GRF Identifications */
uint index = 0;
for (c = info->grfconfig; c != nullptr; c = c->next) {
if (!HasBit(c->flags, GCF_STATIC)) {
if (index == NETWORK_MAX_GRF_COUNT - 1 && count > NETWORK_MAX_GRF_COUNT) {
/* Send fake GRF ID */
p->Send_uint32(0x56D2B000);
p->Send_binary((const char*) _out_of_band_grf_md5, 16);
} else if (index >= NETWORK_MAX_GRF_COUNT) {
break;
} else {
this->SendGRFIdentifier(p, &c->ident);
}
index++;
}
}
}
/* NETWORK_GAME_INFO_VERSION = 3 */
p->Send_uint32(info->game_date);
p->Send_uint32(info->start_date);
/* NETWORK_GAME_INFO_VERSION = 2 */
p->Send_uint8 (info->companies_max);
p->Send_uint8 (info->companies_on);
p->Send_uint8 (info->spectators_max);
/* NETWORK_GAME_INFO_VERSION = 1 */
p->Send_string(info->server_name);
p->Send_string(info->short_server_revision);
p->Send_uint8 (0); // Used to be server-lang.
p->Send_bool (info->use_password);
p->Send_uint8 (info->clients_max);
p->Send_uint8 (info->clients_on);
p->Send_uint8 (info->spectators_on);
p->Send_string(""); // Used to be map-name.
p->Send_uint16(info->map_width);
p->Send_uint16(info->map_height);
p->Send_uint8 (info->map_set);
p->Send_bool (info->dedicated);
}
/**
* Serializes the NetworkGameInfo struct to the packet
* @param p the packet to write the data to
* @param info the NetworkGameInfo struct to serialize
*/
void NetworkUDPSocketHandler::SendNetworkGameInfoExtended(Packet *p, const NetworkGameInfo *info, uint16 flags, uint16 version)
{
p->Send_uint8(0); // version num
p->Send_uint32(info->game_date);
p->Send_uint32(info->start_date);
p->Send_uint8 (info->companies_max);
p->Send_uint8 (info->companies_on);
p->Send_uint8 (info->spectators_max);
p->Send_string(info->server_name);
p->Send_string(info->server_revision);
p->Send_uint8 (0); // Used to be server-lang.
p->Send_bool (info->use_password);
p->Send_uint8 (info->clients_max);
p->Send_uint8 (info->clients_on);
p->Send_uint8 (info->spectators_on);
p->Send_string(""); // Used to be map-name.
p->Send_uint32(info->map_width);
p->Send_uint32(info->map_height);
p->Send_uint8 (info->map_set);
p->Send_bool (info->dedicated);
{
/* 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_uint32(count); // Send number of GRFs
/* Send actual GRF Identifications */
for (c = info->grfconfig; c != nullptr; c = c->next) {
if (!HasBit(c->flags, GCF_STATIC)) {
this->SendGRFIdentifier(p, &c->ident);
}
}
}
}
/**
* Deserializes the NetworkGameInfo struct from the packet
* @param p the packet to read the data from
* @param info the NetworkGameInfo to deserialize into
*/
void NetworkUDPSocketHandler::ReceiveNetworkGameInfo(Packet *p, NetworkGameInfo *info)
{
static const Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11
info->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 udp.h on changes
* to the NetworkGameInfo wire-protocol! */
switch (info->game_info_version) {
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();
this->ReceiveGRFIdentifier(p, &c->ident);
this->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;
case 2:
info->companies_max = p->Recv_uint8 ();
info->companies_on = p->Recv_uint8 ();
info->spectators_max = p->Recv_uint8 ();
FALLTHROUGH;
case 1:
p->Recv_string(info->server_name, sizeof(info->server_name));
p->Recv_string(info->server_revision, sizeof(info->server_revision));
p->Recv_uint8 (); // Used to contain server-lang.
info->use_password = p->Recv_bool ();
info->clients_max = p->Recv_uint8 ();
info->clients_on = p->Recv_uint8 ();
info->spectators_on = p->Recv_uint8 ();
if (info->game_info_version < 3) { // 16 bits dates got scrapped and are read earlier
info->game_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
info->start_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR;
}
while (p->Recv_uint8() != 0) {} // Used to contain the map-name.
info->map_width = p->Recv_uint16();
info->map_height = p->Recv_uint16();
info->map_set = p->Recv_uint8 ();
info->dedicated = p->Recv_bool ();
if (info->map_set >= NETWORK_NUM_LANDSCAPES) info->map_set = 0;
}
}
/**
* Deserializes the NetworkGameInfo struct from the packet
* @param p the packet to read the data from
* @param info the NetworkGameInfo to deserialize into
*/
void NetworkUDPSocketHandler::ReceiveNetworkGameInfoExtended(Packet *p, NetworkGameInfo *info)
{
static const Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11
const uint8 version = p->Recv_uint8();
if (version > 0) return; // Unknown version
info->game_info_version = 255;
info->game_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
info->start_date = Clamp(p->Recv_uint32(), 0, MAX_DATE);
info->companies_max = p->Recv_uint8 ();
info->companies_on = p->Recv_uint8 ();
info->spectators_max = p->Recv_uint8 ();
p->Recv_string(info->server_name, sizeof(info->server_name));
p->Recv_string(info->server_revision, sizeof(info->server_revision));
p->Recv_uint8 (); // Used to contain server-lang.
info->use_password = p->Recv_bool ();
info->clients_max = p->Recv_uint8 ();
info->clients_on = p->Recv_uint8 ();
info->spectators_on = p->Recv_uint8 ();
while (p->Recv_uint8() != 0) {} // Used to contain the map-name.
info->map_width = p->Recv_uint32();
info->map_height = p->Recv_uint32();
info->map_set = p->Recv_uint8 ();
info->dedicated = p->Recv_bool ();
{
GRFConfig **dst = &info->grfconfig;
uint i;
uint num_grfs = p->Recv_uint32();
/* Broken/bad data. It cannot have that many NewGRFs. */
if (num_grfs > MAX_NON_STATIC_GRF_COUNT) return;
for (i = 0; i < num_grfs; i++) {
GRFConfig *c = new GRFConfig();
this->ReceiveGRFIdentifier(p, &c->ident);
this->HandleIncomingNetworkGameInfoGRFConfig(c);
/* Append GRFConfig to the list */
*dst = c;
dst = &c->next;
}
}
if (info->map_set >= NETWORK_NUM_LANDSCAPES) info->map_set = 0;
}
/**
* Handle an incoming packets by sending it to the correct function.
* @param p the received packet