Mark players as buddies in the lobby and add a symbol to identify them in the lobby playerlist, gamelist and in the game description panel of the lobby, replay and load/save screen.
Differential Revision: https://code.wildfiregames.com/D209 Patch By: fpre aka. ffffffff Reviewed By: causative This was SVN commit r19433.
This commit is contained in:
parent
89c413031f
commit
dcf12abe8c
@ -372,6 +372,7 @@ history = 0 ; Number of past messages to display on join
|
||||
room = "arena22" ; Default MUC room to join
|
||||
server = "lobby.wildfiregames.com" ; Address of lobby server
|
||||
xpartamupp = "wfgbot22" ; Name of the server-side xmpp client that manage games
|
||||
buddies = "," ; Comma separated list of playernames that the current user has marked as buddies
|
||||
|
||||
[mod]
|
||||
enabledmods = "mod public"
|
||||
|
@ -158,6 +158,15 @@ function multiplayerName()
|
||||
return Engine.ConfigDB_GetValue("user", "playername.multiplayer") || Engine.GetSystemUsername();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nickname without the lobby rating.
|
||||
*/
|
||||
function removeRatingFromNick(playerName)
|
||||
{
|
||||
let result = /^(\S+)\ \(\d+\)$/g.exec(playerName);
|
||||
return result ? result[1] : playerName;
|
||||
}
|
||||
|
||||
function tryAutoComplete(text, autoCompleteList)
|
||||
{
|
||||
if (!text.length)
|
||||
|
@ -3,6 +3,22 @@
|
||||
*/
|
||||
var g_DescriptionHighlight = "orange";
|
||||
|
||||
/**
|
||||
* XEP-0172 doesn't restrict nicknames, but our lobby policy does.
|
||||
* So use this human readable delimiter to separate buddy names in the config file.
|
||||
*/
|
||||
var g_BuddyListDelimiter = ",";
|
||||
|
||||
/**
|
||||
* Array of playernames that the current user has marked as buddies.
|
||||
*/
|
||||
var g_Buddies = Engine.ConfigDB_GetValue("user", "lobby.buddies").split(g_BuddyListDelimiter);
|
||||
|
||||
/**
|
||||
* Denotes which players are a lobby buddy of the current user.
|
||||
*/
|
||||
var g_BuddySymbol = '•';
|
||||
|
||||
/**
|
||||
* Returns map description and preview image or placeholder.
|
||||
*/
|
||||
@ -123,7 +139,10 @@ function formatPlayerInfo(playerDataArray, playerStates)
|
||||
(typeof getPlayerColor == 'function' ?
|
||||
(isAI ? "white" : getPlayerColor(playerData.Name)) :
|
||||
rgbToGuiColor(playerData.Color || g_Settings.PlayerDefaults[playerIdx].Color)) +
|
||||
'"]' + escapeText(playerData.Name) + "[/color]",
|
||||
'"]' +
|
||||
(g_Buddies.indexOf(removeRatingFromNick(playerData.Name)) != -1 ? g_BuddySymbol + " " : "") +
|
||||
escapeText(playerData.Name) +
|
||||
"[/color]",
|
||||
|
||||
"civ":
|
||||
!playerData.Civ ?
|
||||
|
@ -382,23 +382,34 @@ function updatePlayerList()
|
||||
if (playersBox.selected > -1)
|
||||
g_SelectedPlayer = playersBox.list[playersBox.selected];
|
||||
|
||||
let buddyStatusList = [];
|
||||
let playerList = [];
|
||||
let presenceList = [];
|
||||
let nickList = [];
|
||||
let ratingList = [];
|
||||
|
||||
let cleanPlayerList = Engine.GetPlayerList().sort((a, b) => {
|
||||
let cleanPlayerList = Engine.GetPlayerList().map(player => {
|
||||
player.isBuddy = g_Buddies.indexOf(player.name) != -1;
|
||||
return player;
|
||||
}).sort((a, b) => {
|
||||
let sortA, sortB;
|
||||
let statusOrder = Object.keys(g_PlayerStatuses);
|
||||
let statusA = statusOrder.indexOf(a.presence) + a.name.toLowerCase();
|
||||
let statusB = statusOrder.indexOf(b.presence) + b.name.toLowerCase();
|
||||
|
||||
switch (sortBy)
|
||||
{
|
||||
case 'buddy':
|
||||
sortA = (a.isBuddy ? 1 : 2) + statusA;
|
||||
sortB = (b.isBuddy ? 1 : 2) + statusB;
|
||||
break;
|
||||
case 'rating':
|
||||
sortA = +a.rating;
|
||||
sortB = +b.rating;
|
||||
break;
|
||||
case 'status':
|
||||
let statusOrder = Object.keys(g_PlayerStatuses);
|
||||
sortA = statusOrder.indexOf(a.presence);
|
||||
sortB = statusOrder.indexOf(b.presence);
|
||||
sortA = statusA;
|
||||
sortB = statusB;
|
||||
break;
|
||||
case 'name':
|
||||
default:
|
||||
@ -427,12 +438,14 @@ function updatePlayerList()
|
||||
let coloredPresence = '[color="' + statusColor + '"]' + g_PlayerStatuses[presence].status + "[/color]";
|
||||
let coloredRating = '[color="' + statusColor + '"]' + rating + "[/color]";
|
||||
|
||||
buddyStatusList.push(player.isBuddy ? '[color="' + statusColor + '"]' + g_BuddySymbol + '[/color]' : "");
|
||||
playerList.push(coloredName);
|
||||
presenceList.push(coloredPresence);
|
||||
ratingList.push(coloredRating);
|
||||
nickList.push(player.name);
|
||||
}
|
||||
|
||||
playersBox.list_buddy = buddyStatusList;
|
||||
playersBox.list_name = playerList;
|
||||
playersBox.list_status = presenceList;
|
||||
playersBox.list_rating = ratingList;
|
||||
@ -443,6 +456,31 @@ function updatePlayerList()
|
||||
playersBox.selected = playersBox.list.indexOf(g_SelectedPlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle buddy state for a player in playerlist within the user config
|
||||
*/
|
||||
function toggleBuddy()
|
||||
{
|
||||
let playerList = Engine.GetGUIObjectByName("playersBox");
|
||||
let name = playerList.list[playerList.selected];
|
||||
|
||||
if (!name || name == g_Username || name.indexOf(g_BuddyListDelimiter) != -1)
|
||||
return;
|
||||
|
||||
let index = g_Buddies.indexOf(name);
|
||||
if (index != -1)
|
||||
g_Buddies.splice(index, 1);
|
||||
else
|
||||
g_Buddies.push(name);
|
||||
|
||||
let buddies = g_Buddies.filter(nick => nick).join(g_BuddyListDelimiter);
|
||||
Engine.ConfigDB_CreateValue("user", "lobby.buddies", buddies);
|
||||
Engine.ConfigDB_WriteValueToFile("user", "lobby.buddies", buddies, "config/user.cfg");
|
||||
|
||||
updatePlayerList();
|
||||
updateGameList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the game listing the selected player when toggling the full games filter.
|
||||
*/
|
||||
@ -465,9 +503,7 @@ function selectGameFromPlayername(playerName)
|
||||
for (let i = 0; i < g_GameList.length; ++i)
|
||||
for (let player of stringifiedTeamListToPlayerData(g_GameList[i].players))
|
||||
{
|
||||
let result = /^(\S+)\ \(\d+\)$/g.exec(player.Name);
|
||||
let nick = result ? result[1] : player.Name;
|
||||
|
||||
let nick = removeRatingFromNick(player.Name);
|
||||
if (playerName != nick)
|
||||
continue;
|
||||
|
||||
@ -632,7 +668,18 @@ function updateGameList()
|
||||
g_SelectedGamePort = g_GameList[gamesBox.selected].port;
|
||||
}
|
||||
|
||||
g_GameList = Engine.GetGameList().filter(game => !filterGame(game)).sort((a, b) => {
|
||||
g_GameList = Engine.GetGameList().map(game => {
|
||||
game.hasBuddies = 0;
|
||||
for (let player of stringifiedTeamListToPlayerData(game.players))
|
||||
{
|
||||
let nick = removeRatingFromNick(player.Name);
|
||||
|
||||
// Sort games with playing buddies above games with spectating buddies
|
||||
if (game.hasBuddies < 2 && g_Buddies.indexOf(nick) != -1)
|
||||
game.hasBuddies = player.Team == "observer" ? 1 : 2;
|
||||
}
|
||||
return game;
|
||||
}).filter(game => !filterGame(game)).sort((a, b) => {
|
||||
let sortA, sortB;
|
||||
switch (sortBy)
|
||||
{
|
||||
@ -642,6 +689,10 @@ function updateGameList()
|
||||
sortA = a[sortBy];
|
||||
sortB = b[sortBy];
|
||||
break;
|
||||
case 'buddy':
|
||||
sortA = String(b.hasBuddies) + g_GameStatusOrder.indexOf(a.state) + a.name.toLowerCase();
|
||||
sortB = String(a.hasBuddies) + g_GameStatusOrder.indexOf(b.state) + b.name.toLowerCase();
|
||||
break;
|
||||
case 'mapName':
|
||||
sortA = translate(a.niceMapName);
|
||||
sortB = translate(b.niceMapName);
|
||||
@ -661,6 +712,7 @@ function updateGameList()
|
||||
return 0;
|
||||
});
|
||||
|
||||
let list_buddy = [];
|
||||
let list_name = [];
|
||||
let list_mapName = [];
|
||||
let list_mapSize = [];
|
||||
@ -679,6 +731,7 @@ function updateGameList()
|
||||
if (game.ip == g_SelectedGameIP && game.port == g_SelectedGamePort)
|
||||
selectedGameIndex = +i;
|
||||
|
||||
list_buddy.push(game.hasBuddies ? '[color="' + g_GameColors[game.state] + '"]' + g_BuddySymbol + '[/color]' : "");
|
||||
list_name.push('[color="' + g_GameColors[game.state] + '"]' + gameName);
|
||||
list_mapName.push(translateMapTitle(game.niceMapName));
|
||||
list_mapSize.push(translateMapSize(game.mapSize));
|
||||
@ -688,6 +741,7 @@ function updateGameList()
|
||||
list_data.push(i);
|
||||
}
|
||||
|
||||
gamesBox.list_buddy = list_buddy;
|
||||
gamesBox.list_name = list_name;
|
||||
gamesBox.list_mapName = list_mapName;
|
||||
gamesBox.list_mapSize = list_mapSize;
|
||||
|
@ -23,7 +23,7 @@
|
||||
</action>
|
||||
|
||||
<!-- Left panel: Player list. -->
|
||||
<object name="leftPanel" size="20 30 20% 100%-280">
|
||||
<object name="leftPanel" size="20 30 20% 100%-310">
|
||||
<object name="playersBox"
|
||||
style="ModernList"
|
||||
sprite_asc="ModernArrowDown"
|
||||
@ -36,10 +36,11 @@
|
||||
size="0 0 100% 100%"
|
||||
font="sans-bold-stroke-13"
|
||||
>
|
||||
<column id="buddy" width="12"/>
|
||||
<column id="status" width="26%">
|
||||
<translatableAttribute id="heading">Status</translatableAttribute>
|
||||
</column>
|
||||
<column id="name" width="48%">
|
||||
<column id="name" width="45%-12">
|
||||
<translatableAttribute id="heading">Name</translatableAttribute>
|
||||
</column>
|
||||
<column id="rating" width="26%">
|
||||
@ -51,10 +52,11 @@
|
||||
<action on="SelectionColumnChange">
|
||||
updatePlayerList();
|
||||
</action>
|
||||
<action on="mouseleftdoubleclickitem">toggleBuddy();</action>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="profilePanel" size="20 100%-275 20% 100%-80">
|
||||
<object name="profilePanel" size="20 100%-305 20% 100%-110">
|
||||
<object name="profileBox" type="image" sprite="ModernDarkBoxGold" size="0 0 100% 100%">
|
||||
<object name="profileArea" size="0 0 100% 100%" hidden="true">
|
||||
<object name="usernameText" size="0 0 100% 45" type="text" style="ModernLabelText" text_align="center" font="sans-bold-16" />
|
||||
@ -87,8 +89,14 @@
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="leftButtonPanel" size="20 100%-75 20% 100%-20">
|
||||
<object name="leaderboardButton" type="button" style="ModernButtonRed" size="0 0 100% 25">
|
||||
<object name="leftButtonPanel" size="20 100%-105 20% 100%-20">
|
||||
<object name="toggleBuddy" type="button" style="ModernButtonRed" size="0 100%-85 100% 100%-60">
|
||||
<translatableAttribute id="caption" comment="Toggle Buddy">Toggle Buddy</translatableAttribute>
|
||||
<action on="Press">
|
||||
toggleBuddy();
|
||||
</action>
|
||||
</object>
|
||||
<object name="leaderboardButton" type="button" style="ModernButtonRed" size="0 100%-55 100% 100%-30">
|
||||
<translatableAttribute id="caption">Leaderboard</translatableAttribute>
|
||||
<action on="Press">
|
||||
Engine.SendGetBoardList();
|
||||
@ -97,7 +105,7 @@
|
||||
displayProfile("leaderboard");
|
||||
</action>
|
||||
</object>
|
||||
<object name="userprofileButton" type="button" style="ModernButtonRed" size="0 30 100% 100%">
|
||||
<object name="userprofileButton" type="button" style="ModernButtonRed" size="0 100%-25 100% 100%">
|
||||
<translatableAttribute id="caption">User Profile Lookup</translatableAttribute>
|
||||
<action on="Press">
|
||||
Engine.GetGUIObjectByName("profileFetch").hidden = false;
|
||||
@ -199,7 +207,8 @@
|
||||
<action on="SelectionChange">updateGameSelection();</action>
|
||||
<action on="SelectionColumnChange">applyFilters();</action>
|
||||
<action on="mouseleftdoubleclickitem">joinButton();</action>
|
||||
<column id="name" color="0 60 0" width="27%">
|
||||
<column id="buddy" width="12"/>
|
||||
<column id="name" color="0 60 0" width="27%-12">
|
||||
<translatableAttribute id="heading">Name</translatableAttribute>
|
||||
</column>
|
||||
<column id="mapName" color="128 128 128" width="25%">
|
||||
|
Loading…
Reference in New Issue
Block a user