[Release] Refine Center for PWI: Eclipse

03/20/2015 02:27 Stark77#1
hello folks,

lately i got a few requests to make a refinement tool.
since this community helped me so much with coding some very useful scripts i want to share this with u.

it a very simple tool made with autohotkey (AHK). ofc without any mouse clicks or color read trash.
i call it Refine Center. here is a screenshot:
[Only registered and activated users can see links. Click Here To Register...]

how to use it:
  1. select the character you want to work with in the first combo box
  2. open the Elder NPC and the refine window where u want to refine
  3. the value "Item Position" should be the position of the item in your inventory. starting to count from 1 to 32 (64). default its the last inventory slot. the position of refinement aids doesnt matter.
  4. the value "Refinement" should be the maximum refinement u want to get
  5. use Tienkan and Tisha are the refinement level starting with 0 and separated by comma. default the item will be refined to +7, at +1 to +4 tienkan will be used and at +5 to +6 tisha will be used as refinement aid
  6. the value "delay" is a fixed delay after the button refine is presses (well or the packet is send). it would be nice to read the status of this button for best performance but i was not able to find the offset chain
  7. and thats it: press start

supported hotkeys:
ALT+P = Pause
ALT+ESC = Close App

offsets:
  • the offsets.ini contains the current offset of PWI Eclipse v.842
  • the app is only tested at this server (with windows 7). adjusting the offsets might work for others
  • the offsets.ini needs to be in same path as the exe
  • note that many offsets are not necessary for this app...was just to lazy to remove them

Feel free to report bugs or issues. And please no rocks at me if u fail with it and good luck :P
03/20/2015 05:54 jasty#2
Looks nice.
Does it support all the different Tienkangs / Tisha out there?

Tienkangs = 40973, 26682, 26675, 26675
Tisha = 40972, 26676, 26683, 26676

I made a version a while ago that's not pretty like yours but it's set up to auto-buy the tisha and tienkang from the event boutique when it runs out of any in the inventory. Here are the packets for that if you need (though I'm sure you can find these yourself).

03/20/2015 11:09 Stark77#3
thats a nice idea - ill implement this whenever i find the offset chain for the damn button status^^

oh and ya the tool uses all those IDs.
03/20/2015 13:33 Underavelvetmoon#4
*** MY LIFE!!! I was half way through making my own to release!! Damn it I hate you xD Haha!

Seriously though this looks awesome, and now I dont have to spend my own time making it. Thanks a lot! :D

Will you be releasing the source? I'd be really interested in how everything is integrated, especially reading the process's for different characters.
03/20/2015 14:28 Stark77#5
well i copied many functions from a way bigger project so the source is abit unorganized...if i have some time i will try to fix it abit^^

as for the multiple chars i can give u a snipet:

03/20/2015 15:56 sasukezero#6
Awesome work :)
That makes me actually curious, how you got the Playername offsets and how to actually memread it via Autoit or Hotkey as string oO Im using atm Playerid as Client selection, which is good but harder to see who is who....
I wasnt able to find the addresses myself. I tried finding it by converting the playername to Hex and search it via CE. Also hexdec didnt bring it :/
Would be cool if someone could give me a hint ^^
03/20/2015 17:27 Stark77#7
i think Interest explained how to find the offset here: [Only registered and activated users can see links. Click Here To Register...]

i myself use ReClass2012...search for the PlayerPointer (easy to find with hp value) and search for it... should be close to the classID and other stuff. another way would be to search in CE for the length of the name...log another char with different length and repeat till u find the offset for it. 0x8 after that should be the name (see function getPlayerName).

Code:
getPlayerName(processID,GetPlayerPointer=1)
{
   global
   playerName =
   tempOffset = 0x0
   if (GetPlayerPointer = 1)
   {   
      baseAddress := ReadMemoryUint(realBaseAddress, processID)
      structurePointer := ReadMemoryUint(baseAddress + baseOffset, processID)
      playerPointer := ReadMemoryUint(structurePointer + playerOffset, processID)
   }
   playerNamePointer := ReadMemoryUint(playerPointer + playerNameOffset, processID)
   playerNameLen := ReadMemoryUint(playerNamePointer - 4*0x2, processID)
   loop, %playerNameLen%
   {
      character := ReadMemoryStr(playerNamePointer, tempOffset, processID)
      ; just in case
      if character =
         break
      if (playerNameLen > 12)
         break
      tempOffset := tempOffset + 0x2
      playerName := playerName character
   }
   return playerName
}

ReadMemoryStr(MADDRESS, offset, PID)
{
   ProcessHandle := DllCall("OpenProcess", "Int", 24, "Char", 0, "UInt", pid, "Uint")
   teststr =
   Loop
   {
      Output := "x"
      tempVar := DllCall("ReadProcessMemory", "UInt", ProcessHandle, "UInt", MADDRESS+offset, "str", Output, "Uint", 1, "Uint *", 0)
      if (ErrorLevel or !tempVar)
      {
         DllCall("CloseHandle", "int", ProcessHandle)
         return teststr
      }
      if Output =
         break

      teststr = %teststr%%Output%
      MADDRESS++
   }
   DllCall("CloseHandle", "int", ProcessHandle)
   return, teststr
}
03/20/2015 20:06 sasukezero#8
Thank you very much Stark.
I tried ReClass a few weeks ago, but just to test it out a bit. I didnt think, that i could use it in an easy and more helpfull way.
Ill look into it when i have more time :)

