static bool TryGetActorFromUInt(World world, uint aID, out Actor ret) { if (aID == uint.MaxValue) { ret = null; return(true); } ret = world.GetActorById(aID); return(ret != null); }
public static Order Deserialize(World world, BinaryReader r) { try { var type = (OrderType)r.ReadByte(); switch (type) { case OrderType.Fields: { var order = r.ReadString(); var flags = (OrderFields)r.ReadInt16(); Actor subject = null; if (flags.HasField(OrderFields.Subject)) { var subjectId = r.ReadUInt32(); if (world != null) { TryGetActorFromUInt(world, subjectId, out subject); } } var target = Target.Invalid; if (flags.HasField(OrderFields.Target)) { switch ((TargetType)r.ReadByte()) { case TargetType.Actor: { Actor targetActor; if (world != null && TryGetActorFromUInt(world, r.ReadUInt32(), out targetActor)) { target = Target.FromActor(targetActor); } break; } case TargetType.FrozenActor: { var playerActorID = r.ReadUInt32(); var frozenActorID = r.ReadUInt32(); Actor playerActor; if (world == null || !TryGetActorFromUInt(world, playerActorID, out playerActor)) { break; } if (playerActor.Owner.FrozenActorLayer == null) { break; } var frozen = playerActor.Owner.FrozenActorLayer.FromID(frozenActorID); if (frozen != null) { target = Target.FromFrozenActor(frozen); } break; } case TargetType.Terrain: { if (flags.HasField(OrderFields.TargetIsCell)) { var cell = new CPos(r.ReadInt32()); var subCell = (SubCell)r.ReadByte(); if (world != null) { target = Target.FromCell(world, cell, subCell); } } else { var pos = new WPos(r.ReadInt32(), r.ReadInt32(), r.ReadInt32()); target = Target.FromPos(pos); } break; } } } var targetString = flags.HasField(OrderFields.TargetString) ? r.ReadString() : null; var queued = flags.HasField(OrderFields.Queued); Actor[] extraActors = null; if (flags.HasField(OrderFields.ExtraActors)) { var count = r.ReadInt32(); if (world != null) { extraActors = Exts.MakeArray(count, _ => world.GetActorById(r.ReadUInt32())); } else { r.ReadBytes(4 * count); } } var extraLocation = flags.HasField(OrderFields.ExtraLocation) ? new CPos(r.ReadInt32()) : CPos.Zero; var extraData = flags.HasField(OrderFields.ExtraData) ? r.ReadUInt32() : 0; Actor[] groupedActors = null; if (flags.HasField(OrderFields.Grouped)) { var count = r.ReadInt32(); if (world != null) { groupedActors = Exts.MakeArray(count, _ => world.GetActorById(r.ReadUInt32())); } else { r.ReadBytes(4 * count); } } if (world == null) { return(new Order(order, null, target, targetString, queued, extraActors, extraLocation, extraData, groupedActors)); } if (subject == null && flags.HasField(OrderFields.Subject)) { return(null); } return(new Order(order, subject, target, targetString, queued, extraActors, extraLocation, extraData, groupedActors)); } case OrderType.Handshake: { var name = r.ReadString(); var targetString = r.ReadString(); return(new Order(name, null, false) { Type = OrderType.Handshake, TargetString = targetString }); } default: { Log.Write("debug", "Received unknown order with type {0}", type); return(null); } } } catch (Exception e) { Log.Write("debug", "Caught exception while processing order"); Log.Write("debug", e.ToString()); // HACK: this can hopefully go away in the future Game.Debug("Ignoring malformed order that would have crashed the game"); Game.Debug("Please file a bug report and include the replay from this match"); return(null); } }