This commit is contained in:
rubidium42 2024-04-23 19:34:11 +02:00 committed by GitHub
commit de9bd52178
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 308 additions and 841 deletions

View File

@ -20,7 +20,6 @@
.Op Fl M Ar musicset .Op Fl M Ar musicset
.Op Fl n Ar host Ns Oo : Ns Ar port Oc Ns Op # Ns Ar company .Op Fl n Ar host Ns Oo : Ns Ar port Oc Ns Op # Ns Ar company
.Op Fl p Ar password .Op Fl p Ar password
.Op Fl P Ar password
.Op Fl q Ar savegame .Op Fl q Ar savegame
.Op Fl r Ar width Ns x Ns Ar height .Op Fl r Ar width Ns x Ns Ar height
.Op Fl s Ar driver .Op Fl s Ar driver
@ -100,10 +99,6 @@ play as.
Password used to join server. Password used to join server.
Only useful with Only useful with
.Fl n . .Fl n .
.It Fl P Ar password
Password used to join company.
Only useful with
.Fl n .
.It Fl q Ar savegame .It Fl q Ar savegame
Write some information about the specified savegame and exit. Write some information about the specified savegame and exit.
.It Fl Q .It Fl Q

View File

@ -294,6 +294,7 @@ enum Commands : uint16_t {
CMD_CREATE_SUBSIDY, ///< create a new subsidy CMD_CREATE_SUBSIDY, ///< create a new subsidy
CMD_COMPANY_CTRL, ///< used in multiplayer to create a new companies etc. CMD_COMPANY_CTRL, ///< used in multiplayer to create a new companies etc.
CMD_COMPANY_ALLOW_LIST_CTRL, ///< Used in multiplayer to add/remove a client's public key to/from the company's allow list.
CMD_CUSTOM_NEWS_ITEM, ///< create a custom news message CMD_CUSTOM_NEWS_ITEM, ///< create a custom news message
CMD_CREATE_GOAL, ///< create a new goal CMD_CREATE_GOAL, ///< create a new goal
CMD_REMOVE_GOAL, ///< remove a goal CMD_REMOVE_GOAL, ///< remove a goal

View File

@ -75,6 +75,8 @@ struct CompanyProperties {
uint32_t president_name_2; ///< Parameter of #president_name_1 uint32_t president_name_2; ///< Parameter of #president_name_1
std::string president_name; ///< Name of the president if the user changed it. std::string president_name; ///< Name of the president if the user changed it.
NetworkAuthorizedKeys allow_list; ///< Public keys of clients that are allowed to join this company.
CompanyManagerFace face; ///< Face description of the president. CompanyManagerFace face; ///< Face description of the president.
Money money; ///< Money owned by the company. Money money; ///< Money owned by the company.

View File

@ -890,8 +890,6 @@ CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID
break; break;
} }
/* Send new companies, before potentially setting the password. Otherwise,
* the password update could be sent when the company is not yet known. */
NetworkAdminCompanyNew(c); NetworkAdminCompanyNew(c);
NetworkServerNewCompany(c, ci); NetworkServerNewCompany(c, ci);
@ -899,9 +897,6 @@ CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID
if (client_id == _network_own_client_id) { if (client_id == _network_own_client_id) {
assert(_local_company == COMPANY_SPECTATOR); assert(_local_company == COMPANY_SPECTATOR);
SetLocalCompany(c->index); SetLocalCompany(c->index);
if (!_settings_client.network.default_company_pass.empty()) {
NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass);
}
/* In network games, we need to try setting the company manager face here to sync it to all clients. /* In network games, we need to try setting the company manager face here to sync it to all clients.
* If a favorite company manager face is selected, choose it. Otherwise, use a random face. */ * If a favorite company manager face is selected, choose it. Otherwise, use a random face. */
@ -980,6 +975,46 @@ CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID
return CommandCost(); return CommandCost();
} }
/**
* Add or remove the given public key to the allow list of this company.
* @param flags Operation to perform.
* @param action The action to perform.
* @param public_key The public key of the client to add or remove.
* @return The cost of this operation or an error.
*/
CommandCost CmdCompanyAllowListCtrl(DoCommandFlag flags, CompanyAllowListCtrlAction action, const std::string &public_key)
{
Company *c = Company::GetIfValid(_current_company);
if (c == nullptr) return CMD_ERROR;
/* The public key length includes the '\0'. */
if (public_key.size() != NETWORK_PUBLIC_KEY_LENGTH - 1) return CMD_ERROR;
using ModifierFunction = bool (NetworkAuthorizedKeys::*)(std::string_view key);
ModifierFunction modifier_function;
switch (action) {
case CALCA_ADD:
modifier_function = &NetworkAuthorizedKeys::Add;
break;
case CALCA_REMOVE:
modifier_function = &NetworkAuthorizedKeys::Remove;
break;
default:
return CMD_ERROR;
}
if (flags & DC_EXEC) {
if (std::invoke(modifier_function, c->allow_list, public_key)) {
InvalidateWindowData(WC_CLIENT_LIST, 0);
SetWindowDirty(WC_COMPANY, _current_company);
}
}
return CommandCost();
}
/** /**
* Change the company manager's face. * Change the company manager's face.
* @param flags operation to perform * @param flags operation to perform

View File

@ -18,6 +18,7 @@ enum ClientID : uint32_t;
enum Colours : uint8_t; enum Colours : uint8_t;
CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID company_id, CompanyRemoveReason reason, ClientID client_id); CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID company_id, CompanyRemoveReason reason, ClientID client_id);
CommandCost CmdCompanyAllowListCtrl(DoCommandFlag flags, CompanyAllowListCtrlAction action, const std::string &public_key);
CommandCost CmdGiveMoney(DoCommandFlag flags, Money money, CompanyID dest_company); CommandCost CmdGiveMoney(DoCommandFlag flags, Money money, CompanyID dest_company);
CommandCost CmdRenameCompany(DoCommandFlag flags, const std::string &text); CommandCost CmdRenameCompany(DoCommandFlag flags, const std::string &text);
CommandCost CmdRenamePresident(DoCommandFlag flags, const std::string &text); CommandCost CmdRenamePresident(DoCommandFlag flags, const std::string &text);
@ -25,6 +26,7 @@ CommandCost CmdSetCompanyManagerFace(DoCommandFlag flags, CompanyManagerFace cmf
CommandCost CmdSetCompanyColour(DoCommandFlag flags, LiveryScheme scheme, bool primary, Colours colour); CommandCost CmdSetCompanyColour(DoCommandFlag flags, LiveryScheme scheme, bool primary, Colours colour);
DEF_CMD_TRAIT(CMD_COMPANY_CTRL, CmdCompanyCtrl, CMD_SPECTATOR | CMD_CLIENT_ID | CMD_NO_EST, CMDT_SERVER_SETTING) DEF_CMD_TRAIT(CMD_COMPANY_CTRL, CmdCompanyCtrl, CMD_SPECTATOR | CMD_CLIENT_ID | CMD_NO_EST, CMDT_SERVER_SETTING)
DEF_CMD_TRAIT(CMD_COMPANY_ALLOW_LIST_CTRL, CmdCompanyAllowListCtrl, CMD_NO_EST, CMDT_SERVER_SETTING)
DEF_CMD_TRAIT(CMD_GIVE_MONEY, CmdGiveMoney, 0, CMDT_MONEY_MANAGEMENT) DEF_CMD_TRAIT(CMD_GIVE_MONEY, CmdGiveMoney, 0, CMDT_MONEY_MANAGEMENT)
DEF_CMD_TRAIT(CMD_RENAME_COMPANY, CmdRenameCompany, 0, CMDT_OTHER_MANAGEMENT) DEF_CMD_TRAIT(CMD_RENAME_COMPANY, CmdRenameCompany, 0, CMDT_OTHER_MANAGEMENT)
DEF_CMD_TRAIT(CMD_RENAME_PRESIDENT, CmdRenamePresident, 0, CMDT_OTHER_MANAGEMENT) DEF_CMD_TRAIT(CMD_RENAME_PRESIDENT, CmdRenamePresident, 0, CMDT_OTHER_MANAGEMENT)

View File

@ -2148,9 +2148,6 @@ static constexpr NWidgetPart _nested_company_widgets[] = {
/* Multi player buttons. */ /* Multi player buttons. */
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 0), NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), SetPIPRatio(1, 0, 0),
NWidget(NWID_VERTICAL), SetPIPRatio(1, 0, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_C_HAS_PASSWORD), SetFill(0, 0),
EndContainer(),
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0), NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_C_SELECT_HOSTILE_TAKEOVER), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_C_SELECT_HOSTILE_TAKEOVER),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_C_HOSTILE_TAKEOVER), SetDataTip(STR_COMPANY_VIEW_HOSTILE_TAKEOVER_BUTTON, STR_COMPANY_VIEW_HOSTILE_TAKEOVER_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_C_HOSTILE_TAKEOVER), SetDataTip(STR_COMPANY_VIEW_HOSTILE_TAKEOVER_BUTTON, STR_COMPANY_VIEW_HOSTILE_TAKEOVER_TOOLTIP),
@ -2159,7 +2156,6 @@ static constexpr NWidgetPart _nested_company_widgets[] = {
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_C_GIVE_MONEY), SetDataTip(STR_COMPANY_VIEW_GIVE_MONEY_BUTTON, STR_COMPANY_VIEW_GIVE_MONEY_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_C_GIVE_MONEY), SetDataTip(STR_COMPANY_VIEW_GIVE_MONEY_BUTTON, STR_COMPANY_VIEW_GIVE_MONEY_TOOLTIP),
EndContainer(), EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_C_SELECT_MULTIPLAYER), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_C_SELECT_MULTIPLAYER),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_C_COMPANY_PASSWORD), SetDataTip(STR_COMPANY_VIEW_PASSWORD, STR_COMPANY_VIEW_PASSWORD_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_C_COMPANY_JOIN), SetDataTip(STR_COMPANY_VIEW_JOIN, STR_COMPANY_VIEW_JOIN_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_C_COMPANY_JOIN), SetDataTip(STR_COMPANY_VIEW_JOIN, STR_COMPANY_VIEW_JOIN_TOOLTIP),
EndContainer(), EndContainer(),
EndContainer(), EndContainer(),
@ -2192,10 +2188,6 @@ struct CompanyWindow : Window
/** Display planes in the company window. */ /** Display planes in the company window. */
enum CompanyWindowPlanes { enum CompanyWindowPlanes {
/* Display planes of the #WID_C_SELECT_MULTIPLAYER selection widget. */
CWP_MP_C_PWD = 0, ///< Display the company password button.
CWP_MP_C_JOIN, ///< Display the join company button.
/* Display planes of the #WID_C_SELECT_VIEW_BUILD_HQ selection widget. */ /* Display planes of the #WID_C_SELECT_VIEW_BUILD_HQ selection widget. */
CWP_VB_VIEW = 0, ///< Display the view button CWP_VB_VIEW = 0, ///< Display the view button
CWP_VB_BUILD, ///< Display the build button CWP_VB_BUILD, ///< Display the build button
@ -2236,7 +2228,7 @@ struct CompanyWindow : Window
reinit |= this->GetWidget<NWidgetStacked>(WID_C_SELECT_HOSTILE_TAKEOVER)->SetDisplayedPlane((local || _local_company == COMPANY_SPECTATOR || !c->is_ai || _networking) ? SZSP_NONE : 0); reinit |= this->GetWidget<NWidgetStacked>(WID_C_SELECT_HOSTILE_TAKEOVER)->SetDisplayedPlane((local || _local_company == COMPANY_SPECTATOR || !c->is_ai || _networking) ? SZSP_NONE : 0);
/* Multiplayer buttons. */ /* Multiplayer buttons. */
reinit |= this->GetWidget<NWidgetStacked>(WID_C_SELECT_MULTIPLAYER)->SetDisplayedPlane((!_networking) ? (int)SZSP_NONE : (int)(local ? CWP_MP_C_PWD : CWP_MP_C_JOIN)); reinit |= this->GetWidget<NWidgetStacked>(WID_C_SELECT_MULTIPLAYER)->SetDisplayedPlane((!_networking || !NetworkCanJoinCompany(c->index) || _local_company == c->index) ? (int)SZSP_NONE : 0);
this->SetWidgetDisabledState(WID_C_COMPANY_JOIN, c->is_ai); this->SetWidgetDisabledState(WID_C_COMPANY_JOIN, c->is_ai);
@ -2294,7 +2286,6 @@ struct CompanyWindow : Window
case WID_C_VIEW_INFRASTRUCTURE: case WID_C_VIEW_INFRASTRUCTURE:
case WID_C_GIVE_MONEY: case WID_C_GIVE_MONEY:
case WID_C_HOSTILE_TAKEOVER: case WID_C_HOSTILE_TAKEOVER:
case WID_C_COMPANY_PASSWORD:
case WID_C_COMPANY_JOIN: case WID_C_COMPANY_JOIN:
size.width = GetStringBoundingBox(STR_COMPANY_VIEW_VIEW_HQ_BUTTON).width; size.width = GetStringBoundingBox(STR_COMPANY_VIEW_VIEW_HQ_BUTTON).width;
size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_VIEW_BUILD_HQ_BUTTON).width); size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_VIEW_BUILD_HQ_BUTTON).width);
@ -2302,14 +2293,9 @@ struct CompanyWindow : Window
size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON).width); size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON).width);
size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_VIEW_GIVE_MONEY_BUTTON).width); size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_VIEW_GIVE_MONEY_BUTTON).width);
size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_VIEW_HOSTILE_TAKEOVER_BUTTON).width); size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_VIEW_HOSTILE_TAKEOVER_BUTTON).width);
size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_VIEW_PASSWORD).width);
size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_VIEW_JOIN).width); size.width = std::max(size.width, GetStringBoundingBox(STR_COMPANY_VIEW_JOIN).width);
size.width += padding.width; size.width += padding.width;
break; break;
case WID_C_HAS_PASSWORD:
if (_networking) size = maxdim(size, GetSpriteSize(SPR_LOCK));
break;
} }
} }
@ -2404,12 +2390,6 @@ struct CompanyWindow : Window
case WID_C_DESC_INFRASTRUCTURE_COUNTS: case WID_C_DESC_INFRASTRUCTURE_COUNTS:
DrawInfrastructureCountsWidget(r, c); DrawInfrastructureCountsWidget(r, c);
break; break;
case WID_C_HAS_PASSWORD:
if (_networking && NetworkCompanyIsPassworded(c->index)) {
DrawSprite(SPR_LOCK, PAL_NONE, r.left, r.top);
}
break;
} }
} }
@ -2508,19 +2488,12 @@ struct CompanyWindow : Window
ShowBuyCompanyDialog((CompanyID)this->window_number, true); ShowBuyCompanyDialog((CompanyID)this->window_number, true);
break; break;
case WID_C_COMPANY_PASSWORD:
if (this->window_number == _local_company) ShowNetworkCompanyPasswordWindow(this);
break;
case WID_C_COMPANY_JOIN: { case WID_C_COMPANY_JOIN: {
this->query_widget = WID_C_COMPANY_JOIN; this->query_widget = WID_C_COMPANY_JOIN;
CompanyID company = (CompanyID)this->window_number; CompanyID company = (CompanyID)this->window_number;
if (_network_server) { if (_network_server) {
NetworkServerDoMove(CLIENT_ID_SERVER, company); NetworkServerDoMove(CLIENT_ID_SERVER, company);
MarkWholeScreenDirty(); MarkWholeScreenDirty();
} else if (NetworkCompanyIsPassworded(company)) {
/* ask for the password */
ShowQueryString(STR_EMPTY, STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION, NETWORK_PASSWORD_LENGTH, this, CS_ALPHANUMERAL, QSF_PASSWORD);
} else { } else {
/* just send the join command */ /* just send the join command */
NetworkClientRequestMove(company); NetworkClientRequestMove(company);
@ -2568,10 +2541,6 @@ struct CompanyWindow : Window
case WID_C_COMPANY_NAME: case WID_C_COMPANY_NAME:
Command<CMD_RENAME_COMPANY>::Post(STR_ERROR_CAN_T_CHANGE_COMPANY_NAME, str); Command<CMD_RENAME_COMPANY>::Post(STR_ERROR_CAN_T_CHANGE_COMPANY_NAME, str);
break; break;
case WID_C_COMPANY_JOIN:
NetworkClientRequestMove((CompanyID)this->window_number, str);
break;
} }
} }

View File

@ -72,4 +72,12 @@ enum CompanyCtrlAction : uint8_t {
CCA_END, ///< Sentinel for end. CCA_END, ///< Sentinel for end.
}; };
/** The action to do with CMD_COMPANY_ALLOW_LIST_CTRL. */
enum CompanyAllowListCtrlAction : uint8_t {
CALCA_ADD, ///< Create a public key.
CALCA_REMOVE, ///< Remove a public key.
CALCA_END, ///< Sentinel for end.
};
#endif /* COMPANY_TYPE_H */ #endif /* COMPANY_TYPE_H */

View File

