summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/multiplayer.md11
-rw-r--r--src/console_cmds.cpp1
-rw-r--r--src/lang/english.txt3
-rw-r--r--src/network/network.cpp25
-rw-r--r--src/network/network_coordinator.cpp19
-rw-r--r--src/network/network_func.h1
-rw-r--r--src/network/network_gui.cpp38
-rw-r--r--src/network/network_type.h1
-rw-r--r--src/settings_type.h2
-rw-r--r--src/table/settings/network_settings.ini16
10 files changed, 86 insertions, 31 deletions
diff --git a/docs/multiplayer.md b/docs/multiplayer.md
index daccbf06d..ece0c04df 100644
--- a/docs/multiplayer.md
+++ b/docs/multiplayer.md
@@ -48,6 +48,10 @@ Last updated: 2011-02-16
- click add server
- type in the ip address or hostname
- if you want to add a port use :<port>
+ - If you want to play and you have the invite code of the game server you
+ want connect to.
+ - click add server
+ - type in the invite code
- Now you can select a company and press: "Join company", to help that company
- Or you can press "Spectate game", to spectate the game
- Or you can press "New company", and start your own company (if there are
@@ -110,9 +114,10 @@ Last updated: 2011-02-16
- You can let your server automatically restart a map when, let's say, year 2030
is reached. See 'set restart_game_date' for detail.
- - If you want to be on the server-list, enable Advertising. To do this, select
- 'Internet (advertise)' in the Start Server menu, or type in console:
- 'set server_advertise 1'.
+ - If you want to be on the server-list, make your server public. You can do
+ this either from the Start Server GUI, via the in-game Online Players GUI,
+ or by typing in the console:
+ 'set server_game_type 1'.
- You can protect your server with a password via the console: 'set server_pw',
or via the Start Server menu.
diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp
index 0fcac4488..fd7f09e3c 100644
--- a/src/console_cmds.cpp
+++ b/src/console_cmds.cpp
@@ -2420,7 +2420,6 @@ void IConsoleStdLibRegister()
IConsole::AliasRegister("name", "setting client_name %+");
IConsole::AliasRegister("server_name", "setting server_name %+");
IConsole::AliasRegister("server_port", "setting server_port %+");
- IConsole::AliasRegister("server_advertise", "setting server_advertise %+");
IConsole::AliasRegister("max_clients", "setting max_clients %+");
IConsole::AliasRegister("max_companies", "setting max_companies %+");
IConsole::AliasRegister("max_spectators", "setting max_spectators %+");
diff --git a/src/lang/english.txt b/src/lang/english.txt
index 813705958..baf94c2ee 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -1995,8 +1995,11 @@ STR_FACE_TIE :Tie:
STR_FACE_EARRING :Earring:
STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Change tie or earring
+############ Next lines match ServerGameType
STR_NETWORK_SERVER_VISIBILITY_LOCAL :Local
STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Public
+STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY :Invite only
+############ End of leave-in-this-order
# Network server list
STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multiplayer
diff --git a/src/network/network.cpp b/src/network/network.cpp
index f8138bbbc..d35fbe746 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -934,7 +934,7 @@ bool NetworkServerStart()
NetworkInitGameInfo();
- if (_settings_client.network.server_advertise) {
+ if (_settings_client.network.server_game_type != SERVER_GAME_TYPE_LOCAL) {
_network_coordinator_client.Register();
}
@@ -1000,6 +1000,29 @@ void NetworkDisconnect(bool blocking, bool close_admins)
}
/**
+ * The setting server_game_type was updated; possibly we need to take some
+ * action.
+ */
+void NetworkUpdateServerGameType()
+{
+ if (!_networking) return;
+
+ switch (_settings_client.network.server_game_type) {
+ case SERVER_GAME_TYPE_LOCAL:
+ _network_coordinator_client.CloseConnection();
+ break;
+
+ case SERVER_GAME_TYPE_INVITE_ONLY:
+ case SERVER_GAME_TYPE_PUBLIC:
+ _network_coordinator_client.Register();
+ break;
+
+ default:
+ NOT_REACHED();
+ }
+}
+
+/**
* Receives something from the network.
* @return true if everything went fine, false when the connection got closed.
*/
diff --git a/src/network/network_coordinator.cpp b/src/network/network_coordinator.cpp
index 8bd81b6f6..22b303f00 100644
--- a/src/network/network_coordinator.cpp
+++ b/src/network/network_coordinator.cpp
@@ -94,8 +94,8 @@ bool ClientNetworkCoordinatorSocketHandler::Receive_GC_ERROR(Packet *p)
SetDParamStr(0, detail);
ShowErrorMessage(STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED, STR_JUST_RAW_STRING, WL_ERROR);
- /* To prevent that we constantly try to reconnect, switch to private game. */
- _settings_client.network.server_advertise = false;
+ /* To prevent that we constantly try to reconnect, switch to local game. */
+ _settings_client.network.server_game_type = SERVER_GAME_TYPE_LOCAL;
this->CloseConnection();
return false;
@@ -153,9 +153,18 @@ bool ClientNetworkCoordinatorSocketHandler::Receive_GC_REGISTER_ACK(Packet *p)
default: connection_type = "Unknown"; break; // Should never happen, but don't fail if it does.
}
+ std::string game_type;
+ switch (_settings_client.network.server_game_type) {
+ case SERVER_GAME_TYPE_INVITE_ONLY: game_type = "Invite only"; break;
+ case SERVER_GAME_TYPE_PUBLIC: game_type = "Public"; break;
+
+ case SERVER_GAME_TYPE_LOCAL: // Impossible to register local servers.
+ default: game_type = "Unknown"; break; // Should never happen, but don't fail if it does.
+ }
+
Debug(net, 3, "----------------------------------------");
Debug(net, 3, "Your server is now registered with the Game Coordinator:");
- Debug(net, 3, " Game type: Public");
+ Debug(net, 3, " Game type: {}", game_type);
Debug(net, 3, " Connection type: {}", connection_type);
Debug(net, 3, " Invite code: {}", _network_server_invite_code);
Debug(net, 3, "----------------------------------------");
@@ -298,7 +307,7 @@ void ClientNetworkCoordinatorSocketHandler::Register()
Packet *p = new Packet(PACKET_COORDINATOR_SERVER_REGISTER);
p->Send_uint8(NETWORK_COORDINATOR_VERSION);
- p->Send_uint8(SERVER_GAME_TYPE_PUBLIC);
+ p->Send_uint8(_settings_client.network.server_game_type);
p->Send_uint16(_settings_client.network.server_port);
if (_settings_client.network.server_invite_code.empty() || _settings_client.network.server_invite_code_secret.empty()) {
p->Send_string("");
@@ -467,7 +476,7 @@ void ClientNetworkCoordinatorSocketHandler::CloseAllTokens()
void ClientNetworkCoordinatorSocketHandler::SendReceive()
{
/* Private games are not listed via the Game Coordinator. */
- if (_network_server && !_settings_client.network.server_advertise) {
+ if (_network_server && _settings_client.network.server_game_type == SERVER_GAME_TYPE_LOCAL) {
if (this->sock != INVALID_SOCKET) {
this->CloseConnection();
}
diff --git a/src/network/network_func.h b/src/network/network_func.h
index 6da8fb5cc..c0f68f915 100644
--- a/src/network/network_func.h
+++ b/src/network/network_func.h
@@ -39,6 +39,7 @@ bool NetworkValidateOurClientName();
bool NetworkValidateClientName(std::string &client_name);
bool NetworkValidateServerName(std::string &server_name);
void NetworkUpdateClientName(const std::string &client_name);
+void NetworkUpdateServerGameType();
bool NetworkCompanyHasClients(CompanyID company);
std::string NetworkChangeCompanyPassword(CompanyID company_id, std::string password);
void NetworkReboot();
diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp
index a0d2d47c8..d2fefb5cc 100644
--- a/src/network/network_gui.cpp
+++ b/src/network/network_gui.cpp
@@ -61,16 +61,6 @@ static ClientID _admin_client_id = INVALID_CLIENT_ID; ///< For what client a con
static CompanyID _admin_company_id = INVALID_COMPANY; ///< For what company a confirmation window is open.
/**
- * Visibility of the server. Public servers advertise, where private servers
- * do not.
- */
-static const StringID _server_visibility_dropdown[] = {
- STR_NETWORK_SERVER_VISIBILITY_LOCAL,
- STR_NETWORK_SERVER_VISIBILITY_PUBLIC,
- INVALID_STRING_ID
-};
-
-/**
* Update the network new window because a new server is
* found on the network.
*/
@@ -79,6 +69,17 @@ void UpdateNetworkGameWindow()
InvalidateWindowData(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME, 0);
}
+static DropDownList BuildVisibilityDropDownList()
+{
+ DropDownList list;
+
+ list.emplace_back(new DropDownListStringItem(STR_NETWORK_SERVER_VISIBILITY_LOCAL, SERVER_GAME_TYPE_LOCAL, false));
+ list.emplace_back(new DropDownListStringItem(STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY, SERVER_GAME_TYPE_INVITE_ONLY, false));
+ list.emplace_back(new DropDownListStringItem(STR_NETWORK_SERVER_VISIBILITY_PUBLIC, SERVER_GAME_TYPE_PUBLIC, false));
+
+ return list;
+}
+
typedef GUIList<NetworkGameList*, StringFilter&> GUIGameServerList;
typedef int ServerListPosition;
static const ServerListPosition SLP_INVALID = -1;
@@ -1015,7 +1016,7 @@ struct NetworkStartServerWindow : public Window {
{
switch (widget) {
case WID_NSS_CONNTYPE_BTN:
- SetDParam(0, _server_visibility_dropdown[_settings_client.network.server_advertise]);
+ SetDParam(0, STR_NETWORK_SERVER_VISIBILITY_LOCAL + _settings_client.network.server_game_type);
break;
case WID_NSS_CLIENTS_TXT:
@@ -1036,7 +1037,7 @@ struct NetworkStartServerWindow : public Window {
{
switch (widget) {
case WID_NSS_CONNTYPE_BTN:
- *size = maxdim(GetStringBoundingBox(_server_visibility_dropdown[0]), GetStringBoundingBox(_server_visibility_dropdown[1]));
+ *size = maxdim(maxdim(GetStringBoundingBox(STR_NETWORK_SERVER_VISIBILITY_LOCAL), GetStringBoundingBox(STR_NETWORK_SERVER_VISIBILITY_PUBLIC)), GetStringBoundingBox(STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY));
size->width += padding.width;
size->height += padding.height;
break;
@@ -1066,7 +1067,7 @@ struct NetworkStartServerWindow : public Window {
break;
case WID_NSS_CONNTYPE_BTN: // Connection type
- ShowDropDownMenu(this, _server_visibility_dropdown, _settings_client.network.server_advertise, WID_NSS_CONNTYPE_BTN, 0, 0); // do it for widget WID_NSS_CONNTYPE_BTN
+ ShowDropDownList(this, BuildVisibilityDropDownList(), _settings_client.network.server_game_type, WID_NSS_CONNTYPE_BTN);
break;
case WID_NSS_CLIENTS_BTND: case WID_NSS_CLIENTS_BTNU: // Click on up/down button for number of clients
@@ -1144,7 +1145,7 @@ struct NetworkStartServerWindow : public Window {
{
switch (widget) {
case WID_NSS_CONNTYPE_BTN:
- _settings_client.network.server_advertise = (index != 0);
+ _settings_client.network.server_game_type = (ServerGameType)index;
break;
default:
NOT_REACHED();
@@ -2041,7 +2042,7 @@ public:
{
switch (widget) {
case WID_CL_SERVER_VISIBILITY:
- *size = maxdim(GetStringBoundingBox(_server_visibility_dropdown[0]), GetStringBoundingBox(_server_visibility_dropdown[1]));
+ *size = maxdim(maxdim(GetStringBoundingBox(STR_NETWORK_SERVER_VISIBILITY_LOCAL), GetStringBoundingBox(STR_NETWORK_SERVER_VISIBILITY_PUBLIC)), GetStringBoundingBox(STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY));
size->width += padding.width;
size->height += padding.height;
break;
@@ -2073,7 +2074,7 @@ public:
break;
case WID_CL_SERVER_VISIBILITY:
- SetDParam(0, _server_visibility_dropdown[_settings_client.network.server_advertise]);
+ SetDParam(0, STR_NETWORK_SERVER_VISIBILITY_LOCAL + _settings_client.network.server_game_type);
break;
case WID_CL_SERVER_INVITE_CODE: {
@@ -2117,7 +2118,7 @@ public:
case WID_CL_SERVER_VISIBILITY:
if (!_network_server) break;
- ShowDropDownMenu(this, _server_visibility_dropdown, _settings_client.network.server_advertise, WID_CL_SERVER_VISIBILITY, 0, 0);
+ ShowDropDownList(this, BuildVisibilityDropDownList(), _settings_client.network.server_game_type, WID_CL_SERVER_VISIBILITY);
break;
case WID_CL_MATRIX: {
@@ -2183,7 +2184,8 @@ public:
case WID_CL_SERVER_VISIBILITY:
if (!_network_server) break;
- _settings_client.network.server_advertise = (index != 0);
+ _settings_client.network.server_game_type = (ServerGameType)index;
+ NetworkUpdateServerGameType();
break;
case WID_CL_MATRIX: {
diff --git a/src/network/network_type.h b/src/network/network_type.h
index 6e6fe33de..a3fb217fe 100644
--- a/src/network/network_type.h
+++ b/src/network/network_type.h
@@ -42,6 +42,7 @@ enum NetworkVehicleType {
enum ServerGameType : uint8 {
SERVER_GAME_TYPE_LOCAL = 0,
SERVER_GAME_TYPE_PUBLIC,
+ SERVER_GAME_TYPE_INVITE_ONLY,
};
/** 'Unique' identifier to be given to clients */
diff --git a/src/settings_type.h b/src/settings_type.h
index 79e462c3e..93e2f049f 100644
--- a/src/settings_type.h
+++ b/src/settings_type.h
@@ -15,6 +15,7 @@
#include "town_type.h"
#include "transport_type.h"
#include "network/core/config.h"
+#include "network/network_type.h"
#include "company_type.h"
#include "cargotype.h"
#include "linkgraph/linkgraph_type.h"
@@ -266,6 +267,7 @@ struct NetworkSettings {
uint16 server_port; ///< port the server listens on
uint16 server_admin_port; ///< port the server listens on for the admin network
bool server_admin_chat; ///< allow private chat for the server to be distributed to the admin network
+ ServerGameType server_game_type; ///< Server type: local / public / invite-only.
std::string server_invite_code; ///< Invite code to use when registering as server.
std::string server_invite_code_secret; ///< Secret to proof we got this invite code from the Game Coordinator.
std::string server_name; ///< name of the server
diff --git a/src/table/settings/network_settings.ini b/src/table/settings/network_settings.ini
index 45459b6e1..552f58823 100644
--- a/src/table/settings/network_settings.ini
+++ b/src/table/settings/network_settings.ini
@@ -9,14 +9,18 @@
[pre-amble]
static void UpdateClientConfigValues();
+static std::initializer_list<const char*> _server_game_type{"local", "public", "invite-only"};
+
static const SettingVariant _network_settings_table[] = {
[post-amble]
};
[templates]
SDTC_BOOL = SDTC_BOOL( $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup),
+SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup),
SDTC_VAR = SDTC_VAR( $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $extra, $startup),
[validation]
+SDTC_OMANY = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size");
SDTC_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size");
[defaults]
@@ -159,10 +163,16 @@ flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY
def = true
cat = SC_EXPERT
-[SDTC_BOOL]
-var = network.server_advertise
+[SDTC_OMANY]
+var = network.server_game_type
+type = SLE_UINT8
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY
-def = false
+def = SERVER_GAME_TYPE_LOCAL
+min = SERVER_GAME_TYPE_LOCAL
+max = SERVER_GAME_TYPE_INVITE_ONLY
+full = _server_game_type
+post_cb = [](auto) { NetworkUpdateServerGameType(); }
+cat = SC_BASIC
[SDTC_BOOL]
var = network.autoclean_companies