added ready/gamestart handling
This commit is contained in:
@@ -15,6 +15,9 @@ namespace OpenRA.Server
|
|||||||
public int ExpectLength = 8;
|
public int ExpectLength = 8;
|
||||||
public int Frame = 0;
|
public int Frame = 0;
|
||||||
|
|
||||||
|
/* client data */
|
||||||
|
public bool IsReady;
|
||||||
|
|
||||||
public byte[] PopBytes(int n)
|
public byte[] PopBytes(int n)
|
||||||
{
|
{
|
||||||
var result = data.GetRange(0, n);
|
var result = data.GetRange(0, n);
|
||||||
|
|||||||
@@ -10,6 +10,55 @@ using System.Collections;
|
|||||||
|
|
||||||
namespace OpenRA.Server
|
namespace OpenRA.Server
|
||||||
{
|
{
|
||||||
|
class ServerOrder
|
||||||
|
{
|
||||||
|
public readonly int PlayerId;
|
||||||
|
public readonly string Name;
|
||||||
|
public readonly string Data;
|
||||||
|
|
||||||
|
public ServerOrder(int playerId, string name, string data)
|
||||||
|
{
|
||||||
|
PlayerId = playerId;
|
||||||
|
Name = name;
|
||||||
|
Data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ServerOrder Deserialize(BinaryReader r)
|
||||||
|
{
|
||||||
|
byte b;
|
||||||
|
switch (b = r.ReadByte())
|
||||||
|
{
|
||||||
|
case 0xff:
|
||||||
|
Console.WriteLine("This isn't a server order.");
|
||||||
|
return null;
|
||||||
|
|
||||||
|
case 0xfe:
|
||||||
|
{
|
||||||
|
var playerID = r.ReadInt32();
|
||||||
|
var name = r.ReadString();
|
||||||
|
var data = r.ReadString();
|
||||||
|
|
||||||
|
return new ServerOrder(playerID, name, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException(b.ToString("x2"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] Serialize()
|
||||||
|
{
|
||||||
|
var ms = new MemoryStream();
|
||||||
|
var bw = new BinaryWriter(ms);
|
||||||
|
|
||||||
|
bw.Write((byte)0xfe);
|
||||||
|
bw.Write(PlayerId);
|
||||||
|
bw.Write(Name);
|
||||||
|
bw.Write(Data);
|
||||||
|
return ms.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static class Server
|
static class Server
|
||||||
{
|
{
|
||||||
static List<Connection> conns = new List<Connection>();
|
static List<Connection> conns = new List<Connection>();
|
||||||
@@ -27,10 +76,11 @@ namespace OpenRA.Server
|
|||||||
checkRead.Add(listener.Server);
|
checkRead.Add(listener.Server);
|
||||||
foreach (var c in conns) checkRead.Add(c.socket);
|
foreach (var c in conns) checkRead.Add(c.socket);
|
||||||
|
|
||||||
Socket.Select(checkRead, null, null, 1000000 /* 1s */);
|
/* msdn lies, -1 doesnt work. this is ~1h instead. */
|
||||||
|
Socket.Select(checkRead, null, null, -2 );
|
||||||
|
|
||||||
Console.WriteLine("Select() completed with {0} sockets",
|
//Console.WriteLine("Select() completed with {0} sockets",
|
||||||
checkRead.Count);
|
// checkRead.Count);
|
||||||
|
|
||||||
foreach (Socket s in checkRead)
|
foreach (Socket s in checkRead)
|
||||||
if (s == listener.Server) AcceptConnection();
|
if (s == listener.Server) AcceptConnection();
|
||||||
@@ -62,7 +112,7 @@ namespace OpenRA.Server
|
|||||||
{
|
{
|
||||||
if (0 < (len = conn.socket.Receive(rx)))
|
if (0 < (len = conn.socket.Receive(rx)))
|
||||||
{
|
{
|
||||||
Console.WriteLine("Read {0} bytes", len);
|
// Console.WriteLine("Read {0} bytes", len);
|
||||||
conn.data.AddRange(rx.Take(len));
|
conn.data.AddRange(rx.Take(len));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -81,8 +131,8 @@ namespace OpenRA.Server
|
|||||||
|
|
||||||
static void ReadData(Connection conn)
|
static void ReadData(Connection conn)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Start ReadData() for {0}",
|
//Console.WriteLine("Start ReadData() for {0}",
|
||||||
conn.socket.RemoteEndPoint);
|
// conn.socket.RemoteEndPoint);
|
||||||
|
|
||||||
if (ReadDataInner(conn))
|
if (ReadDataInner(conn))
|
||||||
while (conn.data.Count >= conn.ExpectLength)
|
while (conn.data.Count >= conn.ExpectLength)
|
||||||
@@ -106,8 +156,8 @@ namespace OpenRA.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("End ReadData() for {0}",
|
//Console.WriteLine("End ReadData() for {0}",
|
||||||
conn.socket.RemoteEndPoint);
|
// conn.socket.RemoteEndPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DispatchOrders(Connection conn, int frame, byte[] data)
|
static void DispatchOrders(Connection conn, int frame, byte[] data)
|
||||||
@@ -125,13 +175,40 @@ namespace OpenRA.Server
|
|||||||
catch (Exception e) { DropClient(c, e); }
|
catch (Exception e) { DropClient(c, e); }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame == 0)
|
if (frame == 0 && conn != null)
|
||||||
InterpretServerOrders(data);
|
InterpretServerOrders(conn, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void InterpretServerOrders(byte[] data)
|
static void InterpretServerOrders(Connection conn, byte[] data)
|
||||||
{
|
{
|
||||||
/* todo: handle all server orders! */
|
var ms = new MemoryStream(data);
|
||||||
|
var br = new BinaryReader(ms);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (; ; )
|
||||||
|
{
|
||||||
|
var so = ServerOrder.Deserialize(br);
|
||||||
|
if (so == null) return;
|
||||||
|
InterpretServerOrder(conn, so);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (EndOfStreamException) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InterpretServerOrder(Connection conn, ServerOrder so)
|
||||||
|
{
|
||||||
|
switch (so.Name)
|
||||||
|
{
|
||||||
|
case "ToggleReady":
|
||||||
|
conn.IsReady ^= true;
|
||||||
|
|
||||||
|
// start the game if everyone is ready.
|
||||||
|
if (conns.All(c => c.IsReady))
|
||||||
|
DispatchOrders(null, 0,
|
||||||
|
new ServerOrder(0, "StartGame", "").Serialize());
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DropClient(Connection c, Exception e)
|
static void DropClient(Connection c, Exception e)
|
||||||
|
|||||||
@@ -86,13 +86,14 @@ namespace OpenRa.Game
|
|||||||
buildItems.Clear();
|
buildItems.Clear();
|
||||||
|
|
||||||
renderer.Device.DisableScissor();
|
renderer.Device.DisableScissor();
|
||||||
renderer.DrawText(string.Format("RenderFrame {0} ({2:F1} ms)\nTick {1} ({3:F1} ms)\n$ {4}\nPower {5}",
|
renderer.DrawText(string.Format("RenderFrame {0} ({2:F1} ms)\nTick {1} ({3:F1} ms)\n$ {4}\nPower {5}\nReady: {6}",
|
||||||
Game.RenderFrame,
|
Game.RenderFrame,
|
||||||
Game.orderManager.FrameNumber,
|
Game.orderManager.FrameNumber,
|
||||||
PerfHistory.items["render"].LastValue,
|
PerfHistory.items["render"].LastValue,
|
||||||
PerfHistory.items["tick_time"].LastValue,
|
PerfHistory.items["tick_time"].LastValue,
|
||||||
Game.LocalPlayer.DisplayCash,
|
Game.LocalPlayer.DisplayCash,
|
||||||
Game.LocalPlayer.GetTotalPower()
|
Game.LocalPlayer.GetTotalPower(),
|
||||||
|
Game.LocalPlayer.IsReady ? "Yes" : "No"
|
||||||
), new int2(140, 5), Color.White);
|
), new int2(140, 5), Color.White);
|
||||||
|
|
||||||
PerfHistory.Render(renderer, Game.worldRenderer.lineRenderer);
|
PerfHistory.Render(renderer, Game.worldRenderer.lineRenderer);
|
||||||
|
|||||||
@@ -129,8 +129,13 @@ namespace OpenRa.Game
|
|||||||
base.OnKeyDown(e);
|
base.OnKeyDown(e);
|
||||||
|
|
||||||
/* hack hack hack */
|
/* hack hack hack */
|
||||||
if (e.KeyCode == Keys.F8 && !Game.orderManager.GameStarted)
|
if (e.KeyCode == Keys.F8)
|
||||||
Game.orderManager.StartGame();
|
{
|
||||||
|
Game.LocalPlayer.IsReady ^= true;
|
||||||
|
Game.controller.AddOrder(
|
||||||
|
new Order(Game.LocalPlayer,
|
||||||
|
"ToggleReady", null, null, int2.Zero, "") { IsImmediate = true });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnKeyPress(KeyPressEventArgs e)
|
protected override void OnKeyPress(KeyPressEventArgs e)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace OpenRa.Game
|
|||||||
public readonly string TargetString;
|
public readonly string TargetString;
|
||||||
public bool IsImmediate;
|
public bool IsImmediate;
|
||||||
|
|
||||||
Order(Player player, string orderString, Actor subject,
|
public Order(Player player, string orderString, Actor subject,
|
||||||
Actor targetActor, int2 targetLocation, string targetString)
|
Actor targetActor, int2 targetLocation, string targetString)
|
||||||
{
|
{
|
||||||
this.Player = player;
|
this.Player = player;
|
||||||
@@ -30,6 +30,17 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
public byte[] Serialize()
|
public byte[] Serialize()
|
||||||
{
|
{
|
||||||
|
if (IsImmediate) /* chat, whatever */
|
||||||
|
{
|
||||||
|
var ret = new MemoryStream();
|
||||||
|
var w = new BinaryWriter(ret);
|
||||||
|
w.Write((byte)0xfe);
|
||||||
|
w.Write((uint)Player.Index);
|
||||||
|
w.Write(OrderString);
|
||||||
|
w.Write(TargetString);
|
||||||
|
return ret.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
switch (OrderString)
|
switch (OrderString)
|
||||||
{
|
{
|
||||||
// Format:
|
// Format:
|
||||||
@@ -56,6 +67,13 @@ namespace OpenRa.Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Player LookupPlayer(uint index)
|
||||||
|
{
|
||||||
|
return Game.players
|
||||||
|
.Where(x => x.Value.Index == index)
|
||||||
|
.First().Value;
|
||||||
|
}
|
||||||
|
|
||||||
public static Order Deserialize(BinaryReader r)
|
public static Order Deserialize(BinaryReader r)
|
||||||
{
|
{
|
||||||
switch (r.ReadByte())
|
switch (r.ReadByte())
|
||||||
@@ -72,9 +90,21 @@ namespace OpenRa.Game
|
|||||||
if (r.ReadBoolean())
|
if (r.ReadBoolean())
|
||||||
targetString = r.ReadString();
|
targetString = r.ReadString();
|
||||||
|
|
||||||
var player = Game.players.Where( x => x.Value.Index == playerID ).First().Value;
|
return new Order( LookupPlayer(playerID),
|
||||||
return new Order( player, order, subject, targetActor, targetLocation, targetString);
|
order, subject, targetActor, targetLocation,
|
||||||
|
targetString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 0xfe:
|
||||||
|
{
|
||||||
|
var playerID = r.ReadUInt32();
|
||||||
|
var name = r.ReadString();
|
||||||
|
var data = r.ReadString();
|
||||||
|
|
||||||
|
return new Order(LookupPlayer(playerID),
|
||||||
|
name, null, null, int2.Zero, data);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ namespace OpenRa.Game
|
|||||||
int powerProvided;
|
int powerProvided;
|
||||||
int powerDrained;
|
int powerDrained;
|
||||||
|
|
||||||
|
public bool IsReady;
|
||||||
|
|
||||||
public Player( int index, int palette, string playerName, Race race )
|
public Player( int index, int palette, string playerName, Race race )
|
||||||
{
|
{
|
||||||
this.Index = index;
|
this.Index = index;
|
||||||
|
|||||||
@@ -97,6 +97,22 @@ namespace OpenRa.Game
|
|||||||
Game.chat.AddLine(Pair.New(order.Player.PlayerName + ":", order.TargetString));
|
Game.chat.AddLine(Pair.New(order.Player.PlayerName + ":", order.TargetString));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "ToggleReady":
|
||||||
|
{
|
||||||
|
Game.chat.AddLine(Pair.New(order.Player.PlayerName, "toggled ready status" ));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "AssignPlayer":
|
||||||
|
{
|
||||||
|
break; /* todo: set LocalPlayer based on this */
|
||||||
|
}
|
||||||
|
case "StartGame":
|
||||||
|
{
|
||||||
|
Game.chat.AddLine(Pair.New("Server:", "The game has started."));
|
||||||
|
Game.orderManager.StartGame();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user