Perfect World Bot PWI-Prophet Bot Recoded

08/22/2010 21:57 Elucas#286
Yeah, Right No perfect Client For Indo for now.
And you are lucky^^
This is the perfect Custom_Offsets.ini for PW Indo ;

Quote:
[Perfect_World_Base_Address_In_Decimal]
Application_Title=Element Client3
Base_Address=10229012
Base_AddressFZ=10230148
Base_AddressCHARID=11157196
[Custom_32_Offsets_In_Decimal]
CASTING_Offset=1740
Name_offset=1544
LVL_Offset=1124
Class_offset=1552
HP_OffSet=1132
MaxHP_OffSet=1188
MP_OffSet=1136
MaxMP_OffSet=1192
EXP_Offset=1140
STR_offset=1180
DEX_offset=1184
VIT_offset=1172
MAG_offset=1176
Spirit_offset=1144
Gold_offset=1320
X_Offset=60
Y_Offset=68
Z_Offset=64
MoveX_Offset=
MoveY_Offset=
MoveZ_Offset=
DoneFlag_Offset=
Value_Offset1=
Value_Offset2=
ActiveFlag_Offset=
MovingREAD_Offset=
MovingWRITE_Offset=
PetHP_OffSet=4088
Target_OffSet=2808
TarHP_OffSet=300
TarMaxHP_OffSet=356
TarName_OffSet=588
TarLVL_OffSet=292
TarSpec_OffSet=576
can someone teach me what and how to find the active offsets?
$ACTIVE = memread(memread($CHAR_DATA_BASE + 0xFF4) + 0x18)
?
08/22/2010 22:02 PW-Prophets#287
Quote:
Originally Posted by Interest07 View Post
Code:
InteractWith(objectId, interactionType, client, actionStruct, skillPointer=0)
{
	actionList := ReadMemory(actionStruct+0x30,client)
	WalkToAction := ReadMemory(actionList+0x8,client)

	writeMemory(0, WalkToAction+0x8, client)		;Action finished = 0
	writeMemory(1, WalkToAction+0x14, client)		;Action Start = 1
	writeMemory(0, WalkToAction+0x24, client)		;Action Not Start = 0
	writeMemory(objectId, WalkToAction+0x20, client)	;Set objectId to interact with
	writeMemory(interactionType, WalkToAction+0x38, client)	;Set type of action to perform (0 = regAtk, 1 = pick item, 2 = talk to NPC,3 = useSkill, 4 = gatherResources)
	writeMemory(0, WalkToAction+0x34, client)		;Set error = 0
	writeMemory(skillPointer, WalkToAction+0x50, client)
	writeMemory(WalkToAction, actionstruct+0xC, client)	;Set new action type WalkTo in action struct position action1
	writeMemory(1, actionstruct+0x18, client)		;Set next action position to 1
	writeMemory(WalkToAction, actionstruct+0x14, client)	;Set new action type WalkTo in action struct as next action	
}
Thank you! With this we have written a rough gathering(mats/herbs/items)and talk to npc.

How would we select a submenu once we have the first npc window up?

Thx will update soon!
08/22/2010 23:33 Interest07#288
Quote:
Originally Posted by PW-Prophets View Post
Thank you! With this we have written a rough gathering(mats/herbs/items)and talk to npc.

How would we select a submenu once we have the first npc window up?

Thx will update soon!
You're welcome :)

I'm afraid you can't use this to actually select options in NPC menus (as far as I know), easiest for that is injecting packets. Or if you're good with using click functions, you could probably be able to work something out with that, although I'm always hesitant to use clicks as they can have rather disastrous results at times when they go wrong.

Another option would be using GUI commands [Only registered and activated users can see links. Click Here To Register...] Although in my opinion if you're going to inject functions, it is best to use them to send packets in my opinion.

Also, if you want to use this function for using skills, you need to pass along a pointer to the skill struct. Assuming you know the skillId, you can find this pointer as follows:

