Add passworded mechanism to change server game settings from client
This commit is contained in:
@@ -1093,9 +1093,6 @@ struct BuildVehicleWindow : Window {
|
|||||||
this->GetWidget<NWidgetStacked>(WID_BV_BUILD_SEL)->SetDisplayedPlane(SZSP_NONE);
|
this->GetWidget<NWidgetStacked>(WID_BV_BUILD_SEL)->SetDisplayedPlane(SZSP_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* disable renaming engines in network games if you are not the server */
|
|
||||||
this->SetWidgetDisabledState(WID_BV_RENAME, _networking && !_network_server);
|
|
||||||
|
|
||||||
NWidgetCore *widget = this->GetWidget<NWidgetCore>(WID_BV_LIST);
|
NWidgetCore *widget = this->GetWidget<NWidgetCore>(WID_BV_LIST);
|
||||||
widget->tool_tip = STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP + type;
|
widget->tool_tip = STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP + type;
|
||||||
|
|
||||||
@@ -1564,6 +1561,9 @@ struct BuildVehicleWindow : Window {
|
|||||||
|
|
||||||
this->SetWidgetsDisabledState(this->sel_engine == INVALID_ENGINE, WID_BV_SHOW_HIDE, WID_BV_BUILD, WID_BV_RENAME, WIDGET_LIST_END);
|
this->SetWidgetsDisabledState(this->sel_engine == INVALID_ENGINE, WID_BV_SHOW_HIDE, WID_BV_BUILD, WID_BV_RENAME, WIDGET_LIST_END);
|
||||||
|
|
||||||
|
/* disable renaming engines in network games if you are not the server */
|
||||||
|
this->SetWidgetDisabledState(WID_BV_RENAME, _networking && !(_network_server || _network_settings_access));
|
||||||
|
|
||||||
this->DrawWidgets();
|
this->DrawWidgets();
|
||||||
|
|
||||||
if (!this->IsShaded()) {
|
if (!this->IsShaded()) {
|
||||||
|
@@ -703,6 +703,21 @@ DEF_CONSOLE_CMD(ConRcon)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEF_CONSOLE_CMD(ConSettingsAccess)
|
||||||
|
{
|
||||||
|
if (argc == 0) {
|
||||||
|
IConsoleHelp("Enable changing game settings from this client. Usage: 'settings_access <password>'");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc < 2) return false;
|
||||||
|
|
||||||
|
if (!_network_server) {
|
||||||
|
NetworkClientSendSettingsPassword(argv[1]);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
DEF_CONSOLE_CMD(ConStatus)
|
DEF_CONSOLE_CMD(ConStatus)
|
||||||
{
|
{
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
@@ -2356,6 +2371,7 @@ void IConsoleStdLibRegister()
|
|||||||
IConsoleAliasRegister("info", "server_info");
|
IConsoleAliasRegister("info", "server_info");
|
||||||
IConsoleCmdRegister("reconnect", ConNetworkReconnect, ConHookClientOnly);
|
IConsoleCmdRegister("reconnect", ConNetworkReconnect, ConHookClientOnly);
|
||||||
IConsoleCmdRegister("rcon", ConRcon, ConHookNeedNetwork);
|
IConsoleCmdRegister("rcon", ConRcon, ConHookNeedNetwork);
|
||||||
|
IConsoleCmdRegister("settings_access", ConSettingsAccess, ConHookNeedNetwork);
|
||||||
|
|
||||||
IConsoleCmdRegister("join", ConJoinCompany, ConHookNeedNetwork);
|
IConsoleCmdRegister("join", ConJoinCompany, ConHookNeedNetwork);
|
||||||
IConsoleAliasRegister("spectate", "join 255");
|
IConsoleAliasRegister("spectate", "join 255");
|
||||||
@@ -2380,6 +2396,8 @@ void IConsoleStdLibRegister()
|
|||||||
IConsoleAliasRegister("server_password", "setting server_password %+");
|
IConsoleAliasRegister("server_password", "setting server_password %+");
|
||||||
IConsoleAliasRegister("rcon_pw", "setting rcon_password %+");
|
IConsoleAliasRegister("rcon_pw", "setting rcon_password %+");
|
||||||
IConsoleAliasRegister("rcon_password", "setting rcon_password %+");
|
IConsoleAliasRegister("rcon_password", "setting rcon_password %+");
|
||||||
|
IConsoleAliasRegister("settings_pw", "setting settings_password %+");
|
||||||
|
IConsoleAliasRegister("settings_password", "setting settings_password %+");
|
||||||
IConsoleAliasRegister("name", "setting client_name %+");
|
IConsoleAliasRegister("name", "setting client_name %+");
|
||||||
IConsoleAliasRegister("server_name", "setting server_name %+");
|
IConsoleAliasRegister("server_name", "setting server_name %+");
|
||||||
IConsoleAliasRegister("server_port", "setting server_port %+");
|
IConsoleAliasRegister("server_port", "setting server_port %+");
|
||||||
|
@@ -79,6 +79,8 @@ NetworkRecvStatus NetworkGameSocketHandler::HandlePacket(Packet *p)
|
|||||||
case PACKET_SERVER_NEED_COMPANY_PASSWORD: return this->Receive_SERVER_NEED_COMPANY_PASSWORD(p);
|
case PACKET_SERVER_NEED_COMPANY_PASSWORD: return this->Receive_SERVER_NEED_COMPANY_PASSWORD(p);
|
||||||
case PACKET_CLIENT_GAME_PASSWORD: return this->Receive_CLIENT_GAME_PASSWORD(p);
|
case PACKET_CLIENT_GAME_PASSWORD: return this->Receive_CLIENT_GAME_PASSWORD(p);
|
||||||
case PACKET_CLIENT_COMPANY_PASSWORD: return this->Receive_CLIENT_COMPANY_PASSWORD(p);
|
case PACKET_CLIENT_COMPANY_PASSWORD: return this->Receive_CLIENT_COMPANY_PASSWORD(p);
|
||||||
|
case PACKET_CLIENT_SETTINGS_PASSWORD: return this->Receive_CLIENT_SETTINGS_PASSWORD(p);
|
||||||
|
case PACKET_SERVER_SETTINGS_ACCESS: return this->Receive_SERVER_SETTINGS_ACCESS(p);
|
||||||
case PACKET_SERVER_WELCOME: return this->Receive_SERVER_WELCOME(p);
|
case PACKET_SERVER_WELCOME: return this->Receive_SERVER_WELCOME(p);
|
||||||
case PACKET_CLIENT_GETMAP: return this->Receive_CLIENT_GETMAP(p);
|
case PACKET_CLIENT_GETMAP: return this->Receive_CLIENT_GETMAP(p);
|
||||||
case PACKET_SERVER_WAIT: return this->Receive_SERVER_WAIT(p);
|
case PACKET_SERVER_WAIT: return this->Receive_SERVER_WAIT(p);
|
||||||
@@ -166,6 +168,8 @@ NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_NEED_GAME_PASSWORD(Pa
|
|||||||
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_NEED_COMPANY_PASSWORD(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_NEED_COMPANY_PASSWORD); }
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_NEED_COMPANY_PASSWORD(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_NEED_COMPANY_PASSWORD); }
|
||||||
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_GAME_PASSWORD(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_GAME_PASSWORD); }
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_GAME_PASSWORD(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_GAME_PASSWORD); }
|
||||||
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_COMPANY_PASSWORD(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_COMPANY_PASSWORD); }
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_COMPANY_PASSWORD(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_COMPANY_PASSWORD); }
|
||||||
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_SETTINGS_PASSWORD(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_SETTINGS_PASSWORD); }
|
||||||
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_SETTINGS_ACCESS(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_SETTINGS_ACCESS); }
|
||||||
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_WELCOME(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_WELCOME); }
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_WELCOME(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_WELCOME); }
|
||||||
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_GETMAP); }
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_GETMAP); }
|
||||||
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_WAIT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_WAIT); }
|
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_WAIT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_WAIT); }
|
||||||
|
@@ -63,6 +63,8 @@ enum PacketGameType {
|
|||||||
PACKET_CLIENT_GAME_PASSWORD, ///< Clients sends the (hashed) game password.
|
PACKET_CLIENT_GAME_PASSWORD, ///< Clients sends the (hashed) game password.
|
||||||
PACKET_SERVER_NEED_COMPANY_PASSWORD, ///< Server requests the (hashed) company password.
|
PACKET_SERVER_NEED_COMPANY_PASSWORD, ///< Server requests the (hashed) company password.
|
||||||
PACKET_CLIENT_COMPANY_PASSWORD, ///< Client sends the (hashed) company password.
|
PACKET_CLIENT_COMPANY_PASSWORD, ///< Client sends the (hashed) company password.
|
||||||
|
PACKET_CLIENT_SETTINGS_PASSWORD, ///< Client sends the (hashed) settings password.
|
||||||
|
PACKET_SERVER_SETTINGS_ACCESS, ///< Server sends the settings access state.
|
||||||
|
|
||||||
/* The server welcomes the authenticated client and sends information of other clients. */
|
/* The server welcomes the authenticated client and sends information of other clients. */
|
||||||
PACKET_SERVER_WELCOME, ///< Server welcomes you and gives you your #ClientID.
|
PACKET_SERVER_WELCOME, ///< Server welcomes you and gives you your #ClientID.
|
||||||
@@ -262,6 +264,21 @@ protected:
|
|||||||
*/
|
*/
|
||||||
virtual NetworkRecvStatus Receive_CLIENT_COMPANY_PASSWORD(Packet *p);
|
virtual NetworkRecvStatus Receive_CLIENT_COMPANY_PASSWORD(Packet *p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a password to the server to authorize
|
||||||
|
* uint8 Password type (see NetworkPasswordType).
|
||||||
|
* string The password.
|
||||||
|
* @param p The packet that was just received.
|
||||||
|
*/
|
||||||
|
virtual NetworkRecvStatus Receive_CLIENT_SETTINGS_PASSWORD(Packet *p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indication to the client that the setting access state has changed
|
||||||
|
* bool setting access state
|
||||||
|
* @param p The packet that was just received.
|
||||||
|
*/
|
||||||
|
virtual NetworkRecvStatus Receive_SERVER_SETTINGS_ACCESS(Packet *p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The client is joined and ready to receive his map:
|
* The client is joined and ready to receive his map:
|
||||||
* uint32 Own client ID.
|
* uint32 Own client ID.
|
||||||
|
@@ -57,6 +57,7 @@ bool _network_server; ///< network-server is active
|
|||||||
bool _network_available; ///< is network mode available?
|
bool _network_available; ///< is network mode available?
|
||||||
bool _network_dedicated; ///< are we a dedicated server?
|
bool _network_dedicated; ///< are we a dedicated server?
|
||||||
bool _is_network_server; ///< Does this client wants to be a network-server?
|
bool _is_network_server; ///< Does this client wants to be a network-server?
|
||||||
|
bool _network_settings_access; ///< Can this client change server settings?
|
||||||
NetworkServerGameInfo _network_game_info; ///< Information about our game.
|
NetworkServerGameInfo _network_game_info; ///< Information about our game.
|
||||||
NetworkCompanyState *_network_company_states = nullptr; ///< Statistics about some companies.
|
NetworkCompanyState *_network_company_states = nullptr; ///< Statistics about some companies.
|
||||||
ClientID _network_own_client_id; ///< Our client identifier.
|
ClientID _network_own_client_id; ///< Our client identifier.
|
||||||
|
@@ -22,5 +22,6 @@ extern bool _network_server; ///< network-server is active
|
|||||||
extern bool _network_available; ///< is network mode available?
|
extern bool _network_available; ///< is network mode available?
|
||||||
extern bool _network_dedicated; ///< are we a dedicated server?
|
extern bool _network_dedicated; ///< are we a dedicated server?
|
||||||
extern bool _is_network_server; ///< Does this client wants to be a network-server?
|
extern bool _is_network_server; ///< Does this client wants to be a network-server?
|
||||||
|
extern bool _network_settings_access; ///< Can this client change server settings?
|
||||||
|
|
||||||
#endif /* NETWORK_H */
|
#endif /* NETWORK_H */
|
||||||
|
@@ -159,6 +159,7 @@ ClientNetworkGameSocketHandler::~ClientNetworkGameSocketHandler()
|
|||||||
{
|
{
|
||||||
assert(ClientNetworkGameSocketHandler::my_client == this);
|
assert(ClientNetworkGameSocketHandler::my_client == this);
|
||||||
ClientNetworkGameSocketHandler::my_client = nullptr;
|
ClientNetworkGameSocketHandler::my_client = nullptr;
|
||||||
|
_network_settings_access = false;
|
||||||
|
|
||||||
delete this->savegame;
|
delete this->savegame;
|
||||||
}
|
}
|
||||||
@@ -331,6 +332,8 @@ static uint32 _server_password_game_seed;
|
|||||||
/** One bit of 'entropy' used to generate a salt for the rcon passwords. */
|
/** One bit of 'entropy' used to generate a salt for the rcon passwords. */
|
||||||
static uint32 _rcon_password_game_seed;
|
static uint32 _rcon_password_game_seed;
|
||||||
/** One bit of 'entropy' used to generate a salt for the settings passwords. */
|
/** One bit of 'entropy' used to generate a salt for the settings passwords. */
|
||||||
|
static uint32 _settings_password_game_seed;
|
||||||
|
/** The other bit of 'entropy' used to generate a salt for the company, server, rcon, and settings passwords. */
|
||||||
static char _password_server_id[NETWORK_SERVER_ID_LENGTH];
|
static char _password_server_id[NETWORK_SERVER_ID_LENGTH];
|
||||||
|
|
||||||
/** Maximum number of companies of the currently joined server. */
|
/** Maximum number of companies of the currently joined server. */
|
||||||
@@ -415,6 +418,18 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyPassword(const char
|
|||||||
return NETWORK_RECV_STATUS_OKAY;
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the game password as requested.
|
||||||
|
* @param password The game password.
|
||||||
|
*/
|
||||||
|
NetworkRecvStatus ClientNetworkGameSocketHandler::SendSettingsPassword(const char *password)
|
||||||
|
{
|
||||||
|
Packet *p = new Packet(PACKET_CLIENT_SETTINGS_PASSWORD);
|
||||||
|
p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _settings_password_game_seed));
|
||||||
|
my_client->SendPacket(p);
|
||||||
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
|
}
|
||||||
|
|
||||||
/** Request the map from the server. */
|
/** Request the map from the server. */
|
||||||
NetworkRecvStatus ClientNetworkGameSocketHandler::SendGetMap()
|
NetworkRecvStatus ClientNetworkGameSocketHandler::SendGetMap()
|
||||||
{
|
{
|
||||||
@@ -821,6 +836,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_WELCOME(Packet
|
|||||||
_company_password_game_seed = p->Recv_uint32();
|
_company_password_game_seed = p->Recv_uint32();
|
||||||
_server_password_game_seed = p->Recv_uint32();
|
_server_password_game_seed = p->Recv_uint32();
|
||||||
_rcon_password_game_seed = p->Recv_uint32();
|
_rcon_password_game_seed = p->Recv_uint32();
|
||||||
|
_settings_password_game_seed = p->Recv_uint32();
|
||||||
p->Recv_string(_password_server_id, sizeof(_password_server_id));
|
p->Recv_string(_password_server_id, sizeof(_password_server_id));
|
||||||
|
|
||||||
/* Start receiving the map */
|
/* Start receiving the map */
|
||||||
@@ -1209,6 +1225,17 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_COMPANY_UPDATE(
|
|||||||
return NETWORK_RECV_STATUS_OKAY;
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_SETTINGS_ACCESS(Packet *p)
|
||||||
|
{
|
||||||
|
if (this->status < STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
|
||||||
|
|
||||||
|
_network_settings_access = p->Recv_bool();
|
||||||
|
|
||||||
|
ReInitAllWindows();
|
||||||
|
|
||||||
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the connection's state, i.e. is the connection still up?
|
* Check the connection's state, i.e. is the connection still up?
|
||||||
*/
|
*/
|
||||||
@@ -1263,6 +1290,16 @@ void NetworkClientSendRcon(const char *password, const char *command)
|
|||||||
MyClient::SendRCon(password, command);
|
MyClient::SendRCon(password, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send settings password.
|
||||||
|
* @param password The password.
|
||||||
|
* @param command The command to execute.
|
||||||
|
*/
|
||||||
|
void NetworkClientSendSettingsPassword(const char *password)
|
||||||
|
{
|
||||||
|
MyClient::SendSettingsPassword(password);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify the server of this client wanting to be moved to another company.
|
* Notify the server of this client wanting to be moved to another company.
|
||||||
* @param company_id id of the company the client wishes to be moved to.
|
* @param company_id id of the company the client wishes to be moved to.
|
||||||
|
@@ -49,6 +49,7 @@ protected:
|
|||||||
NetworkRecvStatus Receive_SERVER_CLIENT_INFO(Packet *p) override;
|
NetworkRecvStatus Receive_SERVER_CLIENT_INFO(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_SERVER_NEED_GAME_PASSWORD(Packet *p) override;
|
NetworkRecvStatus Receive_SERVER_NEED_GAME_PASSWORD(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_SERVER_NEED_COMPANY_PASSWORD(Packet *p) override;
|
NetworkRecvStatus Receive_SERVER_NEED_COMPANY_PASSWORD(Packet *p) override;
|
||||||
|
NetworkRecvStatus Receive_SERVER_SETTINGS_ACCESS(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_SERVER_WELCOME(Packet *p) override;
|
NetworkRecvStatus Receive_SERVER_WELCOME(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_SERVER_WAIT(Packet *p) override;
|
NetworkRecvStatus Receive_SERVER_WAIT(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_SERVER_MAP_BEGIN(Packet *p) override;
|
NetworkRecvStatus Receive_SERVER_MAP_BEGIN(Packet *p) override;
|
||||||
@@ -92,6 +93,7 @@ public:
|
|||||||
|
|
||||||
static NetworkRecvStatus SendGamePassword(const char *password);
|
static NetworkRecvStatus SendGamePassword(const char *password);
|
||||||
static NetworkRecvStatus SendCompanyPassword(const char *password);
|
static NetworkRecvStatus SendCompanyPassword(const char *password);
|
||||||
|
static NetworkRecvStatus SendSettingsPassword(const char *password);
|
||||||
|
|
||||||
static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const char *msg, NetworkTextMessageData data);
|
static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const char *msg, NetworkTextMessageData data);
|
||||||
static NetworkRecvStatus SendSetPassword(const char *password);
|
static NetworkRecvStatus SendSetPassword(const char *password);
|
||||||
|
@@ -54,6 +54,7 @@ void NetworkClientsToSpectators(CompanyID cid);
|
|||||||
void NetworkClientConnectGame(NetworkAddress address, CompanyID join_as, const char *join_server_password = nullptr, const char *join_company_password = nullptr);
|
void NetworkClientConnectGame(NetworkAddress address, CompanyID join_as, const char *join_server_password = nullptr, const char *join_company_password = nullptr);
|
||||||
void NetworkClientRequestMove(CompanyID company, const char *pass = "");
|
void NetworkClientRequestMove(CompanyID company, const char *pass = "");
|
||||||
void NetworkClientSendRcon(const char *password, const char *command);
|
void NetworkClientSendRcon(const char *password, const char *command);
|
||||||
|
void NetworkClientSendSettingsPassword(const char *password);
|
||||||
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, NetworkTextMessageData data = NetworkTextMessageData());
|
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, NetworkTextMessageData data = NetworkTextMessageData());
|
||||||
bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio);
|
bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio);
|
||||||
bool NetworkCompanyIsPassworded(CompanyID company_id);
|
bool NetworkCompanyIsPassworded(CompanyID company_id);
|
||||||
|
@@ -218,6 +218,7 @@ ServerNetworkGameSocketHandler::ServerNetworkGameSocketHandler(SOCKET s) : Netwo
|
|||||||
this->receive_limit = _settings_client.network.bytes_per_frame_burst;
|
this->receive_limit = _settings_client.network.bytes_per_frame_burst;
|
||||||
this->server_hash_bits = InteractiveRandom();
|
this->server_hash_bits = InteractiveRandom();
|
||||||
this->rcon_hash_bits = InteractiveRandom();
|
this->rcon_hash_bits = InteractiveRandom();
|
||||||
|
this->settings_hash_bits = InteractiveRandom();
|
||||||
|
|
||||||
/* The Socket and Info pools need to be the same in size. After all,
|
/* The Socket and Info pools need to be the same in size. After all,
|
||||||
* each Socket will be associated with at most one Info object. As
|
* each Socket will be associated with at most one Info object. As
|
||||||
@@ -537,6 +538,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome()
|
|||||||
p->Send_uint32(_settings_game.game_creation.generation_seed);
|
p->Send_uint32(_settings_game.game_creation.generation_seed);
|
||||||
p->Send_uint32(_settings_game.game_creation.generation_seed ^ this->server_hash_bits);
|
p->Send_uint32(_settings_game.game_creation.generation_seed ^ this->server_hash_bits);
|
||||||
p->Send_uint32(_settings_game.game_creation.generation_seed ^ this->rcon_hash_bits);
|
p->Send_uint32(_settings_game.game_creation.generation_seed ^ this->rcon_hash_bits);
|
||||||
|
p->Send_uint32(_settings_game.game_creation.generation_seed ^ this->settings_hash_bits);
|
||||||
p->Send_string(_settings_client.network.network_id);
|
p->Send_string(_settings_client.network.network_id);
|
||||||
this->SendPacket(p);
|
this->SendPacket(p);
|
||||||
|
|
||||||
@@ -860,6 +862,15 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendConfigUpdate()
|
|||||||
return NETWORK_RECV_STATUS_OKAY;
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetworkRecvStatus ServerNetworkGameSocketHandler::SendSettingsAccessUpdate(bool ok)
|
||||||
|
{
|
||||||
|
Packet *p = new Packet(PACKET_SERVER_SETTINGS_ACCESS);
|
||||||
|
p->Send_bool(ok);
|
||||||
|
this->SendPacket(p);
|
||||||
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********
|
/***********
|
||||||
* Receiving functions
|
* Receiving functions
|
||||||
* DEF_SERVER_RECEIVE_COMMAND has parameter: NetworkClientSocket *cs, Packet *p
|
* DEF_SERVER_RECEIVE_COMMAND has parameter: NetworkClientSocket *cs, Packet *p
|
||||||
@@ -1014,6 +1025,29 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMPANY_PASSWOR
|
|||||||
return this->SendWelcome();
|
return this->SendWelcome();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SETTINGS_PASSWORD(Packet *p)
|
||||||
|
{
|
||||||
|
if (this->status != STATUS_ACTIVE) {
|
||||||
|
/* Illegal call, return error and ignore the packet */
|
||||||
|
return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
char password[NETWORK_PASSWORD_LENGTH];
|
||||||
|
p->Recv_string(password, sizeof(password));
|
||||||
|
|
||||||
|
/* Check settings password. Deny if no password is set */
|
||||||
|
if (StrEmpty(_settings_client.network.settings_password) ||
|
||||||
|
strcmp(password, GenerateCompanyPasswordHash(_settings_client.network.settings_password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed ^ this->settings_hash_bits)) != 0) {
|
||||||
|
DEBUG(net, 0, "[settings-ctrl] wrong password from client-id %d", this->client_id);
|
||||||
|
this->settings_authed = false;
|
||||||
|
} else {
|
||||||
|
DEBUG(net, 0, "[settings-ctrl] client-id %d", this->client_id);
|
||||||
|
this->settings_authed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->SendSettingsAccessUpdate(this->settings_authed);
|
||||||
|
}
|
||||||
|
|
||||||
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet *p)
|
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet *p)
|
||||||
{
|
{
|
||||||
NetworkClientSocket *new_cs;
|
NetworkClientSocket *new_cs;
|
||||||
@@ -1108,12 +1142,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((GetCommandFlags(cp.cmd) & CMD_SERVER) && ci->client_id != CLIENT_ID_SERVER) {
|
if ((GetCommandFlags(cp.cmd) & CMD_SERVER) && ci->client_id != CLIENT_ID_SERVER && !this->settings_authed) {
|
||||||
IConsolePrintF(CC_ERROR, "WARNING: server only command from: client %d (IP: %s), kicking...", ci->client_id, this->GetClientIP());
|
IConsolePrintF(CC_ERROR, "WARNING: server only command from: client %d (IP: %s), kicking...", ci->client_id, this->GetClientIP());
|
||||||
return this->SendError(NETWORK_ERROR_KICKED);
|
return this->SendError(NETWORK_ERROR_KICKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((GetCommandFlags(cp.cmd) & CMD_SPECTATOR) == 0 && !Company::IsValidID(cp.company) && ci->client_id != CLIENT_ID_SERVER) {
|
if ((GetCommandFlags(cp.cmd) & CMD_SPECTATOR) == 0 && !Company::IsValidID(cp.company) && ci->client_id != CLIENT_ID_SERVER && !this->settings_authed) {
|
||||||
IConsolePrintF(CC_ERROR, "WARNING: spectator issuing command from client %d (IP: %s), kicking...", ci->client_id, this->GetClientIP());
|
IConsolePrintF(CC_ERROR, "WARNING: spectator issuing command from client %d (IP: %s), kicking...", ci->client_id, this->GetClientIP());
|
||||||
return this->SendError(NETWORK_ERROR_KICKED);
|
return this->SendError(NETWORK_ERROR_KICKED);
|
||||||
}
|
}
|
||||||
@@ -1123,7 +1157,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet
|
|||||||
* to match the company in the packet. If it doesn't, the client has done
|
* to match the company in the packet. If it doesn't, the client has done
|
||||||
* something pretty naughty (or a bug), and will be kicked
|
* something pretty naughty (or a bug), and will be kicked
|
||||||
*/
|
*/
|
||||||
if (!(cp.cmd == CMD_COMPANY_CTRL && cp.p1 == 0 && ci->client_playas == COMPANY_NEW_COMPANY) && ci->client_playas != cp.company) {
|
if (!(cp.cmd == CMD_COMPANY_CTRL && cp.p1 == 0 && ci->client_playas == COMPANY_NEW_COMPANY) && ci->client_playas != cp.company &&
|
||||||
|
!((GetCommandFlags(cp.cmd) & CMD_SERVER) && this->settings_authed)) {
|
||||||
IConsolePrintF(CC_ERROR, "WARNING: client %d (IP: %s) tried to execute a command as company %d, kicking...",
|
IConsolePrintF(CC_ERROR, "WARNING: client %d (IP: %s) tried to execute a command as company %d, kicking...",
|
||||||
ci->client_playas + 1, this->GetClientIP(), cp.company + 1);
|
ci->client_playas + 1, this->GetClientIP(), cp.company + 1);
|
||||||
return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH);
|
return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH);
|
||||||
|
@@ -29,6 +29,7 @@ protected:
|
|||||||
NetworkRecvStatus Receive_CLIENT_COMPANY_INFO(Packet *p) override;
|
NetworkRecvStatus Receive_CLIENT_COMPANY_INFO(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_CLIENT_GAME_PASSWORD(Packet *p) override;
|
NetworkRecvStatus Receive_CLIENT_GAME_PASSWORD(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_CLIENT_COMPANY_PASSWORD(Packet *p) override;
|
NetworkRecvStatus Receive_CLIENT_COMPANY_PASSWORD(Packet *p) override;
|
||||||
|
NetworkRecvStatus Receive_CLIENT_SETTINGS_PASSWORD(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_CLIENT_GETMAP(Packet *p) override;
|
NetworkRecvStatus Receive_CLIENT_GETMAP(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_CLIENT_MAP_OK(Packet *p) override;
|
NetworkRecvStatus Receive_CLIENT_MAP_OK(Packet *p) override;
|
||||||
NetworkRecvStatus Receive_CLIENT_ACK(Packet *p) override;
|
NetworkRecvStatus Receive_CLIENT_ACK(Packet *p) override;
|
||||||
@@ -74,6 +75,8 @@ public:
|
|||||||
int receive_limit; ///< Amount of bytes that we can receive at this moment
|
int receive_limit; ///< Amount of bytes that we can receive at this moment
|
||||||
uint32 server_hash_bits; ///< Server password hash entropy bits
|
uint32 server_hash_bits; ///< Server password hash entropy bits
|
||||||
uint32 rcon_hash_bits; ///< Rcon password hash entropy bits
|
uint32 rcon_hash_bits; ///< Rcon password hash entropy bits
|
||||||
|
uint32 settings_hash_bits; ///< Settings password hash entropy bits
|
||||||
|
bool settings_authed = false;///< Authorised to control all game settings
|
||||||
|
|
||||||
struct PacketWriter *savegame; ///< Writer used to write the savegame.
|
struct PacketWriter *savegame; ///< Writer used to write the savegame.
|
||||||
NetworkAddress client_address; ///< IP-address of the client (so he can be banned)
|
NetworkAddress client_address; ///< IP-address of the client (so he can be banned)
|
||||||
@@ -104,6 +107,7 @@ public:
|
|||||||
NetworkRecvStatus SendCommand(const CommandPacket *cp);
|
NetworkRecvStatus SendCommand(const CommandPacket *cp);
|
||||||
NetworkRecvStatus SendCompanyUpdate();
|
NetworkRecvStatus SendCompanyUpdate();
|
||||||
NetworkRecvStatus SendConfigUpdate();
|
NetworkRecvStatus SendConfigUpdate();
|
||||||
|
NetworkRecvStatus SendSettingsAccessUpdate(bool ok);
|
||||||
|
|
||||||
static void Send();
|
static void Send();
|
||||||
static void AcceptConnection(SOCKET s, const NetworkAddress &address);
|
static void AcceptConnection(SOCKET s, const NetworkAddress &address);
|
||||||
|
@@ -806,7 +806,7 @@ void IniSaveWindowSettings(IniFile *ini, const char *grpname, void *desc)
|
|||||||
*/
|
*/
|
||||||
bool SettingDesc::IsEditable(bool do_command) const
|
bool SettingDesc::IsEditable(bool do_command) const
|
||||||
{
|
{
|
||||||
if (!do_command && !(this->save.conv & SLF_NO_NETWORK_SYNC) && _networking && !_network_server && !(this->desc.flags & SGF_PER_COMPANY)) return false;
|
if (!do_command && !(this->save.conv & SLF_NO_NETWORK_SYNC) && _networking && !(_network_server || _network_settings_access) && !(this->desc.flags & SGF_PER_COMPANY)) return false;
|
||||||
if ((this->desc.flags & SGF_NETWORK_ONLY) && !_networking && _game_mode != GM_MENU) return false;
|
if ((this->desc.flags & SGF_NETWORK_ONLY) && !_networking && _game_mode != GM_MENU) return false;
|
||||||
if ((this->desc.flags & SGF_NO_NETWORK) && _networking) return false;
|
if ((this->desc.flags & SGF_NO_NETWORK) && _networking) return false;
|
||||||
if ((this->desc.flags & SGF_NEWGAME_ONLY) &&
|
if ((this->desc.flags & SGF_NEWGAME_ONLY) &&
|
||||||
@@ -1260,7 +1260,7 @@ static bool MaxNoAIsChange(int32 i)
|
|||||||
{
|
{
|
||||||
if (GetGameSettings().difficulty.max_no_competitors != 0 &&
|
if (GetGameSettings().difficulty.max_no_competitors != 0 &&
|
||||||
AI::GetInfoList()->size() == 0 &&
|
AI::GetInfoList()->size() == 0 &&
|
||||||
(!_networking || _network_server)) {
|
(!_networking || (_network_server || _network_settings_access))) {
|
||||||
ShowErrorMessage(STR_WARNING_NO_SUITABLE_AI, INVALID_STRING_ID, WL_CRITICAL);
|
ShowErrorMessage(STR_WARNING_NO_SUITABLE_AI, INVALID_STRING_ID, WL_CRITICAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1495,6 +1495,15 @@ static bool UpdateRconPassword(int32 p1)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool UpdateSettingsPassword(int32 p1)
|
||||||
|
{
|
||||||
|
if (strcmp(_settings_client.network.settings_password, "*") == 0) {
|
||||||
|
_settings_client.network.settings_password[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool UpdateClientConfigValues(int32 p1)
|
static bool UpdateClientConfigValues(int32 p1)
|
||||||
{
|
{
|
||||||
if (_network_server) NetworkServerSendConfigUpdate();
|
if (_network_server) NetworkServerSendConfigUpdate();
|
||||||
@@ -2112,7 +2121,7 @@ bool SetSettingValue(uint index, int32 value, bool force_newgame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* send non-company-based settings over the network */
|
/* send non-company-based settings over the network */
|
||||||
if (!_networking || (_networking && _network_server)) {
|
if (!_networking || (_networking && (_network_server || _network_settings_access))) {
|
||||||
return DoCommandP(0, index, value, CMD_CHANGE_SETTING);
|
return DoCommandP(0, index, value, CMD_CHANGE_SETTING);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -2272,7 +2281,7 @@ void IConsoleSetSetting(const char *name, const char *value, bool force_newgame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
if (_network_server) {
|
if ((_network_server || _network_settings_access)) {
|
||||||
IConsoleError("This command/variable is not available during network games.");
|
IConsoleError("This command/variable is not available during network games.");
|
||||||
} else {
|
} else {
|
||||||
IConsoleError("This command/variable is only available to a network server.");
|
IConsoleError("This command/variable is only available to a network server.");
|
||||||
|
@@ -228,7 +228,7 @@ struct GameOptionsWindow : Window {
|
|||||||
/* You can only change the drive side if you are in the menu or ingame with
|
/* You can only change the drive side if you are in the menu or ingame with
|
||||||
* no vehicles present. In a networking game only the server can change it */
|
* no vehicles present. In a networking game only the server can change it */
|
||||||
extern bool RoadVehiclesAreBuilt();
|
extern bool RoadVehiclesAreBuilt();
|
||||||
if ((_game_mode != GM_MENU && RoadVehiclesAreBuilt()) || (_networking && !_network_server)) {
|
if ((_game_mode != GM_MENU && RoadVehiclesAreBuilt()) || (_networking && !(_network_server || _network_settings_access))) {
|
||||||
disabled = ~(1 << this->opt->vehicle.road_side); // disable the other value
|
disabled = ~(1 << this->opt->vehicle.road_side); // disable the other value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -303,6 +303,7 @@ struct NetworkSettings {
|
|||||||
char server_password[NETWORK_PASSWORD_LENGTH]; ///< password for joining this server
|
char server_password[NETWORK_PASSWORD_LENGTH]; ///< password for joining this server
|
||||||
char rcon_password[NETWORK_PASSWORD_LENGTH]; ///< password for rconsole (server side)
|
char rcon_password[NETWORK_PASSWORD_LENGTH]; ///< password for rconsole (server side)
|
||||||
char admin_password[NETWORK_PASSWORD_LENGTH]; ///< password for the admin network
|
char admin_password[NETWORK_PASSWORD_LENGTH]; ///< password for the admin network
|
||||||
|
char settings_password[NETWORK_PASSWORD_LENGTH]; ///< password for game settings (server side)
|
||||||
bool server_advertise; ///< advertise the server to the masterserver
|
bool server_advertise; ///< advertise the server to the masterserver
|
||||||
uint8 lan_internet; ///< search on the LAN or internet for servers
|
uint8 lan_internet; ///< search on the LAN or internet for servers
|
||||||
char client_name[NETWORK_CLIENT_NAME_LENGTH]; ///< name of the player (as client)
|
char client_name[NETWORK_CLIENT_NAME_LENGTH]; ///< name of the player (as client)
|
||||||
|
@@ -53,6 +53,7 @@ static bool EnableSingleVehSharedOrderGuiChanged(int32 p1);
|
|||||||
static bool UpdateClientName(int32 p1);
|
static bool UpdateClientName(int32 p1);
|
||||||
static bool UpdateServerPassword(int32 p1);
|
static bool UpdateServerPassword(int32 p1);
|
||||||
static bool UpdateRconPassword(int32 p1);
|
static bool UpdateRconPassword(int32 p1);
|
||||||
|
static bool UpdateSettingsPassword(int32 p1);
|
||||||
static bool UpdateClientConfigValues(int32 p1);
|
static bool UpdateClientConfigValues(int32 p1);
|
||||||
static bool CheckSharingRail(int32 p1);
|
static bool CheckSharingRail(int32 p1);
|
||||||
static bool CheckSharingRoad(int32 p1);
|
static bool CheckSharingRoad(int32 p1);
|
||||||
@@ -5077,6 +5078,15 @@ guiflags = SGF_NETWORK_ONLY
|
|||||||
def = nullptr
|
def = nullptr
|
||||||
cat = SC_BASIC
|
cat = SC_BASIC
|
||||||
|
|
||||||
|
[SDTC_STR]
|
||||||
|
var = network.settings_password
|
||||||
|
type = SLE_STRB
|
||||||
|
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
|
||||||
|
guiflags = SGF_NETWORK_ONLY
|
||||||
|
def = nullptr
|
||||||
|
proc = UpdateSettingsPassword
|
||||||
|
cat = SC_EXPERT
|
||||||
|
|
||||||
[SDTC_STR]
|
[SDTC_STR]
|
||||||
var = network.default_company_pass
|
var = network.default_company_pass
|
||||||
type = SLE_STRB
|
type = SLE_STRB
|
||||||
|
@@ -275,7 +275,7 @@ static CallBackFunction SelectSignTool()
|
|||||||
|
|
||||||
static CallBackFunction ToolbarPauseClick(Window *w)
|
static CallBackFunction ToolbarPauseClick(Window *w)
|
||||||
{
|
{
|
||||||
if (_networking && !_network_server) return CBF_NONE; // only server can pause the game
|
if (_networking && !(_network_server || _network_settings_access)) return CBF_NONE; // only server can pause the game
|
||||||
|
|
||||||
if (DoCommandP(0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED, CMD_PAUSE)) {
|
if (DoCommandP(0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED, CMD_PAUSE)) {
|
||||||
if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP);
|
if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP);
|
||||||
@@ -2013,7 +2013,6 @@ struct MainToolbarWindow : Window {
|
|||||||
|
|
||||||
_last_started_action = CBF_NONE;
|
_last_started_action = CBF_NONE;
|
||||||
CLRBITS(this->flags, WF_WHITE_BORDER);
|
CLRBITS(this->flags, WF_WHITE_BORDER);
|
||||||
this->SetWidgetDisabledState(WID_TN_PAUSE, _networking && !_network_server); // if not server, disable pause button
|
|
||||||
this->SetWidgetDisabledState(WID_TN_FAST_FORWARD, _networking); // if networking, disable fast-forward button
|
this->SetWidgetDisabledState(WID_TN_FAST_FORWARD, _networking); // if networking, disable fast-forward button
|
||||||
PositionMainToolbar(this);
|
PositionMainToolbar(this);
|
||||||
DoZoomInOutWindow(ZOOM_NONE, this);
|
DoZoomInOutWindow(ZOOM_NONE, this);
|
||||||
@@ -2041,6 +2040,8 @@ struct MainToolbarWindow : Window {
|
|||||||
this->SetWidgetDisabledState(WID_TN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN));
|
this->SetWidgetDisabledState(WID_TN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN));
|
||||||
this->SetWidgetDisabledState(WID_TN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
|
this->SetWidgetDisabledState(WID_TN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
|
||||||
|
|
||||||
|
this->SetWidgetDisabledState(WID_TN_PAUSE, _networking && !(_network_server || _network_settings_access)); // if not server, disable pause button
|
||||||
|
|
||||||
this->DrawWidgets();
|
this->DrawWidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -322,9 +322,6 @@ public:
|
|||||||
this->flags |= WF_DISABLE_VP_SCROLL;
|
this->flags |= WF_DISABLE_VP_SCROLL;
|
||||||
NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_TV_VIEWPORT);
|
NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_TV_VIEWPORT);
|
||||||
nvp->InitializeViewport(this, this->town->xy, ZOOM_LVL_NEWS);
|
nvp->InitializeViewport(this, this->town->xy, ZOOM_LVL_NEWS);
|
||||||
|
|
||||||
/* disable renaming town in network games if you are not the server */
|
|
||||||
this->SetWidgetDisabledState(WID_TV_CHANGE_NAME, _networking && !_network_server);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~TownViewWindow()
|
~TownViewWindow()
|
||||||
@@ -341,6 +338,7 @@ public:
|
|||||||
{
|
{
|
||||||
extern const Town *_viewport_highlight_town;
|
extern const Town *_viewport_highlight_town;
|
||||||
this->SetWidgetLoweredState(WID_TV_CATCHMENT, _viewport_highlight_town == this->town);
|
this->SetWidgetLoweredState(WID_TV_CATCHMENT, _viewport_highlight_town == this->town);
|
||||||
|
this->SetWidgetDisabledState(WID_TV_CHANGE_NAME, _networking && !(_network_server || _network_settings_access));
|
||||||
|
|
||||||
this->DrawWidgets();
|
this->DrawWidgets();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user