changeset 223:2dc0355c3417

Irccd: get rid of ServerIdentity, Ref T1
author David Demelier <markand@malikania.fr>
date Tue, 12 Jul 2016 12:50:44 +0200
parents 29ebf432c30a
children 01fc0e526a9d
files lib/irccd/cmd-server-connect.cpp lib/irccd/cmd-server-info.cpp lib/irccd/cmd-server-nick.cpp lib/irccd/config.cpp lib/irccd/config.hpp lib/irccd/mod-server.cpp lib/irccd/server-private.hpp lib/irccd/server-state-connecting.cpp lib/irccd/server.cpp lib/irccd/server.hpp
diffstat 10 files changed, 180 insertions(+), 133 deletions(-) [+]
line wrap: on
line diff
--- a/lib/irccd/cmd-server-connect.cpp	Thu Jul 07 13:13:34 2016 +0200
+++ b/lib/irccd/cmd-server-connect.cpp	Tue Jul 12 12:50:44 2016 +0200
@@ -88,21 +88,18 @@
     return info;
 }
 
-ServerIdentity readIdentity(const json &object)
+void readIdentity(Server &server, const json &object)
 {
-    ServerIdentity identity;
     json::const_iterator it;
 
     if ((it = object.find("nickname")) != object.end() && it->is_string())
-        identity.nickname = *it;
+        server.setNickname(*it);
     if ((it = object.find("realname")) != object.end() && it->is_string())
-        identity.realname = *it;
+        server.setRealname(*it);
     if ((it = object.find("username")) != object.end() && it->is_string())
-        identity.username = *it;
+        server.setUsername(*it);
     if ((it = object.find("ctcpVersion")) != object.end() && it->is_string())
-        identity.ctcpversion = *it;
-
-    return identity;
+        server.setCtcpVersion(*it);
 }
 
 ServerSettings readSettings(const json &object)
@@ -163,7 +160,9 @@
 
 json ServerConnect::exec(Irccd &irccd, const json &request) const
 {
-    auto server = std::make_shared<Server>(readInfoName(request), readInfo(request), readIdentity(request), readSettings(request));
+    auto server = std::make_shared<Server>(readInfoName(request), readInfo(request), readSettings(request));
+
+    readIdentity(*server, request);
 
     if (irccd.serverService().has(server->name()))
         throw std::invalid_argument("server '{}' already exists"_format(server->name()));
--- a/lib/irccd/cmd-server-info.cpp	Thu Jul 07 13:13:34 2016 +0200
+++ b/lib/irccd/cmd-server-info.cpp	Tue Jul 12 12:50:44 2016 +0200
@@ -65,9 +65,9 @@
     response.push_back({"name", server->name()});
     response.push_back({"host", server->info().host});
     response.push_back({"port", server->info().port});
-    response.push_back({"nickname", server->identity().nickname});
-    response.push_back({"username", server->identity().username});
-    response.push_back({"realname", server->identity().realname});
+    response.push_back({"nickname", server->nickname()});
+    response.push_back({"username", server->username()});
+    response.push_back({"realname", server->realname()});
 
     // Optional stuff.
     if (server->info().flags & irccd::ServerInfo::Ipv6)
--- a/lib/irccd/cmd-server-nick.cpp	Thu Jul 07 13:13:34 2016 +0200
+++ b/lib/irccd/cmd-server-nick.cpp	Tue Jul 12 12:50:44 2016 +0200
@@ -63,7 +63,7 @@
 {
     Command::exec(irccd, object);
 
-    irccd.serverService().require(object["server"])->nick(object["nickname"]);
+    irccd.serverService().require(object["server"])->setNickname(object["nickname"]);
 
     return nlohmann::json::object();
 }
--- a/lib/irccd/config.cpp	Thu Jul 07 13:13:34 2016 +0200
+++ b/lib/irccd/config.cpp	Tue Jul 12 12:50:44 2016 +0200
@@ -90,31 +90,6 @@
     return ito->value();
 }
 