@ -914,7 +914,7 @@ DEF_CONSOLE_CMD(ConClientNickChange)
DEF_CONSOLE_CMD(ConJoinCompany) DEF_CONSOLE_CMD(ConJoinCompany)
{ {
if (argc < 2) { if (argc < 2) {
IConsolePrint(CC_HELP, "Request joining another company. Usage: 'join <company-id> [<password>]'."); IConsolePrint(CC_HELP, "Request joining another company. Usage: 'join <company-id>'.");
IConsolePrint(CC_HELP, "For valid company-id see company list, use 255 for spectator."); IConsolePrint(CC_HELP, "For valid company-id see company list, use 255 for spectator.");
return true; return true;
} }
@ -943,9 +943,8 @@ DEF_CONSOLE_CMD(ConJoinCompany)
return true; return true;
} }
/* Check if the company requires a password */ if (!info->CanJoinCompany(company_id)) {
if (NetworkCompanyIsPassworded(company_id) && argc < 3) { IConsolePrint(CC_ERROR, "You are not allowed to join this company.");
IConsolePrint(CC_ERROR, "Company {} requires a password to join.", company_id + 1);
return true; return true;
} }
@ -953,7 +952,7 @@ DEF_CONSOLE_CMD(ConJoinCompany)
if (_network_server) { if (_network_server) {
NetworkServerDoMove(CLIENT_ID_SERVER, company_id); NetworkServerDoMove(CLIENT_ID_SERVER, company_id);
} else { } else {
NetworkClientRequestMove(company_id, NetworkCompanyIsPassworded(company_id) ? argv[2] : ""); NetworkClientRequestMove(company_id);
} }
return true; return true;
@ -1829,13 +1828,6 @@ DEF_CONSOLE_CMD(ConCompanies)
SetDParam(0, c->index); SetDParam(0, c->index);
std::string company_name = GetString(STR_COMPANY_NAME); std::string company_name = GetString(STR_COMPANY_NAME);
const char *password_state = "";
if (c->is_ai) {
password_state = "AI";
} else if (_network_server) {
password_state = _network_company_states[c->index].password.empty() ? "unprotected" : "protected";
}
std::string colour = GetString(STR_COLOUR_DARK_BLUE + _company_colours[c->index]); std::string colour = GetString(STR_COLOUR_DARK_BLUE + _company_colours[c->index]);
IConsolePrint(CC_INFO, "#:{}({}) Company Name: '{}' Year Founded: {} Money: {} Loan: {} Value: {} (T:{}, R:{}, P:{}, S:{}) {}", IConsolePrint(CC_INFO, "#:{}({}) Company Name: '{}' Year Founded: {} Money: {} Loan: {} Value: {} (T:{}, R:{}, P:{}, S:{}) {}",
c->index + 1, colour, company_name, c->index + 1, colour, company_name,
@ -1844,7 +1836,7 @@ DEF_CONSOLE_CMD(ConCompanies)
c->group_all[VEH_ROAD].num_vehicle, c->group_all[VEH_ROAD].num_vehicle,
c->group_all[VEH_AIRCRAFT].num_vehicle, c->group_all[VEH_AIRCRAFT].num_vehicle,
c->group_all[VEH_SHIP].num_vehicle, c->group_all[VEH_SHIP].num_vehicle,
password_state); c->is_ai ? "AI" : "");
} }
return true; return true;
@ -1915,59 +1907,56 @@ DEF_CONSOLE_CMD(ConSayClient)
return true; return true;
} }
DEF_CONSOLE_CMD(ConCompanyPassword)
{
if (argc == 0) {
if (_network_dedicated) {
IConsolePrint(CC_HELP, "Change the password of a company. Usage: 'company_pw <company-no> \"<password>\".");
} else if (_network_server) {
IConsolePrint(CC_HELP, "Change the password of your or any other company. Usage: 'company_pw [<company-no>] \"<password>\"'.");
} else {
IConsolePrint(CC_HELP, "Change the password of your company. Usage: 'company_pw \"<password>\"'.");
}
IConsolePrint(CC_HELP, "Use \"*\" to disable the password.");
return true;
}
CompanyID company_id;
std::string password;
const char *errormsg;
if (argc == 2) {
company_id = _local_company;
password = argv[1];
errormsg = "You have to own a company to make use of this command.";
} else if (argc == 3 && _network_server) {
company_id = (CompanyID)(atoi(argv[1]) - 1);
password = argv[2];
errormsg = "You have to specify the ID of a valid human controlled company.";
} else {
return false;
}
if (!Company::IsValidHumanID(company_id)) {
IConsolePrint(CC_ERROR, errormsg);
return false;
}
password = NetworkChangeCompanyPassword(company_id, password);
if (password.empty()) {
IConsolePrint(CC_INFO, "Company password cleared.");
} else {
IConsolePrint(CC_INFO, "Company password changed to '{}'.", password);
}
return true;
}
/** All the known authorized keys with their name. */ /** All the known authorized keys with their name. */
static std::vector<std::pair<std::string_view, NetworkAuthorizedKeys *>> _console_cmd_authorized_keys{ static std::vector<std::pair<std::string_view, NetworkAuthorizedKeys *>> _console_cmd_authorized_keys{
{ "rcon", &_settings_client.network.rcon_authorized_keys }, { "rcon", &_settings_client.network.rcon_authorized_keys },
{ "server", &_settings_client.network.server_authorized_keys }, { "server", &_settings_client.network.server_authorized_keys },
}; };
enum ConNetworkAuthorizedKeyAction {
CNAKA_LIST,
CNAKA_ADD,
CNAKA_REMOVE,
};
static void PerformNetworkAuthorizedKeyAction(std::string_view name, NetworkAuthorizedKeys *authorized_keys, ConNetworkAuthorizedKeyAction action, const std::string &authorized_key, CompanyID company = INVALID_COMPANY)
{
switch (action) {
case CNAKA_LIST:
IConsolePrint(CC_WHITE, "The authorized keys for {} are:", name);
for (auto &ak : *authorized_keys) IConsolePrint(CC_INFO, " {}", ak);
return;
case CNAKA_ADD:
if (authorized_keys->Contains(authorized_key)) {
IConsolePrint(CC_WARNING, "Not added {} to {} as it already exists.", authorized_key, name);
return;
}
if (company == INVALID_COMPANY) {
authorized_keys->Add(authorized_key);
} else {
Command<CMD_COMPANY_ALLOW_LIST_CTRL>::SendNet(STR_NULL, company, CALCA_ADD, authorized_key);
}
IConsolePrint(CC_INFO, "Added {} to {}.", authorized_key, name);
return;
case CNAKA_REMOVE:
if (!authorized_keys->Contains(authorized_key)) {
IConsolePrint(CC_WARNING, "Not removed {} from {} as it does not exist.", authorized_key, name);
return;
}
if (company == INVALID_COMPANY) {
authorized_keys->Remove(authorized_key);
} else {
Command<CMD_COMPANY_ALLOW_LIST_CTRL>::SendNet(STR_NULL, company, CALCA_REMOVE, authorized_key);
}
IConsolePrint(CC_INFO, "Removed {} from {}.", authorized_key, name);
return;
}
}
DEF_CONSOLE_CMD(ConNetworkAuthorizedKey) DEF_CONSOLE_CMD(ConNetworkAuthorizedKey)
{ {
if (argc <= 2) { if (argc <= 2) {
@ -1979,29 +1968,31 @@ DEF_CONSOLE_CMD(ConNetworkAuthorizedKey)
std::string buffer; std::string buffer;
for (auto [name, _] : _console_cmd_authorized_keys) fmt::format_to(std::back_inserter(buffer), ", {}", name); for (auto [name, _] : _console_cmd_authorized_keys) fmt::format_to(std::back_inserter(buffer), ", {}", name);
IConsolePrint(CC_HELP, "The supported types are: all{}.", buffer); IConsolePrint(CC_HELP, "The supported types are: all{} and company:<id>.", buffer);
return true; return true;
} }
bool valid_type = false; ///< Whether a valid type was given. ConNetworkAuthorizedKeyAction action;
std::string_view action_string = argv[1];
for (auto [name, authorized_keys] : _console_cmd_authorized_keys) { if (StrEqualsIgnoreCase(action_string, "list")) {
if (!StrEqualsIgnoreCase(argv[2], name) && !StrEqualsIgnoreCase(argv[2], "all")) continue; action = CNAKA_LIST;
} else if (StrEqualsIgnoreCase(action_string, "add")) {
valid_type = true; action = CNAKA_ADD;
} else if (StrEqualsIgnoreCase(action_string, "remove") || StrEqualsIgnoreCase(action_string, "delete")) {
if (StrEqualsIgnoreCase(argv[1], "list")) { action = CNAKA_REMOVE;
IConsolePrint(CC_WHITE, "The authorized keys for {} are:", name); } else {
for (auto &authorized_key : *authorized_keys) IConsolePrint(CC_INFO, " {}", authorized_key); IConsolePrint(CC_WARNING, "No valid action was given.");
continue; return false;
} }
std::string authorized_key;
if (action != CNAKA_LIST) {
if (argc <= 3) { if (argc <= 3) {
IConsolePrint(CC_ERROR, "You must enter the key."); IConsolePrint(CC_ERROR, "You must enter the key.");
return false; return false;
} }
std::string authorized_key = argv[3]; authorized_key = argv[3];
if (StrStartsWithIgnoreCase(authorized_key, "client:")) { if (StrStartsWithIgnoreCase(authorized_key, "client:")) {
std::string id_string(authorized_key.substr(7)); std::string id_string(authorized_key.substr(7));
authorized_key = NetworkGetPublicKeyOfClient(static_cast<ClientID>(std::stoi(id_string))); authorized_key = NetworkGetPublicKeyOfClient(static_cast<ClientID>(std::stoi(id_string)));
@ -2011,34 +2002,40 @@ DEF_CONSOLE_CMD(ConNetworkAuthorizedKey)
} }
} }
if (StrEqualsIgnoreCase(argv[1], "add")) { if (authorized_key.size() != NETWORK_PUBLIC_KEY_LENGTH - 1) {
if (authorized_keys->Add(authorized_key)) { IConsolePrint(CC_ERROR, "You must enter a valid authorized key.");
IConsolePrint(CC_INFO, "Added {} to {}.", authorized_key, name); return false;
} else {
IConsolePrint(CC_WARNING, "Not added {} to {} as it already exists.", authorized_key, name);
}
continue;
} }
if (StrEqualsIgnoreCase(argv[1], "remove")) {
if (authorized_keys->Remove(authorized_key)) {
IConsolePrint(CC_INFO, "Removed {} from {}.", authorized_key, name);
} else {
IConsolePrint(CC_WARNING, "Not removed {} from {} as it does not exist.", authorized_key, name);
}
continue;
}
IConsolePrint(CC_WARNING, "No valid action was given.");
return false;
} }
if (!valid_type) { std::string_view type = argv[2];
IConsolePrint(CC_WARNING, "No valid type was given."); if (StrEqualsIgnoreCase(type, "all")) {
return false; for (auto [name, authorized_keys] : _console_cmd_authorized_keys) PerformNetworkAuthorizedKeyAction(name, authorized_keys, action, authorized_key);
for (Company *c : Company::Iterate()) PerformNetworkAuthorizedKeyAction(fmt::format("company:{}", c->index + 1), &c->allow_list, action, authorized_key, c->index);
return true;
} }
return true; if (StrStartsWithIgnoreCase(type, "company:")) {
std::string id_string(type.substr(8));
Company *c = Company::GetIfValid(std::stoi(id_string) - 1);
if (c == nullptr) {
IConsolePrint(CC_ERROR, "You must enter a valid company id; see 'companies'.");
return false;
}
PerformNetworkAuthorizedKeyAction(type, &c->allow_list, action, authorized_key, c->index);
return true;
}
for (auto [name, authorized_keys] : _console_cmd_authorized_keys) {
if (StrEqualsIgnoreCase(type, name)) continue;
PerformNetworkAuthorizedKeyAction(name, authorized_keys, action, authorized_key);
return true;
}
IConsolePrint(CC_WARNING, "No valid type was given.");
return false;
} }
@ -2803,9 +2800,6 @@ void IConsoleStdLibRegister()
IConsole::CmdRegister("authorized_key", ConNetworkAuthorizedKey, ConHookServerOnly); IConsole::CmdRegister("authorized_key", ConNetworkAuthorizedKey, ConHookServerOnly);
IConsole::AliasRegister("ak", "authorized_key %+"); IConsole::AliasRegister("ak", "authorized_key %+");
IConsole::CmdRegister("company_pw", ConCompanyPassword, ConHookNeedNetwork);
IConsole::AliasRegister("company_password", "company_pw %+");
IConsole::AliasRegister("net_frame_freq", "setting frame_freq %+"); IConsole::AliasRegister("net_frame_freq", "setting frame_freq %+");
IConsole::AliasRegister("net_sync_freq", "setting sync_freq %+"); IConsole::AliasRegister("net_sync_freq", "setting sync_freq %+");
IConsole::AliasRegister("server_pw", "setting server_password %+"); IConsole::AliasRegister("server_pw", "setting server_password %+");
@ -2821,7 +2815,6 @@ void IConsoleStdLibRegister()
IConsole::AliasRegister("pause_on_join", "setting pause_on_join %+"); IConsole::AliasRegister("pause_on_join", "setting pause_on_join %+");
IConsole::AliasRegister("autoclean_companies", "setting autoclean_companies %+"); IConsole::AliasRegister("autoclean_companies", "setting autoclean_companies %+");
IConsole::AliasRegister("autoclean_protected", "setting autoclean_protected %+"); IConsole::AliasRegister("autoclean_protected", "setting autoclean_protected %+");
IConsole::AliasRegister("autoclean_unprotected", "setting autoclean_unprotected %+");
IConsole::AliasRegister("restart_game_year", "setting restart_game_year %+"); IConsole::AliasRegister("restart_game_year", "setting restart_game_year %+");
IConsole::AliasRegister("min_players", "setting min_active_clients %+"); IConsole::AliasRegister("min_players", "setting min_active_clients %+");
IConsole::AliasRegister("reload_cfg", "setting reload_cfg %+"); IConsole::AliasRegister("reload_cfg", "setting reload_cfg %+");

View File

@ -308,7 +308,6 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}By enabl
STR_BUTTON_DEFAULT :{BLACK}Default STR_BUTTON_DEFAULT :{BLACK}Default
STR_BUTTON_CANCEL :{BLACK}Cancel STR_BUTTON_CANCEL :{BLACK}Cancel
STR_BUTTON_OK :{BLACK}OK STR_BUTTON_OK :{BLACK}OK
STR_WARNING_PASSWORD_SECURITY :{YELLOW}Warning: Server administrators may be able to read any text entered here.
# On screen keyboard window # On screen keyboard window
STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ . STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ .
@ -2461,7 +2460,6 @@ STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Fetching
STR_NETWORK_CONNECTION_DISCONNECT :{BLACK}Disconnect STR_NETWORK_CONNECTION_DISCONNECT :{BLACK}Disconnect
STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server is protected. Enter password STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server is protected. Enter password
STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Company is protected. Enter password
# Network company list added strings # Network company list added strings
STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Online players STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Online players
@ -2488,6 +2486,7 @@ STR_NETWORK_CLIENT_LIST_PLAYER_NAME_QUERY_CAPTION :Your player nam
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP :{BLACK}Administrative actions to perform for this client STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP :{BLACK}Administrative actions to perform for this client
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP :{BLACK}Administrative actions to perform for this company STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP :{BLACK}Administrative actions to perform for this company
STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :{BLACK}Join this company STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :{BLACK}Join this company
STR_NETWORK_CLIENT_LIST_COMPANY_AUTHORIZE_TOOLTIP :{BLACK}Authorize this client to join your company
STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}Send a message to this player STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}Send a message to this player
STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}Send a message to all players of this company STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}Send a message to all players of this company
STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}Send a message to all spectators STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}Send a message to all spectators
@ -2510,13 +2509,11 @@ STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TURN :{BLACK}Via rela
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Kick STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Kick
STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Ban STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Ban
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Delete STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Delete
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK :Password unlock
STR_NETWORK_CLIENT_LIST_ASK_CAPTION :{WHITE}Admin action STR_NETWORK_CLIENT_LIST_ASK_CAPTION :{WHITE}Admin action
STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}Are you sure you want to kick player '{RAW_STRING}'? STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}Are you sure you want to kick player '{RAW_STRING}'?
STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}Are you sure you want to ban player '{RAW_STRING}'? STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}Are you sure you want to ban player '{RAW_STRING}'?
STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Are you sure you want to delete company '{COMPANY}'? STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Are you sure you want to delete company '{COMPANY}'?
STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}Are you sure you want to reset the password of company '{COMPANY}'?
STR_NETWORK_ASK_RELAY_CAPTION :{WHITE}Use relay? STR_NETWORK_ASK_RELAY_CAPTION :{WHITE}Use relay?
STR_NETWORK_ASK_RELAY_TEXT :{YELLOW}Failed to establish a connection between you and server '{RAW_STRING}'.{}Would you like to relay this session via '{RAW_STRING}'? STR_NETWORK_ASK_RELAY_TEXT :{YELLOW}Failed to establish a connection between you and server '{RAW_STRING}'.{}Would you like to relay this session via '{RAW_STRING}'?
@ -2533,19 +2530,9 @@ STR_NETWORK_ASK_SURVEY_YES :Yes
STR_NETWORK_SPECTATORS :Spectators STR_NETWORK_SPECTATORS :Spectators
# Network set password
STR_COMPANY_PASSWORD_CANCEL :{BLACK}Do not save the entered password
STR_COMPANY_PASSWORD_OK :{BLACK}Give the company the new password
STR_COMPANY_PASSWORD_CAPTION :{WHITE}Company password
STR_COMPANY_PASSWORD_MAKE_DEFAULT :{BLACK}Default company password
STR_COMPANY_PASSWORD_MAKE_DEFAULT_TOOLTIP :{BLACK}Use this company password as default for new companies
# Network company info join/password # Network company info join/password
STR_COMPANY_VIEW_JOIN :{BLACK}Join STR_COMPANY_VIEW_JOIN :{BLACK}Join
STR_COMPANY_VIEW_JOIN_TOOLTIP :{BLACK}Join and play as this company STR_COMPANY_VIEW_JOIN_TOOLTIP :{BLACK}Join and play as this company
STR_COMPANY_VIEW_PASSWORD :{BLACK}Password
STR_COMPANY_VIEW_PASSWORD_TOOLTIP :{BLACK}Password-protect your company to prevent unauthorised users from joining
STR_COMPANY_VIEW_SET_PASSWORD :{BLACK}Set company password
# Network chat # Network chat
STR_NETWORK_CHAT_SEND :{BLACK}Send STR_NETWORK_CHAT_SEND :{BLACK}Send

View File

