merge cnc and ra lobby, fixes #1267, #1224, #106, others

This commit is contained in:
Chris Forbes
2011-11-06 11:50:58 +13:00
parent 4576eaadd6
commit 772734d032
44 changed files with 759 additions and 1432 deletions

View File

@@ -9,7 +9,6 @@
#endregion
using System.Drawing;
using OpenRA.Effects;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -250,8 +250,8 @@
<Compile Include="Player\ClassicProductionQueue.cs" />
<Compile Include="Player\PlaceBuilding.cs" />
<Compile Include="Player\ProductionQueue.cs" />
<Compile Include="Player\TechTree.cs" />
<Compile Include="Player\SurrenderOnDisconnect.cs" />
<Compile Include="Player\TechTree.cs" />
<Compile Include="PrimaryBuilding.cs" />
<Compile Include="Production.cs" />
<Compile Include="ProductionBar.cs" />
@@ -332,9 +332,9 @@
<Compile Include="WaterPaletteRotation.cs" />
<Compile Include="Weapon.cs" />
<Compile Include="Widgets\BuildPaletteWidget.cs" />
<Compile Include="Widgets\Logic\ModBrowserLogic.cs" />
<Compile Include="Widgets\Logic\ColorPickerLogic.cs" />
<Compile Include="Widgets\Logic\ConnectionDialogsLogic.cs" />
<Compile Include="Widgets\Logic\CreateServerMenuLogic.cs" />
<Compile Include="Widgets\Logic\ConnectionLogic.cs" />
<Compile Include="Widgets\Logic\DeveloperModeLogic.cs" />
<Compile Include="Widgets\Logic\DiplomacyLogic.cs" />
<Compile Include="Widgets\Logic\DirectConnectLogic.cs" />
@@ -352,6 +352,7 @@
<Compile Include="Widgets\Logic\RAInstallLogic.cs" />
<Compile Include="Widgets\Logic\ReplayBrowserLogic.cs" />
<Compile Include="Widgets\Logic\ServerBrowserLogic.cs" />
<Compile Include="Widgets\Logic\ServerCreationLogic.cs" />
<Compile Include="Widgets\Logic\SettingsMenuLogic.cs" />
<Compile Include="Widgets\MoneyBinWidget.cs" />
<Compile Include="Widgets\OrderButtonWidget.cs" />
@@ -391,4 +392,4 @@
copy "$(TargetPath)" "$(SolutionDir)mods/ra/"
cd "$(SolutionDir)"</PostBuildEvent>
</PropertyGroup>
</Project>
</Project>

View File

@@ -70,32 +70,6 @@ namespace OpenRA.Mods.RA
public void StartGame()
{
Game.ConnectionStateChanged += orderManager =>
{
Widget.CloseWindow();
switch (orderManager.Connection.ConnectionState)
{
case ConnectionState.PreConnecting:
Widget.LoadWidget("MAINMENU_BG", Widget.RootWidget, new WidgetArgs());
break;
case ConnectionState.Connecting:
Widget.OpenWindow("CONNECTING_BG",
new WidgetArgs() { { "host", orderManager.Host }, { "port", orderManager.Port } });
break;
case ConnectionState.NotConnected:
Widget.OpenWindow("CONNECTION_FAILED_BG",
new WidgetArgs() { { "orderManager", orderManager } });
break;
case ConnectionState.Connected:
var lobby = Game.OpenWindow("SERVER_LOBBY", new WidgetArgs {});
lobby.GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").ClearChat();
lobby.GetWidget("CHANGEMAP_BUTTON").Visible = true;
lobby.GetWidget("ALLOWCHEATS_CHECKBOX").Visible = true;
lobby.GetWidget("DISCONNECT_BUTTON").Visible = true;
break;
}
};
TestAndContinue();
Game.JoinExternalGame();
}

View File

@@ -10,9 +10,8 @@
using System.Collections.Generic;
using System.Linq;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Traits;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{

View File

@@ -1,53 +0,0 @@
#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 OpenRA.Network;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class ConnectionDialogsLogic
{
[ObjectCreator.UseCtor]
public ConnectionDialogsLogic(Widget widget, string host, int port)
{
widget.GetWidget<ButtonWidget>("CONNECTION_BUTTON_ABORT").OnClick = () => {
widget.GetWidget("CONNECTION_BUTTON_ABORT").Parent.Visible = false;
Game.Disconnect();
Game.LoadShellMap();
Widget.CloseWindow();
Widget.OpenWindow("MAINMENU_BG");
};
widget.GetWidget<LabelWidget>("CONNECTING_DESC").GetText = () =>
"Connecting to {0}:{1}...".F(host, port);
}
}
public class ConnectionFailedLogic
{
[ObjectCreator.UseCtor]
public ConnectionFailedLogic(Widget widget, OrderManager orderManager)
{
widget.GetWidget<ButtonWidget>("CONNECTION_BUTTON_CANCEL").OnClick = () => {
widget.GetWidget("CONNECTION_BUTTON_CANCEL").Parent.Visible = false;
Game.Disconnect();
Game.LoadShellMap();
Widget.CloseWindow();
Widget.OpenWindow("MAINMENU_BG");
};
widget.GetWidget<ButtonWidget>("CONNECTION_BUTTON_RETRY").OnClick = () =>
Game.JoinServer(orderManager.Host, orderManager.Port);
widget.GetWidget<LabelWidget>("CONNECTION_FAILED_DESC").GetText = () => string.IsNullOrEmpty(orderManager.ServerError) ?
"Could not connect to {0}:{1}".F(orderManager.Host, orderManager.Port) : orderManager.ServerError;
}
}
}

View File

@@ -0,0 +1,95 @@
#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 OpenRA.Network;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class ConnectionLogic
{
Action onConnect, onRetry, onAbort;
string host;
int port;
void ConnectionStateChanged(OrderManager om)
{
if (om.Connection.ConnectionState == ConnectionState.Connected)
{
CloseWindow();
onConnect();
}
else if (om.Connection.ConnectionState == ConnectionState.NotConnected)
{
// Show connection failed dialog
CloseWindow();
Widget.OpenWindow("CONNECTIONFAILED_PANEL", new WidgetArgs()
{
{ "onAbort", onAbort },
{ "onRetry", onRetry },
{ "host", host },
{ "port", port }
});
}
}
void CloseWindow()
{
Game.ConnectionStateChanged -= ConnectionStateChanged;
Widget.CloseWindow();
}
[ObjectCreator.UseCtor]
public ConnectionLogic(Widget widget, string host, int port, Action onConnect, Action onRetry, Action onAbort)
{
this.host = host;
this.port = port;
this.onConnect = onConnect;
this.onRetry = onRetry;
this.onAbort = onAbort;
Game.ConnectionStateChanged += ConnectionStateChanged;
var panel = widget;
panel.GetWidget<ButtonWidget>("ABORT_BUTTON").OnClick = () => { CloseWindow(); onAbort(); };
widget.GetWidget<LabelWidget>("CONNECTING_DESC").GetText = () =>
"Connecting to {0}:{1}...".F(host, port);
}
public static void Connect(string host, int port, Action onConnect, Action onAbort)
{
Game.JoinServer(host, port);
Widget.OpenWindow("CONNECTING_PANEL", new WidgetArgs()
{
{ "host", host },
{ "port", port },
{ "onConnect", onConnect },
{ "onAbort", onAbort },
{ "onRetry", () => Connect(host, port, onConnect, onAbort) }
});
}
}
public class ConnectionFailedLogic
{
[ObjectCreator.UseCtor]
public ConnectionFailedLogic(Widget widget, string host, int port, Action onRetry, Action onAbort)
{
var panel = widget;
panel.GetWidget<ButtonWidget>("ABORT_BUTTON").OnClick = () => { Widget.CloseWindow(); onAbort(); };
panel.GetWidget<ButtonWidget>("RETRY_BUTTON").OnClick = () => { Widget.CloseWindow(); onRetry(); };
widget.GetWidget<LabelWidget>("CONNECTING_DESC").GetText = () =>
"Could not connect to {0}:{1}".F(host, port);
}
}
}

