Merge ServerOrder into Order and 0xFE order type into 0xFF.
This commit is contained in:
@@ -292,7 +292,11 @@ namespace OpenRA.Server
|
||||
AuthToken = token
|
||||
};
|
||||
|
||||
DispatchOrdersToClient(newConn, 0, 0, new ServerOrder("HandshakeRequest", request.Serialize()).Serialize());
|
||||
DispatchOrdersToClient(newConn, 0, 0, new Order("HandshakeRequest", null, false)
|
||||
{
|
||||
IsImmediate = true,
|
||||
TargetString = request.Serialize()
|
||||
}.Serialize());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -579,9 +583,9 @@ namespace OpenRA.Server
|
||||
{
|
||||
while (ms.Position < ms.Length)
|
||||
{
|
||||
var so = ServerOrder.Deserialize(br);
|
||||
if (so == null) return;
|
||||
InterpretServerOrder(conn, so);
|
||||
var o = Order.Deserialize(null, br);
|
||||
if (o != null)
|
||||
InterpretServerOrder(conn, o);
|
||||
}
|
||||
}
|
||||
catch (EndOfStreamException) { }
|
||||
@@ -590,29 +594,29 @@ namespace OpenRA.Server
|
||||
|
||||
public void SendOrderTo(Connection conn, string order, string data)
|
||||
{
|
||||
DispatchOrdersToClient(conn, 0, 0, new ServerOrder(order, data).Serialize());
|
||||
DispatchOrdersToClient(conn, 0, 0, Order.FromTargetString(order, data, true).Serialize());
|
||||
}
|
||||
|
||||
public void SendMessage(string text, Connection conn = null)
|
||||
{
|
||||
DispatchOrdersToClients(conn, 0, new ServerOrder("Message", text).Serialize());
|
||||
DispatchOrdersToClients(conn, 0, Order.FromTargetString("Message", text, true).Serialize());
|
||||
|
||||
if (Dedicated)
|
||||
Console.WriteLine("[{0}] {1}".F(DateTime.Now.ToString(Settings.TimestampFormat), text));
|
||||
}
|
||||
|
||||
void InterpretServerOrder(Connection conn, ServerOrder so)
|
||||
void InterpretServerOrder(Connection conn, Order o)
|
||||
{
|
||||
// Only accept handshake responses from unvalidated clients
|
||||
// Anything else may be an attempt to exploit the server
|
||||
if (!conn.Validated)
|
||||
{
|
||||
if (so.Name == "HandshakeResponse")
|
||||
ValidateClient(conn, so.Data);
|
||||
if (o.OrderString == "HandshakeResponse")
|
||||
ValidateClient(conn, o.TargetString);
|
||||
else
|
||||
{
|
||||
Log.Write("server", "Rejected connection from {0}; Order `{1}` is not a `HandshakeResponse`.",
|
||||
conn.Socket.RemoteEndPoint, so.Name);
|
||||
conn.Socket.RemoteEndPoint, o.OrderString);
|
||||
|
||||
DropClient(conn);
|
||||
}
|
||||
@@ -620,31 +624,31 @@ namespace OpenRA.Server
|
||||
return;
|
||||
}
|
||||
|
||||
switch (so.Name)
|
||||
switch (o.OrderString)
|
||||
{
|
||||
case "Command":
|
||||
{
|
||||
var handledBy = serverTraits.WithInterface<IInterpretCommand>()
|
||||
.FirstOrDefault(t => t.InterpretCommand(this, conn, GetClient(conn), so.Data));
|
||||
.FirstOrDefault(t => t.InterpretCommand(this, conn, GetClient(conn), o.TargetString));
|
||||
|
||||
if (handledBy == null)
|
||||
{
|
||||
Log.Write("server", "Unknown server command: {0}", so.Data);
|
||||
SendOrderTo(conn, "Message", "Unknown server command: {0}".F(so.Data));
|
||||
Log.Write("server", "Unknown server command: {0}", o.TargetString);
|
||||
SendOrderTo(conn, "Message", "Unknown server command: {0}".F(o.TargetString));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "Chat":
|
||||
DispatchOrdersToClients(conn, 0, so.Serialize());
|
||||
DispatchOrdersToClients(conn, 0, o.Serialize());
|
||||
break;
|
||||
case "Pong":
|
||||
{
|
||||
long pingSent;
|
||||
if (!OpenRA.Exts.TryParseInt64Invariant(so.Data, out pingSent))
|
||||
if (!OpenRA.Exts.TryParseInt64Invariant(o.TargetString, out pingSent))
|
||||
{
|
||||
Log.Write("server", "Invalid order pong payload: {0}", so.Data);
|
||||
Log.Write("server", "Invalid order pong payload: {0}", o.TargetString);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -676,7 +680,7 @@ namespace OpenRA.Server
|
||||
{
|
||||
if (GameSave != null)
|
||||
{
|
||||
var data = MiniYaml.FromString(so.Data)[0];
|
||||
var data = MiniYaml.FromString(o.TargetString)[0];
|
||||
GameSave.AddTraitData(int.Parse(data.Key), data.Value);
|
||||
}
|
||||
|
||||
@@ -688,7 +692,7 @@ namespace OpenRA.Server
|
||||
if (GameSave != null)
|
||||
{
|
||||
// Sanitize potentially malicious input
|
||||
var filename = so.Data;
|
||||
var filename = o.TargetString;
|
||||
var invalidIndex = -1;
|
||||
var invalidChars = Path.GetInvalidFileNameChars();
|
||||
while ((invalidIndex = filename.IndexOfAny(invalidChars)) != -1)
|
||||
@@ -704,7 +708,7 @@ namespace OpenRA.Server
|
||||
Directory.CreateDirectory(baseSavePath);
|
||||
|
||||
GameSave.Save(Path.Combine(baseSavePath, filename));
|
||||
DispatchOrdersToClients(null, 0, new ServerOrder("GameSaved", filename).Serialize());
|
||||
DispatchOrdersToClients(null, 0, Order.FromTargetString("GameSaved", filename, true).Serialize());
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -716,7 +720,7 @@ namespace OpenRA.Server
|
||||
break;
|
||||
|
||||
// Sanitize potentially malicious input
|
||||
var filename = so.Data;
|
||||
var filename = o.TargetString;
|
||||
var invalidIndex = -1;
|
||||
var invalidChars = Path.GetInvalidFileNameChars();
|
||||
while ((invalidIndex = filename.IndexOfAny(invalidChars)) != -1)
|
||||
@@ -808,7 +812,7 @@ namespace OpenRA.Server
|
||||
SendMessage("{0}{1} has disconnected.".F(dropClient.Name, suffix));
|
||||
|
||||
// Send disconnected order, even if still in the lobby
|
||||
DispatchOrdersToClients(toDrop, 0, new ServerOrder("Disconnected", "").Serialize());
|
||||
DispatchOrdersToClients(toDrop, 0, Order.FromTargetString("Disconnected", "", true).Serialize());
|
||||
|
||||
LobbyInfo.Clients.RemoveAll(c => c.Index == toDrop.PlayerIndex);
|
||||
LobbyInfo.ClientPings.RemoveAll(p => p.Index == toDrop.PlayerIndex);
|
||||
@@ -854,7 +858,7 @@ namespace OpenRA.Server
|
||||
public void SyncLobbyInfo()
|
||||
{
|
||||
if (State == ServerState.WaitingPlayers) // Don't do this while the game is running, it breaks things!
|
||||
DispatchOrders(null, 0, new ServerOrder("SyncInfo", LobbyInfo.Serialize()).Serialize());
|
||||
DispatchOrders(null, 0, Order.FromTargetString("SyncInfo", LobbyInfo.Serialize(), true).Serialize());
|
||||
|
||||
foreach (var t in serverTraits.WithInterface<INotifySyncLobbyInfo>())
|
||||
t.LobbyInfoSynced(this);
|
||||
@@ -868,7 +872,7 @@ namespace OpenRA.Server
|
||||
// TODO: Only need to sync the specific client that has changed to avoid conflicts!
|
||||
var clientData = LobbyInfo.Clients.Select(client => client.Serialize()).ToList();
|
||||
|
||||
DispatchOrders(null, 0, new ServerOrder("SyncLobbyClients", clientData.WriteToString()).Serialize());
|
||||
DispatchOrders(null, 0, Order.FromTargetString("SyncLobbyClients", clientData.WriteToString(), true).Serialize());
|
||||
|
||||
foreach (var t in serverTraits.WithInterface<INotifySyncLobbyInfo>())
|
||||
t.LobbyInfoSynced(this);
|
||||
@@ -882,7 +886,7 @@ namespace OpenRA.Server
|
||||
// TODO: Don't sync all the slots if just one changed!
|
||||
var slotData = LobbyInfo.Slots.Select(slot => slot.Value.Serialize()).ToList();
|
||||
|
||||
DispatchOrders(null, 0, new ServerOrder("SyncLobbySlots", slotData.WriteToString()).Serialize());
|
||||
DispatchOrders(null, 0, Order.FromTargetString("SyncLobbySlots", slotData.WriteToString(), true).Serialize());
|
||||
|
||||
foreach (var t in serverTraits.WithInterface<INotifySyncLobbyInfo>())
|
||||
t.LobbyInfoSynced(this);
|
||||
@@ -895,7 +899,7 @@ namespace OpenRA.Server
|
||||
|
||||
var sessionData = new List<MiniYamlNode> { LobbyInfo.GlobalSettings.Serialize() };
|
||||
|
||||
DispatchOrders(null, 0, new ServerOrder("SyncLobbyGlobalSettings", sessionData.WriteToString()).Serialize());
|
||||
DispatchOrders(null, 0, Order.FromTargetString("SyncLobbyGlobalSettings", sessionData.WriteToString(), true).Serialize());
|
||||
|
||||
foreach (var t in serverTraits.WithInterface<INotifySyncLobbyInfo>())
|
||||
t.LobbyInfoSynced(this);
|
||||
@@ -907,7 +911,7 @@ namespace OpenRA.Server
|
||||
var clientPings = LobbyInfo.ClientPings.Select(ping => ping.Serialize()).ToList();
|
||||
|
||||
// Note that syncing pings doesn't trigger INotifySyncLobbyInfo
|
||||
DispatchOrders(null, 0, new ServerOrder("SyncClientPings", clientPings.WriteToString()).Serialize());
|
||||
DispatchOrders(null, 0, Order.FromTargetString("SyncClientPings", clientPings.WriteToString(), true).Serialize());
|
||||
}
|
||||
|
||||
public void StartGame()
|
||||
@@ -960,7 +964,7 @@ namespace OpenRA.Server
|
||||
}
|
||||
|
||||
DispatchOrders(null, 0,
|
||||
new ServerOrder("StartGame", startGameData).Serialize());
|
||||
Order.FromTargetString("StartGame", startGameData, true).Serialize());
|
||||
|
||||
foreach (var t in serverTraits.WithInterface<IStartGame>())
|
||||
t.GameStarted(this);
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2019 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace OpenRA.Server
|
||||
{
|
||||
class ServerOrder
|
||||
{
|
||||
public readonly string Name;
|
||||
public readonly string Data;
|
||||
public readonly uint ExtraData;
|
||||
|
||||
public ServerOrder(string name, string data, uint extraData = 0)
|
||||
{
|
||||
Name = name;
|
||||
Data = data;
|
||||
ExtraData = extraData;
|
||||
}
|
||||
|
||||
public static ServerOrder Deserialize(BinaryReader r)
|
||||
{
|
||||
byte b;
|
||||
switch (b = r.ReadByte())
|
||||
{
|
||||
case 0xbf:
|
||||
// Silently ignore disconnect notifications
|
||||
return null;
|
||||
case 0xff:
|
||||
Console.WriteLine("This isn't a server order.");
|
||||
return null;
|
||||
|
||||
case 0xfe:
|
||||
{
|
||||
var name = r.ReadString();
|
||||
var flags = (OrderFields)r.ReadByte();
|
||||
var data = flags.HasField(OrderFields.TargetString) ? r.ReadString() : null;
|
||||
var extraData = flags.HasField(OrderFields.ExtraData) ? r.ReadUInt32() : 0;
|
||||
|
||||
return new ServerOrder(name, data, extraData);
|
||||
}
|
||||
|
||||
default:
|
||||
throw new NotImplementedException(b.ToString("x2"));
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] Serialize()
|
||||
{
|
||||
var ms = new MemoryStream(1 + Name.Length + 1 + 1 + Data.Length + 1 + 4);
|
||||
var bw = new BinaryWriter(ms);
|
||||
|
||||
OrderFields fields = 0;
|
||||
if (Data != null)
|
||||
fields |= OrderFields.TargetString;
|
||||
|
||||
if (ExtraData != 0)
|
||||
fields |= OrderFields.ExtraData;
|
||||
|
||||
bw.Write((byte)0xfe);
|
||||
bw.Write(Name);
|
||||
bw.Write((byte)fields);
|
||||
|
||||
if (fields.HasField(OrderFields.TargetString))
|
||||
bw.Write(Data);
|
||||
|
||||
if (fields.HasField(OrderFields.ExtraData))
|
||||
bw.Write(ExtraData);
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user