If i understand your function getPlayerName() right, then you are looping through each character to get the full name right ?

I thought before, that you could just read out the full name(obviously not as String, maybe as hex dec or so) and then convert it to string.

Thanks for sharing your way, i am learning more and more here which is awesome :D
03/20/2015 22:18 jasty#9
Quote:
Originally Posted by sasukezero View Post
Thank you very much Stark.
I tried ReClass a few weeks ago, but just to test it out a bit. I didnt think, that i could use it in an easy and more helpfull way.
Ill look into it when i have more time :)

If i understand your function getPlayerName() right, then you are looping through each character to get the full name right ?

I thought before, that you could just read out the full name(obviously not as String, maybe as hex dec or so) and then convert it to string.

Thanks for sharing your way, i am learning more and more here which is awesome :D
Reading name as a string is easy enough.
Code:
$pid = ProcessExists('elementclient.exe')
$ADDRESS_BASE = 0xd2e444
$Player_Offset = 0x28
$PlayerName_Offset = 0x6D8

$Player = _MemoryRead(_MemoryRead(_MemoryRead($ADDRESS_BASE, $pid) + 0x1C, $pid) + $Player_Offset, $pid)
$name = _MemoryRead(_MemoryRead($Player + $PlayerName_Offset, $pid), $pid, 'wchar[100]')
This is a good resource for showing where things are located though the offsets are not current.
[Only registered and activated users can see links. Click Here To Register...]
I use CE and try looking near the last known location for where the data is. Usually small offsets are not changed but the bigger ones get shifted down a few bytes when they add things to the player struct. So maybe that 0x6D8 offset will become 0x6E0, it won't be in a completely new place.
03/20/2015 23:11 sasukezero#10
damn jasty the 'wchar[100]' brought me the thing i needed in case of reading mem.
I failed before by using 'string' ^^ thought it might work.....

That together with Starks post make things easier.

Thanks :)
03/21/2015 09:58 Cindiena#11
Thank you
03/22/2015 03:51 haikiri#12
Hi, first tyvm for sharing such great work and maybe I can help with one detail.
I've been refining my stuff to +7 manually with Tienkan and Tisha, got 4 sets of gear to refined +7 and I saying this so you know that I really do have some hard experience with it to base my hypothesis that: The chance of success of each level is not a complex algorithm of randomizing according to e % rate but, merely a matter of timing.
As in. The percentage of success rate is a direct percentage of "a time cycle".
So, when refining from..
0 to 1, 50% of the cycle time.
1 to 2, 30% of the cycle time... and so on.
Then, as long as u know the beginning of the cycle, you also know the moment when its success and moment when its fail.
Now why do I think that.
Maybe you guys have heard of donkey refining.(rough translation of "refinando com mula")
Its a technique well noun between Brazilian players that consist in making attempts of refinement on a worthless piece of gear until u find a rhythm of fails and success and then you quickly switch the worthless gear to the real gear you want to refine when u "feel" like the next attempt is in a "success moment" of the rhythm.
Conclusion, if its truly a matter of timing instead of %rate, then you could implement this Refining Center with a time factor for the attempt.
Like, assume cycle is 1 sec and start after the cool down of the button to refine.
Then consider the lag between the client and the server doing a ping test to the server and take the average rate between a few tests.
And then make some tests to know if the success rate is at the beginning of the cycle or in the end.
Then finally, make the Refine Center make attempts only during the success moment.
Like, a routine that keep trying 20 times per second, but a second routine miscarries the attempts if the moment is considered a fail rate of the cycle.
And im sorry for the long text if im wrong x.x
03/22/2015 11:40 jasty#13
Refining to +7 is no accomplishment to boast about. I've refined plenty of gear to +9 without any of your cycle gibberish. The fact you are unwilling to refine past an easily attainable level suggests your model lacks any actual predictive power.

Logically the devs of the game have better things to do than waste days of development time coding and testing a complicated scheme like that when there is literally no benefit in them doing so. While I haven't inspected the source code I'd wager the refine function looks something like

bool refineSuccess(Item *gear) {
return rand() < RAND_MAX*REFINE_PROB[gear->refine];
}
03/22/2015 21:21 haikiri#14
Oki doki master jasty, thank you so much for your lovely approach on the topic.

Not trying to refine post +7 only show my lack of try. Trying and failing would actually suggest failure.

Another point that makes me thing it is true, is that I've seen many times ppl say: "I spent x thousands of mirages to refine this or that".
Or ppl saying: "I spent these hundreds of mirages and only got +3".
And I just made last week 2 pieces +7 with about 250 mirages. I had 11xx mirages and in the end had 9xx mirages, can't remember the exactly number.

Also, there are many videos on yt about that.
03/23/2015 05:51 quicktraxex#15
anyone here have prophet bot offset?