-ServerIdentity loadIdentity(const ini::Section &sc)
-{
-    assert(sc.key() == "identity");
-    assert(sc.contains("name") && util::isIdentifierValid(sc["name"].value()));
-
-    ServerIdentity identity;
-
-    // Mandatory stuff.
-    identity.name = sc["name"].value();
-
-    // Optional stuff.
-    ini::Section::const_iterator it;
-
-    if ((it = sc.find("username")) != sc.end())
-        identity.username = it->value();
-    if ((it = sc.find("realname")) != sc.end())
-        identity.realname = it->value();
-    if ((it = sc.find("nickname")) != sc.end())
-        identity.nickname = it->value();
-    if ((it = sc.find("ctcp-version")) != sc.end())
-        identity.ctcpversion = it->value();
-
-    return identity;
-}
-
 PluginConfig loadPluginConfig(const ini::Section &sc)
 {
     PluginConfig config;
@@ -297,7 +272,6 @@
 
     std::string name;
     ServerInfo info;
-    ServerIdentity identity;
     ServerSettings settings;
 
     // Name.
@@ -316,10 +290,6 @@
 
     info.host = it->value();
 
-    // Optional identity
-    if ((it = sc.find("identity")) != sc.end())
-        identity = config.findIdentity(it->value());
-
     // Optional port
     if ((it = sc.find("port")) != sc.end()) {
         try {
@@ -380,7 +350,13 @@
         log::warning("server {}: invalid number for {}: {}"_format(name, it->key(), it->value()));
     }
 
-    return std::make_shared<Server>(std::move(name), std::move(info), std::move(identity), std::move(settings));
+    auto server = std::make_shared<Server>(std::move(name), std::move(info), std::move(settings));
+
+    // Optional identity
+    if ((it = sc.find("identity")) != sc.end())
+        config.loadServerIdentity(*server, it->value());
+
+    return server;
 }
 
 } // !namespace
@@ -403,31 +379,30 @@
     throw std::runtime_error("no configuration file found");
 }
 
-ServerIdentity Config::findIdentity(const std::string &name) const
+void Config::loadServerIdentity(Server &server, const std::string &identity) const
 {
-    assert(util::isIdentifierValid(name));
+    ini::Document::const_iterator sc = std::find_if(m_document.begin(), m_document.end(), [&] (const auto &sc) {
+        if (sc.key() != "identity")
+            return false;
 
-    for (const auto &section : m_document) {
-        if (section.key() != "identity")
-            continue;
+        auto name = sc.find("name");
 
-        auto it = section.find("name");
+        return name != sc.end() && name->value() == identity;
+    });
 
-        if (it == section.end()) {
-            log::warning("identity: missing 'name' property");
-            continue;
-        }
-        if (!util::isIdentifierValid(it->value())) {
-            log::warning("identity: invalid identifier: {}"_format(it->value()));
-            continue;
-        }
-        if (it->value() != name)
-            continue;
+    if (sc == m_document.end())
+        return;
+
+    ini::Section::const_iterator it;
 
-        return loadIdentity(section);
-    }
-
-    return ServerIdentity();
+    if ((it = sc->find("username")) != sc->end())
+        server.setUsername(it->value());
+    if ((it = sc->find("realname")) != sc->end())
+        server.setRealname(it->value());
+    if ((it = sc->find("nickname")) != sc->end())
+        server.setNickname(it->value());
+    if ((it = sc->find("ctcp-version")) != sc->end())
+        server.setCtcpVersion(it->value());
 }
 
 PluginConfig Config::findPluginConfig(const std::string &name) const
--- a/lib/irccd/config.hpp	Thu Jul 07 13:13:34 2016 +0200
+++ b/lib/irccd/config.hpp	Tue Jul 12 12:50:44 2016 +0200
@@ -37,7 +37,6 @@
 class Irccd;
 class Rule;
 class Server;
-class ServerIdentity;
 class TransportServer;
 
 /**
@@ -79,15 +78,17 @@
         return m_path;
     }
 
-    /**
+   /**
      * Find an entity if defined in the configuration file.
      *
      * \pre util::isValidIdentifier(name)
+     * \param server the server to update
+     * \param name the identity name
      * \return default identity if cannot be found
      */
