Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/gui/lobby/lobby.js
Context not available. | |||||
* The playerlist will be assembled using these values. | * The playerlist will be assembled using these values. | ||||
*/ | */ | ||||
var g_PlayerStatuses = { | var g_PlayerStatuses = { | ||||
"available": { "color": "0 219 0", "status": translate("Online") }, | "available": { "color": "0 219 0", "messageBrightness": 1, "status": translate("Online") }, | ||||
"away": { "color": "229 76 13", "status": translate("Away") }, | "away": { "color": "229 76 13", "messageBrightness": 0.8, "status": translate("Away") }, | ||||
"playing": { "color": "200 0 0", "status": translate("Busy") }, | "playing": { "color": "200 0 0", "messageBrightness": 0.6, "status": translate("Busy") }, | ||||
"offline": { "color": "0 0 0", "status": translate("Offline") }, | "offline": { "color": "0 0 0", "messageBrightness": 0.4, "status": translate("Offline") }, | ||||
"unknown": { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") } | "unknown": { "color": "178 178 178", "messageBrightness": 0.4, "status": translateWithContext("lobby presence", "Unknown") } | ||||
}; | }; | ||||
var g_RoleNames = { | var g_RoleNames = { | ||||
Context not available. | |||||
var g_Kicked = false; | var g_Kicked = false; | ||||
/** | /** | ||||
* List of players in lobby. | |||||
*/ | |||||
var g_PlayerList = [ "uninitialized" ]; | |||||
/** | |||||
* Processing of notifications sent by XmppClient.cpp. | * Processing of notifications sent by XmppClient.cpp. | ||||
* | * | ||||
* @returns true if the playerlist GUI must be updated. | * @returns true if the playerlist GUI must be updated. | ||||
Context not available. | |||||
return true; | return true; | ||||
}, | }, | ||||
"presence": msg => true, | "presence": msg => { | ||||
if (g_PlayerList[0] == "uninitialized") | |||||
g_PlayerList[0] = "initial"; | |||||
return true; | |||||
}, | |||||
"role": msg => { | "role": msg => { | ||||
Engine.GetGUIObjectByName("chatInput").hidden = Engine.LobbyGetPlayerRole(g_Username) == "visitor"; | Engine.GetGUIObjectByName("chatInput").hidden = Engine.LobbyGetPlayerRole(g_Username) == "visitor"; | ||||
Context not available. | |||||
toggleBuddyButton.enabled = playerName && playerName != g_Username; | toggleBuddyButton.enabled = playerName && playerName != g_Username; | ||||
} | } | ||||
/* | |||||
* Find data object in a previous list by name and restore its attributes. | |||||
* Trying firstly object at index in previous list and when not same name, search the list for object. | |||||
* @return [ object, index ] - [ found previous object, next index to look for next object in list ] | |||||
*/ | |||||
function restoreObjectFromList(newObject, index, previousList, previousAttributes) | |||||
{ | |||||
let previousObject = previousList[index] && | |||||
previousList[index].name == newObject.name ? previousList[index++] : | |||||
previousList.find((previousObject, indexFound) => previousObject.name == newObject.name && (index = ++indexFound)); | |||||
previousAttributes.forEach(att => newObject[att] = previousObject && previousObject[att] ? previousObject[att] : []); | |||||
return [ previousObject, index ]; | |||||
} | |||||
/** | /** | ||||
* Do a full update of the player listing, including ratings from cached C++ information. | * Do a full update of the player listing, including ratings from cached C++ information. | ||||
*/ | */ | ||||
function updatePlayerList() | function updatePlayerList() | ||||
{ | { | ||||
let isInitialPlayerList = g_PlayerList[0] && g_PlayerList[0] == "initial"; | |||||
let newPlayerList = Engine.GetPlayerList(); | |||||
if (g_PlayerList[0] && g_PlayerList[0] == "uninitialized") | |||||
// If a playerlist is available before initial presences update, go initial | |||||
if (newPlayerList.length > 0) | |||||
isInitialPlayerList = true; | |||||
else | |||||
return; | |||||
if (isInitialPlayerList) | |||||
g_PlayerList = []; | |||||
let playersBox = Engine.GetGUIObjectByName("playersBox"); | let playersBox = Engine.GetGUIObjectByName("playersBox"); | ||||
let sortBy = playersBox.selected_column || "name"; | let sortBy = playersBox.selected_column || "name"; | ||||
let sortOrder = playersBox.selected_column_order || 1; | let sortOrder = playersBox.selected_column_order || 1; | ||||
Context not available. | |||||
let nickList = []; | let nickList = []; | ||||
let ratingList = []; | let ratingList = []; | ||||
let cleanPlayerList = Engine.GetPlayerList().map(player => { | let isUpdatedChat = false; | ||||
let indexPrevious = 0; | |||||
g_PlayerList = newPlayerList.map(player => { | |||||
let playerPrevious = {}; | |||||
[ playerPrevious, indexPrevious ] = restoreObjectFromList(player, indexPrevious, g_PlayerList, ["messages"]); | |||||
if (playerPrevious && (playerPrevious.rating != player.rating || playerPrevious.presence != player.presence)) | |||||
player.messages.forEach(message => { | |||||
message.playerRating = player.rating; | |||||
message.playerPresence = player.presence; | |||||
isUpdatedChat = ircFormat(message) || isUpdatedChat; | |||||
}); | |||||
player.isBuddy = g_Buddies.indexOf(player.name) != -1; | player.isBuddy = g_Buddies.indexOf(player.name) != -1; | ||||
return player; | return player; | ||||
}).sort((a, b) => { | }); | ||||
// Check if unassigned messages to players lie in the chat | |||||
if (isInitialPlayerList) | |||||
g_ChatMessages.forEach(msg => assignChatMessageToPlayer(msg, true) && (isUpdatedChat = ircFormat(msg) || isUpdatedChat)); | |||||
let cleanPlayerList = g_PlayerList.sort((a, b) => { | |||||
let sortA, sortB; | let sortA, sortB; | ||||
let statusOrder = Object.keys(g_PlayerStatuses); | let statusOrder = Object.keys(g_PlayerStatuses); | ||||
let statusA = statusOrder.indexOf(a.presence) + a.name.toLowerCase(); | let statusA = statusOrder.indexOf(a.presence) + a.name.toLowerCase(); | ||||
Context not available. | |||||
playersBox.list = nickList; | playersBox.list = nickList; | ||||
playersBox.selected = playersBox.list.indexOf(g_SelectedPlayer); | playersBox.selected = playersBox.list.indexOf(g_SelectedPlayer); | ||||
if (isUpdatedChat) | |||||
updateChatWindow(); | |||||
} | } | ||||
/** | /** | ||||
Context not available. | |||||
return g_ChatCommands[cmd].handler(args); | return g_ChatCommands[cmd].handler(args); | ||||
} | } | ||||
function assignChatMessageToPlayer(message, checkAlreadyAdded) | |||||
{ | |||||
let playerFrom = g_PlayerList.find(player => player.name && player.name == message.from); | |||||
if (playerFrom && (!checkAlreadyAdded || playerFrom.messages.indexOf(message) == -1)) | |||||
{ | |||||
playerFrom.messages.push(message); | |||||
message.playerRating = playerFrom.rating; | |||||
message.playerPresence = playerFrom.presence; | |||||
return true; | |||||
} | |||||
} | |||||
/** | /** | ||||
* Process and if appropriate, display a formatted message. | * Process and if appropriate, display a formatted message. | ||||
* | * | ||||
Context not available. | |||||
{ | { | ||||
if (msg.from) | if (msg.from) | ||||
{ | { | ||||
assignChatMessageToPlayer(msg); | |||||
if (Engine.LobbyGetPlayerRole(msg.from) == "moderator") | if (Engine.LobbyGetPlayerRole(msg.from) == "moderator") | ||||
msg.from = g_ModeratorPrefix + msg.from; | msg.from = g_ModeratorPrefix + msg.from; | ||||
Context not available. | |||||
} | } | ||||
} | } | ||||
let formatted = ircFormat(msg); | if (!ircFormat(msg)) | ||||
if (!formatted) | |||||
return; | return; | ||||
g_ChatMessages.push(formatted); | g_ChatMessages.push(msg); | ||||
Engine.GetGUIObjectByName("chatText").caption = g_ChatMessages.join("\n"); | updateChatWindow(); | ||||
} | |||||
function updateChatWindow() | |||||
{ | |||||
Engine.GetGUIObjectByName("chatText").caption = g_ChatMessages.map(msg => msg.formatted).join("\n"); | |||||
} | } | ||||
/** | /** | ||||
Context not available. | |||||
} | } | ||||
/** | /** | ||||
* Format text in an IRC-like way. | * Format text in an IRC-like way and add it to msg.formatted. | ||||
* | * | ||||
* @param {Object} msg - Received chat message. | * @param {Object} msg - Received chat message. | ||||
* @returns {string} - Formatted text. | * @returns {boolean} - Text has been formatted. | ||||
*/ | */ | ||||
function ircFormat(msg) | function ircFormat(msg) | ||||
{ | { | ||||
let formattedMessage = ""; | let formattedMessage = ""; | ||||
let coloredFrom = msg.from && colorPlayerName(msg.from); | |||||
let messageBrightness = g_PlayerStatuses[ | |||||
Engine.ConfigDB_GetValue("user", "lobby.chatsenderpresence") == "false" || | |||||
!msg.from || | |||||
msg.from == "system" ? "available" : msg.playerPresence || "offline" | |||||
].messageBrightness; | |||||
let coloredFrom = msg.from ? coloredText( | |||||
msg.from + (Engine.ConfigDB_GetValue("user", "lobby.chatsenderrating") == "true" && msg.playerRating ? | |||||
" (" + msg.playerRating + ")" : ""), | |||||
setColorBrightness(getPlayerColor(msg.from), messageBrightness) | |||||
) : ""; | |||||
// Handle commands allowed past handleChatCommand. | // Handle commands allowed past handleChatCommand. | ||||
if (msg.text[0] == '/') | if (msg.text[0] == '/') | ||||
Context not available. | |||||
break; | break; | ||||
} | } | ||||
default: | default: | ||||
return ""; | return false; | ||||
} | } | ||||
} | } | ||||
else | else | ||||
Context not available. | |||||
}); | }); | ||||
} | } | ||||
msg.formatted = coloredText(formattedMessage, setColorBrightness("255 255 255", messageBrightness)); | |||||
// Add chat message timestamp | // Add chat message timestamp | ||||
if (Engine.ConfigDB_GetValue("user", "chat.timestamp") != "true") | if (Engine.ConfigDB_GetValue("user", "chat.timestamp") != "true") | ||||
return formattedMessage; | return true; | ||||
// Translation: Time as shown in the multiplayer lobby (when you enable it in the options page). | // Translation: Time as shown in the multiplayer lobby (when you enable it in the options page). | ||||
// For a list of symbols that you can use, see: | // For a list of symbols that you can use, see: | ||||
Context not available. | |||||
}); | }); | ||||
// Translation: IRC message format when there is a time prefix. | // Translation: IRC message format when there is a time prefix. | ||||
return sprintf(translate("%(time)s %(message)s"), { | msg.formatted = coloredText( | ||||
"time": senderFont(timePrefixString), | sprintf(translate("%(time)s %(message)s"), { | ||||
"message": formattedMessage | "time": senderFont(timePrefixString), | ||||
}); | "message": formattedMessage | ||||
}), | |||||
setColorBrightness("255 255 255", messageBrightness)); | |||||
return true; | |||||
} | } | ||||
/** | /** | ||||
Context not available. |
Wildfire Games · Phabricator