Code:
skillListPointer := ReadMemory(player+0x101C,client)
nActiveSkills := ReadMemory(player+0x1020,client)
i := -0x4
loop %nActiveSkills%
{
	i := i + 0x4

	skillPointer := ReadMemory(skillListPointer+i, client)
	skillId := ReadMemory(skillPointer+0x8, client)
	if(skillId = 299) ;example for using envenom parasite
	{

		break
	}
}
now skillPointer would contain the value you'd pass along to the function for using that skill

edit: player being CHAR_DATABASE or what is it called, keep forgetting th ename you use hehe.


@smurfin. Well, it is likely that prophets will have the function in AutoIt so I won't try and rummage around in that language :D This function can be used to attack mobs and use skills on them only if you have them selected (on PWI at least, on PW MS selecting is not necessary), and it will move to the resource automatically before digging it
08/23/2010 01:44 Smurfin#289
hehe, thanks, that's very useful.

one other thing I'd like to have the most is an autofollow function because I once had one and find it very useful for botting with a priest or soloing hh.
It was a bit buggy though, coz when I used it the heal skill might be greyed out randomly. It didn't work anymore since the older patch and noone share the offset yet until now. Now I use macro for autofollow, though it works alright, it's a bit buggy since it's using macro with timer.

this is how the autofollow function I use looks like in autoit, perhaps you already found the needed offsets for autofollow or have a better function, please post it here too :D
Code:
func EPfollowLeader2()
SETLEADERID()
$EPWINTITLE = IniRead("SmurfIT.ini", "iNurse", "EP Window Name", "")
Global $PID_EP = WinGetProcess(IniRead("SmurfIT.ini", "iNurse", "EP Window Name", ""))
Global $PINFO_EP = _MEMORYOPEN($PID_EP)
$FTARGET1[1] = 32
$FTARGET1[2] = 3184
$FTARGET1[3] = 48
$FTARGET1[4] = 28
$FOLMODE = _MEMORYPOINTERREAD($APP_BASE_ADDRESS, $PINFO_EP, $FTARGET1)
$FTARGET2[1] = 32
$FTARGET2[2] = 3184
$FTARGET2[3] = 48
$FTARGET2[4] = 28
$FTARGET2[5] = 32
_MEMORYPOINTERWRITE($APP_BASE_ADDRESS, $PINFO_EP, $FTARGET2, Dec($LEADERID))
$FMODE[1] = 32
$FMODE[2] = Dec("C70")
$FMODE[3] = Dec("C")
_MEMORYPOINTERWRITE($APP_BASE_ADDRESS, $PINFO_EP, $FMODE, "0x" & Hex($FOLMODE[1]))
$FMODE[3] = Dec("14")
_MEMORYPOINTERWRITE($APP_BASE_ADDRESS, $PINFO_EP, $FMODE, "0x" & Hex($FOLMODE[1]))
$FMODE[3] = Dec("18")
_MEMORYPOINTERWRITE($APP_BASE_ADDRESS, $PINFO_EP, $FMODE, "1")
_memoryclose($PINFO_EP)
EndFunc
I think your function above can be used for autofollow too ? only need to know what value triggers a [follow] in the game and use char's npc id to be followed, because this function is based on vuduy's explanation at that time about casting skill/do something by using memory write, similar to what your function is about.
08/23/2010 08:22 Elucas#290
umm... i used smurfIT alot, so i got that ifollow had a same case on targeting.
if we can targeting monster with Tab method, then what about using shift + 1 to select group leader?
08/23/2010 08:55 No0oB#291
sure ^^ but if you want to make a good programm you should do your stuff without using the _sendmessage() or send() funcs ^^ what makes you shure the user didn't change his key settings ^^ or maybe he don't want to change them for the "bot" programm ^^
it's rly better to use the implemented funcs of the game ^^
08/23/2010 09:45 Elucas#292
owh, i see.... then the only way is just searching the follow trigger huh.
i don't sure but, follow option dont' have any effect on height (Z). and look like this option is only going to (X), and (Y) cord of the target.
and, btw i thing we need more option on life support. beside Potion we have a skill to healing isn't. this would help out anyone who have pet heal skill, and for Other type potion.
08/23/2010 12:08 Interest07#293
Quote:
Originally Posted by Smurfin View Post
hehe, thanks, that's very useful.