View File

@@ -1,48 +0,0 @@
#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.Net;
using OpenRA.GameRules;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class CreateServerMenuLogic
{
[ObjectCreator.UseCtor]
public CreateServerMenuLogic(Widget widget)
{
var settings = Game.Settings;
var cs = widget;
cs.GetWidget<ButtonWidget>("BUTTON_CANCEL").OnClick = () => Widget.CloseWindow();
cs.GetWidget<ButtonWidget>("BUTTON_START").OnClick = () =>
{
settings.Server.Name = cs.GetWidget<TextFieldWidget>("GAME_TITLE").Text;
settings.Server.ListenPort = int.Parse(cs.GetWidget<TextFieldWidget>("LISTEN_PORT").Text);
settings.Server.ExternalPort = int.Parse(cs.GetWidget<TextFieldWidget>("EXTERNAL_PORT").Text);
settings.Server.Map = WidgetUtils.ChooseInitialMap(Game.Settings.Server.Map);
settings.Save();
// Take a copy so that subsequent settings changes don't affect the server
Game.CreateServer(new ServerSettings(Game.Settings.Server));
Game.JoinServer(IPAddress.Loopback.ToString(), settings.Server.ListenPort);
};
cs.GetWidget<TextFieldWidget>("GAME_TITLE").Text = settings.Server.Name ?? "";
cs.GetWidget<TextFieldWidget>("LISTEN_PORT").Text = settings.Server.ListenPort.ToString();
cs.GetWidget<TextFieldWidget>("EXTERNAL_PORT").Text = settings.Server.ExternalPort.ToString();
var onlineCheckbox = cs.GetWidget<CheckboxWidget>("CHECKBOX_ONLINE");
onlineCheckbox.IsChecked = () => settings.Server.AdvertiseOnline;
onlineCheckbox.OnClick = () => { settings.Server.AdvertiseOnline ^= true; settings.Save(); };
}
}
}

View File

@@ -1,20 +1,10 @@
#region Copyright & License Information
/*
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
* This file is part of OpenRA.
*
* OpenRA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenRA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
* 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

View File

@@ -8,7 +8,7 @@
*/
#endregion
using System.Linq;
using System;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
@@ -16,34 +16,28 @@ namespace OpenRA.Mods.RA.Widgets.Logic
public class DirectConnectLogic
{
[ObjectCreator.UseCtor]
public DirectConnectLogic(Widget widget)
public DirectConnectLogic(Widget widget, Action onExit, Action openLobby)
{
var dc = widget.GetWidget("DIRECTCONNECT_BG");
var panel = widget;
var ipField = panel.GetWidget<TextFieldWidget>("IP");
var portField = panel.GetWidget<TextFieldWidget>("PORT");
dc.GetWidget<TextFieldWidget>("SERVER_ADDRESS").Text = Game.Settings.Player.LastServer;
var last = Game.Settings.Player.LastServer.Split(':');
ipField.Text = last.Length > 1 ? last[0] : "localhost";
portField.Text = last.Length > 2 ? last[1] : "1234";
dc.GetWidget<ButtonWidget>("JOIN_BUTTON").OnClick = () =>
panel.GetWidget<ButtonWidget>("JOIN_BUTTON").OnClick = () =>
{
var address = dc.GetWidget<TextFieldWidget>("SERVER_ADDRESS").Text;
var addressParts = address.Split(':');
if (addressParts.Length < 1 || addressParts.Length > 2)
return;
var port = Exts.WithDefault(1234, () => int.Parse(portField.Text));
var port = Exts.WithDefault(1234, () => int.Parse(addressParts[1]));
Game.Settings.Player.LastServer = address;
Game.Settings.Player.LastServer = "{0}:{1}".F(ipField.Text, port);
Game.Settings.Save();
Widget.CloseWindow();
Game.JoinServer(addressParts[0], port);
ConnectionLogic.Connect(ipField.Text, port, openLobby, onExit);
};
dc.GetWidget<ButtonWidget>("CANCEL_BUTTON").OnClick = () =>
{
Widget.CloseWindow();
Widget.OpenWindow("MAINMENU_BG");
};
panel.GetWidget<ButtonWidget>("BACK_BUTTON").OnClick = () => { Widget.CloseWindow(); onExit(); };
}
}
}

View File

