Merge branch 'master' into jgrpp
# Conflicts: # src/network/core/tcp_connect.cpp
This commit is contained in:
@@ -1324,10 +1324,10 @@ protected:
|
||||
static CargoID produced_cargo_filter;
|
||||
|
||||
enum class SorterType : uint8 {
|
||||
IDW_SORT_BY_NAME, ///< Sorter type to sort by name
|
||||
IDW_SORT_BY_TYPE, ///< Sorter type to sort by type
|
||||
IDW_SORT_BY_PRODUCTION, ///< Sorter type to sort by production amount
|
||||
IDW_SORT_BY_TRANSPORTED, ///< Sorter type to sort by transported percentage
|
||||
ByName, ///< Sorter type to sort by name
|
||||
ByType, ///< Sorter type to sort by type
|
||||
ByProduction, ///< Sorter type to sort by production amount
|
||||
ByTransported, ///< Sorter type to sort by transported percentage
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1552,9 +1552,9 @@ protected:
|
||||
}
|
||||
|
||||
switch (static_cast<IndustryDirectoryWindow::SorterType>(this->industries.SortType())) {
|
||||
case IndustryDirectoryWindow::SorterType::IDW_SORT_BY_NAME:
|
||||
case IndustryDirectoryWindow::SorterType::IDW_SORT_BY_TYPE:
|
||||
case IndustryDirectoryWindow::SorterType::IDW_SORT_BY_PRODUCTION:
|
||||
case IndustryDirectoryWindow::SorterType::ByName:
|
||||
case IndustryDirectoryWindow::SorterType::ByType:
|
||||
case IndustryDirectoryWindow::SorterType::ByProduction:
|
||||
/* Sort by descending production, then descending transported */
|
||||
std::sort(cargos.begin(), cargos.end(), [](const CargoInfo &a, const CargoInfo &b) {
|
||||
if (a.production != b.production) return a.production > b.production;
|
||||
@@ -1562,7 +1562,7 @@ protected:
|
||||
});
|
||||
break;
|
||||
|
||||
case IndustryDirectoryWindow::SorterType::IDW_SORT_BY_TRANSPORTED:
|
||||
case IndustryDirectoryWindow::SorterType::ByTransported:
|
||||
/* Sort by descending transported, then descending production */
|
||||
std::sort(cargos.begin(), cargos.end(), [](const CargoInfo &a, const CargoInfo &b) {
|
||||
if (a.transported != b.transported) return a.transported > b.transported;
|
||||
|
@@ -249,6 +249,8 @@ void NetworkTCPSocketHandler::LogSentPacket(const Packet &pkt) {}
|
||||
*/
|
||||
bool NetworkTCPSocketHandler::CanSendReceive()
|
||||
{
|
||||
assert(this->sock != INVALID_SOCKET);
|
||||
|
||||
fd_set read_fd, write_fd;
|
||||
struct timeval tv;
|
||||
|
||||
|
@@ -91,15 +91,15 @@ private:
|
||||
* lock on the game-state.
|
||||
*/
|
||||
enum class Status {
|
||||
INIT, ///< TCPConnecter is created but resolving hasn't started.
|
||||
RESOLVING, ///< The hostname is being resolved (threaded).
|
||||
FAILURE, ///< Resolving failed.
|
||||
CONNECTING, ///< We are currently connecting.
|
||||
CONNECTED, ///< The connection is established.
|
||||
Init, ///< TCPConnecter is created but resolving hasn't started.
|
||||
Resolving, ///< The hostname is being resolved (threaded).
|
||||
Failure, ///< Resolving failed.
|
||||
Connecting, ///< We are currently connecting.
|
||||
Connected, ///< The connection is established.
|
||||
};
|
||||
|
||||
std::thread resolve_thread; ///< Thread used during resolving.
|
||||
std::atomic<Status> status = Status::INIT; ///< The current status of the connecter.
|
||||
std::atomic<Status> status = Status::Init; ///< The current status of the connecter.
|
||||
std::atomic<bool> killed = false; ///< Whether this connecter is marked as killed.
|
||||
|
||||
addrinfo *ai = nullptr; ///< getaddrinfo() allocated linked-list of resolved addresses.
|
||||
|
@@ -52,7 +52,7 @@ TCPServerConnecter::TCPServerConnecter(const std::string &connection_string, uin
|
||||
break;
|
||||
|
||||
case SERVER_ADDRESS_INVITE_CODE:
|
||||
this->status = Status::CONNECTING;
|
||||
this->status = Status::Connecting;
|
||||
_network_coordinator_client.ConnectToServer(this->server_address.connection_string, this);
|
||||
break;
|
||||
|
||||
@@ -254,14 +254,14 @@ void TCPConnecter::Resolve()
|
||||
|
||||
if (error != 0) {
|
||||
DEBUG(net, 0, "Failed to resolve DNS for %s", this->connection_string.c_str());
|
||||
this->status = Status::FAILURE;
|
||||
this->status = Status::Failure;
|
||||
return;
|
||||
}
|
||||
|
||||
this->ai = ai;
|
||||
this->OnResolved(ai);
|
||||
|
||||
this->status = Status::CONNECTING;
|
||||
this->status = Status::Connecting;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,11 +281,11 @@ bool TCPConnecter::CheckActivity()
|
||||
if (this->killed) return true;
|
||||
|
||||
switch (this->status) {
|
||||
case Status::INIT:
|
||||
case Status::Init:
|
||||
/* Start the thread delayed, so the vtable is loaded. This allows classes
|
||||
* to overload functions used by Resolve() (in case threading is disabled). */
|
||||
if (StartNewThread(&this->resolve_thread, "ottd:resolve", &TCPConnecter::ResolveThunk, this)) {
|
||||
this->status = Status::RESOLVING;
|
||||
this->status = Status::Resolving;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -296,18 +296,18 @@ bool TCPConnecter::CheckActivity()
|
||||
* connection. The rest of this function handles exactly that. */
|
||||
break;
|
||||
|
||||
case Status::RESOLVING:
|
||||
case Status::Resolving:
|
||||
/* Wait till Resolve() comes back with an answer (in case it runs threaded). */
|
||||
return false;
|
||||
|
||||
case Status::FAILURE:
|
||||
case Status::Failure:
|
||||
/* Ensure the OnFailure() is called from the game-thread instead of the
|
||||
* resolve-thread, as otherwise we can get into some threading issues. */
|
||||
this->OnFailure();
|
||||
return true;
|
||||
|
||||
case Status::CONNECTING:
|
||||
case Status::CONNECTED:
|
||||
case Status::Connecting:
|
||||
case Status::Connected:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -363,7 +363,10 @@ bool TCPConnecter::CheckActivity()
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check for errors on any of the sockets. */
|
||||
/* If a socket is writeable, it is either in error-state or connected.
|
||||
* Remove all sockets that are in error-state and mark the first that is
|
||||
* not in error-state as the socket we will use for our connection. */
|
||||
SOCKET connected_socket = INVALID_SOCKET;
|
||||
for (auto it = this->sockets.begin(); it != this->sockets.end(); /* nothing */) {
|
||||
NetworkError socket_error = GetSocketError(*it);
|
||||
if (socket_error.HasError()) {
|
||||
@@ -371,34 +374,28 @@ bool TCPConnecter::CheckActivity()
|
||||
closesocket(*it);
|
||||
this->sock_to_address.erase(*it);
|
||||
it = this->sockets.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* In case all sockets had an error, queue a new one. */
|
||||
if (this->sockets.empty()) {
|
||||
if (!this->TryNextAddress()) {
|
||||
/* There were no more addresses to try, so we failed. */
|
||||
this->OnFailure();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* At least one socket is connected. The first one that does is the one
|
||||
* we will be using, and we close all other sockets. */
|
||||
SOCKET connected_socket = INVALID_SOCKET;
|
||||
for (auto it = this->sockets.begin(); it != this->sockets.end(); /* nothing */) {
|
||||
/* No error but writeable means connected. */
|
||||
if (connected_socket == INVALID_SOCKET && FD_ISSET(*it, &write_fd)) {
|
||||
connected_socket = *it;
|
||||
} else {
|
||||
}
|
||||
|
||||
it++;
|
||||
}
|
||||
|
||||
/* All the writable sockets were in error state. So nothing is connected yet. */
|
||||
if (connected_socket == INVALID_SOCKET) return false;
|
||||
|
||||
/* Close all sockets except the one we picked for our connection. */
|
||||
for (auto it = this->sockets.begin(); it != this->sockets.end(); /* nothing */) {
|
||||
if (connected_socket != *it) {
|
||||
closesocket(*it);
|
||||
}
|
||||
this->sock_to_address.erase(*it);
|
||||
it = this->sockets.erase(it);
|
||||
}
|
||||
assert(connected_socket != INVALID_SOCKET);
|
||||
|
||||
DEBUG(net, 3, "Connected to %s", this->connection_string.c_str());
|
||||
if (_debug_net_level >= 5) {
|
||||
@@ -406,7 +403,7 @@ bool TCPConnecter::CheckActivity()
|
||||
}
|
||||
|
||||
this->OnConnect(connected_socket);
|
||||
this->status = Status::CONNECTED;
|
||||
this->status = Status::Connected;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -425,11 +422,11 @@ bool TCPServerConnecter::CheckActivity()
|
||||
case SERVER_ADDRESS_INVITE_CODE:
|
||||
/* Check if a result has come in. */
|
||||
switch (this->status) {
|
||||
case Status::FAILURE:
|
||||
case Status::Failure:
|
||||
this->OnFailure();
|
||||
return true;
|
||||
|
||||
case Status::CONNECTED:
|
||||
case Status::Connected:
|
||||
this->OnConnect(this->socket);
|
||||
return true;
|
||||
|
||||
@@ -451,8 +448,10 @@ bool TCPServerConnecter::CheckActivity()
|
||||
*/
|
||||
void TCPServerConnecter::SetConnected(SOCKET sock)
|
||||
{
|
||||
assert(sock != INVALID_SOCKET);
|
||||
|
||||
this->socket = sock;
|
||||
this->status = Status::CONNECTED;
|
||||
this->status = Status::Connected;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -460,7 +459,7 @@ void TCPServerConnecter::SetConnected(SOCKET sock)
|
||||
*/
|
||||
void TCPServerConnecter::SetFailure()
|
||||
{
|
||||
this->status = Status::FAILURE;
|
||||
this->status = Status::Failure;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -566,6 +566,8 @@ void ClientNetworkCoordinatorSocketHandler::ConnectFailure(const std::string &to
|
||||
*/
|
||||
void ClientNetworkCoordinatorSocketHandler::ConnectSuccess(const std::string &token, SOCKET sock, NetworkAddress &address)
|
||||
{
|
||||
assert(sock != INVALID_SOCKET);
|
||||
|
||||
/* Connecter will destroy itself. */
|
||||
this->game_connecter = nullptr;
|
||||
|
||||
|
@@ -41,7 +41,7 @@ public:
|
||||
{
|
||||
this->handler->connecter = nullptr;
|
||||
|
||||
handler->sock = s;
|
||||
this->handler->sock = s;
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "landscape.h"
|
||||
#include "company_func.h"
|
||||
#include "signs_base.h"
|
||||
#include "signs_func.h"
|
||||
#include "strings_func.h"
|
||||
@@ -62,3 +63,14 @@ void UpdateAllSignVirtCoords()
|
||||
si->UpdateVirtCoord();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current company can rename a given sign.
|
||||
* @param *si The sign in question.
|
||||
* @return true if the sign can be renamed, else false.
|
||||
*/
|
||||
bool CompanyCanRenameSign(const Sign *si)
|
||||
{
|
||||
if (si->owner == OWNER_DEITY && _current_company != OWNER_DEITY && _game_mode != GM_EDITOR) return false;
|
||||
return true;
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@ CommandCost CmdRenameSign(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
{
|
||||
Sign *si = Sign::GetIfValid(p1);
|
||||
if (si == nullptr) return CMD_ERROR;
|
||||
if (si->owner == OWNER_DEITY && _current_company != OWNER_DEITY && _game_mode != GM_EDITOR) return CMD_ERROR;
|
||||
if (!CompanyCanRenameSign(si)) return CMD_ERROR;
|
||||
|
||||
/* Rename the signs when empty, otherwise remove it */
|
||||
if (!StrEmpty(text)) {
|
||||
|
@@ -18,6 +18,7 @@ extern SignID _new_sign_id;
|
||||
|
||||
void UpdateAllSignVirtCoords();
|
||||
void PlaceProc_Sign(TileIndex tile);
|
||||
bool CompanyCanRenameSign(const Sign *si);
|
||||
|
||||
/* signs_gui.cpp */
|
||||
void ShowRenameSignWindow(const Sign *si);
|
||||
|
@@ -565,10 +565,14 @@ static WindowDesc _query_sign_edit_desc(
|
||||
*/
|
||||
void HandleClickOnSign(const Sign *si)
|
||||
{
|
||||
/* If we can't rename the sign, don't even open the rename GUI. */
|
||||
if (!CompanyCanRenameSign(si)) return;
|
||||
|
||||
if (_ctrl_pressed && (si->owner == _local_company || (si->owner == OWNER_DEITY && _game_mode == GM_EDITOR))) {
|
||||
RenameSign(si->index, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
ShowRenameSignWindow(si);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user