one other thing I'd like to have the most is an autofollow function because I once had one and find it very useful for botting with a priest or soloing hh.
It was a bit buggy though, coz when I used it the heal skill might be greyed out randomly. It didn't work anymore since the older patch and noone share the offset yet until now. Now I use macro for autofollow, though it works alright, it's a bit buggy since it's using macro with timer.

this is how the autofollow function I use looks like in autoit, perhaps you already found the needed offsets for autofollow or have a better function, please post it here too :D
Code:
func EPfollowLeader2()
SETLEADERID()
$EPWINTITLE = IniRead("SmurfIT.ini", "iNurse", "EP Window Name", "")
Global $PID_EP = WinGetProcess(IniRead("SmurfIT.ini", "iNurse", "EP Window Name", ""))
Global $PINFO_EP = _MEMORYOPEN($PID_EP)
$FTARGET1[1] = 32
$FTARGET1[2] = 3184
$FTARGET1[3] = 48
$FTARGET1[4] = 28
$FOLMODE = _MEMORYPOINTERREAD($APP_BASE_ADDRESS, $PINFO_EP, $FTARGET1)
$FTARGET2[1] = 32
$FTARGET2[2] = 3184
$FTARGET2[3] = 48
$FTARGET2[4] = 28
$FTARGET2[5] = 32
_MEMORYPOINTERWRITE($APP_BASE_ADDRESS, $PINFO_EP, $FTARGET2, Dec($LEADERID))
$FMODE[1] = 32
$FMODE[2] = Dec("C70")
$FMODE[3] = Dec("C")
_MEMORYPOINTERWRITE($APP_BASE_ADDRESS, $PINFO_EP, $FMODE, "0x" & Hex($FOLMODE[1]))
$FMODE[3] = Dec("14")
_MEMORYPOINTERWRITE($APP_BASE_ADDRESS, $PINFO_EP, $FMODE, "0x" & Hex($FOLMODE[1]))
$FMODE[3] = Dec("18")
_MEMORYPOINTERWRITE($APP_BASE_ADDRESS, $PINFO_EP, $FMODE, "1")
_memoryclose($PINFO_EP)
EndFunc
I think your function above can be used for autofollow too ? only need to know what value triggers a [follow] in the game and use char's npc id to be followed, because this function is based on vuduy's explanation at that time about casting skill/do something by using memory write, similar to what your function is about.
the function I would use for following would be:
Code:
followId(targetId, client, actionstruct)
{	
	
	actionList := ReadMemory(actionStruct+0x30,client)
	followPlayer := ReadMemory(actionList+0x1C,client)

	writeMemory(0, followPlayer+0x8, client) 		;Set error = 0
	writeMemory(targetId, followPlayer + 0x20, client)	;Set targetId to follow


	writeMemory(followPlayer, actionstruct+0xC, client)	;Set new action type follow in action struct position action1
	writeMemory(1, actionstruct+0x18, client)		;Set next action position to 1
	writeMemory(followPlayer, actionstruct+0x14, client)	;Set new action type follow in action struct as next action	
}
From what I can tell it looks somewhat similar (at least the last bit where you set the new action)
edit:
Yep, its the same, except you don't set the error value to 0, so if the previous time you followed he got stuck, the next time follow won't work for you (as far as I can tell). Ooph, converting dec to hex is a pain to the brain :P
08/23/2010 12:40 Smurfin#294
yea, I suspected it was like that when I first had the random greyed out skill but since I did not understand how to fix it, I just put 2 heal skill instead, so if one got stuck the other one would work or casted both at times, more mp usage but the priest got enough time to regen before it wasted mp pot.

When the script was working, following never fails though, my priest always sticks to whomever I set it to follow, only the cast heal skill fails at random, maybe because following doesn't have cooldown or queue, I remember vuduy once posted there is another queue for executing skill , but it's not important for this, maybe if we want to a bot attacking by using memory write then it'll be needed.