@ -948,7 +948,6 @@ struct QueryStringWindow : public Window
{ {
QueryString editbox; ///< Editbox. QueryString editbox; ///< Editbox.
QueryStringFlags flags; ///< Flags controlling behaviour of the window. QueryStringFlags flags; ///< Flags controlling behaviour of the window.
Dimension warning_size; ///< How much space to use for the warning text
QueryStringWindow(StringID str, StringID caption, uint max_bytes, uint max_chars, WindowDesc *desc, Window *parent, CharSetFilter afilter, QueryStringFlags flags) : QueryStringWindow(StringID str, StringID caption, uint max_bytes, uint max_chars, WindowDesc *desc, Window *parent, CharSetFilter afilter, QueryStringFlags flags) :
Window(desc), editbox(max_bytes, max_chars) Window(desc), editbox(max_bytes, max_chars)
@ -965,27 +964,12 @@ struct QueryStringWindow : public Window
this->flags = flags; this->flags = flags;
this->InitNested(WN_QUERY_STRING); this->InitNested(WN_QUERY_STRING);
this->UpdateWarningStringSize();
this->parent = parent; this->parent = parent;
this->SetFocusedWidget(WID_QS_TEXT); this->SetFocusedWidget(WID_QS_TEXT);
} }
void UpdateWarningStringSize()
{
if (this->flags & QSF_PASSWORD) {
assert(this->nested_root->smallest_x > 0);
this->warning_size.width = this->nested_root->current_x - WidgetDimensions::scaled.frametext.Horizontal() - WidgetDimensions::scaled.framerect.Horizontal();
this->warning_size.height = GetStringHeight(STR_WARNING_PASSWORD_SECURITY, this->warning_size.width);
this->warning_size.height += WidgetDimensions::scaled.frametext.Vertical() + WidgetDimensions::scaled.framerect.Vertical();
} else {
this->warning_size = Dimension{ 0, 0 };
}
this->ReInit();
}
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
{ {
if (widget == WID_QS_DEFAULT && (this->flags & QSF_ENABLE_DEFAULT) == 0) { if (widget == WID_QS_DEFAULT && (this->flags & QSF_ENABLE_DEFAULT) == 0) {
@ -994,20 +978,6 @@ struct QueryStringWindow : public Window
resize.width = 0; resize.width = 0;
size.width = 0; size.width = 0;
} }
if (widget == WID_QS_WARNING) {
size = this->warning_size;
}
}
void DrawWidget(const Rect &r, WidgetID widget) const override
{
if (widget != WID_QS_WARNING) return;
if (this->flags & QSF_PASSWORD) {
DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect).Shrink(WidgetDimensions::scaled.frametext),
STR_WARNING_PASSWORD_SECURITY, TC_FROMSTRING, SA_CENTER);
}
} }
void SetStringParameters(WidgetID widget) const override void SetStringParameters(WidgetID widget) const override
@ -1061,7 +1031,6 @@ static constexpr NWidgetPart _nested_query_string_widgets[] = {
NWidget(WWT_PANEL, COLOUR_GREY), NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(WWT_EDITBOX, COLOUR_GREY, WID_QS_TEXT), SetMinimalSize(256, 12), SetFill(1, 1), SetPadding(2, 2, 2, 2), NWidget(WWT_EDITBOX, COLOUR_GREY, WID_QS_TEXT), SetMinimalSize(256, 12), SetFill(1, 1), SetPadding(2, 2, 2, 2),
EndContainer(), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_QS_WARNING), EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_QS_DEFAULT), SetMinimalSize(87, 12), SetFill(1, 1), SetDataTip(STR_BUTTON_DEFAULT, STR_NULL), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_QS_DEFAULT), SetMinimalSize(87, 12), SetFill(1, 1), SetDataTip(STR_BUTTON_DEFAULT, STR_NULL),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_QS_CANCEL), SetMinimalSize(86, 12), SetFill(1, 1), SetDataTip(STR_BUTTON_CANCEL, STR_NULL), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_QS_CANCEL), SetMinimalSize(86, 12), SetFill(1, 1), SetDataTip(STR_BUTTON_CANCEL, STR_NULL),

View File

@ -54,9 +54,8 @@ static const uint NETWORK_NAME_LENGTH = 80; ///< The m
static const uint NETWORK_COMPANY_NAME_LENGTH = 128; ///< The maximum length of the company name, in bytes including '\0' static const uint NETWORK_COMPANY_NAME_LENGTH = 128; ///< The maximum length of the company name, in bytes including '\0'
static const uint NETWORK_HOSTNAME_LENGTH = 80; ///< The maximum length of the host name, in bytes including '\0' static const uint NETWORK_HOSTNAME_LENGTH = 80; ///< The maximum length of the host name, in bytes including '\0'
static const uint NETWORK_HOSTNAME_PORT_LENGTH = 80 + 6; ///< The maximum length of the host name + port, in bytes including '\0'. The extra six is ":" + port number (with a max of 65536) static const uint NETWORK_HOSTNAME_PORT_LENGTH = 80 + 6; ///< The maximum length of the host name + port, in bytes including '\0'. The extra six is ":" + port number (with a max of 65536)
static const uint NETWORK_SERVER_ID_LENGTH = 33; ///< The maximum length of the network id of the servers, in bytes including '\0'
static const uint NETWORK_REVISION_LENGTH = 33; ///< The maximum length of the revision, in bytes including '\0' static const uint NETWORK_REVISION_LENGTH = 33; ///< The maximum length of the revision, in bytes including '\0'
static const uint NETWORK_PASSWORD_LENGTH = 33; ///< The maximum length of the password, in bytes including '\0' (must be >= NETWORK_SERVER_ID_LENGTH) static const uint NETWORK_PASSWORD_LENGTH = 33; ///< The maximum length of the password, in bytes including '\0'
static const uint NETWORK_CLIENT_NAME_LENGTH = 25; ///< The maximum length of a client's name, in bytes including '\0' static const uint NETWORK_CLIENT_NAME_LENGTH = 25; ///< The maximum length of a client's name, in bytes including '\0'
static const uint NETWORK_RCONCOMMAND_LENGTH = 500; ///< The maximum length of a rconsole command, in bytes including '\0' static const uint NETWORK_RCONCOMMAND_LENGTH = 500; ///< The maximum length of a rconsole command, in bytes including '\0'
static const uint NETWORK_GAMESCRIPT_JSON_LENGTH = 9000; ///< The maximum length of a receiving gamescript json string, in bytes including '\0'. static const uint NETWORK_GAMESCRIPT_JSON_LENGTH = 9000; ///< The maximum length of a receiving gamescript json string, in bytes including '\0'.
@ -96,5 +95,10 @@ static const uint NETWORK_MAX_GRF_COUNT = 255;
* This is related to \c X25519_KEY_SIZE in the network crypto internals. * This is related to \c X25519_KEY_SIZE in the network crypto internals.
*/ */
static const uint NETWORK_SECRET_KEY_LENGTH = 32 * 2 + 1; static const uint NETWORK_SECRET_KEY_LENGTH = 32 * 2 + 1;
/**
* The maximum length of the hexadecimal encoded public keys, in bytes including '\0'.
* This is related to \c X25519_KEY_SIZE in the network crypto internals.
*/
static const uint NETWORK_PUBLIC_KEY_LENGTH = 32 * 2 + 1;
#endif /* NETWORK_CORE_CONFIG_H */ #endif /* NETWORK_CORE_CONFIG_H */

View File

@ -333,7 +333,7 @@ protected:
* string Name of the company. * string Name of the company.
* string Name of the companies manager. * string Name of the companies manager.
* uint8_t Main company colour. * uint8_t Main company colour.
* bool Company is password protected. * bool Company is protected.
* uint32_t Year the company was inaugurated. * uint32_t Year the company was inaugurated.
* bool Company is an AI. * bool Company is an AI.
* @param p The packet that was just received. * @param p The packet that was just received.
@ -347,7 +347,7 @@ protected:
* string Name of the company. * string Name of the company.
* string Name of the companies manager. * string Name of the companies manager.
* uint8_t Main company colour. * uint8_t Main company colour.
* bool Company is password protected. * bool Company is protected.
* uint8_t Quarters of bankruptcy. * uint8_t Quarters of bankruptcy.
* uint8_t Owner of share 1. * uint8_t Owner of share 1.
* uint8_t Owner of share 2. * uint8_t Owner of share 2.

View File

@ -83,10 +83,8 @@ NetworkRecvStatus NetworkGameSocketHandler::HandlePacket(Packet &p)
case PACKET_SERVER_CLIENT_INFO: return this->Receive_SERVER_CLIENT_INFO(p); case PACKET_SERVER_CLIENT_INFO: return this->Receive_SERVER_CLIENT_INFO(p);
case PACKET_CLIENT_IDENTIFY: return this->Receive_CLIENT_IDENTIFY(p); case PACKET_CLIENT_IDENTIFY: return this->Receive_CLIENT_IDENTIFY(p);
case PACKET_SERVER_AUTH_REQUEST: return this->Receive_SERVER_AUTH_REQUEST(p); case PACKET_SERVER_AUTH_REQUEST: return this->Receive_SERVER_AUTH_REQUEST(p);
case PACKET_SERVER_NEED_COMPANY_PASSWORD: return this->Receive_SERVER_NEED_COMPANY_PASSWORD(p);
case PACKET_CLIENT_AUTH_RESPONSE: return this->Receive_CLIENT_AUTH_RESPONSE(p); case PACKET_CLIENT_AUTH_RESPONSE: return this->Receive_CLIENT_AUTH_RESPONSE(p);
case PACKET_SERVER_ENABLE_ENCRYPTION: return this->Receive_SERVER_ENABLE_ENCRYPTION(p); case PACKET_SERVER_ENABLE_ENCRYPTION: return this->Receive_SERVER_ENABLE_ENCRYPTION(p);
case PACKET_CLIENT_COMPANY_PASSWORD: return this->Receive_CLIENT_COMPANY_PASSWORD(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);
@ -104,7 +102,6 @@ NetworkRecvStatus NetworkGameSocketHandler::HandlePacket(Packet &p)
case PACKET_CLIENT_CHAT: return this->Receive_CLIENT_CHAT(p); case PACKET_CLIENT_CHAT: return this->Receive_CLIENT_CHAT(p);
case PACKET_SERVER_CHAT: return this->Receive_SERVER_CHAT(p); case PACKET_SERVER_CHAT: return this->Receive_SERVER_CHAT(p);
case PACKET_SERVER_EXTERNAL_CHAT: return this->Receive_SERVER_EXTERNAL_CHAT(p); case PACKET_SERVER_EXTERNAL_CHAT: return this->Receive_SERVER_EXTERNAL_CHAT(p);
case PACKET_CLIENT_SET_PASSWORD: return this->Receive_CLIENT_SET_PASSWORD(p);
case PACKET_CLIENT_SET_NAME: return this->Receive_CLIENT_SET_NAME(p); case PACKET_CLIENT_SET_NAME: return this->Receive_CLIENT_SET_NAME(p);
case PACKET_CLIENT_QUIT: return this->Receive_CLIENT_QUIT(p); case PACKET_CLIENT_QUIT: return this->Receive_CLIENT_QUIT(p);
case PACKET_CLIENT_ERROR: return this->Receive_CLIENT_ERROR(p); case PACKET_CLIENT_ERROR: return this->Receive_CLIENT_ERROR(p);
@ -118,7 +115,6 @@ NetworkRecvStatus NetworkGameSocketHandler::HandlePacket(Packet &p)
case PACKET_CLIENT_NEWGRFS_CHECKED: return this->Receive_CLIENT_NEWGRFS_CHECKED(p); case PACKET_CLIENT_NEWGRFS_CHECKED: return this->Receive_CLIENT_NEWGRFS_CHECKED(p);
case PACKET_SERVER_MOVE: return this->Receive_SERVER_MOVE(p); case PACKET_SERVER_MOVE: return this->Receive_SERVER_MOVE(p);
case PACKET_CLIENT_MOVE: return this->Receive_CLIENT_MOVE(p); case PACKET_CLIENT_MOVE: return this->Receive_CLIENT_MOVE(p);
case PACKET_SERVER_COMPANY_UPDATE: return this->Receive_SERVER_COMPANY_UPDATE(p);
case PACKET_SERVER_CONFIG_UPDATE: return this->Receive_SERVER_CONFIG_UPDATE(p); case PACKET_SERVER_CONFIG_UPDATE: return this->Receive_SERVER_CONFIG_UPDATE(p);
default: default:
@ -166,10 +162,8 @@ NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_GAME_INFO(Packet &) {
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_CLIENT_INFO); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_CLIENT_INFO); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_IDENTIFY(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_IDENTIFY); } NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_IDENTIFY(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_IDENTIFY); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_AUTH_REQUEST(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_AUTH_REQUEST); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_AUTH_REQUEST(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_AUTH_REQUEST); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_NEED_COMPANY_PASSWORD(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_NEED_COMPANY_PASSWORD); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_AUTH_RESPONSE(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_AUTH_RESPONSE); } NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_AUTH_RESPONSE(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_AUTH_RESPONSE); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_ENABLE_ENCRYPTION(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_ENABLE_ENCRYPTION); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_ENABLE_ENCRYPTION(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_ENABLE_ENCRYPTION); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_COMPANY_PASSWORD(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_COMPANY_PASSWORD); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_WELCOME(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_WELCOME); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_WELCOME(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_WELCOME); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_GETMAP); } NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_GETMAP); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_WAIT(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_WAIT); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_WAIT(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_WAIT); }
@ -187,7 +181,6 @@ NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_COMMAND(Packet &) { r
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_CHAT(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_CHAT); } NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_CHAT(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_CHAT); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_CHAT(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_CHAT); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_CHAT(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_CHAT); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_EXTERNAL_CHAT(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_EXTERNAL_CHAT); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_EXTERNAL_CHAT(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_EXTERNAL_CHAT); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_SET_PASSWORD(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_SET_PASSWORD); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_SET_NAME); } NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_SET_NAME); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_QUIT); } NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_QUIT); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_ERROR); } NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_ERROR); }
@ -201,7 +194,6 @@ NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_CHECK_NEWGRFS(Packet
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_NEWGRFS_CHECKED(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_NEWGRFS_CHECKED); } NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_NEWGRFS_CHECKED(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_NEWGRFS_CHECKED); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_MOVE(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_MOVE); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_MOVE(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_MOVE); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_MOVE(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_MOVE); } NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_MOVE(Packet &) { return this->ReceiveInvalidPacket(PACKET_CLIENT_MOVE); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_COMPANY_UPDATE(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_COMPANY_UPDATE); }
NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_CONFIG_UPDATE(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_CONFIG_UPDATE); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_CONFIG_UPDATE(Packet &) { return this->ReceiveInvalidPacket(PACKET_SERVER_CONFIG_UPDATE); }
void NetworkGameSocketHandler::DeferDeletion() void NetworkGameSocketHandler::DeferDeletion()

View File

