diff --git a/OpenRa.Game/Chrome.cs b/OpenRa.Game/Chrome.cs index b45eb6b6a6..3ec1c36fb1 100644 --- a/OpenRa.Game/Chrome.cs +++ b/OpenRa.Game/Chrome.cs @@ -210,6 +210,15 @@ namespace OpenRa lineRenderer.Flush(); } + public void DrawDialog(string text) + { + var w = renderer.MeasureText(text).X + 120; + var h = 100; + var r = new Rectangle((Game.viewport.Width - w) / 2, (Game.viewport.Height - h) / 2, w, h); + DrawDialogBackground(r, optionsSprites, true); + DrawCentered(text, new int2(Game.viewport.Width / 2, Game.viewport.Height / 2 - 8), Color.White); + } + public void DrawLobby() { DrawDownloadBar(); diff --git a/OpenRa.Game/Graphics/Viewport.cs b/OpenRa.Game/Graphics/Viewport.cs index ca6a1546aa..14e080b2a1 100644 --- a/OpenRa.Game/Graphics/Viewport.cs +++ b/OpenRa.Game/Graphics/Viewport.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using OpenRa.Traits; +using OpenRa.Orders; namespace OpenRa.Graphics { @@ -55,7 +56,24 @@ namespace OpenRa.Graphics } else { - Game.chrome.DrawLobby(); + if (Game.orderManager.IsNetplay) + { + var nos = Game.orderManager.Sources.OfType().First(); + switch (nos.State) + { + case ConnectionState.Connecting: + Game.chrome.DrawDialog("Connecting to server..."); + break; + case ConnectionState.NotConnected: + Game.chrome.DrawDialog("Connection failed."); + break; + case ConnectionState.Connected: + Game.chrome.DrawLobby(); + break; + } + } + else + Game.chrome.DrawLobby(); } var c = Game.chrome.HitTest(mousePos) ? Cursor.Default : Game.controller.ChooseCursor(); diff --git a/OpenRa.Game/Orders/NetworkOrderSource.cs b/OpenRa.Game/Orders/NetworkOrderSource.cs index 052bd3643c..0065dc0a0b 100644 --- a/OpenRa.Game/Orders/NetworkOrderSource.cs +++ b/OpenRa.Game/Orders/NetworkOrderSource.cs @@ -3,9 +3,17 @@ using System.IO; using System.Linq; using System.Net.Sockets; using System.Threading; +using System; namespace OpenRa.Orders { + enum ConnectionState + { + NotConnected, + Connecting, + Connected, + } + class NetworkOrderSource : IOrderSource { TcpClient socket; @@ -13,35 +21,53 @@ namespace OpenRa.Orders Dictionary> orderBuffers = new Dictionary>(); Dictionary gotEverything = new Dictionary(); + public ConnectionState State { get; private set; } + public NetworkOrderSource(string host, int port) { - socket = new TcpClient(host, port); - this.socket.NoDelay = true; - var reader = new BinaryReader(socket.GetStream()); + State = ConnectionState.Connecting; - new Thread(() => + socket = new TcpClient(); + socket.BeginConnect(host, port, OnConnected, null); + socket.NoDelay = true; + } + + void OnConnected(IAsyncResult r) + { + try { - for (; ; ) + socket.EndConnect(r); + State = ConnectionState.Connected; + new Thread(() => { - var len = reader.ReadInt32(); - var frame = reader.ReadInt32(); - var buf = reader.ReadBytes(len - 4); - - lock (orderBuffers) + for (; ; ) { - if (len == 5 && buf[0] == 0xef) /* got everything marker */ - gotEverything[frame] = true; - else + var reader = new BinaryReader(socket.GetStream()); + + var len = reader.ReadInt32(); + var frame = reader.ReadInt32(); + var buf = reader.ReadBytes(len - 4); + + lock (orderBuffers) { - /* accumulate this chunk */ - if (!orderBuffers.ContainsKey(frame)) - orderBuffers[frame] = new List { buf }; + if (len == 5 && buf[0] == 0xef) /* got everything marker */ + gotEverything[frame] = true; else - orderBuffers[frame].Add(buf); + { + /* accumulate this chunk */ + if (!orderBuffers.ContainsKey(frame)) + orderBuffers[frame] = new List { buf }; + else + orderBuffers[frame].Add(buf); + } } } - } - }) { IsBackground = true }.Start(); + }) { IsBackground = true }.Start(); + } + catch + { + State = ConnectionState.NotConnected; + } } static List NoOrders = new List(); @@ -66,7 +92,8 @@ namespace OpenRa.Orders public void SendLocalOrders(int localFrame, List localOrders) { - socket.GetStream().WriteFrameData(localOrders, localFrame); + if (socket.Connected) + socket.GetStream().WriteFrameData(localOrders, localFrame); } public bool IsReadyForFrame(int frameNumber) diff --git a/OpenRa.Game/Orders/OrderManager.cs b/OpenRa.Game/Orders/OrderManager.cs index d149ec15e2..1a5dfd1d2d 100644 --- a/OpenRa.Game/Orders/OrderManager.cs +++ b/OpenRa.Game/Orders/OrderManager.cs @@ -26,6 +26,8 @@ namespace OpenRa.Orders p.SendLocalOrders(i, new List()); } + public IEnumerable Sources { get { return sources; } } + public int FrameNumber { get { return frameNumber; } } public OrderManager( IEnumerable sources )