@@ -20,8 +20,10 @@ namespace OpenRA.Mods.RA.Widgets.Logic
{
public class LobbyLogic
{
Widget lobby, LocalPlayerTemplate, RemotePlayerTemplate, EmptySlotTemplate, EmptySlotTemplateHost,
LocalSpectatorTemplate, RemoteSpectatorTemplate, NewSpectatorTemplate;
Widget EditablePlayerTemplate, NonEditablePlayerTemplate, EmptySlotTemplate,
EditableSpectatorTemplate, NonEditableSpectatorTemplate, NewSpectatorTemplate;
ScrollPanelWidget chatPanel;
Widget chatTemplate;
ScrollPanelWidget Players;
Dictionary<string, string> CountryNames;
@@ -30,39 +32,98 @@ namespace OpenRA.Mods.RA.Widgets.Logic
ColorPickerPaletteModifier PlayerPalettePreview;
readonly Action OnGameStart;
readonly Action onExit;
readonly OrderManager orderManager;
[ObjectCreator.UseCtor]
internal LobbyLogic(Widget widget, World world, OrderManager orderManager)
// Listen for connection failures
void ConnectionStateChanged(OrderManager om)
{
if (om.Connection.ConnectionState == ConnectionState.NotConnected)
{
// Show connection failed dialog
CloseWindow();
Action onConnect = () =>
{
Game.OpenWindow("SERVER_LOBBY", new WidgetArgs()
{
{ "onExit", onExit },
{ "onStart", OnGameStart },
{ "addBots", false }
});
};
Action onRetry = () =>
{
CloseWindow();
ConnectionLogic.Connect(om.Host, om.Port, onConnect, onExit);
};
Widget.OpenWindow("CONNECTIONFAILED_PANEL", new WidgetArgs()
{
{ "onAbort", onExit },
{ "onRetry", onRetry },
{ "host", om.Host },
{ "port", om.Port }
});
}
}
void CloseWindow()
{
Game.LobbyInfoChanged -= UpdateCurrentMap;
Game.LobbyInfoChanged -= UpdatePlayerList;
Game.BeforeGameStart -= OnGameStart;
Game.AddChatLine -= AddChatLine;
Game.ConnectionStateChanged -= ConnectionStateChanged;
Widget.CloseWindow();
}
[ObjectCreator.UseCtor]
internal LobbyLogic(Widget widget, World world, OrderManager orderManager,
Action onExit, Action onStart, bool addBots)
{
var lobby = widget;
this.orderManager = orderManager;
this.lobby = widget;
Game.BeforeGameStart += CloseWindow;
this.OnGameStart = () => { CloseWindow(); onStart(); };
this.onExit = onExit;
Game.LobbyInfoChanged += UpdateCurrentMap;
Game.LobbyInfoChanged += UpdatePlayerList;
UpdateCurrentMap();
Game.BeforeGameStart += OnGameStart;
Game.AddChatLine += AddChatLine;
Game.ConnectionStateChanged += ConnectionStateChanged;
UpdateCurrentMap();
PlayerPalettePreview = world.WorldActor.Trait<ColorPickerPaletteModifier>();
PlayerPalettePreview.Ramp = Game.Settings.Player.ColorRamp;
Players = lobby.GetWidget<ScrollPanelWidget>("PLAYERS");
LocalPlayerTemplate = Players.GetWidget("TEMPLATE_LOCAL");
RemotePlayerTemplate = Players.GetWidget("TEMPLATE_REMOTE");
EditablePlayerTemplate = Players.GetWidget("TEMPLATE_EDITABLE_PLAYER");
NonEditablePlayerTemplate = Players.GetWidget("TEMPLATE_NONEDITABLE_PLAYER");
EmptySlotTemplate = Players.GetWidget("TEMPLATE_EMPTY");
EmptySlotTemplateHost = Players.GetWidget("TEMPLATE_EMPTY_HOST");
LocalSpectatorTemplate = Players.GetWidget("TEMPLATE_LOCAL_SPECTATOR");
RemoteSpectatorTemplate = Players.GetWidget("TEMPLATE_REMOTE_SPECTATOR");
EditableSpectatorTemplate = Players.GetWidget("TEMPLATE_EDITABLE_SPECTATOR");
NonEditableSpectatorTemplate = Players.GetWidget("TEMPLATE_NONEDITABLE_SPECTATOR");
NewSpectatorTemplate = Players.GetWidget("TEMPLATE_NEW_SPECTATOR");
var mapPreview = lobby.GetWidget<MapPreviewWidget>("LOBBY_MAP_PREVIEW");
var mapPreview = lobby.GetWidget<MapPreviewWidget>("MAP_PREVIEW");
mapPreview.IsVisible = () => Map != null;
mapPreview.Map = () => Map;
mapPreview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint( orderManager, mapPreview, Map, mi );
mapPreview.SpawnColors = () => LobbyUtils.GetSpawnColors( orderManager, Map );
var mapTitle = lobby.GetWidget<LabelWidget>("MAP_TITLE");
if (mapTitle != null)
{
mapTitle.IsVisible = () => Map != null;
mapTitle.GetText = () => Map.Title;
}
CountryNames = Rules.Info["world"].Traits.WithInterface<CountryInfo>()
.Where(c => c.Selectable)
.ToDictionary(a => a.Race, a => a.Name);
CountryNames.Add("random", "Random");
CountryNames.Add("random", "Any");
var mapButton = lobby.GetWidget<ButtonWidget>("CHANGEMAP_BUTTON");
mapButton.OnClick = () =>
@@ -74,48 +135,40 @@ namespace OpenRA.Mods.RA.Widgets.Logic
Game.Settings.Save();
});
Widget.OpenWindow("MAP_CHOOSER", new WidgetArgs()
Widget.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
{
{ "initialMap", MapUid },
{ "initialMap", Map.Uid },
{ "onExit", () => {} },
{ "onSelect", onSelect }
});
};
mapButton.IsVisible = () => mapButton.Visible && Game.IsHost;
var disconnectButton = lobby.GetWidget<ButtonWidget>("DISCONNECT_BUTTON");
disconnectButton.OnClick = () =>
{
CloseWindow();
Game.Disconnect();
Game.LoadShellMap();
Widget.OpenWindow("MAINMENU_BG");
};
disconnectButton.OnClick = () => { CloseWindow(); onExit(); };
var gameStarting = false;
var allowCheats = lobby.GetWidget<CheckboxWidget>("ALLOWCHEATS_CHECKBOX");
allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
allowCheats.OnClick = () =>
{
if (Game.IsHost)
orderManager.IssueOrder(Order.Command(
allowCheats.IsDisabled = () => !Game.IsHost || gameStarting || orderManager.LocalClient == null
|| orderManager.LocalClient.IsReady;
allowCheats.OnClick = () => orderManager.IssueOrder(Order.Command(
"allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
};
var startGameButton = lobby.GetWidget<ButtonWidget>("START_GAME_BUTTON");
startGameButton.IsVisible = () => Game.IsHost;
startGameButton.IsDisabled = () => gameStarting;
startGameButton.OnClick = () =>
{
mapButton.Visible = false;
disconnectButton.Visible = false;
gameStarting = true;
orderManager.IssueOrder(Order.Command("startgame"));
};
// Todo: Only show if the map requirements are met for player slots
startGameButton.IsVisible = () => Game.IsHost;
bool teamChat = false;
var chatLabel = lobby.GetWidget<LabelWidget>("LABEL_CHATTYPE");
var chatTextField = lobby.GetWidget<TextFieldWidget>("CHAT_TEXTFIELD");
chatTextField.OnEnterKey = () =>
{
if (chatTextField.Text.Length == 0)
@@ -133,36 +186,69 @@ namespace OpenRA.Mods.RA.Widgets.Logic
return true;
};
Game.AddChatLine += AddChatLine;
}
chatPanel = lobby.GetWidget<ScrollPanelWidget>("CHAT_DISPLAY");
chatTemplate = chatPanel.GetWidget("CHAT_TEMPLATE");
chatPanel.RemoveChildren();
public void CloseWindow()
{
Game.LobbyInfoChanged -= UpdateCurrentMap;
Game.LobbyInfoChanged -= UpdatePlayerList;
Game.AddChatLine -= AddChatLine;
Game.BeforeGameStart -= CloseWindow;
var musicButton = lobby.GetWidget<ButtonWidget>("MUSIC_BUTTON");
if (musicButton != null)
musicButton.OnClick = () => Widget.OpenWindow("MUSIC_PANEL", new WidgetArgs
{ { "onExit", () => {} } });
Widget.CloseWindow();
// Add a bot on the first lobbyinfo update
if (addBots)
Game.LobbyInfoChanged += WidgetUtils.Once(() =>
{
var slot = orderManager.LobbyInfo.FirstEmptySlot();
var bot = Rules.Info["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name).FirstOrDefault();
if (slot != null && bot != null)
orderManager.IssueOrder(Order.Command("slot_bot {0} {1}".F(slot, bot)));
});
}
void AddChatLine(Color c, string from, string text)
{
lobby.GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").AddLine(c, from, text);
var template = chatTemplate.Clone();
var nameLabel = template.GetWidget<LabelWidget>("NAME");
var timeLabel = template.GetWidget<LabelWidget>("TIME");
var textLabel = template.GetWidget<LabelWidget>("TEXT");
var name = from + ":";
var font = Game.Renderer.Fonts[nameLabel.Font];
var nameSize = font.Measure(from);
var time = DateTime.Now;
timeLabel.GetText = () => "{0:D2}:{1:D2}".F(time.Hour, time.Minute);
nameLabel.GetColor = () => c;
nameLabel.GetText = () => name;
nameLabel.Bounds.Width = nameSize.X;
textLabel.Bounds.X += nameSize.X;
textLabel.Bounds.Width -= nameSize.X;
// Hack around our hacky wordwrap behavior: need to resize the widget to fit the text
text = WidgetUtils.WrapText(text, textLabel.Bounds.Width, font);
textLabel.GetText = () => text;
var dh = font.Measure(text).Y - textLabel.Bounds.Height;
if (dh > 0)
{
textLabel.Bounds.Height += dh;
template.Bounds.Height += dh;
}
chatPanel.AddChild(template);
chatPanel.ScrollToBottom();
Sound.Play("scold1.aud");
}
void UpdateCurrentMap()
{
var newMap = orderManager.LobbyInfo.GlobalSettings.Map;
if (MapUid == newMap) return;
MapUid = newMap;
if (MapUid == orderManager.LobbyInfo.GlobalSettings.Map) return;
MapUid = orderManager.LobbyInfo.GlobalSettings.Map;
Map = new Map(Game.modData.AvailableMaps[MapUid].Path);
var title = Widget.RootWidget.GetWidget<LabelWidget>("LOBBY_TITLE");
if (title != null)
title.Text = "OpenRA Multiplayer Lobby - {0} - {1}".F(
orderManager.LobbyInfo.GlobalSettings.ServerName, Map.Title);
var title = Widget.RootWidget.GetWidget<LabelWidget>("TITLE");
title.Text = orderManager.LobbyInfo.GlobalSettings.ServerName;
}
void UpdatePlayerList()
@@ -173,108 +259,119 @@ namespace OpenRA.Mods.RA.Widgets.Logic
foreach (var kv in orderManager.LobbyInfo.Slots)
{
var s = kv.Value;
var c = orderManager.LobbyInfo.ClientInSlot(kv.Key);
var key = kv.Key;
var slot = kv.Value;
var client = orderManager.LobbyInfo.ClientInSlot(key);
Widget template;
if (c == null)
// Empty slot
if (client == null)
{
template = EmptySlotTemplate.Clone();
Func<string> getText = () => slot.Closed ? "Closed" : "Open";
var ready = orderManager.LocalClient.IsReady;
if (Game.IsHost)
{
template = EmptySlotTemplateHost.Clone();
var name = template.GetWidget<DropDownButtonWidget>("NAME");
name.GetText = () => s.Closed ? "Closed" : "Open";
name.OnMouseDown = _ => LobbyUtils.ShowSlotDropDown(name, s, c, orderManager);
var name = template.GetWidget<DropDownButtonWidget>("NAME_HOST");
name.IsVisible = () => true;
name.IsDisabled = () => ready;
name.GetText = getText;
name.OnMouseDown = _ => LobbyUtils.ShowSlotDropDown(name, slot, client, orderManager);
}
else
{
template = EmptySlotTemplate.Clone();
var name = template.GetWidget<LabelWidget>("NAME");
name.GetText = () => s.Closed ? "Closed" : "Open";
name.IsVisible = () => true;
name.GetText = getText;
}
var join = template.GetWidget<ButtonWidget>("JOIN");
if (join != null)
{
join.OnClick = () => orderManager.IssueOrder(Order.Command("slot " + s.PlayerReference));
join.IsVisible = () => !s.Closed && c == null && !orderManager.LocalClient.IsReady;
}
join.IsVisible = () => !slot.Closed;
join.IsDisabled = () => ready;
join.OnClick = () => orderManager.IssueOrder(Order.Command("slot " + key));
}
else if ((c.Index == orderManager.LocalClient.Index && !c.IsReady) || (c.Bot != null && Game.IsHost))
// Editable player in slot
else if ((client.Index == orderManager.LocalClient.Index) ||
(client.Bot != null && Game.IsHost))
{
template = LocalPlayerTemplate.Clone();
template = EditablePlayerTemplate.Clone();
var botReady = client.Bot != null && Game.IsHost && orderManager.LocalClient.IsReady;
var ready = botReady || client.IsReady;
var botReady = (c.Bot != null && Game.IsHost
&& orderManager.LocalClient.IsReady);
var ready = botReady || c.IsReady;
if (c.Bot == null)
{
LobbyUtils.SetupNameWidget(orderManager, c, template.GetWidget<TextFieldWidget>("NAME"));
}
else
if (client.Bot != null)
{
var name = template.GetWidget<DropDownButtonWidget>("BOT_DROPDOWN");
name.IsVisible = () => true;
name.IsDisabled = () => ready;
name.GetText = () => c.Name;
name.OnMouseDown = _ => LobbyUtils.ShowSlotDropDown(name, s, c, orderManager);
}
name.GetText = () => client.Name;
name.OnMouseDown = _ => LobbyUtils.ShowSlotDropDown(name, slot, client, orderManager);
}
else
{
var name = template.GetWidget<TextFieldWidget>("NAME");
name.IsVisible = () => true;
name.IsDisabled = () => ready;
LobbyUtils.SetupNameWidget(orderManager, client, name);
}
var color = template.GetWidget<DropDownButtonWidget>("COLOR");
color.IsDisabled = () => s.LockColor;
color.OnMouseDown = _ => LobbyUtils.ShowColorDropDown(color, c, orderManager, PlayerPalettePreview);
color.IsDisabled = () => slot.LockColor || ready;
color.OnMouseDown = _ => LobbyUtils.ShowColorDropDown(color, client, orderManager, PlayerPalettePreview);
var colorBlock = color.GetWidget<ColorBlockWidget>("COLORBLOCK");
colorBlock.GetColor = () => c.ColorRamp.GetColor(0);
colorBlock.GetColor = () => client.ColorRamp.GetColor(0);
var faction = template.GetWidget<DropDownButtonWidget>("FACTION");
faction.IsDisabled = () => s.LockRace;
faction.OnMouseDown = _ => LobbyUtils.ShowRaceDropDown(faction, c, orderManager, CountryNames);
faction.IsDisabled = () => slot.LockRace || ready;
faction.OnMouseDown = _ => LobbyUtils.ShowRaceDropDown(faction, client, orderManager, CountryNames);
var factionname = faction.GetWidget<LabelWidget>("FACTIONNAME");
factionname.GetText = () => CountryNames[c.Country];
factionname.GetText = () => CountryNames[client.Country];
var factionflag = faction.GetWidget<ImageWidget>("FACTIONFLAG");
factionflag.GetImageName = () => c.Country;
factionflag.GetImageName = () => client.Country;
factionflag.GetImageCollection = () => "flags";
var team = template.GetWidget<DropDownButtonWidget>("TEAM");
team.IsDisabled = () => s.LockTeam;
team.OnMouseDown = _ => LobbyUtils.ShowTeamDropDown(team, c, orderManager, Map);
team.GetText = () => (c.Team == 0) ? "-" : c.Team.ToString();
team.IsDisabled = () => slot.LockTeam || ready;
team.OnMouseDown = _ => LobbyUtils.ShowTeamDropDown(team, client, orderManager, Map);
team.GetText = () => (client.Team == 0) ? "-" : client.Team.ToString();
var status = template.GetWidget<CheckboxWidget>("STATUS");
status.IsChecked = () => c.IsReady;
status.OnClick = CycleReady;
status.IsVisible = () => c.Bot == null;
if (client.Bot == null)
{
// local player
var status = template.GetWidget<CheckboxWidget>("STATUS_CHECKBOX");
status.IsChecked = () => ready;
status.IsVisible = () => true;
status.OnClick += CycleReady;
}
else // Bot
template.GetWidget<ImageWidget>("STATUS_IMAGE").IsVisible = () => true;
}
else
{
template = RemotePlayerTemplate.Clone();
template.GetWidget<LabelWidget>("NAME").GetText = () => c.Name;
{ // Non-editable player in slot
template = NonEditablePlayerTemplate.Clone();
template.GetWidget<LabelWidget>("NAME").GetText = () => client.Name;
var color = template.GetWidget<ColorBlockWidget>("COLOR");
color.GetColor = () => c.ColorRamp.GetColor(0);
color.GetColor = () => client.ColorRamp.GetColor(0);
var faction = template.GetWidget<LabelWidget>("FACTION");
var factionname = faction.GetWidget<LabelWidget>("FACTIONNAME");
factionname.GetText = () => CountryNames[c.Country];
factionname.GetText = () => CountryNames[client.Country];
var factionflag = faction.GetWidget<ImageWidget>("FACTIONFLAG");
factionflag.GetImageName = () => c.Country;
factionflag.GetImageName = () => client.Country;
factionflag.GetImageCollection = () => "flags";
var team = template.GetWidget<LabelWidget>("TEAM");
team.GetText = () => (c.Team == 0) ? "-" : c.Team.ToString();
team.GetText = () => (client.Team == 0) ? "-" : client.Team.ToString();
var status = template.GetWidget<CheckboxWidget>("STATUS");
status.IsChecked = () => c.IsReady;
if (c.Index == orderManager.LocalClient.Index)
status.OnClick = CycleReady;
status.IsVisible = () => c.Bot == null;
template.GetWidget<ImageWidget>("STATUS_IMAGE").IsVisible = () =>
client.Bot != null || client.IsReady;
var kickButton = template.GetWidget<ButtonWidget>("KICK");
kickButton.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index;
kickButton.OnClick = () => orderManager.IssueOrder(Order.Command("kick " + c.Index));
kickButton.IsVisible = () => Game.IsHost && client.Index != orderManager.LocalClient.Index;
kickButton.IsDisabled = () => orderManager.LocalClient.IsReady;
kickButton.OnClick = () => orderManager.IssueOrder(Order.Command("kick " + client.Index));
}
template.IsVisible = () => true;
@@ -284,39 +381,42 @@ namespace OpenRA.Mods.RA.Widgets.Logic
// Add spectators
foreach (var client in orderManager.LobbyInfo.Clients.Where(client => client.Slot == null))
{
var c = client;
Widget template;
var c = client;
var ready = c.IsReady;
// Editable spectator
if (c.Index == orderManager.LocalClient.Index && !c.IsReady)
if (c.Index == orderManager.LocalClient.Index)
{
template = LocalSpectatorTemplate.Clone();
LobbyUtils.SetupNameWidget(orderManager, c, template.GetWidget<TextFieldWidget>("NAME"));
template = EditableSpectatorTemplate.Clone();
var name = template.GetWidget<TextFieldWidget>("NAME");
name.IsDisabled = () => ready;
LobbyUtils.SetupNameWidget(orderManager, c, name);
var color = template.GetWidget<DropDownButtonWidget>("COLOR");
color.IsDisabled = () => ready;
color.OnMouseDown = _ => LobbyUtils.ShowColorDropDown(color, c, orderManager, PlayerPalettePreview);
var colorBlock = color.GetWidget<ColorBlockWidget>("COLORBLOCK");
colorBlock.GetColor = () => c.ColorRamp.GetColor(0);
var status = template.GetWidget<CheckboxWidget>("STATUS");
status.IsChecked = () => c.IsReady;
var status = template.GetWidget<CheckboxWidget>("STATUS_CHECKBOX");
status.IsChecked = () => ready;
status.OnClick += CycleReady;
}
// Non-editable spectator
else
{
template = RemoteSpectatorTemplate.Clone();
template = NonEditableSpectatorTemplate.Clone();
template.GetWidget<LabelWidget>("NAME").GetText = () => c.Name;
var color = template.GetWidget<ColorBlockWidget>("COLOR");
color.GetColor = () => c.ColorRamp.GetColor(0);
var status = template.GetWidget<CheckboxWidget>("STATUS");
status.IsChecked = () => c.IsReady;
if (c.Index == orderManager.LocalClient.Index)
status.OnClick += CycleReady;
template.GetWidget<ImageWidget>("STATUS_IMAGE").IsVisible = () => c.Bot != null || c.IsReady;
var kickButton = template.GetWidget<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));
}
@@ -325,11 +425,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic
}
// Spectate button
if (orderManager.LocalClient.Slot != null && !orderManager.LocalClient.IsReady)
if (orderManager.LocalClient.Slot != null)
{
var spec = NewSpectatorTemplate.Clone();
var btn = spec.GetWidget<ButtonWidget>("SPECTATE");
btn.OnClick = () => orderManager.IssueOrder(Order.Command("spectate"));
btn.IsDisabled = () => orderManager.LocalClient.IsReady;
spec.IsVisible = () => true;
Players.AddChild(spec);
}

View File

@@ -8,58 +8,62 @@
*/
#endregion
using System;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class MainMenuButtonsLogic
{
Widget rootMenu;
[ObjectCreator.UseCtor]
public MainMenuButtonsLogic(Widget widget)
{
rootMenu = widget;
Game.modData.WidgetLoader.LoadWidget( new WidgetArgs(), Widget.RootWidget, "PERF_BG" );
widget.GetWidget<ButtonWidget>("MAINMENU_BUTTON_JOIN").OnClick = () => Widget.OpenWindow("JOINSERVER_BG");
widget.GetWidget<ButtonWidget>("MAINMENU_BUTTON_CREATE").OnClick = () => Widget.OpenWindow("CREATESERVER_BG");
widget.GetWidget<ButtonWidget>("MAINMENU_BUTTON_JOIN").OnClick = () => OpenGamePanel("JOINSERVER_BG");
widget.GetWidget<ButtonWidget>("MAINMENU_BUTTON_CREATE").OnClick = () => OpenGamePanel("CREATESERVER_BG");
widget.GetWidget<ButtonWidget>("MAINMENU_BUTTON_DIRECTCONNECT").OnClick = () => OpenGamePanel("DIRECTCONNECT_BG");
widget.GetWidget<ButtonWidget>("MAINMENU_BUTTON_SETTINGS").OnClick = () => Widget.OpenWindow("SETTINGS_MENU");
widget.GetWidget<ButtonWidget>("MAINMENU_BUTTON_MUSIC").OnClick = () => Widget.OpenWindow("MUSIC_MENU");
widget.GetWidget<ButtonWidget>("MAINMENU_BUTTON_REPLAY_VIEWER").OnClick = () => Widget.OpenWindow("REPLAYBROWSER_BG");
widget.GetWidget<ButtonWidget>("MAINMENU_BUTTON_MODS").OnClick = () =>
Widget.OpenWindow("MODS_PANEL", new WidgetArgs()
{
{ "onExit", () => {} },
{ "onSwitch", RemoveShellmapUI }
});
widget.GetWidget<ButtonWidget>("MAINMENU_BUTTON_REPLAY_VIEWER").OnClick = () =>
Widget.OpenWindow("REPLAYBROWSER_BG", new WidgetArgs()
{
{ "onExit", () => {} },
{ "onStart", RemoveShellmapUI }
});
widget.GetWidget<ButtonWidget>("MAINMENU_BUTTON_QUIT").OnClick = () => Game.Exit();
DisplayModSelector();
}
public static void DisplayModSelector()
void RemoveShellmapUI()
{
var selector = Game.modData.WidgetLoader.LoadWidget( new WidgetArgs(), Widget.RootWidget, "QUICKMODSWITCHER" );
var switcher = selector.GetWidget<DropDownButtonWidget>("SWITCHER");
switcher.OnMouseDown = _ => ShowModsDropDown(switcher);
switcher.GetText = WidgetUtils.ActiveModTitle;
selector.GetWidget<LabelWidget>("VERSION").GetText = WidgetUtils.ActiveModVersion;
rootMenu.Parent.RemoveChild(rootMenu);
}
static void LoadMod(string mod)
void OpenGamePanel(string id)
{
var mods = Mod.AllMods[mod].WithPrerequisites();
if (Game.CurrentMods.Keys.SymmetricDifference(mods).Any())
Game.RunAfterTick(() => Game.InitializeWithMods(mods));
}
static void ShowModsDropDown(DropDownButtonWidget dropdown)
{
Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (m, itemTemplate) =>
Widget.OpenWindow(id, new WidgetArgs()
{
var item = ScrollItemWidget.Setup(itemTemplate,
() => m == Game.CurrentMods.Keys.First(),
() => LoadMod(m));
item.GetWidget<LabelWidget>("LABEL").GetText = () => Mod.AllMods[m].Title;
return item;
};
{ "onExit", () => {} },
{ "openLobby", () => OpenLobbyPanel() }
});
}
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, Mod.AllMods.Keys, setupItem);
void OpenLobbyPanel()
{
Game.OpenWindow("SERVER_LOBBY", new WidgetArgs()
{
{ "onExit", () => { Game.Disconnect(); } },
{ "onStart", RemoveShellmapUI },
{ "addBots", false }
});
}
}
}