@ -71,10 +71,6 @@ enum PacketGameType : uint8_t {
PACKET_SERVER_CHECK_NEWGRFS, ///< Server sends NewGRF IDs and MD5 checksums for the client to check. PACKET_SERVER_CHECK_NEWGRFS, ///< Server sends NewGRF IDs and MD5 checksums for the client to check.
PACKET_CLIENT_NEWGRFS_CHECKED, ///< Client acknowledges that it has all required NewGRFs. PACKET_CLIENT_NEWGRFS_CHECKED, ///< Client acknowledges that it has all required NewGRFs.
/* Checking the company passwords. */
PACKET_SERVER_NEED_COMPANY_PASSWORD, ///< Server requests the (hashed) company password.
PACKET_CLIENT_COMPANY_PASSWORD, ///< Client sends the (hashed) company password.
/* 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.
PACKET_SERVER_CLIENT_INFO, ///< Server sends you information about a client. PACKET_SERVER_CLIENT_INFO, ///< Server sends you information about a client.
@ -119,9 +115,7 @@ enum PacketGameType : uint8_t {
PACKET_SERVER_MOVE, ///< Server tells everyone that someone is moved to another company. PACKET_SERVER_MOVE, ///< Server tells everyone that someone is moved to another company.
/* Configuration updates. */ /* Configuration updates. */
PACKET_CLIENT_SET_PASSWORD, ///< A client (re)sets its company's password.
PACKET_CLIENT_SET_NAME, ///< A client changes its name. PACKET_CLIENT_SET_NAME, ///< A client changes its name.
PACKET_SERVER_COMPANY_UPDATE, ///< Information (password) of a company changed.
PACKET_SERVER_CONFIG_UPDATE, ///< Some network configuration important to the client changed. PACKET_SERVER_CONFIG_UPDATE, ///< Some network configuration important to the client changed.
/* A client quitting. */ /* A client quitting. */
@ -202,7 +196,8 @@ protected:
* Send information about a client: * Send information about a client:
* uint32_t ID of the client (always unique on a server. 1 = server, 0 is invalid). * uint32_t ID of the client (always unique on a server. 1 = server, 0 is invalid).
* uint8_t ID of the company the client is playing as (255 for spectators). * uint8_t ID of the company the client is playing as (255 for spectators).
* string Name of the client. * string Name of the client.
* string Public key of the client.
* @param p The packet that was just received. * @param p The packet that was just received.
*/ */
virtual NetworkRecvStatus Receive_SERVER_CLIENT_INFO(Packet &p); virtual NetworkRecvStatus Receive_SERVER_CLIENT_INFO(Packet &p);
@ -224,14 +219,6 @@ protected:
*/ */
virtual NetworkRecvStatus Receive_SERVER_AUTH_REQUEST(Packet &p); virtual NetworkRecvStatus Receive_SERVER_AUTH_REQUEST(Packet &p);
/**
* Indication to the client that the server needs a company password:
* uint32_t Generation seed.
* string Network ID of the server.
* @param p The packet that was just received.
*/
virtual NetworkRecvStatus Receive_SERVER_NEED_COMPANY_PASSWORD(Packet &p);
/** /**
* Send the response to the authentication request: * Send the response to the authentication request:
* 32 * uint8_t Public key of the client. * 32 * uint8_t Public key of the client.
@ -249,19 +236,9 @@ protected:
*/ */
virtual NetworkRecvStatus Receive_SERVER_ENABLE_ENCRYPTION(Packet &p); virtual NetworkRecvStatus Receive_SERVER_ENABLE_ENCRYPTION(Packet &p);
/**
* Send a password to the server to authorize
* uint8_t Password type (see NetworkPasswordType).
* string The password.
* @param p The packet that was just received.
*/
virtual NetworkRecvStatus Receive_CLIENT_COMPANY_PASSWORD(Packet &p);
/** /**
* The client is joined and ready to receive their map: * The client is joined and ready to receive their map:
* uint32_t Own client ID. * uint32_t Own client ID.
* uint32_t Generation seed.
* string Network ID of the server.
* @param p The packet that was just received. * @param p The packet that was just received.
*/ */
virtual NetworkRecvStatus Receive_SERVER_WELCOME(Packet &p); virtual NetworkRecvStatus Receive_SERVER_WELCOME(Packet &p);
@ -401,13 +378,6 @@ protected:
*/ */
virtual NetworkRecvStatus Receive_SERVER_EXTERNAL_CHAT(Packet &p); virtual NetworkRecvStatus Receive_SERVER_EXTERNAL_CHAT(Packet &p);
/**
* Set the password for the clients current company:
* string The password.
* @param p The packet that was just received.
*/
virtual NetworkRecvStatus Receive_CLIENT_SET_PASSWORD(Packet &p);
/** /**
* Gives the client a new name: * Gives the client a new name:
* string New name of the client. * string New name of the client.
@ -497,18 +467,10 @@ protected:
/** /**
* Request the server to move this client into another company: * Request the server to move this client into another company:
* uint8_t ID of the company the client wants to join. * uint8_t ID of the company the client wants to join.
* string Password, if the company is password protected.
* @param p The packet that was just received. * @param p The packet that was just received.
*/ */
virtual NetworkRecvStatus Receive_CLIENT_MOVE(Packet &p); virtual NetworkRecvStatus Receive_CLIENT_MOVE(Packet &p);
/**
* Update the clients knowledge of which company is password protected:
* uint16_t Bitwise representation of each company
* @param p The packet that was just received.
*/
virtual NetworkRecvStatus Receive_SERVER_COMPANY_UPDATE(Packet &p);
/** /**
* Update the clients knowledge of the max settings: * Update the clients knowledge of the max settings:
* uint8_t Maximum number of companies allowed. * uint8_t Maximum number of companies allowed.

View File

@ -67,7 +67,6 @@ 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?
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.
ClientID _redirect_console_to_client; ///< If not invalid, redirect the console output to a client. ClientID _redirect_console_to_client; ///< If not invalid, redirect the console output to a client.
uint8_t _network_reconnect; ///< Reconnect timeout uint8_t _network_reconnect; ///< Reconnect timeout
@ -85,7 +84,6 @@ uint32_t _sync_seed_2; ///< Second part of the seed.
#endif #endif
uint32_t _sync_frame; ///< The frame to perform the sync check. uint32_t _sync_frame; ///< The frame to perform the sync check.
bool _network_first_time; ///< Whether we have finished joining or not. bool _network_first_time; ///< Whether we have finished joining or not.
CompanyMask _network_company_passworded; ///< Bitmask of the password status of all companies.
static_assert((int)NETWORK_COMPANY_NAME_LENGTH == MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH); static_assert((int)NETWORK_COMPANY_NAME_LENGTH == MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH);
@ -126,6 +124,28 @@ NetworkClientInfo::~NetworkClientInfo()
return nullptr; return nullptr;
} }
/**
* Returns whether the given company can be joined by this client.
* @param company_id The id of the company.
* @return \c true when this company is allowed to join, otherwise \c false.
*/
bool NetworkClientInfo::CanJoinCompany(CompanyID company_id) const
{
Company *c = Company::GetIfValid(company_id);
return c != nullptr && c->allow_list.Contains(this->public_key);
}
/**
* Returns whether the given company can be joined by this client.
* @param company_id The id of the company.
* @return \c true when this company is allowed to join, otherwise \c false.
*/
bool NetworkCanJoinCompany(CompanyID company_id)
{
NetworkClientInfo *info = NetworkClientInfo::GetByClientID(_network_own_client_id);
return info != nullptr && info->CanJoinCompany(company_id);
}
/** /**
* Return the client state given it's client-identifier * Return the client state given it's client-identifier
* @param client_id the ClientID to search for * @param client_id the ClientID to search for
@ -165,10 +185,12 @@ bool NetworkAuthorizedKeys::Contains(std::string_view key) const
/** /**
* Add the given key to the authorized keys, when it is not already contained. * Add the given key to the authorized keys, when it is not already contained.
* @param key The key to add. * @param key The key to add.
* @return \c true when the key was added, \c false when the key already existed. * @return \c true when the key was added, \c false when the key already existed or the key was empty.
*/ */
bool NetworkAuthorizedKeys::Add(std::string_view key) bool NetworkAuthorizedKeys::Add(std::string_view key)
{ {
if (key.empty()) return false;
auto iter = FindKey(this, key); auto iter = FindKey(this, key);
if (iter != this->end()) return false; if (iter != this->end()) return false;
@ -205,68 +227,6 @@ uint8_t NetworkSpectatorCount()
return count; return count;
} }
/**
* Change the company password of a given company.
* @param company_id ID of the company the password should be changed for.
* @param password The unhashed password we like to set ('*' or '' resets the password)
* @return The password.
*/
std::string NetworkChangeCompanyPassword(CompanyID company_id, std::string password)
{
if (password.compare("*") == 0) password = "";
if (_network_server) {
NetworkServerSetCompanyPassword(company_id, password, false);
} else {
NetworkClientSetCompanyPassword(password);
}
return password;
}
/**
* Hash the given password using server ID and game seed.
* @param password Password to hash.
* @param password_server_id Server ID.
* @param password_game_seed Game seed.
* @return The hashed password.
*/
std::string GenerateCompanyPasswordHash(const std::string &password, const std::string &password_server_id, uint32_t password_game_seed)
{
if (password.empty()) return password;
size_t password_length = password.size();
size_t password_server_id_length = password_server_id.size();
std::ostringstream salted_password;
/* Add the password with the server's ID and game seed as the salt. */
for (uint i = 0; i < NETWORK_SERVER_ID_LENGTH - 1; i++) {
char password_char = (i < password_length ? password[i] : 0);
char server_id_char = (i < password_server_id_length ? password_server_id[i] : 0);
char seed_char = password_game_seed >> (i % 32);
salted_password << (char)(password_char ^ server_id_char ^ seed_char); // Cast needed, otherwise interpreted as integer to format
}
Md5 checksum;
MD5Hash digest;
/* Generate the MD5 hash */
std::string salted_password_string = salted_password.str();
checksum.Append(salted_password_string.data(), salted_password_string.size());
checksum.Finish(digest);
return FormatArrayAsHex(digest);
}
/**
* Check if the company we want to join requires a password.
* @param company_id id of the company we want to check the 'passworded' flag for.
* @return true if the company requires a password.
*/
bool NetworkCompanyIsPassworded(CompanyID company_id)
{
return HasBit(_network_company_passworded, company_id);
}
/* This puts a text-message to the console, or in the future, the chat-box, /* This puts a text-message to the console, or in the future, the chat-box,
* (to keep it all a bit more general) * (to keep it all a bit more general)
@ -663,10 +623,6 @@ void NetworkClose(bool close_admins)
NetworkFreeLocalCommandQueue(); NetworkFreeLocalCommandQueue();
delete[] _network_company_states;
_network_company_states = nullptr;
_network_company_passworded = 0;
InitializeNetworkPools(close_admins); InitializeNetworkPools(close_admins);
} }
@ -813,7 +769,7 @@ public:
/** /**
* Join a client to the server at with the given connection string. * Join a client to the server at with the given connection string.
* The default for the passwords is \c nullptr. When the server or company needs a * The default for the passwords is \c nullptr. When the server needs a
* password and none is given, the user is asked to enter the password in the GUI. * password and none is given, the user is asked to enter the password in the GUI.
* This function will return false whenever some information required to join is not * This function will return false whenever some information required to join is not
* correct such as the company number or the client's name, or when there is not * correct such as the company number or the client's name, or when there is not
@ -825,10 +781,9 @@ public:
* @param connection_string The IP address, port and company number to join as. * @param connection_string The IP address, port and company number to join as.
* @param default_company The company number to join as when none is given. * @param default_company The company number to join as when none is given.
* @param join_server_password The password for the server. * @param join_server_password The password for the server.
* @param join_company_password The password for the company.
* @return Whether the join has started. * @return Whether the join has started.
*/ */
bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const std::string &join_server_password, const std::string &join_company_password) bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const std::string &join_server_password)
{ {
Debug(net, 9, "NetworkClientConnectGame(): connection_string={}", connection_string); Debug(net, 9, "NetworkClientConnectGame(): connection_string={}", connection_string);
@ -841,7 +796,6 @@ bool NetworkClientConnectGame(const std::string &connection_string, CompanyID de
_network_join.connection_string = resolved_connection_string; _network_join.connection_string = resolved_connection_string;
_network_join.company = join_as; _network_join.company = join_as;
_network_join.server_password = join_server_password; _network_join.server_password = join_server_password;
_network_join.company_password = join_company_password;
if (_game_mode == GM_MENU) { if (_game_mode == GM_MENU) {
/* From the menu we can immediately continue with the actual join. */ /* From the menu we can immediately continue with the actual join. */
@ -887,6 +841,9 @@ static void NetworkInitGameInfo()
ci->client_playas = _network_dedicated ? COMPANY_SPECTATOR : COMPANY_FIRST; ci->client_playas = _network_dedicated ? COMPANY_SPECTATOR : COMPANY_FIRST;
ci->client_name = _settings_client.network.client_name; ci->client_name = _settings_client.network.client_name;
NetworkAuthenticationClientHandler::EnsureValidSecretKeyAndUpdatePublicKey(_settings_client.network.client_secret_key, _settings_client.network.client_public_key);
ci->public_key = _settings_client.network.client_public_key;
} }
/** /**
@ -958,7 +915,6 @@ bool NetworkServerStart()
Debug(net, 5, "Starting listeners for incoming server queries"); Debug(net, 5, "Starting listeners for incoming server queries");
NetworkUDPServerListen(); NetworkUDPServerListen();
_network_company_states = new NetworkCompanyState[MAX_COMPANIES];
_network_server = true; _network_server = true;
_networking = true; _networking = true;
_frame_counter = 0; _frame_counter = 0;
@ -968,7 +924,6 @@ bool NetworkServerStart()
_network_own_client_id = CLIENT_ID_SERVER; _network_own_client_id = CLIENT_ID_SERVER;
_network_clients_connected = 0; _network_clients_connected = 0;
_network_company_passworded = 0;
NetworkInitGameInfo(); NetworkInitGameInfo();
@ -1296,11 +1251,6 @@ void NetworkGameLoop()
NetworkSend(); NetworkSend();
} }
static void NetworkGenerateServerId()
{
_settings_client.network.network_id = GenerateUid("OpenTTD Server ID");
}
/** This tries to launch the network for a given OS */ /** This tries to launch the network for a given OS */
void NetworkStartUp() void NetworkStartUp()
{ {
@ -1310,9 +1260,6 @@ void NetworkStartUp()
_network_available = NetworkCoreInitialize(); _network_available = NetworkCoreInitialize();
_network_dedicated = false; _network_dedicated = false;
/* Generate an server id when there is none yet */
if (_settings_client.network.network_id.empty()) NetworkGenerateServerId();
_network_game_info = {}; _network_game_info = {};
NetworkInitialize(); NetworkInitialize();

View File

@ -328,7 +328,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyInfo(const Company
SetDParam(0, c->index); SetDParam(0, c->index);
p->Send_string(GetString(STR_PRESIDENT_NAME)); p->Send_string(GetString(STR_PRESIDENT_NAME));
p->Send_uint8 (c->colour); p->Send_uint8 (c->colour);
p->Send_bool (NetworkCompanyIsPassworded(c->index)); p->Send_bool (true);
p->Send_uint32(c->inaugurated_year.base()); p->Send_uint32(c->inaugurated_year.base());
p->Send_bool (c->is_ai); p->Send_bool (c->is_ai);
p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy
@ -353,7 +353,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyUpdate(const Compa
SetDParam(0, c->index); SetDParam(0, c->index);
p->Send_string(GetString(STR_PRESIDENT_NAME)); p->Send_string(GetString(STR_PRESIDENT_NAME));
p->Send_uint8 (c->colour); p->Send_uint8 (c->colour);
p->Send_bool (NetworkCompanyIsPassworded(c->index)); p->Send_bool (true);
p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy
this->SendPacket(std::move(p)); this->SendPacket(std::move(p));

View File

@ -24,6 +24,7 @@ extern NetworkClientInfoPool _networkclientinfo_pool;
struct NetworkClientInfo : NetworkClientInfoPool::PoolItem<&_networkclientinfo_pool> { struct NetworkClientInfo : NetworkClientInfoPool::PoolItem<&_networkclientinfo_pool> {
ClientID client_id; ///< Client identifier (same as ClientState->client_id) ClientID client_id; ///< Client identifier (same as ClientState->client_id)
std::string client_name; ///< Name of the client std::string client_name; ///< Name of the client
std::string public_key; ///< The public key of the client.
CompanyID client_playas; ///< As which company is this client playing (CompanyID) CompanyID client_playas; ///< As which company is this client playing (CompanyID)
TimerGameEconomy::Date join_date; ///< Gamedate the client has joined TimerGameEconomy::Date join_date; ///< Gamedate the client has joined
@ -35,6 +36,8 @@ struct NetworkClientInfo : NetworkClientInfoPool::PoolItem<&_networkclientinfo_p
~NetworkClientInfo(); ~NetworkClientInfo();
static NetworkClientInfo *GetByClientID(ClientID client_id); static NetworkClientInfo *GetByClientID(ClientID client_id);
bool CanJoinCompany(CompanyID company_id) const;
}; };
#endif /* NETWORK_BASE_H */ #endif /* NETWORK_BASE_H */

View File

@ -313,11 +313,6 @@ ClientNetworkGameSocketHandler * ClientNetworkGameSocketHandler::my_client = nul
/** Last frame we performed an ack. */ /** Last frame we performed an ack. */
static uint32_t last_ack_frame; static uint32_t last_ack_frame;
/** One bit of 'entropy' used to generate a salt for the company passwords. */
static uint32_t _password_game_seed;
/** The other bit of 'entropy' used to generate a salt for the company passwords. */
static std::string _password_server_id;
/** Maximum number of companies of the currently joined server. */ /** Maximum number of companies of the currently joined server. */
static uint8_t _network_server_max_companies; static uint8_t _network_server_max_companies;
/** The current name of the server you are on. */ /** The current name of the server you are on. */
@ -326,9 +321,6 @@ std::string _network_server_name;
/** Information about the game to join to. */ /** Information about the game to join to. */
NetworkJoinInfo _network_join; NetworkJoinInfo _network_join;
/** Make sure the server ID length is the same as a md5 hash. */
static_assert(NETWORK_SERVER_ID_LENGTH == MD5_HASH_BYTES * 2 + 1);
/*********** /***********
* Sending functions * Sending functions
************/ ************/
@ -388,20 +380,6 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendAuthResponse()
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;
} }
/**
* Set the company password as requested.
* @param password The company password.
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyPassword(const std::string &password)
{
Debug(net, 9, "Client::SendCompanyPassword()");
auto p = std::make_unique<Packet>(my_client, PACKET_CLIENT_COMPANY_PASSWORD);
p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed));
my_client->SendPacket(std::move(p));
return NETWORK_RECV_STATUS_OKAY;
}
/** Request the map from the server. */ /** Request the map from the server. */
NetworkRecvStatus ClientNetworkGameSocketHandler::SendGetMap() NetworkRecvStatus ClientNetworkGameSocketHandler::SendGetMap()
{ {
@ -485,21 +463,6 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendError(NetworkErrorCode err
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;
} }
/**
* Tell the server that we like to change the password of the company.
* @param password The new password.
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const std::string &password)
{
Debug(net, 9, "Client::SendSetPassword()");
auto p = std::make_unique<Packet>(my_client, PACKET_CLIENT_SET_PASSWORD);
p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed));
my_client->SendPacket(std::move(p));
return NETWORK_RECV_STATUS_OKAY;
}
/** /**
* Tell the server that we like to change the name of the client. * Tell the server that we like to change the name of the client.
* @param name The new name. * @param name The new name.
@ -547,15 +510,13 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const std::string &pa
/** /**
* Ask the server to move us. * Ask the server to move us.
* @param company The company to move to. * @param company The company to move to.
* @param password The password of the company to move to.
*/ */
NetworkRecvStatus ClientNetworkGameSocketHandler::SendMove(CompanyID company, const std::string &password) NetworkRecvStatus ClientNetworkGameSocketHandler::SendMove(CompanyID company)
{ {
Debug(net, 9, "Client::SendMove(): company={}", company); Debug(net, 9, "Client::SendMove(): company={}", company);
auto p = std::make_unique<Packet>(my_client, PACKET_CLIENT_MOVE); auto p = std::make_unique<Packet>(my_client, PACKET_CLIENT_MOVE);
p->Send_uint8(company); p->Send_uint8(company);
p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _password_game_seed));
my_client->SendPacket(std::move(p)); my_client->SendPacket(std::move(p));
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;
} }
@ -608,6 +569,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac
Debug(net, 9, "Client::Receive_SERVER_CLIENT_INFO(): client_id={}, playas={}", client_id, playas); Debug(net, 9, "Client::Receive_SERVER_CLIENT_INFO(): client_id={}, playas={}", client_id, playas);
std::string name = p.Recv_string(NETWORK_NAME_LENGTH); std::string name = p.Recv_string(NETWORK_NAME_LENGTH);
std::string public_key = p.Recv_string(NETWORK_PUBLIC_KEY_LENGTH);
if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET; if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT; if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT;
@ -632,6 +594,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac
ci->client_playas = playas; ci->client_playas = playas;
ci->client_name = name; ci->client_name = name;
ci->public_key = public_key;
InvalidateWindowData(WC_CLIENT_LIST, 0); InvalidateWindowData(WC_CLIENT_LIST, 0);
@ -651,6 +614,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac
if (client_id == _network_own_client_id) this->SetInfo(ci); if (client_id == _network_own_client_id) this->SetInfo(ci);
ci->client_name = name; ci->client_name = name;
ci->public_key = public_key;
InvalidateWindowData(WC_CLIENT_LIST, 0); InvalidateWindowData(WC_CLIENT_LIST, 0);
@ -745,7 +709,7 @@ class ClientGamePasswordRequestHandler : public NetworkAuthenticationPasswordReq
if (!_network_join.server_password.empty()) { if (!_network_join.server_password.empty()) {
request->Reply(_network_join.server_password); request->Reply(_network_join.server_password);
} else { } else {
ShowNetworkNeedPassword(NETWORK_GAME_PASSWORD, request); ShowNetworkNeedPassword(request);
} }
} }
}; };
@ -793,34 +757,6 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ENABLE_ENCRYPTI
return this->SendIdentify(); return this->SendIdentify();
} }
class CompanyPasswordRequest : public NetworkAuthenticationPasswordRequest {
virtual void Reply(const std::string &password) override
{
MyClient::SendCompanyPassword(password);
}
};
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEED_COMPANY_PASSWORD(Packet &p)
{
if (this->status < STATUS_ENCRYPTED || this->status >= STATUS_AUTH_COMPANY) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
Debug(net, 9, "Client::status = AUTH_COMPANY");
this->status = STATUS_AUTH_COMPANY;
Debug(net, 9, "Client::Receive_SERVER_NEED_COMPANY_PASSWORD()");
_password_game_seed = p.Recv_uint32();
_password_server_id = p.Recv_string(NETWORK_SERVER_ID_LENGTH);
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
if (!_network_join.company_password.empty()) {
return SendCompanyPassword(_network_join.company_password);
}
ShowNetworkNeedPassword(NETWORK_COMPANY_PASSWORD, std::make_shared<CompanyPasswordRequest>());
return NETWORK_RECV_STATUS_OKAY;
}
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_WELCOME(Packet &p) NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_WELCOME(Packet &p)
{ {
if (this->status < STATUS_ENCRYPTED || this->status >= STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET; if (this->status < STATUS_ENCRYPTED || this->status >= STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
@ -831,10 +767,6 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_WELCOME(Packet
Debug(net, 9, "Client::Receive_SERVER_WELCOME(): client_id={}", _network_own_client_id); Debug(net, 9, "Client::Receive_SERVER_WELCOME(): client_id={}", _network_own_client_id);
/* Initialize the password hash salting variables, even if they were previously. */
_password_game_seed = p.Recv_uint32();
_password_server_id = p.Recv_string(NETWORK_SERVER_ID_LENGTH);
/* Start receiving the map */ /* Start receiving the map */
return SendGetMap(); return SendGetMap();
} }
@ -1258,19 +1190,6 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CONFIG_UPDATE(P
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;
} }
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_COMPANY_UPDATE(Packet &p)
{
if (this->status < STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
static_assert(sizeof(_network_company_passworded) <= sizeof(uint16_t));
_network_company_passworded = p.Recv_uint16();
SetWindowClassesDirty(WC_COMPANY);
Debug(net, 9, "Client::Receive_SERVER_COMPANY_UPDATE()");
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?
*/ */
@ -1327,12 +1246,10 @@ void NetworkClientSendRcon(const std::string &password, const std::string &comma
/** /**
* 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.
* @param pass the password, is only checked on the server end if a password is needed.
* @return void
*/ */
void NetworkClientRequestMove(CompanyID company_id, const std::string &pass) void NetworkClientRequestMove(CompanyID company_id)
{ {
MyClient::SendMove(company_id, pass); MyClient::SendMove(company_id);
} }
/** /**
@ -1442,15 +1359,6 @@ void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const
MyClient::SendChat(action, type, dest, msg, data); MyClient::SendChat(action, type, dest, msg, data);
} }
/**
* Set/Reset company password on the client side.
* @param password Password to be set.
*/
void NetworkClientSetCompanyPassword(const std::string &password)
{
MyClient::SendSetPassword(password);
}
/** /**
* Tell whether the client has team members who they can chat to. * Tell whether the client has team members who they can chat to.
* @param cio client to check members of. * @param cio client to check members of.

View File

@ -27,7 +27,6 @@ private:
STATUS_AUTH_GAME, ///< Last action was requesting game (server) password. STATUS_AUTH_GAME, ///< Last action was requesting game (server) password.
STATUS_ENCRYPTED, ///< The game authentication has completed and from here on the connection to the server is encrypted. STATUS_ENCRYPTED, ///< The game authentication has completed and from here on the connection to the server is encrypted.
STATUS_NEWGRFS_CHECK, ///< Last action was checking NewGRFs. STATUS_NEWGRFS_CHECK, ///< Last action was checking NewGRFs.
STATUS_AUTH_COMPANY, ///< Last action was requesting company password.
STATUS_AUTHORIZED, ///< The client is authorized at the server. STATUS_AUTHORIZED, ///< The client is authorized at the server.
STATUS_MAP_WAIT, ///< The client is waiting as someone else is downloading the map. STATUS_MAP_WAIT, ///< The client is waiting as someone else is downloading the map.
STATUS_MAP, ///< The client is downloading the map. STATUS_MAP, ///< The client is downloading the map.
@ -48,7 +47,6 @@ protected:
NetworkRecvStatus Receive_SERVER_CLIENT_INFO(Packet &p) override; NetworkRecvStatus Receive_SERVER_CLIENT_INFO(Packet &p) override;
NetworkRecvStatus Receive_SERVER_AUTH_REQUEST(Packet &p) override; NetworkRecvStatus Receive_SERVER_AUTH_REQUEST(Packet &p) override;
NetworkRecvStatus Receive_SERVER_ENABLE_ENCRYPTION(Packet &p) override; NetworkRecvStatus Receive_SERVER_ENABLE_ENCRYPTION(Packet &p) override;
NetworkRecvStatus Receive_SERVER_NEED_COMPANY_PASSWORD(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;
@ -68,7 +66,6 @@ protected:
NetworkRecvStatus Receive_SERVER_RCON(Packet &p) override; NetworkRecvStatus Receive_SERVER_RCON(Packet &p) override;
NetworkRecvStatus Receive_SERVER_CHECK_NEWGRFS(Packet &p) override; NetworkRecvStatus Receive_SERVER_CHECK_NEWGRFS(Packet &p) override;
NetworkRecvStatus Receive_SERVER_MOVE(Packet &p) override; NetworkRecvStatus Receive_SERVER_MOVE(Packet &p) override;
NetworkRecvStatus Receive_SERVER_COMPANY_UPDATE(Packet &p) override;
NetworkRecvStatus Receive_SERVER_CONFIG_UPDATE(Packet &p) override; NetworkRecvStatus Receive_SERVER_CONFIG_UPDATE(Packet &p) override;
static NetworkRecvStatus SendNewGRFsOk(); static NetworkRecvStatus SendNewGRFsOk();
@ -90,13 +87,11 @@ public:
static NetworkRecvStatus SendAck(); static NetworkRecvStatus SendAck();
static NetworkRecvStatus SendAuthResponse(); static NetworkRecvStatus SendAuthResponse();
static NetworkRecvStatus SendCompanyPassword(const std::string &password);
static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const std::string &msg, int64_t data); static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const std::string &msg, int64_t data);
static NetworkRecvStatus SendSetPassword(const std::string &password);
static NetworkRecvStatus SendSetName(const std::string &name); static NetworkRecvStatus SendSetName(const std::string &name);
static NetworkRecvStatus SendRCon(const std::string &password, const std::string &command); static NetworkRecvStatus SendRCon(const std::string &password, const std::string &command);
static NetworkRecvStatus SendMove(CompanyID company, const std::string &password); static NetworkRecvStatus SendMove(CompanyID company);
static bool IsConnected(); static bool IsConnected();
@ -109,7 +104,6 @@ public:
typedef ClientNetworkGameSocketHandler MyClient; typedef ClientNetworkGameSocketHandler MyClient;
void NetworkClient_Connected(); void NetworkClient_Connected();
void NetworkClientSetCompanyPassword(const std::string &password);
/** Information required to join a server. */ /** Information required to join a server. */
struct NetworkJoinInfo { struct NetworkJoinInfo {
@ -117,7 +111,6 @@ struct NetworkJoinInfo {
std::string connection_string; ///< The address of the server to join. std::string connection_string; ///< The address of the server to join.
CompanyID company; ///< The company to join. CompanyID company; ///< The company to join.
std::string server_password; ///< The password of the server to join. std::string server_password; ///< The password of the server to join.
std::string company_password; ///< The password of the company to join.
}; };
extern NetworkJoinInfo _network_join; extern NetworkJoinInfo _network_join;

View File

@ -443,6 +443,15 @@ void CombinedAuthenticationServerHandler::Add(CombinedAuthenticationServerHandle
this->SendResponse(); this->SendResponse();
} }
/**
* Ensures that the given secret key is valid, and when not overwrite it with a valid secret key. Then update the public key to be associated with the secret key.
* @param secret_key The location where the secret key is stored; can be overwritten when invalid.
* @param public_key The location where the public key is stored; can be overwritten when invalid.
*/
/* static */ void NetworkAuthenticationClientHandler::EnsureValidSecretKeyAndUpdatePublicKey(std::string &secret_key, std::string &public_key)
{
X25519AuthorizedKeyClientHandler::GetValidSecretKeyAndUpdatePublicKey(secret_key, public_key);
}
/** /**
* Create a NetworkAuthenticationClientHandler. * Create a NetworkAuthenticationClientHandler.

View File

@ -248,6 +248,7 @@ public:
*/ */
virtual bool ReceiveEnableEncryption(struct Packet &p) = 0; virtual bool ReceiveEnableEncryption(struct Packet &p) = 0;
static void EnsureValidSecretKeyAndUpdatePublicKey(std::string &secret_key, std::string &public_key);
static std::unique_ptr<NetworkAuthenticationClientHandler> Create(std::shared_ptr<NetworkAuthenticationPasswordRequestHandler> password_handler, std::string &secret_key, std::string &public_key); static std::unique_ptr<NetworkAuthenticationClientHandler> Create(std::shared_ptr<NetworkAuthenticationPasswordRequestHandler> password_handler, std::string &secret_key, std::string &public_key);
}; };

View File

@ -24,8 +24,6 @@
#include "../company_type.h" #include "../company_type.h"
#include "../string_type.h" #include "../string_type.h"
extern NetworkCompanyState *_network_company_states;
extern ClientID _network_own_client_id; extern ClientID _network_own_client_id;
extern ClientID _redirect_console_to_client; extern ClientID _redirect_console_to_client;
extern uint8_t _network_reconnect; extern uint8_t _network_reconnect;
@ -41,7 +39,6 @@ bool NetworkValidateServerName(std::string &server_name);
void NetworkUpdateClientName(const std::string &client_name); void NetworkUpdateClientName(const std::string &client_name);
void NetworkUpdateServerGameType(); void NetworkUpdateServerGameType();
bool NetworkCompanyHasClients(CompanyID company); bool NetworkCompanyHasClients(CompanyID company);
std::string NetworkChangeCompanyPassword(CompanyID company_id, std::string password);
void NetworkReboot(); void NetworkReboot();
void NetworkDisconnect(bool close_admins = true); void NetworkDisconnect(bool close_admins = true);
void NetworkGameLoop(); void NetworkGameLoop();
@ -51,13 +48,12 @@ void NetworkPopulateCompanyStats(NetworkCompanyStats *stats);
void NetworkUpdateClientInfo(ClientID client_id); void NetworkUpdateClientInfo(ClientID client_id);
void NetworkClientsToSpectators(CompanyID cid); void NetworkClientsToSpectators(CompanyID cid);
bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const std::string &join_server_password = "", const std::string &join_company_password = ""); bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const std::string &join_server_password = "");
void NetworkClientJoinGame(); void NetworkClientJoinGame();
void NetworkClientRequestMove(CompanyID company, const std::string &pass = ""); void NetworkClientRequestMove(CompanyID company);
void NetworkClientSendRcon(const std::string &password, const std::string &command); void NetworkClientSendRcon(const std::string &password, const std::string &command);
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, int64_t data = 0); void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, int64_t data = 0);
bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio); bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio);
bool NetworkCompanyIsPassworded(CompanyID company_id);
uint NetworkMaxCompaniesAllowed(); uint NetworkMaxCompaniesAllowed();
bool NetworkMaxCompaniesReached(); bool NetworkMaxCompaniesReached();
void NetworkPrintClients(); void NetworkPrintClients();
@ -73,6 +69,7 @@ void NetworkServerNewCompany(const Company *company, NetworkClientInfo *ci);
bool NetworkServerChangeClientName(ClientID client_id, const std::string &new_name); bool NetworkServerChangeClientName(ClientID client_id, const std::string &new_name);
bool NetworkCanJoinCompany(CompanyID company_id);
void NetworkServerDoMove(ClientID client_id, CompanyID company_id); void NetworkServerDoMove(ClientID client_id, CompanyID company_id);
void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const std::string &string); void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const std::string &string);
void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, ClientID from_id, int64_t data = 0, bool from_admin = false); void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, ClientID from_id, int64_t data = 0, bool from_admin = false);