anyway, it's good to have this follow function back and works better, thanks for the help, Interest07 :handsdown: I'll fix my bot later when I have the time
08/23/2010 12:53 asaky#295
Quote:
Originally Posted by Smurfin View Post
yea, I suspected it was like that when I first had the random greyed out skill but since I did not understand how to fix it, I just put 2 heal skill instead, so if one got stuck the other one would work or casted both at times, more mp usage but the priest got enough time to regen before it wasted mp pot.

When the script was working, following never fails though, my priest always sticks to whomever I set it to follow, only the cast heal skill fails at random, maybe because following doesn't have cooldown or queue, I remember vuduy once posted there is another queue for executing skill , but it's not important for this, maybe if we want to a bot attacking by using memory write then it'll be needed.

anyway, it's good to have this follow function back and works better, thanks for the help, Interest07 :handsdown: I'll fix my bot later when I have the time
You should help the prophets make there bot better, Its a really good bot so far. With squad support and a offset retreiver it would be the best bot out there.
08/23/2010 13:14 Interest07#296
Quote:
Originally Posted by Smurfin View Post
yea, I suspected it was like that when I first had the random greyed out skill but since I did not understand how to fix it, I just put 2 heal skill instead, so if one got stuck the other one would work or casted both at times, more mp usage but the priest got enough time to regen before it wasted mp pot.

When the script was working, following never fails though, my priest always sticks to whomever I set it to follow, only the cast heal skill fails at random, maybe because following doesn't have cooldown or queue, I remember vuduy once posted there is another queue for executing skill , but it's not important for this, maybe if we want to a bot attacking by using memory write then it'll be needed.

anyway, it's good to have this follow function back and works better, thanks for the help, Interest07 :handsdown: I'll fix my bot later when I have the time
The InteractWith function I posted earlier should also work with executing skills (although not genie skills/pet skills afaik, have to use packets for them). Unless you mean something else?
08/23/2010 13:26 Smurfin#297
@asaky : I wish I could but I'm very limited lol, I got confused easily in this programming stuff and only managed to make something from gathering what you ppl already shared here.

@Interest07 :
Quote:
Originally Posted by Interest07 View Post
The InteractWith function I posted earlier should also work with executing skills (although not genie skills/pet skills afaik, have to use packets for them). Unless you mean something else?
no, I was just guessing if it had a queue for action, in this case for executing skills, because someone mentioned about it earlier and I think so too coz if pressing 2 skill hotkeys, both will be executed, but if pressing 3 or more, only two will be executed, one is the one executed immediately but another one is put in queue, while the rest are ignored.

btw, comparing your function to the follow function I use previously, I think I could make my old script working again by just changing 3184 to 4084 which is decimal value from 0xFF4.

$CHAR_DATA_BASE = memread(memread($APP_BASE_ADDRESS) + 0x20)
actionStruct is [CHARACTER_DATABASE + 0xFF4]
actionList := ReadMemory(actionStruct+0x30,client)
followPlayer := ReadMemory(actionList+0x1C,client)

that's similar to what I used above, only hex/dec difference
$FTARGET1[1] = 32 ;hex is 0x20
$FTARGET1[2] = 3184 ; this is C70 in hex, should be FF4 by now, but in pwi
$FTARGET1[3] = 48 ;hex is 0x30
$FTARGET1[4] = 28 ;hex is 0x1C

and I already changed $FMODE[2] = Dec("C70") to $FMODE[2] = Dec("FF4") but it still doesn't work. How do you find this "FF4" offset ? I'd like to find what should be the correct offset in PW Indo.
08/23/2010 15:50 Interest07#298
Quote:
Originally Posted by Smurfin View Post
@asaky : I wish I could but I'm very limited lol, I got confused easily in this programming stuff and only managed to make something from gathering what you ppl already shared here.

@Interest07 :


no, I was just guessing if it had a queue for action, in this case for executing skills, because someone mentioned about it earlier and I think so too coz if pressing 2 skill hotkeys, both will be executed, but if pressing 3 or more, only two will be executed, one is the one executed immediately but another one is put in queue, while the rest are ignored.

btw, comparing your function to the follow function I use previously, I think I could make my old script working again by just changing 3184 to 4084 which is decimal value from 0xFF4.

