/// <summary> /// This function computes the address inside FFXIV process space to be modified for a given field /// and then modifies it. /// This will be deprecated with proper setters. /// </summary> /// <typeparam name="TX">Type of the value to modify, stick to base types</typeparam> /// <param name="field">Name of the structure field to modify</param> /// <param name="value">Value to assign to field</param> public virtual void Modify <TX>(string field, TX value) { IntPtr tobemodified = IntPtr.Add(Address, (int)Marshal.OffsetOf(typeof(TU), field)); try { object byteValue = typeof(BitConverter).GetMethod("GetBytes", new[] { value.GetType() }) .Invoke(null, new object[] { value }); MemoryReader.GetInstance().WriteAddress(tobemodified, byteValue as byte[]); } catch (AmbiguousMatchException) { /* * This fixes 2 issues: * 1. Reflector cannot determine the proper GetBytes() * call for single byte values (or I'm just bad) * 2. Hack for single byte values, above code create byte[2] * array which are then written and cause crashes. * I hate catching exceptions for this kind of shit. * There is probably something more sexy to be done but it works. */ var byteArray = new byte[1]; byteArray[0] = Convert.ToByte(value); MemoryReader.GetInstance().WriteAddress(tobemodified, byteArray); } }
/// <summary> /// Constructor building the list of items out of initial pointer and count. /// </summary> /// <param name="pointer">Subarray pointer</param> /// <param name="count">Subarray max elements</param> /// <param name="clean">Should we ignore empty objects? Useful for currently equipped items.</param> internal InventoryBuilder(IntPtr pointer, int count, bool clean) { MemoryReader mr = MemoryReader.GetInstance(); Items = new List <Item>(); for (int i = 0; i < count; i++) { IntPtr address = pointer + (i * Marshal.SizeOf(typeof(Item.ITEMINFO))); var currentItem = new Item(mr.CreateStructFromAddress <Item.ITEMINFO>(address), address); if (currentItem.Id != 0 || currentItem.QuestID != 0 || !clean) { Items.Add(currentItem); } } }
/// <summary> /// This refreshes the instance /// It may have unexpected behavior if address changes. /// This will be deprecated with proper getters. /// </summary> public virtual void Refresh() { Structure = MemoryReader.GetInstance().CreateStructFromAddress <TU>(Address); }
/// <summary> /// Retrieves the Subzone ID /// </summary> /// <returns>Subzone ID or 0</returns> private int GetSubzone() { IntPtr ptr = MemoryReader.GetInstance().ResolvePointerPath(Constants.SUBZONEPTR); return(MemoryReader.GetInstance().ReadInt4(ptr)); }