View File

@ -1317,7 +1317,6 @@ enum DropDownAdmin {
DD_CLIENT_ADMIN_KICK, DD_CLIENT_ADMIN_KICK,
DD_CLIENT_ADMIN_BAN, DD_CLIENT_ADMIN_BAN,
DD_COMPANY_ADMIN_RESET, DD_COMPANY_ADMIN_RESET,
DD_COMPANY_ADMIN_UNLOCK,
}; };
/** /**
@ -1350,15 +1349,6 @@ static void AdminCompanyResetCallback(Window *, bool confirmed)
} }
} }
/**
* Callback function for admin command to unlock company.
* @param confirmed Iff the user pressed Yes.
*/
static void AdminCompanyUnlockCallback(Window *, bool confirmed)
{
if (confirmed) NetworkServerSetCompanyPassword(_admin_company_id, "", false);
}
/** /**
* Button shown for either a company or client in the client-list. * Button shown for either a company or client in the client-list.
* *
@ -1429,7 +1419,6 @@ using ClientButton = Button<ClientID>;
struct NetworkClientListWindow : Window { struct NetworkClientListWindow : Window {
private: private:
ClientListWidgets query_widget; ///< During a query this tracks what widget caused the query. ClientListWidgets query_widget; ///< During a query this tracks what widget caused the query.
CompanyID join_company; ///< During query for company password, this stores what company we wanted to join.
ClientID dd_client_id; ///< During admin dropdown, track which client this was for. ClientID dd_client_id; ///< During admin dropdown, track which client this was for.
CompanyID dd_company_id; ///< During admin dropdown, track which company this was for. CompanyID dd_company_id; ///< During admin dropdown, track which company this was for.
@ -1465,10 +1454,6 @@ private:
if (_network_server) { if (_network_server) {
NetworkServerDoMove(CLIENT_ID_SERVER, company_id); NetworkServerDoMove(CLIENT_ID_SERVER, company_id);
MarkWholeScreenDirty(); MarkWholeScreenDirty();
} else if (NetworkCompanyIsPassworded(company_id)) {
w->query_widget = WID_CL_COMPANY_JOIN;
w->join_company = company_id;
ShowQueryString(STR_EMPTY, STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION, NETWORK_PASSWORD_LENGTH, w, CS_ALPHANUMERAL, QSF_PASSWORD);
} else { } else {
NetworkClientRequestMove(company_id); NetworkClientRequestMove(company_id);
} }
@ -1520,7 +1505,6 @@ private:
{ {
DropDownList list; DropDownList list;
list.push_back(MakeDropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET, DD_COMPANY_ADMIN_RESET, NetworkCompanyHasClients(company_id))); list.push_back(MakeDropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET, DD_COMPANY_ADMIN_RESET, NetworkCompanyHasClients(company_id)));
list.push_back(MakeDropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK, DD_COMPANY_ADMIN_UNLOCK, !NetworkCompanyIsPassworded(company_id)));
Rect wi_rect; Rect wi_rect;
wi_rect.left = pt.x; wi_rect.left = pt.x;
@ -1542,18 +1526,25 @@ private:
ShowNetworkChatQueryWindow(DESTTYPE_CLIENT, client_id); ShowNetworkChatQueryWindow(DESTTYPE_CLIENT, client_id);
} }
static void OnClickClientAuthorize([[maybe_unused]] NetworkClientListWindow *w, [[maybe_unused]] Point pt, ClientID client_id)
{
AutoRestoreBackup<CompanyID> cur_company(_current_company, NetworkClientInfo::GetByClientID(_network_own_client_id)->client_playas);
Command<CMD_COMPANY_ALLOW_LIST_CTRL>::Post(CALCA_ADD, NetworkClientInfo::GetByClientID(client_id)->public_key);
}
/** /**
* Part of RebuildList() to create the information for a single company. * Part of RebuildList() to create the information for a single company.
* @param company_id The company to build the list for. * @param company_id The company to build the list for.
* @param client_playas The company the client is joined as. * @param client_playas The company the client is joined as.
* @param can_join_company Whether this company can be joined by us.
*/ */
void RebuildListCompany(CompanyID company_id, CompanyID client_playas) void RebuildListCompany(CompanyID company_id, CompanyID client_playas, bool can_join_company)
{ {
ButtonCommon *chat_button = new CompanyButton(SPR_CHAT, company_id == COMPANY_SPECTATOR ? STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP : STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyChat); ButtonCommon *chat_button = new CompanyButton(SPR_CHAT, company_id == COMPANY_SPECTATOR ? STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP : STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyChat);
if (_network_server) this->buttons[line_count].push_back(std::make_unique<CompanyButton>(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP, COLOUR_RED, company_id, &NetworkClientListWindow::OnClickCompanyAdmin, company_id == COMPANY_SPECTATOR)); if (_network_server) this->buttons[line_count].push_back(std::make_unique<CompanyButton>(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP, COLOUR_RED, company_id, &NetworkClientListWindow::OnClickCompanyAdmin, company_id == COMPANY_SPECTATOR));
this->buttons[line_count].emplace_back(chat_button); this->buttons[line_count].emplace_back(chat_button);
if (client_playas != company_id) this->buttons[line_count].push_back(std::make_unique<CompanyButton>(SPR_JOIN, STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyJoin, company_id != COMPANY_SPECTATOR && Company::Get(company_id)->is_ai)); if (can_join_company) this->buttons[line_count].push_back(std::make_unique<CompanyButton>(SPR_JOIN, STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyJoin, company_id != COMPANY_SPECTATOR && Company::Get(company_id)->is_ai));
this->line_count += 1; this->line_count += 1;
@ -1564,6 +1555,7 @@ private:
if (_network_server) this->buttons[line_count].push_back(std::make_unique<ClientButton>(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP, COLOUR_RED, ci->client_id, &NetworkClientListWindow::OnClickClientAdmin, _network_own_client_id == ci->client_id)); if (_network_server) this->buttons[line_count].push_back(std::make_unique<ClientButton>(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP, COLOUR_RED, ci->client_id, &NetworkClientListWindow::OnClickClientAdmin, _network_own_client_id == ci->client_id));
if (_network_own_client_id != ci->client_id) this->buttons[line_count].push_back(std::make_unique<ClientButton>(SPR_CHAT, STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP, COLOUR_ORANGE, ci->client_id, &NetworkClientListWindow::OnClickClientChat)); if (_network_own_client_id != ci->client_id) this->buttons[line_count].push_back(std::make_unique<ClientButton>(SPR_CHAT, STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP, COLOUR_ORANGE, ci->client_id, &NetworkClientListWindow::OnClickClientChat));
if (_network_own_client_id != ci->client_id && client_playas != COMPANY_SPECTATOR && !ci->CanJoinCompany(client_playas)) this->buttons[line_count].push_back(std::make_unique<ClientButton>(SPR_JOIN, STR_NETWORK_CLIENT_LIST_COMPANY_AUTHORIZE_TOOLTIP, COLOUR_GREEN, ci->client_id, &NetworkClientListWindow::OnClickClientAuthorize));
if (ci->client_id == _network_own_client_id) { if (ci->client_id == _network_own_client_id) {
this->player_self_index = this->line_count; this->player_self_index = this->line_count;
@ -1598,18 +1590,18 @@ private:
} }
if (client_playas != COMPANY_SPECTATOR) { if (client_playas != COMPANY_SPECTATOR) {
this->RebuildListCompany(client_playas, client_playas); this->RebuildListCompany(client_playas, client_playas, false);
} }
/* Companies */ /* Companies */
for (const Company *c : Company::Iterate()) { for (const Company *c : Company::Iterate()) {
if (c->index == client_playas) continue; if (c->index == client_playas) continue;
this->RebuildListCompany(c->index, client_playas); this->RebuildListCompany(c->index, client_playas, own_ci != nullptr && c->allow_list.Contains(own_ci->public_key));
} }
/* Spectators */ /* Spectators */
this->RebuildListCompany(COMPANY_SPECTATOR, client_playas); this->RebuildListCompany(COMPANY_SPECTATOR, client_playas, client_playas != COMPANY_SPECTATOR);
this->vscroll->SetCount(this->line_count); this->vscroll->SetCount(this->line_count);
} }
@ -1866,13 +1858,6 @@ public:
SetDParam(0, _admin_company_id); SetDParam(0, _admin_company_id);
break; break;
case DD_COMPANY_ADMIN_UNLOCK:
_admin_company_id = this->dd_company_id;
text = STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK;
callback = AdminCompanyUnlockCallback;
SetDParam(0, _admin_company_id);
break;
default: default:
NOT_REACHED(); NOT_REACHED();
} }
@ -1913,10 +1898,6 @@ public:
this->InvalidateData(); this->InvalidateData();
break; break;
} }
case WID_CL_COMPANY_JOIN:
NetworkClientRequestMove(this->join_company, str);
break;
} }
} }
@ -2233,127 +2214,13 @@ void ShowJoinStatusWindow()
new NetworkJoinStatusWindow(&_network_join_status_window_desc); new NetworkJoinStatusWindow(&_network_join_status_window_desc);
} }
void ShowNetworkNeedPassword(NetworkPasswordType npt, std::shared_ptr<NetworkAuthenticationPasswordRequest> request) void ShowNetworkNeedPassword(std::shared_ptr<NetworkAuthenticationPasswordRequest> request)
{ {
NetworkJoinStatusWindow *w = dynamic_cast<NetworkJoinStatusWindow *>(FindWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN)); NetworkJoinStatusWindow *w = dynamic_cast<NetworkJoinStatusWindow *>(FindWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN));
if (w == nullptr) return; if (w == nullptr) return;
w->request = request; w->request = request;
StringID caption; ShowQueryString(STR_EMPTY, STR_NETWORK_NEED_GAME_PASSWORD_CAPTION, NETWORK_PASSWORD_LENGTH, w, CS_ALPHANUMERAL, QSF_NONE);
switch (npt) {
default: NOT_REACHED();
case NETWORK_GAME_PASSWORD: caption = STR_NETWORK_NEED_GAME_PASSWORD_CAPTION; break;
case NETWORK_COMPANY_PASSWORD: caption = STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION; break;
}
ShowQueryString(STR_EMPTY, caption, NETWORK_PASSWORD_LENGTH, w, CS_ALPHANUMERAL, QSF_PASSWORD);
}
struct NetworkCompanyPasswordWindow : public Window {
QueryString password_editbox; ///< Password editbox.
Dimension warning_size; ///< How much space to use for the warning text
NetworkCompanyPasswordWindow(WindowDesc *desc, Window *parent) : Window(desc), password_editbox(NETWORK_PASSWORD_LENGTH)
{
this->InitNested(0);
this->UpdateWarningStringSize();
this->parent = parent;
this->querystrings[WID_NCP_PASSWORD] = &this->password_editbox;
this->password_editbox.cancel_button = WID_NCP_CANCEL;
this->password_editbox.ok_button = WID_NCP_OK;
this->SetFocusedWidget(WID_NCP_PASSWORD);
}
void UpdateWarningStringSize()
{
assert(this->nested_root->smallest_x > 0);
this->warning_size.width = this->nested_root->current_x - (WidgetDimensions::scaled.framerect.Horizontal()) * 2;
this->warning_size.height = GetStringHeight(STR_WARNING_PASSWORD_SECURITY, this->warning_size.width);
this->warning_size.height += (WidgetDimensions::scaled.framerect.Vertical()) * 2;
this->ReInit();
}
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
{
if (widget == WID_NCP_WARNING) {
size = this->warning_size;
}
}
void DrawWidget(const Rect &r, WidgetID widget) const override
{
if (widget != WID_NCP_WARNING) return;
DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect),
STR_WARNING_PASSWORD_SECURITY, TC_FROMSTRING, SA_CENTER);
}
void OnOk()
{
if (this->IsWidgetLowered(WID_NCP_SAVE_AS_DEFAULT_PASSWORD)) {
_settings_client.network.default_company_pass = this->password_editbox.text.buf;
}
NetworkChangeCompanyPassword(_local_company, this->password_editbox.text.buf);
}
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
{
switch (widget) {
case WID_NCP_OK:
this->OnOk();
[[fallthrough]];
case WID_NCP_CANCEL:
this->Close();
break;
case WID_NCP_SAVE_AS_DEFAULT_PASSWORD:
this->ToggleWidgetLoweredState(WID_NCP_SAVE_AS_DEFAULT_PASSWORD);
this->SetDirty();
break;
}
}
};
static constexpr NWidgetPart _nested_network_company_password_window_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_COMPANY_PASSWORD_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_NCP_BACKGROUND),
NWidget(NWID_VERTICAL), SetPIP(5, 5, 5),
NWidget(NWID_HORIZONTAL), SetPIP(5, 5, 5),
NWidget(WWT_TEXT, COLOUR_GREY, WID_NCP_LABEL), SetDataTip(STR_COMPANY_VIEW_PASSWORD, STR_NULL),
NWidget(WWT_EDITBOX, COLOUR_GREY, WID_NCP_PASSWORD), SetFill(1, 0), SetMinimalSize(194, 12), SetDataTip(STR_COMPANY_VIEW_SET_PASSWORD, STR_NULL),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(5, 0, 5),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_NCP_SAVE_AS_DEFAULT_PASSWORD), SetMinimalSize(194, 12),
SetDataTip(STR_COMPANY_PASSWORD_MAKE_DEFAULT, STR_COMPANY_PASSWORD_MAKE_DEFAULT_TOOLTIP),
EndContainer(),
EndContainer(),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_NCP_WARNING), EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NCP_CANCEL), SetFill(1, 0), SetDataTip(STR_BUTTON_CANCEL, STR_COMPANY_PASSWORD_CANCEL),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NCP_OK), SetFill(1, 0), SetDataTip(STR_BUTTON_OK, STR_COMPANY_PASSWORD_OK),
EndContainer(),
};
static WindowDesc _network_company_password_window_desc(
WDP_AUTO, nullptr, 0, 0,
WC_COMPANY_PASSWORD_WINDOW, WC_NONE,
0,
std::begin(_nested_network_company_password_window_widgets), std::end(_nested_network_company_password_window_widgets)
);
void ShowNetworkCompanyPasswordWindow(Window *parent)
{
CloseWindowById(WC_COMPANY_PASSWORD_WINDOW, 0);
new NetworkCompanyPasswordWindow(&_network_company_password_window_desc, parent);
} }
/** /**

View File

@ -17,12 +17,11 @@
#include "network_type.h" #include "network_type.h"
#include "network_gamelist.h" #include "network_gamelist.h"
void ShowNetworkNeedPassword(NetworkPasswordType npt, std::shared_ptr<class NetworkAuthenticationPasswordRequest> request); void ShowNetworkNeedPassword(std::shared_ptr<class NetworkAuthenticationPasswordRequest> request);
void ShowNetworkChatQueryWindow(DestType type, int dest); void ShowNetworkChatQueryWindow(DestType type, int dest);
void ShowJoinStatusWindow(); void ShowJoinStatusWindow();
void ShowNetworkGameWindow(); void ShowNetworkGameWindow();
void ShowClientList(); void ShowClientList();
void ShowNetworkCompanyPasswordWindow(Window *parent);
void ShowNetworkAskRelay(const std::string &server_connection_string, const std::string &relay_connection_string, const std::string &token); void ShowNetworkAskRelay(const std::string &server_connection_string, const std::string &relay_connection_string, const std::string &token);
void ShowNetworkAskSurvey(); void ShowNetworkAskSurvey();
void ShowSurveyResultTextfileWindow(); void ShowSurveyResultTextfileWindow();

View File

@ -80,8 +80,6 @@ extern std::string _network_server_name;
extern uint8_t _network_reconnect; extern uint8_t _network_reconnect;
extern CompanyMask _network_company_passworded;
void NetworkQueryServer(const std::string &connection_string); void NetworkQueryServer(const std::string &connection_string);
void GetBindAddresses(NetworkAddressList *addresses, uint16_t port); void GetBindAddresses(NetworkAddressList *addresses, uint16_t port);
@ -116,7 +114,6 @@ void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send,
uint NetworkCalculateLag(const NetworkClientSocket *cs); uint NetworkCalculateLag(const NetworkClientSocket *cs);
StringID GetNetworkErrorMsg(NetworkErrorCode err); StringID GetNetworkErrorMsg(NetworkErrorCode err);
bool NetworkMakeClientNameUnique(std::string &new_name); bool NetworkMakeClientNameUnique(std::string &new_name);
std::string GenerateCompanyPasswordHash(const std::string &password, const std::string &password_server_id, uint32_t password_game_seed);
std::string_view ParseCompanyFromConnectionString(const std::string &connection_string, CompanyID *company_id); std::string_view ParseCompanyFromConnectionString(const std::string &connection_string, CompanyID *company_id);
NetworkAddress ParseConnectionString(const std::string &connection_string, uint16_t default_port); NetworkAddress ParseConnectionString(const std::string &connection_string, uint16_t default_port);

View File

@ -332,6 +332,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendClientInfo(NetworkClientIn
p->Send_uint32(ci->client_id); p->Send_uint32(ci->client_id);
p->Send_uint8 (ci->client_playas); p->Send_uint8 (ci->client_playas);
p->Send_string(ci->client_name); p->Send_string(ci->client_name);
p->Send_string(ci->public_key);
this->SendPacket(std::move(p)); this->SendPacket(std::move(p));
} }
@ -412,8 +413,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck()
this->status = STATUS_NEWGRFS_CHECK; this->status = STATUS_NEWGRFS_CHECK;
if (_grfconfig == nullptr) { if (_grfconfig == nullptr) {
/* There are no NewGRFs, continue with the company password. */ /* There are no NewGRFs, so they're welcome. */
return this->SendNeedCompanyPassword(); return this->SendWelcome();
} }
auto p = std::make_unique<Packet>(this, PACKET_SERVER_CHECK_NEWGRFS, TCP_MTU); auto p = std::make_unique<Packet>(this, PACKET_SERVER_CHECK_NEWGRFS, TCP_MTU);
@ -472,39 +473,13 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendEnableEncryption()
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;
} }
/** Request the company password. */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedCompanyPassword()
{
Debug(net, 9, "client[{}] SendNeedCompanyPassword()", this->client_id);
/* Invalid packet when status is anything but STATUS_NEWGRFS_CHECK. */
if (this->status != STATUS_NEWGRFS_CHECK) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
Debug(net, 9, "client[{}] status = AUTH_COMPANY", this->client_id);
this->status = STATUS_AUTH_COMPANY;
NetworkClientInfo *ci = this->GetInfo();
if (!Company::IsValidID(ci->client_playas) || _network_company_states[ci->client_playas].password.empty()) {
return this->SendWelcome();
}
/* Reset 'lag' counters */
this->last_frame = this->last_frame_server = _frame_counter;
auto p = std::make_unique<Packet>(this, PACKET_SERVER_NEED_COMPANY_PASSWORD);
p->Send_uint32(_settings_game.game_creation.generation_seed);
p->Send_string(_settings_client.network.network_id);
this->SendPacket(std::move(p));
return NETWORK_RECV_STATUS_OKAY;
}
/** Send the client a welcome message with some basic information. */ /** Send the client a welcome message with some basic information. */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome() NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome()
{ {
Debug(net, 9, "client[{}] SendWelcome()", this->client_id); Debug(net, 9, "client[{}] SendWelcome()", this->client_id);
/* Invalid packet when status is anything but STATUS_AUTH_COMPANY. */ /* Invalid packet when status is anything but STATUS_NEWGRFS_CHECK. */
if (this->status != STATUS_AUTH_COMPANY) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); if (this->status != STATUS_NEWGRFS_CHECK) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
Debug(net, 9, "client[{}] status = AUTHORIZED", this->client_id); Debug(net, 9, "client[{}] status = AUTHORIZED", this->client_id);
this->status = STATUS_AUTHORIZED; this->status = STATUS_AUTHORIZED;
@ -516,8 +491,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome()
auto p = std::make_unique<Packet>(this, PACKET_SERVER_WELCOME); auto p = std::make_unique<Packet>(this, PACKET_SERVER_WELCOME);
p->Send_uint32(this->client_id); p->Send_uint32(this->client_id);
p->Send_uint32(_settings_game.game_creation.generation_seed);
p->Send_string(_settings_client.network.network_id);
this->SendPacket(std::move(p)); this->SendPacket(std::move(p));
/* Transmit info about all the active clients */ /* Transmit info about all the active clients */
@ -839,19 +812,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMove(ClientID client_id, C
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;
} }
/** Send an update about the company password states. */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyUpdate()
{
Debug(net, 9, "client[{}] SendCompanyUpdate()", this->client_id);
auto p = std::make_unique<Packet>(this, PACKET_SERVER_COMPANY_UPDATE);
static_assert(sizeof(_network_company_passworded) <= sizeof(uint16_t));
p->Send_uint16(_network_company_passworded);
this->SendPacket(std::move(p));
return NETWORK_RECV_STATUS_OKAY;
}
/** Send an update about the max company/spectator counts. */ /** Send an update about the max company/spectator counts. */
NetworkRecvStatus ServerNetworkGameSocketHandler::SendConfigUpdate() NetworkRecvStatus ServerNetworkGameSocketHandler::SendConfigUpdate()
{ {
@ -885,7 +845,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_NEWGRFS_CHECKED
Debug(net, 9, "client[{}] Receive_CLIENT_NEWGRFS_CHECKED()", this->client_id); Debug(net, 9, "client[{}] Receive_CLIENT_NEWGRFS_CHECKED()", this->client_id);
return this->SendNeedCompanyPassword(); return this->SendWelcome();
} }
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet &p) NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet &p)
@ -938,6 +898,11 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_IDENTIFY(Packet
if (!Company::IsValidHumanID(playas)) { if (!Company::IsValidHumanID(playas)) {
return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH); return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH);
} }
if (!Company::Get(playas)->allow_list.Contains(this->peer_public_key)) {
/* When we're not authorized, just bump us to a spectator. */
playas = COMPANY_SPECTATOR;
}
break; break;
} }
@ -959,6 +924,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_IDENTIFY(Packet
ci->join_date = TimerGameEconomy::date; ci->join_date = TimerGameEconomy::date;
ci->client_name = client_name; ci->client_name = client_name;
ci->client_playas = playas; ci->client_playas = playas;
ci->public_key = this->peer_public_key;
Debug(desync, 1, "client: {:08x}; {:02x}; {:02x}; {:02x}", TimerGameEconomy::date, TimerGameEconomy::date_fract, (int)ci->client_playas, (int)ci->index); Debug(desync, 1, "client: {:08x}; {:02x}; {:02x}; {:02x}", TimerGameEconomy::date, TimerGameEconomy::date_fract, (int)ci->client_playas, (int)ci->index);
/* Make sure companies to which people try to join are not autocleaned */ /* Make sure companies to which people try to join are not autocleaned */
@ -1019,29 +985,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_AUTH_RESPONSE(P
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;
} }
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMPANY_PASSWORD(Packet &p)
{
if (this->status != STATUS_AUTH_COMPANY) {
return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
}
Debug(net, 9, "client[{}] Receive_CLIENT_COMPANY_PASSWORD()", this->client_id);
std::string password = p.Recv_string(NETWORK_PASSWORD_LENGTH);
/* Check company password. Allow joining if we cleared the password meanwhile.
* Also, check the company is still valid - client could be moved to spectators
* in the middle of the authorization process */
CompanyID playas = this->GetInfo()->client_playas;
if (Company::IsValidID(playas) && !_network_company_states[playas].password.empty() &&
_network_company_states[playas].password.compare(password) != 0) {
/* Password is invalid */
return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
}
return this->SendWelcome();
}
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet &) NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet &)
{ {
/* The client was never joined.. so this is impossible, right? /* The client was never joined.. so this is impossible, right?
@ -1102,10 +1045,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MAP_OK(Packet &
NetworkAdminClientInfo(this, true); NetworkAdminClientInfo(this, true);
/* also update the new client with our max values */ /* also update the new client with our max values */
this->SendConfigUpdate(); return this->SendConfigUpdate();
/* quickly update the syncing client with company details */
return this->SendCompanyUpdate();
} }
/* Wrong status for this packet, give a warning to client, and close connection */ /* Wrong status for this packet, give a warning to client, and close connection */
@ -1177,6 +1117,24 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet
} }
} }
if (cp.cmd == CMD_COMPANY_ALLOW_LIST_CTRL) {
/* Maybe the client just got moved before allowing? */
if (ci->client_id != CLIENT_ID_SERVER && ci->client_playas != cp.company) return NETWORK_RECV_STATUS_OKAY;
/* Only allow clients to add/remove currently joined clients. The server owner does not go via this method, so is allowed to do more. */
std::string public_key = std::get<1>(EndianBufferReader::ToValue<CommandTraits<CMD_COMPANY_ALLOW_LIST_CTRL>::Args>(cp.data));
bool found = false;
for (const NetworkClientInfo *info : NetworkClientInfo::Iterate()) {
if (info->public_key == public_key) {
found = true;
break;
}
}
/* Maybe the client just left? */
if (!found) return NETWORK_RECV_STATUS_OKAY;
}
if (GetCommandFlags(cp.cmd) & CMD_CLIENT_ID) NetworkReplaceCommandClientId(cp, this->client_id); if (GetCommandFlags(cp.cmd) & CMD_CLIENT_ID) NetworkReplaceCommandClientId(cp, this->client_id);
this->incoming_queue.push_back(cp); this->incoming_queue.push_back(cp);
@ -1453,22 +1411,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_CHAT(Packet &p)
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;
} }
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_PASSWORD(Packet &p)
{
if (this->status != STATUS_ACTIVE) {
/* Illegal call, return error and ignore the packet */
return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
}
Debug(net, 9, "client[{}] Receive_CLIENT_SET_PASSWORD()", this->client_id);
std::string password = p.Recv_string(NETWORK_PASSWORD_LENGTH);
const NetworkClientInfo *ci = this->GetInfo();
NetworkServerSetCompanyPassword(ci->client_playas, password);
return NETWORK_RECV_STATUS_OKAY;
}
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet &p) NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet &p)
{ {
if (this->status != STATUS_ACTIVE) { if (this->status != STATUS_ACTIVE) {
@ -1540,16 +1482,9 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MOVE(Packet &p)
/* Check if the company is valid, we don't allow moving to AI companies */ /* Check if the company is valid, we don't allow moving to AI companies */
if (company_id != COMPANY_SPECTATOR && !Company::IsValidHumanID(company_id)) return NETWORK_RECV_STATUS_OKAY; if (company_id != COMPANY_SPECTATOR && !Company::IsValidHumanID(company_id)) return NETWORK_RECV_STATUS_OKAY;
/* Check if we require a password for this company */ if (company_id != COMPANY_SPECTATOR && !Company::Get(company_id)->allow_list.Contains(this->peer_public_key)) {
if (company_id != COMPANY_SPECTATOR && !_network_company_states[company_id].password.empty()) { Debug(net, 2, "Wrong public key from client-id #{} for company #{}", this->client_id, company_id + 1);
/* we need a password from the client - should be in this packet */ return NETWORK_RECV_STATUS_OKAY;
std::string password = p.Recv_string(NETWORK_PASSWORD_LENGTH);
/* Incorrect password sent, return! */
if (_network_company_states[company_id].password.compare(password) != 0) {
Debug(net, 2, "Wrong password from client-id #{} for company #{}", this->client_id, company_id + 1);
return NETWORK_RECV_STATUS_OKAY;
}
} }
/* if we get here we can move the client */ /* if we get here we can move the client */
@ -1614,11 +1549,10 @@ void NetworkUpdateClientInfo(ClientID client_id)
NetworkAdminClientUpdate(ci); NetworkAdminClientUpdate(ci);
} }
/** Check if the server has autoclean_companies activated /**
* Two things happen: * Remove companies that have not been used depending on the \c autoclean_companies setting
* 1) If a company is not protected, it is closed after 1 year (for example) * and values for \c autoclean_protected, which removes any company, and
* 2) If a company is protected, protection is disabled after 3 years (for example) * \c autoclean_novehicles, which removes companies without vehicles.
* (and item 1. happens a year later)
*/ */
static void NetworkAutoCleanCompanies() static void NetworkAutoCleanCompanies()
{ {
@ -1653,19 +1587,11 @@ static void NetworkAutoCleanCompanies()
/* The company is empty for one month more */ /* The company is empty for one month more */
if (c->months_empty != std::numeric_limits<decltype(c->months_empty)>::max()) c->months_empty++; if (c->months_empty != std::numeric_limits<decltype(c->months_empty)>::max()) c->months_empty++;
/* Is the company empty for autoclean_unprotected-months, and is there no protection? */ /* Is the company empty for autoclean_protected-months? */
if (_settings_client.network.autoclean_unprotected != 0 && c->months_empty > _settings_client.network.autoclean_unprotected && _network_company_states[c->index].password.empty()) { if (_settings_client.network.autoclean_protected != 0 && c->months_empty > _settings_client.network.autoclean_protected) {
/* Shut the company down */ /* Shut the company down */
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, c->index, CRR_AUTOCLEAN, INVALID_CLIENT_ID); Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, c->index, CRR_AUTOCLEAN, INVALID_CLIENT_ID);
IConsolePrint(CC_INFO, "Auto-cleaned company #{} with no password.", c->index + 1); IConsolePrint(CC_INFO, "Auto-cleaned company #{}.", c->index + 1);
}
/* Is the company empty for autoclean_protected-months, and there is a protection? */
if (_settings_client.network.autoclean_protected != 0 && c->months_empty > _settings_client.network.autoclean_protected && !_network_company_states[c->index].password.empty()) {
/* Unprotect the company */
_network_company_states[c->index].password.clear();
IConsolePrint(CC_INFO, "Auto-removed protection from company #{}.", c->index + 1);
c->months_empty = 0;
NetworkServerUpdateCompanyPassworded(c->index, false);
} }
/* Is the company empty for autoclean_novehicles-months, and has no vehicles? */ /* Is the company empty for autoclean_novehicles-months, and has no vehicles? */
if (_settings_client.network.autoclean_novehicles != 0 && c->months_empty > _settings_client.network.autoclean_novehicles && !HasBit(has_vehicles, c->index)) { if (_settings_client.network.autoclean_novehicles != 0 && c->months_empty > _settings_client.network.autoclean_novehicles && !HasBit(has_vehicles, c->index)) {
@ -1742,25 +1668,6 @@ bool NetworkServerChangeClientName(ClientID client_id, const std::string &new_na
return true; return true;
} }
/**
* Set/Reset a company password on the server end.
* @param company_id ID of the company the password should be changed for.
* @param password The new password.
* @param already_hashed Is the given password already hashed?
*/
void NetworkServerSetCompanyPassword(CompanyID company_id, const std::string &password, bool already_hashed)
{
if (!Company::IsValidHumanID(company_id)) return;
if (already_hashed) {
_network_company_states[company_id].password = password;
} else {
_network_company_states[company_id].password = GenerateCompanyPasswordHash(password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed);
}
NetworkServerUpdateCompanyPassworded(company_id, !_network_company_states[company_id].password.empty());
}
/** /**
* Handle the command-queue of a socket. * Handle the command-queue of a socket.
* @param cs The socket to handle the queue for. * @param cs The socket to handle the queue for.
@ -1880,7 +1787,6 @@ void NetworkServer_Tick(bool send_frame)
break; break;
case NetworkClientSocket::STATUS_AUTH_GAME: case NetworkClientSocket::STATUS_AUTH_GAME:
case NetworkClientSocket::STATUS_AUTH_COMPANY:
/* These don't block? */ /* These don't block? */
if (lag > _settings_client.network.max_password_time) { if (lag > _settings_client.network.max_password_time) {
IConsolePrint(CC_WARNING, "Client #{} (IP: {}) is dropped because it took longer than {} ticks to enter the password.", cs->client_id, cs->GetClientIP(), _settings_client.network.max_password_time); IConsolePrint(CC_WARNING, "Client #{} (IP: {}) is dropped because it took longer than {} ticks to enter the password.", cs->client_id, cs->GetClientIP(), _settings_client.network.max_password_time);
@ -2026,10 +1932,9 @@ void NetworkServerShowStatusToConsole()
{ {
static const char * const stat_str[] = { static const char * const stat_str[] = {
"inactive", "inactive",
"authorizing (server password)", "authorizing",
"identifing client", "identifing client",
"checking NewGRFs", "checking NewGRFs",
"authorizing (company password)",
"authorized", "authorized",
"waiting", "waiting",
"loading map", "loading map",
@ -2069,25 +1974,6 @@ void NetworkServerUpdateGameInfo()
if (_network_server) FillStaticNetworkServerGameInfo(); if (_network_server) FillStaticNetworkServerGameInfo();
} }
/**
* Tell that a particular company is (not) passworded.
* @param company_id The company that got/removed the password.
* @param passworded Whether the password was received or removed.
*/
void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded)
{
if (NetworkCompanyIsPassworded(company_id) == passworded) return;
SB(_network_company_passworded, company_id, 1, !!passworded);
SetWindowClassesDirty(WC_COMPANY);
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendCompanyUpdate();
}
NetworkAdminCompanyUpdate(Company::GetIfValid(company_id));
}
/** /**
* Handle the tid-bits of moving a client from one company to another. * Handle the tid-bits of moving a client from one company to another.
* @param client_id id of the client we want to move. * @param client_id id of the client we want to move.
@ -2268,20 +2154,13 @@ void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci)
if (!_network_server) return; if (!_network_server) return;
_network_company_states[c->index].password.clear();
NetworkServerUpdateCompanyPassworded(c->index, false);
if (ci != nullptr) { if (ci != nullptr) {
/* ci is nullptr when replaying, or for AIs. In neither case there is a client. */ /* ci is nullptr when replaying, or for AIs. In neither case there is a client. */
ci->client_playas = c->index; ci->client_playas = c->index;
NetworkUpdateClientInfo(ci->client_id); NetworkUpdateClientInfo(ci->client_id);
Command<CMD_COMPANY_ALLOW_LIST_CTRL>::SendNet(STR_NULL, c->index, CALCA_ADD, ci->public_key);
Command<CMD_RENAME_PRESIDENT>::SendNet(STR_NULL, c->index, ci->client_name); Command<CMD_RENAME_PRESIDENT>::SendNet(STR_NULL, c->index, ci->client_name);
}
if (ci != nullptr) {
/* ci is nullptr when replaying, or for AIs. In neither case there is a client.
We need to send Admin port update here so that they first know about the new company
and then learn about a possibly joining client (see FS#6025) */
NetworkServerSendChat(NETWORK_ACTION_COMPANY_NEW, DESTTYPE_BROADCAST, 0, "", ci->client_id, c->index + 1); NetworkServerSendChat(NETWORK_ACTION_COMPANY_NEW, DESTTYPE_BROADCAST, 0, "", ci->client_id, c->index + 1);
} }
} }

View File

@ -30,13 +30,11 @@ protected:
NetworkRecvStatus Receive_CLIENT_IDENTIFY(Packet &p) override; NetworkRecvStatus Receive_CLIENT_IDENTIFY(Packet &p) override;
NetworkRecvStatus Receive_CLIENT_GAME_INFO(Packet &p) override; NetworkRecvStatus Receive_CLIENT_GAME_INFO(Packet &p) override;
NetworkRecvStatus Receive_CLIENT_AUTH_RESPONSE(Packet &p) override; NetworkRecvStatus Receive_CLIENT_AUTH_RESPONSE(Packet &p) override;
NetworkRecvStatus Receive_CLIENT_COMPANY_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;
NetworkRecvStatus Receive_CLIENT_COMMAND(Packet &p) override; NetworkRecvStatus Receive_CLIENT_COMMAND(Packet &p) override;
NetworkRecvStatus Receive_CLIENT_CHAT(Packet &p) override; NetworkRecvStatus Receive_CLIENT_CHAT(Packet &p) override;
NetworkRecvStatus Receive_CLIENT_SET_PASSWORD(Packet &p) override;
NetworkRecvStatus Receive_CLIENT_SET_NAME(Packet &p) override; NetworkRecvStatus Receive_CLIENT_SET_NAME(Packet &p) override;
NetworkRecvStatus Receive_CLIENT_QUIT(Packet &p) override; NetworkRecvStatus Receive_CLIENT_QUIT(Packet &p) override;
NetworkRecvStatus Receive_CLIENT_ERROR(Packet &p) override; NetworkRecvStatus Receive_CLIENT_ERROR(Packet &p) override;
@ -49,7 +47,6 @@ protected:
NetworkRecvStatus SendWelcome(); NetworkRecvStatus SendWelcome();
NetworkRecvStatus SendAuthRequest(); NetworkRecvStatus SendAuthRequest();
NetworkRecvStatus SendEnableEncryption(); NetworkRecvStatus SendEnableEncryption();
NetworkRecvStatus SendNeedCompanyPassword();
public: public:
/** Status of a client */ /** Status of a client */
@ -58,7 +55,6 @@ public:
STATUS_AUTH_GAME, ///< The client is authorizing with game (server) password. STATUS_AUTH_GAME, ///< The client is authorizing with game (server) password.
STATUS_IDENTIFY, ///< The client is identifying itself. STATUS_IDENTIFY, ///< The client is identifying itself.
STATUS_NEWGRFS_CHECK, ///< The client is checking NewGRFs. STATUS_NEWGRFS_CHECK, ///< The client is checking NewGRFs.
STATUS_AUTH_COMPANY, ///< The client is authorizing with company password.
STATUS_AUTHORIZED, ///< The client is authorized. STATUS_AUTHORIZED, ///< The client is authorized.
STATUS_MAP_WAIT, ///< The client is waiting as someone else is downloading the map. STATUS_MAP_WAIT, ///< The client is waiting as someone else is downloading the map.
STATUS_MAP, ///< The client is downloading the map. STATUS_MAP, ///< The client is downloading the map.
@ -104,7 +100,6 @@ public:
NetworkRecvStatus SendFrame(); NetworkRecvStatus SendFrame();
NetworkRecvStatus SendSync(); NetworkRecvStatus SendSync();
NetworkRecvStatus SendCommand(const CommandPacket &cp); NetworkRecvStatus SendCommand(const CommandPacket &cp);
NetworkRecvStatus SendCompanyUpdate();
NetworkRecvStatus SendConfigUpdate(); NetworkRecvStatus SendConfigUpdate();
static void Send(); static void Send();
@ -128,7 +123,5 @@ public:
void NetworkServer_Tick(bool send_frame); void NetworkServer_Tick(bool send_frame);
void ChangeNetworkRestartTime(bool reset); void ChangeNetworkRestartTime(bool reset);
void NetworkServerSetCompanyPassword(CompanyID company_id, const std::string &password, bool already_hashed = true);
void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded);
#endif /* NETWORK_SERVER_H */ #endif /* NETWORK_SERVER_H */

