mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2026-07-25 08:22:17 +00:00
Add: Company allow-list can be set to allow anyone.
This commit is contained in:
committed by
Peter Nelson
parent
a6803199d5
commit
da4dd91887
@@ -81,6 +81,7 @@ struct CompanyProperties {
|
||||
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.
|
||||
bool allow_any = false; ///< Set if anyone is allowed to join this company.
|
||||
|
||||
CompanyManagerFace face{}; ///< Face description of the president.
|
||||
|
||||
|
||||
+17
-3
@@ -1014,6 +1014,16 @@ static bool ExecuteAllowListCtrlAction(CompanyAllowListCtrlAction action, Compan
|
||||
case CALCA_REMOVE:
|
||||
return c->allow_list.Remove(public_key);
|
||||
|
||||
case CALCA_ALLOW_ANY:
|
||||
if (c->allow_any) return false;
|
||||
c->allow_any = true;
|
||||
return true;
|
||||
|
||||
case CALCA_ALLOW_LISTED:
|
||||
if (!c->allow_any) return false;
|
||||
c->allow_any = false;
|
||||
return true;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
@@ -1031,12 +1041,16 @@ CommandCost CmdCompanyAllowListCtrl(DoCommandFlags flags, CompanyAllowListCtrlAc
|
||||
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;
|
||||
|
||||
switch (action) {
|
||||
case CALCA_ADD:
|
||||
case CALCA_REMOVE:
|
||||
/* The public key length includes the '\0'. */
|
||||
if (public_key.size() != NETWORK_PUBLIC_KEY_LENGTH - 1) return CMD_ERROR;
|
||||
break;
|
||||
|
||||
case CALCA_ALLOW_ANY:
|
||||
case CALCA_ALLOW_LISTED:
|
||||
if (public_key.size() != 0) return CMD_ERROR;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -80,6 +80,8 @@ enum CompanyCtrlAction : uint8_t {
|
||||
enum CompanyAllowListCtrlAction : uint8_t {
|
||||
CALCA_ADD, ///< Create a public key.
|
||||
CALCA_REMOVE, ///< Remove a public key.
|
||||
CALCA_ALLOW_ANY, ///< Allow joining the company without a key.
|
||||
CALCA_ALLOW_LISTED, ///< Allow only listed keys to join the company.
|
||||
|
||||
CALCA_END, ///< Sentinel for end.
|
||||
};
|
||||
|
||||
@@ -2547,6 +2547,8 @@ 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_BAN :Ban
|
||||
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Delete
|
||||
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_ALLOW_ANY :Allow any client
|
||||
STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_ALLOW_LISTED :Allow only listed clients
|
||||
|
||||
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}'?
|
||||
|
||||
@@ -131,7 +131,7 @@ NetworkClientInfo::~NetworkClientInfo()
|
||||
bool NetworkClientInfo::CanJoinCompany(CompanyID company_id) const
|
||||
{
|
||||
Company *c = Company::GetIfValid(company_id);
|
||||
return c != nullptr && c->allow_list.Contains(this->public_key);
|
||||
return c != nullptr && (c->allow_any || c->allow_list.Contains(this->public_key));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1539,6 +1539,8 @@ private:
|
||||
AdminKickClient, ///< Admin kick client.
|
||||
AdminBanClient, ///< Admin ban client.
|
||||
AdminResetCompany, ///< Admin reset company.
|
||||
CompanyAllowAny, ///< Allow any client.
|
||||
CompanyAllowListed, ///< Allow only listed clients.
|
||||
};
|
||||
|
||||
ClientListWidgets query_widget{}; ///< During a query this tracks what widget caused the query.
|
||||
@@ -1620,7 +1622,11 @@ private:
|
||||
static void OnClickCompanyAdmin([[maybe_unused]] NetworkClientListWindow *w, [[maybe_unused]] Point pt, CompanyID company_id)
|
||||
{
|
||||
DropDownList list;
|
||||
list.push_back(MakeDropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET, to_underlying(DropDownAction::AdminResetCompany), NetworkCompanyHasClients(company_id)));
|
||||
if (_network_server) list.push_back(MakeDropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET, to_underlying(DropDownAction::AdminResetCompany), NetworkCompanyHasClients(company_id)));
|
||||
if (const Company *c = Company::GetIfValid(company_id); c != nullptr) {
|
||||
list.push_back(MakeDropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_ALLOW_ANY, to_underlying(DropDownAction::CompanyAllowAny), c->allow_any));
|
||||
list.push_back(MakeDropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_ALLOW_LISTED, to_underlying(DropDownAction::CompanyAllowListed), !c->allow_any));
|
||||
}
|
||||
|
||||
Rect wi_rect;
|
||||
wi_rect.left = pt.x;
|
||||
@@ -1631,6 +1637,7 @@ private:
|
||||
w->dd_company_id = company_id;
|
||||
ShowDropDownListAt(w, std::move(list), -1, WID_CL_MATRIX, wi_rect, COLOUR_GREY, DropDownOption::InstantClose);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chat button on a Client is clicked.
|
||||
* @param w The instance of this window.
|
||||
@@ -1657,7 +1664,9 @@ private:
|
||||
void RebuildListCompany(CompanyID company_id, CompanyID client_playas, bool can_join_company)
|
||||
{
|
||||
ButtonLine &company_line = *this->buttons.emplace_back(std::make_unique<CompanyButtonLine>(company_id));
|
||||
if (_network_server) company_line.AddButton<CompanyButton>(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP, COLOUR_RED, company_id, &NetworkClientListWindow::OnClickCompanyAdmin, company_id == COMPANY_SPECTATOR);
|
||||
if (_network_server || company_id == _local_company) {
|
||||
company_line.AddButton<CompanyButton>(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP, COLOUR_RED, company_id, &NetworkClientListWindow::OnClickCompanyAdmin, company_id == COMPANY_SPECTATOR);
|
||||
}
|
||||
ButtonCommon &chat_button = company_line.AddButton<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 (can_join_company) company_line.AddButton<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);
|
||||
|
||||
@@ -1700,7 +1709,7 @@ private:
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
if (c->index == client_playas) continue;
|
||||
|
||||
this->RebuildListCompany(c->index, client_playas, (own_ci != nullptr && c->allow_list.Contains(own_ci->public_key)) || _network_server);
|
||||
this->RebuildListCompany(c->index, client_playas, _network_server || c->allow_any || (own_ci != nullptr && c->allow_list.Contains(own_ci->public_key)));
|
||||
}
|
||||
|
||||
/* Spectators */
|
||||
@@ -1897,6 +1906,18 @@ public:
|
||||
text = GetEncodedString(STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET, _admin_company_id);
|
||||
break;
|
||||
|
||||
case DropDownAction::CompanyAllowAny: {
|
||||
AutoRestoreBackup cur_company(_current_company, this->dd_company_id);
|
||||
Command<Commands::CompanyAllowListControl>::Post(CALCA_ALLOW_ANY, {});
|
||||
return;
|
||||
}
|
||||
|
||||
case DropDownAction::CompanyAllowListed: {
|
||||
AutoRestoreBackup cur_company(_current_company, this->dd_company_id);
|
||||
Command<Commands::CompanyAllowListControl>::Post(CALCA_ALLOW_LISTED, {});
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
@@ -942,7 +942,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_IDENTIFY(Packet
|
||||
return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH);
|
||||
}
|
||||
|
||||
if (!Company::Get(playas)->allow_list.Contains(this->peer_public_key)) {
|
||||
const Company *c = Company::Get(playas);
|
||||
if (!c->allow_any && !c->allow_list.Contains(this->peer_public_key)) {
|
||||
/* When we're not authorized, just bump us to a spectator. */
|
||||
playas = COMPANY_SPECTATOR;
|
||||
}
|
||||
@@ -1161,16 +1162,18 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet
|
||||
|
||||
/* 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<Commands::CompanyAllowListControl>::Args>(cp.data));
|
||||
bool found = false;
|
||||
for (const NetworkClientInfo *info : NetworkClientInfo::Iterate()) {
|
||||
if (info->public_key == public_key) {
|
||||
found = true;
|
||||
break;
|
||||
if (!public_key.empty()) {
|
||||
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;
|
||||
/* Maybe the client just left? */
|
||||
if (!found) return NETWORK_RECV_STATUS_OKAY;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetCommandFlags(cp.cmd).Test(CommandFlag::ClientID)) NetworkReplaceCommandClientId(cp, this->client_id);
|
||||
@@ -1517,11 +1520,14 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MOVE(Packet &p)
|
||||
Debug(net, 9, "client[{}] Receive_CLIENT_MOVE(): company_id={}", this->client_id, company_id);
|
||||
|
||||
/* 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) {
|
||||
if (!Company::IsValidHumanID(company_id)) return NETWORK_RECV_STATUS_OKAY;
|
||||
|
||||
if (company_id != COMPANY_SPECTATOR && !Company::Get(company_id)->allow_list.Contains(this->peer_public_key)) {
|
||||
Debug(net, 2, "Wrong public key from client-id #{} for company #{}", this->client_id, company_id + 1);
|
||||
return NETWORK_RECV_STATUS_OKAY;
|
||||
const Company *c = Company::Get(company_id);
|
||||
if (!c->allow_any && !c->allow_list.Contains(this->peer_public_key)) {
|
||||
Debug(net, 2, "Wrong public key from client-id #{} for company #{}", this->client_id, company_id + 1);
|
||||
return NETWORK_RECV_STATUS_OKAY;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we get here we can move the client */
|
||||
|
||||
@@ -499,6 +499,7 @@ static const SaveLoad _company_desc[] = {
|
||||
|
||||
SLE_CONDVECTOR(CompanyProperties, allow_list, SLE_STR, SLV_COMPANY_ALLOW_LIST, SLV_COMPANY_ALLOW_LIST_V2),
|
||||
SLEG_CONDSTRUCTLIST("allow_list", SlAllowListData, SLV_COMPANY_ALLOW_LIST_V2, SL_MAX_VERSION),
|
||||
SLE_VAR(CompanyProperties, allow_any, SLE_BOOL),
|
||||
|
||||
SLE_VARNAME(CompanyProperties, face.bits, "face", SLE_UINT32),
|
||||
SLE_CONDSSTRNAME(CompanyProperties, face.style_label, "face_style", SLE_STR, SLV_FACE_STYLES, SL_MAX_VERSION),
|
||||
|
||||
Reference in New Issue
Block a user