diabloIII
来源:互联网 发布:网络管理是什么意思 编辑:程序博客网 时间:2024/04/26 01:22
public readonly int ObjectManager_ofs_storage = 0x7CC;public readonly int ObjectManagerStorage_ofs__local = 0x1B8;public readonly int ObjectManagerStorage_ofs__data = 0x0A8;public readonly int ObjectManagerStorage_ofs__attrib_groups = 0x0C8;public readonly int player_data_size = 0x8598;public readonly int player_ofs__area = 0x78F8;public readonly int player_ofs__seed = 0x7448;public readonly int player_ofs__name = 0x7450;public readonly int player_ofs__class = 0x78FC;public readonly int player_ofs__actor_id = 0x8;public readonly int acd_ofs__id = 0x000;public readonly int acd_ofs__gb_type = 0x0B0;public readonly int acd_ofs__gb_id = 0x0B4;public readonly int acd_ofs__attrib_group_id = 0x120;public readonly int acd_ofs__sno = 0x090;public readonly int acd_ofs__item_location = 0x114;public readonly int acd_ofs__item_x = 0x118;public readonly int acd_ofs__item_y = 0x11C;public readonly int acd_ofs__pos_x = 0x0D0;public readonly int acd_ofs__pos_y = 0x0D4;public readonly int acd_ofs__pos_z = 0x0D8;public readonly int acd_ofs__monster_type = 0x0B8;public readonly int attrib_link_ofs__next = 0x000;public readonly int attrib_link_ofs__id = 0x004;public readonly int attrib_link_ofs__value = 0x008;public readonly int AttribGroupsContainer_ofs__FastAttribGroups = 0x070;
Reading Player's Location:
int ObjectManagerPtr = MR.ReadInt(ObjectManagerAddress);int ObjectManagerStoragePtr = ObjectManagerPtr + ObjectManager_ofs_storage;int ObjectManagerStorageDataPtr = MR.ReadInt(ObjectManagerStoragePtr + ObjectManagerStorage_ofs__data);int ObjectManagerStorageLocalPtr = MR.ReadInt(ObjectManagerStoragePtr + ObjectManagerStorage_ofs__local);int MyPlayerIndex = MR.ReadInt(ObjectManagerStorageLocalPtr);for (int i = 0; i < 4; i++){ uint seed = MR.ReadUInt(ObjectManagerStorageDataPtr + i * player_data_size + 0x58 + player_ofs__seed); if (seed == 0) continue; string CharacterName = MR.ReadString(ObjectManagerStorageDataPtr + i * player_data_size + 0x58 + player_ofs__name, 12 + 1, Encoding.ASCII, true); uint class_idx = MR.ReadUInt(ObjectManagerStorageDataPtr + i * player_data_size + 0x58 + player_ofs__class); // 0=DH, 1=barb, 2=wiz, 3=wd, 4=monk uint levelarea_id = MR.ReadUInt(ObjectManagerStorageDataPtr + i * player_data_size + 0x58 + player_ofs__area); if (MyPlayerIndex == i) { // tadamm: this is our player's levelarea_id and other stuff } uint ActorID = MR.ReadUInt(ObjectManagerStorageDataPtr + i * player_data_size + 0x58 + player_ofs__actor_id); if ((ActorID == 0) || (ActorID == uint.MaxValue)) { // our player's actor is always valid, but party members too far from us will "disappear" }}
Reading an UI Component:
What you need:
- the UI component's path ("Name", don't ask me for it)
Note:
- figuring out the idiot internal coodinate -> screen coordinate conversion took me 4 days, and it is not working with letterbox, but pixel-perfect on every resolution and screen ratios
ObjectManagerPtr = MR.ReadInt(ObjectManagerAddress);ObjectManagerStoragePtr = ObjectManagerPtr + ObjectManager_ofs_storage;ui_mgr_ptr = MR.ReadInt(ObjectManagerStoragePtr + 0x1A8);ui_component_map_hashtable = MR.ReadInt(ui_mgr_ptr + 0x000);ui_component_table_start = MR.ReadInt(ui_component_map_hashtable + 0x008);ui_component_table_size = MR.ReadInt(ui_component_map_hashtable + 0x010);ui_component_table = new int[ui_component_table_size];ui_component_table_mask = MR.ReadInt(ui_component_map_hashtable + 0x040);MR.ReadMem(ui_component_table_start, ui_component_table, ui_component_table_size * 4); // blocked memory read
1) Dumping all components
for (int i = 0; i < ui_component_table_size; i++){int link = MR.ReadInt(ui_component_table_start + i * 4);while (link != 0){ int ui_component_ptr = MR.ReadInt(link + 0x210); bool visible = MR.ReadInt(ui_component_ptr + 0x028) == 1; ulong hash = MR.ReadULong(ui_component_ptr + 0x030 + 0x00); string name = MR.ReadString(ui_component_ptr + 0x030 + 0x08, 256, Encoding.ASCII, true); float X = MR.ReadFloat(ui_component_ptr + 0x508); float Y = MR.ReadFloat(ui_component_ptr + 0x50C); float R = MR.ReadFloat(ui_component_ptr + 0x510); float B = MR.ReadFloat(ui_component_ptr + 0x514); int TextPtr = MR.ReadInt(ui_component_ptr + 0xAE0); string Text = null; if (TextPtr != 0) Text = MR.ReadString(TextPtr, 256, Encoding.ASCII, true); // true means trimming at \0 if (visible) {float fourthreewidth = (float)D3ClientWindowSize.Height / 3.0f * 4.0f;float mb_ratio = 600.0f / D3ClientWindowSize.Height;float mb = (D3ClientWindowSize.Width - fourthreewidth) * mb_ratio;float SX = (X + mb) / (1200.0f / D3ClientWindowSize.Height);float SR = (R + mb) / (1200.0f / D3ClientWindowSize.Height);float SY = Y * (D3ClientWindowSize.Height / 1200.0f);float SB = (B - 1) * (D3ClientWindowSize.Height / 1200.0f);Rect.X = Convert.ToInt32(SX);Rect.Y = Convert.ToInt32(SY);Rect.Width = Convert.ToInt32(SR - SX - 1);Rect.Height = Convert.ToInt32(SB - SY - 1); } // do something with the variables here... link = MR.ReadInt(link + 0x000);}}
2. Reading an UI component with a specific path (Name)
Hash = FNVHash(Name.ToLower());Bucket = (int)(((Hash >> 32) ^ (uint)Hash) & (uint)ui_component_table_mask);pair_address = ui_component_table[Bucket];msUIPair pair = new msUIPair();int n = 0;while ((pair_address != 0) && (n < 10)){MR.ReadMem(pair_address, pair, 16);if (pair.UIReference_Hash == this.Hash){int ui_component_ptr = MR.ReadInt(pair_address + msUIPair.ValueOfs); // pair.value// found it, use this ptr to read and process UI component!return;}pair_address = pair.NextPair;n++;}The used structures: [StructLayout(LayoutKind.Sequential, Pack = 1)] public sealed class msUIPair { public int NextPair; // 0x000:4 public int UIReference_Unknown; // 0x004:4 public ulong UIReference_Hash; // 0x008:8 // char[200] UIReference_Path... // 0x010:200 public static int ValueOfs = 0x210; }//Hash generator:private ulong FNVHash(string s){ ulong FNVHash = 0xCBF29CE484222325; for (int i = 0; i < s.Length; i++) { FNVHash = FNVHash ^ (byte)s[i]; FNVHash = FNVHash * 0x100000001B3; FNVHash = FNVHash & 0xFFFFFFFFFFFFFFFF; } return FNVHash; }
Reading Attributes
What you need:
- the attribute's ID and mask
The basics
You can find attributes by their Index (the number), and their mask.
Most attributes has no mask (no mask = 0xFFFFF).
Examples:
- Resistance_All has no mask, so it's "FullID" = 0xFFFFF << 12 | 99
- "lightning resist" is contained in "Resistance" attribute with mask 0x2, so it's FullID = 0x2 << 12 | 96
public readonly int ObjectManagerStorage_ofs__acds = 0xD4;ObjectManagerPtr = MR.ReadInt(ObjectManagerAddress);ObjectManagerStoragePtr = ObjectManagerPtr + ObjectManager_ofs_storage;addr_acds = MR.ReadInt(ObjectManagerStoragePtr + ObjectManagerStorage_ofs__acds);addr_attrib_groups = MR.ReadInt(ObjectManagerStoragePtr + ObjectManagerStorage_ofs__attrib_groups);addr_acds_container = MR.ReadInt(addr_acds);acd_data_list_ofs = MR.ReadInt(addr_acds_container + 0x148); //container.List, double pointeracd_data_start_ofs = MR.ReadInt(acd_data_list_ofs); //container.Listacd_sizeof = MR.ReadInt(addr_acds_container + 0x104); //container.SizeOfacd_bits = MR.ReadInt(addr_acds_container + 0x18C); //container.Bitsacd_count_ofs = addr_acds_container + 0x108; //container.Countaddr_attrib_groups_container = MR.ReadInt(addr_attrib_groups + AttribGroupsContainer_ofs__FastAttribGroups); // AttribGroupsContainer.FastAttribGroupsattrib_data_list_ofs = MR.ReadInt(addr_attrib_groups_container + 0x148); //container.List, double pointerattrib_sizeof = MR.ReadInt(addr_attrib_groups_container + 0x104); //container.SizeOfattrib_bits = MR.ReadInt(addr_attrib_groups_container + 0x18C); //container.Bits//Enumerating All Actors and their AttributesACDCount = MR.ReadInt(acd_count_ofs);for (int i = 0; i <= ACDCount; i++){ int acd_address = acd_data_start_ofs + i * acd_sizeof; uint AcdID = MR.ReadUInt(acd_address + acd_ofs__id); if (AcdID == uint.MaxValue) continue; int gb_type = MR.ReadInt(acd_address + acd_ofs__gb_type); // gamebalance type uint gb_id = MR.ReadUInt(acd_address + acd_ofs__gb_id); // gamebalance id // gb_type = 2 means this is an item int group_id = MR.ReadInt(acd_address + acd_ofs__attrib_group_id); int full_id = group_id & 0xFFFF; int a = full_id >> attrib_bits; int b = full_id & ((1 << attrib_bits) - 1); int dwFirst = MR.ReadInt((int)(attrib_data_list_ofs) + a * 4); int group_ofs = (int)(dwFirst + attrib_sizeof * b); int group_formula_ofs = MR.ReadInt(group_ofs + 0x010); int acd_FormulaMapData = MR.ReadInt(group_formula_ofs + 0x008 + 0x000); if (acd_FormulaMapData == 0) continue; int acd_FormulaMapMask = MR.ReadInt(group_formula_ofs + 0x418); uint SNO = MR.ReadUInt(acd_address + acd_ofs__sno); int Location = MR.ReadInt(acd_address + acd_ofs__item_location); // Inventory = 0, Head = 1, Torso = 2, RightHand = 3, LeftHand = 4, Hands = 5, Waist = 6, Feet = 7, Shoulders = 8, Legs = 9, Bracers = 10, LeftRing = 11, RightRing = 12, Neck = 13, Stash = 15, Merchant = 18 // regarding location you can read item_x (int), item_y (int) OR pos_x (float), pos_y (float), pos_z (float) values here // item_x and item_y means the coordinates in stash or inventory // pos_x, pos_y, pos_z are world coordinates for things on the floor // if this is a monster, you can read the int @ acd_address + acd_ofs__monster_type // monster types: normal = 0, elite = 1, yellow? = 2, purple? = 3, keywarden = 4 for (int link_index = 0; link_index <= 255; link_index++) { int link_root_address = acd_FormulaMapData + link_index * 4; int link_address = MR.ReadInt(link_root_address); int n = 0; // safety counter against infinite loops while ((link_address != 0) && (n < 20)) { uint id = MR.ReadUInt(link_address + attrib_link_ofs__id); int attribute_index = (int)(id & 0xFFF); if (attribute_index > 0) { uint mask = id >> 12; int value = MR.ReadInt(link_address + attrib_link_ofs__value); // do whatever you want with the attribute_index, mask, value here // NOTE: you have to cast float type attributes to float here } link_address = MR.ReadInt(link_address + attrib_link_ofs__next); n += 1; } }}}
Fast reading a specific attribute:
public int GetAttribHelper(int acd_FormulaMapData, int acd_FormulaMapMask, int AttributeIndex, uint AttributeMask, int Default = -1) { uint full_id = AttributeIndex | (AttributeMask << 12); uint idxmask = full_id ^ (full_id >> 16); int idx = (int)(acd_FormulaMapMask & idxmask); int link_root_address = acd_FormulaMapData + idx * 4; int link_address = MR.ReadInt(link_root_address); int n = 0; while ((link_address != 0) && (n < 20)) { uint id = MR.ReadUInt(link_address + attrib_link_ofs__id); if (id == full_id) { int v = MR.ReadInt(link_address + attrib_link_ofs__value); return v; } link_address = MR.ReadInt(link_address + attrib_link_ofs__next); n += 1; } return Default; }
Example of reading a skill's cooldown
First you need the current "time" of the current game:
public readonly int ObjectManagerStorage_ofs__ticks = 0x94;int CurrentTick = MR.ReadInt(ObjectManagerStoragePtr + ObjectManagerStorage_ofs__ticks);
Then you just read the Power_Cooldown (0x12D) attribute masked by the selected skill (sweeping wind = 96090)
int CooldownFinishTicks = GetAttribHelper(your_player_characters_acd_FormulaMapData, your_player_characters_acd_FormulaMapMask, 0x12D, 96090, 0);double seconds_left = (CooldownFinishTicks > CurrentTick) ? (CooldownFinishTicks - CurrentTick) / 60.0d : 0;
- diabloIII
- DiabloIII的平台性讨论
- grizzly版swift和glance整合
- Linux c中经常用到的一些处理:
- opencms8.5安装问题集锦
- :org.apache.jasper.JasperException: java.lang.ClassCastException三种解决方法
- 20130909安博培训第一天
- diabloIII
- AU格式解析
- 统计学习方法-概率知识补充
- gluPerspective和gluLookAt
- jQuery 基本语法总结(10)
- Android Wifi模块分析(转)
- 小例子大智慧4--委托Delegate
- 仿百度文库方案[openoffice.org 3+swftools+flexpaper](二) 之 安装openoffice.org
- 0909