View File

@ -70,19 +70,8 @@ struct NetworkCompanyStats {
bool ai; ///< Is this company an AI bool ai; ///< Is this company an AI
}; };
/** Some state information of a company, especially for servers */
struct NetworkCompanyState {
std::string password; ///< The password for the company
};
struct NetworkClientInfo; struct NetworkClientInfo;
/** The type of password we're asking for. */
enum NetworkPasswordType {
NETWORK_GAME_PASSWORD, ///< The password of the game.
NETWORK_COMPANY_PASSWORD, ///< The password of the company.
};
/** /**
* Destination of our chat messages. * Destination of our chat messages.
* @warning The values of the enum items are part of the admin network API. Only append at the end. * @warning The values of the enum items are part of the admin network API. Only append at the end.

View File

@ -169,7 +169,6 @@ static void ShowHelp()
" -G seed = Set random seed\n" " -G seed = Set random seed\n"
" -n host[:port][#company]= Join network game\n" " -n host[:port][#company]= Join network game\n"
" -p password = Password to join server\n" " -p password = Password to join server\n"
" -P password = Password to join company\n"
" -D [host][:port] = Start dedicated server\n" " -D [host][:port] = Start dedicated server\n"
#if !defined(_WIN32) #if !defined(_WIN32)
" -f = Fork into the background (dedicated only)\n" " -f = Fork into the background (dedicated only)\n"
@ -385,7 +384,6 @@ struct AfterNewGRFScan : NewGRFScanCallback {
uint16_t dedicated_port = 0; ///< Port for the dedicated server. uint16_t dedicated_port = 0; ///< Port for the dedicated server.
std::string connection_string; ///< Information about the server to connect to std::string connection_string; ///< Information about the server to connect to
std::string join_server_password; ///< The password to join the server with. std::string join_server_password; ///< The password to join the server with.
std::string join_company_password; ///< The password to join the company with.
bool save_config = true; ///< The save config setting. bool save_config = true; ///< The save config setting.
/** /**
@ -449,7 +447,7 @@ struct AfterNewGRFScan : NewGRFScanCallback {
LoadIntroGame(); LoadIntroGame();
_switch_mode = SM_NONE; _switch_mode = SM_NONE;
NetworkClientConnectGame(connection_string, COMPANY_NEW_COMPANY, join_server_password, join_company_password); NetworkClientConnectGame(connection_string, COMPANY_NEW_COMPANY, join_server_password);
} }
/* After the scan we're not used anymore. */ /* After the scan we're not used anymore. */
@ -486,7 +484,7 @@ static std::vector<OptionData> CreateOptions()
{ {
std::vector<OptionData> options; std::vector<OptionData> options;
/* Options that require a parameter. */ /* Options that require a parameter. */
for (char c : "GIMPSbcmnpqrstv") options.push_back({ .type = ODF_HAS_VALUE, .id = c, .shortname = c }); for (char c : "GIMSbcmnpqrstv") options.push_back({ .type = ODF_HAS_VALUE, .id = c, .shortname = c });
#if !defined(_WIN32) #if !defined(_WIN32)
options.push_back({ .type = ODF_HAS_VALUE, .id = 'f', .shortname = 'f' }); options.push_back({ .type = ODF_HAS_VALUE, .id = 'f', .shortname = 'f' });
#endif #endif
@ -559,9 +557,6 @@ int openttd_main(std::span<char * const> arguments)
case 'p': case 'p':
scanner->join_server_password = mgo.opt; scanner->join_server_password = mgo.opt;
break; break;
case 'P':
scanner->join_company_password = mgo.opt;
break;
case 'r': ParseResolution(&resolution, mgo.opt); break; case 'r': ParseResolution(&resolution, mgo.opt); break;
case 't': scanner->startyear = atoi(mgo.opt); break; case 't': scanner->startyear = atoi(mgo.opt); break;
case 'd': { case 'd': {
@ -900,12 +895,6 @@ static void MakeNewGameDone()
InitializeRailGUI(); InitializeRailGUI();
InitializeRoadGUI(); InitializeRoadGUI();
/* We are the server, we start a new company (not dedicated),
* so set the default password *if* needed. */
if (_network_server && !_settings_client.network.default_company_pass.empty()) {
NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass);
}
if (_settings_client.gui.pause_on_newgame) Command<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, true); if (_settings_client.gui.pause_on_newgame) Command<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, true);
CheckEngines(); CheckEngines();

View File

@ -450,6 +450,8 @@ static const SaveLoad _company_desc[] = {
SLE_VAR(CompanyProperties, president_name_2, SLE_UINT32), SLE_VAR(CompanyProperties, president_name_2, SLE_UINT32),
SLE_CONDSSTR(CompanyProperties, president_name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION), SLE_CONDSSTR(CompanyProperties, president_name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION),
SLE_CONDVECTOR(CompanyProperties, allow_list, SLE_STR, SLV_COMPANY_ALLOW_LIST, SL_MAX_VERSION),
SLE_VAR(CompanyProperties, face, SLE_UINT32), SLE_VAR(CompanyProperties, face, SLE_UINT32),
/* money was changed to a 64 bit field in savegame version 1. */ /* money was changed to a 64 bit field in savegame version 1. */

View File

@ -1244,13 +1244,17 @@ public:
*/ */
static size_t SlCalcLen(const void *storage, VarType conv, SaveLoadType cmd = SL_VAR) static size_t SlCalcLen(const void *storage, VarType conv, SaveLoadType cmd = SL_VAR)
{ {
assert(cmd == SL_VAR || cmd == SL_REF); assert(cmd == SL_VAR || cmd == SL_REF || cmd == SL_STDSTR);
const SlStorageT *list = static_cast<const SlStorageT *>(storage); const SlStorageT *list = static_cast<const SlStorageT *>(storage);
int type_size = SlGetArrayLength(list->size()); size_t type_size = SlGetArrayLength(list->size());
int item_size = SlCalcConvFileLen(cmd == SL_VAR ? conv : (VarType)SLE_FILE_U32); if constexpr (std::is_same_v<std::vector<std::string>, SlStorageT> || std::is_same_v<std::deque<std::string>, SlStorageT>) {
return list->size() * item_size + type_size; return std::accumulate(list->begin(), list->end(), type_size, [](size_t sum, const std::string &str) { return sum + SlCalcStdStringLen(&str); });
} else {
size_t item_size = SlCalcConvFileLen(cmd == SL_VAR ? conv : (VarType)SLE_FILE_U32);
return list->size() * item_size + type_size;
}
} }
static void SlSaveLoadMember(SaveLoadType cmd, Tvar *item, VarType conv) static void SlSaveLoadMember(SaveLoadType cmd, Tvar *item, VarType conv)
@ -1258,6 +1262,7 @@ public:
switch (cmd) { switch (cmd) {
case SL_VAR: SlSaveLoadConv(item, conv); break; case SL_VAR: SlSaveLoadConv(item, conv); break;
case SL_REF: SlSaveLoadRef(item, conv); break; case SL_REF: SlSaveLoadRef(item, conv); break;
case SL_STDSTR: SlStdString(item, conv); break;
default: default:
NOT_REACHED(); NOT_REACHED();
} }
@ -1271,7 +1276,7 @@ public:
*/ */
static void SlSaveLoad(void *storage, VarType conv, SaveLoadType cmd = SL_VAR) static void SlSaveLoad(void *storage, VarType conv, SaveLoadType cmd = SL_VAR)
{ {
assert(cmd == SL_VAR || cmd == SL_REF); assert(cmd == SL_VAR || cmd == SL_REF || cmd == SL_STDSTR);
SlStorageT *list = static_cast<SlStorageT *>(storage); SlStorageT *list = static_cast<SlStorageT *>(storage);
@ -1290,6 +1295,7 @@ public:
switch (cmd) { switch (cmd) {
case SL_VAR: length = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? SlReadUint32() : SlReadArrayLength(); break; case SL_VAR: length = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? SlReadUint32() : SlReadArrayLength(); break;
case SL_REF: length = IsSavegameVersionBefore(SLV_69) ? SlReadUint16() : IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? SlReadUint32() : SlReadArrayLength(); break; case SL_REF: length = IsSavegameVersionBefore(SLV_69) ? SlReadUint16() : IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? SlReadUint32() : SlReadArrayLength(); break;
case SL_STDSTR: length = SlReadArrayLength(); break;
default: NOT_REACHED(); default: NOT_REACHED();
} }
@ -1360,6 +1366,7 @@ static inline size_t SlCalcDequeLen(const void *deque, VarType conv)
case SLE_VAR_U32: return SlStorageHelper<std::deque, uint32_t>::SlCalcLen(deque, conv); case SLE_VAR_U32: return SlStorageHelper<std::deque, uint32_t>::SlCalcLen(deque, conv);
case SLE_VAR_I64: return SlStorageHelper<std::deque, int64_t>::SlCalcLen(deque, conv); case SLE_VAR_I64: return SlStorageHelper<std::deque, int64_t>::SlCalcLen(deque, conv);
case SLE_VAR_U64: return SlStorageHelper<std::deque, uint64_t>::SlCalcLen(deque, conv); case SLE_VAR_U64: return SlStorageHelper<std::deque, uint64_t>::SlCalcLen(deque, conv);
case SLE_VAR_STR: return SlStorageHelper<std::deque, std::string>::SlCalcLen(deque, conv, SL_STDSTR);
default: NOT_REACHED(); default: NOT_REACHED();
} }
} }
@ -1381,6 +1388,7 @@ static void SlDeque(void *deque, VarType conv)
case SLE_VAR_U32: SlStorageHelper<std::deque, uint32_t>::SlSaveLoad(deque, conv); break; case SLE_VAR_U32: SlStorageHelper<std::deque, uint32_t>::SlSaveLoad(deque, conv); break;
case SLE_VAR_I64: SlStorageHelper<std::deque, int64_t>::SlSaveLoad(deque, conv); break; case SLE_VAR_I64: SlStorageHelper<std::deque, int64_t>::SlSaveLoad(deque, conv); break;
case SLE_VAR_U64: SlStorageHelper<std::deque, uint64_t>::SlSaveLoad(deque, conv); break; case SLE_VAR_U64: SlStorageHelper<std::deque, uint64_t>::SlSaveLoad(deque, conv); break;
case SLE_VAR_STR: SlStorageHelper<std::deque, std::string>::SlSaveLoad(deque, conv, SL_STDSTR); break;
default: NOT_REACHED(); default: NOT_REACHED();
} }
} }
@ -1402,6 +1410,7 @@ static inline size_t SlCalcVectorLen(const void *vector, VarType conv)
case SLE_VAR_U32: return SlStorageHelper<std::vector, uint32_t>::SlCalcLen(vector, conv); case SLE_VAR_U32: return SlStorageHelper<std::vector, uint32_t>::SlCalcLen(vector, conv);
case SLE_VAR_I64: return SlStorageHelper<std::vector, int64_t>::SlCalcLen(vector, conv); case SLE_VAR_I64: return SlStorageHelper<std::vector, int64_t>::SlCalcLen(vector, conv);
case SLE_VAR_U64: return SlStorageHelper<std::vector, uint64_t>::SlCalcLen(vector, conv); case SLE_VAR_U64: return SlStorageHelper<std::vector, uint64_t>::SlCalcLen(vector, conv);
case SLE_VAR_STR: return SlStorageHelper<std::vector, std::string>::SlCalcLen(vector, conv, SL_STDSTR);
default: NOT_REACHED(); default: NOT_REACHED();
} }
} }
@ -1423,6 +1432,7 @@ static void SlVector(void *vector, VarType conv)
case SLE_VAR_U32: SlStorageHelper<std::vector, uint32_t>::SlSaveLoad(vector, conv); break; case SLE_VAR_U32: SlStorageHelper<std::vector, uint32_t>::SlSaveLoad(vector, conv); break;
case SLE_VAR_I64: SlStorageHelper<std::vector, int64_t>::SlSaveLoad(vector, conv); break; case SLE_VAR_I64: SlStorageHelper<std::vector, int64_t>::SlSaveLoad(vector, conv); break;
case SLE_VAR_U64: SlStorageHelper<std::vector, uint64_t>::SlSaveLoad(vector, conv); break; case SLE_VAR_U64: SlStorageHelper<std::vector, uint64_t>::SlSaveLoad(vector, conv); break;
case SLE_VAR_STR: SlStorageHelper<std::vector, std::string>::SlSaveLoad(vector, conv, SL_STDSTR); break;
default: NOT_REACHED(); default: NOT_REACHED();
} }
} }

