widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #11407
Re: [Merge] lp:~widelands-dev/widelands/net-uuid into lp:widelands
Looks mostly OK - I have added some nits.
We should test to make sure that 2 Widelands instances can be run from the same computer and join the same game. I need to figure out how to run a metaserver.
Diff comments:
>
> === modified file 'src/network/internet_gaming.cc'
> --- src/network/internet_gaming.cc 2017-08-16 04:31:56 +0000
> +++ src/network/internet_gaming.cc 2017-10-14 06:58:24 +0000
> @@ -416,19 +405,24 @@
> if (state_ == CONNECTING) {
> if (cmd == IGPCMD_LOGIN) {
> // Clients request to login was granted
> - clientname_ = packet.string();
> + std::string assigned_name = packet.string();
> + if (clientname_ != assigned_name) {
> + format_and_add_chat("", "", true,
> + (boost::format(
> + _("You logged in as '%s' since your requested name is already in use or reserved."))
You have been logged in...
> + % assigned_name).str());
> + }
> + clientname_ = assigned_name;
> clientrights_ = packet.string();
> + if (clientrights_ == INTERNET_CLIENT_UNREGISTERED) {
> + // Might happen that we log in with less rights than we wanted to.
> + // Happens when we are already logged in with another client.
> + reg_ = false;
> + }
> state_ = LOBBY;
> log("InternetGaming: Client %s logged in.\n", clientname_.c_str());
> return;
>
> - } else if (cmd == IGPCMD_RELOGIN) {
> - // Clients request to relogin was granted
> - state_ = LOBBY;
> - log("InternetGaming: Client %s relogged in.\n", clientname_.c_str());
> - format_and_add_chat("", "", true, _("Successfully reconnected to the metaserver!"));
> - return;
> -
> } else if (cmd == IGPCMD_ERROR) {
> std::string errortype = packet.string();
> if (errortype != "LOGIN" && errortype != "RELOGIN") {
> @@ -451,9 +445,8 @@
> cmd.c_str());
> }
> }
> -
> try {
> - if (cmd == IGPCMD_LOGIN || cmd == IGPCMD_RELOGIN) {
> + if (cmd == IGPCMD_LOGIN) {// || cmd == IGPCMD_RELOGIN) {
Remove commented out code
> // Login specific commands but not in CONNECTING state...
> log("InternetGaming: Received %s cmd although client is not in CONNECTING state.\n",
> cmd.c_str());
> @@ -766,6 +759,10 @@
>
> /// ChatProvider: sends a message via the metaserver.
> void InternetGaming::send(const std::string& msg) {
> + // TODO(Notabilis): Messages can get lost when we are temporarily disconnected from the metaserver,
> + // even when we reconnect again. "Answered" messages like IGPCMD_GAME_CONNECT are resend but chat
resend -> resent
> + // messages are not. Resend them after some time when we did not received the matching IGPCMD_CHAT
received -> receive
> + // command from the server?
> if (!logged_in()) {
> format_and_add_chat(
> "", "", true, _("Message could not be sent: You are not connected to the metaserver!"));
> @@ -777,6 +774,7 @@
>
> if (msg.size() && *msg.begin() == '@') {
> // Format a personal message
> + // TODO(Notabilis): msg should be trimmed before checking for the space character
You can do that right now with boost::trim. Include <boost/algorithm/string.hpp> for that.
> std::string::size_type const space = msg.find(' ');
> if (space >= msg.size() - 1) {
> format_and_add_chat(
> @@ -834,6 +832,7 @@
> SendPacket m;
> m.string(IGPCMD_ANNOUNCEMENT);
> m.string(arg);
> + // NOCOM(Notabilis): This looks like a bug to me
Can you be a bit more specific? We shouldn't have NOCOM stuff in trunk.
> net->send(s);
> return;
> } else
>
> === modified file 'src/network/internet_gaming.h'
> --- src/network/internet_gaming.h 2017-07-01 08:22:54 +0000
> +++ src/network/internet_gaming.h 2017-10-14 06:58:24 +0000
> @@ -57,10 +57,12 @@
> void reset();
>
> // Login and logout
> + // pwd should contain either the password for a registered account or the UUID otherwise
> void initialize_connection();
> bool login(const std::string& nick,
> const std::string& pwd,
> bool registered,
> + bool send_uuid,
sent_uuid or uuid_to_send?
> const std::string& metaserver,
> uint32_t port);
> bool relogin();
> @@ -189,6 +198,8 @@
> /// data saved for possible relogin
> std::string pwd_;
> bool reg_;
> + bool send_uuid_;
sent_uuid_ or uuid_to_send_?
> + std::string tmp_uuid_;
> std::string meta_;
> uint16_t port_;
>
>
> === modified file 'src/network/internet_gaming_protocol.h'
> --- src/network/internet_gaming_protocol.h 2017-07-01 08:22:54 +0000
> +++ src/network/internet_gaming_protocol.h 2017-10-14 06:58:24 +0000
> @@ -99,27 +103,38 @@
> */
>
> /**
> - * The nonce:
> - *
> - * The nonce is used on the metaserver to link multiple connections by the same client. This
> - * normally
> - * happens when the client supports IPv4 and IPv6 and connects with both protocol versions. This
> - * way,
> - * the metaserver knows that the clients supports both versions and can show games / offer his game
> + * The UUID:
> + *
> + * The UUID is a semi-permanent ID stored in the configuration file of Widelands.
> + * It has to be stored in the file since it should survive crashes of the game or computer.
> + * If the game is not started for 24 hours, a new one is created to increase privacy.
> + * Basically it allows the metaserver to identify the user even when multiple users try to join with
> + * the same username. This is only used for unregistered users, registered users can use their
> + * password instead.
> + * Note that the send UUID differs from the stored one: The send UUID is hash(username | stored-id).
send -> sent
> + * Use-cases of the UUID in detail:
> + *
> + * 1) The UUID replaced the nonce introduced with IPv6.
> + * The UUID is used on the metaserver to link multiple connections by the same client. This
> + * normally happens when the client supports IPv4 and IPv6 and connects with both protocol versions. This
> + * way, the metaserver knows that the clients supports both versions and can show games / offer his game
clients support or client supports. his -> its
> * of/for clients with both protocol versions.
> *
> - * When a network client connects to the metaserver with (RE)LOGIN he also sends a nonce.
> - * When "another" netclient connects to the metaserver and sends TELL_IP containing the same nonce,
> + * When a network client connects to the metaserver with (RE)LOGIN he also sends the UUID.
he -> it
> + * When "another" netclient connects to the metaserver and sends TELL_IP containing the same UUID,
> * it is considered the same game client connecting with another IP. This way, two connections by
> - * IPv4 and
> - * IPv6 can be matched so the server learns both addresses of the client.
> - *
> - * In the case of registered players, the password can be used instead of a random nonce. The
> - * username alone
> - * can not be used for this, especially not for unregistered users: The metaserver can not
> - * differentiate
> - * between a second connection by the user and an initial login of another user (with the same
> - * name).
> + * IPv4 and IPv6 can be matched so the server learns both addresses of the client.
> + *
> + * In the case of registered players, the password can be used instead of a UUID. The username
> + * alone can not be used for this, especially not for unregistered users: The metaserver can not
> + * differentiate between a second connection by the user and an initial login of another user
> + * (with the same name).
> + *
> + * 2) Reconnect after crash / network problems.
> + * When Widelands breaks the connection without logging out, the server still assumes that the old
> + * connection is active. So when the player reconnects, another name is chosen. Sending the UUID allows
> + * to reclaim the old name, since the server recognizes that there isn't a second player trying to use
> + * the same name.
> */
>
> /**
>
> === modified file 'src/ui_fsmenu/internet_lobby.cc'
> --- src/ui_fsmenu/internet_lobby.cc 2017-06-20 19:55:32 +0000
> +++ src/ui_fsmenu/internet_lobby.cc 2017-10-14 06:58:24 +0000
> @@ -103,7 +104,8 @@
> // Login information
> nickname_(nick),
> password_(pwd),
> - is_registered_(registered) {
> + is_registered_(registered),
> + send_uuid_(send_uuid) {
Please rename - same as above
> joingame_.sigclicked.connect(
> boost::bind(&FullscreenMenuInternetLobby::clicked_joingame, boost::ref(*this)));
> hostgame_.sigclicked.connect(
>
> === modified file 'src/ui_fsmenu/multiplayer.cc'
> --- src/ui_fsmenu/multiplayer.cc 2017-02-25 13:27:40 +0000
> +++ src/ui_fsmenu/multiplayer.cc 2017-10-14 06:58:24 +0000
> @@ -105,14 +105,17 @@
> nickname_ = s.get_string("nickname", _("nobody"));
> password_ = s.get_string("password", "nobody");
> register_ = s.get_bool("registered", false);
> + send_uuid_ = s.get_bool("send_uuid", false);
Please rename - same as above
> } else {
> LoginBox lb(*this);
> if (lb.run<UI::Panel::Returncodes>() == UI::Panel::Returncodes::kOk) {
> nickname_ = lb.get_nickname();
> password_ = lb.get_password();
> register_ = lb.registered();
> + send_uuid_ = lb.send_uuid();
Please rename - same as above
>
> s.set_bool("registered", lb.registered());
> + s.set_bool("send_uuid", lb.send_uuid());
> s.set_bool("auto_log", lb.set_automaticlog());
> } else {
> return;
>
> === modified file 'src/wlapplication.cc'
> --- src/wlapplication.cc 2017-09-11 08:09:07 +0000
> +++ src/wlapplication.cc 2017-10-14 06:58:24 +0000
> @@ -763,6 +766,34 @@
> s.get_natural("metaserverport");
> // KLUDGE!
>
> + long int last_start = s.get_int("last_start", 0);
> + if (last_start + 24*60*60 < time(nullptr)) {
We uses spaces between arithmetic operators: 24 * 60 * 60
> + // First start of the game or not started for 24 hours. Create a (new) UUID.
> + // Admittedly this is a pretty stupid generator. But it should be fine for us.
> + // For the use of the UUID, see network/internet_gaming_protocol.h
> + static const std::string random_chars = "0123456789ABCDEF";
Looks like you have the same code above - can you pull out a function?
> + std::string uuid;
> + std::random_device rd;
> + std::mt19937 gen(rd());
> + std::uniform_int_distribution<> dist(0, random_chars.length() - 1);
> + while (uuid.length() < 16) {
> + uuid.push_back(random_chars[dist(gen)]);
> + }
> + s.set_string("uuid", uuid);
> + }
> + s.set_int("last_start", time(nullptr));
> +
> + // Save configuration now. Otherwise, the UUID is not saved
> + // when the game crashes, loosing part of its advantage
> + // NOCOM(Sebastian): This might be broken. Starting a second game re-enables the music
We should not have NOCOMs in the code - do you need help debugging?
> + try {
> + g_options.write("config", false);
> + } catch (const std::exception& e) {
> + log("WARNING: could not save configuration: %s\n", e.what());
> + } catch (...) {
> + log("WARNING: could not save configuration");
> + }
> +
> return true;
> }
>
--
https://code.launchpad.net/~widelands-dev/widelands/net-uuid/+merge/332264
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/net-uuid into lp:widelands.
References