ugly hacked async connection

This commit is contained in:
Chris Forbes
2010-01-18 18:08:10 +13:00
parent b7c5b9e265
commit f6e70f74e3
4 changed files with 77 additions and 21 deletions

View File

@@ -210,6 +210,15 @@ namespace OpenRa
lineRenderer.Flush(); 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() public void DrawLobby()
{ {
DrawDownloadBar(); DrawDownloadBar();

View File

@@ -2,6 +2,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Windows.Forms; using System.Windows.Forms;
using OpenRa.Traits; using OpenRa.Traits;
using OpenRa.Orders;
namespace OpenRa.Graphics namespace OpenRa.Graphics
{ {
@@ -55,7 +56,24 @@ namespace OpenRa.Graphics
} }
else else
{ {
Game.chrome.DrawLobby(); if (Game.orderManager.IsNetplay)
{
var nos = Game.orderManager.Sources.OfType<NetworkOrderSource>().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(); var c = Game.chrome.HitTest(mousePos) ? Cursor.Default : Game.controller.ChooseCursor();

View File

@@ -3,9 +3,17 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
using System;
namespace OpenRa.Orders namespace OpenRa.Orders
{ {
enum ConnectionState
{
NotConnected,
Connecting,
Connected,
}
class NetworkOrderSource : IOrderSource class NetworkOrderSource : IOrderSource
{ {
TcpClient socket; TcpClient socket;
@@ -13,35 +21,53 @@ namespace OpenRa.Orders
Dictionary<int, List<byte[]>> orderBuffers = new Dictionary<int, List<byte[]>>(); Dictionary<int, List<byte[]>> orderBuffers = new Dictionary<int, List<byte[]>>();
Dictionary<int, bool> gotEverything = new Dictionary<int, bool>(); Dictionary<int, bool> gotEverything = new Dictionary<int, bool>();
public ConnectionState State { get; private set; }
public NetworkOrderSource(string host, int port) public NetworkOrderSource(string host, int port)
{ {
socket = new TcpClient(host, port); State = ConnectionState.Connecting;
this.socket.NoDelay = true;
var reader = new BinaryReader(socket.GetStream());
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(); for (; ; )
var frame = reader.ReadInt32();
var buf = reader.ReadBytes(len - 4);
lock (orderBuffers)
{ {
if (len == 5 && buf[0] == 0xef) /* got everything marker */ var reader = new BinaryReader(socket.GetStream());
gotEverything[frame] = true;
else var len = reader.ReadInt32();
var frame = reader.ReadInt32();
var buf = reader.ReadBytes(len - 4);
lock (orderBuffers)
{ {
/* accumulate this chunk */ if (len == 5 && buf[0] == 0xef) /* got everything marker */
if (!orderBuffers.ContainsKey(frame)) gotEverything[frame] = true;
orderBuffers[frame] = new List<byte[]> { buf };
else else
orderBuffers[frame].Add(buf); {
/* accumulate this chunk */
if (!orderBuffers.ContainsKey(frame))
orderBuffers[frame] = new List<byte[]> { buf };
else
orderBuffers[frame].Add(buf);
}
} }
} }
} }) { IsBackground = true }.Start();
}) { IsBackground = true }.Start(); }
catch
{
State = ConnectionState.NotConnected;
}
} }
static List<byte[]> NoOrders = new List<byte[]>(); static List<byte[]> NoOrders = new List<byte[]>();
@@ -66,7 +92,8 @@ namespace OpenRa.Orders
public void SendLocalOrders(int localFrame, List<Order> localOrders) public void SendLocalOrders(int localFrame, List<Order> localOrders)
{ {
socket.GetStream().WriteFrameData(localOrders, localFrame); if (socket.Connected)
socket.GetStream().WriteFrameData(localOrders, localFrame);
} }
public bool IsReadyForFrame(int frameNumber) public bool IsReadyForFrame(int frameNumber)

View File

@@ -26,6 +26,8 @@ namespace OpenRa.Orders
p.SendLocalOrders(i, new List<Order>()); p.SendLocalOrders(i, new List<Order>());
} }
public IEnumerable<IOrderSource> Sources { get { return sources; } }
public int FrameNumber { get { return frameNumber; } } public int FrameNumber { get { return frameNumber; } }
public OrderManager( IEnumerable<IOrderSource> sources ) public OrderManager( IEnumerable<IOrderSource> sources )