-    IRCCD_EXPORT ServerIdentity findIdentity(const std::string &name) const;
+    IRCCD_EXPORT void loadServerIdentity(Server &server, const std::string &name) const;
 
-    /**
+     /**
      * Find a plugin configuration if defined in the configuration file.
      *
      * \pre util::isValidIdentifier(name)
--- a/lib/irccd/mod-server.cpp	Thu Jul 07 13:13:34 2016 +0200
+++ b/lib/irccd/mod-server.cpp	Tue Jul 12 12:50:44 2016 +0200
@@ -89,31 +89,31 @@
     return info;
 }
 
-ServerIdentity readIdentity(duk_context *ctx)
+void readIdentity(Server &server, duk_context *ctx)
 {
-    ServerIdentity identity;
-
     // 'nickname' property.
     duk_get_prop_string(ctx, 0, "nickname");
-    identity.nickname = duk_is_string(ctx, -1) ? dukx_get_std_string(ctx, -1) : identity.nickname;
+    if (duk_is_string(ctx, -1))
+        server.setNickname(dukx_get_std_string(ctx, -1));
     duk_pop(ctx);
 
     // 'username' property.
     duk_get_prop_string(ctx, 0, "username");
-    identity.username = duk_is_string(ctx, -1) ? dukx_get_std_string(ctx, -1) : identity.username;
+    if (duk_is_string(ctx, -1))
+        server.setUsername(dukx_get_std_string(ctx, -1));
     duk_pop(ctx);
 
     // 'realname' property.
     duk_get_prop_string(ctx, 0, "realname");
-    identity.realname = duk_is_string(ctx, -1) ? dukx_get_std_string(ctx, -1) : identity.realname;
+    if (duk_is_string(ctx, -1))
+        server.setRealname(dukx_get_std_string(ctx, -1));
     duk_pop(ctx);
 
     // 'ctcpversion' property.
     duk_get_prop_string(ctx, 0, "version");
-    identity.ctcpversion = duk_is_string(ctx, -1) ? dukx_get_std_string(ctx, -1) : identity.ctcpversion;
+    if (duk_is_string(ctx, -1))
+        server.setCtcpVersion(dukx_get_std_string(ctx, -1));
     duk_pop(ctx);
-
-    return identity;
 }
 
 ServerSettings readSettings(duk_context *ctx)
@@ -216,11 +216,11 @@
     duk_put_prop_string(ctx, -2, "sslVerify");
     dukx_push_std_string(ctx, server->settings().command);
     duk_put_prop_string(ctx, -2, "commandChar");
-    dukx_push_std_string(ctx, server->identity().realname);
+    dukx_push_std_string(ctx, server->realname());
     duk_put_prop_string(ctx, -2, "realname");
-    dukx_push_std_string(ctx, server->identity().nickname);
+    dukx_push_std_string(ctx, server->nickname());
     duk_put_prop_string(ctx, -2, "nickname");
-    dukx_push_std_string(ctx, server->identity().username);
+    dukx_push_std_string(ctx, server->username());
     duk_put_prop_string(ctx, -2, "username");
     dukx_push_array(ctx, server->settings().channels, [] (auto ctx, auto channel) {
         dukx_push_std_string(ctx, channel.name);
@@ -359,7 +359,7 @@
  */
 duk_ret_t nick(duk_context *ctx)
 {
-    self(ctx)->nick(duk_require_string(ctx, 0));
+    self(ctx)->setNickname(duk_require_string(ctx, 0));
 
     return 0;
 }
@@ -491,7 +491,9 @@
         return 0;
 
     try {
-        auto s = std::make_shared<Server>(readName(ctx), readInfo(ctx), readIdentity(ctx), readSettings(ctx));
+        auto s = std::make_shared<Server>(readName(ctx), readInfo(ctx), readSettings(ctx));
+
+        readIdentity(*s, ctx);
 
         duk_push_this(ctx);
         duk_push_pointer(ctx, new std::shared_ptr<Server>(std::move(s)));
--- a/lib/irccd/server-private.hpp	Thu Jul 07 13:13:34 2016 +0200
+++ b/lib/irccd/server-private.hpp	Tue Jul 12 12:50:44 2016 +0200
@@ -74,6 +74,16 @@
     {
         return m_handle;
     }
+
+    /**
+     * Tells if the connection is made.
+     *
+     * \return true if connected
+     */
+    inline bool isConnected() const noexcept
+    {
+        return irc_is_connected(m_handle.get());
+    }
 };
 
 } // !irccd
