private unsafe List <ChatMessage> GetMessages() { var list = new List <ChatMessage>(); uint bytesRead = 0; // Static base pointer to chat object array uint chatBasePointer = MemFunctions.ResolveNestedPointer(_client.Handle, ChatObjectsBase, 0); // Number between 0-199 (Number of messages that can be shown in the ingame chat window) uint lastChatOffset = MemFunctions.ResolveNestedPointer(_client.Handle, LastChatObject, 0); // Calculate index of first message to show uint firstChatToShow = FetchCount > lastChatOffset ? 0 : (lastChatOffset - FetchCount); for (uint chatOffset = firstChatToShow; chatOffset < lastChatOffset; chatOffset++) { // More efficient to read the whole chat structure into an object in one hit. // Object is kinda like a Union in old school C / C++ (see the object definition) var chatObj = new Chatobj(); // Structure object byte overlay pointer byte *lpChatObj = &chatObj.bytes[0]; // To pass to mem functions (number of bytes to read) int sizeofChatObj = Marshal.SizeOf(chatObj); // Read chatObj structure from PW memory into our object Mem.MemReadBytesToStruct(_client.Handle, chatBasePointer + (0x1C * chatOffset), lpChatObj, sizeofChatObj); // Actual message entry in object is just a pointer, so go retrieve the message uint chatPointer = MemFunctions.ResolveNestedPointer(_client.Handle, chatBasePointer + (0x1C * (chatOffset)) + 0x8, 0); string str = MemFunctions.MemReadUnicode(_client.Handle, chatObj.p_msg, 256, ref bytesRead).Replace("\r", "\r\n"); list.Add(new ChatMessage { Id = chatObj.msgId, Scope = (Scopes)chatObj.msgScope, Raw = str, ItemId = chatObj.itemId, }); } return(list); }
private void LoadSendChatOpcode() { //Allocate memory for the opcode to call the sendChat function _sendChatOpcodeAddress = MemFunctions.AllocateMemory(_client.Handle, _sendChatOpcode.Length); //Write the opcode to memory MemFunctions.MemWriteBytes(_client.Handle, _sendChatOpcodeAddress, _sendChatOpcode); //Calculate relative call address of sendChat() uint relAddress = SendChatCall - (uint)_sendChatOpcodeAddress - 12 - (uint)(_sendChatOpcode.Length / 2); //Insert the functionAddress in opcode byte[] functionAddress = BitConverter.GetBytes(relAddress); MemFunctions.MemWriteBytes(_client.Handle, _sendChatOpcodeAddress + 22, functionAddress); uint chatClassPtr = MemFunctions.ResolveNestedPointer(_client.Handle, BaseCall, 0x1C, 0x18, 0x8, 0xC4, 0x20, 0); byte[] chatClassPtrBytes = BitConverter.GetBytes(chatClassPtr); MemFunctions.MemWriteBytes(_client.Handle, _sendChatOpcodeAddress + 13, chatClassPtrBytes); }
public static ElementClient[] GetClients() { var processes = Process.GetProcessesByName("elementclient"); return(processes.Select(pr => { IntPtr handle = MemFunctions.OpenProcess(pr.Id); uint playerBase = MemFunctions.ResolveNestedPointer(handle, BaseCall, 0x1C, 0x34); uint namePtr = MemFunctions.ResolveNestedPointer(handle, playerBase, NameOffset, 0); uint bytesRead = 0; return new ElementClient { Pid = pr.Id, Handle = handle, PlayerBase = playerBase, Nickname = MemFunctions.MemReadUnicode(handle, namePtr, 0x32, ref bytesRead), }; }).ToArray()); }
// Just updates the variable information in the opcode without reallocating the whole opcode // to another memory location private void UpdateSetChatTextOpcode(string str) { Encoding unicode = Encoding.Unicode; byte[] unicodeBytes = unicode.GetBytes(str); //Allocate memory for the chat message int chatMsgAddress = MemFunctions.AllocateMemory(_client.Handle, unicodeBytes.Length); // Write the message to memory MemFunctions.MemWriteBytes(_client.Handle, chatMsgAddress, unicodeBytes); // Write the address of the string pointer byte[] stringAddr = BitConverter.GetBytes(chatMsgAddress); MemFunctions.MemWriteBytes(_client.Handle, _setChatTextOpcodeAddress + 2, stringAddr); // Get the pointer to the chat input box object uint chatBoxObjPtr = MemFunctions.ResolveNestedPointer(_client.Handle, BaseCall, 0x1C, 0x18, 0x8, 0xC4, 0x20, 0x1C4, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0); byte[] chatBoxObjPtrBytes = BitConverter.GetBytes(chatBoxObjPtr); MemFunctions.MemWriteBytes(_client.Handle, _setChatTextOpcodeAddress + 7, chatBoxObjPtrBytes); }
private int LoadAppendCharOpcode() { //Allocate memory for the opcode to call the sendChat function _appendCharOpcodeAddress = MemFunctions.AllocateMemory(_client.Handle, _appendCharOpcode.Length); //Write the opcode to memory MemFunctions.MemWriteBytes(_client.Handle, _appendCharOpcodeAddress, _appendCharOpcode); //Calculate relative call address of chatBoxKeyHandler() uint relAddress = ChatBoxKeyHandlerCall - (uint)_appendCharOpcodeAddress - 9 - (uint)(_appendCharOpcode.Length / 2); //Insert the functionAddress in opcode byte[] functionAddress = BitConverter.GetBytes(relAddress); MemFunctions.MemWriteBytes(_client.Handle, _appendCharOpcodeAddress + 15, functionAddress); // Get and load the pointer to the chat system class uint chatEntryBoxObjPtr = MemFunctions.ResolveNestedPointer(_client.Handle, BaseCall, 0x1C, 0x18, 0x8, 0xC4, 0x20, 0x1C4, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0x8, 0); byte[] chatEntryBoxObjPtrBytes = BitConverter.GetBytes(chatEntryBoxObjPtr); MemFunctions.MemWriteBytes(_client.Handle, _appendCharOpcodeAddress + 8, chatEntryBoxObjPtrBytes); return(_appendCharOpcodeAddress); }