#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 OpenRA.FileFormats; using OpenRA.Server; using OpenRA.Widgets; using OpenRA.Mods.RA.Widgets.Delegates; namespace OpenRA.Mods.Cnc.Widgets { public class CncServerBrowserLogic : IWidgetDelegate { // Prevent repeated additions of RefreshServerList to the master server static bool masterServerSetup; GameServer currentServer = null; Widget 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 CncServerBrowserLogic( [ObjectCreator.Param] Widget widget, [ObjectCreator.Param] Action onExit ) { var panel = widget.GetWidget("SERVERBROWSER_PANEL"); var sl = panel.GetWidget("SERVER_LIST"); // Menu buttons panel.GetWidget("REFRESH_BUTTON").OnMouseUp = mi => { searchStatus = SearchStatus.Fetching; sl.RemoveChildren(); MasterServerQuery.Refresh(Game.Settings.Server.MasterServer); return true; }; var join = panel.GetWidget("JOIN_BUTTON"); join.IsVisible = () => currentServer != null && ServerBrowserDelegate.CanJoin(currentServer); join.OnMouseUp = mi => { if (currentServer == null) return false; Widget.CloseWindow(); Game.JoinServer(currentServer.Address.Split(':')[0], int.Parse(currentServer.Address.Split(':')[1])); return true; }; panel.GetWidget("BACK_BUTTON").OnMouseUp = mi => { onExit(); return true; }; // Server list serverTemplate = sl.GetWidget("SERVER_TEMPLATE"); // Display the progress label over the server list // The text is only visible when the list is empty var progressText = panel.GetWidget("PROGRESS_LABEL"); progressText.IsVisible = () => searchStatus != SearchStatus.Hidden; progressText.GetText = ProgressLabelText; // Server info var infoPanel = panel.GetWidget("SERVER_INFO"); infoPanel.IsVisible = () => currentServer != null; var preview = infoPanel.GetWidget("MAP_PREVIEW"); preview.Map = () => CurrentMap(); preview.IsVisible = () => CurrentMap() != null; infoPanel.GetWidget("SERVER_IP").GetText = () => currentServer.Address; infoPanel.GetWidget("SERVER_MODS").GetText = () => ServerBrowserDelegate.GenerateModsLabel(currentServer); infoPanel.GetWidget("MAP_TITLE").GetText = () => (CurrentMap() != null) ? CurrentMap().Title : "Unknown"; infoPanel.GetWidget("MAP_PLAYERS").GetText = () => { if (currentServer == null) return ""; string ret = currentServer.Players.ToString(); if (CurrentMap() != null) ret += "/" + CurrentMap().PlayerCount.ToString(); return ret; }; // Master server should be set up *once* if (!masterServerSetup) { masterServerSetup = true; MasterServerQuery.OnComplete += games => RefreshServerListStub(games); } MasterServerQuery.Refresh(Game.Settings.Server.MasterServer); } Map CurrentMap() { return (currentServer == null) ? null : GetMap(currentServer.Map); } static Map GetMap(string uid) { return (!Game.modData.AvailableMaps.ContainsKey(uid)) ? null : Game.modData.AvailableMaps[uid]; } public void RefreshServerList(IEnumerable games) { var sl = Widget.RootWidget.GetWidget("SERVERBROWSER_PANEL") .GetWidget("SERVER_LIST"); sl.RemoveChildren(); currentServer = null; if (games == null) { searchStatus = SearchStatus.Failed; return; } var gamesWaiting = games.Where(g => ServerBrowserDelegate.CanJoin(g)); if (gamesWaiting.Count() == 0) { searchStatus = SearchStatus.NoGames; return; } searchStatus = SearchStatus.Hidden; int i = 0; foreach (var loop in gamesWaiting) { var game = loop; var template = serverTemplate.Clone() as ContainerWidget; template.GetBackground = () => (currentServer == game) ? "dialog2" : null; template.OnMouseDown = mi => { if (mi.Button != MouseButton.Left) return false; currentServer = game; return true; }; template.IsVisible = () => true; template.GetWidget("TITLE").GetText = () => game.Name; template.GetWidget("MAP").GetText = () => {var map = GetMap(game.Map); return map == null ? "Unknown" : map.Title;}; template.GetWidget("PLAYERS").GetText = () => "{0} / {1}".F(game.Players, -1); template.GetWidget("IP").GetText = () => game.Address; sl.AddChild(template); if (i == 0) currentServer = game; i++; } } static void RefreshServerListStub(IEnumerable games) { var panel = Widget.RootWidget.GetWidget("SERVERBROWSER_PANEL"); // The panel may not be open anymore if (panel == null) return; var browserLogic = panel.DelegateObject as CncServerBrowserLogic; if (browserLogic == null) return; browserLogic.RefreshServerList(games); } } }