--- a/lib/irccd/server-state-connecting.cpp	Thu Jul 07 13:13:34 2016 +0200
+++ b/lib/irccd/server-state-connecting.cpp	Tue Jul 12 12:50:44 2016 +0200
@@ -43,7 +43,6 @@
 bool connect(Server &server)
 {
     const ServerInfo &info = server.info();
-    const ServerIdentity &identity = server.identity();
     const char *password = info.password.empty() ? nullptr : info.password.c_str();
     std::string host = info.host;
     int code;
@@ -58,14 +57,14 @@
 
     if (info.flags & ServerInfo::Ipv6) {
         code = irc_connect6(server.session(), host.c_str(), info.port, password,
-                    identity.nickname.c_str(),
-                    identity.username.c_str(),
-                    identity.realname.c_str());
+                            server.nickname().c_str(),
+                            server.username().c_str(),
+                            server.realname().c_str());
     } else {
         code = irc_connect(server.session(), host.c_str(), info.port, password,
-                   identity.nickname.c_str(),
-                   identity.username.c_str(),
-                   identity.realname.c_str());
+                           server.nickname().c_str(),
+                           server.username().c_str(),
+                           server.realname().c_str());
     }
 
     return code == 0;
--- a/lib/irccd/server.cpp	Thu Jul 07 13:13:34 2016 +0200
+++ b/lib/irccd/server.cpp	Tue Jul 12 12:50:44 2016 +0200
@@ -188,7 +188,7 @@
 {
     // Update our nickname.
     if (isSelf(strify(orig)))
-        m_identity.nickname = strify(params[0]);
+        m_nickname = strify(params[0]);
 
     onNick(NickEvent{shared_from_this(), strify(orig), strify(params[0])});
 }
@@ -343,11 +343,10 @@
     return ServerChannel{value, ""};
 }
 
-Server::Server(std::string name, ServerInfo info, ServerIdentity identity, ServerSettings settings)
+Server::Server(std::string name, ServerInfo info, ServerSettings settings)
     : m_name(std::move(name))
     , m_info(std::move(info))
     , m_settings(std::move(settings))
-    , m_identity(std::move(identity))
     , m_session(std::make_unique<Session>())
     , m_state(std::make_unique<state::Connecting>())
 {
@@ -418,7 +417,7 @@
 
     // Save this to the session.
     irc_set_ctx(*m_session, this);
-    irc_set_ctcp_version(*m_session, m_identity.ctcpversion.c_str());
+    irc_set_ctcp_version(*m_session, m_ctcpversion.c_str());
 }
 
 Server::~Server()
@@ -426,6 +425,22 @@
     irc_disconnect(*m_session);
 }
 
+void Server::setNickname(std::string nickname)
+{
+    if (m_session->isConnected())
+        m_queue.push([=] () {
+            return irc_cmd_nick(*m_session, nickname.c_str()) == 0;
+        });
+    else
+        m_nickname = std::move(nickname);
+}
+
+void Server::setCtcpVersion(std::string ctcpversion)
+{
+    m_ctcpversion = std::move(ctcpversion);
+    irc_set_ctcp_version(*m_session, ctcpversion.c_str());
+}
+
 void Server::update() noexcept
 {
     if (m_stateNext) {
@@ -477,7 +492,7 @@
 
     irc_target_get_nick(nick.c_str(), target, sizeof (target));
 
-    return m_identity.nickname == target;
+    return m_nickname == target;
 }
 
 void Server::cmode(std::string channel, std::string mode)
@@ -545,13 +560,6 @@
     });
 }
 