View File

@@ -0,0 +1,60 @@
#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.Linq;
using OpenRA.FileFormats;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class ModBrowserLogic
{
Mod currentMod;
[ObjectCreator.UseCtor]
public ModBrowserLogic(Widget widget, Action onSwitch, Action onExit)
{
var panel = widget;
var modList = panel.GetWidget<ScrollPanelWidget>("MOD_LIST");
var loadButton = panel.GetWidget<ButtonWidget>("LOAD_BUTTON");
loadButton.OnClick = () => LoadMod(currentMod.Id, onSwitch);
loadButton.IsDisabled = () => currentMod.Id == Game.CurrentMods.Keys.First();
panel.GetWidget<ButtonWidget>("BACK_BUTTON").OnClick = () => { Widget.CloseWindow(); onExit(); };
currentMod = Mod.AllMods[Game.modData.Manifest.Mods[0]];
// Mod list
var modTemplate = modList.GetWidget<ScrollItemWidget>("MOD_TEMPLATE");
foreach (var m in Mod.AllMods)
{
var mod = m.Value;
var item = ScrollItemWidget.Setup(modTemplate, () => currentMod == mod, () => currentMod = mod);
item.GetWidget<LabelWidget>("TITLE").GetText = () => mod.Title;
item.GetWidget<LabelWidget>("VERSION").GetText = () => mod.Version;
item.GetWidget<LabelWidget>("AUTHOR").GetText = () => mod.Author;
modList.AddChild(item);
}
}
void LoadMod(string mod, Action onSwitch)
{
var mods = Mod.AllMods[mod].WithPrerequisites();
Game.RunAfterTick(() =>
{
Widget.CloseWindow();
onSwitch();
Game.InitializeWithMods(mods);
});
}
}
}