View File

@ -379,6 +379,8 @@ enum SaveLoadVersion : uint16_t {
SLV_SCRIPT_RANDOMIZER, ///< 333 PR#12063 v14.0-RC1 Save script randomizers. SLV_SCRIPT_RANDOMIZER, ///< 333 PR#12063 v14.0-RC1 Save script randomizers.
SLV_VEHICLE_ECONOMY_AGE, ///< 334 PR#12141 v14.0 Add vehicle age in economy year, for profit stats minimum age SLV_VEHICLE_ECONOMY_AGE, ///< 334 PR#12141 v14.0 Add vehicle age in economy year, for profit stats minimum age
SLV_COMPANY_ALLOW_LIST, ///< 335 PR#12337 Saving of list of client keys that are allowed to join this company.
SL_MAX_VERSION, ///< Highest possible saveload version SL_MAX_VERSION, ///< Highest possible saveload version
}; };
@ -944,6 +946,16 @@ inline constexpr bool SlCheckVarSize(SaveLoadType cmd, VarType type, size_t leng
*/ */
#define SLE_CONDDEQUE(base, variable, type, from, to) SLE_GENERAL(SL_DEQUE, base, variable, type, 0, from, to, 0) #define SLE_CONDDEQUE(base, variable, type, from, to) SLE_GENERAL(SL_DEQUE, base, variable, type, 0, from, to, 0)
/**
* Storage of a vector of #SL_VAR elements in some savegame versions.
* @param base Name of the class or struct containing the list.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
*/
#define SLE_CONDVECTOR(base, variable, type, from, to) SLE_GENERAL(SL_VECTOR, base, variable, type, 0, from, to, 0)
/** /**
* Storage of a variable in every version of a savegame. * Storage of a variable in every version of a savegame.
* @param base Name of the class or struct containing the variable. * @param base Name of the class or struct containing the variable.

View File

@ -320,12 +320,9 @@ struct NetworkSettings {
std::string client_name; ///< name of the player (as client) std::string client_name; ///< name of the player (as client)
std::string client_secret_key; ///< The secret key of the client for authorized key logins. std::string client_secret_key; ///< The secret key of the client for authorized key logins.
std::string client_public_key; ///< The public key of the client for authorized key logins. std::string client_public_key; ///< The public key of the client for authorized key logins.
std::string default_company_pass; ///< default password for new companies in encrypted form
std::string connect_to_ip; ///< default for the "Add server" query std::string connect_to_ip; ///< default for the "Add server" query
std::string network_id; ///< network ID for servers
bool autoclean_companies; ///< automatically remove companies that are not in use bool autoclean_companies; ///< automatically remove companies that are not in use
uint8_t autoclean_unprotected; ///< remove passwordless companies after this many months uint8_t autoclean_protected; ///< Remove companies after this many months.
uint8_t autoclean_protected; ///< remove the password from passworded companies after this many months
uint8_t autoclean_novehicles; ///< remove companies with no vehicles after this many months uint8_t autoclean_novehicles; ///< remove companies with no vehicles after this many months
uint8_t max_companies; ///< maximum amount of companies uint8_t max_companies; ///< maximum amount of companies
uint8_t max_clients; ///< maximum amount of clients uint8_t max_clients; ///< maximum amount of clients

View File

@ -79,20 +79,6 @@ def = nullptr
; Prevent the user from setting the public key from the console using 'setting' ; Prevent the user from setting the public key from the console using 'setting'
pre_cb = [](auto) { return false; } pre_cb = [](auto) { return false; }
[SDTC_SSTR]
var = network.default_company_pass
type = SLE_STR
length = NETWORK_PASSWORD_LENGTH
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC
def = nullptr
[SDTC_SSTR]
var = network.network_id
type = SLE_STR
length = NETWORK_SERVER_ID_LENGTH
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY
def = nullptr
[SDTC_SSTR] [SDTC_SSTR]
var = network.server_invite_code var = network.server_invite_code
type = SLE_STR type = SLE_STR

View File

@ -192,14 +192,6 @@ var = network.autoclean_companies
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY
def = false def = false
[SDTC_VAR]
var = network.autoclean_unprotected
type = SLE_UINT8
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_0_IS_SPECIAL | SF_NETWORK_ONLY
def = 12
min = 0
max = 240
[SDTC_VAR] [SDTC_VAR]
var = network.autoclean_protected var = network.autoclean_protected
type = SLE_UINT8 type = SLE_UINT8

View File

@ -18,6 +18,7 @@
/* The length of the hexadecimal representation of a X25519 key must fit in the key length. */ /* The length of the hexadecimal representation of a X25519 key must fit in the key length. */
static_assert(NETWORK_SECRET_KEY_LENGTH >= X25519_KEY_SIZE * 2 + 1); static_assert(NETWORK_SECRET_KEY_LENGTH >= X25519_KEY_SIZE * 2 + 1);
static_assert(NETWORK_PUBLIC_KEY_LENGTH >= X25519_KEY_SIZE * 2 + 1);
class MockNetworkSocketHandler : public NetworkSocketHandler { class MockNetworkSocketHandler : public NetworkSocketHandler {
public: public:

View File

@ -20,7 +20,6 @@ enum QueryStringFlags {
QSF_ACCEPT_UNCHANGED = 0x01, ///< return success even when the text didn't change QSF_ACCEPT_UNCHANGED = 0x01, ///< return success even when the text didn't change
QSF_ENABLE_DEFAULT = 0x02, ///< enable the 'Default' button ("\0" is returned) QSF_ENABLE_DEFAULT = 0x02, ///< enable the 'Default' button ("\0" is returned)
QSF_LEN_IN_CHARS = 0x04, ///< the length of the string is counted in characters QSF_LEN_IN_CHARS = 0x04, ///< the length of the string is counted in characters
QSF_PASSWORD = 0x08, ///< password entry box, show warning about password security
}; };
DECLARE_ENUM_AS_BIT_SET(QueryStringFlags) DECLARE_ENUM_AS_BIT_SET(QueryStringFlags)

View File

@ -97,7 +97,7 @@ static CallBackFunction _last_started_action = CBF_NONE; ///< Last started user
*/ */
class DropDownListCompanyItem : public DropDownIcon<DropDownIcon<DropDownString<DropDownListItem>, true>> { class DropDownListCompanyItem : public DropDownIcon<DropDownIcon<DropDownString<DropDownListItem>, true>> {
public: public:
DropDownListCompanyItem(CompanyID company, bool shaded) : DropDownIcon<DropDownIcon<DropDownString<DropDownListItem>, true>>(SPR_COMPANY_ICON, COMPANY_SPRITE_COLOUR(company), NetworkCompanyIsPassworded(company) ? SPR_LOCK : SPR_EMPTY, PAL_NONE, STR_NULL, company, false, shaded) DropDownListCompanyItem(CompanyID company, bool shaded) : DropDownIcon<DropDownIcon<DropDownString<DropDownListItem>, true>>(SPR_COMPANY_ICON, COMPANY_SPRITE_COLOUR(company), NetworkCanJoinCompany(company) ? SPR_EMPTY : SPR_LOCK, PAL_NONE, STR_NULL, company, false, shaded)
{ {
SetDParam(0, company); SetDParam(0, company);
SetDParam(1, company); SetDParam(1, company);

View File

@ -47,9 +47,7 @@ enum CompanyWidgets : WidgetID {
WID_C_SELECT_HOSTILE_TAKEOVER, ///< Selection widget for the hostile takeover button. WID_C_SELECT_HOSTILE_TAKEOVER, ///< Selection widget for the hostile takeover button.
WID_C_HOSTILE_TAKEOVER, ///< Button to hostile takeover another company. WID_C_HOSTILE_TAKEOVER, ///< Button to hostile takeover another company.
WID_C_HAS_PASSWORD, ///< Has company password lock.
WID_C_SELECT_MULTIPLAYER, ///< Multiplayer selection panel. WID_C_SELECT_MULTIPLAYER, ///< Multiplayer selection panel.
WID_C_COMPANY_PASSWORD, ///< Button to set company password.
WID_C_COMPANY_JOIN, ///< Button to join company. WID_C_COMPANY_JOIN, ///< Button to join company.
}; };

View File

@ -32,7 +32,6 @@ enum AboutWidgets : WidgetID {
enum QueryStringWidgets : WidgetID { enum QueryStringWidgets : WidgetID {
WID_QS_CAPTION, ///< Caption of the window. WID_QS_CAPTION, ///< Caption of the window.
WID_QS_TEXT, ///< Text of the query. WID_QS_TEXT, ///< Text of the query.
WID_QS_WARNING, ///< Warning label about password security
WID_QS_DEFAULT, ///< Default button. WID_QS_DEFAULT, ///< Default button.
WID_QS_CANCEL, ///< Cancel button. WID_QS_CANCEL, ///< Cancel button.
WID_QS_OK, ///< OK button. WID_QS_OK, ///< OK button.

View File

@ -86,7 +86,6 @@ enum ClientListWidgets : WidgetID {
WID_CL_CLIENT_NAME_EDIT, ///< Edit button for client name. WID_CL_CLIENT_NAME_EDIT, ///< Edit button for client name.
WID_CL_MATRIX, ///< Company/client list. WID_CL_MATRIX, ///< Company/client list.
WID_CL_SCROLLBAR, ///< Scrollbar for company/client list. WID_CL_SCROLLBAR, ///< Scrollbar for company/client list.
WID_CL_COMPANY_JOIN, ///< Used for QueryWindow when a company has a password.
WID_CL_CLIENT_COMPANY_COUNT, ///< Count of clients and companies. WID_CL_CLIENT_COMPANY_COUNT, ///< Count of clients and companies.
}; };
@ -97,17 +96,6 @@ enum NetworkJoinStatusWidgets : WidgetID {
WID_NJS_CANCELOK, ///< Cancel / OK button. WID_NJS_CANCELOK, ///< Cancel / OK button.
}; };
/** Widgets of the #NetworkCompanyPasswordWindow class. */
enum NetworkCompanyPasswordWidgets : WidgetID {
WID_NCP_BACKGROUND, ///< Background of the window.
WID_NCP_LABEL, ///< Label in front of the password field.
WID_NCP_PASSWORD, ///< Input field for the password.
WID_NCP_SAVE_AS_DEFAULT_PASSWORD, ///< Toggle 'button' for saving the current password as default password.
WID_NCP_WARNING, ///< Warning text about password security
WID_NCP_CANCEL, ///< Close the window without changing anything.
WID_NCP_OK, ///< Safe the password etc.
};
/** Widgets of the #NetworkAskRelayWindow class. */ /** Widgets of the #NetworkAskRelayWindow class. */
enum NetworkAskRelayWidgets : WidgetID { enum NetworkAskRelayWidgets : WidgetID {
WID_NAR_CAPTION, ///< Caption of the window. WID_NAR_CAPTION, ///< Caption of the window.

View File

@ -502,13 +502,6 @@ enum WindowClass {
*/ */
WC_SEND_NETWORK_MSG, WC_SEND_NETWORK_MSG,
/**
* Company password query; %Window numbers:
* - 0 = #NetworkCompanyPasswordWidgets
*/
WC_COMPANY_PASSWORD_WINDOW,
/** /**
* Industry cargoes chain; %Window numbers: * Industry cargoes chain; %Window numbers:
* - 0 = #IndustryCargoesWidgets * - 0 = #IndustryCargoesWidgets