public void Text_StringStorageEncodingWriteTest() { const bool k_output_ms = true; using (var ms = new System.IO.MemoryStream()) using (var io = new IO.EndianStream(ms)) { MS.StringStorage storage = //Strings.StringStorage.kCStringUnicode; new MS.StringStorage(MS.StringStorageWidthType.Ascii, MS.StringStorageType.CString, 256); var encoding = StringStorageEncoding.TryAndGetStaticEncoding(storage); const string test1 = "This is a test", test2 = "Test this is", test3 = "wtf is apple juice?", test4 = "one more for good luck."; // Test case for strings which are greater-than-or-equal to the CString storage length (which includes a null terminating char) var sb = new System.Text.StringBuilder(storage.FixedLength); sb.Append('1', storage.FixedLength); string test5 = sb.ToString(); io.Writer.Write(test1, encoding); io.Writer.Write(test2, encoding); io.Writer.Write(test3, encoding); io.Writer.Write(test4, encoding); io.Writer.Write(test5, encoding); if (k_output_ms) { string output_ms_path = System.IO.Path.Combine(base.TestContext.TestResultsDirectory, "StringStorageEncodingTestWrite.bin"); Console.WriteLine("Writing to: {0}", output_ms_path); using (var fs = new System.IO.FileStream(output_ms_path, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.Read)) { ms.WriteTo(fs); } } ms.Seek(0, System.IO.SeekOrigin.Begin); Assert.AreEqual(test1, io.Reader.ReadString(encoding)); Assert.AreEqual(test2, io.Reader.ReadString(encoding, test2.Length)); Assert.AreEqual(test3, io.Reader.ReadString(encoding)); Assert.AreEqual(test4, io.Reader.ReadString(encoding, test4.Length)); Assert.AreNotEqual(test5, io.Reader.ReadString(encoding)); } }
public void Serialize(IO.EndianStream s) { uint sdk_ver = (s.Owner as AkSoundBank).SdkVersion; if (AkVersion.HasOldBankHeader(sdk_ver)) { SerializeOld(s); } else { s.Stream(ref BankGeneratorVersion); s.Stream(ref SoundBankID); s.Stream(ref LanguageID); s.Stream(ref FeedbackSupported); } }
void SerializeParams(IO.EndianStream s) { s.Pad32(); // float VolumeMain s.Pad32(); // float s.Pad32(); // float s.Pad32(); // float LFEVolumeMain s.Pad32(); // float s.Pad32(); // float s.Pad32(); // float PitchMain s.Pad32(); // float s.Pad32(); // float s.Pad32(); // float LPFMain s.Pad32(); // float s.Pad32(); // float s.Pad32(); // StateGroupID }
public override void Serialize(IO.EndianStream s, AkSubchunkHeader header) { Contract.Assert(s.IsReading); var bank = s.Owner as AkSoundBank; long eos = EndOfStream(s, header); while (s.BaseStream.Position != eos) { AKBKHashHeader hdr = new AKBKHashHeader(); hdr.Serialize(s); SerializeStringType(s, hdr, bank); } }
public void Serialize(IO.EndianStream s) { s.Stream(ref HaveArrow); if (!HaveArrow) { return; } s.StreamV(ref Origin); s.StreamV(ref Target); s.Stream(ref Offset); s.Stream(ref ObjectID); s.Stream(ref LocationObjectID); s.Stream(ref PlayerID); s.Stream(ref FlagVisible); s.Stream(ref FlagUseTarget); s.Stream(ref FlagTargetDirty); s.Stream(ref FlagForceTargetVisible); s.StreamSignature(cSaveMarker.Arrow); }
public override void Serialize(IO.EndianStream s) { base.Serialize(s); BSaveGame.StreamArray(s, ref IgnoreList); s.Stream(ref NextTickTime); s.Stream(ref CryoObjectID); s.StreamV(ref Direction); s.StreamV(ref Right); s.Stream(ref CryoObjectProtoID); s.Stream(ref BomberProtoID); s.Stream(ref FilterTypeID); s.Stream(ref CryoRadius); s.Stream(ref MinCryoFalloff); s.Stream(ref TickDuration); s.Stream(ref TicksRemaining); s.Stream(ref CryoAmountPerTick); s.Stream(ref KillableHpLeft); s.Stream(ref FreezingThawTime); s.Stream(ref FrozenThawTime); s.Stream(BomberData); s.Stream(ref ReactionPlayed); }
public void Serialize(IO.EndianStream s) { var eraFile = s.Owner as EraFileUtil; if (s.IsWriting) { mHeader.UpdateTotalSize(s.BaseStream); } long header_position = s.BaseStream.CanSeek ? s.BaseStream.Position : -1; // write the header, but it won't have the correct CRC if things have changed, // or if this is a fresh new archive mHeader.Serialize(s); mSignature.Serialize(s); var leftovers_size = mHeader.HeaderSize - s.BaseStream.Position; s.Pad((int)leftovers_size); // verify or update the header checksum if (s.IsReading) { if (header_position != -1 && !eraFile.Options.Test(EraFileUtilOptions.SkipVerification)) { var actual_adler = mHeader.ComputeAdler32(s.BaseStream, header_position); if (actual_adler != mHeader.Adler32) { throw new System.IO.InvalidDataException(string.Format( "ERA header adler32 {0} does not match actual adler32 {1}", mHeader.Adler32.ToString("X8"), actual_adler.ToString("X8") )); } } } else if (s.IsWriting) { if (header_position != -1) { mHeader.ComputeAdler32AndWrite(s, header_position); } } }
public void BDT_ToXmlTest() { bool any_failed = false; foreach (var reference in UgxFiles) { using (var fs = File.OpenRead(reference.FilePath)) { fs.Seek(reference.FileOffset, SeekOrigin.Begin); var bdt_bytes = new byte[reference.ChunkSize]; int bytes_read = fs.Read(bdt_bytes, 0, bdt_bytes.Length); Assert.AreEqual(bdt_bytes.Length, bytes_read); try { var bdt = new BinaryDataTree(); bdt.DecompileAttributesWithTypeData = true; using (var bdt_ms = new MemoryStream(bdt_bytes)) using (var es = new IO.EndianStream(bdt_ms, Shell.EndianFormat.Big, permissions: FileAccess.Read)) { es.StreamMode = FileAccess.Read; bdt.Serialize(es); } var ms = new MemoryStream(); bdt.ToXml(ms); ms.Flush(); ms.Position = 0; Console.WriteLine(); Console.WriteLine(); Console.WriteLine(reference.FilePath); using (var sr = new StreamReader(ms)) Console.WriteLine(sr.ReadToEnd()); } catch (Exception ex) { Console.WriteLine("Test failed on {0}:\n{1}", reference.FilePath, ex); any_failed = true; } } } Assert.IsFalse(any_failed); }
public override void Serialize(IO.EndianStream s) { base.Serialize(s); s.Stream(ref RealTargettingLaserID); s.StreamV(ref DesiredTargettingPosition); BSaveGame.StreamArray(s, ref Shots); s.Stream(ref FiredInitialShot); s.Stream(ref ShotsRemaining); s.Stream(ref ImpactsToProcess); s.Stream(ref TargetBeamID); s.Stream(ref ProjectileID); s.Stream(ref EffectProtoID); s.Stream(ref RockSmallProtoID); s.Stream(ref RockMediumProtoID); s.Stream(ref RockLargeProtoID); s.Stream(ref FiredSound); s.Stream(ref TargetingDelay); s.Stream(ref AutoShotDelay); s.Stream(ref AutoShotInnerRadius); s.Stream(ref AutoShotOuterRadius); s.Stream(ref XOffset); s.Stream(ref YOffset); s.Stream(ref ZOffset); s.Stream(ref LOSMode); }
public override void Serialize(IO.EndianStream s) { base.Serialize(s); BSaveGame.StreamArray(s, ref SquadsRepairing); BSaveGame.StreamArray(s, ref IgnoreList); s.Stream(ref NextTickTime); s.Stream(ref RepairObjectID); s.Stream(ref RepairAttachmentProtoID); s.Stream(ref FilterTypeID); s.Stream(ref RepairRadius); s.Stream(ref TickDuration); s.Stream(ref RepairCombatValuePerTick); s.Stream(ref CooldownTimeIfDamaged); s.Stream(ref TicksRemaining); s.Stream(ref SpreadAmongSquads); s.Stream(ref AllowReinforce); s.Stream(ref IgnorePlacement); s.Stream(ref HealAny); s.Stream(ref NeverStops); }
public void Serialize(IO.EndianStream s) { BSaveGame.StreamVectorArray(s, ref Path, cMaximumPathLength); s.Stream(Target); s.Stream(ref Source); s.Stream(ref ID); s.Stream(ref Type); s.Stream(ref UserData); s.Stream(ref Priority); s.Stream(ref UserData2); s.Stream(ref WaitCount); s.Stream(ref Evaluated); s.Stream(ref ExistForOneUpdate); s.Stream(ref ExistUntilEvaluated); s.Stream(ref AllowComplete); s.Stream(ref NotifySource); s.Stream(ref Leash); s.Stream(ref ForceLeash); s.Stream(ref Trigger); s.Stream(ref RemoveActions); s.Stream(ref Complete); s.Stream(ref CompleteValue); s.Stream(ref PreserveDPS); s.Stream(ref MustComplete); s.Stream(ref UserDataSet); }
public void Serialize(IO.EndianStream s) { BSaveGame.StreamMatrix(s, ref Matrix); s.Stream(ref SubUpdateNumber); s.Stream(ref GrannySubUpdateNumber); BSaveGame.StreamMatrix(s, ref Matrix1); BSaveGame.StreamMatrix(s, ref Matrix2); s.StreamV(ref CombinedMinCorner); s.StreamV(ref CombinedMaxCorner); s.StreamV(ref MinCorner); s.StreamV(ref MaxCorner); s.Stream(ref ModelAsset); if (s.StreamCond(ModelUVOffsets, offsets => !offsets.EqualsZero())) { s.Stream(ModelUVOffsets); } StreamFlags(s); StreamAttachments(s); }
static void Stream(IO.EndianStream s, bool crypt, IO.IEndianStreamSerializable obj, long size = 0, ulong userKey = 0, Action <IO.EndianStream> streamLeftovers = null) { if (!crypt) { obj.Serialize(s); if (s.IsWriting && streamLeftovers != null) { streamLeftovers(s); } } else { using (var ms = new System.IO.MemoryStream()) using (var crypted = new IO.EndianStream(ms, s.ByteOrder)) { crypted.StreamMode = s.StreamMode; if (s.IsReading) { var tea = new Security.Cryptography.PhxTEA(s.Reader, crypted.Writer); tea.InitializeKey(Security.Cryptography.PhxTEA.kKeyGameFile, userKey); tea.Decrypt(size); crypted.Seek(0); } obj.Serialize(crypted); if (streamLeftovers != null) { streamLeftovers(crypted); } if (s.IsWriting) { crypted.Seek(0); var tea = new Security.Cryptography.PhxTEA(crypted.Reader, s.Writer); tea.InitializeKey(Security.Cryptography.PhxTEA.kKeyGameFile, userKey); tea.Encrypt(size); } } } }
public static IO.EndianStream StreamNotNull <T>(this IO.EndianStream s, ref T obj) where T : class, IO.IEndianStreamSerializable, new() { bool not_null = obj != null; s.Stream(ref not_null); if (s.IsReading && not_null) { obj = new T(); } if (not_null) { s.Stream(obj); } return(s); }
public void Serialize(IO.EndianStream s) { s.StreamVersion(kVersion); s.Stream(ref NoFogMask); s.Stream(ref AIDisable); s.Stream(ref AIShadow); s.Stream(ref NoVismap); s.Stream(ref NoRandomPlayerPlacement); s.Stream(ref DisableOneBuilding); s.Stream(ref BuildingQueue); s.Stream(ref UseTestLeaders); s.Stream(ref EnableFlight); s.Stream(ref NoBirthAnims); s.Stream(ref Veterancy); s.Stream(ref TrueLOS); s.Stream(ref NoDestruction); s.Stream(ref CoopSharedResources); s.Stream(ref MaxProjectileHeightForDecal); s.Stream(ref EnableSubbreakage); s.Stream(ref EnableThrowPart); s.Stream(ref AllowAnimIsDirty); s.Stream(ref NoVictoryCondition); s.Stream(ref AIAutoDifficulty); s.Stream(ref Demo); s.Stream(ref AsyncWorldUpdate); s.Stream(ref EnableHintSystem); s.Stream(ref PercentFadeTimeCorpseSink); s.Stream(ref CorpseSinkSpeed); s.Stream(ref CorpseMinScale); s.Stream(ref BlockOutsideBounds); s.Stream(ref AINoAttack); s.Stream(ref PassThroughOwnVehicles); s.Stream(ref EnableCapturePointResourceSharing); s.Stream(ref NoUpdatePathingQuad); s.Stream(ref SlaveUnitPosition); s.Stream(ref Turning); s.Stream(ref HumanAttackMove); s.Stream(ref MoreNewMovement3); s.Stream(ref OverrideGroundIK); s.Stream(ref DriveWarthog); s.Stream(ref EnableCorpses); s.Stream(ref DisablePathingLimits); s.Stream(ref DisableVelocityMatchingBySquadType); s.Stream(ref ActiveAbilities); s.Stream(ref AlphaTest); s.Stream(ref NoDamage); s.Stream(ref IgnoreAllPlatoonmates); s.Stream(ref ClassicPlatoonGrouping); s.Stream(ref NoShieldDamage); s.Stream(ref EnableSubUpdating); s.Stream(ref MPSubUpdating); s.Stream(ref AlternateSubUpdating); s.Stream(ref DynamicSubUpdateTime); s.Stream(ref DecoupledUpdate); s.StreamMethods(ReadFloats, WriteFloats); }
public void StreamCapacity(IO.EndianStream s, ref int capacity) { if (!SerializeCapacity) { return; } switch (IndexSize) { case sizeof(byte): byte cap8 = (byte)capacity; s.Stream(ref cap8); capacity = cap8; break; case sizeof(ushort): ushort cap16 = (ushort)capacity; s.Stream(ref cap16); capacity = cap16; break; case sizeof(int): s.Stream(ref capacity); break; default: throw new KSoft.Debug.UnreachableException(IndexSize.ToString()); } }
/// <summary>Stream an element index of a FreeList, writing a bool if is IsNotNone</summary> /// <param name="s"></param> /// <param name="ptr"></param> /// <returns></returns> public static IO.EndianStream StreamFreeListItemPtr(IO.EndianStream s, ref int ptr) { bool in_use = s.IsReading ? false : ptr.IsNotNone(); s.Stream(ref in_use); // only stream the index value if not NONE if (in_use) { s.Stream(ref ptr); } else { ptr = TypeExtensions.kNone; } return(s); }
void SerializeHack2008(IO.EndianStream s) { s.Pad(0x74); int item_count = 0; s.Stream(ref item_count); long children_size = item_count * sizeof(uint); long playlist_size = item_count * AkPlaylistItem.kSizeOf; long predicted_end = children_size + sizeof(uint) + playlist_size; long vb_end = s.VirtualBufferStart + s.VirtualBufferLength; if ((s.BaseStream.Position + predicted_end) == vb_end) { s.Pad((int)(children_size + sizeof(uint))); Playlist = new AkPlaylistItem[item_count]; s.StreamArray(Playlist); } }
public void Serialize(IO.EndianStream s) { s.StreamVersion(kVersion); s.Stream(ref Id); s.Stream(ref Name, kNameStorage); s.Stream(ref Description, kDescStorage); s.Stream(ref Author, kAuthorStorage); s.Stream(ref mDateTime); s.Stream(ref AuthorXuid); s.Stream(ref Length); s.Stream(ref SessionId); s.Stream(ref GameType); s.Stream(ref DataCryptKey); s.Stream(DataHash, 0, DataHash.Length); s.Stream(ref DataSize); s.Stream(Hash, 0, Hash.Length); s.Pad(kPaddingLength); }
public void Serialize(IO.EndianStream s) { s.Stream(ref Type, GameSettingTypeStreamer.Instance); switch (Type) { case GameSettingType.Float: s.Stream(ref Float); break; case GameSettingType.Int: s.Stream(ref Int); break; case GameSettingType.Byte: s.Stream(ref Byte); break; case GameSettingType.Bool: s.Stream(ref Bool); break; case GameSettingType.Long: s.Stream(ref Long); break; case GameSettingType.String: s.Stream(ref String); break; } }
public override void Serialize(IO.EndianStream s) { base.Serialize(s); s.Stream(ref FakeGravityBall); s.StreamV(ref HorizontalMoveInputDir); s.StreamV(ref VerticalMoveInputDir); s.StreamV(ref LastUpdatePos); s.StreamV(ref CameraFocusPoint); s.Stream(ref TimestampNextCommand); s.Stream(ref TimeUntilHint); s.Stream(ref CommandInterval); s.Stream(ref MinBallDistance); s.Stream(ref MaxBallDistance); s.Stream(ref MinBallHeight); s.Stream(ref MaxBallHeight); s.Stream(ref MaxBallSpeedStagnant); s.Stream(ref MaxBallSpeedPulling); s.Stream(ref CameraDistance); s.Stream(ref CameraHeight); s.Stream(ref CameraHoverPointDistance); s.Stream(ref CameraMaxBallAngle); s.Stream(ref PullingRange); s.Stream(ref PickupShakeDuration); s.Stream(ref PickupRumbleShakeStrength); s.Stream(ref PickupCameraShakeStrength); s.Stream(ref ExplodeTime); s.Stream(ref DelayShutdownTimeLeft); s.Stream(ref HintShown); s.Stream(ref HintCompleted); s.Stream(ref ShuttingDown); }
public override void Serialize(IO.EndianStream s) { var eraUtil = s.Owner as EraFileUtil; long position = s.BaseStream.Position; base.Serialize(s); s.Stream(ref mFileTimeBits); s.Stream(ref DataUncompressedSize); if (s.IsWriting) { Bitwise.ByteSwap.SwapInt64(CompressedDataTiger128, sizeof(ulong) * 0); Bitwise.ByteSwap.SwapInt64(CompressedDataTiger128, sizeof(ulong) * 1); } s.Stream(CompressedDataTiger128); { Bitwise.ByteSwap.SwapInt64(CompressedDataTiger128, sizeof(ulong) * 0); Bitwise.ByteSwap.SwapInt64(CompressedDataTiger128, sizeof(ulong) * 1); } s.StreamUInt24(ref FileNameOffset); s.Pad8(); if (eraUtil != null && eraUtil.DebugOutput != null) { eraUtil.DebugOutput.Write("FileEntry: {0} @{1} offset={2} end={3} size={4} dsize={5} adler={6} ", base.EntryId.ToString("X16"), position.ToString("X8"), base.DataOffset.u32.ToString("X8"), (base.DataOffset.u32 + base.DataSize).ToString("X8"), base.DataSize.ToString("X8"), DataUncompressedSize.ToString("X8"), base.Adler32.ToString("X8")); if (!string.IsNullOrEmpty(FileName)) { eraUtil.DebugOutput.Write(FileName); } eraUtil.DebugOutput.WriteLine(); } }
void ReadChunks(IO.EndianStream es, IO.EndianReader s) { while (!EndOfStream(es)) { var hdr = new AkSubchunkHeader(); hdr.Serialize(es); using (es.EnterVirtualBufferWithBookmark(hdr.ChunkSize)) { var obj = AkSoundBankObjectBase.New(hdr.Tag, GeneratorVersion); if (obj != null) { obj.Serialize(es, hdr); mChunks.Add(hdr, obj); } } } }
private void ValidateAdler32(EraFileEntryChunk fileEntry, IO.EndianStream blockStream) { var actual_adler = fileEntry.ComputeAdler32(blockStream); if (actual_adler != fileEntry.Adler32) { string chunk_name = !string.IsNullOrEmpty(fileEntry.FileName) ? fileEntry.FileName : "FileNames";//fileEntry.EntryId.ToString("X16"); throw new System.IO.InvalidDataException(string.Format( "Invalid chunk adler32 for '{0}' offset={1} size={2} " + "expected {3} but got {4}", chunk_name, fileEntry.DataOffset, fileEntry.DataSize.ToString("X8"), fileEntry.Adler32.ToString("X8"), actual_adler.ToString("X8") )); } }
void SerializeUserMode16(IO.EndianStream s) { s.Stream(ref UIPowerRadius); s.Stream(ref UIProtoPowerID); s.Stream(ref UIModeRestoreCameraZoomMin); s.Stream(ref UIModeRestoreCameraZoomMax); s.Stream(ref UIModeRestoreCameraZoom); s.Stream(ref UIModeRestoreCameraPitchMin); s.Stream(ref UIModeRestoreCameraPitchMax); s.Stream(ref UIModeRestoreCameraPitch); s.Stream(ref UIModeRestoreCameraYaw); s.Stream(ref FlagUIModeRestoreCameraZoomMin); s.Stream(ref FlagUIModeRestoreCameraZoomMax); s.Stream(ref FlagUIModeRestoreCameraZoom); s.Stream(ref FlagUIModeRestoreCameraPitchMin); s.Stream(ref FlagUIModeRestoreCameraPitchMax); s.Stream(ref FlagUIModeRestoreCameraPitch); s.Stream(ref FlagUIModeRestoreCameraYaw); s.Stream(ref FlagCameraScrollEnabled); s.Stream(ref FlagCameraYawEnabled); s.Stream(ref FlagCameraZoomEnabled); s.Stream(ref FlagCameraAutoZoomInstantEnabled); s.Stream(ref FlagCameraAutoZoomEnabled); s.Stream(ref FlagRestoreCameraEnableUserScroll); s.Stream(ref FlagRestoreCameraEnableUserYaw); s.Stream(ref FlagRestoreCameraEnableUserZoom); s.Stream(ref FlagRestoreCameraEnableAutoZoomInstant); s.Stream(ref FlagRestoreCameraEnableAutoZoom); s.Stream(ref PowerType, BPowerTypeStreamer.Instance); s.Stream(ref PowerUser, () => BPowerUser.FromType(PowerType)); }
/// <summary>Stream the elements of a floating point array, using a 16-bit length prefix</summary> /// <param name="s"></param> /// <param name="array">Allocated on read</param> /// <returns></returns> public static IO.EndianStream StreamArray16(IO.EndianStream s, ref float[] array) { bool reading = s.IsReading; var count = (ushort)(reading ? 0 : array.Length); s.Stream(ref count); if (reading) { array = new float[count]; } for (int x = 0; x < count; x++) { s.Stream(ref array[x]); } return(s); }
public void Serialize(IO.EndianStream s) { s.StreamSignature(kSignature); s.Stream(ref HeaderSize); s.Stream(ref Adler32); s.Stream(ref TotalSize); s.Stream(ref ChunkCount); s.Stream(ref mFlags); if (s.IsReading && mFlags != 0) { // TODO: trace System.Diagnostics.Debugger.Break(); } s.Stream(ref mID); s.Stream(ref mExtraDataSize); s.Pad(sizeof(short) + sizeof(int)); }
public void ComputeAdler32AndWrite(IO.EndianStream s, long headerPosition) { Contract.Requires(s != null); Contract.Requires(headerPosition >= 0); long current_position = s.BaseStream.Position; long adler_start_position = headerPosition + kAdler32StartOffset; s.BaseStream.Seek(adler_start_position, SeekOrigin.Begin); var adler = Security.Cryptography.Adler32.Compute(s.BaseStream, Adler32BufferLength); Adler32 = adler; s.BaseStream.Seek(headerPosition, SeekOrigin.Begin); this.Serialize(s); s.BaseStream.Seek(current_position, SeekOrigin.Begin); }
private void SerializeMainChunk(EcfChunk chunk, IO.EndianStream s) { if (s.IsReading) { if (!chunk.IsDeflateStream) { throw new System.IO.InvalidDataException(string.Format("{0}'s is supposed to be an XMB but isn't compressed", chunk.EntryId.ToString("X16"))); } FileData = CompressedStream.DecompressFromStream(s); } else if (s.IsWriting) { Contract.Assert(false); chunk.IsDeflateStream = true; } }
public void Serialize(IO.EndianStream s) { s.Stream(ref HasCommand); s.Stream(ref NewCommand); s.Stream(ref StateChanged); s.Stream(ref NewState); s.Stream(ref HasPreconditionResult); s.Stream(ref PreconditionResult); s.Stream(ref PreconditionTime); s.Stream(ref State); s.Stream(ref GamesReinforced); s.Stream(ref TimesReinforced); s.Stream(ref HintDisplayedCount); BSaveGame.StreamList(s, Pages, kPagesListInfo); s.Stream(ref TimesReinforcedThisGame); s.Stream(ref EventReady); s.Stream(ref Active); s.Stream(ref Permission); s.Stream(ref InitialWaitTimeRemaining); s.Stream(ref TerminalWaitTimeRemaining); s.Stream(ref CoolDownTimer); s.Stream(ref LastCoolDownAmount); s.Stream(ref CoolDownTimerAccumulator); BSaveGame.StreamArray(s, ref SubHints); s.Stream(ref ParentHint); Contract.Assert(ParentHint <= kMaxCount); s.Stream(ref PrereqsMet); s.Stream(ref DirtyProfile); s.StreamSignature(cSaveMarker.Concept); }