lobby info hax
This commit is contained in:
@@ -51,6 +51,17 @@
|
|||||||
<Compile Include="Connection.cs" />
|
<Compile Include="Connection.cs" />
|
||||||
<Compile Include="Server.cs" />
|
<Compile Include="Server.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="ServerOrder.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\OpenRa.DataStructures\OpenRa.DataStructures.csproj">
|
||||||
|
<Project>{2F9E7A23-56C0-4286-9C8E-1060A9B2F073}</Project>
|
||||||
|
<Name>OpenRa.DataStructures</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\OpenRa.FileFormats\OpenRa.FileFormats.csproj">
|
||||||
|
<Project>{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}</Project>
|
||||||
|
<Name>OpenRa.FileFormats</Name>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
|||||||
@@ -1,70 +1,21 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Net.Sockets;
|
|
||||||
using System.Threading;
|
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using OpenRa.FileFormats;
|
||||||
|
|
||||||
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>();
|
||||||
static TcpListener listener = new TcpListener(IPAddress.Any, 1234);
|
static TcpListener listener = new TcpListener(IPAddress.Any, 1234);
|
||||||
static Dictionary<int, List<Connection>> inFlightFrames
|
static Dictionary<int, List<Connection>> inFlightFrames
|
||||||
= new Dictionary<int, List<Connection>>();
|
= new Dictionary<int, List<Connection>>();
|
||||||
|
static Session lobbyInfo = new Session();
|
||||||
|
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
@@ -109,16 +60,26 @@ namespace OpenRA.Server
|
|||||||
|
|
||||||
conns.Add(newConn);
|
conns.Add(newConn);
|
||||||
|
|
||||||
|
lobbyInfo.Clients.Add(
|
||||||
|
new Session.Client()
|
||||||
|
{
|
||||||
|
Index = newConn.PlayerIndex,
|
||||||
|
Palette = newConn.PlayerIndex,
|
||||||
|
Name = "Player {0}".F(newConn.PlayerIndex),
|
||||||
|
Race = 1,
|
||||||
|
State = Session.ClientState.NotReady
|
||||||
|
});
|
||||||
|
|
||||||
DispatchOrdersToClient(newConn, 0,
|
DispatchOrdersToClient(newConn, 0,
|
||||||
new ServerOrder(newConn.PlayerIndex, "AssignPlayer", "").Serialize());
|
new ServerOrder(newConn.PlayerIndex, "AssignPlayer", "").Serialize());
|
||||||
|
|
||||||
// todo: tell this client about all the other conns.
|
|
||||||
|
|
||||||
Console.WriteLine("Accepted connection from {0}.",
|
Console.WriteLine("Accepted connection from {0}.",
|
||||||
newConn.socket.RemoteEndPoint);
|
newConn.socket.RemoteEndPoint);
|
||||||
|
|
||||||
DispatchOrders(newConn, 0, new ServerOrder(newConn.PlayerIndex,
|
DispatchOrders(newConn, 0, new ServerOrder(newConn.PlayerIndex,
|
||||||
"Chat", "has joined the game.").Serialize());
|
"Chat", "has joined the game.").Serialize());
|
||||||
|
|
||||||
|
SyncLobbyInfo();
|
||||||
}
|
}
|
||||||
catch (Exception e) { DropClient(newConn, e); }
|
catch (Exception e) { DropClient(newConn, e); }
|
||||||
}
|
}
|
||||||
@@ -165,8 +126,8 @@ namespace OpenRA.Server
|
|||||||
|
|
||||||
case ReceiveState.Data:
|
case ReceiveState.Data:
|
||||||
{
|
{
|
||||||
if (bytes.Length > 0)
|
// if (bytes.Length > 0)
|
||||||
Console.WriteLine("{0} bytes", bytes.Length);
|
// Console.WriteLine("{0} bytes", bytes.Length);
|
||||||
|
|
||||||
DispatchOrders(conn, conn.Frame, bytes);
|
DispatchOrders(conn, conn.Frame, bytes);
|
||||||
conn.ExpectLength = 8;
|
conn.ExpectLength = 8;
|
||||||
@@ -242,7 +203,8 @@ namespace OpenRA.Server
|
|||||||
s =>
|
s =>
|
||||||
{
|
{
|
||||||
Console.WriteLine("Player@{0} is now known as {1}", conn.socket.RemoteEndPoint, s);
|
Console.WriteLine("Player@{0} is now known as {1}", conn.socket.RemoteEndPoint, s);
|
||||||
DispatchOrders( null, 0, new ServerOrder( conn.PlayerIndex, "SetName", s ).Serialize());
|
lobbyInfo.Clients[ conn.PlayerIndex ].Name = s;
|
||||||
|
SyncLobbyInfo();
|
||||||
return true;
|
return true;
|
||||||
}},
|
}},
|
||||||
{ "lag",
|
{ "lag",
|
||||||
@@ -275,8 +237,8 @@ namespace OpenRA.Server
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DispatchOrders(null, 0,
|
lobbyInfo.Clients[ conn.PlayerIndex ].Race = 1 + race;
|
||||||
new ServerOrder(conn.PlayerIndex, "SetRace", race.ToString()).Serialize());
|
SyncLobbyInfo();
|
||||||
return true;
|
return true;
|
||||||
}},
|
}},
|
||||||
{ "pal",
|
{ "pal",
|
||||||
@@ -297,8 +259,8 @@ namespace OpenRA.Server
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DispatchOrders(null, 0,
|
lobbyInfo.Clients[ conn.PlayerIndex ].Palette = pal;
|
||||||
new ServerOrder(conn.PlayerIndex, "SetPalette", pal.ToString()).Serialize());
|
SyncLobbyInfo();
|
||||||
return true;
|
return true;
|
||||||
}},
|
}},
|
||||||
{ "map",
|
{ "map",
|
||||||
@@ -379,11 +341,13 @@ namespace OpenRA.Server
|
|||||||
static void DropClient(Connection toDrop, Exception e)
|
static void DropClient(Connection toDrop, Exception e)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Client dropped: {0}.", toDrop.socket.RemoteEndPoint);
|
Console.WriteLine("Client dropped: {0}.", toDrop.socket.RemoteEndPoint);
|
||||||
Console.WriteLine(e.ToString());
|
//Console.WriteLine(e.ToString());
|
||||||
|
|
||||||
conns.Remove(toDrop);
|
conns.Remove(toDrop);
|
||||||
SendChat(toDrop, "Connection Dropped");
|
SendChat(toDrop, "Connection Dropped");
|
||||||
|
|
||||||
|
lobbyInfo.Clients.RemoveAll(c => c.Index == toDrop.PlayerIndex);
|
||||||
|
|
||||||
/* don't get stuck waiting for the dropped player, if they were the one holding up a frame */
|
/* don't get stuck waiting for the dropped player, if they were the one holding up a frame */
|
||||||
|
|
||||||
foreach( var f in inFlightFrames.ToArray() )
|
foreach( var f in inFlightFrames.ToArray() )
|
||||||
@@ -392,6 +356,9 @@ namespace OpenRA.Server
|
|||||||
inFlightFrames.Remove(f.Key);
|
inFlightFrames.Remove(f.Key);
|
||||||
DispatchOrders(null, f.Key, new byte[] { 0xef });
|
DispatchOrders(null, f.Key, new byte[] { 0xef });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conns.Count == 0) OnServerEmpty();
|
||||||
|
else SyncLobbyInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Write(this Stream s, byte[] data) { s.Write(data, 0, data.Length); }
|
public static void Write(this Stream s, byte[] data) { s.Write(data, 0, data.Length); }
|
||||||
@@ -400,5 +367,22 @@ namespace OpenRA.Server
|
|||||||
{
|
{
|
||||||
return ts.Except(new[] { t });
|
return ts.Except(new[] { t });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void OnServerEmpty()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Server emptied out; doing a bit of housekeeping to prepare for next game..");
|
||||||
|
inFlightFrames.Clear();
|
||||||
|
lobbyInfo = new Session();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SyncLobbyInfo()
|
||||||
|
{
|
||||||
|
var clientData = lobbyInfo.Clients.ToDictionary(
|
||||||
|
a => a.Index.ToString(),
|
||||||
|
a => FieldSaver.Save(a)).WriteToString();
|
||||||
|
|
||||||
|
DispatchOrders(null, 0,
|
||||||
|
new ServerOrder(0, "SyncInfo", clientData).Serialize());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
54
OpenRA.Server/ServerOrder.cs
Normal file
54
OpenRA.Server/ServerOrder.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,25 +8,24 @@ namespace OpenRa.FileFormats
|
|||||||
public class Session
|
public class Session
|
||||||
{
|
{
|
||||||
public List<Client> Clients = new List<Client>();
|
public List<Client> Clients = new List<Client>();
|
||||||
public string Map = "scm12ea.ini";
|
// todo: add mods, mapname, global settings here
|
||||||
// public string[] Mods = { };
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum ClientState
|
public enum ClientState
|
||||||
{
|
{
|
||||||
NotReady,
|
NotReady,
|
||||||
// Downloading,
|
// Downloading,
|
||||||
// Uploading,
|
// Uploading,
|
||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Client
|
public class Client
|
||||||
{
|
{
|
||||||
public int Index;
|
public int Index;
|
||||||
public int Palette;
|
public int Palette;
|
||||||
public int Race;
|
public int Race;
|
||||||
// public int SpawnPoint;
|
// public int SpawnPoint;
|
||||||
public string Name;
|
public string Name;
|
||||||
public ClientState State;
|
public ClientState State;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -343,5 +343,21 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
return Game.PathFinder.FindPath(search).Count != 0;
|
return Game.PathFinder.FindPath(search).Count != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void SyncLobbyInfo(string data)
|
||||||
|
{
|
||||||
|
var ys = MiniYaml.FromString(data);
|
||||||
|
foreach (var y in ys)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
if (!int.TryParse(y.Key, out index))
|
||||||
|
continue; // not a player.
|
||||||
|
|
||||||
|
var client = new Session.Client();
|
||||||
|
FieldLoader.Load(client, y.Value);
|
||||||
|
|
||||||
|
players[index].SyncFromLobby(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,18 +49,6 @@ namespace OpenRa.Game.Orders
|
|||||||
Game.chat.AddLine(order.Player, "is now YOU.");
|
Game.chat.AddLine(order.Player, "is now YOU.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "SetName":
|
|
||||||
{
|
|
||||||
Game.chat.AddLine(order.Player, "is now known as " + order.TargetString);
|
|
||||||
order.Player.PlayerName = order.TargetString;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "SetRace":
|
|
||||||
{
|
|
||||||
order.Player.Race = order.TargetString == "0" ? Race.Soviet : Race.Allies;
|
|
||||||
Game.chat.AddLine(order.Player, "is now playing {0}".F(order.Player.Race));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "SetLag":
|
case "SetLag":
|
||||||
{
|
{
|
||||||
int lag = int.Parse(order.TargetString);
|
int lag = int.Parse(order.TargetString);
|
||||||
@@ -74,13 +62,6 @@ namespace OpenRa.Game.Orders
|
|||||||
Game.chat.AddLine(Color.White, "Server", "Order lag is now {0} frames.".F(lag));
|
Game.chat.AddLine(Color.White, "Server", "Order lag is now {0} frames.".F(lag));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "SetPalette":
|
|
||||||
{
|
|
||||||
int palette = int.Parse(order.TargetString);
|
|
||||||
Game.chat.AddLine(order.Player, "has changed color to {0}".F(palette));
|
|
||||||
order.Player.Palette = (PaletteType) palette;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "StartGame":
|
case "StartGame":
|
||||||
{
|
{
|
||||||
Game.chat.AddLine(Color.White, "Server", "The game has started.");
|
Game.chat.AddLine(Color.White, "Server", "The game has started.");
|
||||||
@@ -93,6 +74,12 @@ namespace OpenRa.Game.Orders
|
|||||||
Game.ChangeMap(order.TargetString);
|
Game.ChangeMap(order.TargetString);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "SyncInfo":
|
||||||
|
{
|
||||||
|
Game.chat.AddLine(Color.White, "Server", "Synchronizing lobby info..."); // temp
|
||||||
|
Game.SyncLobbyInfo(order.TargetString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||||||
using OpenRa.Game.GameRules;
|
using OpenRa.Game.GameRules;
|
||||||
using OpenRa.Game.Graphics;
|
using OpenRa.Game.Graphics;
|
||||||
using OpenRa.Game.Traits;
|
using OpenRa.Game.Traits;
|
||||||
|
using OpenRa.FileFormats;
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
@@ -151,5 +152,28 @@ namespace OpenRa.Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SyncFromLobby(Session.Client client)
|
||||||
|
{
|
||||||
|
if (PlayerName != client.Name)
|
||||||
|
{
|
||||||
|
Game.chat.AddLine(this, "is now known as " + client.Name);
|
||||||
|
PlayerName = client.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Race != (Race)client.Race)
|
||||||
|
{
|
||||||
|
Game.chat.AddLine(this, "is now playing {0}".F((Race)client.Race));
|
||||||
|
Race = (Race)client.Race;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Palette != (PaletteType)client.Palette)
|
||||||
|
{
|
||||||
|
Game.chat.AddLine(this, "has changed color to {0}".F((PaletteType)client.Palette));
|
||||||
|
Palette = (PaletteType)client.Palette;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: IsReady tracking?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user