View File

@@ -33,8 +33,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic
Widget.OpenWindow("INSTALL_FROMCD_PANEL", args);
panel.GetWidget<ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;
MainMenuButtonsLogic.DisplayModSelector();
}
}
}

View File

@@ -18,70 +18,80 @@ namespace OpenRA.Mods.RA.Widgets.Logic
{
public class ReplayBrowserLogic
{
Widget widget;
Widget panel;
[ObjectCreator.UseCtor]
public ReplayBrowserLogic(Widget widget)
public ReplayBrowserLogic(Widget widget, Action onExit, Action onStart)
{
this.widget = widget;
panel = widget;
widget.GetWidget<ButtonWidget>("CANCEL_BUTTON").OnClick = () => Widget.CloseWindow();
panel.GetWidget<ButtonWidget>("CANCEL_BUTTON").OnClick = () => { Widget.CloseWindow(); onExit(); };
/* find some replays? */
var rl = widget.GetWidget<ScrollPanelWidget>("REPLAY_LIST");
var rl = panel.GetWidget<ScrollPanelWidget>("REPLAY_LIST");
var replayDir = Path.Combine(Platform.SupportDir, "Replays");
var template = widget.GetWidget<ScrollItemWidget>("REPLAY_TEMPLATE");
SelectReplay(null);
var template = panel.GetWidget<ScrollItemWidget>("REPLAY_TEMPLATE");
rl.RemoveChildren();
if (Directory.Exists(replayDir))
foreach (var replayFile in Directory.GetFiles(replayDir, "*.rep").Reverse())
{
var files = Directory.GetFiles(replayDir, "*.rep").Reverse();
foreach (var replayFile in files)
AddReplay(rl, replayFile, template);
widget.GetWidget<ButtonWidget>("WATCH_BUTTON").OnClick = () =>
SelectReplay(files.FirstOrDefault());
}
var watch = panel.GetWidget<ButtonWidget>("WATCH_BUTTON");
watch.IsDisabled = () => currentReplay == null || currentMap == null || currentReplay.Duration == 0;
watch.OnClick = () =>
{
if (currentReplay != null)
{
Game.JoinReplay(currentReplay.Filename);
Widget.CloseWindow();
Game.JoinReplay(currentReplay);
onStart();
}
};
widget.GetWidget("REPLAY_INFO").IsVisible = () => currentReplay != null;
panel.GetWidget("REPLAY_INFO").IsVisible = () => currentReplay != null;
}
string currentReplay;
Replay currentReplay;
Map currentMap;
void SelectReplay(string filename)
{
currentReplay = filename;
if (filename == null)
return;
if (currentReplay != null)
try
{
try
{
var summary = new Replay(currentReplay);
var mapStub = summary.Map();
currentReplay = new Replay(filename);
currentMap = currentReplay.Map();
widget.GetWidget<LabelWidget>("DURATION").GetText =
() => WidgetUtils.FormatTime(summary.Duration * 3 /* todo: 3:1 ratio isnt always true. */);
widget.GetWidget<MapPreviewWidget>("MAP_PREVIEW").Map = () => mapStub;
widget.GetWidget<LabelWidget>("MAP_TITLE").GetText =
() => mapStub != null ? mapStub.Title : "(Unknown Map)";
}
catch(Exception e)
{
Log.Write("debug", "Exception while parsing replay: {0}", e);
currentReplay = null;
}
panel.GetWidget<LabelWidget>("DURATION").GetText =
() => WidgetUtils.FormatTime(currentReplay.Duration * 3 /* todo: 3:1 ratio isnt always true. */);
panel.GetWidget<MapPreviewWidget>("MAP_PREVIEW").Map = () => currentMap;
panel.GetWidget<LabelWidget>("MAP_TITLE").GetText =
() => currentMap != null ? currentMap.Title : "(Unknown Map)";
var players = currentReplay.LobbyInfo.Slots
.Count(s => currentReplay.LobbyInfo.ClientInSlot(s.Key) != null);
panel.GetWidget<LabelWidget>("PLAYERS").GetText = () => players.ToString();
}
catch (Exception e)
{
Log.Write("debug", "Exception while parsing replay: {0}", e);
currentReplay = null;
currentMap = null;
}
}
void AddReplay(ScrollPanelWidget list, string filename, ScrollItemWidget template)
{
var item = ScrollItemWidget.Setup(template,
() => currentReplay == filename,
() => currentReplay != null && currentReplay.Filename == filename,
() => SelectReplay(filename));
var f = Path.GetFileName(filename);
item.GetWidget<LabelWidget>("TITLE").GetText = () => f;

View File

@@ -8,6 +8,7 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.FileFormats;
@@ -18,65 +19,88 @@ namespace OpenRA.Mods.RA.Widgets.Logic
{
public class ServerBrowserLogic
{
GameServer currentServer = null;
ScrollItemWidget ServerTemplate;
GameServer currentServer;
ScrollItemWidget serverTemplate;
enum SearchStatus { Fetching, Failed, NoGames, Hidden }
SearchStatus searchStatus = SearchStatus.Fetching;
public string ProgressLabelText()
{
switch (searchStatus)
{
case SearchStatus.Fetching: return "Fetching game list...";
case SearchStatus.Failed: return "Failed to contact master server.";
case SearchStatus.NoGames: return "No games found.";
default: return "";
}
}
[ObjectCreator.UseCtor]
public ServerBrowserLogic(Widget widget)
public ServerBrowserLogic(Widget widget, Action openLobby, Action onExit)
{
var bg = widget.GetWidget("JOINSERVER_BG");
var panel = widget;
var sl = panel.GetWidget<ScrollPanelWidget>("SERVER_LIST");
bg.GetWidget("JOINSERVER_PROGRESS_TITLE").Visible = true;
bg.GetWidget<LabelWidget>("JOINSERVER_PROGRESS_TITLE").Text = "Fetching game list...";
ServerList.Query(RefreshServerList);
bg.GetWidget("SERVER_INFO").IsVisible = () => currentServer != null;
var preview = bg.GetWidget<MapPreviewWidget>("MAP_PREVIEW");
preview.Map = () => CurrentMap();
preview.IsVisible = () => CurrentMap() != null;
bg.GetWidget<LabelWidget>("SERVER_IP").GetText = () => currentServer.Address;
bg.GetWidget<LabelWidget>("SERVER_MODS").GetText = () => GenerateModsLabel(currentServer);
bg.GetWidget<LabelWidget>("MAP_TITLE").GetText = () => (CurrentMap() != null) ? CurrentMap().Title : "Unknown";
bg.GetWidget<LabelWidget>("MAP_PLAYERS").GetText = () =>
// Menu buttons
var refreshButton = panel.GetWidget<ButtonWidget>("REFRESH_BUTTON");
refreshButton.IsDisabled = () => searchStatus == SearchStatus.Fetching;
refreshButton.OnClick = () =>
{
if (currentServer == null)
return "";
string ret = currentServer.Players.ToString();
if (CurrentMap() != null)
ret += "/" + CurrentMap().PlayerCount.ToString();
return ret;
};
var sl = bg.GetWidget<ScrollPanelWidget>("SERVER_LIST");
ServerTemplate = sl.GetWidget<ScrollItemWidget>("SERVER_TEMPLATE");
bg.GetWidget<ButtonWidget>("REFRESH_BUTTON").OnClick = () =>
{
bg.GetWidget("JOINSERVER_PROGRESS_TITLE").Visible = true;
bg.GetWidget<LabelWidget>("JOINSERVER_PROGRESS_TITLE").Text = "Fetching game list...";
searchStatus = SearchStatus.Fetching;
sl.RemoveChildren();
currentServer = null;
ServerList.Query(RefreshServerList);
ServerList.Query(games => RefreshServerList(panel, games));
};
bg.GetWidget<ButtonWidget>("CANCEL_BUTTON").OnClick = () => Widget.CloseWindow();
bg.GetWidget<ButtonWidget>("DIRECTCONNECT_BUTTON").OnClick = () =>
{
Widget.CloseWindow();
Widget.OpenWindow("DIRECTCONNECT_BG");
};
bg.GetWidget<ButtonWidget>("JOIN_BUTTON").OnClick = () =>
var join = panel.GetWidget<ButtonWidget>("JOIN_BUTTON");
join.IsDisabled = () => currentServer == null || !currentServer.CanJoin();
join.OnClick = () =>
{
if (currentServer == null)
return;
var host = currentServer.Address.Split(':')[0];
var port = int.Parse(currentServer.Address.Split(':')[1]);
Widget.CloseWindow();
Game.JoinServer(currentServer.Address.Split(':')[0], int.Parse(currentServer.Address.Split(':')[1]));
ConnectionLogic.Connect(host, port, openLobby, onExit);
};
panel.GetWidget<ButtonWidget>("BACK_BUTTON").OnClick = () => { Widget.CloseWindow(); onExit(); };
// Server list
serverTemplate = sl.GetWidget<ScrollItemWidget>("SERVER_TEMPLATE");
// Display the progress label over the server list
// The text is only visible when the list is empty
var progressText = panel.GetWidget<LabelWidget>("PROGRESS_LABEL");
progressText.IsVisible = () => searchStatus != SearchStatus.Hidden;
progressText.GetText = ProgressLabelText;
// Map preview
var preview = panel.GetWidget<MapPreviewWidget>("MAP_PREVIEW");
preview.Map = () => CurrentMap();
preview.IsVisible = () => CurrentMap() != null;
// Server info
var infoPanel = panel.GetWidget("SERVER_INFO");
infoPanel.IsVisible = () => currentServer != null;
infoPanel.GetWidget<LabelWidget>("SERVER_IP").GetText = () => currentServer.Address;
infoPanel.GetWidget<LabelWidget>("SERVER_MODS").GetText = () => ServerBrowserLogic.GenerateModsLabel(currentServer);
infoPanel.GetWidget<LabelWidget>("MAP_TITLE").GetText = () => (CurrentMap() != null) ? CurrentMap().Title : "Unknown";
infoPanel.GetWidget<LabelWidget>("MAP_PLAYERS").GetText = () => GetPlayersLabel(currentServer);
ServerList.Query(games => RefreshServerList(panel, games));
}
string GetPlayersLabel(GameServer game)
{
if (game == null)
return "";
var map = Game.modData.FindMapByUid(game.Map);
return map == null ? "{0}".F(currentServer.Players) : "{0} / {1}".F(currentServer.Players, map.PlayerCount);
}
Map CurrentMap()
@@ -97,23 +121,16 @@ namespace OpenRA.Mods.RA.Widgets.Logic
return s.UsefulMods.Select(m => GenerateModLabel(m)).JoinWith("\n");
}
void RefreshServerList(IEnumerable<GameServer> games)
public void RefreshServerList(Widget panel, IEnumerable<GameServer> games)
{
var r = Widget.RootWidget;
var bg = r.GetWidget("JOINSERVER_BG");
if (bg == null) // We got a MasterServer reply AFTER the browser is gone, just return to prevent crash - Gecko
return;
var sl = bg.GetWidget<ScrollPanelWidget>("SERVER_LIST");
var sl = panel.GetWidget<ScrollPanelWidget>("SERVER_LIST");
sl.RemoveChildren();
currentServer = null;
if (games == null)
{
r.GetWidget("JOINSERVER_PROGRESS_TITLE").Visible = true;
r.GetWidget<LabelWidget>("JOINSERVER_PROGRESS_TITLE").Text = "Failed to contact master server.";
searchStatus = SearchStatus.Failed;
return;
}
@@ -121,22 +138,28 @@ namespace OpenRA.Mods.RA.Widgets.Logic
if (gamesWaiting.Count() == 0)
{
r.GetWidget("JOINSERVER_PROGRESS_TITLE").Visible = true;
r.GetWidget<LabelWidget>("JOINSERVER_PROGRESS_TITLE").Text = "No games found.";
searchStatus = SearchStatus.NoGames;
return;
}
r.GetWidget("JOINSERVER_PROGRESS_TITLE").Visible = false;
searchStatus = SearchStatus.Hidden;
currentServer = gamesWaiting.FirstOrDefault();
foreach (var loop in gamesWaiting)
{
var game = loop;
var item = ScrollItemWidget.Setup(ServerTemplate,
() => currentServer == game,
() => currentServer = game);
item.GetWidget<LabelWidget>("TITLE").GetText = () => "{0} ({1})".F(game.Name, game.Address);
var item = ScrollItemWidget.Setup(serverTemplate, () => currentServer == game, () => currentServer = game);
item.GetWidget<LabelWidget>("TITLE").GetText = () => game.Name;
// TODO: Use game.MapTitle once the server supports it
item.GetWidget<LabelWidget>("MAP").GetText = () =>
{
var map = Game.modData.FindMapByUid(game.Map);
return map == null ? "Unknown" : map.Title;
};
// TODO: Use game.MaxPlayers once the server supports it
item.GetWidget<LabelWidget>("PLAYERS").GetText = () => GetPlayersLabel(game);
item.GetWidget<LabelWidget>("IP").GetText = () => game.Address;
sl.AddChild(item);
}
}

View File

@@ -0,0 +1,96 @@
#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.Net;
using OpenRA.GameRules;
using OpenRA.Widgets;
namespace OpenRA.Mods.RA.Widgets.Logic
{
public class ServerCreationLogic
{
Widget panel;
Action onCreate;
Action onExit;
Map map;
bool advertiseOnline;
[ObjectCreator.UseCtor]
public ServerCreationLogic(Widget widget, Action onExit, Action openLobby)
{
panel = widget;
onCreate = openLobby;
this.onExit = onExit;
var settings = Game.Settings;
panel.GetWidget<ButtonWidget>("BACK_BUTTON").OnClick = () => { Widget.CloseWindow(); onExit(); };
panel.GetWidget<ButtonWidget>("CREATE_BUTTON").OnClick = CreateAndJoin;
map = Game.modData.AvailableMaps[ WidgetUtils.ChooseInitialMap(Game.Settings.Server.Map) ];
var mapButton = panel.GetWidget<ButtonWidget>("MAP_BUTTON");
if (mapButton != null)
{
panel.GetWidget<ButtonWidget>("MAP_BUTTON").OnClick = () =>
{
Widget.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
{
{ "initialMap", map.Uid },
{ "onExit", () => {} },
{ "onSelect", (Action<Map>)(m => map = m) }
});
};
panel.GetWidget<MapPreviewWidget>("MAP_PREVIEW").Map = () => map;
panel.GetWidget<LabelWidget>("MAP_NAME").GetText = () => map.Title;
}
panel.GetWidget<TextFieldWidget>("SERVER_NAME").Text = settings.Server.Name ?? "";
panel.GetWidget<TextFieldWidget>("LISTEN_PORT").Text = settings.Server.ListenPort.ToString();
advertiseOnline = Game.Settings.Server.AdvertiseOnline;
var externalPort = panel.GetWidget<TextFieldWidget>("EXTERNAL_PORT");
externalPort.Text = settings.Server.ExternalPort.ToString();
externalPort.IsDisabled = () => !advertiseOnline;
var advertiseCheckbox = panel.GetWidget<CheckboxWidget>("ADVERTISE_CHECKBOX");
advertiseCheckbox.IsChecked = () => advertiseOnline;
advertiseCheckbox.OnClick = () => advertiseOnline ^= true;
}
void CreateAndJoin()
{
var name = panel.GetWidget<TextFieldWidget>("SERVER_NAME").Text;
int listenPort, externalPort;
if (!int.TryParse(panel.GetWidget<TextFieldWidget>("LISTEN_PORT").Text, out listenPort))
listenPort = 1234;
if (!int.TryParse(panel.GetWidget<TextFieldWidget>("EXTERNAL_PORT").Text, out externalPort))
externalPort = 1234;
// Save new settings
Game.Settings.Server.Name = name;
Game.Settings.Server.ListenPort = listenPort;
Game.Settings.Server.ExternalPort = externalPort;
Game.Settings.Server.AdvertiseOnline = advertiseOnline;
Game.Settings.Server.Map = map.Uid;
Game.Settings.Save();
// Take a copy so that subsequent changes don't affect the server
var settings = new ServerSettings(Game.Settings.Server);
// Create and join the server
Game.CreateServer(settings);
Widget.CloseWindow();
ConnectionLogic.Connect(IPAddress.Loopback.ToString(), Game.Settings.Server.ListenPort, onCreate, onExit);
}
}
}