Merge pull request #3158 from pchote/diy-pings
Rewrite ingame ping implementation.
This commit is contained in:
@@ -199,7 +199,12 @@ namespace OpenRA
|
||||
{
|
||||
return new Order("HandshakeResponse", null, false) { IsImmediate = true, TargetString = text };
|
||||
}
|
||||
|
||||
|
||||
public static Order Pong(string pingTime)
|
||||
{
|
||||
return new Order("Pong", null, false) { IsImmediate = true, TargetString = pingTime };
|
||||
}
|
||||
|
||||
public static Order PauseGame(bool paused)
|
||||
{
|
||||
return new Order("PauseGame", null, false) { TargetString = paused ? "Pause" : "UnPause" };
|
||||
|
||||
@@ -62,6 +62,8 @@ namespace OpenRA.Network
|
||||
public bool IsReady { get { return State == ClientState.Ready; } }
|
||||
public bool IsObserver { get { return Slot == null; } }
|
||||
public int Ping = -1;
|
||||
public int PingJitter = -1;
|
||||
public int[] PingHistory = {};
|
||||
}
|
||||
|
||||
public class Slot
|
||||
|
||||
@@ -190,6 +190,11 @@ namespace OpenRA.Network
|
||||
Game.Debug("{0} has reciprocated",targetPlayer.PlayerName);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "Ping":
|
||||
{
|
||||
orderManager.IssueOrder(Order.Pong(order.TargetString));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -25,8 +25,6 @@ namespace OpenRA.Server
|
||||
public int ExpectLength = 8;
|
||||
public int Frame = 0;
|
||||
public int MostRecentFrame = 0;
|
||||
public string RemoteAddress;
|
||||
public int Latency = -1;
|
||||
|
||||
/* client data */
|
||||
public int PlayerIndex;
|
||||
@@ -101,34 +99,6 @@ namespace OpenRA.Server
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool hasBeenPinged;
|
||||
public void Ping()
|
||||
{
|
||||
if (!hasBeenPinged)
|
||||
{
|
||||
hasBeenPinged = true;
|
||||
var pingSender = new Ping();
|
||||
pingSender.PingCompleted += new PingCompletedEventHandler(pongRecieved);
|
||||
AutoResetEvent waiter = new AutoResetEvent(false);
|
||||
pingSender.SendAsync(RemoteAddress, waiter);
|
||||
}
|
||||
}
|
||||
|
||||
void pongRecieved(object sender, PingCompletedEventArgs e)
|
||||
{
|
||||
if (e.Cancelled || e.Error != null)
|
||||
Latency = -1;
|
||||
else
|
||||
{
|
||||
PingReply pong = e.Reply;
|
||||
if (pong != null && pong.Status == IPStatus.Success)
|
||||
Latency = (int)pong.RoundtripTime;
|
||||
else
|
||||
Latency = -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum ReceiveState { Header, Data };
|
||||
|
||||
@@ -59,8 +59,6 @@ namespace OpenRA.Server
|
||||
public Map Map;
|
||||
XTimer gameTimeout;
|
||||
|
||||
int highestLatency;
|
||||
|
||||
protected volatile ServerState pState = new ServerState();
|
||||
public ServerState State
|
||||
{
|
||||
@@ -217,9 +215,6 @@ namespace OpenRA.Server
|
||||
DispatchOrdersToClient(newConn, 0, 0, new ServerOrder("HandshakeRequest", request.Serialize()).Serialize());
|
||||
}
|
||||
catch (Exception) { DropClient(newConn); }
|
||||
|
||||
newConn.RemoteAddress = ((IPEndPoint)newConn.socket.RemoteEndPoint).Address.ToString();
|
||||
newConn.Ping();
|
||||
}
|
||||
|
||||
void ValidateClient(Connection newConn, string data)
|
||||
@@ -271,7 +266,8 @@ namespace OpenRA.Server
|
||||
// Check if IP is banned
|
||||
if (lobbyInfo.GlobalSettings.Ban != null)
|
||||
{
|
||||
if (lobbyInfo.GlobalSettings.Ban.Contains(newConn.RemoteAddress))
|
||||
var remote_addr = ((IPEndPoint)newConn.socket.RemoteEndPoint).Address.ToString();
|
||||
if (lobbyInfo.GlobalSettings.Ban.Contains(remote_addr))
|
||||
{
|
||||
Console.WriteLine("Rejected connection from "+client.Name+"("+newConn.socket.RemoteEndPoint+"); Banned.");
|
||||
Log.Write("server", "Rejected connection from {0}; Banned.",
|
||||
@@ -286,8 +282,6 @@ namespace OpenRA.Server
|
||||
preConns.Remove(newConn);
|
||||
conns.Add(newConn);
|
||||
|
||||
client.Ping = newConn.Latency;
|
||||
|
||||
// Enforce correct PlayerIndex and Slot
|
||||
client.Index = newConn.PlayerIndex;
|
||||
client.Slot = lobbyInfo.FirstEmptySlot();
|
||||
@@ -296,22 +290,24 @@ namespace OpenRA.Server
|
||||
SyncClientToPlayerReference(client, Map.Players[client.Slot]);
|
||||
|
||||
lobbyInfo.Clients.Add(client);
|
||||
//Assume that first validated client is server admin
|
||||
if(lobbyInfo.Clients.Where(c1 => c1.Bot == null).Count()==1)
|
||||
|
||||
// Assume that first validated client is server admin
|
||||
if (lobbyInfo.Clients.Where(c1 => c1.Bot == null).Count() == 1)
|
||||
client.IsAdmin=true;
|
||||
|
||||
OpenRA.Network.Session.Client clientAdmin = lobbyInfo.Clients.Where(c1 => c1.IsAdmin).Single();
|
||||
|
||||
Log.Write("server", "Client {0}: Accepted connection from {1} with {2} ms ping latency.",
|
||||
newConn.PlayerIndex, newConn.socket.RemoteEndPoint, newConn.Latency);
|
||||
Log.Write("server", "Client {0}: Accepted connection from {1}.",
|
||||
newConn.PlayerIndex, newConn.socket.RemoteEndPoint);
|
||||
|
||||
foreach (var t in ServerTraits.WithInterface<IClientJoined>())
|
||||
t.ClientJoined(this, newConn);
|
||||
|
||||
SyncLobbyInfo();
|
||||
SendChat(newConn, "has joined the game.");
|
||||
|
||||
SetDynamicOrderLag();
|
||||
SyncLobbyInfo();
|
||||
// Send initial ping
|
||||
SendOrderTo(newConn, "Ping", Environment.TickCount.ToString());
|
||||
|
||||
if (File.Exists("{0}motd_{1}.txt".F(Platform.SupportDir, lobbyInfo.GlobalSettings.Mods[0])))
|
||||
{
|
||||
@@ -464,6 +460,31 @@ namespace OpenRA.Server
|
||||
foreach (var c in conns.Except(conn).ToArray())
|
||||
DispatchOrdersToClient(c, fromIndex, 0, so.Serialize());
|
||||
break;
|
||||
case "Pong":
|
||||
{
|
||||
int pingSent;
|
||||
if (!int.TryParse(so.Data, out pingSent))
|
||||
{
|
||||
Log.Write("server", "Invalid order pong payload: {0}", so.Data);
|
||||
break;
|
||||
}
|
||||
|
||||
var history = fromClient.PingHistory.ToList();
|
||||
history.Add(Environment.TickCount - pingSent);
|
||||
|
||||
// Cap ping history at 5 values (25 seconds)
|
||||
if (history.Count > 5)
|
||||
history.RemoveRange(0, history.Count - 5);
|
||||
|
||||
fromClient.Ping = history.Sum() / history.Count;
|
||||
fromClient.PingJitter = (history.Max() - history.Min())/2;
|
||||
fromClient.PingHistory = history.ToArray();
|
||||
|
||||
if (State == ServerState.WaitingPlayers)
|
||||
SyncLobbyInfo();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -503,9 +524,6 @@ namespace OpenRA.Server
|
||||
}
|
||||
}
|
||||
|
||||
if (highestLatency == toDrop.Latency)
|
||||
SetDynamicOrderLag();
|
||||
|
||||
DispatchOrders( toDrop, toDrop.MostRecentFrame, new byte[] { 0xbf } );
|
||||
|
||||
if (conns.Count != 0 || lobbyInfo.GlobalSettings.Dedicated)
|
||||
@@ -521,23 +539,6 @@ namespace OpenRA.Server
|
||||
catch { }
|
||||
}
|
||||
|
||||
public void SetDynamicOrderLag()
|
||||
{
|
||||
foreach (var conn in conns)
|
||||
{
|
||||
if (conn.Latency > highestLatency)
|
||||
highestLatency = conn.Latency;
|
||||
}
|
||||
|
||||
Log.Write("server", "Measured {0} ms as the highest connection round trip time.".F(highestLatency));
|
||||
|
||||
lobbyInfo.GlobalSettings.OrderLatency = highestLatency / 120;
|
||||
if (lobbyInfo.GlobalSettings.OrderLatency < 1) // should never be 0
|
||||
lobbyInfo.GlobalSettings.OrderLatency = 1;
|
||||
|
||||
Log.Write("server", "Order lag has been adjusted to {0} frames.".F(lobbyInfo.GlobalSettings.OrderLatency));
|
||||
}
|
||||
|
||||
public void SyncLobbyInfo()
|
||||
{
|
||||
if (State != ServerState.GameStarted) /* don't do this while the game is running, it breaks things. */
|
||||
|
||||
@@ -138,7 +138,7 @@ namespace OpenRA.Widgets
|
||||
{
|
||||
var owned = colors.ContainsKey(p);
|
||||
var pos = ConvertToPreview(p);
|
||||
var sprite = ChromeProvider.GetImage("spawnpoints", owned ? "owned" : "unowned");
|
||||
var sprite = ChromeProvider.GetImage("lobby-bits", owned ? "spawn-claimed" : "spawn-unclaimed");
|
||||
var offset = new int2(-sprite.bounds.Width/2, -sprite.bounds.Height/2);
|
||||
|
||||
if (owned)
|
||||
|
||||
@@ -429,6 +429,7 @@
|
||||
<Compile Include="Activities\RepairBridge.cs" />
|
||||
<Compile Include="BridgeHut.cs" />
|
||||
<Compile Include="Lint\CheckSequences.cs" />
|
||||
<Compile Include="ServerTraits\PlayerPinger.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
||||
|
||||
@@ -100,22 +100,6 @@ namespace OpenRA.Mods.RA.Server
|
||||
server.StartGame();
|
||||
return true;
|
||||
}},
|
||||
{ "lag",
|
||||
s =>
|
||||
{
|
||||
int lag;
|
||||
if (!int.TryParse(s, out lag))
|
||||
{
|
||||
Log.Write("server", "Invalid order lag: {0}", s);
|
||||
return false;
|
||||
}
|
||||
|
||||
Log.Write("server", "Order lag is now {0} frames.", lag);
|
||||
|
||||
server.lobbyInfo.GlobalSettings.OrderLatency = lag;
|
||||
server.SyncLobbyInfo();
|
||||
return true;
|
||||
}},
|
||||
{ "slot",
|
||||
s =>
|
||||
{
|
||||
|
||||
41
OpenRA.Mods.RA/ServerTraits/PlayerPinger.cs
Normal file
41
OpenRA.Mods.RA/ServerTraits/PlayerPinger.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using OpenRA.Server;
|
||||
using OpenRA.Network;
|
||||
using S = OpenRA.Server.Server;
|
||||
|
||||
namespace OpenRA.Mods.RA.Server
|
||||
{
|
||||
public class PlayerPinger : ServerTrait, ITick
|
||||
{
|
||||
int PingInterval = 5000; // Ping every 5 seconds
|
||||
|
||||
// TickTimeout is in microseconds
|
||||
public int TickTimeout { get { return PingInterval * 100; } }
|
||||
|
||||
int lastPing = 0;
|
||||
bool isInitialPing = true;
|
||||
public void Tick(S server)
|
||||
{
|
||||
if ((Environment.TickCount - lastPing > PingInterval) || isInitialPing)
|
||||
{
|
||||
isInitialPing = false;
|
||||
lastPing = Environment.TickCount;
|
||||
foreach (var p in server.conns)
|
||||
server.SendOrderTo(p, "Ping", Environment.TickCount.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,20 +162,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
};
|
||||
mapButton.IsVisible = () => mapButton.Visible && Game.IsHost;
|
||||
|
||||
var randomMapButton = lobby.GetOrNull<ButtonWidget>("RANDOMMAP_BUTTON");
|
||||
var maps = Game.modData.AvailableMaps.Where(m => m.Value.Selectable).ToArray();
|
||||
if (randomMapButton != null && maps.Any())
|
||||
{
|
||||
randomMapButton.OnClick = () =>
|
||||
{
|
||||
var mapUid = maps.Random(Game.CosmeticRandom).Key;
|
||||
orderManager.IssueOrder(Order.Command("map " + mapUid));
|
||||
Game.Settings.Server.Map = mapUid;
|
||||
Game.Settings.Save();
|
||||
};
|
||||
randomMapButton.IsVisible = () => mapButton.Visible && Game.IsHost;
|
||||
}
|
||||
|
||||
var assignTeams = lobby.GetOrNull<DropDownButtonWidget>("ASSIGNTEAMS_DROPDOWNBUTTON");
|
||||
if (assignTeams != null)
|
||||
{
|
||||
@@ -377,7 +363,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
|
||||
// get template for possible reuse
|
||||
if (idx < Players.Children.Count)
|
||||
template = Players.Children [idx];
|
||||
template = Players.Children[idx];
|
||||
|
||||
// Empty slot
|
||||
if (client == null)
|
||||
@@ -385,29 +371,17 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
if (template == null || template.Id != EmptySlotTemplate.Id)
|
||||
template = EmptySlotTemplate.Clone();
|
||||
|
||||
Func<string> getText = () => slot.Closed ? "Closed" : "Open";
|
||||
var ready = orderManager.LocalClient.IsReady;
|
||||
|
||||
if (Game.IsHost)
|
||||
{
|
||||
var name = template.Get<DropDownButtonWidget>("NAME_HOST");
|
||||
name.IsVisible = () => true;
|
||||
name.IsDisabled = () => ready;
|
||||
name.GetText = getText;
|
||||
name.OnMouseDown = _ => LobbyUtils.ShowSlotDropDown(name, slot, client, orderManager);
|
||||
}
|
||||
LobbyUtils.SetupEditableSlotWidget(template, slot, client, orderManager);
|
||||
else
|
||||
{
|
||||
var name = template.Get<LabelWidget>("NAME");
|
||||
name.IsVisible = () => true;
|
||||
name.GetText = getText;
|
||||
}
|
||||
LobbyUtils.SetupSlotWidget(template, slot, client);
|
||||
|
||||
var join = template.Get<ButtonWidget>("JOIN");
|
||||
join.IsVisible = () => !slot.Closed;
|
||||
join.IsDisabled = () => ready;
|
||||
join.IsDisabled = () => orderManager.LocalClient.IsReady;
|
||||
join.OnClick = () => orderManager.IssueOrder(Order.Command("slot " + key));
|
||||
}
|
||||
|
||||
// Editable player in slot
|
||||
else if ((client.Index == orderManager.LocalClient.Index) ||
|
||||
(client.Bot != null && Game.IsHost))
|
||||
@@ -415,92 +389,33 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
if (template == null || template.Id != EditablePlayerTemplate.Id)
|
||||
template = EditablePlayerTemplate.Clone();
|
||||
|
||||
var botReady = client.Bot != null && Game.IsHost && orderManager.LocalClient.IsReady;
|
||||
var ready = botReady || client.IsReady;
|
||||
LobbyUtils.SetupAdminPingWidget(template, slot, client, orderManager, client.Bot == null);
|
||||
|
||||
if (client.Bot != null)
|
||||
{
|
||||
var name = template.Get<DropDownButtonWidget>("BOT_DROPDOWN");
|
||||
name.IsVisible = () => true;
|
||||
name.IsDisabled = () => ready;
|
||||
name.GetText = () => client.Name;
|
||||
name.OnMouseDown = _ => LobbyUtils.ShowSlotDropDown(name, slot, client, orderManager);
|
||||
}
|
||||
LobbyUtils.SetupEditableSlotWidget(template, slot, client, orderManager);
|
||||
else
|
||||
{
|
||||
var name = template.Get<TextFieldWidget>("NAME");
|
||||
name.IsVisible = () => true;
|
||||
name.IsDisabled = () => ready;
|
||||
LobbyUtils.SetupNameWidget(orderManager, client, name);
|
||||
}
|
||||
LobbyUtils.SetupEditableNameWidget(template, slot, client, orderManager);
|
||||
|
||||
var color = template.Get<DropDownButtonWidget>("COLOR");
|
||||
color.IsDisabled = () => slot.LockColor || ready;
|
||||
color.OnMouseDown = _ => LobbyUtils.ShowColorDropDown(color, client, orderManager, colorPreview);
|
||||
|
||||
var colorBlock = color.Get<ColorBlockWidget>("COLORBLOCK");
|
||||
colorBlock.GetColor = () => client.ColorRamp.GetColor(0);
|
||||
|
||||
var faction = template.Get<DropDownButtonWidget>("FACTION");
|
||||
faction.IsDisabled = () => slot.LockRace || ready;
|
||||
faction.OnMouseDown = _ => LobbyUtils.ShowRaceDropDown(faction, client, orderManager, CountryNames);
|
||||
|
||||
var factionname = faction.Get<LabelWidget>("FACTIONNAME");
|
||||
factionname.GetText = () => CountryNames[client.Country];
|
||||
var factionflag = faction.Get<ImageWidget>("FACTIONFLAG");
|
||||
factionflag.GetImageName = () => client.Country;
|
||||
factionflag.GetImageCollection = () => "flags";
|
||||
|
||||
var team = template.Get<DropDownButtonWidget>("TEAM");
|
||||
team.IsDisabled = () => slot.LockTeam || ready;
|
||||
team.OnMouseDown = _ => LobbyUtils.ShowTeamDropDown(team, client, orderManager, Map);
|
||||
team.GetText = () => (client.Team == 0) ? "-" : client.Team.ToString();
|
||||
LobbyUtils.SetupEditableColorWidget(template, slot, client, orderManager, colorPreview);
|
||||
LobbyUtils.SetupEditableFactionWidget(template, slot, client, orderManager, CountryNames);
|
||||
LobbyUtils.SetupEditableTeamWidget(template, slot, client, orderManager, Map.GetSpawnPoints().Length);
|
||||
LobbyUtils.SetupEditableReadyWidget(template, slot, client, orderManager);
|
||||
|
||||
if (slot.LockTeam || client.Team > 0)
|
||||
TeamGame = true;
|
||||
|
||||
if (client.Bot == null)
|
||||
{
|
||||
// local player
|
||||
var status = template.Get<CheckboxWidget>("STATUS_CHECKBOX");
|
||||
status.IsChecked = () => ready;
|
||||
status.IsVisible = () => true;
|
||||
status.OnClick = CycleReady;
|
||||
}
|
||||
else // Bot
|
||||
template.Get<ImageWidget>("STATUS_IMAGE").IsVisible = () => true;
|
||||
}
|
||||
else
|
||||
{ // Non-editable player in slot
|
||||
if (template == null || template.Id != NonEditablePlayerTemplate.Id)
|
||||
template = NonEditablePlayerTemplate.Clone();
|
||||
|
||||
template.Get<LabelWidget>("NAME").GetText = () => client.Name;
|
||||
if (client.IsAdmin)
|
||||
template.Get<LabelWidget>("NAME").Font = "Bold";
|
||||
if (client.Ping > -1)
|
||||
template.Get<LabelWidget>("NAME").GetColor = () => LobbyUtils.GetPingColor(client.Ping);
|
||||
|
||||
var color = template.Get<ColorBlockWidget>("COLOR");
|
||||
color.GetColor = () => client.ColorRamp.GetColor(0);
|
||||
|
||||
var faction = template.Get<LabelWidget>("FACTION");
|
||||
var factionname = faction.Get<LabelWidget>("FACTIONNAME");
|
||||
factionname.GetText = () => CountryNames[client.Country];
|
||||
var factionflag = faction.Get<ImageWidget>("FACTIONFLAG");
|
||||
factionflag.GetImageName = () => client.Country;
|
||||
factionflag.GetImageCollection = () => "flags";
|
||||
|
||||
var team = template.Get<LabelWidget>("TEAM");
|
||||
team.GetText = () => (client.Team == 0) ? "-" : client.Team.ToString();
|
||||
|
||||
template.Get<ImageWidget>("STATUS_IMAGE").IsVisible = () =>
|
||||
client.Bot != null || client.IsReady;
|
||||
|
||||
var kickButton = template.Get<ButtonWidget>("KICK");
|
||||
kickButton.IsVisible = () => Game.IsHost && client.Index != orderManager.LocalClient.Index;
|
||||
kickButton.IsDisabled = () => orderManager.LocalClient.IsReady;
|
||||
kickButton.OnClick = () => orderManager.IssueOrder(Order.Command("kick " + client.Index));
|
||||
LobbyUtils.SetupAdminPingWidget(template, slot, client, orderManager, client.Bot == null);
|
||||
LobbyUtils.SetupNameWidget(template, slot, client);
|
||||
LobbyUtils.SetupKickWidget(template, slot, client, orderManager);
|
||||
LobbyUtils.SetupColorWidget(template, slot, client);
|
||||
LobbyUtils.SetupFactionWidget(template, slot, client, CountryNames);
|
||||
LobbyUtils.SetupTeamWidget(template, slot, client);
|
||||
LobbyUtils.SetupReadyWidget(template, slot, client);
|
||||
}
|
||||
|
||||
template.IsVisible = () => true;
|
||||
@@ -518,7 +433,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
{
|
||||
Widget template = null;
|
||||
var c = client;
|
||||
var ready = c.IsReady;
|
||||
|
||||
// get template for possible reuse
|
||||
if (idx < Players.Children.Count)
|
||||
@@ -530,20 +444,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
if (template == null || template.Id != EditableSpectatorTemplate.Id)
|
||||
template = EditableSpectatorTemplate.Clone();
|
||||
|
||||
var name = template.Get<TextFieldWidget>("NAME");
|
||||
name.IsDisabled = () => ready;
|
||||
LobbyUtils.SetupNameWidget(orderManager, c, name);
|
||||
|
||||
var color = template.Get<DropDownButtonWidget>("COLOR");
|
||||
color.IsDisabled = () => ready;
|
||||
color.OnMouseDown = _ => LobbyUtils.ShowColorDropDown(color, c, orderManager, colorPreview);
|
||||
|
||||
var colorBlock = color.Get<ColorBlockWidget>("COLORBLOCK");
|
||||
colorBlock.GetColor = () => c.ColorRamp.GetColor(0);
|
||||
|
||||
var status = template.Get<CheckboxWidget>("STATUS_CHECKBOX");
|
||||
status.IsChecked = () => ready;
|
||||
status.OnClick = CycleReady;
|
||||
LobbyUtils.SetupEditableNameWidget(template, null, c, orderManager);
|
||||
LobbyUtils.SetupEditableColorWidget(template, null, c, orderManager, colorPreview);
|
||||
LobbyUtils.SetupEditableReadyWidget(template, null, client, orderManager);
|
||||
}
|
||||
// Non-editable spectator
|
||||
else
|
||||
@@ -551,20 +454,13 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
if (template == null || template.Id != NonEditableSpectatorTemplate.Id)
|
||||
template = NonEditableSpectatorTemplate.Clone();
|
||||
|
||||
template.Get<LabelWidget>("NAME").GetText = () => c.Name;
|
||||
if (client.IsAdmin)
|
||||
template.Get<LabelWidget>("NAME").Font = "Bold";
|
||||
var color = template.Get<ColorBlockWidget>("COLOR");
|
||||
color.GetColor = () => c.ColorRamp.GetColor(0);
|
||||
|
||||
template.Get<ImageWidget>("STATUS_IMAGE").IsVisible = () => c.Bot != null || c.IsReady;
|
||||
|
||||
var kickButton = template.Get<ButtonWidget>("KICK");
|
||||
kickButton.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index;
|
||||
kickButton.IsDisabled = () => orderManager.LocalClient.IsReady;
|
||||
kickButton.OnClick = () => orderManager.IssueOrder(Order.Command("kick " + c.Index));
|
||||
LobbyUtils.SetupNameWidget(template, null, client);
|
||||
LobbyUtils.SetupKickWidget(template, null, client, orderManager);
|
||||
LobbyUtils.SetupColorWidget(template, null, client);
|
||||
LobbyUtils.SetupReadyWidget(template, null, client);
|
||||
}
|
||||
|
||||
LobbyUtils.SetupAdminPingWidget(template, null, c, orderManager, true);
|
||||
template.IsVisible = () => true;
|
||||
|
||||
if (idx >= Players.Children.Count)
|
||||
@@ -575,7 +471,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
idx++;
|
||||
}
|
||||
|
||||
|
||||
// Spectate button
|
||||
if (orderManager.LocalClient.Slot != null)
|
||||
{
|
||||
@@ -602,11 +497,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
Players.RemoveChild(Players.Children[idx]);
|
||||
}
|
||||
|
||||
void CycleReady()
|
||||
{
|
||||
orderManager.IssueOrder(Order.Command("ready"));
|
||||
}
|
||||
|
||||
class DropDownOption
|
||||
{
|
||||
public string Title;
|
||||
|
||||
@@ -21,31 +21,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
{
|
||||
public static class LobbyUtils
|
||||
{
|
||||
public static void SetupNameWidget(OrderManager orderManager, Session.Client c, TextFieldWidget name)
|
||||
{
|
||||
if (c.IsAdmin)
|
||||
name.Font = "Bold";
|
||||
name.Text = c.Name;
|
||||
if (c.Ping > -1)
|
||||
name.TextColor = GetPingColor(c.Ping);
|
||||
name.OnEnterKey = () =>
|
||||
{
|
||||
name.Text = name.Text.Trim();
|
||||
if (name.Text.Length == 0)
|
||||
name.Text = c.Name;
|
||||
|
||||
name.LoseFocus();
|
||||
if (name.Text == c.Name)
|
||||
return true;
|
||||
|
||||
orderManager.IssueOrder(Order.Command("name " + name.Text));
|
||||
Game.Settings.Player.Name = name.Text;
|
||||
Game.Settings.Save();
|
||||
return true;
|
||||
};
|
||||
name.OnLoseFocus = () => name.OnEnterKey();
|
||||
}
|
||||
|
||||
class SlotDropDownOption
|
||||
{
|
||||
public string Title;
|
||||
@@ -92,7 +67,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
}
|
||||
|
||||
public static void ShowTeamDropDown(DropDownButtonWidget dropdown, Session.Client client,
|
||||
OrderManager orderManager, Map map)
|
||||
OrderManager orderManager, int teamCount)
|
||||
{
|
||||
Func<int, ScrollItemWidget, ScrollItemWidget> setupItem = (ii, itemTemplate) =>
|
||||
{
|
||||
@@ -103,7 +78,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
return item;
|
||||
};
|
||||
|
||||
var options = Exts.MakeArray(map.GetSpawnPoints().Length + 1, i => i).ToList();
|
||||
var options = Exts.MakeArray(teamCount + 1, i => i).ToList();
|
||||
dropdown.ShowDropDown("TEAM_DROPDOWN_TEMPLATE", 150, options, setupItem);
|
||||
}
|
||||
|
||||
@@ -192,13 +167,151 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
}
|
||||
}
|
||||
|
||||
public static Color GetPingColor(int ping)
|
||||
static Color GetPingColor(Session.Client c)
|
||||
{
|
||||
if (ping > 720) // OrderLag > 6
|
||||
if (c.Ping < 0) // Ping unknown
|
||||
return Color.Gray;
|
||||
if (c.Ping > 720) // OrderLag > 6
|
||||
return Color.Red;
|
||||
if (ping > 360) // OrderLag > 3
|
||||
if (c.Ping > 360) // OrderLag > 3
|
||||
return Color.Orange;
|
||||
|
||||
return Color.LimeGreen;
|
||||
}
|
||||
|
||||
public static void SetupAdminPingWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, bool visible)
|
||||
{
|
||||
parent.Get("ADMIN_INDICATOR").IsVisible = () => c.IsAdmin;
|
||||
var block = parent.Get("PING_BLOCK");
|
||||
block.IsVisible = () => visible;
|
||||
|
||||
if (visible)
|
||||
block.Get<ColorBlockWidget>("PING_COLOR").GetColor = () => GetPingColor(c);
|
||||
}
|
||||
|
||||
public static void SetupEditableNameWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager)
|
||||
{
|
||||
var name = parent.Get<TextFieldWidget>("NAME");
|
||||
name.IsVisible = () => true;
|
||||
name.IsDisabled = () => orderManager.LocalClient.IsReady;
|
||||
|
||||
name.Text = c.Name;
|
||||
name.OnEnterKey = () =>
|
||||
{
|
||||
name.Text = name.Text.Trim();
|
||||
if (name.Text.Length == 0)
|
||||
name.Text = c.Name;
|
||||
|
||||
name.LoseFocus();
|
||||
if (name.Text == c.Name)
|
||||
return true;
|
||||
|
||||
orderManager.IssueOrder(Order.Command("name " + name.Text));
|
||||
Game.Settings.Player.Name = name.Text;
|
||||
Game.Settings.Save();
|
||||
return true;
|
||||
};
|
||||
|
||||
name.OnLoseFocus = () => name.OnEnterKey();
|
||||
}
|
||||
|
||||
public static void SetupNameWidget(Widget parent, Session.Slot s, Session.Client c)
|
||||
{
|
||||
var name = parent.Get<LabelWidget>("NAME");
|
||||
name.GetText = () => c.Name;
|
||||
}
|
||||
|
||||
public static void SetupEditableSlotWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager)
|
||||
{
|
||||
var slot = parent.Get<DropDownButtonWidget>("SLOT_OPTIONS");
|
||||
slot.IsVisible = () => true;
|
||||
slot.IsDisabled = () => orderManager.LocalClient.IsReady;
|
||||
slot.GetText = () => c != null ? c.Name : s.Closed ? "Closed" : "Open";
|
||||
slot.OnMouseDown = _ => LobbyUtils.ShowSlotDropDown(slot, s, c, orderManager);
|
||||
|
||||
// Ensure Name selector (if present) is hidden
|
||||
var name = parent.GetOrNull("NAME");
|
||||
if (name != null)
|
||||
name.IsVisible = () => false;
|
||||
}
|
||||
|
||||
public static void SetupSlotWidget(Widget parent, Session.Slot s, Session.Client c)
|
||||
{
|
||||
var name = parent.Get<LabelWidget>("NAME");
|
||||
name.IsVisible = () => true;
|
||||
name.GetText = () => c != null ? c.Name : s.Closed ? "Closed" : "Open";
|
||||
|
||||
// Ensure Slot selector (if present) is hidden
|
||||
var slot = parent.GetOrNull("SLOT_OPTIONS");
|
||||
if (slot != null)
|
||||
slot.IsVisible = () => false;
|
||||
}
|
||||
|
||||
public static void SetupKickWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager)
|
||||
{
|
||||
var button = parent.Get<ButtonWidget>("KICK");
|
||||
button.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index;
|
||||
button.IsDisabled = () => orderManager.LocalClient.IsReady;
|
||||
button.OnClick = () => orderManager.IssueOrder(Order.Command("kick " + c.Index));
|
||||
}
|
||||
|
||||
public static void SetupEditableColorWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, ColorPreviewManagerWidget colorPreview)
|
||||
{
|
||||
var color = parent.Get<DropDownButtonWidget>("COLOR");
|
||||
color.IsDisabled = () => (s != null && s.LockColor) || orderManager.LocalClient.IsReady;
|
||||
color.OnMouseDown = _ => LobbyUtils.ShowColorDropDown(color, c, orderManager, colorPreview);
|
||||
|
||||
SetupColorWidget(color, s, c);
|
||||
}
|
||||
|
||||
public static void SetupColorWidget(Widget parent, Session.Slot s, Session.Client c)
|
||||
{
|
||||
var color = parent.Get<ColorBlockWidget>("COLORBLOCK");
|
||||
color.GetColor = () => c.ColorRamp.GetColor(0);
|
||||
}
|
||||
|
||||
public static void SetupEditableFactionWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, Dictionary<string,string> countryNames)
|
||||
{
|
||||
var dropdown = parent.Get<DropDownButtonWidget>("FACTION");
|
||||
dropdown.IsDisabled = () => s.LockRace || orderManager.LocalClient.IsReady;
|
||||
dropdown.OnMouseDown = _ => LobbyUtils.ShowRaceDropDown(dropdown, c, orderManager, countryNames);
|
||||
SetupFactionWidget(dropdown, s, c, countryNames);
|
||||
}
|
||||
|
||||
public static void SetupFactionWidget(Widget parent, Session.Slot s, Session.Client c, Dictionary<string,string> countryNames)
|
||||
{
|
||||
var factionname = parent.Get<LabelWidget>("FACTIONNAME");
|
||||
factionname.GetText = () => countryNames[c.Country];
|
||||
var factionflag = parent.Get<ImageWidget>("FACTIONFLAG");
|
||||
factionflag.GetImageName = () => c.Country;
|
||||
factionflag.GetImageCollection = () => "flags";
|
||||
}
|
||||
|
||||
public static void SetupEditableTeamWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, int teamCount)
|
||||
{
|
||||
var dropdown = parent.Get<DropDownButtonWidget>("TEAM");
|
||||
dropdown.IsDisabled = () => s.LockTeam || orderManager.LocalClient.IsReady;
|
||||
dropdown.OnMouseDown = _ => LobbyUtils.ShowTeamDropDown(dropdown, c, orderManager, teamCount);
|
||||
dropdown.GetText = () => (c.Team == 0) ? "-" : c.Team.ToString();
|
||||
}
|
||||
|
||||
public static void SetupTeamWidget(Widget parent, Session.Slot s, Session.Client c)
|
||||
{
|
||||
parent.Get<LabelWidget>("TEAM").GetText = () => (c.Team == 0) ? "-" : c.Team.ToString();
|
||||
}
|
||||
|
||||
public static void SetupEditableReadyWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager)
|
||||
{
|
||||
var status = parent.Get<CheckboxWidget>("STATUS_CHECKBOX");
|
||||
status.IsChecked = () => orderManager.LocalClient.IsReady || c.Bot != null;
|
||||
status.IsVisible = () => true;
|
||||
status.IsDisabled = () => c.Bot != null;
|
||||
status.OnClick = () => orderManager.IssueOrder(Order.Command("ready"));
|
||||
}
|
||||
|
||||
public static void SetupReadyWidget(Widget parent, Session.Slot s, Session.Client c)
|
||||
{
|
||||
parent.Get<ImageWidget>("STATUS_IMAGE").IsVisible = () => c.IsReady || c.Bot != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
height="512"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
inkscape:version="0.48.2 r9819"
|
||||
sodipodi:docname="chrome.svg"
|
||||
inkscape:export-filename="/Users/paul/src/OpenRA/mods/cnc/uibits/chrome.png"
|
||||
inkscape:export-xdpi="90"
|
||||
@@ -61,9 +61,9 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2"
|
||||
inkscape:cx="159.47924"
|
||||
inkscape:cy="358.66173"
|
||||
inkscape:zoom="11.313708"
|
||||
inkscape:cx="352.22285"
|
||||
inkscape:cy="474.91804"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
@@ -663,7 +663,7 @@
|
||||
sodipodi:end="6.2831853"
|
||||
sodipodi:start="0.00014815468"
|
||||
transform="matrix(0.90203431,0,0,0.77317229,6.750015,557.2837)"
|
||||
d="m 290.17741,50.543926 a 4.9887238,5.8201776 0 1 1 0,-8.62e-4"
|
||||
d="m 290.17741,50.543926 c -4e-4,3.214396 -2.23426,5.819792 -4.98946,5.819316 -2.75519,-4.77e-4 -4.98839,-2.606645 -4.98798,-5.82104 4e-4,-3.214395 2.23426,-5.819792 4.98946,-5.819315 2.75491,4.76e-4 4.98798,2.606119 4.98798,5.820177"
|
||||
sodipodi:ry="5.8201776"
|
||||
sodipodi:rx="4.9887238"
|
||||
sodipodi:cy="50.543064"
|
||||
@@ -733,7 +733,7 @@
|
||||
sodipodi:cy="50.543064"
|
||||
sodipodi:rx="4.9887238"
|
||||
sodipodi:ry="5.8201776"
|
||||
d="m 290.17741,50.543926 a 4.9887238,5.8201776 0 1 1 0,-8.62e-4"
|
||||
d="m 290.17741,50.543926 c -4e-4,3.214396 -2.23426,5.819792 -4.98946,5.819316 -2.75519,-4.77e-4 -4.98839,-2.606645 -4.98798,-5.82104 4e-4,-3.214395 2.23426,-5.819792 4.98946,-5.819315 2.75491,4.76e-4 4.98798,2.606119 4.98798,5.820177"
|
||||
transform="matrix(0.90203431,0,0,0.77317229,38.750015,525.2837)"
|
||||
sodipodi:start="0.00014815468"
|
||||
sodipodi:end="6.2831853"
|
||||
@@ -1274,5 +1274,13 @@
|
||||
inkscape:export-filename="/Users/paul/src/OpenRA/mods/cnc/uibits/rect3776.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
style="fill:#ffc000;fill-opacity:1;stroke:none"
|
||||
d="m 340,584.3622 0,-5 1.81818,2 2.18182,-2 2.18182,2 1.81818,-2 0,5 z"
|
||||
id="path3179"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
@@ -386,9 +386,10 @@ music: chrome.png
|
||||
next: 256,16,16,16
|
||||
prev: 272,16,16,16
|
||||
|
||||
spawnpoints: chrome.png
|
||||
owned: 256,32,16,16
|
||||
unowned: 256,48,16,16
|
||||
lobby-bits: chrome.png
|
||||
spawn-claimed: 256,32,16,16
|
||||
spawn-unclaimed: 256,48,16,16
|
||||
admin: 340,39,7,5
|
||||
|
||||
checkbox-bits: chrome.png
|
||||
checked: 272,32,16,16
|
||||
|
||||
@@ -68,15 +68,35 @@ Container@SERVER_LOBBY:
|
||||
Height:25
|
||||
Visible:false
|
||||
Children:
|
||||
Image@ADMIN_INDICATOR:
|
||||
ImageCollection:lobby-bits
|
||||
ImageName:admin
|
||||
X:2
|
||||
Visible:false
|
||||
Background@PING_BLOCK:
|
||||
Background:button
|
||||
X:0
|
||||
Y:6
|
||||
Width:11
|
||||
Height:14
|
||||
Visible:false
|
||||
Children:
|
||||
ColorBlock@PING_COLOR:
|
||||
X:2
|
||||
Y:2
|
||||
Width:PARENT_RIGHT-4
|
||||
Height:PARENT_BOTTOM-4
|
||||
TextField@NAME:
|
||||
Text:Name
|
||||
Width:205
|
||||
X:15
|
||||
Width:190
|
||||
Height:25
|
||||
MaxLength:16
|
||||
Visible:false
|
||||
DropDownButton@BOT_DROPDOWN:
|
||||
DropDownButton@SLOT_OPTIONS:
|
||||
Text:Name
|
||||
Width:205
|
||||
X:15
|
||||
Width:190
|
||||
Height:25
|
||||
Font:Regular
|
||||
Visible:false
|
||||
@@ -136,11 +156,29 @@ Container@SERVER_LOBBY:
|
||||
Height:25
|
||||
Visible:false
|
||||
Children:
|
||||
Image@ADMIN_INDICATOR:
|
||||
ImageCollection:lobby-bits
|
||||
ImageName:admin
|
||||
X:2
|
||||
Visible:false
|
||||
Background@PING_BLOCK:
|
||||
Background:button
|
||||
X:0
|
||||
Y:6
|
||||
Width:11
|
||||
Height:14
|
||||
Visible:false
|
||||
Children:
|
||||
ColorBlock@PING_COLOR:
|
||||
X:2
|
||||
Y:2
|
||||
Width:PARENT_RIGHT-4
|
||||
Height:PARENT_BOTTOM-4
|
||||
Label@NAME:
|
||||
Text:Name
|
||||
Width:200
|
||||
Width:185
|
||||
Height:25
|
||||
X:5
|
||||
X:15
|
||||
Y:0-1
|
||||
Button@KICK:
|
||||
Text:X
|
||||
@@ -149,12 +187,12 @@ Container@SERVER_LOBBY:
|
||||
X:180
|
||||
Y:2
|
||||
Font:Bold
|
||||
ColorBlock@COLOR:
|
||||
ColorBlock@COLORBLOCK:
|
||||
X:215
|
||||
Y:6
|
||||
Width:35
|
||||
Height:13
|
||||
Label@FACTION:
|
||||
Container@FACTION:
|
||||
Width:100
|
||||
Height:25
|
||||
X:285
|
||||
@@ -192,9 +230,10 @@ Container@SERVER_LOBBY:
|
||||
Height:25
|
||||
Visible:false
|
||||
Children:
|
||||
DropDownButton@NAME_HOST:
|
||||
DropDownButton@SLOT_OPTIONS:
|
||||
Text:Name
|
||||
Width:205
|
||||
X:15
|
||||
Width:190
|
||||
Height:25
|
||||
Font:Regular
|
||||
Visible:false
|
||||
@@ -202,7 +241,7 @@ Container@SERVER_LOBBY:
|
||||
Text:Name
|
||||
Width:200
|
||||
Height:25
|
||||
X:5
|
||||
X:15
|
||||
Y:0-1
|
||||
Visible:false
|
||||
Button@JOIN:
|
||||
@@ -219,9 +258,28 @@ Container@SERVER_LOBBY:
|
||||
Height:25
|
||||
Visible:false
|
||||
Children:
|
||||
Image@ADMIN_INDICATOR:
|
||||
ImageCollection:lobby-bits
|
||||
ImageName:admin
|
||||
X:2
|
||||
Visible:false
|
||||
Background@PING_BLOCK:
|
||||
Background:button
|
||||
X:0
|
||||
Y:6
|
||||
Width:11
|
||||
Height:14
|
||||
Visible:false
|
||||
Children:
|
||||
ColorBlock@PING_COLOR:
|
||||
X:2
|
||||
Y:2
|
||||
Width:PARENT_RIGHT-4
|
||||
Height:PARENT_BOTTOM-4
|
||||
TextField@NAME:
|
||||
Text:Name
|
||||
Width:205
|
||||
X:15
|
||||
Width:190
|
||||
Height:25
|
||||
MaxLength:16
|
||||
DropDownButton@COLOR:
|
||||
@@ -256,11 +314,29 @@ Container@SERVER_LOBBY:
|
||||
Height:25
|
||||
Visible:false
|
||||
Children:
|
||||
Image@ADMIN_INDICATOR:
|
||||
ImageCollection:lobby-bits
|
||||
ImageName:admin
|
||||
X:2
|
||||
Visible:false
|
||||
Background@PING_BLOCK:
|
||||
Background:button
|
||||
X:0
|
||||
Y:6
|
||||
Width:11
|
||||
Height:14
|
||||
Visible:false
|
||||
Children:
|
||||
ColorBlock@PING_COLOR:
|
||||
X:2
|
||||
Y:2
|
||||
Width:PARENT_RIGHT-4
|
||||
Height:PARENT_BOTTOM-4
|
||||
Label@NAME:
|
||||
Text:Name
|
||||
Width:200
|
||||
Width:185
|
||||
Height:25
|
||||
X:5
|
||||
X:15
|
||||
Y:0-1
|
||||
Button@KICK:
|
||||
Text:X
|
||||
@@ -269,7 +345,7 @@ Container@SERVER_LOBBY:
|
||||
X:180
|
||||
Y:2
|
||||
Font:Bold
|
||||
ColorBlock@COLOR:
|
||||
ColorBlock@COLORBLOCK:
|
||||
X:215
|
||||
Y:6
|
||||
Width:35
|
||||
@@ -300,9 +376,9 @@ Container@SERVER_LOBBY:
|
||||
Button@SPECTATE:
|
||||
Text:Spectate
|
||||
Font:Regular
|
||||
Width:470
|
||||
Width:455
|
||||
Height:25
|
||||
X:0
|
||||
X:15
|
||||
Y:0
|
||||
Container@LABEL_CONTAINER:
|
||||
X:20
|
||||
@@ -355,7 +431,7 @@ Container@SERVER_LOBBY:
|
||||
Height:20
|
||||
Text: Crates
|
||||
DropDownButton@ASSIGNTEAMS_DROPDOWNBUTTON:
|
||||
X:399
|
||||
X:398
|
||||
Y:255
|
||||
Width:120
|
||||
Height:25
|
||||
|
||||
@@ -112,6 +112,7 @@ LoadScreen: CncLoadScreen
|
||||
|
||||
ServerTraits:
|
||||
LobbyCommands
|
||||
PlayerPinger
|
||||
MasterServerPinger
|
||||
|
||||
ChromeMetrics:
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
@@ -236,9 +236,10 @@ dialog: dialog.png
|
||||
corner-bl: 191,489,9,9
|
||||
corner-br: 200,489,9,9
|
||||
|
||||
spawnpoints: spawnpoints.png
|
||||
unowned: 528,128,16,16
|
||||
owned: 512,128,16,16
|
||||
lobby-bits: spawnpoints.png
|
||||
spawn-unclaimed: 528,128,16,16
|
||||
spawn-claimed: 512,128,16,16
|
||||
admin: 37,5,7,5
|
||||
|
||||
strategic: strategic.png
|
||||
unowned: 0,0,32,32
|
||||
|
||||
@@ -48,16 +48,33 @@ Background@SERVER_LOBBY:
|
||||
Height:25
|
||||
Visible:false
|
||||
Children:
|
||||
Image@ADMIN_INDICATOR:
|
||||
ImageCollection:lobby-bits
|
||||
ImageName:admin
|
||||
X:2
|
||||
Visible:false
|
||||
Container@PING_BLOCK:
|
||||
X:0
|
||||
Y:6
|
||||
Width:11
|
||||
Height:14
|
||||
Visible:false
|
||||
Children:
|
||||
ColorBlock@PING_COLOR:
|
||||
X:2
|
||||
Y:2
|
||||
Width:PARENT_RIGHT-4
|
||||
Height:PARENT_BOTTOM-4
|
||||
TextField@NAME:
|
||||
Text:Name
|
||||
Width:150
|
||||
X:15
|
||||
Width:135
|
||||
Height:25
|
||||
X:0
|
||||
Y:0
|
||||
MaxLength:16
|
||||
DropDownButton@BOT_DROPDOWN:
|
||||
DropDownButton@SLOT_OPTIONS:
|
||||
Text:Name
|
||||
Width:150
|
||||
X:15
|
||||
Width:135
|
||||
Height:25
|
||||
Font:Regular
|
||||
Visible:false
|
||||
@@ -117,11 +134,28 @@ Background@SERVER_LOBBY:
|
||||
Height:25
|
||||
Visible:false
|
||||
Children:
|
||||
Image@ADMIN_INDICATOR:
|
||||
ImageCollection:lobby-bits
|
||||
ImageName:admin
|
||||
X:2
|
||||
Visible:false
|
||||
Container@PING_BLOCK:
|
||||
X:0
|
||||
Y:6
|
||||
Width:11
|
||||
Height:14
|
||||
Visible:false
|
||||
Children:
|
||||
ColorBlock@PING_COLOR:
|
||||
X:2
|
||||
Y:2
|
||||
Width:PARENT_RIGHT-4
|
||||
Height:PARENT_BOTTOM-4
|
||||
Label@NAME:
|
||||
Text:Name
|
||||
Width:145
|
||||
Width:130
|
||||
Height:25
|
||||
X:5
|
||||
X:20
|
||||
Y:0-1
|
||||
Button@KICK:
|
||||
Text:X
|
||||
@@ -130,12 +164,12 @@ Background@SERVER_LOBBY:
|
||||
X:125
|
||||
Y:2
|
||||
Font:Bold
|
||||
ColorBlock@COLOR:
|
||||
ColorBlock@COLORBLOCK:
|
||||
X:165
|
||||
Y:6
|
||||
Width:45
|
||||
Height:13
|
||||
Label@FACTION:
|
||||
Container@FACTION:
|
||||
Width:130
|
||||
Height:25
|
||||
X:250
|
||||
@@ -167,7 +201,6 @@ Background@SERVER_LOBBY:
|
||||
Height:20
|
||||
ImageCollection:checkbox-bits
|
||||
ImageName:checked
|
||||
|
||||
Container@TEMPLATE_EMPTY:
|
||||
X:5
|
||||
Y:0
|
||||
@@ -177,15 +210,15 @@ Background@SERVER_LOBBY:
|
||||
Children:
|
||||
Label@NAME:
|
||||
Text:Name
|
||||
Width:145
|
||||
Width:130
|
||||
Height:25
|
||||
X:5
|
||||
X:20
|
||||
Y:0-1
|
||||
DropDownButton@NAME_HOST:
|
||||
DropDownButton@SLOT_OPTIONS:
|
||||
Text:Name
|
||||
Width:150
|
||||
Width:135
|
||||
Height:25
|
||||
X:0
|
||||
X:15
|
||||
Y:0
|
||||
Visible:false
|
||||
Button@JOIN:
|
||||
@@ -201,9 +234,27 @@ Background@SERVER_LOBBY:
|
||||
Height:25
|
||||
Visible:false
|
||||
Children:
|
||||
Image@ADMIN_INDICATOR:
|
||||
ImageCollection:lobby-bits
|
||||
ImageName:admin
|
||||
X:2
|
||||
Visible:false
|
||||
Container@PING_BLOCK:
|
||||
X:0
|
||||
Y:6
|
||||
Width:11
|
||||
Height:14
|
||||
Visible:false
|
||||
Children:
|
||||
ColorBlock@PING_COLOR:
|
||||
X:2
|
||||
Y:2
|
||||
Width:PARENT_RIGHT-4
|
||||
Height:PARENT_BOTTOM-4
|
||||
TextField@NAME:
|
||||
Text:Name
|
||||
Width:150
|
||||
X:15
|
||||
Width:135
|
||||
Height:25
|
||||
MaxLength:16
|
||||
DropDownButton@COLOR:
|
||||
@@ -238,7 +289,6 @@ Background@SERVER_LOBBY:
|
||||
Height:20
|
||||
ImageCollection:checkbox-bits
|
||||
ImageName:checked
|
||||
|
||||
Container@TEMPLATE_NONEDITABLE_SPECTATOR:
|
||||
X:5
|
||||
Y:0
|
||||
@@ -246,11 +296,28 @@ Background@SERVER_LOBBY:
|
||||
Height:25
|
||||
Visible:false
|
||||
Children:
|
||||
Image@ADMIN_INDICATOR:
|
||||
ImageCollection:lobby-bits
|
||||
ImageName:admin
|
||||
X:2
|
||||
Visible:false
|
||||
Container@PING_BLOCK:
|
||||
X:0
|
||||
Y:6
|
||||
Width:11
|
||||
Height:14
|
||||
Visible:false
|
||||
Children:
|
||||
ColorBlock@PING_COLOR:
|
||||
X:2
|
||||
Y:2
|
||||
Width:PARENT_RIGHT-4
|
||||
Height:PARENT_BOTTOM-4
|
||||
Label@NAME:
|
||||
Text:Name
|
||||
Width:145
|
||||
Width:130
|
||||
Height:25
|
||||
X:5
|
||||
X:20
|
||||
Y:0-1
|
||||
Button@KICK:
|
||||
Text:X
|
||||
@@ -259,7 +326,7 @@ Background@SERVER_LOBBY:
|
||||
X:125
|
||||
Y:2
|
||||
Font:Bold
|
||||
ColorBlock@COLOR:
|
||||
ColorBlock@COLORBLOCK:
|
||||
X:165
|
||||
Y:6
|
||||
Width:45
|
||||
@@ -386,13 +453,6 @@ Background@SERVER_LOBBY:
|
||||
Height:25
|
||||
Text:Change Map
|
||||
Font:Bold
|
||||
Button@RANDOMMAP_BUTTON:
|
||||
X:PARENT_RIGHT-154
|
||||
Y:PARENT_BOTTOM-259
|
||||
Width:120
|
||||
Height:25
|
||||
Text:Random Map
|
||||
Font:Bold
|
||||
DropDownButton@ASSIGNTEAMS_DROPDOWNBUTTON:
|
||||
X:PARENT_RIGHT-154
|
||||
Y:PARENT_BOTTOM-229
|
||||
|
||||
@@ -89,6 +89,7 @@ LoadScreen: D2kLoadScreen
|
||||
|
||||
ServerTraits:
|
||||
LobbyCommands
|
||||
PlayerPinger
|
||||
MasterServerPinger
|
||||
|
||||
ChromeMetrics:
|
||||
|
||||
@@ -169,9 +169,10 @@ dialog: dialog.png
|
||||
corner-bl: 191,489,9,9
|
||||
corner-br: 200,489,9,9
|
||||
|
||||
spawnpoints: spawnpoints.png
|
||||
unowned: 528,128,16,16
|
||||
owned: 512,128,16,16
|
||||
lobby-bits: spawnpoints.png
|
||||
spawn-unclaimed: 528,128,16,16
|
||||
spawn-claimed: 512,128,16,16
|
||||
admin: 37,5,7,5
|
||||
|
||||
strategic: strategic.png
|
||||
unowned: 0,0,32,32
|
||||
|
||||
@@ -48,16 +48,33 @@ Background@SERVER_LOBBY:
|
||||
Height:25
|
||||
Visible:false
|
||||
Children:
|
||||
Image@ADMIN_INDICATOR:
|
||||
ImageCollection:lobby-bits
|
||||
ImageName:admin
|
||||
X:2
|
||||
Visible:false
|
||||
Container@PING_BLOCK:
|
||||
X:0
|
||||
Y:6
|
||||
Width:11
|
||||
Height:14
|
||||
Visible:false
|
||||
Children:
|
||||
ColorBlock@PING_COLOR:
|
||||
X:2
|
||||
Y:2
|
||||
Width:PARENT_RIGHT-4
|
||||
Height:PARENT_BOTTOM-4
|
||||
TextField@NAME:
|
||||
Text:Name
|
||||
Width:150
|
||||
X:15
|
||||
Width:135
|
||||
Height:25
|
||||
X:0
|
||||
Y:0
|
||||
MaxLength:16
|
||||
DropDownButton@BOT_DROPDOWN:
|
||||
DropDownButton@SLOT_OPTIONS:
|
||||
Text:Name
|
||||
Width:150
|
||||
X:15
|
||||
Width:135
|
||||
Height:25
|
||||
Font:Regular
|
||||
Visible:false
|
||||
@@ -117,11 +134,28 @@ Background@SERVER_LOBBY:
|
||||
Height:25
|
||||
Visible:false
|
||||
Children:
|
||||
Image@ADMIN_INDICATOR:
|
||||
ImageCollection:lobby-bits
|
||||
ImageName:admin
|
||||
X:2
|
||||
Visible:false
|
||||
Container@PING_BLOCK:
|
||||
X:0
|
||||
Y:6
|
||||
Width:11
|
||||
Height:14
|
||||
Visible:false
|
||||
Children:
|
||||
ColorBlock@PING_COLOR:
|
||||
X:2
|
||||
Y:2
|
||||
Width:PARENT_RIGHT-4
|
||||
Height:PARENT_BOTTOM-4
|
||||
Label@NAME:
|
||||
Text:Name
|
||||
Width:145
|
||||
Width:130
|
||||
Height:25
|
||||
X:5
|
||||
X:20
|
||||
Y:0-1
|
||||
Button@KICK:
|
||||
Text:X
|
||||
@@ -130,12 +164,12 @@ Background@SERVER_LOBBY:
|
||||
X:125
|
||||
Y:2
|
||||
Font:Bold
|
||||
ColorBlock@COLOR:
|
||||
ColorBlock@COLORBLOCK:
|
||||
X:165
|
||||
Y:6
|
||||
Width:45
|
||||
Height:13
|
||||
Label@FACTION:
|
||||
Container@FACTION:
|
||||
Width:130
|
||||
Height:25
|
||||
X:250
|
||||
@@ -167,7 +201,6 @@ Background@SERVER_LOBBY:
|
||||
Height:20
|
||||
ImageCollection:checkbox-bits
|
||||
ImageName:checked
|
||||
|
||||
Container@TEMPLATE_EMPTY:
|
||||
X:5
|
||||
Y:0
|
||||
@@ -177,15 +210,15 @@ Background@SERVER_LOBBY:
|
||||
Children:
|
||||
Label@NAME:
|
||||
Text:Name
|
||||
Width:145
|
||||
Width:130
|
||||
Height:25
|
||||
X:5
|
||||
X:20
|
||||
Y:0-1
|
||||
DropDownButton@NAME_HOST:
|
||||
DropDownButton@SLOT_OPTIONS:
|
||||
Text:Name
|
||||
Width:150
|
||||
Width:135
|
||||
Height:25
|
||||
X:0
|
||||
X:15
|
||||
Y:0
|
||||
Visible:false
|
||||
Button@JOIN:
|
||||
@@ -201,9 +234,27 @@ Background@SERVER_LOBBY:
|
||||
Height:25
|
||||
Visible:false
|
||||
Children:
|
||||
Image@ADMIN_INDICATOR:
|
||||
ImageCollection:lobby-bits
|
||||
ImageName:admin
|
||||
X:2
|
||||
Visible:false
|
||||
Container@PING_BLOCK:
|
||||
X:0
|
||||
Y:6
|
||||
Width:11
|
||||
Height:14
|
||||
Visible:false
|
||||
Children:
|
||||
ColorBlock@PING_COLOR:
|
||||
X:2
|
||||
Y:2
|
||||
Width:PARENT_RIGHT-4
|
||||
Height:PARENT_BOTTOM-4
|
||||
TextField@NAME:
|
||||
Text:Name
|
||||
Width:150
|
||||
X:15
|
||||
Width:135
|
||||
Height:25
|
||||
MaxLength:16
|
||||
DropDownButton@COLOR:
|
||||
@@ -238,7 +289,6 @@ Background@SERVER_LOBBY:
|
||||
Height:20
|
||||
ImageCollection:checkbox-bits
|
||||
ImageName:checked
|
||||
|
||||
Container@TEMPLATE_NONEDITABLE_SPECTATOR:
|
||||
X:5
|
||||
Y:0
|
||||
@@ -246,11 +296,28 @@ Background@SERVER_LOBBY:
|
||||
Height:25
|
||||
Visible:false
|
||||
Children:
|
||||
Image@ADMIN_INDICATOR:
|
||||
ImageCollection:lobby-bits
|
||||
ImageName:admin
|
||||
X:2
|
||||
Visible:false
|
||||
Container@PING_BLOCK:
|
||||
X:0
|
||||
Y:6
|
||||
Width:11
|
||||
Height:14
|
||||
Visible:false
|
||||
Children:
|
||||
ColorBlock@PING_COLOR:
|
||||
X:2
|
||||
Y:2
|
||||
Width:PARENT_RIGHT-4
|
||||
Height:PARENT_BOTTOM-4
|
||||
Label@NAME:
|
||||
Text:Name
|
||||
Width:145
|
||||
Width:130
|
||||
Height:25
|
||||
X:5
|
||||
X:20
|
||||
Y:0-1
|
||||
Button@KICK:
|
||||
Text:X
|
||||
@@ -259,7 +326,7 @@ Background@SERVER_LOBBY:
|
||||
X:125
|
||||
Y:2
|
||||
Font:Bold
|
||||
ColorBlock@COLOR:
|
||||
ColorBlock@COLORBLOCK:
|
||||
X:165
|
||||
Y:6
|
||||
Width:45
|
||||
|
||||
@@ -103,6 +103,7 @@ LoadScreen: RALoadScreen
|
||||
|
||||
ServerTraits:
|
||||
LobbyCommands
|
||||
PlayerPinger
|
||||
MasterServerPinger
|
||||
|
||||
ChromeMetrics:
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 5.5 KiB |
Reference in New Issue
Block a user