Originally Posted by
Cypher
I love your GUIs, very nicely done. I have a request though, would you mind posting your CastSpellById code? Whenever I tried to call CastSpellById from a new thread (which I created to loop the fishbot code in) it crashed, even when I set the object manager pointer in the new threads TLS.
I ended up getting it working by doing all my casting/looting/etc in a callback in WoWs main thread (on render), but would like to know what it is I overlooked that prevented function calls from working properly from that thread.
Thanks.
P.S. I'm stealing your LootBot idea for use with my AoE farming instance runs.
EDIT: As an aside, you could use LUA in your fishbot instead to add a lot of useful functionality such as casting by name ("CastSpell(\"Fishing\");") will automatically resolve the skill so you don't need to choose the level manually, you can also disable autoloot and loot each slot manually, dumping out the loot names, quantity, rarity, etc, plus, you can confirm BoP items. APIs to look into are CastSpell LootSlot GetLootSlotInfo GetCVar SetCVar ConfirmLoot or anything else under "loot" in the WoWWiki API list.
The fishing bot is written in C# using the BlackMagic lib using the offsets from your sticky, nothing out of the ordinary, I'll try to list the most relevant code below:
To start fishing:
Code:
fishThread = new Thread(mainLoop);
fishThread.IsBackground = true;
fishThread.Start();
In any case, The whole concept of (multi)-threaded programming is quite new to me, I absolutly hate coding things I don't fully understand but it was a necessity for the fisher to work. I've downloaded some ebooks on the subject because it will probably another 1-3 years before this subject gets touched in class If I made any outrageous mistake by doing it this way (by starting a thread of the mainLoop method) please point me in the right direction.
Inside the mainLoop() method (which is a private void, if it matters in the slightest) I have a line:
Code:
if (bInjection) { call_CastSpellById(ID_INJECTION); }
Which brings us to: (CASTSPELLBYID = 0x00773400)
Code:
private static void call_CastSpellById(int id)
{
uint codeCave = wow.AllocateMemory();
wow.Asm.Clear();
wow.Asm.AddLine("fs mov eax, [0x2C]");
wow.Asm.AddLine("mov eax, [eax]");
wow.Asm.AddLine("add eax, 8");
wow.Asm.AddLine("mov dword [eax], {0}", objectManager);
wow.Asm.AddLine("push 0");
wow.Asm.AddLine("push 0");
wow.Asm.AddLine("push 0");
wow.Asm.AddLine("push {0}", id);
wow.Asm.AddLine("call {0}", CASTSPELLBYID);
wow.Asm.AddLine("add esp,16");
wow.Asm.AddLine("retn");
wow.Asm.InjectAndExecute(codeCave);
wow.FreeMemory(codeCave);
}
As you can see, nothing special. I update the objectManger as suggested in other threads (pun intended) and call the function after. (just an fyi: I'm running Windows XP 32 bit)
Thanks for the hints on the LUA functions, I was going to look into them "in the not so distant future" because your first screenshot revealed the possiblity and power of said functions
And a happy New Year!