Handshake mod versions and map. Bump the protocol version.

This commit is contained in:
Paul Chote
2010-12-31 13:20:32 +13:00
parent e2d1eec56e
commit 486fa9a978
4 changed files with 63 additions and 12 deletions

View File

@@ -15,6 +15,26 @@ using OpenRA.FileFormats;
namespace OpenRA.Network namespace OpenRA.Network
{ {
public class HandshakeRequest
{
[FieldLoader.Load] public string[] Mods;
[FieldLoader.Load] public string Map;
public string Serialize()
{
var data = new List<MiniYamlNode>();
data.Add(new MiniYamlNode("Handshake", FieldSaver.Save(this)));
return data.WriteToString();
}
public static HandshakeRequest Deserialize(string data)
{
var handshake = new HandshakeRequest();
FieldLoader.Load(handshake, MiniYaml.FromString(data).First().Value);
return handshake;
}
}
public class HandshakeResponse public class HandshakeResponse
{ {
[FieldLoader.Load] public string[] Mods; [FieldLoader.Load] public string[] Mods;

View File

@@ -12,6 +12,7 @@ using System.Drawing;
using System.Linq; using System.Linq;
using OpenRA.Traits; using OpenRA.Traits;
using System; using System;
using OpenRA.FileFormats;
namespace OpenRA.Network namespace OpenRA.Network
{ {
@@ -100,18 +101,43 @@ namespace OpenRA.Network
case "HandshakeRequest": case "HandshakeRequest":
{ {
// Check valid mods/versions var request = HandshakeRequest.Deserialize(order.TargetString);
var serverInfo = Session.Deserialize(order.TargetString);
var serverMods = serverInfo.GlobalSettings.Mods;
var localMods = orderManager.LobbyInfo.GlobalSettings.Mods;
// TODO: Check that the map exists on the client // Check valid mods/versions
var serverMods = request.Mods;
var localMods = orderManager.LobbyInfo.GlobalSettings.Mods;
bool valid = true;
if (localMods.Length != serverMods.Length)
valid = false;
else
foreach (var m in serverMods)
{
var parts = m.Split('@');
if (!localMods.Contains(parts[0]))
{
valid = false;
break;
}
if (parts[1] == "{DEV_VERSION}" || Mod.AllMods[parts[0]].Version == "{DEV_VERSION}")
continue;
if (parts[1] != Mod.AllMods[parts[0]].Version)
{
valid = false;
break;
}
}
if (!valid)
throw new InvalidOperationException("Mod/Version mismatch. Client: `{0}`, Server: `{1}`".F(
string.Join(",",localMods.Select(m => "{0}@{1}".F(m, Mod.AllMods[m].Version)).ToArray()),
string.Join(",",serverMods)));
// Check that the map exists on the client
if (!Game.modData.AvailableMaps.ContainsKey(request.Map))
throw new InvalidOperationException("Missing map {0}".F(request.Map));
// Todo: Display a friendly dialog
if (serverMods.SymmetricDifference(localMods).Count() > 0)
throw new InvalidOperationException("Version mismatch. Client: `{0}`, Server: `{1}`"
.F(string.Join(",",localMods), string.Join(",",serverMods)));
var info = new Session.Client() var info = new Session.Client()
{ {
Name = Game.Settings.Player.Name, Name = Game.Settings.Player.Name,

View File

@@ -13,6 +13,6 @@ namespace OpenRA.Server
public static class ProtocolVersion public static class ProtocolVersion
{ {
// you *must* increment this whenever you make an incompatible protocol change // you *must* increment this whenever you make an incompatible protocol change
public static readonly int Version = 6; public static readonly int Version = 7;
} }
} }

View File

@@ -167,7 +167,12 @@ namespace OpenRA.Server
preConns.Add(newConn); preConns.Add(newConn);
// Dispatch a handshake order // Dispatch a handshake order
DispatchOrdersToClient(newConn, 0, 0, new ServerOrder("HandshakeRequest", lobbyInfo.Serialize()).Serialize()); var request = new HandshakeRequest()
{
Map = lobbyInfo.GlobalSettings.Map,
Mods = lobbyInfo.GlobalSettings.Mods.Select(m => "{0}@{1}".F(m,Mod.AllMods[m].Version)).ToArray()
};
DispatchOrdersToClient(newConn, 0, 0, new ServerOrder("HandshakeRequest", request.Serialize()).Serialize());
} }
catch (Exception) { DropClient(newConn); } catch (Exception) { DropClient(newConn); }
} }