Ticket #4069: 4069_chat_history_v3.patch
File 4069_chat_history_v3.patch, 27.7 KB (added by , 8 years ago) |
---|
-
binaries/data/config/default.cfg
pan.y = 1 348 348 rotate.x = 3 349 349 rotate.y = 2 350 350 zoom.in = 5 351 351 zoom.out = 4 352 352 353 [chat] 354 timestamp = false ; Show time chat message was posted 355 356 [chat.session] 357 extended = true ; Whether to display the chat history 358 353 359 [lobby] 354 chattimestamp = false ; Show time chat message was posted355 360 history = 0 ; Number of past messages to display on join 356 361 room = "arena21" ; Default MUC room to join 357 362 server = "lobby.wildfiregames.com" ; Address of lobby server 358 363 xpartamupp = "wfgbot21" ; Name of the server-side xmpp client that manage games 359 364 -
binaries/data/mods/public/gui/common/styles.xml
188 188 scroll_bottom="false" 189 189 textcolor="white" 190 190 text_align="left" 191 191 text_valign="top" 192 192 /> 193 194 <style name="ChatPanel" 195 buffer_zone="5" 196 font="sans-13" 197 scrollbar="true" 198 scrollbar_style="ModernScrollBar" 199 scroll_bottom="true" 200 textcolor="white" 201 textcolor_selected="gold" 202 text_align="left" 203 text_valign="center" 204 /> 205 193 206 </styles> -
binaries/data/mods/public/gui/gamesetup/gamesetup.js
function addChatMessage(msg) 1792 1792 if (!g_FormatChatMessage[msg.type]) 1793 1793 return; 1794 1794 1795 1795 let user = colorizePlayernameByGUID(msg.guid || -1, msg.username || ""); 1796 1796 1797 g_ChatMessages.push(g_FormatChatMessage[msg.type](msg, user)); 1797 let text = g_FormatChatMessage[msg.type](msg, user); 1798 1799 if (Engine.ConfigDB_GetValue("user", "chat.timestamp") == "true") 1800 text = sprintf(translate("%(time)s %(message)s"), { 1801 "time": sprintf(translate("\\[%(time)s]"), { 1802 "time": Engine.FormatMillisecondsIntoDateString(new Date().getTime(), translate("HH:mm")) 1803 }), 1804 "message": text 1805 }); 1806 1807 g_ChatMessages.push(text); 1798 1808 1799 1809 Engine.GetGUIObjectByName("chatText").caption = g_ChatMessages.join("\n"); 1800 1810 } 1801 1811 1802 1812 function showMoreOptions(show) -
binaries/data/mods/public/gui/gamesetup/styles.xml
1 <?xml version="1.0" encoding="utf-8"?>2 3 <styles>4 5 <style name="ChatPanel"6 buffer_zone="5"7 font="sans-13"8 scrollbar="true"9 scrollbar_style="ModernScrollBar"10 scroll_bottom="true"11 textcolor="white"12 textcolor_selected="gold"13 text_align="left"14 text_valign="center"15 />16 17 </styles> -
binaries/data/mods/public/gui/lobby/lobby.js
const g_MapSizes = prepareForDropdown(g_ 7 7 * Used for the gamelist-filtering. 8 8 */ 9 9 const g_MapTypes = prepareForDropdown(g_Settings && g_Settings.MapTypes); 10 10 11 11 /** 12 * Whether or not to display timestamps in the chat window.13 */14 const g_ShowTimestamp = Engine.ConfigDB_GetValue("user", "lobby.chattimestamp") == "true";15 16 /**17 12 * Mute clients who exceed the rate of 1 message per second for this time 18 13 */ 19 14 const g_SpamBlockTimeframe = 5; 20 15 21 16 /** … … function ircFormat(msg) 969 964 "message": msg.text 970 965 }); 971 966 } 972 967 973 968 // Add chat message timestamp 974 if ( !g_ShowTimestamp)969 if (Engine.ConfigDB_GetValue("user", "chat.timestamp") != "true") 975 970 return formattedMessage; 976 971 977 972 let time; 978 973 if (msg.datetime) 979 974 { -
binaries/data/mods/public/gui/lobby/styles.xml
1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 3 3 <styles> 4 <style name="ChatPanel"5 buffer_zone="5"6 font="sans-13"7 scrollbar="true"8 scrollbar_style="ModernScrollBar"9 scroll_bottom="true"10 textcolor="white"11 textcolor_selected="gold"12 text_align="left"13 text_valign="center"14 />15 16 4 <style name="MapPlayerList" 17 5 buffer_zone="8" 18 6 font="sans-14" 19 7 scrollbar="true" 20 8 scrollbar_style="ModernScrollBar" -
binaries/data/mods/public/gui/options/options.json
88 88 { 89 89 "type": "number", 90 90 "label": "Batch Training Size", 91 91 "tooltip": "Number of units trained per batch", 92 92 "parameters": { "config": "gui.session.batchtrainingsize", "min": 1, "max": 20 } 93 }, 94 { 95 "type": "boolean", 96 "label": "Chat Timestamp", 97 "tooltip": "Show time that messages are posted in the lobby, gamesetup and ingame chat.", 98 "parameters": { "config": "chat.timestamp" } 93 99 } 94 100 ], 95 101 "graphicsSetting": 96 102 [ 97 103 { … … 243 249 { 244 250 "type": "number", 245 251 "label": "Chat Backlog", 246 252 "tooltip": "Number of backlogged messages to load when joining the lobby", 247 253 "parameters": { "config": "lobby.history", "min": "0" } 248 },249 {250 "type": "boolean",251 "label": "Chat Timestamp",252 "tooltip": "Show time that messages are posted in the lobby chat",253 "parameters": { "config": "lobby.chattimestamp" }254 254 } 255 255 ] 256 256 } -
binaries/data/mods/public/gui/page_gamesetup.xml
8 8 <include>common/sprites.xml</include> 9 9 <include>common/styles.xml</include> 10 10 11 11 <include>gamesetup/setup.xml</include> 12 12 <include>gamesetup/sprites.xml</include> 13 <include>gamesetup/styles.xml</include>14 13 <include>gamesetup/gamesetup.xml</include> 15 14 <include>common/global.xml</include> 16 15 </page> -
binaries/data/mods/public/gui/session/chat_window.xml
1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 3 <object name="chatDialogPanel" size="50%-180 50%-66 50%+180 50%+54" type="image" hidden="true" sprite="genericPanel"> 4 5 <!-- Message addressee --> 6 <object size="16 14 50 38" type="text" style="chatPanel"> 7 <translatableAttribute id="caption" context="chat input">To:</translatableAttribute> 8 </object> 9 <object size="75 12 100%-16 36" name="chatAddressee" type="dropdown" style="ModernDropDown" tooltip_style="sessionToolTipBold"> 10 <translatableAttribute id="tooltip" context="chat input">Select chatmessage addressee</translatableAttribute> 11 </object> 12 13 <!-- Message text --> 14 <object size="16 46 50 70" type="text" style="chatPanel"> 15 <translatableAttribute id="caption" context="chat input">Text:</translatableAttribute> 16 </object> 17 <object name="chatInput" size="75 44 100%-16 68" type="input" style="ModernInput" max_length="80"> 18 <translatableAttribute id="tooltip" context="chat input">Type the message to send.</translatableAttribute> 19 <action on="Press">submitChatInput();</action> 20 <action on="Tab"> 21 let playernames = []; 22 for (let player in g_PlayerAssignments) 23 playernames.push(g_PlayerAssignments[player].name); 24 autoCompleteNick(this, playernames); 25 </action> 3 <object 4 name="chatDialogPanel" 5 size="50%-210 50%-410 50%+210 50%+60" 6 type="image" 7 hidden="true" 8 sprite="genericPanel" 9 > 10 <!-- Chat History Page --> 11 <object type="image" name="chatHistoryPage" size="0 0 100% 350" hidden="false"> 12 13 <!-- Chat History Filter --> 14 <object type="text" size="16 12 60 32" style="ModernLeftLabelText"> 15 <translatableAttribute id="caption" context="chat input">Filter:</translatableAttribute> 16 </object> 17 18 <object 19 type="dropdown" 20 name="chatHistoryFilter" 21 size="75 10 100%-16 34" 22 style="ModernDropDown" 23 tooltip_style="sessionToolTipBold" 24 > 25 <translatableAttribute id="tooltip" context="chat input">Filter the chat history.</translatableAttribute> 26 <action on="SelectionChange">updateChatHistory();</action> 27 </object> 28 29 <object 30 type="text" 31 name="chatHistory" 32 size="10 46 100%-10 100%" 33 sprite="ModernDarkBoxGold" 34 style="ChatPanel" 35 /> 36 </object> 37 38 <!-- Chat input elements --> 39 <object name="chatPage" size="0 100%-120 100% 100%"> 40 41 <!-- Message addressee --> 42 <object size="16 100%-106 50 100%-82" type="text" style="ModernLeftLabelText"> 43 <translatableAttribute id="caption" context="chat input">To:</translatableAttribute> 44 </object> 45 <object 46 name="chatAddressee" 47 type="dropdown" 48 size="75 100%-108 100%-16 100%-84" 49 style="ModernDropDown" 50 tooltip_style="sessionToolTipBold" 51 > 52 <translatableAttribute id="tooltip" context="chat input">Select chatmessage addressee.</translatableAttribute> 53 </object> 54 55 <!-- Message text --> 56 <object type="text" size="16 100%-74 50 100%-50" style="ModernLeftLabelText"> 57 <translatableAttribute id="caption" context="chat input">Text:</translatableAttribute> 58 </object> 59 <object 60 type="input" 61 name="chatInput" 62 size="75 100%-76 100%-16 100%-52" 63 style="ModernInput" 64 max_length="80" 65 > 66 <translatableAttribute id="tooltip" context="chat input">Type the message to send.</translatableAttribute> 67 <action on="Press">submitChatInput();</action> 68 <action on="Tab"> 69 let playernames = []; 70 for (let player in g_PlayerAssignments) 71 playernames.push(g_PlayerAssignments[player].name); 72 autoCompleteNick(this, playernames); 73 </action> 74 </object> 75 76 <!-- Cancel Button --> 77 <object size="16 100%-40 30%+16 100%-12" type="button" style="StoneButton"> 78 <translatableAttribute id="caption">Cancel</translatableAttribute> 79 <action on="Press">closeChat();</action> 80 </object> 81 82 <!-- Extended Chat Checkbox --> 83 <object 84 type="checkbox" 85 name="extendedChat" 86 checked="false" 87 style="ModernTickBox" 88 size="50%-50 100%-38 50%-24 100%-12" 89 > 90 <action on="Press">onChatWindowExtendedToggle();</action> 91 </object> 92 93 <!-- Extended Chat Label --> 94 <object type="text" size="50%-24 100%-38 50%+40 100%-12" text_align="left" textcolor="white"> 95 <translatableAttribute id="caption" context="chat">History</translatableAttribute> 96 </object> 97 98 <!-- Send Button --> 99 <object size="60%+16 100%-40 100%-16 100%-12" type="button" style="StoneButton"> 100 <translatableAttribute id="caption">Send</translatableAttribute> 101 <action on="Press">submitChatInput();</action> 102 </object> 26 103 </object> 27 28 <!-- Cancel Button -->29 <object size="16 100%-40 30%+16 100%-12" type="button" style="StoneButton">30 <translatableAttribute id="caption">Cancel</translatableAttribute>31 <action on="Press">closeChat();</action>32 </object>33 34 <!-- Send Button -->35 <object size="60%+16 100%-40 100%-16 100%-12" type="button" style="StoneButton">36 <translatableAttribute id="caption">Send</translatableAttribute>37 <action on="Press">submitChatInput();</action>38 </object>39 40 104 </object> -
binaries/data/mods/public/gui/session/diplomacy_window.xml
9 9 <object type="text" style="TitleText" size="50%-96 -16 50%+96 16"> 10 10 <translatableAttribute id="caption">Diplomacy</translatableAttribute> 11 11 </object> 12 12 13 13 <object name="diplomacyHeader" size="32 32 100%-32 64"> 14 <object name="diplomacyHeaderName" size="0 0 150 100%" type="text" style=" chatPanel" ghost="true">14 <object name="diplomacyHeaderName" size="0 0 150 100%" type="text" style="ModernLeftLabelText" ghost="true"> 15 15 <translatableAttribute id="caption">Name</translatableAttribute> 16 16 </object> 17 <object name="diplomacyHeaderCiv" size="150 0 250 100%" type="text" style=" chatPanel" ghost="true">17 <object name="diplomacyHeaderCiv" size="150 0 250 100%" type="text" style="ModernLeftLabelText" ghost="true"> 18 18 <translatableAttribute id="caption">Civilization</translatableAttribute> 19 19 </object> 20 <object name="diplomacyHeaderTeam" size="250 0 300 100%" type="text" style=" chatPanel" ghost="true">20 <object name="diplomacyHeaderTeam" size="250 0 300 100%" type="text" style="ModernLeftLabelText" ghost="true"> 21 21 <translatableAttribute id="caption">Team</translatableAttribute> 22 22 </object> 23 <object name="diplomacyHeaderTheirs" size="300 0 360 100%" type="text" style=" chatPanel" ghost="true">23 <object name="diplomacyHeaderTheirs" size="300 0 360 100%" type="text" style="ModernLeftLabelText" ghost="true"> 24 24 <translatableAttribute id="caption">Theirs</translatableAttribute> 25 25 </object> 26 <object name="diplomacyHeaderAlly" size="100%-180 0 100%-160 100%" type="text" style=" chatPanel" tooltip_style="sessionToolTipBold">26 <object name="diplomacyHeaderAlly" size="100%-180 0 100%-160 100%" type="text" style="ModernLeftLabelText" tooltip_style="sessionToolTipBold"> 27 27 <translatableAttribute id="caption">A</translatableAttribute> 28 28 <translatableAttribute id="tooltip">Ally</translatableAttribute> 29 29 </object> 30 <object name="diplomacyHeaderNeutral" size="100%-160 0 100%-140 100%" type="text" style=" chatPanel" tooltip_style="sessionToolTipBold">30 <object name="diplomacyHeaderNeutral" size="100%-160 0 100%-140 100%" type="text" style="ModernLeftLabelText" tooltip_style="sessionToolTipBold"> 31 31 <translatableAttribute id="caption">N</translatableAttribute> 32 32 <translatableAttribute id="tooltip">Neutral</translatableAttribute> 33 33 </object> 34 <object name="diplomacyHeaderEnemy" size="100%-140 0 100%-120 100%" type="text" style=" chatPanel" tooltip_style="sessionToolTipBold">34 <object name="diplomacyHeaderEnemy" size="100%-140 0 100%-120 100%" type="text" style="ModernLeftLabelText" tooltip_style="sessionToolTipBold"> 35 35 <translatableAttribute id="caption">E</translatableAttribute> 36 36 <translatableAttribute id="tooltip">Enemy</translatableAttribute> 37 37 </object> 38 <object name="diplomacyHeaderTribute" size="100%-110 0 100% 100%" type="text" style=" chatPanel">38 <object name="diplomacyHeaderTribute" size="100%-110 0 100% 100%" type="text" style="ModernLeftLabelText"> 39 39 <translatableAttribute id="caption">Tribute</translatableAttribute> 40 40 </object> 41 41 </object> 42 42 43 <object size="32 64 100%-32 384"> 43 44 <repeat count="16"> 44 45 <object name="diplomacyPlayer[n]" size="0 0 100% 20" type="image" hidden="false"> 45 <object name="diplomacyPlayerName[n]" size="0 0 150 100%" type="text" style=" chatPanel" ghost="true"/>46 <object name="diplomacyPlayerCiv[n]" size="150 0 250 100%" type="text" style=" chatPanel" ghost="true"/>47 <object name="diplomacyPlayerTeam[n]" size="250 0 300 100%" type="text" style=" chatPanel" ghost="true"/>48 <object name="diplomacyPlayerTheirs[n]" size="300 0 360 100%" type="text" style=" chatPanel" ghost="true"/>46 <object name="diplomacyPlayerName[n]" size="0 0 150 100%" type="text" style="ModernLeftLabelText" ghost="true"/> 47 <object name="diplomacyPlayerCiv[n]" size="150 0 250 100%" type="text" style="ModernLeftLabelText" ghost="true"/> 48 <object name="diplomacyPlayerTeam[n]" size="250 0 300 100%" type="text" style="ModernLeftLabelText" ghost="true"/> 49 <object name="diplomacyPlayerTheirs[n]" size="300 0 360 100%" type="text" style="ModernLeftLabelText" ghost="true"/> 49 50 50 51 <!-- Diplomatic stance - selection --> 51 52 <object name="diplomacyPlayerAlly[n]" size="100%-180 0 100%-160 100%" type="button" style="StoneButton" hidden="true"/> 52 53 <object name="diplomacyPlayerNeutral[n]" size="100%-160 0 100%-140 100%" type="button" style="StoneButton" hidden="true"/> 53 54 <object name="diplomacyPlayerEnemy[n]" size="100%-140 0 100%-120 100%" type="button" style="StoneButton" hidden="true"/> … … 71 72 </object> 72 73 </object> 73 74 </repeat> 74 75 </object> 75 76 76 <object name="diplomacyCeasefireCounter" size="32 100%-90 100%-32 100%-62" type="text" style=" chatPanel" ghost="true"></object>77 <object name="diplomacyCeasefireCounter" size="32 100%-90 100%-32 100%-62" type="text" style="ModernLeftLabelText" ghost="true"></object> 77 78 78 79 <object size="50%-64 100%-50 50%+64 100%-22" type="button" style="StoneButton"> 79 80 <translatableAttribute id="caption">Close</translatableAttribute> 80 81 <action on="Press">closeDiplomacy();</action> 81 82 </object> -
binaries/data/mods/public/gui/session/menu.js
function openChat(teamChat = false) 217 217 let command = teamChat ? (g_IsObserver ? "/observers" : "/allies") : ""; 218 218 chatAddressee.selected = chatAddressee.list_data.indexOf(command); 219 219 220 220 Engine.GetGUIObjectByName("chatInput").focus(); 221 221 Engine.GetGUIObjectByName("chatDialogPanel").hidden = false; 222 223 updateChatHistory(); 222 224 } 223 225 224 226 function closeChat() 225 227 { 226 228 Engine.GetGUIObjectByName("chatInput").caption = ""; 227 229 Engine.GetGUIObjectByName("chatInput").blur(); // Remove focus 228 230 Engine.GetGUIObjectByName("chatDialogPanel").hidden = true; 229 231 } 230 232 233 function initChatWindow() 234 { 235 let filters = prepareForDropdown(g_ChatHistoryFilters); 236 let chatHistoryFilter = Engine.GetGUIObjectByName("chatHistoryFilter"); 237 chatHistoryFilter.list = filters.text; 238 chatHistoryFilter.list_data = filters.key; 239 chatHistoryFilter.selected = 0; 240 241 // Restore user preference 242 if (Engine.ConfigDB_GetValue("user", "chat.session.extended") == "true") 243 Engine.GetGUIObjectByName("extendedChat").checked = true; 244 245 resizeChatWindow(); 246 } 247 248 function resizeChatWindow() 249 { 250 // Hide the panel 251 let chatHistoryPage = Engine.GetGUIObjectByName("chatHistoryPage"); 252 let extended = Engine.GetGUIObjectByName("extendedChat").checked; 253 chatHistoryPage.hidden = !extended; 254 255 // Resize the window 256 let chatDialogPanel = Engine.GetGUIObjectByName("chatDialogPanel"); 257 let chatPage = Engine.GetGUIObjectByName("chatPage"); 258 let panelSize = chatDialogPanel.size; 259 let topOffset = 60; 260 let height = -chatPage.size.top + (extended ? chatHistoryPage.size.bottom : 0); 261 panelSize.top = -height / 2 - topOffset; 262 panelSize.bottom = height / 2 - topOffset; 263 chatDialogPanel.size = panelSize; 264 } 265 266 function updateChatHistory() 267 { 268 if (Engine.GetGUIObjectByName("chatDialogPanel").hidden || 269 !Engine.GetGUIObjectByName("extendedChat").checked) 270 return; 271 272 let chatHistoryFilter = Engine.GetGUIObjectByName("chatHistoryFilter"); 273 let selected = chatHistoryFilter.list_data[chatHistoryFilter.selected]; 274 275 Engine.GetGUIObjectByName("chatHistory").caption = 276 g_ChatHistory.filter(msg => msg.filter[selected]).map(msg => 277 Engine.ConfigDB_GetValue("user", "chat.timestamp") == "true" ? 278 sprintf(translate("%(time)s %(message)s"), { 279 "time": msg.timePrefix, 280 "message": msg.txt 281 }) : 282 msg.txt 283 ).join("\n"); 284 } 285 286 function onChatWindowExtendedToggle() 287 { 288 // Save user preference 289 let extended = Engine.GetGUIObjectByName("extendedChat").checked.toString(); 290 Engine.ConfigDB_CreateValue("user", "chat.session.extended", extended); 291 Engine.ConfigDB_WriteValueToFile("user", "chat.session.extended", extended, "config/user.cfg"); 292 293 resizeChatWindow(); 294 295 Engine.GetGUIObjectByName("chatInput").focus(); 296 } 297 231 298 function openDiplomacy() 232 299 { 233 300 closeOpenDialogs(); 234 301 235 302 if (g_ViewedPlayer < 1) -
binaries/data/mods/public/gui/session/messages.js
const g_ChatTimeout = 30; 13 13 * Maximum number of lines to display simultaneously. 14 14 */ 15 15 const g_ChatLines = 20; 16 16 17 17 /** 18 * The strings to be displayed including sender and formating.18 * The currently displayed strings, limited by the given timeframe and limit above. 19 19 */ 20 20 var g_ChatMessages = []; 21 21 22 22 /** 23 * All unparsed chat messages received since connect, including timestamp. 24 */ 25 var g_ChatHistory = []; 26 27 /** 23 28 * Holds the timer-IDs used for hiding the chat after g_ChatTimeout seconds. 24 29 */ 25 30 var g_ChatTimers = []; 26 31 27 32 /** … … var g_IsChatAddressee = { 170 175 171 176 "/msg": (senderID, addresseeGUID) => 172 177 addresseeGUID == Engine.GetPlayerGUID() 173 178 }; 174 179 180 var g_ChatHistoryFilters = [ 181 { 182 "key": "all", 183 "text": translateWithContext("chat history filter", "Chat and notifications"), 184 "filter": (msg, senderID) => true 185 }, 186 { 187 "key": "chat", 188 "text": translateWithContext("chat history filter", "Chat messages"), 189 "filter": (msg, senderID) => msg.type == "message" 190 }, 191 { 192 "key": "player", 193 "text": translateWithContext("chat history filter", "Players chat"), 194 "filter": (msg, senderID) => 195 msg.type == "message" && senderID > 0 && !isPlayerObserver(senderID) 196 }, 197 { 198 "key": "ally", 199 "text": translateWithContext("chat history filter", "Ally chat"), 200 "filter": (msg, senderID) => 201 msg.type == "message" && 202 msg.cmd && msg.cmd == "/allies" && 203 g_Players[Engine.GetPlayerID()] && 204 g_Players[Engine.GetPlayerID()].isAlly[senderID] 205 }, 206 { 207 "key": "enemy", 208 "text": translateWithContext("chat history filter", "Enemy chat"), 209 "filter": (msg, senderID) => 210 msg.type == "message" && 211 msg.cmd && msg.cmd == "/enemies" && 212 g_Players[Engine.GetPlayerID()] && 213 g_Players[Engine.GetPlayerID()].isEnemy[senderID] 214 }, 215 { 216 "key": "observer", 217 "text": translateWithContext("chat history filter", "Observer chat"), 218 "filter": (msg, senderID) => 219 msg.type == "message" && 220 msg.cmd && msg.cmd == "/observers" 221 }, 222 { 223 "key": "private", 224 "text": translateWithContext("chat history filter", "Private chat"), 225 "filter": (msg, senderID) => !!msg.isVisiblePM 226 } 227 ]; 228 175 229 var g_PlayerStateMessages = { 176 230 "won": translate("You have won!"), 177 231 "defeated": translate("You have been defeated!") 178 232 }; 179 233 … … function addChatMessage(msg) 701 755 702 756 let formatted = g_FormatChatMessage[msg.type](msg); 703 757 if (!formatted) 704 758 return; 705 759 760 // Update chat overlay 706 761 g_ChatMessages.push(formatted); 707 762 g_ChatTimers.push(setTimeout(removeOldChatMessage, g_ChatTimeout * 1000)); 708 763 709 764 if (g_ChatMessages.length > g_ChatLines) 710 765 removeOldChatMessage(); 711 766 else 712 767 Engine.GetGUIObjectByName("chatText").caption = g_ChatMessages.join("\n"); 768 769 // Save to chat history 770 let historical = { 771 "txt": formatted, 772 "timePrefix": sprintf(translate("\\[%(time)s]"), { 773 "time": Engine.FormatMillisecondsIntoDateString(new Date().getTime(), translate("HH:mm")) 774 }), 775 "filter": {} 776 }; 777 778 // Apply the filters now before diplomacies or playerstates change 779 let senderID = msg.guid && g_PlayerAssignments[msg.guid] ? g_PlayerAssignments[msg.guid].player : 0; 780 for (let filter of g_ChatHistoryFilters) 781 historical.filter[filter.key] = filter.filter(msg, senderID); 782 783 g_ChatHistory.push(historical); 784 updateChatHistory(); 713 785 } 714 786 715 787 /** 716 788 * Called when the timer has run out for the oldest chatmessage or when the message limit is reached. 717 789 */ … … function formatChatCommand(msg) 859 931 }); 860 932 } 861 933 862 934 /** 863 935 * Checks if the current user is an addressee of the chatmessage sent by another player. 864 * Sets the context of that message.936 * Sets the context and potentially addresseeGUID of that message. 865 937 * Returns true if the message should be displayed. 866 938 * 867 939 * @param {Object} msg 868 940 */ 869 941 function parseChatAddressee(msg) 870 942 { 871 943 if (msg.text[0] != '/') 872 944 return true; 873 945 874 946 // Split addressee command and message-text 875 let cmd = msg.text.split(/\s/)[0]; 876 msg.text = msg.text.substr(cmd.length + 1); 877 878 if (cmd == "/ally") 879 cmd = "/allies"; 880 881 if (cmd == "/enemy") 882 cmd = "/enemies"; 883 884 if (cmd == "/observer") 885 cmd = "/observers"; 947 msg.cmd = msg.text.split(/\s/)[0]; 948 msg.text = msg.text.substr(msg.cmd.length + 1); 886 949 887 950 // GUID for players and observers, ID for bots 888 951 let senderID = (g_PlayerAssignments[msg.guid] || msg).player; 889 952 let isSender = msg.guid ? msg.guid == Engine.GetPlayerGUID() : senderID == Engine.GetPlayerID(); 890 953 891 954 // Parse private message 892 let isPM = cmd == "/msg";955 let isPM = msg.cmd == "/msg"; 893 956 let addresseeGUID; 894 957 let addresseeIndex; 895 958 if (isPM) 896 959 { 897 960 addresseeGUID = matchUsername(msg.text); … … function parseChatAddressee(msg) 910 973 msg.text = msg.text.substr(addressee.name.length + 1); 911 974 addresseeIndex = addressee.player; 912 975 } 913 976 914 977 // Set context string 915 if (!g_ChatAddresseeContext[ cmd])978 if (!g_ChatAddresseeContext[msg.cmd]) 916 979 { 917 980 if (isSender) 918 warn("Unknown chat command: " + cmd);981 warn("Unknown chat command: " + msg.cmd); 919 982 return false; 920 983 } 921 msg.context = g_ChatAddresseeContext[ cmd];984 msg.context = g_ChatAddresseeContext[msg.cmd]; 922 985 923 986 // For observers only permit public- and observer-chat and PM to observers 924 987 if (isPlayerObserver(senderID) && 925 (isPM && !isPlayerObserver(addresseeIndex) || !isPM && cmd != "/observers"))988 (isPM && !isPlayerObserver(addresseeIndex) || !isPM && msg.cmd != "/observers")) 926 989 return false; 927 990 928 return isSender || g_IsChatAddressee[cmd](senderID, addresseeGUID); 991 let visible = isSender || g_IsChatAddressee[msg.cmd](senderID, addresseeGUID); 992 msg.isVisiblePM = isPM && visible; 993 994 return visible; 929 995 } 930 996 931 997 /** 932 998 * Returns the guid of the user with the longest name that is a prefix of the given string. 933 999 */ -
binaries/data/mods/public/gui/session/session.js
function init(initData, hotloadData) 292 292 // If in Atlas editor, disable the exit button 293 293 if (Engine.IsAtlasRunning()) 294 294 Engine.GetGUIObjectByName("menuExitButton").enabled = false; 295 295 296 296 initHotkeyTooltips(); 297 initChatWindow(); 297 298 298 299 if (hotloadData) 299 300 g_Selection.selected = hotloadData.selection; 300 301 301 302 sendLobbyPlayerlistUpdate(); -
binaries/data/mods/public/gui/session/session.xml
69 69 <object name="notificationText" size="0 0 100% 100%" type="text" style="notificationPanel" ghost="true"/> 70 70 </object> 71 71 72 72 <!-- Chat messages --> 73 73 <object name="chatPanel" size="0 130 100% 100%-240" type="image" ghost="true" z="0" absolute="true"> 74 <object name="chatText" size="3 1 100%-1 100%-1" type="text" style="chatPanel " ghost="true"/>74 <object name="chatText" size="3 1 100%-1 100%-1" type="text" style="chatPanelOverlay" ghost="true"/> 75 75 </object> 76 76 77 77 <!-- Entity selection state text --> 78 78 <object name="debugEntityState" 79 79 type="text" -
binaries/data/mods/public/gui/session/styles.xml
229 229 /> 230 230 231 231 <!-- ================================ ================================ --> 232 232 <!-- Misc Styles --> 233 233 <!-- ================================ ================================ --> 234 <style name="chatPanel "234 <style name="chatPanelOverlay" 235 235 buffer_zone="5" 236 236 font="sans-bold-stroke-14" 237 237 textcolor="white" 238 238 textcolor_selected="white" 239 239 text_align="left"