Tooltips: Unify the tooltip[] and list[] description tooltip display functions (...
[oweals/minetest.git] / src / client.cpp
index a36f5413f58f62c23f429cec61be2dba4f8c0383..a5228132d629c5eae1927fc5f01cda0e36c0e66b 100644 (file)
@@ -104,6 +104,8 @@ Client::Client(
        m_animation_time(0),
        m_crack_level(-1),
        m_crack_pos(0,0,0),
+       m_last_chat_message_sent(time(NULL)),
+       m_chat_message_allowance(5.0f),
        m_map_seed(0),
        m_password(password),
        m_chosen_auth_mech(AUTH_MECHANISM_NONE),
@@ -400,6 +402,14 @@ void Client::step(float dtime)
                }
        }
 
+       /*
+               Send pending messages on out chat queue
+       */
+       if (!m_out_chat_queue.empty() && canSendChatMessage()) {
+               sendChatMessage(m_out_chat_queue.front());
+               m_out_chat_queue.pop();
+       }
+
        /*
                Handle environment
        */
@@ -1158,13 +1168,50 @@ void Client::sendInventoryAction(InventoryAction *a)
        Send(&pkt);
 }
 
+bool Client::canSendChatMessage() const
+{
+       u32 now = time(NULL);
+       float time_passed = now - m_last_chat_message_sent;
+
+       float virt_chat_message_allowance = m_chat_message_allowance + time_passed *
+                       (CLIENT_CHAT_MESSAGE_LIMIT_PER_10S / 8.0f);
+
+       if (virt_chat_message_allowance < 1.0f)
+               return false;
+
+       return true;
+}
+
 void Client::sendChatMessage(const std::wstring &message)
 {
-       NetworkPacket pkt(TOSERVER_CHAT_MESSAGE, 2 + message.size() * sizeof(u16));
+       const s16 max_queue_size = g_settings->getS16("max_out_chat_queue_size");
+       if (canSendChatMessage()) {
+               u32 now = time(NULL);
+               float time_passed = now - m_last_chat_message_sent;
+               m_last_chat_message_sent = time(NULL);
 
-       pkt << message;
+               m_chat_message_allowance += time_passed * (CLIENT_CHAT_MESSAGE_LIMIT_PER_10S / 8.0f);
+               if (m_chat_message_allowance > CLIENT_CHAT_MESSAGE_LIMIT_PER_10S)
+                       m_chat_message_allowance = CLIENT_CHAT_MESSAGE_LIMIT_PER_10S;
 
-       Send(&pkt);
+               m_chat_message_allowance -= 1.0f;
+
+               NetworkPacket pkt(TOSERVER_CHAT_MESSAGE, 2 + message.size() * sizeof(u16));
+
+               pkt << message;
+
+               Send(&pkt);
+       } else if (m_out_chat_queue.size() < (u16) max_queue_size || max_queue_size == -1) {
+               m_out_chat_queue.push(message);
+       } else {
+               infostream << "Could not queue chat message because maximum out chat queue size ("
+                               << max_queue_size << ") is reached." << std::endl;
+       }
+}
+
+void Client::clearOutChatQueue()
+{
+       m_out_chat_queue = std::queue<std::wstring>();
 }
 
 void Client::sendChangePassword(const std::string &oldpassword,
@@ -1924,4 +1971,3 @@ std::string Client::getModStoragePath() const
 {
        return porting::path_user + DIR_DELIM + "client" + DIR_DELIM + "mod_storage";
 }
-