$CHAR_DATA_BASE = memread(memread($APP_BASE_ADDRESS) + 0x20)
actionStruct is [CHARACTER_DATABASE + 0xFF4]
actionList := ReadMemory(actionStruct+0x30,client)
followPlayer := ReadMemory(actionList+0x1C,client)

that's similar to what I used above, only hex/dec difference
$FTARGET1[1] = 32 ;hex is 0x20
$FTARGET1[2] = 3184 ; this is C70 in hex, should be FF4 by now, but in pwi
$FTARGET1[3] = 48 ;hex is 0x30
$FTARGET1[4] = 28 ;hex is 0x1C

and I already changed $FMODE[2] = Dec("C70") to $FMODE[2] = Dec("FF4") but it still doesn't work. How do you find this "FF4" offset ? I'd like to find what should be the correct offset in PW Indo.
Ahhh I see what you mean now, you want to pass along several skills it has to perform in order as soon as it can? I'm not quite sure how you'd do that, I prefer just checking the cooldown time of the skills to see if I can use the next skill:
1) use skill1
2) wait for cooldown to be 0
3) use skill 2
etcetera, if I recall correctly if you use a skill, it will start a cooldown that needs to be 0 before you can use any other skill. So just execute the next skill as soon as that value is 0 and you should be able to chain skills quite easily.

As for finding that offset for your version of perfect world. I find it easiest to just use hotkeys to browse through my "character_database" and have a tooltip show the values until I find what I'm looking for, similar to the code I posted a while ago. You already know the values will look like, so it shouldn't be too hard to recognise it when you hit the right offset.

For example:

Say I'm looking for that offset (FF4 in PWI). I do know what values are supposed to pop up if I have the correct value for that offset.
So I simply set that offset equal to a variable actionStructOffset, then have a tooltip on my screen listing some values using that offset.
THen I use a hotkey to increase (or decrease) the actionStructOffset value until the tooltip shows values that make sense. And tadaaa I got my offset.

Code:
client := "Element Client"
actionStructOffset := 0x0

loop
{
	actionstruct := ReadMemory(player+actionStructOffset,client)
	actionList := ReadMemory(actionStruct+0x30,client)
	moveAction := ReadMemory(actionList+0x4,client)	

	output := ""
	
	val1 := ReadMemory(actionstruct+0x8,client, 1)
	output = %output%New Action0 | %val1% `n
	val1 := ReadMemory(actionstruct+0xC,client)
	output = %output%New Action1 | %val1% `n
	val1 := ReadMemory(actionstruct+0x10,client)
	output = %output%New Action2 | %val1% `n
	val1 := ReadMemory(actionstruct+0x14,client)
	output = %output%Current Action | %val1% `n
	val1 := ReadMemory(actionstruct+0x18,client)
	output = %output%Next Action | %val1% `n -------------------- `n
	
	i := -0x4
	loop 40
	{
		i := i + 0x4
		testing :=readmemory(MoveAction+i, client)
		output = %output%[%i%]%testing%`n
	}		
}

=::
actionStructOffset := actionStructOffset + 0x4
return

-::
actionStructOffset := actionStructOffset - 0x4
return
this would look like this on my screen once I've gotten to the right offset:
[Only registered and activated users can see links. Click Here To Register...]

Most of the time the values will be error messages, so you know the quickly move on to the next offset. Sometimes it might look to be possibly correct values, then you just move a little, see if any values change as you'd expect. If not then you move on, if yes, yay you're there :p
This is the easiest way to find offsets rather quickly.
08/23/2010 16:03 Smurfin#299
yea, kinda like that, but since macro is working again by just unfreezing client, we won't be needing the memory write method for executing skills for a while, maybe until the developers decided to block key sends completely.

tks again for pointing that out, I should use that way to find the offset I need.

hehe, that function is very useful, can be used for a lot of things ^^) , once the offset is found, can even be used for picking up ground mats etc.
08/23/2010 16:26 Interest07#300
True, you don't really need to use these functions for using skills at the moment, although it does leave things open for more customization if you are not bound by hotkeys.