public TagMap(byte[] data) { if (data == null) { throw new ArgumentNullException(nameof(data)); } Reader = new BufferMemoryReader(data); if (data.Length > 0) { Count = Reader.Read <int>(0x00); Entries = new Entry[Count]; var offset = 0x04; for (int i = 0; i < Count; i++) { Entries[i] = new Entry(); Entries[i].Type = Reader.Read <int>(offset); offset += 4; Entries[i].Key = Reader.Read <int>(offset); offset += 4; switch (Entries[i].Type) { case 0: Entries[i].Value = Reader.Read <int>(offset); offset += 4; break; case 1: Entries[i].Value = Reader.Read <float>(offset); offset += 4; break; case 2: Entries[i].Value = Reader.Read <SNO>(offset); offset += 4; break; case 3: Entries[i].Value = Reader.Read <GBID>(offset); offset += 4; break; case 4: Entries[i].Value = new ScriptFormula(Reader, ref offset); break; case 5: // TODO: Better type Entries[i].Value = Reader.Read <int>(offset); offset += 4; break; case 6: Entries[i].Value = Reader.Read <AttributeId>(offset); offset += 4; break; case 7: // TODO: Better type Entries[i].Value = Reader.Read <int>(offset); offset += 4; break; default: throw new NotImplementedException($"Entry type {Entries[i].Type} deserialization not implemented."); } } } }
public void Update() { Container.TakeSnapshot(); if (PreviousData.Length != CurrentData.Length) { Array.Resize(ref PreviousData, CurrentData.Length); } Buffer.BlockCopy(CurrentData, 0, PreviousData, 0, CurrentData.Length); Container.GetAllocatedBytes(ref CurrentData); if (PreviousMapping.Length != CurrentMapping.Length) { Array.Resize(ref PreviousMapping, CurrentMapping.Length); } Buffer.BlockCopy(CurrentMapping, 0, PreviousMapping, 0, CurrentMapping.Length * sizeof(int)); var count = CurrentData.Length / Container.ItemSize; var mr = new BufferMemoryReader(CurrentData); if (CurrentMapping.Length != count) { Array.Resize(ref CurrentMapping, count); } for (int i = 0; i < count; i++) { CurrentMapping[i] = mr.Read <int>(i * Container.ItemSize); } if (PreviousMapping.Length == CurrentMapping.Length) { for (int i = 0; i < CurrentMapping.Length; i++) { if (CurrentMapping[i] != PreviousMapping[i]) { if (PreviousMapping[i] != -1) { OnItemRemoved(i); } if (CurrentMapping[i] != -1) { OnItemAdded(i); } } } } //var state = (Container.NextHash << 16) + Container.NextIndex; //if (state != State) // OnCollectionModified(); //State = state; }
public static SNOFile <T> LoadFile <T>(string path) where T : SerializeMemoryObject { var buffer = new BufferMemoryReader(File.ReadAllBytes(path)); var file = buffer.Read <SNOFile <T> >(0x00); if (!file.Header.IsValid) { throw new InvalidDataException("Invalid header bytes."); } return(file); }
public static SymbolMap FindAll(byte[] data, BufferMemoryReader mem) { var symbols = new SymbolMap(); foreach (var pattern in PatternProvider.GetPatterns().Select(a => FlairPattern.Parse(a))) { foreach (var pair in FindSymbols(pattern, data, mem)) { symbols.AddRange(pair.Key, pair.Value); } } return(symbols); }
public ScriptFormula(BufferMemoryReader reader, ref int offset) { x00 = reader.Read <int>(offset + 0x00); x04 = reader.Read <int>(offset + 0x04); x08 = reader.Read <int>(offset + 0x08); x0C = reader.Read <int>(offset + 0x0C); x10 = reader.Read <int>(offset + 0x10); OpCodeNameSize = reader.Read <int>(offset + 0x14); x18 = reader.Read <int>(offset + 0x18); OpCodeSize = reader.Read <int>(offset + 0x1C); OpCodeName = reader.ReadString(offset + 0x20, OpCodeNameSize); OpCode = reader.ReadBytes(offset + 0x20 + MemoryObject.AlignedSize(OpCodeNameSize, 4), OpCodeSize); offset += 0x20 + MemoryObject.AlignedSize(OpCodeNameSize, 4) + MemoryObject.AlignedSize(OpCodeSize, 4); }
public T Read(MemoryAddress address) { var block = _blocks.FirstOrDefault(x => x.Contains(address)); if (block == null) { throw new ArgumentException("Address not contained in the cache.", nameof(address)); } var reader = new BufferMemoryReader(block.Data, 0, block.Data.Length, _allocator.Memory.Reader.PointerSize); var offset = address - block.Address; var value = reader.Read <T>(offset); return(value); }
internal static void Run() { var exe = Program.GetExeFile(); var data = File.ReadAllBytes(exe.FullName); var mem = new BufferMemoryReader(data); var version = FileVersionInfo.GetVersionInfo(exe.FullName).FileVersion; PE = new PEHeaderReader(data); var symbols = SymbolLocator.FindAll(data, mem); uint containerManager; var dir = new DirectoryInfo("enigma-d3-memory-" + new Version(version.Replace(", ", "."))); dir.Create(); var objPtrs = new Dictionary <string, uint>(); objPtrs.Add("SNOGroups", symbols.BestMatch("SnoGroups")); objPtrs.Add("SNOGroupsByCode", symbols.BestMatch("SnoGroupsByCode")); objPtrs.Add("AttributeDescriptors", symbols.BestMatch("AttributeDescriptors")); objPtrs.Add("MessageDescriptor", symbols.BestMatch("MessageDescriptor")); objPtrs.Add("LocalData", symbols.BestMatch("LocalData")); objPtrs.Add("ContainerManager", containerManager = symbols.BestMatch("ContainerManager")); objPtrs.Add("ApplicationLoopCount", symbols.BestMatch("ApplicationLoopCount")); objPtrs.Add("ObjectManager", symbols.BestMatch("ObjectManager")); objPtrs.Add("ObjectManagerPristine", symbols.BestMatch("ObjectManagerPristine")); objPtrs.Add("MapActId", symbols.BestMatch("MapActId")); objPtrs.Add("VideoPreferences", symbols.BestMatch("VideoPreferences")); objPtrs.Add("SoundPreferences", symbols.BestMatch("SoundPreferences")); objPtrs.Add("GameplayPreferences", symbols.BestMatch("GameplayPreferences")); objPtrs.Add("SocialPreferences", symbols.BestMatch("SocialPreferences")); objPtrs.Add("ChatPreferences", symbols.BestMatch("ChatPreferences")); objPtrs.Add("HotkeyPreferences", objPtrs["SoundPreferences"] == 0 ? 0 : objPtrs["SoundPreferences"] + 0x50); objPtrs.Add("LevelArea", GetStatic_LevelArea(data, symbols)); objPtrs.Add("LevelAreaName", GetStatic_LevelAreaName(data, symbols)); WriteObjectPtrFile(Path.Combine(dir.FullName, "ObjectPtr.cs"), objPtrs); var methodPtrs = new Dictionary <string, uint>(); methodPtrs.Add("SNOGroups_Initialize", TranslateToVA(symbols.BestMatch("CSnoGroups::Initialize"))); methodPtrs.Add("GameMessage_GetHandlerInfo", TranslateToVA(symbols.BestMatch("CGameMessage::GetHandlerInfo"))); WriteMethodPtrFile(Path.Combine(dir.FullName, "MethodPtr.cs"), methodPtrs); var globals = new Dictionary <string, string>(); globals.Add("static readonly Version SupportedVersion", $"new Version({version})"); globals.Add("const int SNOGroupsCount", "60"); // TODO: Don't hardcode. globals.Add("const int AttributeDescriptorsCount", GetAttributeDescriptorsCount(symbols).ToString()); var sizeof_playerdata = symbols.BestMatch("sizeof(PlayerData)"); // ((symbols.BestMatch("sizeof(PlayerDataManager)") - 0x038) / 8); globals.Add("const int SizeOf_PlayerData", sizeof_playerdata.ToHex()); if (Engine.Current?.ProcessVersion == Engine.SupportedVersion) { globals.Add("const int Offset_PlayerData_HeroName", GetOffset_PlayerData_HeroName(sizeof_playerdata).ToHex()); globals.Add("const int Offset_PlayerData_LifePercentage", GetOffset_PlayerData_LifePercentage(sizeof_playerdata).ToHex()); } else { globals.Add("const int Offset_PlayerData_HeroName", "0; // Run [CodeGen -memory -deploy] again"); globals.Add("const int Offset_PlayerData_LifePercentage", "0; // Run [CodeGen -memory -deploy] again"); } // TODO: globals.Add("const int SizeOf_LevelArea", symbols.BestMatch("sizeof(LevelArea)").ToHex()); WriteGlobalsFile(Path.Combine(dir.FullName, "Globals.cs"), globals); var project = new SharedProject("862a67ee-9ceb-42fe-9406-d7feafc55b00", "Enigma.D3.Memory"); project.AddCompileFile(Path.Combine(dir.FullName, "Globals.cs")); project.AddCompileFile(Path.Combine(dir.FullName, "MethodPtr.cs")); project.AddCompileFile(Path.Combine(dir.FullName, "ObjectPtr.cs")); project.Save(Path.Combine(dir.FullName, "Enigma.D3.Memory.Generated.*")); if (Program.DeployGeneratedCode) { project.Deploy( dir, Program.SolutionDirectory.CreateSubdirectory(project.RootNamespace + ".Generated")); } }
public void Update() { Container.TakeSnapshot(); if (PreviousData.Length != CurrentData.Length) { Array.Resize(ref PreviousData, CurrentData.Length); } Buffer.BlockCopy(CurrentData, 0, PreviousData, 0, CurrentData.Length); Container.GetAllocatedBytes(ref CurrentData); if (PreviousMapping.Length != CurrentMapping.Length) { Array.Resize(ref PreviousMapping, CurrentMapping.Length); } Buffer.BlockCopy(CurrentMapping, 0, PreviousMapping, 0, CurrentMapping.Length * sizeof(int)); var count = CurrentData.Length / Container.ItemSize; var mr = new BufferMemoryReader(CurrentData); if (CurrentMapping.Length != count) { Array.Resize(ref CurrentMapping, count); } for (int i = 0; i < count; i++) { CurrentMapping[i] = mr.Read <int>(i * Container.ItemSize); } NewItems.Clear(); OldItems.Clear(); // Compare against previous where there is a value. for (int i = 0; i < Math.Min(PreviousMapping.Length, CurrentMapping.Length); i++) { if (CurrentMapping[i] != PreviousMapping[i]) { if (PreviousMapping[i] != -1) { OnItemRemoved(i); OldItems.Add(MemoryObjectFactory.UnsafeCreate <T>(new BufferMemoryReader(PreviousData), i * Container.ItemSize)); } if (CurrentMapping[i] != -1) { OnItemAdded(i); NewItems.Add(MemoryObjectFactory.UnsafeCreate <T>(new BufferMemoryReader(CurrentData), i * Container.ItemSize)); } } } // Check expanded area. for (int i = PreviousMapping.Length; i < CurrentMapping.Length; i++) { if (CurrentMapping[i] != -1) { OnItemAdded(i); NewItems.Add(MemoryObjectFactory.UnsafeCreate <T>(new BufferMemoryReader(CurrentData), i * Container.ItemSize)); } } // Check reduced area. for (int i = CurrentMapping.Length; i < PreviousMapping.Length; i++) { if (PreviousMapping[i] != -1) { OnItemRemoved(i); OldItems.Add(MemoryObjectFactory.UnsafeCreate <T>(new BufferMemoryReader(PreviousData), i * Container.ItemSize)); } } }
/// <summary> /// Update the container buffer and item snapshots. Old (removed) items will be added to /// <see cref="OldItems"/> and new items to <see cref="NewItems"/>. /// </summary> public void Update() { _container.TakeSnapshot(); _previousSegments = _currentSegments; if (_previousData.Length != _currentData.Length) { Array.Resize(ref _previousData, _currentData.Length); } Buffer.BlockCopy(_currentData, 0, _previousData, 0, _currentData.Length); _currentSegments = _container.GetAllocatedBytes(ref _currentData); if (_currentData.Length != _previousData.Length) // buffer was resized (and replaced), update underlying buffer for all items { for (int i = 0; i < _items.Length; i++) { if (_items[i] == null) { continue; } _items[i].SetSnapshot(_currentData, i * _container.ItemSize, _container.ItemSize); } } if (_previousMapping.Length != _currentMapping.Length) { Array.Resize(ref _previousMapping, _currentMapping.Length); } Buffer.BlockCopy(_currentMapping, 0, _previousMapping, 0, _currentMapping.Length * sizeof(int)); var count = _currentData.Length / _container.ItemSize; var mr = new BufferMemoryReader(_currentData); if (_currentMapping.Length != count) { Array.Resize(ref _currentMapping, count); } for (int i = 0; i <= _container.MaxIndex; i++) { _currentMapping[i] = mr.Read <int>(i * _container.ItemSize); } for (int i = _container.MaxIndex + 1; i < count; i++) { _currentMapping[i] = -1; } NewItems.Clear(); OldItems.Clear(); if (_items.Length != _container.Capacity) { Array.Resize(ref _items, _container.Capacity); } // Compare against previous where there is a value. for (int i = 0; i < Math.Min(_previousMapping.Length, _currentMapping.Length); i++) { if (_currentMapping[i] != _previousMapping[i]) { if (_previousMapping[i] != -1) { var item = CreatePreviousItem(i); OnItemRemoved(i, item); OldItems.Add(item); } if (_currentMapping[i] != -1 && _currentMapping[i] != 0) // NB: New item starts with ID 0 { var item = CreateCurrentItem(i); OnItemAdded(i, item); NewItems.Add(item); } } } // Check expanded area. for (int i = _previousMapping.Length; i < _currentMapping.Length; i++) { if (_currentMapping[i] != -1) { var item = CreateCurrentItem(i); OnItemAdded(i, item); NewItems.Add(item); } } // Check reduced area. for (int i = _currentMapping.Length; i < _previousMapping.Length; i++) { if (_previousMapping[i] != -1) { var item = CreatePreviousItem(i); OnItemRemoved(i, item); OldItems.Add(item); } } }