diff options
| author | Wither OrNot | 2025-02-13 14:49:35 +0000 |
|---|---|---|
| committer | Wither OrNot | 2025-02-13 14:49:37 +0000 |
| commit | 0d59561bee4cf7db10d53a8aa58952ae65e856b5 (patch) | |
| tree | b2ddb66c883dd2ef75426de4c080f3121f0a8658 /LibTSforge/PhysicalStore | |
| download | TSforge-0d59561bee4cf7db10d53a8aa58952ae65e856b5.zip | |
Initial commit1.0.0
Co-authored-by: neko <[email protected]>
Co-authored-by: Lyssa <[email protected]>
Co-authored-by: abbodi1406 <[email protected]>
Diffstat (limited to 'LibTSforge/PhysicalStore')
| -rw-r--r-- | LibTSforge/PhysicalStore/Common.cs | 21 | ||||
| -rw-r--r-- | LibTSforge/PhysicalStore/IPhysicalStore.cs | 92 | ||||
| -rw-r--r-- | LibTSforge/PhysicalStore/PhysicalStoreModern.cs | 411 | ||||
| -rw-r--r-- | LibTSforge/PhysicalStore/PhysicalStoreWin7.cs | 374 | ||||
| -rw-r--r-- | LibTSforge/PhysicalStore/VariableBag.cs | 187 |
5 files changed, 1085 insertions, 0 deletions
diff --git a/LibTSforge/PhysicalStore/Common.cs b/LibTSforge/PhysicalStore/Common.cs new file mode 100644 index 0000000..f73f022 --- /dev/null +++ b/LibTSforge/PhysicalStore/Common.cs @@ -0,0 +1,21 @@ +namespace LibTSforge.PhysicalStore +{ + using System.Runtime.InteropServices; + + public enum BlockType : uint + { + NONE, + NAMED, + ATTRIBUTE, + TIMER + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct Timer + { + public ulong Unknown; + public ulong Time1; + public ulong Time2; + public ulong Expiry; + } +} diff --git a/LibTSforge/PhysicalStore/IPhysicalStore.cs b/LibTSforge/PhysicalStore/IPhysicalStore.cs new file mode 100644 index 0000000..e451281 --- /dev/null +++ b/LibTSforge/PhysicalStore/IPhysicalStore.cs @@ -0,0 +1,92 @@ +namespace LibTSforge.PhysicalStore +{ + using System; + using System.Collections.Generic; + + public class PSBlock + { + public BlockType Type; + public uint Flags; + public uint Unknown = 0; + public byte[] Key; + public string KeyAsStr + { + get + { + return Utils.DecodeString(Key); + } + set + { + Key = Utils.EncodeString(value); + } + } + public byte[] Value; + public string ValueAsStr + { + get + { + return Utils.DecodeString(Value); + } + set + { + Value = Utils.EncodeString(value); + } + } + public uint ValueAsInt + { + get + { + return BitConverter.ToUInt32(Value, 0); + } + set + { + Value = BitConverter.GetBytes(value); + } + } + public byte[] Data; + public string DataAsStr + { + get + { + return Utils.DecodeString(Data); + } + set + { + Data = Utils.EncodeString(value); + } + } + public uint DataAsInt + { + get + { + return BitConverter.ToUInt32(Data, 0); + } + set + { + Data = BitConverter.GetBytes(value); + } + } + } + + public interface IPhysicalStore : IDisposable + { + PSBlock GetBlock(string key, string value); + PSBlock GetBlock(string key, uint value); + void AddBlock(PSBlock block); + void AddBlocks(IEnumerable<PSBlock> blocks); + void SetBlock(string key, string value, byte[] data); + void SetBlock(string key, string value, string data); + void SetBlock(string key, string value, uint data); + void SetBlock(string key, uint value, byte[] data); + void SetBlock(string key, uint value, string data); + void SetBlock(string key, uint value, uint data); + void DeleteBlock(string key, string value); + void DeleteBlock(string key, uint value); + byte[] Serialize(); + void Deserialize(byte[] data); + byte[] ReadRaw(); + void WriteRaw(byte[] data); + IEnumerable<PSBlock> FindBlocks(string valueSearch); + IEnumerable<PSBlock> FindBlocks(uint valueSearch); + } +} diff --git a/LibTSforge/PhysicalStore/PhysicalStoreModern.cs b/LibTSforge/PhysicalStore/PhysicalStoreModern.cs new file mode 100644 index 0000000..f697bea --- /dev/null +++ b/LibTSforge/PhysicalStore/PhysicalStoreModern.cs @@ -0,0 +1,411 @@ +namespace LibTSforge.PhysicalStore +{ + using System; + using System.Collections.Generic; + using System.IO; + using LibTSforge.Crypto; + + public class ModernBlock + { + public BlockType Type; + public uint Flags; + public uint Unknown; + public byte[] Value; + public string ValueAsStr + { + get + { + return Utils.DecodeString(Value); + } + set + { + Value = Utils.EncodeString(value); + } + } + public uint ValueAsInt + { + get + { + return BitConverter.ToUInt32(Value, 0); + } + set + { + Value = BitConverter.GetBytes(value); + } + } + public byte[] Data; + public string DataAsStr + { + get + { + return Utils.DecodeString(Data); + } + set + { + Data = Utils.EncodeString(value); + } + } + public uint DataAsInt + { + get + { + return BitConverter.ToUInt32(Data, 0); + } + set + { + Data = BitConverter.GetBytes(value); + } + } + + public void Encode(BinaryWriter writer) + { + writer.Write((uint)Type); + writer.Write(Flags); + writer.Write((uint)Value.Length); + writer.Write((uint)Data.Length); + writer.Write(Unknown); + writer.Write(Value); + writer.Write(Data); + } + + public static ModernBlock Decode(BinaryReader reader) + { + uint type = reader.ReadUInt32(); + uint flags = reader.ReadUInt32(); + + uint valueLen = reader.ReadUInt32(); + uint dataLen = reader.ReadUInt32(); + uint unk3 = reader.ReadUInt32(); + + byte[] value = reader.ReadBytes((int)valueLen); + byte[] data = reader.ReadBytes((int)dataLen); + + return new ModernBlock + { + Type = (BlockType)type, + Flags = flags, + Unknown = unk3, + Value = value, + Data = data, + }; + } + } + + public sealed class PhysicalStoreModern : IPhysicalStore + { + private byte[] PreHeaderBytes = new byte[] { }; + private readonly Dictionary<string, List<ModernBlock>> Data = new Dictionary<string, List<ModernBlock>>(); + private readonly FileStream TSFile; + private readonly PSVersion Version; + private readonly bool Production; + + public byte[] Serialize() + { + BinaryWriter writer = new BinaryWriter(new MemoryStream()); + writer.Write(PreHeaderBytes); + writer.Write(Data.Keys.Count); + + foreach (string key in Data.Keys) + { + List<ModernBlock> blocks = Data[key]; + byte[] keyNameEnc = Utils.EncodeString(key); + + writer.Write(keyNameEnc.Length); + writer.Write(keyNameEnc); + writer.Write(blocks.Count); + writer.Align(4); + + foreach (ModernBlock block in blocks) + { + block.Encode(writer); + writer.Align(4); + } + } + + return writer.GetBytes(); + } + + public void Deserialize(byte[] data) + { + BinaryReader reader = new BinaryReader(new MemoryStream(data)); + PreHeaderBytes = reader.ReadBytes(8); + + while (reader.BaseStream.Position < data.Length - 0x4) + { + uint numKeys = reader.ReadUInt32(); + + for (int i = 0; i < numKeys; i++) + { + uint lenKeyName = reader.ReadUInt32(); + string keyName = Utils.DecodeString(reader.ReadBytes((int)lenKeyName)); uint numValues = reader.ReadUInt32(); + + reader.Align(4); + + Data[keyName] = new List<ModernBlock>(); + + for (int j = 0; j < numValues; j++) + { + Data[keyName].Add(ModernBlock.Decode(reader)); + reader.Align(4); + } + } + } + } + + public void AddBlock(PSBlock block) + { + if (!Data.ContainsKey(block.KeyAsStr)) + { + Data[block.KeyAsStr] = new List<ModernBlock>(); + } + + Data[block.KeyAsStr].Add(new ModernBlock + { + Type = block.Type, + Flags = block.Flags, + Unknown = block.Unknown, + Value = block.Value, + Data = block.Data + }); + } + + public void AddBlocks(IEnumerable<PSBlock> blocks) + { + foreach (PSBlock block in blocks) + { + AddBlock(block); + } + } + + public PSBlock GetBlock(string key, string value) + { + List<ModernBlock> blocks = Data[key]; + + foreach (ModernBlock block in blocks) + { + if (block.ValueAsStr == value) + { + return new PSBlock + { + Type = block.Type, + Flags = block.Flags, + Key = Utils.EncodeString(key), + Value = block.Value, + Data = block.Data + }; + } + } + + return null; + } + + public PSBlock GetBlock(string key, uint value) + { + List<ModernBlock> blocks = Data[key]; + + foreach (ModernBlock block in blocks) + { + if (block.ValueAsInt == value) + { + return new PSBlock + { + Type = block.Type, + Flags = block.Flags, + Key = Utils.EncodeString(key), + Value = block.Value, + Data = block.Data + }; + } + } + + return null; + } + + public void SetBlock(string key, string value, byte[] data) + { + List<ModernBlock> blocks = Data[key]; + + for (int i = 0; i < blocks.Count; i++) + { + ModernBlock block = blocks[i]; + + if (block.ValueAsStr == value) + { + block.Data = data; + blocks[i] = block; + break; + } + } + + Data[key] = blocks; + } + + public void SetBlock(string key, uint value, byte[] data) + { + List<ModernBlock> blocks = Data[key]; + + for (int i = 0; i < blocks.Count; i++) + { + ModernBlock block = blocks[i]; + + if (block.ValueAsInt == value) + { + block.Data = data; + blocks[i] = block; + break; + } + } + + Data[key] = blocks; + } + + public void SetBlock(string key, string value, string data) + { + SetBlock(key, value, Utils.EncodeString(data)); + } + + public void SetBlock(string key, string value, uint data) + { + SetBlock(key, value, BitConverter.GetBytes(data)); + } + + public void SetBlock(string key, uint value, string data) + { + SetBlock(key, value, Utils.EncodeString(data)); + } + + public void SetBlock(string key, uint value, uint data) + { + SetBlock(key, value, BitConverter.GetBytes(data)); + } + + public void DeleteBlock(string key, string value) + { + if (Data.ContainsKey(key)) + { + List<ModernBlock> blocks = Data[key]; + + foreach (ModernBlock block in blocks) + { + if (block.ValueAsStr == value) + { + blocks.Remove(block); + break; + } + } + + Data[key] = blocks; + } + } + + public void DeleteBlock(string key, uint value) + { + if (Data.ContainsKey(key)) + { + List<ModernBlock> blocks = Data[key]; + + foreach (ModernBlock block in blocks) + { + if (block.ValueAsInt == value) + { + blocks.Remove(block); + break; + } + } + + Data[key] = blocks; + } + } + + public PhysicalStoreModern(string tsPath, bool production, PSVersion version) + { + TSFile = File.Open(tsPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); + Deserialize(PhysStoreCrypto.DecryptPhysicalStore(TSFile.ReadAllBytes(), production)); + TSFile.Seek(0, SeekOrigin.Begin); + Version = version; + Production = production; + } + + public void Dispose() + { + if (TSFile.CanWrite) + { + byte[] data = PhysStoreCrypto.EncryptPhysicalStore(Serialize(), Production, Version); + TSFile.SetLength(data.LongLength); + TSFile.Seek(0, SeekOrigin.Begin); + TSFile.WriteAllBytes(data); + TSFile.Close(); + } + } + + public byte[] ReadRaw() + { + byte[] data = PhysStoreCrypto.DecryptPhysicalStore(TSFile.ReadAllBytes(), Production); + TSFile.Seek(0, SeekOrigin.Begin); + return data; + } + + public void WriteRaw(byte[] data) + { + byte[] encrData = PhysStoreCrypto.EncryptPhysicalStore(data, Production, Version); + TSFile.SetLength(encrData.LongLength); + TSFile.Seek(0, SeekOrigin.Begin); + TSFile.WriteAllBytes(encrData); + TSFile.Close(); + } + + public IEnumerable<PSBlock> FindBlocks(string valueSearch) + { + List<PSBlock> results = new List<PSBlock>(); + + foreach (string key in Data.Keys) + { + List<ModernBlock> values = Data[key]; + + foreach (ModernBlock block in values) + { + if (block.ValueAsStr.Contains(valueSearch)) + { + results.Add(new PSBlock + { + Type = block.Type, + Flags = block.Flags, + KeyAsStr = key, + Value = block.Value, + Data = block.Data + }); + } + } + } + + return results; + } + + public IEnumerable<PSBlock> FindBlocks(uint valueSearch) + { + List<PSBlock> results = new List<PSBlock>(); + + foreach (string key in Data.Keys) + { + List<ModernBlock> values = Data[key]; + + foreach (ModernBlock block in values) + { + if (block.ValueAsInt == valueSearch) + { + results.Add(new PSBlock + { + Type = block.Type, + Flags = block.Flags, + KeyAsStr = key, + Value = block.Value, + Data = block.Data + }); + } + } + } + + return results; + } + } +} diff --git a/LibTSforge/PhysicalStore/PhysicalStoreWin7.cs b/LibTSforge/PhysicalStore/PhysicalStoreWin7.cs new file mode 100644 index 0000000..c1af391 --- /dev/null +++ b/LibTSforge/PhysicalStore/PhysicalStoreWin7.cs @@ -0,0 +1,374 @@ +namespace LibTSforge.PhysicalStore +{ + using System; + using System.Collections.Generic; + using System.IO; + using LibTSforge.Crypto; + + public class Win7Block + { + public BlockType Type; + public uint Flags; + public byte[] Key; + public string KeyAsStr + { + get + { + return Utils.DecodeString(Key); + } + set + { + Key = Utils.EncodeString(value); + } + } + public byte[] Value; + public string ValueAsStr + { + get + { + return Utils.DecodeString(Value); + } + set + { + Value = Utils.EncodeString(value); + } + } + public uint ValueAsInt + { + get + { + return BitConverter.ToUInt32(Value, 0); + } + set + { + Value = BitConverter.GetBytes(value); + } + } + public byte[] Data; + public string DataAsStr + { + get + { + return Utils.DecodeString(Data); + } + set + { + Data = Utils.EncodeString(value); + } + } + public uint DataAsInt + { + get + { + return BitConverter.ToUInt32(Data, 0); + } + set + { + Data = BitConverter.GetBytes(value); + } + } + + internal void Encode(BinaryWriter writer) + { + writer.Write((uint)Type); + writer.Write(Flags); + writer.Write(Key.Length); + writer.Write(Value.Length); + writer.Write(Data.Length); + writer.Write(Key); + writer.Write(Value); + writer.Write(Data); + } + + internal static Win7Block Decode(BinaryReader reader) + { + uint type = reader.ReadUInt32(); + uint flags = reader.ReadUInt32(); + + int keyLen = reader.ReadInt32(); + int valueLen = reader.ReadInt32(); + int dataLen = reader.ReadInt32(); + + byte[] key = reader.ReadBytes(keyLen); + byte[] value = reader.ReadBytes(valueLen); + byte[] data = reader.ReadBytes(dataLen); + return new Win7Block + { + Type = (BlockType)type, + Flags = flags, + Key = key, + Value = value, + Data = data, + }; + } + } + + public sealed class PhysicalStoreWin7 : IPhysicalStore + { + private byte[] PreHeaderBytes = new byte[] { }; + private readonly List<Win7Block> Blocks = new List<Win7Block>(); + private readonly FileStream TSPrimary; + private readonly FileStream TSSecondary; + private readonly bool Production; + + public byte[] Serialize() + { + BinaryWriter writer = new BinaryWriter(new MemoryStream()); + writer.Write(PreHeaderBytes); + + foreach (Win7Block block in Blocks) + { + block.Encode(writer); + writer.Align(4); + } + + return writer.GetBytes(); + } + + public void Deserialize(byte[] data) + { + int len = data.Length; + + BinaryReader reader = new BinaryReader(new MemoryStream(data)); + PreHeaderBytes = reader.ReadBytes(8); + + while (reader.BaseStream.Position < len - 0x14) + { + Blocks.Add(Win7Block.Decode(reader)); + reader.Align(4); + } + } + + public void AddBlock(PSBlock block) + { + Blocks.Add(new Win7Block + { + Type = block.Type, + Flags = block.Flags, + Key = block.Key, + Value = block.Value, + Data = block.Data + }); + } + + public void AddBlocks(IEnumerable<PSBlock> blocks) + { + foreach (PSBlock block in blocks) + { + AddBlock(block); + } + } + + public PSBlock GetBlock(string key, string value) + { + foreach (Win7Block block in Blocks) + { + if (block.KeyAsStr == key && block.ValueAsStr == value) + { + return new PSBlock + { + Type = block.Type, + Flags = block.Flags, + Key = block.Key, + Value = block.Value, + Data = block.Data + }; + } + } + + return null; + } + + public PSBlock GetBlock(string key, uint value) + { + foreach (Win7Block block in Blocks) + { + if (block.KeyAsStr == key && block.ValueAsInt == value) + { + return new PSBlock + { + Type = block.Type, + Flags = block.Flags, + Key = block.Key, + Value = block.Value, + Data = block.Data + }; + } + } + + return null; + } + + public void SetBlock(string key, string value, byte[] data) + { + for (int i = 0; i < Blocks.Count; i++) + { + Win7Block block = Blocks[i]; + + if (block.KeyAsStr == key && block.ValueAsStr == value) + { + block.Data = data; + Blocks[i] = block; + break; + } + } + } + + public void SetBlock(string key, uint value, byte[] data) + { + for (int i = 0; i < Blocks.Count; i++) + { + Win7Block block = Blocks[i]; + + if (block.KeyAsStr == key && block.ValueAsInt == value) + { + block.Data = data; + Blocks[i] = block; + break; + } + } + } + + public void SetBlock(string key, string value, string data) + { + SetBlock(key, value, Utils.EncodeString(data)); + } + + public void SetBlock(string key, string value, uint data) + { + SetBlock(key, value, BitConverter.GetBytes(data)); + } + + public void SetBlock(string key, uint value, string data) + { + SetBlock(key, value, Utils.EncodeString(data)); + } + + public void SetBlock(string key, uint value, uint data) + { + SetBlock(key, value, BitConverter.GetBytes(data)); + } + + public void DeleteBlock(string key, string value) + { + foreach (Win7Block block in Blocks) + { + if (block.KeyAsStr == key && block.ValueAsStr == value) + { + Blocks.Remove(block); + return; + } + } + } + + public void DeleteBlock(string key, uint value) + { + foreach (Win7Block block in Blocks) + { + if (block.KeyAsStr == key && block.ValueAsInt == value) + { + Blocks.Remove(block); + return; + } + } + } + + public PhysicalStoreWin7(string primaryPath, bool production) + { + TSPrimary = File.Open(primaryPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); + TSSecondary = File.Open(primaryPath.Replace("-0.", "-1."), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); + Production = production; + + Deserialize(PhysStoreCrypto.DecryptPhysicalStore(TSPrimary.ReadAllBytes(), production)); + TSPrimary.Seek(0, SeekOrigin.Begin); + } + + public void Dispose() + { + if (TSPrimary.CanWrite && TSSecondary.CanWrite) + { + byte[] data = PhysStoreCrypto.EncryptPhysicalStore(Serialize(), Production, PSVersion.Win7); + + TSPrimary.SetLength(data.LongLength); + TSSecondary.SetLength(data.LongLength); + + TSPrimary.Seek(0, SeekOrigin.Begin); + TSSecondary.Seek(0, SeekOrigin.Begin); + + TSPrimary.WriteAllBytes(data); + TSSecondary.WriteAllBytes(data); + + TSPrimary.Close(); + TSSecondary.Close(); + } + } + + public byte[] ReadRaw() + { + byte[] data = PhysStoreCrypto.DecryptPhysicalStore(TSPrimary.ReadAllBytes(), Production); + TSPrimary.Seek(0, SeekOrigin.Begin); + return data; + } + + public void WriteRaw(byte[] data) + { + byte[] encrData = PhysStoreCrypto.EncryptPhysicalStore(data, Production, PSVersion.Win7); + + TSPrimary.SetLength(encrData.LongLength); + TSSecondary.SetLength(encrData.LongLength); + + TSPrimary.Seek(0, SeekOrigin.Begin); + TSSecondary.Seek(0, SeekOrigin.Begin); + + TSPrimary.WriteAllBytes(encrData); + TSSecondary.WriteAllBytes(encrData); + + TSPrimary.Close(); + TSSecondary.Close(); + } + + public IEnumerable<PSBlock> FindBlocks(string valueSearch) + { + List<PSBlock> results = new List<PSBlock>(); + + foreach (Win7Block block in Blocks) + { + if (block.ValueAsStr.Contains(valueSearch)) + { + results.Add(new PSBlock + { + Type = block.Type, + Flags = block.Flags, + Key = block.Key, + Value = block.Value, + Data = block.Data + }); + } + } + + return results; + } + + public IEnumerable<PSBlock> FindBlocks(uint valueSearch) + { + List<PSBlock> results = new List<PSBlock>(); + + foreach (Win7Block block in Blocks) + { + if (block.ValueAsInt == valueSearch) + { + results.Add(new PSBlock + { + Type = block.Type, + Flags = block.Flags, + Key = block.Key, + Value = block.Value, + Data = block.Data + }); + } + } + + return results; + } + } +} diff --git a/LibTSforge/PhysicalStore/VariableBag.cs b/LibTSforge/PhysicalStore/VariableBag.cs new file mode 100644 index 0000000..ddc2efe --- /dev/null +++ b/LibTSforge/PhysicalStore/VariableBag.cs @@ -0,0 +1,187 @@ +namespace LibTSforge.PhysicalStore +{ + using System; + using System.Collections.Generic; + using System.IO; + + public enum CRCBlockType : uint + { + UINT = 1 << 0, + STRING = 1 << 1, + BINARY = 1 << 2 + } + + public class CRCBlock + { + public CRCBlockType DataType; + public byte[] Key; + public string KeyAsStr + { + get + { + return Utils.DecodeString(Key); + } + set + { + Key = Utils.EncodeString(value); + } + } + public byte[] Value; + public string ValueAsStr + { + get + { + return Utils.DecodeString(Value); + } + set + { + Value = Utils.EncodeString(value); + } + } + public uint ValueAsInt + { + get + { + return BitConverter.ToUInt32(Value, 0); + } + set + { + Value = BitConverter.GetBytes(value); + } + } + + public void Encode(BinaryWriter writer) + { + uint crc = CRC(); + writer.Write(crc); + writer.Write((uint)DataType); + writer.Write(Key.Length); + writer.Write(Value.Length); + + writer.Write(Key); + writer.Align(8); + + writer.Write(Value); + writer.Align(8); + } + + public static CRCBlock Decode(BinaryReader reader) + { + uint crc = reader.ReadUInt32(); + uint type = reader.ReadUInt32(); + uint lenName = reader.ReadUInt32(); + uint lenVal = reader.ReadUInt32(); + + byte[] key = reader.ReadBytes((int)lenName); + reader.Align(8); + + byte[] value = reader.ReadBytes((int)lenVal); + reader.Align(8); + + CRCBlock block = new CRCBlock + { + DataType = (CRCBlockType)type, + Key = key, + Value = value, + }; + + if (block.CRC() != crc) + { + throw new InvalidDataException("Invalid CRC in variable bag."); + } + + return block; + } + + public uint CRC() + { + BinaryWriter wtemp = new BinaryWriter(new MemoryStream()); + wtemp.Write(0); + wtemp.Write((uint)DataType); + wtemp.Write(Key.Length); + wtemp.Write(Value.Length); + wtemp.Write(Key); + wtemp.Write(Value); + return Utils.CRC32(wtemp.GetBytes()); + } + } + + public class VariableBag + { + public List<CRCBlock> Blocks = new List<CRCBlock>(); + + public void Deserialize(byte[] data) + { + int len = data.Length; + + BinaryReader reader = new BinaryReader(new MemoryStream(data)); + + while (reader.BaseStream.Position < len - 0x10) + { + Blocks.Add(CRCBlock.Decode(reader)); + } + } + + public byte[] Serialize() + { + BinaryWriter writer = new BinaryWriter(new MemoryStream()); + + foreach (CRCBlock block in Blocks) + { + block.Encode(writer); + } + + return writer.GetBytes(); + } + + public CRCBlock GetBlock(string key) + { + foreach (CRCBlock block in Blocks) + { + if (block.KeyAsStr == key) + { + return block; + } + } + + return null; + } + + public void SetBlock(string key, byte[] value) + { + for (int i = 0; i < Blocks.Count; i++) + { + CRCBlock block = Blocks[i]; + + if (block.KeyAsStr == key) + { + block.Value = value; + Blocks[i] = block; + break; + } + } + } + + public void DeleteBlock(string key) + { + foreach (CRCBlock block in Blocks) + { + if (block.KeyAsStr == key) + { + Blocks.Remove(block); + return; + } + } + } + + public VariableBag(byte[] data) + { + Deserialize(data); + } + + public VariableBag() + { + + } + } +} |
