Ticket #3832: t3832-fix-lobby-timestamps.diff
File t3832-fix-lobby-timestamps.diff, 8.8 KB (added by , 8 years ago) |
---|
-
source/lobby/XmppClient.cpp
592 592 scriptInterface.SetProperty(ret, "level", message.level); 593 593 if (!message.data.empty()) 594 594 scriptInterface.SetProperty(ret, "data", message.data); 595 if (!message.datetime.empty()) 596 scriptInterface.SetProperty(ret, "datetime", message.datetime); 595 scriptInterface.SetProperty(ret, "time", message.time); 597 596 598 597 m_GuiMessageQueue.pop_front(); 599 598 } … … 655 654 message.level = L"room-message"; 656 655 message.from = wstring_from_utf8(msg.from().resource().to_string()); 657 656 message.text = wstring_from_utf8(msg.body().to_string()); 658 if (msg.when()) 659 // See http://xmpp.org/extensions/xep-0082.html#sect-idp285136 for format 660 message.datetime = msg.when()->stamp().to_string(); 657 message.time = ComputeTimestamp(msg); 661 658 PushGuiMessage(message); 662 659 } 663 660 … … 674 671 message.level = L"private-message"; 675 672 message.from = wstring_from_utf8(msg.from().username().to_string()); 676 673 message.text = wstring_from_utf8(msg.body().to_string()); 677 if (msg.when()) 678 //See http://xmpp.org/extensions/xep-0082.html#sect-idp285136 for format 679 message.datetime = msg.when()->stamp().to_string(); 674 message.time = ComputeTimestamp(msg); 680 675 PushGuiMessage(message); 681 676 } 682 677 … … 769 764 message.level = wstring_from_utf8(level); 770 765 message.text = wstring_from_utf8(text); 771 766 message.data = wstring_from_utf8(data); 767 message.time = time(NULL); 772 768 PushGuiMessage(message); 773 769 } 774 770 … … 939 935 *****************************************************/ 940 936 941 937 /** 938 * Compute the POSIX timestamp of a message. Uses message datetime when possible, current time otherwise. 939 * 940 * @param msg The message on which to base the computation 941 * @returns POSIX GMT/UTC seconds since Jan. 1st 1970 942 */ 943 time_t XmppClient::ComputeTimestamp(const glooxwrapper::Message& msg) { 944 if (!msg.when()) 945 return time(NULL); 946 947 glooxwrapper::string timestampStr = msg.when()->stamp(); 948 struct tm timestamp = {0}; 949 // See http://xmpp.org/extensions/xep-0082.html#sect-idp285136 for format 950 void * res = strptime(timestampStr.c_str(), "%Y-%m-%dT%H:%M:%SZ", ×tamp); 951 if (res == NULL) 952 LOGERROR("Recived delayed message with corrupted timestamp %s", timestampStr.to_string()); 953 // mktime returns localtime, so we have to re-adjust back to GMT/UTC 954 return mktime(×tamp) - timezone; 955 } 956 957 /** 942 958 * Convert a gloox presence type to string. 943 959 * 944 960 * @param p Presence to be converted -
source/lobby/XmppClient.h
127 127 std::string StanzaErrorToString(gloox::StanzaError err) const; 128 128 std::string ConnectionErrorToString(gloox::ConnectionError err) const; 129 129 std::string RegistrationResultToString(gloox::RegistrationResult res) const; 130 time_t ComputeTimestamp(const glooxwrapper::Message& msg); 130 131 131 132 public: 132 133 /* Messages */ … … 138 139 std::wstring data; 139 140 std::wstring from; 140 141 std::wstring message; 141 std::string datetime;142 time_t time; 142 143 }; 143 144 void GuiPollMessage(ScriptInterface& scriptInterface, JS::MutableHandleValue ret); 144 145 void SendMUCMessage(const std::string& message); 145 146 void ClearPresenceUpdates(); 146 147 int GetMucMessageCount(); 147 148 protected: 148 149 void PushGuiMessage(XmppClient::GUIMessage message); 149 150 void CreateGUIMessage(const std::string& type, const std::string& level, const std::string& text = "", const std::string& data = ""); 150 151 -
binaries/data/mods/public/gui/lobby/lobby.js
111 111 updateLeaderboard(); 112 112 updatePlayerList(); 113 113 Engine.GetGUIObjectByName("hostButton").enabled = false; 114 addChatMessage({ "from": "system", "text": translate("Disconnected.") + msg.text, "color": g_SystemColor }); 114 addChatMessage({ 115 "from": "system", 116 "text": translate("Disconnected.") + msg.text, 117 "color": g_SystemColor, 118 "time": msg.time 119 }); 115 120 }, 116 121 "error": msg => { 117 addChatMessage({ "from": "system", "text": msg.text, "color": g_SystemColor 122 addChatMessage({ "from": "system", "text": msg.text, "color": g_SystemColor, "time": msg.time}); 118 123 } 119 124 }, 120 125 "chat": { … … 124 129 "join": msg => { 125 130 addChatMessage({ 126 131 "text": "/special " + sprintf(translate("%(nick)s has joined."), { "nick": msg.text }), 127 "isSpecial": true 132 "isSpecial": true, 133 "time": msg.time 128 134 }); 129 135 Engine.SendGetRatingList(); 130 136 }, … … 131 137 "leave": msg => { 132 138 addChatMessage({ 133 139 "text": "/special " + sprintf(translate("%(nick)s has left."), { "nick": msg.text }), 134 "isSpecial": true 140 "isSpecial": true, 141 "time": msg.time 135 142 }); 136 143 }, 137 144 "presence": msg => { … … 142 149 "oldnick": msg.text, 143 150 "newnick": msg.data 144 151 }), 145 "isSpecial": true 152 "isSpecial": true, 153 "time": msg.time 146 154 }); 147 155 }, 148 156 "room-message": msg => { … … 149 157 addChatMessage({ 150 158 "from": escapeText(msg.from), 151 159 "text": escapeText(msg.text), 152 " datetime": msg.datetime160 "time": msg.time 153 161 }); 154 162 }, 155 163 "private-message": msg => { … … 157 165 addChatMessage({ 158 166 "from": "(Private) " + escapeText(msg.from), // TODO: placeholder 159 167 "text": escapeText(msg.text.trim()), // some XMPP clients send trailing whitespace 160 " datetime": msg.datetime168 "time": msg.time 161 169 }); 162 170 } 163 171 }, … … 656 664 "text": sprintf( 657 665 translate("This game's address '%(ip)s' does not appear to be valid."), 658 666 { "ip": game.ip } 659 ) 667 ), 668 "time": Date.now() / 1000 660 669 }); 661 670 return; 662 671 } … … 767 776 default: 768 777 addChatMessage({ 769 778 "from": "system", 770 "text": sprintf(translate("We're sorry, the '%(cmd)s' command is not supported."), { "cmd": cmd }) 779 "text": sprintf(translate("We're sorry, the '%(cmd)s' command is not supported."), { "cmd": cmd }), 780 "time": Date.now() / 1000 771 781 }); 772 782 } 773 783 return true; … … 789 799 if (g_Username != msg.from) 790 800 msg.text = msg.text.replace(g_Username, colorPlayerName(g_Username)); 791 801 792 // Run spam test if it's not a historical message 793 if (!msg.datetime) 794 { 795 updateSpamMonitor(msg.from); 796 if (isSpam(msg.text, msg.from)) 797 return; 798 } 802 updateSpamMonitor(msg); 803 if (isSpam(msg.text, msg.from)) 804 return; 799 805 } 800 806 801 807 var formatted = ircFormat(msg); … … 877 883 if (!g_ShowTimestamp) 878 884 return formattedMessage; 879 885 880 var time;881 if (msg.datetime)882 {883 let dTime = msg.datetime.split("T");884 let parserDate = dTime[0].split("-");885 let parserTime = dTime[1].split(":");886 // See http://xmpp.org/extensions/xep-0082.html#sect-idp285136 for format of datetime887 // Date takes Year, Month, Day, Hour, Minute, Second888 time = new Date(Date.UTC(parserDate[0], parserDate[1], parserDate[2], parserTime[0], parserTime[1], parserTime[2].split("Z")[0]));889 }890 else891 time = new Date(Date.now());892 893 886 // Translation: Time as shown in the multiplayer lobby (when you enable it in the options page). 894 887 // For a list of symbols that you can use, see: 895 888 // https://sites.google.com/site/icuprojectuserguide/formatparse/datetime?pli=1#TOC-Date-Field-Symbol-Table 896 var timeString = Engine.FormatMillisecondsIntoDateString( time.getTime(), translate("HH:mm"));889 var timeString = Engine.FormatMillisecondsIntoDateString(msg.time * 1000, translate("HH:mm")); 897 890 898 891 // Translation: Time prefix as shown in the multiplayer lobby (when you enable it in the options page). 899 892 var timePrefixString = '[font="' + g_SenderFont + '"]' + sprintf(translate("\\[%(time)s]"), { "time": timeString }) + '[/font]'; … … 905 898 /** 906 899 * Update the spam monitor. 907 900 * 908 * @param { string} from - User to update.901 * @param {Object} msg - Message containing user to update. 909 902 */ 910 function updateSpamMonitor( from)903 function updateSpamMonitor(msg) 911 904 { 912 if (g_SpamMonitor[from]) 913 ++g_SpamMonitor[from][0]; 905 // Ignore historical messages (older than 5s) 906 // TODO: Properly check for spam in historical messages as well 907 if (msg.time < Date.now() / 1000 - 5) 908 return; 909 910 if (g_SpamMonitor[msg.from]) 911 ++g_SpamMonitor[msg.from][0]; 914 912 else 915 g_SpamMonitor[ from] = [1, Math.floor(Date.now() / 1000), 0];913 g_SpamMonitor[msg.from] = [1, Math.floor(Date.now() / 1000), 0]; 916 914 } 917 915 918 916 /** … … 945 943 { 946 944 g_SpamMonitor[from][2] = time; 947 945 if (from == g_Username) 948 addChatMessage({ "from": "system", "text": translate("Please do not spam. You have been blocked for thirty seconds.") }); 946 addChatMessage({ 947 "from": "system", 948 "text": translate("Please do not spam. You have been blocked for thirty seconds."), 949 "time": Date.now() / 1000 950 }); 949 951 return true; 950 952 } 951 953