in this thread I want to release my private script engine's source code that I have been using on and off for some years. As it has become heavily outdated with the big update and I don't bot anymore - I just play the game for fun from time to time - I think it is time to release the source code, as it may help some interested fellas with creating their own bot.
This script engine originated in a time when botting guild wars was not about money (see my registration date) but about helping each other with learning a new skill - coding. The whole thing took off when Harko released Requia and GW bots became much more than some inept macro scripts. I don't know how many of you remember this time but even back then some idiots destroyed this wonderful thing by trying to milk other peoples work for money. My journey started with creating the first basic lua scripts and somehow ended by recoding the whole damn script engine (in a very basic state, of course!). It never really was about botting a game, this was merely a good motivator. It was about learning and understanding. This was always very important to me and when Harko's Requia basically caused a huge divide in the Guild Wars botting community because some idiots realised there was big bank to be made, I withdrawed from the whole thing and went private. But deep down in my heart I always missed the times when professional developers took their time to teach totally inept morons like me the very basic principals of programming - hence the name of this script engine: Aeterna.
So all credit belongs to Harko - thank you!
Another point I want to make regarding safety: I never had a single account banned. And I always disregarded alle safety measures, because I would not really care if I got banned. I botted on up to 4 accounts simultaneously from a single IP adress without a VPN. I let the bots do their work during my 24h shifts, I traded big amounts of rares and money with my main account (making it 5 accounts from a single IP simultaneously) and even rushed my newly created bot account with my main to elona.
Why do I tell you this? Because I think that anets security measures are much more basic than everybody thinks. I do not think it has something to do with bot run time, VPN or hardware id - I think the common denominator of all the people that got banned is the GWCA. So create your own little thing and be safe.
Now to the code: it is more than 5 years old and I never had any programming classes. Tought it all to myself with the help of many wonderful people. Went on and off through the years so please bear with me when some passages do not seem to make any sense or are coded very badly. In the end it all worked, even if I did not always understood what I just did.
Concept is as follows: Aeterna is a lua script engine. The ingame variables and functions are registered to the lua engine, the bot itself is written in lua. On attaching Aeterna to a Guild Wars process, it injects the library from where the ingame functions (such as UseSkill) are called within the Guild Wars address space. So the hook is written in C++ to make use of inline assembly. Communication between Aeterna an the attached Guild Wars process works by sending specified windowmessages and overriding the WindowProc function in both Guild Wars and Aeterna.
The gui:
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Windows.Forms;
using Microsoft.Win32;
using LuaInterface;
using AutoItX3Lib;
using System.Runtime.InteropServices;
namespace Pellax
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.CreateHandle();
collectProcessesTimer.Tick += new EventHandler(_CollectProcesses);
refreshGridTimer.Tick += new EventHandler(_refreshGrid);
Event_OnScriptEnd += new OnScriptEndHandler(ScriptEnd);
CollectProcesses();
FormClosing += Form1_Closing;
}
System.Windows.Forms.Timer refreshGridTimer = new System.Windows.Forms.Timer();
private void _refreshGrid(object sender, EventArgs e)
{
propertyGrid1.Refresh(); //method for the event handler in Form1 constructor
}
private void refreshGrid()
{
refreshGridTimer.Interval = 250;
refreshGridTimer.Start();
}
[DllImport("user32.dll")]
static extern int SetWindowText(IntPtr hWnd, string text);
//the user defined message constants for interprocess communication. There are the same definitions in GwHook.dll
const int AM_LIBRARYFREED = 0x1335;
const int AM_UNLOADLIBRARY = 0x1336;
const int AM_AETERNAMESSAGEDEFAULT = 0x1337;
const int AM_ERROR = 0x1338;
const int AM_COMINFO = 0x1339;
const int AM_COMESTABLISHED = 0x1340;
const int AM_MOVETO = 0x1341;
const int AM_TRAVEL = 0x1342;
const int AM_USESKILL = 0x1343;
const int AM_PLAYERID = 0x1344;
const int AM_LANGDIS = 0x1345;
const int AM_ENTERMISSION = 0x1346;
const int AM_TARGETNEXTALLY = 0x1347;
const int AM_DROPITEM = 0x1348;
const int AM_LOOTITEM = 0x1349;
const int AM_TARGETNPC = 0x1350;
const int AM_TARGETNEARESTITEM = 0x1351;
const int AM_TARGETNEARESTALLY = 0x1352;
const int AM_TARGETNEARESTENEMY = 0x1353;
const int AM_TARGETATTACK = 0x1354;
const int AM_SELLITEM = 0x1355;
const int AM_GETITEMVALUE = 0x1356;
const int AM_RECEIVEITEMVALUE = 0x1357;
const int AM_SELLCOMPLETE = 0x1358;
const int AM_IDENTITEM = 0x1359;
const int AM_IDENTITEMCOMPLETE = 0x1360;
const int AM_MOVETOEXACT = 0x1361;
const int AM_MOVETOINFOX = 0x1362;
const int AM_MOVETOINFOY = 0x1363;
const int AM_TARGETNEXTENEMY = 0x1364;
const int AM_TARGETNEXTITEM = 0x1365;
const int AM_SALVAGEITEM = 0x1366;
const int AM_SALVAGEITEMPTR = 0x1367;
int lastMessage;
int info1;
int info2;
protected override void WndProc(ref Message m) //override WndProc of Form1 to look for userdefined messages
{
switch (m.Msg)
{
case AM_AETERNAMESSAGEDEFAULT:
Print("AM_AETERNAMESSAGEDEFAULT RECEIVED\n");
lastMessage = (int)AM_AETERNAMESSAGEDEFAULT;
Print(m.WParam.ToString());
Print("\n");
Print(m.LParam.ToString());
Print("\n");
break;
case AM_ERROR:
Print("An error occured.\n");
lastMessage = (int)AM_ERROR;
break;
case AM_COMESTABLISHED:
Print("Communication between Aeterna and Guild Wars successfully established.\n");
lastMessage = (int)AM_COMESTABLISHED;
break;
case AM_LIBRARYFREED:
Print("GwHook successfully unloaded.\n");
break;
case AM_RECEIVEITEMVALUE:
gm.ItemValue = (int)m.WParam;
lastMessage = (int)AM_RECEIVEITEMVALUE;
break;
case AM_SELLCOMPLETE:
lastMessage = (int)AM_SELLCOMPLETE;
break;
}
base.WndProc(ref m); //call the regular WndProc method after looking for custom messages in order to keep the Window alive
}
delegate void OnScriptEndHandler();
OnScriptEndHandler Event_OnScriptEnd;
//------------------------##############Process Collection#################------------------------------------
System.Windows.Forms.Timer collectProcessesTimer = new System.Windows.Forms.Timer();
private void CollectProcesses()
{
collectProcessesTimer.Interval = 1000;
collectProcessesTimer.Start();
}
private void _CollectProcesses(object source, EventArgs e)
{
Process[] proc = Process.GetProcessesByName("gw");
if (proc.Length != 0)
{
for (int i = 0; i < proc.Length; i++)
{
ListViewItem item = new ListViewItem();
item.Tag = proc[i]; //The ListViewItem is given the process object as a tag.
//This is relevant for attaching, closing and removing routines.
item.Text = "Guild Wars (" + proc[i].Id.ToString() + ")";
AddListViewItem(item);
}
}
RemoveListViewItems(); //The routine that checks for dead processes and removes them from the list
}
private void AddListViewItem(ListViewItem item)
{
ListViewItem lwitem = listView1.FindItemWithText(item.Text);
if (lwitem == null)
listView1.Items.Add(item);
}
private void RemoveListViewItems()
{
ListView.ListViewItemCollection lwitems = new ListView.ListViewItemCollection(listView1);
if (lwitems.Count == 0)
return;
for (int i = 0; i < lwitems.Count; i++) //Check all gathered LVItems (lvitems above)
{
Process process = (Process)lwitems[i].Tag;
if (process != null && process.HasExited)
listView1.Items.Remove(lwitems[i]);
}
}
//------------------------##############Process Collection#################--------------------------------------
//------------------------##############File Handling Routines################-----------------------------------
bool saved = false;
bool changed = false;
bool attached = false;
bool injected = false;
string script = "";
string currentFile = "";
string GWPath = ""; //currently suspended due to failed startup path acquisition via registry
GwMemory gm;
Communicator com;
ValueStorageClass vsc; //object for the propertygrid
Lua luaVM;
AutoIt au3;
Thread LuaThread; //the lua engine runs in this thread
Process guildWarsProcess;
private void OpenLuaDoc()
{
if (!saved && richTextBox2.Text != "")
{
DialogResult d = MessageBox.Show("Content not saved yet. Do now?", "", MessageBoxButtons.YesNo);
if (d == DialogResult.Yes)
{
SaveLuaDoc();
return;
}
}
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "LUA files (*.lua)|*.lua";
ofd.InitialDirectory = Application.StartupPath;
if (ofd.ShowDialog() == DialogResult.Cancel)
{
return;
}
else
{
try
{
Stream fileStream = new FileStream(ofd.FileName, FileMode.Open);
FileInfo fileInfo = new FileInfo(ofd.FileName);
richTextBox2.LoadFile(fileStream, RichTextBoxStreamType.PlainText);
fileStream.Close();
}
catch (Exception e)
{
MessageBox.Show("ERROR OPENING FILE.\n" + e.Message);
}
}
currentFile = ofd.FileName;
changed = false;
}
private void SaveLuaDoc()
{
if (saved)
return;
if (!changed)
return;
if (currentFile == "")
{
SaveLuaDocAs();
return;
}
if (currentFile == "NEWLUADOCCREATED")
{
SaveLuaDocAs();
return;
}
try
{
Stream fileStream = new FileStream(currentFile, FileMode.Create);
FileInfo fileInfo = new FileInfo(currentFile);
this.richTextBox2.SaveFile(fileStream, RichTextBoxStreamType.PlainText);
fileStream.Close();
}
catch (Exception e)
{
MessageBox.Show("ERROR SAVING FILE.\n" + e.Message);
}
saved = true;
changed = false;
}
private void SaveLuaDocAs()
{
if (richTextBox2.Text == "")
return;
SaveFileDialog sfd = new SaveFileDialog();
sfd.AddExtension = true;
sfd.CreatePrompt = false;
sfd.Filter = "LUA Files (*.lua)|*.lua";
sfd.InitialDirectory = Application.StartupPath;
if (sfd.ShowDialog() == DialogResult.Cancel)
{
return;
}
else
{
try
{
Stream fileStream = new FileStream(sfd.FileName, FileMode.Create);
FileInfo fileInfo = new FileInfo(sfd.FileName);
this.richTextBox2.SaveFile(fileStream, RichTextBoxStreamType.PlainText);
fileStream.Close();
}
catch (Exception e)
{
MessageBox.Show("ERROR SAVING FILE.\n" + e.Message);
}
}
currentFile = sfd.FileName;
changed = false;
saved = true;
}
private void NewLuaDoc()
{
if (!saved && richTextBox2.Text != "")
{
DialogResult d = MessageBox.Show("Content not saved yet. Do now?", "", MessageBoxButtons.YesNo);
if (d == DialogResult.Yes)
{
SaveLuaDoc();
return;
}
}
currentFile = "NEWLUADOCCREATED";
richTextBox2.Text = "";
}
private void richTextBox2_TextChanged(object sender, EventArgs e)
{
changed = true;
saved = false;
script = richTextBox2.Text;
}
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenLuaDoc();
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveLuaDoc();
}
private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveLuaDocAs();
}
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
NewLuaDoc();
}
//------------------------##############File Handling Routines################-----------------------------------
//------------------------##############GUI related routines ################-----------------------------------
private void Attach()
{
if (attached)
return;
ListView.SelectedListViewItemCollection lvsi = new ListView.SelectedListViewItemCollection(listView1);
if (lvsi.Count == 0)
{
Print("No Guild Wars process selected.\n");
return;
}
guildWarsProcess = (Process)lvsi[0].Tag; //The process object (tag) of the LVItems is "extracted"
//Hard-coded, but multi select is disabled so IDGAF
try
{
this.Text = "Aeterna - v1.0: " + guildWarsProcess.MainWindowTitle + " " + guildWarsProcess.Id.ToString();
SetWindowText(guildWarsProcess.MainWindowHandle, "Guild Wars: " + guildWarsProcess.Id.ToString());
gm = new GwMemory(guildWarsProcess.Id);
gm.readAdresses = new Thread(new ThreadStart(gm.ReadAdresses));
gm.readAdresses.IsBackground = true;
gm.readAdresses.Start();
vsc = new ValueStorageClass(gm);
refreshGrid();
propertyGrid1.SelectedObject = vsc;
if (checkBox1.Checked)
{
Process thisProcess = Process.GetCurrentProcess();
com = new Communicator(thisProcess.MainWindowHandle, guildWarsProcess.MainWindowHandle);
int res = Communicator.DllInject(guildWarsProcess.Id, thisProcess.MainWindowHandle, guildWarsProcess.MainWindowHandle);
if (res != 0x1337)
{
Print("Injection faild.\n");
injected = false;
return;
}
bool sendret = com.SendMessageToChildParam(AM_COMINFO, thisProcess.Id, 0); //This sends a parameterized message to the GwHook. Thusly the GwHook
//can retrieve the windowhandle to its master process. This establishes
//the communication between this engine and the GwHook.
if (!sendret)
{
Print("Error: could not send COMINFO to child. Only master-to-child-communication may be possible.\n");
}
injected = true;
}
button4.Enabled = false;
button5.Enabled = true;
attached = true;
}
catch (Exception e)
{
Print(e.Message+"\n");
}
}
private void Detach()
{
button4.Enabled = true;
button5.Enabled = false;
propertyGrid1.SelectedObject = null;
gm.readAdresses.Abort();
gm = null;
vsc = null;
if (injected)
{
com.SendMessageToChild(AM_UNLOADLIBRARY);
injected = false;
}
attached = false; //reset everything to allow another process to be selected. Unloading the library currently not working.
}
private void RunScript()
{
try {
LuaThread = new Thread(new ThreadStart(RunEngine));
LuaThread.IsBackground = true;
LuaThread.Start();
button3.Enabled = true;
button2.Enabled = false;
}
catch (Exception e)
{
Print(e.Message + "\n");
}
}
private void EndScript()
{
LuaThread.Abort();
button3.Enabled = false;
button2.Enabled = true;
}
private void ClearConsole()
{
richTextBox1.Text = "";
}
private void StartNewProcess()
{
OpenFileDialog dlgFileOpen = new OpenFileDialog();
dlgFileOpen.InitialDirectory = GWPath; //not working properly, see above
dlgFileOpen.Filter = "Guild Wars|gw.exe";
if (dlgFileOpen.ShowDialog() == DialogResult.OK)
{
string exePath = dlgFileOpen.FileName;
Process proc = new Process();
proc.StartInfo.FileName = exePath;
proc.Start();
}
}
private void CloseSelectedProcess()
{
ListView.SelectedListViewItemCollection lvic = new ListView.SelectedListViewItemCollection(listView1);
if (lvic.Count == 0)
{
Print("No Guild Wars process selected.\n");
return;
}
DialogResult dialogResult = MessageBox.Show("Are you sure you want to close the process?", "", MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.Yes)
{
Process po = (Process)lvic[0].Tag;
if (!po.HasExited)
{
po.Kill();
lvic[0].Remove();
}
}
}
private delegate void PrintEventHandler(string text);
public void Print(string text)
{
if (richTextBox1.InvokeRequired)
{
PrintEventHandler peh = new PrintEventHandler(Print);
richTextBox1.BeginInvoke(peh, text);
}
else
{
richTextBox1.AppendText(text);
}
} //method for displaying a string in the Aeterna console
private delegate void ScriptEndHandler(); //is executed on script end. sets the buttons and terminates the lua related background threads
private void ScriptEnd()
{
if (this.InvokeRequired)
{
ScriptEndHandler seh = new ScriptEndHandler(ScriptEnd);
this.BeginInvoke(seh);
}
else
{
button2.Enabled = true;
button3.Enabled = false;
startToolStripMenuItem.Enabled = true;
stopToolStripMenuItem.Enabled = false;
}
LuaThread.Abort();
}
//------------------------##############GUI related routines ################-----------------------------------
private void RunEngine()
{
try
{
luaVM = new Lua();
au3 = new AutoIt();
luaVM.RegisterFunction("Send", au3, au3.GetType().GetMethod("Send"));
luaVM.RegisterFunction("Sleep", au3, au3.GetType().GetMethod("Sleep"));
luaVM.RegisterFunction("ControlSend", au3, au3.GetType().GetMethod("ControlSend"));
luaVM.RegisterFunction("ControlClick", au3, au3.GetType().GetMethod("ControlClick"));
luaVM.RegisterFunction("RandomSleep", au3, au3.GetType().GetMethod("RandomSleep"));
luaVM.RegisterFunction("Random", au3, au3.GetType().GetMethod("Random"));
luaVM.RegisterFunction("PixelGetColor", au3, au3.GetType().GetMethod("PixelGetColor"));
luaVM.RegisterFunction("PixelSearch", au3, au3.GetType().GetMethod("PixelSearch"));
luaVM.RegisterFunction("WinMove", au3, au3.GetType().GetMethod("WinMove"));
luaVM.RegisterFunction("WinSize", au3, au3.GetType().GetMethod("WinSize"));
luaVM.RegisterFunction("SetOps", au3, au3.GetType().GetMethod("SetOps"));
luaVM.RegisterFunction("Print", this, this.GetType().GetMethod("Print"));
luaVM.RegisterFunction("WinSetTitle", au3, au3.GetType().GetMethod("WinSetTitle"));
luaVM.RegisterFunction("MouseMove", au3, au3.GetType().GetMethod("MouseMove"));
luaVM.RegisterFunction("WinActivate", au3, au3.GetType().GetMethod("WinActivate"));
luaVM.RegisterFunction("WinActive", au3, au3.GetType().GetMethod("WinActive"));
luaVM.RegisterFunction("GetLastMessage", this, this.GetType().GetMethod("GetLastMessage"));
luaVM.RegisterFunction("SendMessage", this, this.GetType().GetMethod("SendMessage"));
luaVM.RegisterFunction("MoveTo", this, this.GetType().GetMethod("MoveTo"));
luaVM.RegisterFunction("Travel", this, this.GetType().GetMethod("Travel"));
luaVM.RegisterFunction("DumpAddresses", this, this.GetType().GetMethod("DumpAddresses"));
luaVM.RegisterFunction("SetTitle", this, this.GetType().GetMethod("SetTitle"));
luaVM.RegisterFunction("CloseGw", this, this.GetType().GetMethod("CloseGw"));
luaVM.RegisterFunction("MoveToExact", this, this.GetType().GetMethod("MoveToExact"));
//luaVM.RegisterFunction("ShutdownStandBy", this, this.GetType().GetMethod("ShutdownStandBy"));
luaVM.RegisterFunction("UseSkill", this, this.GetType().GetMethod("UseSkill"));
luaVM.RegisterFunction("EnterMission", this, this.GetType().GetMethod("EnterMission"));
luaVM.RegisterFunction("TargetNextAlly", this, this.GetType().GetMethod("TargetNextAlly"));
luaVM.RegisterFunction("DropItem", this, this.GetType().GetMethod("DropItem"));
luaVM.RegisterFunction("LootItem", this, this.GetType().GetMethod("LootItem"));
luaVM.RegisterFunction("TargetNpc", this, this.GetType().GetMethod("TargetNpc"));
luaVM.RegisterFunction("TargetNearestItem", this, this.GetType().GetMethod("TargetNearestItem"));
luaVM.RegisterFunction("TargetNearestAlly", this, this.GetType().GetMethod("TargetNearestAlly"));
luaVM.RegisterFunction("TargetNearestEnemy", this, this.GetType().GetMethod("TargetNearestEnemy"));
luaVM.RegisterFunction("AttackTarget", this, this.GetType().GetMethod("AttackTarget"));
luaVM.RegisterFunction("TerminateScript", this, this.GetType().GetMethod("TerminateScript"));
luaVM.RegisterFunction("SellItem", this, this.GetType().GetMethod("SellItem"));
luaVM.RegisterFunction("TargetNextEnemy", this, this.GetType().GetMethod("TargetNextEnemy"));
luaVM.RegisterFunction("TargetNextItem", this, this.GetType().GetMethod("TargetNextItem"));
luaVM.RegisterFunction("GetItem", gm, gm.GetType().GetMethod("GetItem"));
luaVM.RegisterFunction("GetItemValue", this, this.GetType().GetMethod("GetItemValue"));
luaVM.RegisterFunction("ItemID", this, this.GetType().GetMethod("ItemID"));
luaVM.RegisterFunction("ItemRarity", this, this.GetType().GetMethod("ItemRarity"));
luaVM.RegisterFunction("ItemQuantity", this, this.GetType().GetMethod("ItemQuantity"));
luaVM.RegisterFunction("ItemModelID", this, this.GetType().GetMethod("ItemModelID"));
luaVM.RegisterFunction("ItemValue", this, this.GetType().GetMethod("ItemValue"));
luaVM.RegisterFunction("SellItem", this, this.GetType().GetMethod("SellItem"));
luaVM.RegisterFunction("IdentItem", this, this.GetType().GetMethod("IdentItem"));
luaVM.RegisterFunction("SalvageItem", this, this.GetType().GetMethod("SalvageItem"));
luaVM.RegisterFunction("PlayerX", this, this.GetType().GetMethod("PlayerX"));
luaVM.RegisterFunction("PlayerXMovementSpeed", this, this.GetType().GetMethod("PlayerXMovementSpeed"));
luaVM.RegisterFunction("PlayerY", this, this.GetType().GetMethod("PlayerY"));
luaVM.RegisterFunction("PlayerYMovementSpeed", this, this.GetType().GetMethod("PlayerYMovementSpeed"));
luaVM.RegisterFunction("PlayerHp", this, this.GetType().GetMethod("PlayerHp"));
luaVM.RegisterFunction("PlayerHpMax", this, this.GetType().GetMethod("PlayerHpMax"));
luaVM.RegisterFunction("PlayerEp", this, this.GetType().GetMethod("PlayerEp"));
luaVM.RegisterFunction("PlayerEpMax", this, this.GetType().GetMethod("PlayerEpMax"));
luaVM.RegisterFunction("PlayerRegen", this, this.GetType().GetMethod("PlayerRegen"));
luaVM.RegisterFunction("PlayerIsDead", this, this.GetType().GetMethod("PlayerIsDead"));
luaVM.RegisterFunction("PlayerLevel", this, this.GetType().GetMethod("PlayerLevel"));
luaVM.RegisterFunction("PlayerId", this, this.GetType().GetMethod("PlayerId"));
luaVM.RegisterFunction("PlayerSpellId", this, this.GetType().GetMethod("PlayerSpellId"));
luaVM.RegisterFunction("PlayerGold", this, this.GetType().GetMethod("PlayerGold"));
luaVM.RegisterFunction("PlayerGoldStash", this, this.GetType().GetMethod("PlayerGoldStash"));
luaVM.RegisterFunction("PlayerInMission", this, this.GetType().GetMethod("PlayerInMission"));
luaVM.RegisterFunction("PlayerTownId", this, this.GetType().GetMethod("PlayerTownId"));
luaVM.RegisterFunction("TargetX", this, this.GetType().GetMethod("TargetX"));
luaVM.RegisterFunction("TargetXMovementSpeed", this, this.GetType().GetMethod("TargetXMovementSpeed"));
luaVM.RegisterFunction("TargetY", this, this.GetType().GetMethod("TargetY"));
luaVM.RegisterFunction("TargetYMovementSpeed", this, this.GetType().GetMethod("TargetYMovementSpeed"));
luaVM.RegisterFunction("TargetHp", this, this.GetType().GetMethod("TargetHp"));
luaVM.RegisterFunction("TargetLevel", this, this.GetType().GetMethod("TargetLevel"));
luaVM.RegisterFunction("TargetType", this, this.GetType().GetMethod("TargetType"));
luaVM.RegisterFunction("TargetId", this, this.GetType().GetMethod("TargetId"));
luaVM.RegisterFunction("TargetFaction", this, this.GetType().GetMethod("TargetFaction"));
luaVM.RegisterFunction("TargetPrimaryProfession", this, this.GetType().GetMethod("TargetPrimaryProfession"));
luaVM.RegisterFunction("TargetSecondaryProfession", this, this.GetType().GetMethod("TargetSecondaryProfession"));
luaVM.RegisterFunction("TargetSpellId", this, this.GetType().GetMethod("TargetSpellId"));
luaVM.RegisterFunction("TargetIsCasting", this, this.GetType().GetMethod("TargetIsCasting"));
luaVM.RegisterFunction("TargetDistance", this, this.GetType().GetMethod("TargetDistance"));
}
catch (Exception e)
{
Print(e.Message + "\n");
}
try
{
au3.SetOps(); //sets certain au3 options right, e.g. window title matchmode and others, necessary for ControlSend/Click to work properly
Print("LuaEngine: " + "Starting script execution" + " - " + DateTime.Now + "." + "\n");
luaVM.DoString(script); //script is a string above, that gets redefined when the richtextbox text changes
}
catch (ThreadAbortException tae)
{
Print("LuaEngine error: " + tae.Message + " - " + DateTime.Now + "\n");
luaVM = null;
au3 = null;
Event_OnScriptEnd.Invoke();
LuaThread.Abort();
return;
}
catch (LuaException le)
{
Print("LuaEngine error: " + le.Message + " - " + DateTime.Now + "." + "\n");
luaVM = null;
au3 = null;
Event_OnScriptEnd.Invoke();
LuaThread.Abort();
return;
}
catch (Exception e)
{
Print("LuaEngine error: " + e.Message + DateTime.Now + "." + "\n");
luaVM = null;
au3 = null;
Event_OnScriptEnd.Invoke();
LuaThread.Abort();
return;
}
Print("LuaEngine: Script execution successfully ended - " + DateTime.Now + "." + "\n");
au3 = null;
luaVM = null;
Event_OnScriptEnd.Invoke();
LuaThread.Abort();
return;
}
//these functions are registered in the luaVM above. See RunEngine() method.
public void ShutdownStandyBy()
{
Application.SetSuspendState(PowerState.Hibernate, true, true);
}
public void CloseGw()
{
if (guildWarsProcess != null)
guildWarsProcess.Kill();
}
public float PlayerX()
{
return gm.PlayerX;
}
public float PlayerXMovementSpeed()
{
return gm.PlayerXMovementSpeed;
}
public float PlayerY()
{
return gm.PlayerY;
}
public float PlayerYMovementSpeed()
{
return gm.PlayerYMovementSpeed;
}
public int PlayerHp()
{
return ((int)gm.PlayerHpCurrent * gm.PlayerHpMax);
}
public int PlayerHpMax()
{
return gm.PlayerHpMax;
}
public int PlayerEp()
{
return ((int)gm.PlayerEpCurrent * gm.PlayerEpMax);
}
public int PlayerEpMax()
{
return gm.PlayerEpMax;
}
public int PlayerIsDead()
{
if (gm.PlayerHpCurrent == 0)
{
return 1;
}
else
{
return 0;
}
}
public float PlayerRegen()
{
return gm.PlayerRegen;
}
public int PlayerLevel()
{
return gm.PlayerLevel;
}
public int PlayerId()
{
return gm.PlayerID;
}
public int PlayerSpellId()
{
return gm.PlayerSpellId;
}
public int PlayerGold()
{
return gm.PlayerGold;
}
public int PlayerGoldStash()
{
return gm.PlayerGoldStash;
}
public int GetLastMessage()
{
if (com == null)
{
return 0;
}
return lastMessage;
}
public int SendMessage(int target, uint Message)
{
if (com == null)
return -1;
if (target == 0)
{
com.SendMessageToMaster(Message);
return 0;
}
if (target == 1)
{
com.SendMessageToChild(Message);
return 1;
}
else
{
return -1;
}
}
public int PlayerInMission()
{
return gm.PlayerInMission;
}
public int PlayerTownId()
{
return gm.PlayerTownId;
}
public float TargetX()
{
return gm.TargetX;
}
public float TargetXMovementSpeed()
{
return gm.TargetXMovementSpeed;
}
public float TargetY()
{
return gm.TargetY;
}
public float TargetYMovementSpeed()
{
return gm.TargetYMovementSpeed;
}
public float TargetHp()
{
return gm.TargetHpCurrent;
}
public int TargetLevel()
{
return gm.TargetLevel;
}
public int TargetType()
{
return gm.TargetType;
}
public int TargetId()
{
return gm.TargetId;
}
public int TargetFaction()
{
return gm.TargetFaction;
}
public int TargetPrimaryProfession()
{
return gm.TargetPrimaryProfession;
}
public int TargetSecondaryProfession()
{
return gm.TargetSecondaryProfession;
}
public int TargetSpellId()
{
return gm.TargetSpellId;
}
public int TargetIsCasting()
{
if (gm.TargetSpellId != 0)
{
return 1;
}
else
{
return 0;
}
}
public double TargetDistance()
{
return gm.TargetDistance;
}
public int ItemID()
{
return gm.ItemID;
}
public int ItemRarity()
{
return gm.ItemRarity;
}
public int ItemQuantity()
{
return gm.ItemQuantity;
}
public int ItemModelID()
{
return gm.ItemModelID;
}
public int ItemValue()
{
return gm.ItemValue;
}
public void IdentItem(int idKit, int idToIdent)
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChildParam(AM_IDENTITEM, idKit, idToIdent);
}
}
public void SalvageItem(int idKit, int idToSalvage)
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChildParam(AM_SALVAGEITEMPTR, gm.GetUnknownPointer(), 0);
com.SendMessageToChildParam(AM_SALVAGEITEM, idKit, idToSalvage);
}
}
public int GetItemValue(int itemID)
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return 0;
}
else
{
gm.ItemValue = -1; //reset last message flag, see below
com.SendMessageToChildParam(AM_GETITEMVALUE, itemID, 0);
while (gm.ItemValue == -1) //the processing takes some time. wait until the item value is actually received
{ //to prevent crashes
Thread.Sleep(200);
}
return gm.ItemValue;
}
}
public void SellItem(int id, int value)
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
lastMessage = 0;
com.SendMessageToChildParam(AM_SELLITEM, id, value);
while (lastMessage != AM_SELLCOMPLETE) //same as GetItemValue above
{
Thread.Sleep(100);
}
}
}
public void MoveTo(float x, float y)
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChildParam(AM_MOVETOINFOX, 0, x);
com.SendMessageToChildParam(AM_MOVETOINFOY, 0, y);
com.SendMessageToChild(AM_MOVETO);
}
}
public void MoveToExact(float x, float y)
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChildParam(AM_MOVETOINFOX, 0, x);
com.SendMessageToChildParam(AM_MOVETOINFOY, 0, y);
com.SendMessageToChild(AM_MOVETOEXACT);
}
}
public void Travel(int location, int dis, int lang)
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChildParam(AM_LANGDIS, dis, lang); //only 2 parameters per window message possible
com.SendMessageToChildParam(AM_TRAVEL, location, 0); //thusly split in half for 3 necessary inforamtion
}
}
public void UseSkill(long slot, long target)
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
long myId = gm.PlayerID;
com.SendMessageToChildParam(AM_PLAYERID, (int)myId, 0); //UseSkill requires the current AgentId in ASM code
com.SendMessageToChildParam(AM_USESKILL, (int)slot, (int)target); //again 2 windows messages for 3 necessary parameters
}
}
public void EnterMission()
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChild(AM_ENTERMISSION);
}
}
public void TargetNextAlly()
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChild(AM_TARGETNEXTALLY);
}
}
public void DropItem()
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChild(AM_DROPITEM);
}
}
public void LootItem()
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
int itemID = gm.TargetId;
com.SendMessageToChildParam(AM_LOOTITEM, itemID, 0);
}
}
public void TargetNpc(int id)
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChildParam(AM_TARGETNPC, (int)id, 0);
}
}
public void TargetNearestItem()
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChild(AM_TARGETNEARESTITEM);
}
}
public void TargetNearestAlly()
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChild(AM_TARGETNEARESTALLY);
}
}
public void TargetNearestEnemy()
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChild(AM_TARGETNEARESTENEMY);
}
}
public void TargetNextEnemy()
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChild(AM_TARGETNEXTENEMY);
}
}
public void TargetNextItem()
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChild(AM_TARGETNEXTITEM);
}
}
public void AttackTarget()
{
if (com == null)
{
Print("Error: not attached to a Guild Wars process.\n");
return;
}
else
{
com.SendMessageToChildParam(AM_TARGETATTACK, gm.TargetId, 0);
}
}
public void DumpAddresses()
{
Print("PlayerX Address: " + gm.PlayerXAddress.ToString("X4") + "\n");
Print("PlayerMovementSpeedX Address: " + gm.PlayerMovementSpeedXAddress.ToString("X4") + "\n");
Print("PlayerY Address: " + gm.PlayerYAddress.ToString("X4") + "\n");
Print("PlayerMovementSpeedY Address: " + gm.PlayerMovementSpeedYAddress.ToString("X4") + "\n");
Print("PlayerID Address: " + gm.PlayerIDAddress.ToString("X4") + "\n");
Print("PlayerCurrentHp Address: " + gm.PlayerCurrentHpAddress.ToString("X4") + "\n");
Print("PlayerMaxHp Address: " + gm.PlayerMaxHpAddress.ToString("X4") + "\n");
Print("PlayerCurrentEp Address: " + gm.PlayerCurrentEnergyAddress.ToString("X4") + "\n");
Print("PlayerMaxEp Address: " + gm.PlayerMaxEnergyAddress.ToString("X4") + "\n");
Print("PlayerLevel Address: " + gm.PlayerLevelAddress.ToString("X4") + "\n");
Print("PlayerCastingSpell Address: " + gm.PlayerCastingSpellAddress.ToString("X4") + "\n");
Print("PlayerTownId Address: " + gm.PlayerTownIdAddress.ToString("X4") + "\n");
Print("PlayerGold Address: " + gm.PlayerGoldAddress.ToString("X4") + "\n");
}
public void SetTitle(string newName)
{
if (guildWarsProcess == null)
return;
SetWindowText(guildWarsProcess.MainWindowHandle, newName);
}
public void TerminateScript()
{
Thread.CurrentThread.Abort();
}
//------------------------##############Button configuration ################-----------------------------------
private void button1_Click(object sender, EventArgs e)
{
ClearConsole();
}
private void button2_Click(object sender, EventArgs e)
{
RunScript();
}
private void button3_Click(object sender, EventArgs e)
{
EndScript();
}
private void button4_Click(object sender, EventArgs e)
{
Attach();
}
private void button5_Click(object sender, EventArgs e)
{
Detach();
}
private void button6_Click(object sender, EventArgs e)
{
StartNewProcess();
}
private void button7_Click(object sender, EventArgs e)
{
CloseSelectedProcess();
}
private void startToolStripMenuItem_Click(object sender, EventArgs e)
{
RunScript();
}
private void stopToolStripMenuItem_Click(object sender, EventArgs e)
{
EndScript();
}
private void clearConsoleToolStripMenuItem_Click(object sender, EventArgs e)
{
ClearConsole();
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
bool bHandled = false;
switch (keyData)
{
case Keys.F5:
RunScript();
bHandled = true;
break;
case Keys.F9:
EndScript();
bHandled = true;
break;
}
return bHandled;
}
//------------------------##############Button configuration ################-----------------------------------
//------------------------############## DIRT ################-----------------------------------
private void Form1_Load(object sender, EventArgs e)
{
}
private void Form1_Closing(object sender, FormClosingEventArgs f)
{
DialogResult dlg;
if (changed)
{
dlg = MessageBox.Show("Warning, content not saved yet! Continue?", "Aeterna", MessageBoxButtons.YesNo);
if (dlg == DialogResult.No)
{
f.Cancel = true;
SaveLuaDoc();
}
if (injected)
com.SendMessageToChild(AM_UNLOADLIBRARY);
}
else if (!changed)
{
dlg = MessageBox.Show("Do you really want to quit Aeterna?", "Aeterna", MessageBoxButtons.YesNo);
if (dlg == DialogResult.No)
{
f.Cancel = true;
}
else if (dlg == DialogResult.Yes)
{
try
{
if (gm.readAdresses != null && gm.readAdresses.IsAlive)
{
gm.readAdresses.Abort();
}
if (injected)
com.SendMessageToChild(AM_UNLOADLIBRARY);
}
catch (Exception e)
{
Print(e.Message + "\n");
}
}
}
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
About abt = new About();
abt.Show();
}
private void helpToolStripMenuItem1_Click(object sender, EventArgs e)
{
Help hlp = new Help();
hlp.Show();
}
/*
private void AcquireGWPath() //Bugging ATM
{
return;
RegistryKey rk = Registry.LocalMachine.OpenSubKey("SOFTWARE\\ArenaNet\\Guild Wars");
GWPath = (string)rk.GetValue("Path");
}
/* Old method to bring the stat variables in the luaVM to the current state. Produced many crashes.
public void RefreshLuaVariables(Lua luaVM)
{
while (true)
{
try
{
luaVM["PlayerX"] = vsc.PlayerX;
luaVM["PlayerY"] = vsc.PlayerY;
luaVM["PlayerHpCurrent"] = vsc.PlayerHp;
luaVM["PlayerHpMax"] = vsc.PlayerHpMax;
luaVM["PlayerEpCurrent"] = vsc.PlayerEp;
luaVM["PlayerEpMax"] = vsc.PlayerEpMax;
luaVM["PlayerRegen"] = vsc.PlayerRegen;
luaVM["PlayerIsDead"] = vsc.PlayerIsDead;
luaVM["TargetX"] = vsc.TargetX;
luaVM["TargetY"] = vsc.TargetY;
luaVM["TargetHp"] = vsc.TargetHp;
luaVM["TargetLevel"] = vsc.TargetLevel;
luaVM["TargetType"] = vsc.TargetType;
luaVM["TargetId"] = vsc.TargetId;
luaVM["TargetSpellId"] = vsc.TargetSkill;
luaVM["TargetIsCasting"] = vsc.TargetIsCasting;
luaVM["TargetFaction"] = vsc.TargetFaction;
luaVM["SystemDate"] = DateTime.Now.ToString();
}
catch (Exception e)
{
Print("Lua variable refresh thread: " + e.Message + "\n");
}
Thread.Sleep(100);
}
}
***Previous method to initiate and refresh the global lua variables***
if (vsc != null) //value storage class initiated?
{
try
{
luaVM["PlayerX"] = vsc.PlayerX; //register global lua variables, will be refreshed below
luaVM["PlayerY"] = vsc.PlayerY;
luaVM["PlayerHpCurrent"] = vsc.PlayerHp;
luaVM["PlayerHpMax"] = vsc.PlayerHpMax;
luaVM["PlayerEpCurrent"] = vsc.PlayerEp;
luaVM["PlayerEpMax"] = vsc.PlayerEpMax;
luaVM["PlayerRegen"] = vsc.PlayerRegen;
luaVM["PlayerIsDead"] = vsc.PlayerIsDead;
luaVM["TargetX"] = vsc.TargetX;
luaVM["TargetY"] = vsc.TargetY;
luaVM["TargetHp"] = vsc.TargetHp;
luaVM["TargetLevel"] = vsc.TargetLevel;
luaVM["TargetType"] = vsc.TargetType;
luaVM["TargetId"] = vsc.TargetId;
luaVM["TargetSpellId"] = vsc.TargetSkill;
luaVM["TargetIsCasting"] = vsc.TargetIsCasting;
luaVM["TargetFaction"] = vsc.TargetFaction;
luaVM["SystemDate"] = DateTime.Now.ToString();
}
catch (Exception e)
{
Print("Error on Engine startup: " + e.Message + "\n.");
}
LuaVarRefresh = new Thread(() => RefreshLuaVariables(luaVM));
LuaVarRefresh.IsBackground = true;
LuaVarRefre******art();
}
*/
/* Same as above, only with a timer to avoid background threads. Unfortunately it does not work.
*
*
*
public System.Windows.Forms.Timer refreshLuaVars = new System.Windows.Forms.Timer();
public void refreshLuaVariables()
{
refreshLuaVars.Interval = 100;
refreshLuaVars.Start();
MessageBox.Show("Hit Start");
}
public void _refreshLuaVars(Lua luaVM)
{
//MessageBox.Show("Timer ticked");
luaVM["PlayerX"] = vsc.PlayerX;
luaVM["PlayerY"] = vsc.PlayerY;
luaVM["PlayerHpCurrent"] = vsc.PlayerHp;
luaVM["PlayerHpMax"] = vsc.PlayerHpMax;
luaVM["PlayerEpCurrent"] = vsc.PlayerEp;
luaVM["PlayerEpMax"] = vsc.PlayerEpMax;
luaVM["PlayerRegen"] = vsc.PlayerRegen;
luaVM["PlayerIsDead"] = vsc.PlayerIsDead;
luaVM["TargetX"] = vsc.TargetX;
luaVM["TargetY"] = vsc.TargetY;
luaVM["TargetHp"] = vsc.TargetHp;
luaVM["TargetLevel"] = vsc.TargetLevel;
luaVM["TargetType"] = vsc.TargetType;
luaVM["TargetId"] = vsc.TargetId;
luaVM["TargetSpellId"] = vsc.TargetSkill;
luaVM["TargetIsCasting"] = vsc.TargetIsCasting;
luaVM["TargetFaction"] = vsc.TargetFaction;
luaVM["SystemDate"] = DateTime.Now.ToString();
Print(luaVM["PlayerX"].ToString());
Print("\n");
}
*/
//------------------------############## DIRT ################-----------------------------------
}
}
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Windows.Interop;
namespace Pellax
{
class Communicator
{
IntPtr MainWindowHandle;
IntPtr ChildWindowHandle;
public Communicator(IntPtr hWindowMaster, IntPtr hWindowChild)
{
MainWindowHandle = hWindowMaster;
ChildWindowHandle = hWindowChild;
}
[DllImport("DllInjector", EntryPoint = "InjectDll", CallingConvention = CallingConvention.Cdecl)]
public static extern int DllInject(int ProcessId, IntPtr hWindowMaster, IntPtr hWindowChild); //Import the injection method coded in C++
//------------------------##############PROCESS COMMUNICATION##############------------------------------------
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool PostMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool SendMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam);
public bool SendMessageToMaster(uint Msg)
{
bool msg = PostMessage(MainWindowHandle, Msg, IntPtr.Zero, IntPtr.Zero);
return msg;
}
public bool SendMessageToMasterParam(uint Msg, int wParam, int lParam)
{
bool msg = PostMessage(MainWindowHandle, Msg, (IntPtr)wParam, (IntPtr)lParam);
return msg;
}
public bool SendMessageToChild(uint Msg)
{
bool msg = PostMessage(ChildWindowHandle, Msg, IntPtr.Zero, IntPtr.Zero);
return msg;
}
public bool SendMessageToChildParam(uint Msg, int wParam, int lParam)
{
bool msg = PostMessage(ChildWindowHandle, Msg, (IntPtr)wParam, (IntPtr)lParam);
return msg;
}
public bool SendMessageToChildParam(uint Msg, float wParam, float lParam)
{
bool msg = PostMessage(ChildWindowHandle, Msg, (IntPtr)wParam, (IntPtr)lParam);
return msg;
}
public bool SendMessageToChildWait(uint Msg, int wParam, int lParam)
{
bool msg = SendMessage(ChildWindowHandle, Msg, (IntPtr)wParam, (IntPtr)lParam);
return msg;
}
public bool SendMessageToMasterWait(uint Msg, int wParam, int lParam)
{
bool msg = SendMessage(MainWindowHandle, Msg, (IntPtr)wParam, (IntPtr)lParam);
return msg;
}
//SendMessage waits for a response, whereas PostMessage immediately returns
//------------------------##############PROCESS COMMUNICATION##############------------------------------------
}
}
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using GwRead;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace Pellax
{
class GwMemory
{
GwReader gwr; //a reference to the managed GwReader.dll. Contains all the functions for reading and writing memory stuff.
public GwMemory(int procID)
{
gwr = new GwReader(procID);
}
public float PlayerX;
public float PlayerY;
public float PlayerXMovementSpeed;
public float PlayerYMovementSpeed;
public float PlayerHpCurrent;
public int PlayerHpMax;
public float PlayerRegen;
public float PlayerEpCurrent;
public int PlayerEpMax;
public int PlayerLevel;
public int PlayerID;
public int PlayerSpellId;
public int PlayerGold;
public int PlayerGoldStash;
public int PlayerTownId;
public int PlayerInMission;
public float TargetX;
public float TargetY;
public float TargetXMovementSpeed;
public float TargetYMovementSpeed;
public float TargetHpCurrent;
public int TargetFaction;
public int TargetId;
public int TargetType;
public int TargetLevel;
public int TargetSpellId;
public int TargetPrimaryProfession;
public int TargetSecondaryProfession;
public double TargetDistance;
public int PlayerIDAddress;
public int PlayerXAddress;
public int PlayerYAddress;
public int PlayerCurrentHpAddress;
public int PlayerMaxHpAddress;
public int PlayerMaxEnergyAddress;
public int PlayerCurrentEnergyAddress;
public int PlayerLevelAddress;
public int PlayerPrimaryProfessionAddress;
public int PlayerSecondaryProfessionAddress;
public int PlayerTypeAddress;
public int PlayerMovementSpeedXAddress;
public int PlayerMovementSpeedYAddress;
public int PlayerCastingSpellAddress;
public int PlayerFactionAddress;
public int PlayerTownIdAddress;
public int PlayerGoldAddress;
public int ItemID = 0;
public int ItemRarity = 0;
public int ItemQuantity = 0;
public int ItemModelID = 0;
public int ItemValue = 0;
public int BagNumberOfItems;
public Thread readAdresses;
public void ReadAdresses()
{
while (true)
{
PlayerX = gwr.ReadPlayerX();
PlayerY = gwr.ReadPlayerY();
PlayerXMovementSpeed = gwr.ReadPlayerMovementSpeedX();
PlayerYMovementSpeed = gwr.ReadPlayerMovementSpeedY();
PlayerHpCurrent = gwr.ReadPlayerHpCurrent();
PlayerHpMax = gwr.ReadPlayerHpMax();
PlayerEpCurrent = gwr.ReadPlayerEnergyCurrent();
PlayerEpMax = gwr.ReadPlayerEnergyMax();
PlayerLevel = gwr.ReadPlayerLevel();
PlayerID = gwr.ReadPlayerID();
PlayerSpellId = gwr.ReadPlayerCastingSpell();
PlayerGold = gwr.ReadPlayerGold();
PlayerGoldStash = gwr.ReadPlayerGoldStash();
PlayerTownId = gwr.ReadPlayerTownId();
PlayerInMission = gwr.ReadPlayerInMission();
TargetX = gwr.ReadTargetX();
TargetY = gwr.ReadTargetY();
TargetXMovementSpeed = gwr.ReadTargetMovementSpeedX();
TargetYMovementSpeed = gwr.ReadTargetMovementSpeedY();
TargetHpCurrent = gwr.ReadTargetHpCurrent();
TargetFaction = gwr.ReadTargetFaction();
TargetId = gwr.ReadTargetID();
TargetType = gwr.ReadTargetType();
TargetLevel = gwr.ReadTargetLevel();
TargetSpellId = gwr.ReadTargetCastingSpell();
TargetPrimaryProfession = gwr.ReadTargetPrimaryProfession();
TargetSecondaryProfession = gwr.ReadTargetSecondaryProfession();
TargetDistance = ( Math.Sqrt(Math.Pow((double)(PlayerX - TargetX), 2) + Math.Pow((double)(PlayerY - TargetY), 2)) );
BagNumberOfItems = gwr.ReadBagNumberOfItems();
PlayerIDAddress = gwr.PlayerIDAddress;
PlayerXAddress = gwr.PlayerXAddress;
PlayerYAddress = gwr.PlayerYAddress;
PlayerCurrentHpAddress = gwr.PlayerCurrentHpAddress;
PlayerMaxHpAddress = gwr.PlayerMaxHpAddress;
PlayerMaxEnergyAddress = gwr.PlayerMaxEnergyAddress;
PlayerCurrentEnergyAddress = gwr.PlayerCurrentEnergyAddress;
PlayerLevelAddress = gwr.PlayerLevelAddress;
PlayerPrimaryProfessionAddress = gwr.PlayerPrimaryProfessionAddress;
PlayerSecondaryProfessionAddress = gwr.PlayerSecondaryProfessionAddress;
PlayerTypeAddress = gwr.PlayerTypeAddress;
PlayerMovementSpeedXAddress = gwr.PlayerMovementSpeedXAddress;
PlayerMovementSpeedYAddress = gwr.PlayerMovementSpeedYAddress;
PlayerCastingSpellAddress = gwr.PlayerCastingSpellAddress;
PlayerFactionAddress = gwr.PlayerFactionAddress;
PlayerTownIdAddress = gwr.PlayerTownIdAddress;
PlayerGoldAddress = gwr.PlayerGoldAddress;
Thread.Sleep(100);
}
}
public int TargetNpc(int id)
{
int result = gwr.TargetNpc(id);
return result;
}
public int GetItem(int bag, int slot)
{
int[] item = gwr.GetItem(bag, slot);
ItemID = item[0];
ItemRarity = item[1];
ItemQuantity = item[2];
ItemModelID = item[3];
ItemValue = item[4];
return 0;
}
public int GetUnknownPointer()
{
return gwr.ReadUnknownPointer();
}
}
}
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace GwRead
{
public class GwReader
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, UIntPtr nSize, out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteProcessMemory(IntPtr handle, IntPtr lpBaseAddress, byte[] lpBuffer, UIntPtr nSize, out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Boolean bInheritHandle, UInt32 dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
static extern int GetLastError();
int PlayerIDOffset = 0x2C;
int PlayerXOffset = 0x74;
int PlayerYOffset = 0x78;
int PlayerCurrentHpOffset = 0x130;
int PlayerMaxHpOffset = 0x134;
int PlayerMaxEnergyOffset = 0x120;
int PlayerCurrentEnergyOffset = 0x11C;
int PlayerLevelOffset = 0x10C;
int PlayerPrimaryProfessionOffset = 0x10A;
int PlayerSecondaryProfessionOffset = 0x10B;
int PlayerTypeOffset = 0x9C;
int PlayerMovementSpeedXOffset = 0xA0;
int PlayerMovementSpeedYOffset = 0xA4;
int PlayerCastingSpellOffset = 0x1B4;
int PlayerFactionOffset = 0x1B0;
public int PlayerIDAddress = 0x2C;
public int PlayerXAddress = 0x74;
public int PlayerYAddress = 0x78;
public int PlayerCurrentHpAddress = 0x130;
public int PlayerMaxHpAddress = 0x134;
public int PlayerMaxEnergyAddress = 0x120;
public int PlayerCurrentEnergyAddress = 0x11C;
public int PlayerLevelAddress = 0x10C;
public int PlayerPrimaryProfessionAddress = 0x10A;
public int PlayerSecondaryProfessionAddress = 0x10B;
public int PlayerTypeAddress = 0x9C;
public int PlayerMovementSpeedXAddress = 0xA0;
public int PlayerMovementSpeedYAddress = 0xA4;
public int PlayerCastingSpellAddress = 0x1B4;
public int PlayerFactionAddress = 0x1B0;
public int PlayerTownIdAddress = 0;
public int PlayerGoldAddress = 0;
int staticAdressIDSelf = 0xECA394; //0xEBF3C4; //0xEBF3D4; //0xEBF3CC;
int staticAdressIDTarget = 0xEC9EE8; //0xEBEF18; //0xEBEF28; //0xEBEF20;
int staticAdressAgentArray = 0xECA3E8; //0xEBF418; //0xEBF420
int staticAddressTownId = 0xEC2848; //0xEB7970; //0xEB7978;
int staticAddressInMission = 0xEBF9B8;
int baseAddress = 0xA3C790; //0xA5D3F0; //0xA52230; //0xA52230; //0xA46134;//0x3B3C30;//0xA30790;
IntPtr handle;
IntPtr handleWrite;
public GwReader(int procID)
{
handle = OpenProcess(0x10, false, (UInt32)procID);
handleWrite = OpenProcess(0x8 | 0x20, false, (UInt32)procID);
}
int ReadIntChain(int baseAddress, int[] offsets)
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)baseAddress, buffer, (UIntPtr)4, out bytesWritten);
int nextValue = BitConverter.ToInt32(buffer, 0);
for (int i = 0; i < offsets.Length; i++)
{
ReadProcessMemory(handle, (IntPtr)(nextValue + offsets[i]), buffer, (UIntPtr)4, out bytesWritten);
nextValue = BitConverter.ToInt32(buffer, 0);
}
int result = 0;
ReadProcessMemory(handle, (IntPtr)nextValue, buffer, (UIntPtr)4, out bytesWritten);
result = BitConverter.ToInt32(buffer, 0);
return result;
}
int ReadIntPtrChain(int baseAddress1, int[] offsets)
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)baseAddress1, buffer, (UIntPtr)4, out bytesWritten);
int nextValue = BitConverter.ToInt32(buffer, 0);
for (int i = 0; i < offsets.Length; i++)
{
ReadProcessMemory(handle, (IntPtr)(nextValue + offsets[i]), buffer, (UIntPtr)4, out bytesWritten);
nextValue = BitConverter.ToInt32(buffer, 0);
}
return nextValue;
}
int ReadByte(int address)
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)address, buffer, (UIntPtr)1, out bytesWritten);
int value = BitConverter.ToInt32(buffer, 0);
return value;
}
int ReadInt(int address)
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)address, buffer, (UIntPtr)4, out bytesWritten);
int value = BitConverter.ToInt32(buffer, 0);
return value;
}
int ReadSelfBase()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)staticAdressIDSelf, buffer, (UIntPtr)4, out bytesWritten);
int IDSelf = BitConverter.ToInt32(buffer, 0);
ReadProcessMemory(handle, (IntPtr)staticAdressAgentArray, buffer, (UIntPtr)4, out bytesWritten);
int baseAgentArray = BitConverter.ToInt32(buffer, 0);
ReadProcessMemory(handle, (IntPtr)baseAgentArray + (IDSelf * 4), buffer, (UIntPtr)4, out bytesWritten);
int AgentSelf = BitConverter.ToInt32(buffer, 0);
return AgentSelf;
}
int ReadTargetBase()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)staticAdressIDTarget, buffer, (UIntPtr)4, out bytesWritten);
int IDTarget = BitConverter.ToInt32(buffer, 0);
ReadProcessMemory(handle, (IntPtr)staticAdressAgentArray, buffer, (UIntPtr)4, out bytesWritten);
int baseAgentArray = BitConverter.ToInt32(buffer, 0);
ReadProcessMemory(handle, (IntPtr)baseAgentArray + (IDTarget * 4), buffer, (UIntPtr)4, out bytesWritten);
int AgentTarget = BitConverter.ToInt32(buffer, 0);
return AgentTarget;
}
public int ReadBagNumberOfItems()
{
int[] offsets = { 0x18, 0x40, 0xF8, 0x4, 0x10 };
return ReadIntChain(baseAddress, offsets);
}
public int[] GetItem(int bag, int slot)
{
int[] itemStats = { 1, 2, 3, 4, 5 }; //Id, rarity, quantity, modelId
int bagConverted = 0;
switch (bag)
{
case 4:
bagConverted = 0xD0;
break;
case 8:
bagConverted = 0xA4;
break;
case 12:
bagConverted = 0x78;
break;
case 16:
bagConverted = 0x4C;
break;
}
//MessageBox.Show(bagConverted.ToString());
int[] itemArrayOffsets = { 0x158, 0x38, 0x0, bagConverted, (slot * 4) };
int basead = ReadInt(baseAddress);
int offBegin = ReadInt(basead + 0x18);
int off1 = ReadInt(offBegin + 0x40); //0x158
//MessageBox.Show(off1.ToString("X"));
int off2 = ReadInt(off1 + 0x38); //0x38
//MessageBox.Show(off2.ToString("X"));
int off3 = ReadInt(off2 + 0);
//MessageBox.Show(off3.ToString("X"));
int off4 = ReadInt(off3 + bagConverted);
//MessageBox.Show(off4.ToString("X"));
int off5 = ReadInt(off4 + (slot * 4));
//MessageBox.Show(off5.ToString("X"));
/*
Hier gabs irgendwie ärger mit ReadIntPointerChain usw. musste es dann manuell machen, hatte keine lust die ursprüngliche routine zu bearbeiten, da es ja mit allem anderen klappt.
*/
/*
int itemArray = ReadIntPtrChain(ReadInt(baseAddress), itemArrayOffsets);
MessageBox.Show("ptr chain " + itemArray.ToString());
int itemArray = ReadIntChain(baseAddress, itemArrayOffsets);
//MessageBox.Show("chain " + itemArray.ToString());
int itemOfInterest = ReadInt(itemArray + (slot * 4));
//MessageBox.Show(itemOfInterest.ToString());
//int itemOfInterestRarity = ReadInt(itemOfInterest + 0x3C); //rarity
*/
itemStats[0] = ReadInt(off5);
itemStats[1] = ReadByte(ReadInt(off5 + 0x38)); //rarity?
itemStats[2] = ReadByte(off5 + 0x4C); //quantity, ehemals 4B
itemStats[3] = ReadInt(off5 + 0x2C); //modelId
itemStats[4] = ReadInt(off5 + 0x24); //value
return itemStats;
}
public int TargetNpc(int id)
{
IntPtr NpcIdAddress = (IntPtr)staticAdressIDTarget;
byte[] buffer = new byte[4];
buffer = BitConverter.GetBytes(id);
IntPtr lpNumberOfBytesWritten;
if (handleWrite == null)
{
return -1;
}
WriteProcessMemory(handleWrite, NpcIdAddress, buffer, (UIntPtr)4, out lpNumberOfBytesWritten);
int result = GetLastError();
return result;
}
public int ReadUnknownPointer()
{
int[] unknownPointerOffsets = { 0x158, 0xB8 };
int uPtr = ReadIntPtrChain(baseAddress, unknownPointerOffsets);
return uPtr;
}
public int ReadPlayerGold()
{
int goldBase = 0xA318B0;
int[] playerGoldOffsets = { 0x18, 0x40, 0xF8, 0x90 };
return ReadIntChain(goldBase, playerGoldOffsets);
}
public int ReadPlayerGoldStash()
{
int[] playerGoldStashOffsets = { 0x7DC, 0x24, 0x14, 0x80 };
int gAddress = ReadIntPtrChain(0xA35298, playerGoldStashOffsets);
return gAddress;
/*
int[] playerGoldStashOffsets = { 0x7DC, 0x24, 0x14, 0x80 };
return ReadIntChain(0xA35298, playerGoldStashOffsets);
*/
}
public float ReadPlayerX()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadSelfBase() + PlayerXOffset, buffer, (UIntPtr)4, out bytesWritten);
float PlayerX = BitConverter.ToSingle(buffer, 0);
PlayerXAddress = (ReadSelfBase() + PlayerXOffset);
return PlayerX;
}
public float ReadPlayerY()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadSelfBase() + PlayerYOffset, buffer, (UIntPtr)4, out bytesWritten);
float PlayerY = BitConverter.ToSingle(buffer, 0);
PlayerYAddress = ReadSelfBase() + PlayerYOffset;
return PlayerY;
}
public float ReadPlayerHpCurrent()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadSelfBase() + PlayerCurrentHpOffset, buffer, (UIntPtr)4, out bytesWritten);
float PlayerHpCurrent = BitConverter.ToSingle(buffer, 0);
PlayerCurrentHpAddress = ReadSelfBase() + PlayerCurrentHpOffset;
return PlayerHpCurrent;
}
public int ReadPlayerHpMax()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadSelfBase() + PlayerMaxHpOffset, buffer, (UIntPtr)4, out bytesWritten);
int PlayerMaxHP = BitConverter.ToInt32(buffer, 0);
PlayerMaxHpAddress = ReadSelfBase() + PlayerMaxHpOffset;
return PlayerMaxHP;
}
public int ReadPlayerCastingSpell()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadSelfBase() + PlayerCastingSpellOffset, buffer, (UIntPtr)4, out bytesWritten);
int PlayerCastingSpell = BitConverter.ToInt16(buffer, 0);
PlayerCastingSpellAddress = ReadSelfBase() + PlayerCastingSpellOffset;
return PlayerCastingSpell;
}
public int ReadPlayerLevel()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadSelfBase() + PlayerLevelOffset, buffer, (UIntPtr)4, out bytesWritten);
int PlayerLevel = BitConverter.ToInt32(buffer, 0);
PlayerLevelAddress = ReadSelfBase() + PlayerLevelOffset;
return PlayerLevel;
}
public int ReadPlayerID()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadSelfBase() + PlayerIDOffset, buffer, (UIntPtr)4, out bytesWritten);
int PlayerLevel = BitConverter.ToInt32(buffer, 0);
PlayerIDAddress = ReadSelfBase() + PlayerIDOffset;
return PlayerLevel;
}
public float ReadPlayerMovementSpeedX()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadSelfBase() + PlayerMovementSpeedXOffset, buffer, (UIntPtr)4, out bytesWritten);
float PlayerXMovementSpeed = BitConverter.ToSingle(buffer, 0);
PlayerMovementSpeedXAddress = ReadSelfBase() + PlayerMovementSpeedXOffset;
return PlayerXMovementSpeed;
}
public float ReadPlayerMovementSpeedY()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadSelfBase() + PlayerMovementSpeedYOffset, buffer, (UIntPtr)4, out bytesWritten);
float PlayerYMovementSpeed = BitConverter.ToSingle(buffer, 0);
PlayerMovementSpeedYAddress = ReadSelfBase() + PlayerMovementSpeedYOffset;
return PlayerYMovementSpeed;
}
public int ReadTargetID()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadTargetBase() + PlayerIDOffset, buffer, (UIntPtr)4, out bytesWritten);
int TargetID = BitConverter.ToInt32(buffer, 0);
return TargetID;
}
public float ReadPlayerEnergyCurrent()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadSelfBase() + PlayerCurrentEnergyOffset, buffer, (UIntPtr)4, out bytesWritten);
float PlayerEnergyCurrent = BitConverter.ToSingle(buffer, 0);
PlayerCurrentEnergyAddress = ReadSelfBase() + PlayerCurrentEnergyOffset;
return PlayerEnergyCurrent;
}
public int ReadPlayerEnergyMax()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadSelfBase() + PlayerMaxEnergyOffset, buffer, (UIntPtr)4, out bytesWritten);
int PlayerEpMax = BitConverter.ToInt32(buffer, 0);
PlayerMaxEnergyAddress = ReadSelfBase() + PlayerMaxEnergyOffset;
return PlayerEpMax;
}
public int ReadPlayerTownId()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)staticAddressTownId, buffer, (UIntPtr)4, out bytesWritten);
int PlayerTownId = BitConverter.ToInt32(buffer, 0);
PlayerTownIdAddress = staticAddressTownId;
return PlayerTownId;
}
public int ReadPlayerInMission()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)staticAddressInMission, buffer, (UIntPtr)4, out bytesWritten);
int PlayerInMission = BitConverter.ToInt32(buffer, 0);
return PlayerInMission;
}
public float ReadTargetX()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadTargetBase() + PlayerXOffset, buffer, (UIntPtr)4, out bytesWritten);
float TargetX = BitConverter.ToSingle(buffer, 0);
return TargetX;
}
public float ReadTargetY()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadTargetBase() + PlayerYOffset, buffer, (UIntPtr)4, out bytesWritten);
float TargetY = BitConverter.ToSingle(buffer, 0);
return TargetY;
}
public float ReadTargetMovementSpeedX()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadTargetBase() + PlayerMovementSpeedXOffset, buffer, (UIntPtr)4, out bytesWritten);
float TargetXMovementSpeed = BitConverter.ToSingle(buffer, 0);
return TargetXMovementSpeed;
}
public float ReadTargetMovementSpeedY()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadTargetBase() + PlayerMovementSpeedYOffset, buffer, (UIntPtr)4, out bytesWritten);
float TargetYMovementSpeed = BitConverter.ToSingle(buffer, 0);
return TargetYMovementSpeed;
}
public float ReadTargetHpCurrent()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadTargetBase() + PlayerCurrentHpOffset, buffer, (UIntPtr)4, out bytesWritten);
float TargetHpCurrent = BitConverter.ToSingle(buffer, 0);
return TargetHpCurrent;
}
public int ReadTargetType()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadTargetBase() + PlayerTypeOffset, buffer, (UIntPtr)4, out bytesWritten);
int TargetType = BitConverter.ToInt32(buffer, 0);
return TargetType;
}
public int ReadTargetFaction()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadTargetBase() + PlayerFactionOffset, buffer, (UIntPtr)4, out bytesWritten);
int TargetFaction = BitConverter.ToInt16(buffer, 0);
return TargetFaction;
}
public int ReadTargetCastingSpell()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadTargetBase() + PlayerCastingSpellOffset, buffer, (UIntPtr)4, out bytesWritten);
int TargetCastingSpell = BitConverter.ToInt16(buffer, 0);
return TargetCastingSpell;
}
public int ReadTargetLevel()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadTargetBase() + PlayerLevelOffset, buffer, (UIntPtr)4, out bytesWritten);
int TargetLevel = BitConverter.ToInt32(buffer, 0);
return TargetLevel;
}
public int ReadTargetPrimaryProfession()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadTargetBase() + PlayerPrimaryProfessionOffset, buffer, (UIntPtr)4, out bytesWritten);
int PrimaryProfession = buffer[0];
return PrimaryProfession;
}
public int ReadTargetSecondaryProfession()
{
byte[] buffer = new byte[4];
IntPtr bytesWritten;
ReadProcessMemory(handle, (IntPtr)ReadTargetBase() + PlayerSecondaryProfessionOffset, buffer, (UIntPtr)4, out bytesWritten);
int TargetSecondaryProfession = buffer[0];
return TargetSecondaryProfession;
}
}
}
In the end it looked something like this:






