Restore 0xFE order for handshakes.

This restores handshake compatibility with protocol 7 servers.
This commit is contained in:
Paul Chote
2019-05-11 16:09:53 +00:00
committed by abcdefg30
parent bfddfec461
commit fe41dcb45e
3 changed files with 99 additions and 60 deletions

View File

@@ -20,6 +20,7 @@ namespace OpenRA
{ {
SyncHash = 0x65, SyncHash = 0x65,
Disconnect = 0xBF, Disconnect = 0xBF,
Handshake = 0xFE,
Fields = 0xFF Fields = 0xFF
} }
@@ -54,6 +55,7 @@ namespace OpenRA
public CPos ExtraLocation; public CPos ExtraLocation;
public uint ExtraData; public uint ExtraData;
public bool IsImmediate; public bool IsImmediate;
public OrderType Type = OrderType.Fields;
public bool SuppressVisualFeedback; public bool SuppressVisualFeedback;
public Target VisualFeedbackTarget; public Target VisualFeedbackTarget;
@@ -157,6 +159,14 @@ namespace OpenRA
return new Order(order, subject, target, targetString, queued, extraLocation, extraData); return new Order(order, subject, target, targetString, queued, extraLocation, extraData);
} }
case OrderType.Handshake:
{
var name = r.ReadString();
var targetString = r.ReadString();
return new Order(name, null, false) { Type = OrderType.Handshake, TargetString = targetString };
}
default: default:
{ {
Log.Write("debug", "Received unknown order with type {0}", type); Log.Write("debug", "Received unknown order with type {0}", type);
@@ -239,81 +249,108 @@ namespace OpenRA
public byte[] Serialize() public byte[] Serialize()
{ {
var minLength = 1 + OrderString.Length + 1 + 4 + 1 + 13 + (TargetString != null ? TargetString.Length + 1 : 0) + 4 + 4; var minLength = 1 + OrderString.Length + 1;
if (Type == OrderType.Handshake)
minLength += TargetString.Length + 1;
else if (Type == OrderType.Fields)
minLength += 4 + 1 + 13 + (TargetString != null ? TargetString.Length + 1 : 0) + 4 + 4;
// ProtocolVersion.Orders and the associated documentation MUST be updated if the serialized format changes
var ret = new MemoryStream(minLength); var ret = new MemoryStream(minLength);
var w = new BinaryWriter(ret); var w = new BinaryWriter(ret);
w.Write((byte)OrderType.Fields); w.Write((byte)Type);
w.Write(OrderString); w.Write(OrderString);
var fields = OrderFields.None; switch (Type)
if (Subject != null)
fields |= OrderFields.Subject;
if (TargetString != null)
fields |= OrderFields.TargetString;
if (ExtraData != 0)
fields |= OrderFields.ExtraData;
if (Target.SerializableType != TargetType.Invalid)
fields |= OrderFields.Target;
if (Queued)
fields |= OrderFields.Queued;
if (ExtraLocation != CPos.Zero)
fields |= OrderFields.ExtraLocation;
if (Target.SerializableCell != null)
fields |= OrderFields.TargetIsCell;
w.Write((byte)fields);
if (fields.HasField(OrderFields.Subject))
w.Write(UIntFromActor(Subject));
if (fields.HasField(OrderFields.Target))
{ {
w.Write((byte)Target.SerializableType); case OrderType.Handshake:
switch (Target.SerializableType)
{ {
case TargetType.Actor: // Changing the Handshake order format will break cross-version switching
w.Write(UIntFromActor(Target.SerializableActor)); // Don't do this unless you really have to!
break; w.Write(TargetString ?? "");
case TargetType.FrozenActor:
w.Write(Target.FrozenActor.Viewer.PlayerActor.ActorID); break;
w.Write(Target.FrozenActor.ID);
break;
case TargetType.Terrain:
if (fields.HasField(OrderFields.TargetIsCell))
{
w.Write(Target.SerializableCell.Value);
w.Write((byte)Target.SerializableSubCell);
}
else
w.Write(Target.SerializablePos);
break;
} }
case OrderType.Fields:
{
var fields = OrderFields.None;
if (Subject != null)
fields |= OrderFields.Subject;
if (TargetString != null)
fields |= OrderFields.TargetString;
if (ExtraData != 0)
fields |= OrderFields.ExtraData;
if (Target.SerializableType != TargetType.Invalid)
fields |= OrderFields.Target;
if (Queued)
fields |= OrderFields.Queued;
if (ExtraLocation != CPos.Zero)
fields |= OrderFields.ExtraLocation;
if (Target.SerializableCell != null)
fields |= OrderFields.TargetIsCell;
w.Write((byte)fields);
if (fields.HasField(OrderFields.Subject))
w.Write(UIntFromActor(Subject));
if (fields.HasField(OrderFields.Target))
{
w.Write((byte)Target.SerializableType);
switch (Target.SerializableType)
{
case TargetType.Actor:
w.Write(UIntFromActor(Target.SerializableActor));
break;
case TargetType.FrozenActor:
w.Write(Target.FrozenActor.Viewer.PlayerActor.ActorID);
w.Write(Target.FrozenActor.ID);
break;
case TargetType.Terrain:
if (fields.HasField(OrderFields.TargetIsCell))
{
w.Write(Target.SerializableCell.Value);
w.Write((byte)Target.SerializableSubCell);
}
else
w.Write(Target.SerializablePos);
break;
}
}
if (fields.HasField(OrderFields.TargetString))
w.Write(TargetString);
if (fields.HasField(OrderFields.ExtraLocation))
w.Write(ExtraLocation);
if (fields.HasField(OrderFields.ExtraData))
w.Write(ExtraData);
break;
}
default:
throw new InvalidDataException("Cannot serialize order type {0}".F(Type));
} }
if (fields.HasField(OrderFields.TargetString))
w.Write(TargetString);
if (fields.HasField(OrderFields.ExtraLocation))
w.Write(ExtraLocation);
if (fields.HasField(OrderFields.ExtraData))
w.Write(ExtraData);
return ret.ToArray(); return ret.ToArray();
} }
public override string ToString() public override string ToString()
{ {
return ("OrderString: \"{0}\" \n\t Subject: \"{1}\". \n\t Target: \"{2}\"." + return ("OrderString: \"{0}\" \n\t Type: \"{1}\". \n\t Subject: \"{2}\". \n\t Target: \"{3}\"." +
"\n\t TargetString: \"{3}\".\n\t IsImmediate: {4}.\n\t Player(PlayerName): {5}\n").F( "\n\t TargetString: \"{4}\".\n\t IsImmediate: {5}.\n\t Player(PlayerName): {6}\n").F(
OrderString, Subject, Target, TargetString, IsImmediate, Player != null ? Player.PlayerName : null); OrderString, Type, Subject, Target, TargetString, IsImmediate,
Player != null ? Player.PlayerName : null);
} }
} }
} }

View File

@@ -235,6 +235,7 @@ namespace OpenRA.Network
orderManager.IssueOrder(new Order("HandshakeResponse", null, false) orderManager.IssueOrder(new Order("HandshakeResponse", null, false)
{ {
Type = OrderType.Handshake,
IsImmediate = true, IsImmediate = true,
TargetString = response.Serialize() TargetString = response.Serialize()
}); });

View File

@@ -294,6 +294,7 @@ namespace OpenRA.Server
DispatchOrdersToClient(newConn, 0, 0, new Order("HandshakeRequest", null, false) DispatchOrdersToClient(newConn, 0, 0, new Order("HandshakeRequest", null, false)
{ {
Type = OrderType.Handshake,
IsImmediate = true, IsImmediate = true,
TargetString = request.Serialize() TargetString = request.Serialize()
}.Serialize()); }.Serialize());