mirror of https://github.com/OpenTTD/OpenTTD.git
Merge e420467d60
into ac6a945e26
This commit is contained in:
commit
de9bd52178
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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")) {
|
std::string_view type = argv[2];
|
||||||
if (authorized_keys->Remove(authorized_key)) {
|
if (StrEqualsIgnoreCase(type, "all")) {
|
||||||
IConsolePrint(CC_INFO, "Removed {} from {}.", authorized_key, name);
|
for (auto [name, authorized_keys] : _console_cmd_authorized_keys) PerformNetworkAuthorizedKeyAction(name, authorized_keys, action, authorized_key);
|
||||||
} else {
|
for (Company *c : Company::Iterate()) PerformNetworkAuthorizedKeyAction(fmt::format("company:{}", c->index + 1), &c->allow_list, action, authorized_key, c->index);
|
||||||
IConsolePrint(CC_WARNING, "Not removed {} from {} as it does not exist.", authorized_key, name);
|
return true;
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IConsolePrint(CC_WARNING, "No valid action was given.");
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!valid_type) {
|
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.");
|
IConsolePrint(CC_WARNING, "No valid type was given.");
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 %+");
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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. */
|
||||||
|
@ -203,6 +197,7 @@ protected:
|
||||||
* 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.
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,17 +1482,10 @@ 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 */
|
|
||||||
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;
|
return NETWORK_RECV_STATUS_OKAY;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* if we get here we can move the client */
|
/* if we get here we can move the client */
|
||||||
NetworkServerDoMove(this->client_id, company_id);
|
NetworkServerDoMove(this->client_id, company_id);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -1244,20 +1244,25 @@ 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 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;
|
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)
|
||||||
{
|
{
|
||||||
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue