Ticket #2640: 2640_3.patch
File 2640_3.patch, 37.2 KB (added by , 9 years ago) |
---|
-
new file inaries/data/mods/public/gui/common/functions_chat.js
From 2d4f86f1d0ea48e6a47c862cd88731a274804d99 Mon Sep 17 00:00:00 2001 From: matt <matthewdoerksen@hotmail.com> Date: Sat, 20 Jun 2015 19:01:11 -0700 Subject: [PATCH] Move lobby chat functionality. --- .../data/mods/public/gui/common/functions_chat.js | 306 +++++++++++++++++++++ .../data/mods/public/gui/gamesetup/gamesetup.js | 79 +----- .../data/mods/public/gui/gamesetup/gamesetup.xml | 1 + binaries/data/mods/public/gui/lobby/lobby.js | 141 ++++------ binaries/data/mods/public/gui/lobby/lobby.xml | 1 + binaries/data/mods/public/gui/session/messages.js | 223 +-------------- binaries/data/mods/public/gui/session/session.xml | 1 + 7 files changed, 375 insertions(+), 377 deletions(-) create mode 100644 binaries/data/mods/public/gui/common/functions_chat.js diff --git a/binaries/data/mods/public/gui/common/functions_chat.js b/binaries/data/mods/public/gui/common/functions_chat.js new file mode 100644 index 0000000..ca29459
- + 1 function addChatMessageGameSetup(msg) 2 { 3 var username = ""; 4 if (msg.username) 5 username = escapeText(msg.username); 6 else if (msg.guid && g_PlayerAssignments[msg.guid]) 7 username = escapeText(g_PlayerAssignments[msg.guid].name); 8 9 var message = ""; 10 if ("text" in msg && msg.text) 11 message = escapeText(msg.text); 12 13 // TODO: Maybe host should have distinct font/color? 14 var color = "white"; 15 16 if (msg.guid && g_PlayerAssignments[msg.guid] && g_PlayerAssignments[msg.guid].player != -1) 17 { 18 // Valid player who has been assigned - get player color 19 var player = g_PlayerAssignments[msg.guid].player - 1; 20 var mapName = g_GameAttributes.map; 21 var mapData = loadMapData(mapName); 22 var mapSettings = (mapData && mapData.settings ? mapData.settings : {}); 23 var pData = mapSettings.PlayerData ? mapSettings.PlayerData[player] : {}; 24 var pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[player] : {}; 25 26 color = rgbToGuiColor(getSetting(pData, pDefs, "Color")); 27 } 28 29 var formatted; 30 switch (msg.type) 31 { 32 case "connect": 33 var formattedUsername = '[color="'+ color +'"]' + username + '[/color]'; 34 formatted = '[font="sans-bold-13"] ' + sprintf(translate("== %(message)s"), { message: sprintf(translate("%(username)s has joined"), { username: formattedUsername }) }) + '[/font]'; 35 break; 36 37 case "disconnect": 38 var formattedUsername = '[color="'+ color +'"]' + username + '[/color]'; 39 formatted = '[font="sans-bold-13"] ' + sprintf(translate("== %(message)s"), { message: sprintf(translate("%(username)s has left"), { username: formattedUsername }) }) + '[/font]'; 40 break; 41 42 case "message": 43 var formattedUsername = '[color="'+ color +'"]' + username + '[/color]'; 44 var formattedUsernamePrefix = '[font="sans-bold-13"]' + sprintf(translate("<%(username)s>"), { username: formattedUsername }) + '[/font]' 45 formatted = sprintf(translate("%(username)s %(message)s"), { username: formattedUsernamePrefix, message: message }); 46 break; 47 48 case "ready": 49 var formattedUsername = '[font="sans-bold-13"][color="'+ color +'"]' + username + '[/color][/font]' 50 if (msg.ready) 51 formatted = ' ' + sprintf(translate("* %(username)s is ready!"), { username: formattedUsername }); 52 else 53 formatted = ' ' + sprintf(translate("* %(username)s is not ready."), { username: formattedUsername }); 54 break; 55 56 case "settings": 57 formatted = '[font="sans-bold-13"] ' + sprintf(translate("== %(message)s"), { message: translate('Game settings have been changed') }) + '[/font]'; 58 break; 59 60 default: 61 error(sprintf("Invalid chat message '%(message)s'", { message: uneval(msg) })); 62 return; 63 } 64 65 g_ChatMessages.push(formatted); 66 67 Engine.GetGUIObjectByName("chatText").caption = g_ChatMessages.join("\n"); 68 } 69 70 function addChatMessageSession(msg, playerAssignments) 71 { 72 // Default to global assignments, but allow overriding for when reporting 73 // new players joining 74 if (!playerAssignments) 75 playerAssignments = g_PlayerAssignments; 76 77 var playerColor, username; 78 79 // No context by default. May be set by parseChatCommands(). 80 msg.context = ""; 81 82 if ("guid" in msg && playerAssignments[msg.guid]) 83 { 84 var n = playerAssignments[msg.guid].player; 85 // Observers have an ID of -1 which is not a valid index. 86 if (n < 0) 87 n = 0; 88 playerColor = g_Players[n].color.r + " " + g_Players[n].color.g + " " + g_Players[n].color.b; 89 username = escapeText(playerAssignments[msg.guid].name); 90 91 // Parse in-line commands in regular messages. 92 if (msg.type == "message") 93 parseChatCommands(msg, playerAssignments); 94 } 95 else if (msg.type == "defeat" && msg.player) 96 { 97 [username, playerColor] = getUsernameAndColor(msg.player); 98 } 99 else if (msg.type == "message") 100 { 101 [username, playerColor] = getUsernameAndColor(msg.player); 102 parseChatCommands(msg, playerAssignments); 103 } 104 else 105 { 106 playerColor = "255 255 255"; 107 username = translate("Unknown player"); 108 } 109 110 var formatted; 111 112 switch (msg.type) 113 { 114 case "connect": 115 formatted = sprintf(translate("%(player)s is starting to rejoin the game."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" }); 116 break; 117 case "disconnect": 118 formatted = sprintf(translate("%(player)s has left the game."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" }); 119 break; 120 case "rejoined": 121 formatted = sprintf(translate("%(player)s has rejoined the game."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" }); 122 break; 123 case "defeat": 124 // In singleplayer, the local player is "You". "You has" is incorrect. 125 if (!g_IsNetworked && msg.player == Engine.GetPlayerID()) 126 formatted = translate("You have been defeated."); 127 else 128 formatted = sprintf(translate("%(player)s has been defeated."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" }); 129 break; 130 case "diplomacy": 131 var message; 132 if (msg.player == Engine.GetPlayerID()) 133 { 134 [username, playerColor] = getUsernameAndColor(msg.player1); 135 if (msg.status == "ally") 136 message = translate("You are now allied with %(player)s."); 137 else if (msg.status == "enemy") 138 message = translate("You are now at war with %(player)s."); 139 else // (msg.status == "neutral") 140 message = translate("You are now neutral with %(player)s."); 141 } 142 else if (msg.player1 == Engine.GetPlayerID()) 143 { 144 [username, playerColor] = getUsernameAndColor(msg.player); 145 if (msg.status == "ally") 146 message = translate("%(player)s is now allied with you."); 147 else if (msg.status == "enemy") 148 message = translate("%(player)s is now at war with you."); 149 else // (msg.status == "neutral") 150 message = translate("%(player)s is now neutral with you."); 151 } 152 else // No need for other players to know of this. 153 return; 154 155 formatted = sprintf(message, { "player": '[color="'+ playerColor + '"]' + username + '[/color]' }); 156 break; 157 case "tribute": 158 if (msg.player != Engine.GetPlayerID()) 159 return; 160 161 [username, playerColor] = getUsernameAndColor(msg.player1); 162 163 // Format the amounts to proper English: 200 food, 100 wood, and 300 metal; 100 food; 400 wood and 200 stone 164 let amounts = Object.keys(msg.amounts) 165 .filter(function (type) { return msg.amounts[type] > 0; }) 166 .map(function (type) { return sprintf(translate("%(amount)s %(resourceType)s"), { 167 "amount": msg.amounts[type], 168 "resourceType": getLocalizedResourceName(type, "withinSentence")}); 169 }); 170 171 if (amounts.length > 1) 172 { 173 let lastAmount = amounts.pop(); 174 amounts = sprintf(translate("%(previousAmounts)s and %(lastAmount)s"), { 175 previousAmounts: amounts.join(translate(", ")), 176 lastAmount: lastAmount 177 }); 178 } 179 180 formatted = sprintf(translate("%(player)s has sent you %(amounts)s."), { 181 player: "[color=\"" + playerColor + "\"]" + username + "[/color]", 182 amounts: amounts 183 }); 184 break; 185 case "attack": 186 if (msg.player != Engine.GetPlayerID()) 187 return; 188 189 [username, playerColor] = getUsernameAndColor(msg.attacker); 190 // Since livestock can be attacked/gathered by other players, 191 // we display a more specific notification in this case to not confuse the player 192 if (msg.targetIsDomesticAnimal) 193 var message = translate("Your livestock have been attacked by %(attacker)s!"); 194 else 195 var message = translate("You have been attacked by %(attacker)s!"); 196 formatted = sprintf(message, { attacker: "[color=\"" + playerColor + "\"]" + username + "[/color]" }); 197 break; 198 case "message": 199 // May have been hidden by the 'team' command. 200 if (msg.hide) 201 return; 202 203 var message; 204 if ("translate" in msg && msg.translate) 205 { 206 message = translate(msg.text); // No need to escape, not a user message. 207 if ("translateParameters" in msg && msg.translateParameters) 208 { 209 var parameters = msg.parameters || {}; 210 translateObjectKeys(parameters, msg.translateParameters); 211 message = sprintf(message, parameters); 212 } 213 } 214 else 215 message = escapeText(msg.text); 216 217 if (msg.action) 218 { 219 if (msg.context !== "") 220 { 221 formatted = sprintf(translate("(%(context)s) * %(user)s %(message)s"), { 222 context: msg.context, 223 user: "[color=\"" + playerColor + "\"]" + username + "[/color]", 224 message: message 225 }); 226 } 227 else 228 { 229 formatted = sprintf(translate("* %(user)s %(message)s"), { 230 user: "[color=\"" + playerColor + "\"]" + username + "[/color]", 231 message: message 232 }); 233 } 234 } 235 else 236 { 237 var userTag = sprintf(translate("<%(user)s>"), { user: username }) 238 var formattedUserTag = sprintf(translate("<%(user)s>"), { user: "[color=\"" + playerColor + "\"]" + username + "[/color]" }) 239 if (msg.context !== "") 240 { 241 formatted = sprintf(translate("(%(context)s) %(userTag)s %(message)s"), { 242 context: msg.context, 243 userTag: formattedUserTag, 244 message: message 245 }); 246 } 247 else 248 { 249 formatted = sprintf(translate("%(userTag)s %(message)s"), { userTag: formattedUserTag, message: message}); 250 } 251 } 252 break; 253 default: 254 error(sprintf("Invalid chat message '%(message)s'", { message: uneval(msg) })); 255 return; 256 } 257 258 chatMessages.push(formatted); 259 chatTimers.push(setTimeout(removeOldChatMessages, CHAT_TIMEOUT)); 260 261 if (chatMessages.length > MAX_NUM_CHAT_LINES) 262 removeOldChatMessages(); 263 else 264 Engine.GetGUIObjectByName("chatText").caption = chatMessages.join("\n"); 265 } 266 267 function addChatMessageLobby(msg) 268 { 269 // Some calls of this function will leave some msg parameters empty. Text is required though. 270 if (msg.from) 271 { 272 // Display the moderator symbol in the chatbox. 273 var playerRole = Engine.LobbyGetPlayerRole(msg.from); 274 if (playerRole == "moderator") 275 msg.from = g_modPrefix + msg.from; 276 } 277 else 278 msg.from = null; 279 if (!msg.color) 280 msg.color = null; 281 if (!msg.key) 282 msg.key = null; 283 if (!msg.datetime) 284 msg.datetime = null; 285 286 // Highlight local user's nick 287 if (msg.text.indexOf(g_Name) != -1 && g_Name != msg.from) 288 msg.text = msg.text.replace(new RegExp('\\b' + '\\' + g_Name + '\\b', "g"), colorPlayerName(g_Name)); 289 290 // Run spam test if it's not a historical message 291 if (!msg.datetime) 292 updateSpamMonitor(msg.from); 293 if (isSpam(msg.text, msg.from)) 294 return; 295 296 // Format Text 297 var formatted = ircFormat(msg.text, msg.from, msg.color, msg.key, msg.datetime); 298 299 // If there is text, add it to the chat box. 300 if (formatted) 301 { 302 g_ChatMessages.push(formatted); 303 Engine.GetGUIObjectByName("chatText").caption = g_ChatMessages.join("\n"); 304 } 305 } 306 -
binaries/data/mods/public/gui/gamesetup/gamesetup.js
diff --git a/binaries/data/mods/public/gui/gamesetup/gamesetup.js b/binaries/data/mods/public/gui/gamesetup/gamesetup.js index 856b79d..960393a 100644
a b function handleNetMessage(message) 451 451 // If we have extra player slots and we are the controller, give the player an ID. 452 452 if (g_IsController && message.hosts[host].player === -1 && g_AssignedCount < g_GameAttributes.settings.PlayerData.length) 453 453 Engine.AssignNetworkPlayer(g_AssignedCount + 1, host); 454 addChatMessage ({ "type": "connect", "username": message.hosts[host].name });454 addChatMessageGameSetup({ "type": "connect", "username": message.hosts[host].name }); 455 455 newPlayer = host; 456 456 } 457 457 } … … function handleNetMessage(message) 460 460 { 461 461 if (!message.hosts[host]) 462 462 { 463 addChatMessage ({ "type": "disconnect", "guid": host });463 addChatMessageGameSetup({ "type": "disconnect", "guid": host }); 464 464 if (g_PlayerAssignments[host].player != -1) 465 465 resetReady = true; // Observers shouldn't reset ready. 466 466 } … … function handleNetMessage(message) 494 494 break; 495 495 496 496 case "chat": 497 addChatMessage ({ "type": "message", "guid": message.guid, "text": message.text });497 addChatMessageGameSetup({ "type": "message", "guid": message.guid, "text": message.text }); 498 498 break; 499 499 500 500 // Singular client to host message 501 501 case "ready": 502 502 g_ReadyChanged -= 1; 503 503 if (g_ReadyChanged < 1 && g_PlayerAssignments[message.guid].player != -1) 504 addChatMessage ({ "type": "ready", "guid": message.guid, "ready": +message.status == 1 });504 addChatMessageGameSetup({ "type": "ready", "guid": message.guid, "ready": +message.status == 1 }); 505 505 if (!g_IsController) 506 506 break; 507 507 g_PlayerAssignments[message.guid].status = +message.status == 1; … … function submitChatInput() 1688 1688 } 1689 1689 } 1690 1690 1691 function addChatMessage(msg)1692 {1693 var username = "";1694 if (msg.username)1695 username = escapeText(msg.username);1696 else if (msg.guid && g_PlayerAssignments[msg.guid])1697 username = escapeText(g_PlayerAssignments[msg.guid].name);1698 1699 var message = "";1700 if ("text" in msg && msg.text)1701 message = escapeText(msg.text);1702 1703 // TODO: Maybe host should have distinct font/color?1704 var color = "white";1705 1706 if (msg.guid && g_PlayerAssignments[msg.guid] && g_PlayerAssignments[msg.guid].player != -1)1707 {1708 // Valid player who has been assigned - get player color1709 var player = g_PlayerAssignments[msg.guid].player - 1;1710 var mapName = g_GameAttributes.map;1711 var mapData = loadMapData(mapName);1712 var mapSettings = (mapData && mapData.settings ? mapData.settings : {});1713 var pData = mapSettings.PlayerData ? mapSettings.PlayerData[player] : {};1714 var pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[player] : {};1715 1716 color = rgbToGuiColor(getSetting(pData, pDefs, "Color"));1717 }1718 1719 var formatted;1720 switch (msg.type)1721 {1722 case "connect":1723 var formattedUsername = '[color="'+ color +'"]' + username + '[/color]';1724 formatted = '[font="sans-bold-13"] ' + sprintf(translate("== %(message)s"), { message: sprintf(translate("%(username)s has joined"), { username: formattedUsername }) }) + '[/font]';1725 break;1726 1727 case "disconnect":1728 var formattedUsername = '[color="'+ color +'"]' + username + '[/color]';1729 formatted = '[font="sans-bold-13"] ' + sprintf(translate("== %(message)s"), { message: sprintf(translate("%(username)s has left"), { username: formattedUsername }) }) + '[/font]';1730 break;1731 1732 case "message":1733 var formattedUsername = '[color="'+ color +'"]' + username + '[/color]';1734 var formattedUsernamePrefix = '[font="sans-bold-13"]' + sprintf(translate("<%(username)s>"), { username: formattedUsername }) + '[/font]'1735 formatted = sprintf(translate("%(username)s %(message)s"), { username: formattedUsernamePrefix, message: message });1736 break;1737 1738 case "ready":1739 var formattedUsername = '[font="sans-bold-13"][color="'+ color +'"]' + username + '[/color][/font]'1740 if (msg.ready)1741 formatted = ' ' + sprintf(translate("* %(username)s is ready!"), { username: formattedUsername });1742 else1743 formatted = ' ' + sprintf(translate("* %(username)s is not ready."), { username: formattedUsername });1744 break;1745 1746 case "settings":1747 formatted = '[font="sans-bold-13"] ' + sprintf(translate("== %(message)s"), { message: translate('Game settings have been changed') }) + '[/font]';1748 break;1749 1750 default:1751 error(sprintf("Invalid chat message '%(message)s'", { message: uneval(msg) }));1752 return;1753 }1754 1755 g_ChatMessages.push(formatted);1756 1757 Engine.GetGUIObjectByName("chatText").caption = g_ChatMessages.join("\n");1758 }1759 1760 1691 function toggleMoreOptions() 1761 1692 { 1762 1693 Engine.GetGUIObjectByName("moreOptionsFade").hidden = !Engine.GetGUIObjectByName("moreOptionsFade").hidden; … … function resetReadyData() 1835 1766 return; 1836 1767 1837 1768 if (g_ReadyChanged < 1) 1838 addChatMessage ({ "type": "settings"});1769 addChatMessageGameSetup({ "type": "settings"}); 1839 1770 else if (g_ReadyChanged == 2 && !g_ReadyInit) 1840 1771 return; // duplicate calls on init 1841 1772 else -
binaries/data/mods/public/gui/gamesetup/gamesetup.xml
diff --git a/binaries/data/mods/public/gui/gamesetup/gamesetup.xml b/binaries/data/mods/public/gui/gamesetup/gamesetup.xml index 4788977..d575793 100644
a b 3 3 <objects> 4 4 5 5 <script file="gui/common/network.js"/> 6 <script file="gui/common/functions_chat.js"/> 6 7 <script file="gui/common/functions_civinfo.js"/> 7 8 <script file="gui/common/functions_global_object.js"/> 8 9 <script file="gui/common/functions_utility.js"/> -
binaries/data/mods/public/gui/lobby/lobby.js
diff --git a/binaries/data/mods/public/gui/lobby/lobby.js b/binaries/data/mods/public/gui/lobby/lobby.js index 0777bfd..64ee983 100644
a b function lobbyDisconnect() 75 75 } 76 76 77 77 //////////////////////////////////////////////////////////////////////////////////////////////// 78 // Update functions 79 //////////////////////////////////////////////////////////////////////////////////////////////// 80 81 function updateGameListOrderSelection() 82 { 83 g_GameListSortBy = Engine.GetGUIObjectByName("gamesBox").selected_column; 84 g_GameListOrder = Engine.GetGUIObjectByName("gamesBox").selected_column_order; 85 86 applyFilters(); 87 } 88 89 function updatePlayerListOrderSelection() 90 { 91 g_PlayerListSortBy = Engine.GetGUIObjectByName("playersBox").selected_column; 92 g_PlayerListOrder = Engine.GetGUIObjectByName("playersBox").selected_column_order; 93 94 updatePlayerList(); 95 } 96 97 function resetFilters() 98 { 99 // Reset states of gui objects 78 // Update functions 79 //////////////////////////////////////////////////////////////////////////////////////////////// 80 81 function updateGameListOrderSelection() 82 { 83 g_GameListSortBy = Engine.GetGUIObjectByName("gamesBox").selected_column; 84 g_GameListOrder = Engine.GetGUIObjectByName("gamesBox").selected_column_order; 85 86 applyFilters(); 87 } 88 89 function updatePlayerListOrderSelection() 90 { 91 g_PlayerListSortBy = Engine.GetGUIObjectByName("playersBox").selected_column; 92 g_PlayerListOrder = Engine.GetGUIObjectByName("playersBox").selected_column_order; 93 94 updatePlayerList(); 95 } 96 97 function resetFilters() 98 { 99 // Reset states of gui objects 100 100 Engine.GetGUIObjectByName("mapSizeFilter").selected = 0 101 101 Engine.GetGUIObjectByName("playersNumberFilter").selected = 0; 102 Engine.GetGUIObjectByName("mapTypeFilter").selected = 0; 103 Engine.GetGUIObjectByName("showFullFilter").checked = false; 104 105 applyFilters(); 106 } 107 108 function applyFilters() 102 Engine.GetGUIObjectByName("mapTypeFilter").selected = 0; 103 Engine.GetGUIObjectByName("showFullFilter").checked = false; 104 105 applyFilters(); 106 } 107 108 function applyFilters() 109 109 { 110 110 // Update the list of games 111 111 updateGameList(); … … function updateSubject(newSubject) 162 162 subjectBox.hidden = false; 163 163 logo.size = "50%-110 40 50%+110 140"; 164 164 } 165 } 166 167 /** 168 * Do a full update of the player listing, including ratings from cached C++ information. 169 * 170 * @return Array containing the player, presence, nickname, and rating listings. 171 */ 165 } 166 167 /** 168 * Do a full update of the player listing, including ratings from cached C++ information. 169 * 170 * @return Array containing the player, presence, nickname, and rating listings. 171 */ 172 172 function updatePlayerList() 173 173 { 174 174 var playersBox = Engine.GetGUIObjectByName("playersBox"); … … function updateGameList() 402 402 // to update the game info panel. 403 403 g_GameList = gameList; 404 404 405 // Sort the list of games to that games 'waiting' are displayed at the top, followed by 'init', followed by 'running'. 405 // Sort the list of games to that games 'waiting' are displayed at the top, followed by 'init', followed by 'running'. 406 406 var gameStatuses = ['waiting', 'init', 'running']; 407 407 g_GameList.sort(function (a,b) { 408 408 switch (g_GameListSortBy) … … function joinSelectedGame() 633 633 // Check if it looks like an ip address 634 634 if (sip.split('.').length != 4) 635 635 { 636 addChatMessage ({ "from": "system", "text": sprintf(translate("This game's address '%(ip)s' does not appear to be valid."), { ip: sip }) });636 addChatMessageLobby({ "from": "system", "text": sprintf(translate("This game's address '%(ip)s' does not appear to be valid."), { ip: sip }) }); 637 637 return; 638 638 } 639 639 … … function onTick() 681 681 { 682 682 case "mucmessage": // For room messages 683 683 var from = escapeText(message.from); 684 addChatMessage ({ "from": from, "text": text, "datetime": message.datetime});684 addChatMessageLobby({ "from": from, "text": text, "datetime": message.datetime}); 685 685 break; 686 686 case "message": // For private messages 687 687 var from = escapeText(message.from); 688 addChatMessage ({ "from": from, "text": text, "datetime": message.datetime});688 addChatMessageLobby({ "from": from, "text": text, "datetime": message.datetime}); 689 689 break; 690 690 case "muc": 691 691 var nick = message.text; … … function onTick() 716 716 nickList.push(nick); 717 717 ratingList.push(String(rating)); 718 718 Engine.SendGetRatingList(); 719 addChatMessage ({ "text": "/special " + sprintf(translate("%(nick)s has joined."), { nick: nick }), "key": g_specialKey });719 addChatMessageLobby({ "text": "/special " + sprintf(translate("%(nick)s has joined."), { nick: nick }), "key": g_specialKey }); 720 720 } 721 721 break; 722 722 case "leave": … … function onTick() 726 726 presenceList.splice(nickIndex, 1); 727 727 nickList.splice(nickIndex, 1); 728 728 ratingList.splice(nickIndex, 1); 729 addChatMessage ({ "text": "/special " + sprintf(translate("%(nick)s has left."), { nick: nick }), "key": g_specialKey });729 addChatMessageLobby({ "text": "/special " + sprintf(translate("%(nick)s has left."), { nick: nick }), "key": g_specialKey }); 730 730 break; 731 731 case "nick": 732 732 if (nickIndex == -1) // This shouldn't ever happen 733 733 break; 734 734 if (!isValidNick(message.data)) 735 735 { 736 addChatMessage ({ "from": "system", "text": sprintf(translate("Invalid nickname: %(nick)s"), { nick: message.data })});736 addChatMessageLobby({ "from": "system", "text": sprintf(translate("Invalid nickname: %(nick)s"), { nick: message.data })}); 737 737 break; 738 738 } 739 739 var [name, status, rating] = formatPlayerListEntry(message.data, presence, stripColorCodes(ratingList[nickIndex])); // TODO: actually we don't want to change the presence here, so use what was used before 740 740 playerList[nickIndex] = name; 741 741 // presence stays the same 742 742 nickList[nickIndex] = message.data; 743 addChatMessage ({ "text": "/special " + sprintf(translate("%(oldnick)s is now known as %(newnick)s."), { oldnick: nick, newnick: message.data }), "key": g_specialKey });743 addChatMessageLobby({ "text": "/special " + sprintf(translate("%(oldnick)s is now known as %(newnick)s."), { oldnick: nick, newnick: message.data }), "key": g_specialKey }); 744 744 Engine.SendGetRatingList(); 745 745 break; 746 746 case "presence": … … function onTick() 770 770 switch (message.level) 771 771 { 772 772 case "standard": 773 addChatMessage ({ "from": "system", "text": text, "color": "150 0 0" });773 addChatMessageLobby({ "from": "system", "text": text, "color": "150 0 0" }); 774 774 if (message.text == "disconnected") 775 775 { 776 776 // Clear the list of games and the list of players … … function onTick() 786 786 } 787 787 break; 788 788 case "error": 789 addChatMessage ({ "from": "system", "text": text, "color": "150 0 0" });789 addChatMessageLobby({ "from": "system", "text": text, "color": "150 0 0" }); 790 790 break; 791 791 case "internal": 792 792 switch (message.text) … … function handleSpecialCommand(text) 868 868 case "me": 869 869 return false; 870 870 default: 871 addChatMessage ({ "from":"system", "text": sprintf(translate("We're sorry, the '%(cmd)s' command is not supported."), { cmd: cmd})});871 addChatMessageLobby({ "from":"system", "text": sprintf(translate("We're sorry, the '%(cmd)s' command is not supported."), { cmd: cmd})}); 872 872 } 873 873 return true; 874 874 } 875 875 876 /**877 * Process and, if appropriate, display a formatted message.878 *879 * @param msg The message to be processed.880 */881 function addChatMessage(msg)882 {883 // Some calls of this function will leave some msg parameters empty. Text is required though.884 if (msg.from)885 {886 // Display the moderator symbol in the chatbox.887 var playerRole = Engine.LobbyGetPlayerRole(msg.from);888 if (playerRole == "moderator")889 msg.from = g_modPrefix + msg.from;890 }891 else892 msg.from = null;893 if (!msg.color)894 msg.color = null;895 if (!msg.key)896 msg.key = null;897 if (!msg.datetime)898 msg.datetime = null;899 900 // Highlight local user's nick901 if (msg.text.indexOf(g_Name) != -1 && g_Name != msg.from)902 msg.text = msg.text.replace(new RegExp('\\b' + '\\' + g_Name + '\\b', "g"), colorPlayerName(g_Name));903 904 // Run spam test if it's not a historical message905 if (!msg.datetime)906 updateSpamMonitor(msg.from);907 if (isSpam(msg.text, msg.from))908 return;909 910 // Format Text911 var formatted = ircFormat(msg.text, msg.from, msg.color, msg.key, msg.datetime);912 913 // If there is text, add it to the chat box.914 if (formatted)915 {916 g_ChatMessages.push(formatted);917 Engine.GetGUIObjectByName("chatText").caption = g_ChatMessages.join("\n");918 }919 }920 921 876 function ircSplit(string) 922 877 { 923 878 var idx = string.indexOf(' '); … … function isSpam(text, from) 1062 1017 { 1063 1018 g_spamMonitor[from][2] = time; 1064 1019 if (from == g_Name) 1065 addChatMessage ({ "from": "system", "text": translate("Please do not spam. You have been blocked for thirty seconds.") });1020 addChatMessageLobby({ "from": "system", "text": translate("Please do not spam. You have been blocked for thirty seconds.") }); 1066 1021 return true; 1067 1022 } 1068 1023 // Return false if everything is clear. -
binaries/data/mods/public/gui/lobby/lobby.xml
diff --git a/binaries/data/mods/public/gui/lobby/lobby.xml b/binaries/data/mods/public/gui/lobby/lobby.xml index 879b49d..6574518 100644
a b 1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 3 3 <objects> 4 <script file="gui/common/functions_chat.js"/> 4 5 <script file="gui/common/functions_global_object.js"/> 5 6 <script file="gui/common/functions_utility.js"/> 6 7 <script file="gui/common/timer.js"/> -
binaries/data/mods/public/gui/session/messages.js
diff --git a/binaries/data/mods/public/gui/session/messages.js b/binaries/data/mods/public/gui/session/messages.js index 0aef597..5c504c3 100644
a b var g_NotificationsTypes = 44 44 } else { 45 45 message["guid"] = guid; 46 46 } 47 addChatMessage (message);47 addChatMessageSession(message); 48 48 }, 49 49 "aichat": function(notification, player) 50 50 { … … var g_NotificationsTypes = 74 74 } else { 75 75 message["guid"] = guid; 76 76 } 77 addChatMessage (message);77 addChatMessageSession(message); 78 78 }, 79 79 "defeat": function(notification, player) 80 80 { 81 addChatMessage ({81 addChatMessageSession({ 82 82 "type": "defeat", 83 83 "guid": findGuidForPlayerID(g_PlayerAssignments, player), 84 84 "player": player … … var g_NotificationsTypes = 88 88 }, 89 89 "diplomacy": function(notification, player) 90 90 { 91 addChatMessage ({91 addChatMessageSession({ 92 92 "type": "diplomacy", 93 93 "player": player, 94 94 "player1": notification.player1, … … var g_NotificationsTypes = 103 103 }, 104 104 "tribute": function(notification, player) 105 105 { 106 addChatMessage ({106 addChatMessageSession({ 107 107 "type": "tribute", 108 108 "player": player, 109 109 "player1": notification.donator, … … var g_NotificationsTypes = 116 116 return; 117 117 if (Engine.ConfigDB_GetValue("user", "gui.session.attacknotificationmessage") !== "true") 118 118 return; 119 addChatMessage ({119 addChatMessageSession({ 120 120 "type": "attack", 121 121 "player": player, 122 122 "attacker": notification.attacker, … … function handleNetMessage(message) 259 259 if (!message.hosts[host]) 260 260 { 261 261 // Tell the user about the disconnection 262 addChatMessage ({ "type": "disconnect", "guid": host });262 addChatMessageSession({ "type": "disconnect", "guid": host }); 263 263 264 264 // Update the cached player data, so we can display the disconnection status 265 265 updatePlayerDataRemove(g_Players, host); … … function handleNetMessage(message) 275 275 updatePlayerDataAdd(g_Players, host, message.hosts[host]); 276 276 277 277 // Tell the user about the connection 278 addChatMessage ({ "type": "connect", "guid": host }, message.hosts);278 addChatMessageSession({ "type": "connect", "guid": host }, message.hosts); 279 279 } 280 280 } 281 281 … … function handleNetMessage(message) 290 290 break; 291 291 292 292 case "chat": 293 addChatMessage ({ "type": "message", "guid": message.guid, "text": message.text });293 addChatMessageSession({ "type": "message", "guid": message.guid, "text": message.text }); 294 294 break; 295 295 296 296 case "aichat": 297 addChatMessage ({ "type": "message", "guid": message.guid, "text": message.text, "translate": true });297 addChatMessageSession({ "type": "message", "guid": message.guid, "text": message.text, "translate": true }); 298 298 break; 299 299 300 300 case "rejoined": 301 addChatMessage ({ "type": "rejoined", "guid": message.guid});301 addChatMessageSession({ "type": "rejoined", "guid": message.guid}); 302 302 break; 303 303 304 304 // To prevent errors, ignore these message types that occur during autostart … … function submitChatDirectly(text) 318 318 if (g_IsNetworked) 319 319 Engine.SendNetworkChat(text); 320 320 else 321 addChatMessage ({ "type": "message", "guid": "local", "text": text });321 addChatMessageSession({ "type": "message", "guid": "local", "text": text }); 322 322 } 323 323 } 324 324 … … function submitChatInput() 385 385 if (g_IsNetworked) 386 386 Engine.SendNetworkChat(text); 387 387 else 388 addChatMessage ({ "type": "message", "guid": "local", "text": text });388 addChatMessageSession({ "type": "message", "guid": "local", "text": text }); 389 389 } 390 390 input.caption = ""; // Clear chat input 391 391 } … … function submitChatInput() 395 395 toggleChatWindow(); 396 396 } 397 397 398 function addChatMessage(msg, playerAssignments)399 {400 // Default to global assignments, but allow overriding for when reporting401 // new players joining402 if (!playerAssignments)403 playerAssignments = g_PlayerAssignments;404 405 var playerColor, username;406 407 // No context by default. May be set by parseChatCommands().408 msg.context = "";409 410 if ("guid" in msg && playerAssignments[msg.guid])411 {412 var n = playerAssignments[msg.guid].player;413 // Observers have an ID of -1 which is not a valid index.414 if (n < 0)415 n = 0;416 playerColor = g_Players[n].color.r + " " + g_Players[n].color.g + " " + g_Players[n].color.b;417 username = escapeText(playerAssignments[msg.guid].name);418 419 // Parse in-line commands in regular messages.420 if (msg.type == "message")421 parseChatCommands(msg, playerAssignments);422 }423 else if (msg.type == "defeat" && msg.player)424 {425 [username, playerColor] = getUsernameAndColor(msg.player);426 }427 else if (msg.type == "message")428 {429 [username, playerColor] = getUsernameAndColor(msg.player);430 parseChatCommands(msg, playerAssignments);431 }432 else433 {434 playerColor = "255 255 255";435 username = translate("Unknown player");436 }437 438 var formatted;439 440 switch (msg.type)441 {442 case "connect":443 formatted = sprintf(translate("%(player)s is starting to rejoin the game."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" });444 break;445 case "disconnect":446 formatted = sprintf(translate("%(player)s has left the game."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" });447 break;448 case "rejoined":449 formatted = sprintf(translate("%(player)s has rejoined the game."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" });450 break;451 case "defeat":452 // In singleplayer, the local player is "You". "You has" is incorrect.453 if (!g_IsNetworked && msg.player == Engine.GetPlayerID())454 formatted = translate("You have been defeated.");455 else456 formatted = sprintf(translate("%(player)s has been defeated."), { player: "[color=\"" + playerColor + "\"]" + username + "[/color]" });457 break;458 case "diplomacy":459 var message;460 if (msg.player == Engine.GetPlayerID())461 {462 [username, playerColor] = getUsernameAndColor(msg.player1);463 if (msg.status == "ally")464 message = translate("You are now allied with %(player)s.");465 else if (msg.status == "enemy")466 message = translate("You are now at war with %(player)s.");467 else // (msg.status == "neutral")468 message = translate("You are now neutral with %(player)s.");469 }470 else if (msg.player1 == Engine.GetPlayerID())471 {472 [username, playerColor] = getUsernameAndColor(msg.player);473 if (msg.status == "ally")474 message = translate("%(player)s is now allied with you.");475 else if (msg.status == "enemy")476 message = translate("%(player)s is now at war with you.");477 else // (msg.status == "neutral")478 message = translate("%(player)s is now neutral with you.");479 }480 else // No need for other players to know of this.481 return;482 483 formatted = sprintf(message, { "player": '[color="'+ playerColor + '"]' + username + '[/color]' });484 break;485 case "tribute":486 if (msg.player != Engine.GetPlayerID())487 return;488 489 [username, playerColor] = getUsernameAndColor(msg.player1);490 491 // Format the amounts to proper English: 200 food, 100 wood, and 300 metal; 100 food; 400 wood and 200 stone492 let amounts = Object.keys(msg.amounts)493 .filter(function (type) { return msg.amounts[type] > 0; })494 .map(function (type) { return sprintf(translate("%(amount)s %(resourceType)s"), {495 "amount": msg.amounts[type],496 "resourceType": getLocalizedResourceName(type, "withinSentence")});497 });498 499 if (amounts.length > 1)500 {501 let lastAmount = amounts.pop();502 amounts = sprintf(translate("%(previousAmounts)s and %(lastAmount)s"), {503 previousAmounts: amounts.join(translate(", ")),504 lastAmount: lastAmount505 });506 }507 508 formatted = sprintf(translate("%(player)s has sent you %(amounts)s."), {509 player: "[color=\"" + playerColor + "\"]" + username + "[/color]",510 amounts: amounts511 });512 break;513 case "attack":514 if (msg.player != Engine.GetPlayerID())515 return;516 517 [username, playerColor] = getUsernameAndColor(msg.attacker);518 // Since livestock can be attacked/gathered by other players,519 // we display a more specific notification in this case to not confuse the player520 if (msg.targetIsDomesticAnimal)521 var message = translate("Your livestock have been attacked by %(attacker)s!");522 else523 var message = translate("You have been attacked by %(attacker)s!");524 formatted = sprintf(message, { attacker: "[color=\"" + playerColor + "\"]" + username + "[/color]" });525 break;526 case "message":527 // May have been hidden by the 'team' command.528 if (msg.hide)529 return;530 531 var message;532 if ("translate" in msg && msg.translate)533 {534 message = translate(msg.text); // No need to escape, not a user message.535 if ("translateParameters" in msg && msg.translateParameters)536 {537 var parameters = msg.parameters || {};538 translateObjectKeys(parameters, msg.translateParameters);539 message = sprintf(message, parameters);540 }541 }542 else543 message = escapeText(msg.text);544 545 if (msg.action)546 {547 if (msg.context !== "")548 {549 formatted = sprintf(translate("(%(context)s) * %(user)s %(message)s"), {550 context: msg.context,551 user: "[color=\"" + playerColor + "\"]" + username + "[/color]",552 message: message553 });554 }555 else556 {557 formatted = sprintf(translate("* %(user)s %(message)s"), {558 user: "[color=\"" + playerColor + "\"]" + username + "[/color]",559 message: message560 });561 }562 }563 else564 {565 var userTag = sprintf(translate("<%(user)s>"), { user: username })566 var formattedUserTag = sprintf(translate("<%(user)s>"), { user: "[color=\"" + playerColor + "\"]" + username + "[/color]" })567 if (msg.context !== "")568 {569 formatted = sprintf(translate("(%(context)s) %(userTag)s %(message)s"), {570 context: msg.context,571 userTag: formattedUserTag,572 message: message573 });574 }575 else576 {577 formatted = sprintf(translate("%(userTag)s %(message)s"), { userTag: formattedUserTag, message: message});578 }579 }580 break;581 default:582 error(sprintf("Invalid chat message '%(message)s'", { message: uneval(msg) }));583 return;584 }585 586 chatMessages.push(formatted);587 chatTimers.push(setTimeout(removeOldChatMessages, CHAT_TIMEOUT));588 589 if (chatMessages.length > MAX_NUM_CHAT_LINES)590 removeOldChatMessages();591 else592 Engine.GetGUIObjectByName("chatText").caption = chatMessages.join("\n");593 }594 595 398 function removeOldChatMessages() 596 399 { 597 400 clearTimeout(chatTimers[0]); // The timer only needs to be cleared when new messages bump old messages off -
binaries/data/mods/public/gui/session/session.xml
diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml index d9ee7da..988d0db 100644
a b 3 3 <objects> 4 4 5 5 <script file="gui/common/colorFades.js"/> 6 <script file="gui/common/functions_chat.js"/> 6 7 <script file="gui/common/functions_civinfo.js"/> 7 8 <script file="gui/common/functions_global_object.js"/> 8 9 <script file="gui/common/functions_utility.js"/>