Author |
Internal Exp Viewer *Final version all patches,Tutorial Done*
uploaded 3/3/02 |
NinjaFish Lunatic
Joined: Feb 14,
2002 Posts: 13 |
Posted: 2002-02-26
06:30
uhm...no patcher in the "last" version? and here i thought i was gonna
be able to play in full-screen mode...oh well... the app runs just
fine as an app...it only crashes when i try to patch ragnarok.exe.
but i guess that doesn't matter anymore
and a special note:
there is likely less wrong with winxp than any other version of
windows, and 90% of the people that bash the xbox speak from
ignorance.
|
Sasami Orc Hero
L.2
Joined: Feb 08,
2002 Posts: 388 From: Jurai (Currently
Okayama, Japan)
|
Posted: 2002-02-26
07:05
How many places to I have to put around the program that it's
ragexe.exe, not ragnarok.exe! And I am not ignorant about the
xbox or winxp, I have much experience with both.
[ This Message was edited by: Sasami on 2002-02-26 07:05
]
|
Sasami Orc Hero
L.2
Joined: Feb 08,
2002 Posts: 388 From: Jurai (Currently
Okayama, Japan)
|
Posted: 2002-02-26
07:06
I've decided to post the first part of my tutorial, I got
bored, I'll finish the rest of it later.
Ingredients: A
programming language (c++ or VB) an asm dissasembler (I use
OLLYDBG) patience dr. pepper
Ok, I kept promising
people that I'd do this for a while, and I finally got around to it,
So here goes.
A few quick defenitions. Hwnd - The
"Handle" of a window that you use to control aspects of it. Hdc
- the "Handle to a Device Context" or a value you can use to put
graphics into a window. You can find the hdc using the api
getdc(hwnd). Api - Application Programming Interface...
basically functions windows has you can call. You can find them
all in the "api viewer" in visual basic.
The first thing I
did on my long quest was learn how to find the memory locations. I
found a program called winhex on
http://www.download.com/
and looked in ragnaroks ram and searched for the proper values,
then had them changed, and searched for the new values, and through
this I found the new locations, pretty simple. Next, I wrote the
first external exe viewer that was written for the english
server after patch 41 i think it was? I used visual basic and the
following APIs. (I tried this all out in C too and it worked
fine, but I code much much faster in VB.)
=================================================================================================
FindWindow - Finds a windows hwnd with only the name
GetWindowThreadProcessId - Finds the threadprocess knowing the
hwnd OpenProcess - opens the process using the threadprocess
CloseHandle - closes the process ReadProcessMemory - reads a
memoryvalue inside the opened process
=================================================================================================
Here is an example of how to find a value.
-------------------------------------------------------------------------------------------------
thehwnd = FindWindow(vbNullString, "Ragnarok")
GetWindowThreadProcessId thehwnd, ProcessId ProcessHandle =
OpenProcess(&H1F0FFF, False, ProcessId) ReadProcessMemory
ProcessHandle, &h55ff0c, NewString, 3, 0&
-------------------------------------------------------------------------------------------------
***newhwnd,processid,and processhandle are all "longs" or 4
bytes ***NewString is of course a string... thats where the data
at location &h55ff0c (or in C 0x55ff0c) will be stored, and
3 bytes will be stored according to the number after it. ***When
declaring the string, declare it as: dim stringname as string *
number (you need the * number part to make it a certain length, and
not variable.)
once you have the new value in a string,
you can copy it into a long or integer (4 bytes/2bytes) with the
following api.
=================================================================================================
CopyMemory - copies memory from one variable to another.
=================================================================================================
-------------------------------------------------------------------------------------------------
CopyMemory IntegerVariable, NewString, 3
-------------------------------------------------------------------------------------------------
From there, it was a simple matter of blitting it into the
external window.
=================================================================================================
Textout - Outputs a text into any hdc
=================================================================================================
-------------------------------------------------------------------------------------------------
Textout me.hdc, x , y, "NewStringName", 13 <-- the last
number is the length of the string.
-------------------------------------------------------------------------------------------------
so basically, i used
-------------------------------------------------------------------------------------------------
textout me.hdc, 0, 0, trim$(baseexpval) + "" +
trim$(baseexpnextval) + "" + left$(trim$(baseexpval /
baseexpnextval * 100), 4) + "%"
-------------------------------------------------------------------------------------------------
Now, this is the basic thing that most of the exp programs
do, but I tried to go farther and I succeeded in some places and
failed in others.
My brilliant idea was instead of
textouting into my windows hdc, i wanted to textout into ROs
hdc, and it worked... somewhat... here is what it looks like.
-------------------------------------------------------------------------------------------------
thehwnd = FindWindow(vbNullString, "Ragnarok") textout
thehwnd, 0, 0, trim$(baseexpval) + "" + trim$(baseexpnextval) + "" +
left$(trim$(baseexpval / baseexpnextval * 100), 4) + "%"
-------------------------------------------------------------------------------------------------
Now, there were two problems with this code. #1 it
always put it at location 0,0 #2 it showed in the window, but
always blinked
The way i solved the first one was just
finding the address in memory for the x and y locations
Basically, i put the basic info window at a random location,
took a screen shot, found the x and y position in paint,
searched for the value in winhex, did the same again, and found
where the x and y were stored, and changed my textout
accordingly. Now, the second problem I never did find out how to
fix. To explain why it didn't work I have to explain a little about
DirectX first. DirectX usually has at least to HDCs, one that
the user actually sees, the second is a back one where all the
changes occur, and on refreshes is copied onto the top one that
users see, so the user never sees any changes occuring. Basically,
my program blit onto the top one and when a refresh happened it
dissapeared, and then put it back up, causing a blinking effect.
There were 3 ways I could think of fixing this #1 Making my
program blit between ragnaroks pageswap (When the bottom hdc goes to
the top hdc) and the refresh #2 controlling the refresh
myself through my program and only initiating after my thing gets
blit #3 finding the hdc of the back hdc
So... #2 was
impractical, and I never did find out about #1 and #3, I just gave
up after scouring hundreds of sites, asking college professors
and people who should know, and asking on message boards. So,
what was I to do to make it internal? hm...
This is about
the time Arsenic posted his ArseKit link on the pak0 forums... right
after Ro-world died might I add. I liked his patching the exe
approach, and this is where the assembly came in. Before I get
into the assembly I will explain the rest of the functions of the
external viewer.
Windowed Full Screen
-------------------------------------------------------------------------------------------------
Dim resizerag As WINDOWPLACEMENT thehwnd =
FindWindow(vbNullString, "Ragnarok") //gets the hwnd
GetWindowPlacement thehwnd, resizerag //gets the current window
placement SetWindowLong thehwnd, -16, GetWindowLong(thehwnd,
-16) And Not 12582912 //Used for making the window not on top
SetWindowPos thehwnd, 0, 0, 0, 0, 0, 39 //same as above
resizerag.rcNormalPosition.Top = 0
resizerag.rcNormalPosition.Bottom = GetSystemMetrics(1) //screen
y res resizerag.rcNormalPosition.Left = 0
resizerag.rcNormalPosition.Right = GetSystemMetrics(0) //screen
x res SetWindowPlacement thehwnd, resizerag //Resize the window
-------------------------------------------------------------------------------------------------
Always On Top SetWindowPos Me.hwnd, IsOnTop, 0, 0, 0, 0,
83 -1 for on top -2 for not on top
Now on to the
assembly. (I'll write it tomorrow ^_^)
[edit] I have not yet
read over this and checked for grammer, spelling, or general
mistakes. When I finish it I will do so.
[ This
Message was edited by: Sasami on 2002-02-26 07:44
]
|
PikaPuff Orc
Hero
Joined: Feb 09,
2002 Posts: 332 From: Hawaii
|
Posted: 2002-02-26
07:15
*faints from big post* if i ever finish my ics111 homework,
i'll try to read that...
anyways, i want a sp/hp viewer
because:
when i sit or stand still to regain hp (thief) or
sp (mage) i alt+tab out to read these forums (or whatever)
so i can't see my hp/sp total on RO. and since your program
(ext version) is tiny, and has the 'always on top' function...
so i can read the forums and just glance at the sp/hp
counter to know when i'm at full hp/sp and go back into the game.
hehe and if you want to go nuts (which i don't) you can find
the value for the quantity of the first item in your vending box, so
you can sell pots in the first slot, and clance at the counter to
know when to go in the shop and refill _________________ PikaPuff,
Jesse Dioquino, The Puff Look At My Balls!
|
monkeyfishhead Spore
Joined: Feb 08,
2002 Posts: 136 From: USA
California
|
Posted: 2002-02-26
07:19
so....your final version of the expviewer doesnt work with
xp? the one you released before that worked with my xp home
edition...but i guess your done with it...so ill just stick with the
one before that..if thatll even work...
[edit]: ok it works
with my xp h.e. thanks for your cool prog sasami!!!
_________________ JOOBNESSSSSS!
meow...im a
cat
[ This Message was edited by:
monkeyfishhead on 2002-02-26 07:30 ]
|
Lord Gien Fabre
Joined: Feb 09,
2002 Posts: 28 |
Posted: 2002-02-26
07:23
Quote:
|
On 2002-02-26 02:40, Sasami wrote: Ah,
so NinjaFish is just crazy or does it crash w/o
my patch too? I hear some peoples RO games constantly crash.
|
|
Mines
crashed without your patch, but rarely.
|
Sasami Orc Hero
L.2
Joined: Feb 08,
2002 Posts: 388 From: Jurai (Currently
Okayama, Japan)
|
Posted: 2002-02-26
07:28
Quote:
|
On 2002-02-26 07:19, monkeyfishhead wrote:
so....your final version of the expviewer doesnt work
with xp? the one you released before that worked with my xp
home edition...but i guess your done with it...so ill just
stick with the one before that..if thatll even work...
|
|
when I
finish my tuturoial, you should be able to figure it out yourself
^_^ if not, I will get around to finding them.
And mine
rarely crashes also, some peoples crash constantly. His problem
though was because he was patching the wrong exe.
|
DarkByte Fabre
Joined: Feb 08,
2002 Posts: 30 From: Montreal, Qc,
Canada
|
Posted: 2002-02-26
07:34
HDC: Handle to a Device Context API: Application
Programming Interface
Good job on the viewer btw. Reason
i mentioned the "tip" is because it pops every time i start the
proggie. Not that i start it that often, but sometimes i switch
between collapsed and full size and this pops. No biggie
actually.
|
Sasami Orc Hero
L.2
Joined: Feb 08,
2002 Posts: 388 From: Jurai (Currently
Okayama, Japan)
|
Posted: 2002-02-26
07:42
ah, so thats what they stand for ^_^ I had forgotten both of
those a long time ago hehe
oops, my mistake, i'll go fix
that.
[edit] new fixed version uploaded, also changed the
title bar so it no longer says patch 51 hehehe
[ This Message was edited by: Sasami on 2002-02-26 07:50
]
|
DarkByte Fabre
Joined: Feb 08,
2002 Posts: 30 From: Montreal, Qc,
Canada
|
Posted: 2002-02-26
07:49
Humm .. i've been working on my personal version of the
viewer (external only) and i'm not getting the lastkill base/job
exp. Am i forgetting something ?
|
Sasami Orc Hero
L.2
Joined: Feb 08,
2002 Posts: 388 From: Jurai (Currently
Okayama, Japan)
|
Posted: 2002-02-26
07:53
I forgot to put that into the tutorial. I'll add that
tomorrow. Just make an extra variable that stores the kill, and when
it changes, subtract them, theres your last kill exp, store that in
a variable, then in your first variable, put the new exp.
a=currentexp while(1!=2) //loop forever { . if
a!=currentexp . { . . b=currentexp-a //last kill . .
a=currentexp . } }
[edit to add .s to see nested
programming.]
[ This Message was edited by:
Sasami on 2002-02-26 07:56 ]
|
DarkByte Fabre
Joined: Feb 08,
2002 Posts: 30 From: Montreal, Qc,
Canada
|
Posted: 2002-02-26
07:58
DOH !!!!!!!!!
I feel stupid now I guess i just was expecting to
find the values in ram.
|
PikaPuff Orc
Hero
Joined: Feb 09,
2002 Posts: 332 From: Hawaii
|
Posted: 2002-02-26
08:24
hm... been around 3 years since i've worked with c++
... i'll just read your tutorial and make my own version
with hp/sp...
i''ll probably still end up asking you how to
find values
_________________ PikaPuff,
Jesse Dioquino, The Puff Look At My Balls!
|
Snorks Willow
Joined: Feb 09,
2002 Posts: 56 |
Posted: 2002-02-26
08:36
Just a couple of questions. How did you determine what the
proper values were? Also, how did you find them in the new
locations? I hope I don't sound too dumb.
|
S#arp Pupa
Joined: Feb 26,
2002 Posts: 1 |
Posted: 2002-02-26
09:08
Hey Sasami, I am very interested in the Auto Dealer script
you are about to write. I think it's very cool. I dunno how you can
make a script that "integrates" into the game, not an external
program. Item_Collector got his own script and it works great. So if
you release your script, it will cost 1 million zenies? Whoa I dunno
when I can afford that Keep
up the good work, it would still be cool to see your source code,
knowing how it is done ^^
| |