-void Server::nick(std::string newnick)
-{
-    m_queue.push([=] () {
-        return irc_cmd_nick(*m_session, newnick.c_str()) == 0;
-    });
-}
-
 void Server::notice(std::string target, std::string message)
 {
     m_queue.push([=] () {
--- a/lib/irccd/server.hpp	Thu Jul 07 13:13:34 2016 +0200
+++ b/lib/irccd/server.hpp	Tue Jul 12 12:50:44 2016 +0200
@@ -43,18 +43,6 @@
 namespace irccd {
 
 /**
- * \brief Identity to use when connecting.
- */
-class ServerIdentity {
-public:
-    std::string name{"irccd"};                      //!< identity name
-    std::string nickname{"irccd"};                  //!< nickname to show
-    std::string username{"irccd"};                  //!< username to use for connection
-    std::string realname{"IRC Client Daemon"};      //!< the full real name
-    std::string ctcpversion{"IRC Client Daemon"};   //!< the CTCP version to define
-};
-
-/**
  * \brief A channel to join with an optional password.
  */
 class ServerChannel {
@@ -474,10 +462,15 @@
     // Identifier.
     std::string m_name;
 
+    // Identity.
+    std::string m_nickname{"irccd"};
+    std::string m_username{"irccd"};
+    std::string m_realname{"IRC Client Daemon"};
+    std::string m_ctcpversion{"IRC Client Daemon"};
+
     // Various settings.
     ServerInfo m_info;
     ServerSettings m_settings;
-    ServerIdentity m_identity;
     ServerCache m_cache;
 
     // Queue of requests to send.
@@ -522,10 +515,9 @@
      *
      * \param name the identifier
      * \param info the information
-     * \param identity the identity
      * \param settings the settings
      */
-    IRCCD_EXPORT Server(std::string name, ServerInfo info, ServerIdentity identity = {}, ServerSettings settings = {});
+    IRCCD_EXPORT Server(std::string name, ServerInfo info, ServerSettings settings = {});
 
     /**
      * Destructor. Close the connection if needed.
@@ -543,6 +535,84 @@
     }
 
     /**
+     * Get the nickname.
+     *
+     * \return the nickname
+     */
+    inline const std::string &nickname() const noexcept
+    {
+        return m_nickname;
+    }
+
+    /**
+     * Set the nickname.
+     *
+     * If the server is connected, send a nickname command to the IRC server, otherwise change it locally.
+     *
+     * \param nickname the nickname
+     */
+    IRCCD_EXPORT void setNickname(std::string nickname);
+
+    /**
+     * Get the CTCP version.
+     *
+     * \return the CTCP version
+     */
+    inline const std::string &ctcpVersion() const noexcept
+    {
+        return m_ctcpversion;
+    }
+
+    /**
+     * Set the CTCP version.
+     *
+     * \param ctcpversion the version
+     */
+    IRCCD_EXPORT void setCtcpVersion(std::string ctcpversion);
+
+    /**
+     * Get the username.
+     *
+     * \return the username
+     */
+    inline const std::string &username() const noexcept
+    {
+        return m_username;
+    }
+
+    /**
+     * Set the username.
+     *
+     * \param name the username
+     * \note the username will be changed on the next connection
+     */
+    inline void setUsername(std::string name) noexcept
+    {
+        m_username = std::move(name);
+    }
+
+    /**
+     * Get the realname.
+     *
+     * \return the realname
+     */
+    inline const std::string &realname() const noexcept
+    {
+        return m_realname;
+    }
+
+    /**
+     * Set the realname.
+     *
+     * \param name the username
+     * \note the username will be changed on the next connection
+     */
+    inline void setRealname(std::string realname) noexcept
+    {
+        m_realname = std::move(realname);
+    }
+
+    /**
      * Get the server information.
      *
      * \return the server information
@@ -574,16 +644,6 @@
     }
 
     /**
-     * Access the identity.
-     *
-     * \return the identity
-     */
-    inline const ServerIdentity &identity() const noexcept
-    {
-        return m_identity;
-    }
-
-    /**
      * Access the cache.
      *
      * \return the cache
@@ -730,13 +790,6 @@
     IRCCD_EXPORT virtual void names(std::string channel);
 
     /**
-     * Change your nickname.
-     *
-     * \param newnick the new nickname to use
-     */
-    IRCCD_EXPORT virtual void nick(std::string newnick);
-
-    /**
      * Send a private notice.
      *
      * \param target the target