Merge tag '12.0-beta1' into jgrpp-beta
# Conflicts: # CMakeLists.txt # bin/ai/CMakeLists.txt # bin/game/CMakeLists.txt # src/build_vehicle_gui.cpp # src/console_cmds.cpp # src/core/overflowsafe_type.hpp # src/fios.cpp # src/lang/english.txt # src/lang/german.txt # src/lang/korean.txt # src/lang/polish.txt # src/network/core/game_info.cpp # src/network/core/game_info.h # src/network/core/tcp_game.cpp # src/network/core/tcp_game.h # src/network/network.cpp # src/network/network_client.cpp # src/network/network_client.h # src/network/network_coordinator.cpp # src/network/network_gui.cpp # src/network/network_server.cpp # src/network/network_server.h # src/newgrf_engine.cpp # src/openttd.cpp # src/rev.cpp.in # src/settings_type.h # src/train.h # src/train_cmd.cpp
This commit is contained in:
@@ -140,8 +140,8 @@ void ClientNetworkEmergencySave()
|
||||
if (!_networking) return;
|
||||
if (!ClientNetworkGameSocketHandler::EmergencySavePossible()) return;
|
||||
|
||||
static int _netsave_ctr = 0;
|
||||
DoAutoOrNetsave(_netsave_ctr, true);
|
||||
static FiosNumberedSaveName _netsave_ctr("netsave");
|
||||
DoAutoOrNetsave(_netsave_ctr, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -180,29 +180,24 @@ ClientNetworkGameSocketHandler::~ClientNetworkGameSocketHandler()
|
||||
NetworkRecvStatus ClientNetworkGameSocketHandler::CloseConnection(NetworkRecvStatus status)
|
||||
{
|
||||
assert(status != NETWORK_RECV_STATUS_OKAY);
|
||||
/*
|
||||
* Sending a message just before leaving the game calls cs->SendPackets.
|
||||
* This might invoke this function, which means that when we close the
|
||||
* connection after cs->SendPackets we will close an already closed
|
||||
* connection. This handles that case gracefully without having to make
|
||||
* that code any more complex or more aware of the validity of the socket.
|
||||
*/
|
||||
if (this->sock == INVALID_SOCKET) return status;
|
||||
assert(this->sock != INVALID_SOCKET);
|
||||
if (this->status == STATUS_CLOSING) return status;
|
||||
|
||||
DEBUG(net, 3, "Shutting down client connection %d", this->client_id);
|
||||
if (!this->HasClientQuit()) {
|
||||
DEBUG(net, 3, "Closed client connection %d", this->client_id);
|
||||
|
||||
SetBlocking(this->sock);
|
||||
SetBlocking(this->sock);
|
||||
|
||||
this->SendPackets(true);
|
||||
this->SendPackets(true);
|
||||
|
||||
ShutdownSocket(this->sock, false, true, 2);
|
||||
ShutdownSocket(this->sock, false, true, 2);
|
||||
|
||||
/* Wait a number of ticks so our leave message can reach the server.
|
||||
* This is especially needed for Windows servers as they seem to get
|
||||
* the "socket is closed" message before receiving our leave message,
|
||||
* which would trigger the server to close the connection as well. */
|
||||
CSleep(3 * MILLISECONDS_PER_TICK);
|
||||
/* Wait a number of ticks so our leave message can reach the server.
|
||||
* This is especially needed for Windows servers as they seem to get
|
||||
* the "socket is closed" message before receiving our leave message,
|
||||
* which would trigger the server to close the connection as well. */
|
||||
CSleep(3 * MILLISECONDS_PER_TICK);
|
||||
}
|
||||
|
||||
DEBUG(net, 1, "Shutdown client connection %d", this->client_id);
|
||||
|
||||
@@ -291,7 +286,7 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
|
||||
/* static */ void ClientNetworkGameSocketHandler::Send()
|
||||
{
|
||||
my_client->SendPackets();
|
||||
my_client->CheckConnection();
|
||||
if (my_client != nullptr) my_client->CheckConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -385,8 +380,8 @@ static std::string _password_server_id;
|
||||
|
||||
/** Maximum number of companies of the currently joined server. */
|
||||
static uint8 _network_server_max_companies;
|
||||
/** Maximum number of spectators of the currently joined server. */
|
||||
static uint8 _network_server_max_spectators;
|
||||
/** The current name of the server you are on. */
|
||||
std::string _network_server_name;
|
||||
|
||||
/** Information about the game to join to. */
|
||||
NetworkJoinInfo _network_join;
|
||||
@@ -402,7 +397,7 @@ static_assert(NETWORK_SERVER_ID_LENGTH == 16 * 2 + 1);
|
||||
/**
|
||||
* Query the server for server information.
|
||||
*/
|
||||
NetworkRecvStatus ClientNetworkGameSocketHandler::SendInformationQuery(bool request_company_info)
|
||||
NetworkRecvStatus ClientNetworkGameSocketHandler::SendInformationQuery()
|
||||
{
|
||||
my_client->status = STATUS_GAME_INFO;
|
||||
|
||||
@@ -413,14 +408,6 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendInformationQuery(bool requ
|
||||
p->Send_uint16(0); // version
|
||||
my_client->SendPacket(p);
|
||||
|
||||
if (request_company_info) {
|
||||
my_client->status = STATUS_COMPANY_INFO;
|
||||
_network_join_status = NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO;
|
||||
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
|
||||
|
||||
my_client->SendPacket(new Packet(PACKET_CLIENT_COMPANY_INFO));
|
||||
}
|
||||
|
||||
return NETWORK_RECV_STATUS_OKAY;
|
||||
}
|
||||
|
||||
@@ -696,13 +683,9 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_BANNED(Packet *
|
||||
|
||||
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_GAME_INFO(Packet *p)
|
||||
{
|
||||
if (this->status != STATUS_COMPANY_INFO && this->status != STATUS_GAME_INFO) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
|
||||
if (this->status != STATUS_GAME_INFO) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
|
||||
|
||||
NetworkGameList *item = GetLobbyGameInfo();
|
||||
if (item == nullptr) {
|
||||
/* This is not the lobby, so add it to the game list. */
|
||||
item = NetworkGameListAddItem(this->connection_string);
|
||||
}
|
||||
NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
|
||||
|
||||
/* Clear any existing GRFConfig chain. */
|
||||
ClearGRFConfigList(&item->info.grfconfig);
|
||||
@@ -713,20 +696,16 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_GAME_INFO(Packe
|
||||
/* Ensure we consider the server online. */
|
||||
item->online = true;
|
||||
|
||||
/* It could be either window, but only one is open, so redraw both. */
|
||||
UpdateNetworkGameWindow();
|
||||
SetWindowDirty(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_LOBBY);
|
||||
|
||||
/* We will receive company info next, so keep connection open. */
|
||||
if (this->status == STATUS_COMPANY_INFO) return NETWORK_RECV_STATUS_OKAY;
|
||||
return NETWORK_RECV_STATUS_CLOSE_QUERY;
|
||||
}
|
||||
|
||||
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_GAME_INFO_EXTENDED(Packet *p)
|
||||
{
|
||||
if (this->status != STATUS_COMPANY_INFO && this->status != STATUS_INACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
|
||||
if (this->status != STATUS_GAME_INFO) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
|
||||
|
||||
NetworkGameList *item = GetLobbyGameInfo();
|
||||
NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
|
||||
|
||||
/* Clear any existing GRFConfig chain. */
|
||||
ClearGRFConfigList(&item->info.grfconfig);
|
||||
@@ -737,50 +716,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_GAME_INFO_EXTEN
|
||||
/* Ensure we consider the server online. */
|
||||
item->online = true;
|
||||
|
||||
SetWindowDirty(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_LOBBY);
|
||||
|
||||
/* We will receive company info next, so keep connection open. */
|
||||
if (this->status == STATUS_COMPANY_INFO) return NETWORK_RECV_STATUS_OKAY;
|
||||
return NETWORK_RECV_STATUS_CLOSE_QUERY;
|
||||
}
|
||||
|
||||
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_COMPANY_INFO(Packet *p)
|
||||
{
|
||||
if (this->status != STATUS_COMPANY_INFO) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
|
||||
|
||||
byte company_info_version = p->Recv_uint8();
|
||||
|
||||
if (!this->HasClientQuit() && company_info_version == NETWORK_COMPANY_INFO_VERSION) {
|
||||
/* We have received all data... (there are no more packets coming) */
|
||||
if (!p->Recv_bool()) return NETWORK_RECV_STATUS_CLOSE_QUERY;
|
||||
|
||||
CompanyID current = (Owner)p->Recv_uint8();
|
||||
if (current >= MAX_COMPANIES) return NETWORK_RECV_STATUS_CLOSE_QUERY;
|
||||
|
||||
NetworkCompanyInfo *company_info = GetLobbyCompanyInfo(current);
|
||||
if (company_info == nullptr) return NETWORK_RECV_STATUS_CLOSE_QUERY;
|
||||
|
||||
company_info->company_name = p->Recv_string(NETWORK_COMPANY_NAME_LENGTH);
|
||||
company_info->inaugurated_year = p->Recv_uint32();
|
||||
company_info->company_value = p->Recv_uint64();
|
||||
company_info->money = p->Recv_uint64();
|
||||
company_info->income = p->Recv_uint64();
|
||||
company_info->performance = p->Recv_uint16();
|
||||
company_info->use_password = p->Recv_bool();
|
||||
for (uint i = 0; i < NETWORK_VEH_END; i++) {
|
||||
company_info->num_vehicle[i] = p->Recv_uint16();
|
||||
}
|
||||
for (uint i = 0; i < NETWORK_VEH_END; i++) {
|
||||
company_info->num_station[i] = p->Recv_uint16();
|
||||
}
|
||||
company_info->ai = p->Recv_bool();
|
||||
|
||||
company_info->clients = p->Recv_string(NETWORK_CLIENTS_LENGTH);
|
||||
|
||||
SetWindowDirty(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_LOBBY);
|
||||
|
||||
return NETWORK_RECV_STATUS_OKAY;
|
||||
}
|
||||
UpdateNetworkGameWindow();
|
||||
|
||||
return NETWORK_RECV_STATUS_CLOSE_QUERY;
|
||||
}
|
||||
@@ -877,7 +813,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p
|
||||
* NETWORK_ERROR_NOT_EXPECTED on requesting the game info. Show a special
|
||||
* error popup in that case.
|
||||
*/
|
||||
if (error == NETWORK_ERROR_NOT_EXPECTED && (this->status == STATUS_GAME_INFO || this->status == STATUS_COMPANY_INFO)) {
|
||||
if (error == NETWORK_ERROR_NOT_EXPECTED && this->status == STATUS_GAME_INFO) {
|
||||
ShowErrorMessage(STR_NETWORK_ERROR_SERVER_TOO_OLD, INVALID_STRING_ID, WL_CRITICAL);
|
||||
return NETWORK_RECV_STATUS_CLOSE_QUERY;
|
||||
}
|
||||
@@ -1084,6 +1020,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet
|
||||
/* Say we received the map and loaded it correctly! */
|
||||
SendMapOk();
|
||||
|
||||
ShowClientList();
|
||||
|
||||
/* New company/spectator (invalid company) or company we want to join is not active
|
||||
* Switch local company to spectator and await the server's judgement */
|
||||
if (_network_join.company == COMPANY_NEW_COMPANY || !Company::IsValidID(_network_join.company)) {
|
||||
@@ -1373,7 +1311,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CONFIG_UPDATE(P
|
||||
if (this->status < STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
|
||||
|
||||
_network_server_max_companies = p->Recv_uint8();
|
||||
_network_server_max_spectators = p->Recv_uint8();
|
||||
_network_server_name = p->Recv_string(NETWORK_NAME_LENGTH);
|
||||
|
||||
return NETWORK_RECV_STATUS_OKAY;
|
||||
}
|
||||
@@ -1433,7 +1371,6 @@ const char *ClientNetworkGameSocketHandler::GetServerStatusName(ServerStatus sta
|
||||
static const char* _server_status_names[] {
|
||||
"INACTIVE",
|
||||
"GAME_INFO",
|
||||
"COMPANY_INFO",
|
||||
"JOIN",
|
||||
"NEWGRFS_CHECK",
|
||||
"AUTH_GAME",
|
||||
@@ -1643,12 +1580,3 @@ bool NetworkMaxCompaniesReached()
|
||||
{
|
||||
return Company::GetNumItems() >= (_network_server ? _settings_client.network.max_companies : _network_server_max_companies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if max_spectatos has been reached on the server (local check only).
|
||||
* @return true if the max value has been reached or exceeded, false otherwise.
|
||||
*/
|
||||
bool NetworkMaxSpectatorsReached()
|
||||
{
|
||||
return NetworkSpectatorCount() >= (_network_server ? _settings_client.network.max_spectators : _network_server_max_spectators);
|
||||
}
|
||||
|
Reference in New Issue
Block a user