PDA

View Full Version : getPlayerXp() - Function to get player's total xp for a skill, or overall



Brotein
02-23-2016, 08:42 PM
So I was making a bot for a friend in openGL. I used to read it from the skills tab ingame. I saw a price grabbing function and used the same concept with getPage() and, between() and replace() string functions. Enjoy!

*Please note that it's runecraft and not runecrafting, don't make this error!*


(*
getPlayerXp
~~~~~~~~

.. code-block:: pascal

function getPlayerXp(skillName, playerName : string) : uInt32;

This function will grab a player's skill's total experience. This is useful
for providing accurate xp information to a progress report. The 'skillName'
string is the name of the skill you want the xp for, it is converted to lower
case since that's how it's done on draynor. The 'playerName' string is the
ingame name of the player, and it will encode the white spaces to a '+' for the
URL query. Returns as an uInt32.

.. note::
=====================
= Acceptable Inputs =
=====================
| overall |
| attack |
| defense |
| strength |
| hitpoints |
| ranged |
| prayer |
| magic |
| cooking |
| woodcutting |
| fletching |
| fishing |
| firemaking |
| crafting |
| smithing |
| mining |
| herblore |
| agility |
| thieving |
| slayer |
| farming |
| runecraft |
| hunter |
| construction |
| summoning |
| dungeoneering |
=====================

- Original function by The Mayor
- Modified by Brotein

Example:

.. code-block:: pascal

writeln(getPlayerXp('Smithing', 'Your Player Name Here'));

*)
function getPlayerXp(skillName, playerName : string) : uInt32;
var
url, xp, temp : string;
begin
temp := replace(playerName, ' ', '+', [rfReplaceAll]);
url := getPage('www.draynor.net/stats_lookup.php?runescape_name=' + temp + '&submit=GO');
temp := lowerCase(skillName);
xp := between(temp + '_temp"></div>', '</td>', url);
xp := between('Experience:</strong> <span class="green">', '</span>', xp);
xp := replace(xp, ',', '', [rfReplaceAll]);
result := strToIntDef(xp, 0);
end;

Lucidity
02-23-2016, 09:25 PM
This is a good idea even for OSRS if someone were to have a staking bot they'd be able to grab the opponents stats!

Joopi
02-23-2016, 10:04 PM
Or just use osbuddy as the client or use Reflection. Either way I think it's a cool idea.

Harrier
02-23-2016, 10:24 PM
Or just use osbuddy as the client or use Reflection. Either way I think it's a cool idea.

Since when was there a hook for player data like on the highscores in OSRS?

Obscurity
02-23-2016, 11:06 PM
Don't mean to steal your thunder, mate. But saw your post and decided to write a little something:


Hiscores() - Returns a player's level or experience in a desired skill. Returns -1 on failure.

Player:
-------
The player you'd like to search.

Skill:
------
The skill you'd like to search. NOT case sensitive.
Options:
--------
overall, total
def, defence, defense
str, strength
cons, constitution, hp, hitpoints
range, ranged
pray, prayer
mage, magic
cook, cooking
wc, woodcut, woodcutting
fletch, fletching
fish, fishing
fm, fire, firemake, firemaking
craft, crafting
smith, smithing
mine, mining
herb, herblore
agi, agility
thieve, thieving
slay, slayer, slaying
farm, farming
rc, runecraft, runecrafting
hunt, hunter, hunting
con, construction
sum, summon, summoning
dg, dung, dungeon, dungeoneering
div, divination
inv, invent, invention

Experience:
-----------
If true, return experience instead of level.

Oldschool:
----------
If true, search the Oldschool hiscores instead of RuneScape 3.

Function Hiscores(Player, Skill : string; Experience, Oldschool : Boolean = False ) : Integer;
Const
Skills :=[
'overall|total',
'att(ack)?',
'def(en(c|s)e)?',
'str(ength)?',
'cons(titution)?|h(itpoints|p)',
'ranged?',
'pray(er)?',
'mag(ic|e)',
'cook(ing)?',
'w(oodcut(ting)?|c)',
'fletch(ing)?',
'fish(ing)?',
'f(ire(mak(e|ing))?|m)',
'craft(ing)?',
'smith(ing)?',
'min(e|ing)',
'herb(lore)?',
'agi(lity)?',
'thiev(e|ing)',
'slay(er|ing)?',
'farm(ing)?',
'r(unecraft(ing)?|c)',
'hunt(er|ing)?',
'con(struction)?',
'sum(mon(ing)?)?',
'd(ung(eon(eer|ing)?)?|g)',
'div(ination)?',
'inv(ent(ion)?)?'
];
Var
Index : Integer;
Page : string;
Statistics : TStringArray;
Begin
Page := GetPage('http://services.runescape.com/m=hiscore' + ['_oldschool'][Oldschool - 1] + '/index_lite.ws?player=' + Player);
If Pos('404 - Page not found', Page) Then
Exit(-1);
Statistics := Explode(#10, Page);
For Index To [27, 23][Oldschool] Do
If ExecRegExpr('(?i)' + Skills[Index], Skill) Then
Begin
Statistics := Explode(',', Statistics[Index]);
Exit(StrToInt(Statistics[1 + Experience]));
End;
End;


Slayer := Hiscores('A Friend', 'slay', true); //~ Return RS3 Slayer XP
Dungeoneering := Hiscores('A Friend', 'dg'); //~ Return RS3 Dungeoneering level
Herblore := Hiscores('A Friend', 'HeRb', true, true); //~ Return OSR Herblore XP

Reg ex. IDC.

KeepBotting
02-23-2016, 11:35 PM
Don't mean to steal your thunder, mate. But saw your post and decided to write a little something:


Hiscores() - Returns a player's level or experience in a desired skill. Returns -1 on failure.

Player:
-------
The player you'd like to search.

Skill:
------
The skill you'd like to search. NOT case sensitive.
Options:
--------
overall, total
def, defence, defense
str, strength
cons, constitution, hp, hitpoints
range, ranged
pray, prayer
mage, magic
cook, cooking
wc, woodcut, woodcutting
fletch, fletching
fish, fishing
fm, fire, firemake, firemaking
craft, crafting
smith, smithing
mine, mining
herb, herblore
agi, agility
thieve, thieving
slay, slayer, slaying
farm, farming
rc, runecraft, runecrafting
hunt, hunter, hunting
con, construction
sum, summon, summoning
dg, dung, dungeon, dungeoneering
div, divination
inv, invent, invention

Experience:
-----------
If true, return experience instead of level.

Oldschool:
----------
If true, search the Oldschool hiscores instead of RuneScape 3.

Function Hiscores(Player, Skill : string; Experience, Oldschool : Boolean = False ) : Integer;
Const
Skills :=[
'overall|total',
'att(ack)?',
'def(en(c|s)e)?',
'str(ength)?',
'cons(titution)?|h(itpoints|p)',
'ranged?',
'pray(er)?',
'mag(ic|e)',
'cook(ing)?',
'w(oodcut(ting)?|c)',
'fletch(ing)?',
'fish(ing)?',
'f(ire(mak(e|ing))?|m)',
'craft(ing)?',
'smith(ing)?',
'min(e|ing)',
'herb(lore)?',
'agi(lity)?',
'thiev(e|ing)',
'slay(er|ing)?',
'farm(ing)?',
'r(unecraft(ing)?|c)',
'hunt(er|ing)?',
'con(struction)?',
'sum(mon(ing)?)?',
'd(ung(eon(eer|ing)?)?|g)',
'div(ination)?',
'inv(ent(ion)?)?'
];
Var
Index : Integer;
Page : string;
Statistics : TStringArray;
Begin
Page := GetPage('http://services.runescape.com/m=hiscore' + ['_oldschool'][Oldschool - 1] + '/index_lite.ws?player=' + Player);
If Pos('404 - Page not found', Page) Then
Exit(-1);
Statistics := Explode(#10, Page);
For Index To [27,23][Oldschool] Do
If ExecRegExpr('(?i)' + Skills[Index], Skill) Then
Begin
Statistics := Explode(',', Statistics[Index]);
Exit(StrToInt(Statistics[1 + Experience]));
End;
End;


Slayer := Hiscores('A Friend', 'slay', true); //~ Return RS3 Slayer XP
Dungeoneering := Hiscores('A Friend', 'dg'); //~ Return RS3 Dungeoneering level
Herblore := Hiscores('A Friend', 'HeRb', true, true); //~ Return OSR Herblore XP

Reg ex. IDC.

Can you explain this

+ ['_oldschool'][Oldschool - 1] +

I have never seen brackets used like that before

Obscurity
02-23-2016, 11:47 PM
KeepBotting;

['_oldschool'] is just a single length string array. So if we did...
someString := ['_oldschool'][0]
...someString would be _oldschool.

If Oldschool is true, 1, ['_oldschool'][0] - '_oldschool'.

If Oldschool is false, 0, ['_oldschool'][-1] - ''.

Was just my way of doing 'http://...' + (Oldschool ? '_oldschool' : '') + '...'.

KeepBotting
02-23-2016, 11:50 PM
KeepBotting;

['_oldschool'] is just a single length string array. So if we did...
someString := ['_oldschool'][0]
...someString would be _oldschool.

If Oldschool is true, 1, ['_oldschool'][0] - '_oldschool'.

If Oldschool is false, 0, ['_oldschool'][-1] - ''.

Was just my way of doing (Oldschool ? '_oldschool' : '').

Oh that is incredible, thank you very much... I love the ternary operator and didn't know there was a way to do it in Lape!

Obscurity
02-24-2016, 12:10 AM
Oh that is incredible, thank you very much... I love the ternary operator and didn't know there was a way to do it in Lape!

Not having the ternary operator was one of the things I hated as well. Meh, that's a hackish way, but it works.

slacky
02-24-2016, 05:35 AM
Oh that is incredible, thank you very much... I love the ternary operator and didn't know there was a way to do it in Lape!
Keep in mind that what obs. is also doing is relying on implicit casting between boolean and integer when subtracting and adding to/from a boolean.
There is no guarantee that will work in any later lape version, and with any recent lape versions his code will not work.


If Oldschool is false, 0, ['_oldschool'][-1] - ''.
This is incorrect.. You are accessing an element out of range when doing ``['_oldschool'][Oldschool - 1]``
When "Oldschool" is False (0) you have: "Boolean.False - 1" which relies on an implicit cast from Boolean to a byte-sized integer (this much is obvious), the result of doing this however might not be as obvious.
The indexing operation would then cast the result of the operation into an Unsigned Int8 (from a boolean), making the the above equal to ``['_oldschool'][255]``, even if the result was `-1`, which I assume you expected, the issue remains:
This can at any point cause a script to access violate. And there is also no guarantee that the result of that is empty, it's just likely.

Further more: adding or subtracting from a boolean barely works in current lape version (used by simba) which should be enough of a hint to show that it's at best undefined behavior:
> var MyBool:Boolean = False;
> WriteLn(MyBool - 1);
Error: Cannot invoke identifier


The best behavior if one where to allow arithmetic operations on booleans (in this case + and -) would be to have it wrap around 0..1, however this would only make sense with Boolean, and not with ByteBool, LongBool or WordBool. So it would be more or less inconsistent, which is not a good thing for any programming language. But could be done, I guess.

Obscurity
02-24-2016, 11:42 AM
slacky;

If it works for current Simba, in this situation, I'm fine with it. :-P. Would you consider Ord(someBool) safer?

slacky
02-24-2016, 11:54 AM
slacky;

If it works for current Simba, in this situation, I'm fine with it. :-P. Would you consider Ord(someBool) safer?
Yes, and that would be different. But your function would still not be "working", it can crash at any time.

run this a couple of times to see how an access violation can easily happen when going out of range:


var x:String;
begin
x := ['meh'][1];
end.

More involved to produce an easily reproducable crash case for ['meh'][255] tho, but it can happen there as well obviously as you are doing the same thing, just bigger offset.

Using ord on "Boolean.False" and subtracting 1 you'd get -1, unlike 255 which you are getting by relying on implicit casts.
so the operation becomes: ['somestring'][-1], and this can also crash at any time, as you are still going out of range.

the bank
02-24-2016, 01:33 PM
Since when was there a hook for player data like on the highscores in OSRS?

Of course there is a hook for it. Whether Kyle; has hooked it or not is a totally different story. I have no idea.

HOWEVER:

getPlayers()[n].getFacade().getSkills(); = Skill[]

^ static ref ^ indices for which player

THEN:

skill.getExperience();
skill.getLevel();
skill.getEffectiveLevel();

All of the above is named from and hooked in my updater.


This has the bonus of working even when the player isn't hiscore listed.

slacky
02-24-2016, 01:47 PM
Don't be an idiot.
Of course there is a hook for it.
Don't be an idiot.
You can't hook shit to gain the same functionality as the method proposed in the first thread, the client simply doesn't have that information. To be clear, the method shown in the first thread can get that stats of ANY player.
Suggestion for next time you feel like calling someone an idiot is the actually check if what they are saying is correct. Which it IS in this case.

PS: Only said "Don't be an idiot" to show how unnecessary that actually is.

Harrier
02-24-2016, 01:52 PM
Don't be an idiot.

Of course there is a hook for it. Whether Kyle; has hooked it or not is a totally different story. I have no idea.

HOWEVER:

getPlayers()[n].getFacade().getSkills(); = Skill[]

^ static ref ^ indices for which player

THEN:

skill.getExperience();
skill.getLevel();
skill.getEffectiveLevel();

All of the above is named from and hooked in my updater.


This has the bonus of working even when the player isn't hiscore listed.
I was thinking about for other players. Ofc there is one for your own player it's easy to see that, and on OSRS all players are listed on the highscores anyway the only issue is that it can be out by 6 hours max.
So back to my original question can you get player data like on the highscores in OSRS such as other players, ranks, and mini game data?

the bank
02-24-2016, 02:07 PM
-snip-

kristi
02-24-2016, 02:15 PM
Flight maybe implement this into AL?

Harrier
02-24-2016, 03:07 PM
My included code was for other players. Do you seriously need me to make a video or something demonstrating this?


EDIT:



More proof that you're a fucking retard. Yes, totally, I existed and was ridiculously active at the same time as him, but I'm also him. Your logic knows no bounds.
I based that off the FACT you claimed to write KYAB in the past.

Dogerina
02-24-2016, 03:17 PM
Don't be an idiot.

Of course there is a hook for it. Whether Kyle; has hooked it or not is a totally different story. I have no idea.

HOWEVER:

getPlayers()[n].getFacade().getSkills(); = Skill[]

^ static ref ^ indices for which player

THEN:

skill.getExperience();
skill.getLevel();
skill.getEffectiveLevel();

All of the above is named from and hooked in my updater.


This has the bonus of working even when the player isn't hiscore listed.

Don't be an idiot.
The facade is a static reference only for the local player

Kyle
02-24-2016, 03:22 PM
Don't be an idiot.
The facade is a static reference only for the local player

Was just about to say that lol. Unless there was something I was missing haha

the bank
02-24-2016, 03:27 PM
I based that off the FACT you claimed to write KYAB in the past.

No, I didn't. What I said was that I had worked on several projects in the past and was wondering if their source code was still floating around. I based this all on an old archive I had found on one of my usb drives.

Infact, that was all cleared up after speaking to Benland100. I had no role in the KYAB project, it had just made it into my archive somehow. I'm not going to apologize for calling you an idiot, because you truly did demonstrate exactly that. Admins can -rep me and warn me all they want, I will continue to standup for myself when people accuse me of bullshit.

So, Harrier, I will briefly go over my history so we won't have this problem again :)

- Entered the scene in ~2006
- Joined RSCA (the home of iBot/Nexus and the Ares re-build)
- Slowly worked my way up the ranks as I learned
- Became a developer for Nexus
- Became a Global Moderator for RSCA (at the time - by far largest site in RS botting)
- Impsoft was sued for almost a million dollars by Jagex, RSCA no loger exists
- Joined MITB
- Became active in the client hacking scene there
- Earned Java Guru cup
- Earned Community Member status (equivalent to SRL Members)
- Developed Arcanum bot alongside Ollie and a couple others
- Developed Avenger bot with vbcoderx
- Developed the first Reflection Explorer for rs2
- Maintained (and still do) ~140 hook updater
- Wrote many many tutorials on updater and bot creation
- Started my own site geared entirely to client hacking (rsmonkey - since dismantled as I didn't want to pay server upkeep)
- Quit for 5-6 years
- Came back, saw that scene was shit, MITB merged with Moparscape etc
- Joined villavu as it seemed to be where intelligent people (and people I still remembered) were
- Here we are

So what's on the deck for the future?

Well:

- I've written an RS3 reflection include
- I've solved the issue of multiple gamepacks by building a server hosted updater
- I've already "hooked" all sorts of things for the NXT client, because Java will die. Of course my hooks (err - memory pointer offsets) are based on their first beta release and will change, but I have studied and gained a very thorough understanding of the new client

The first two I initially planned on releasing anytime (well - releasing access to the update server, not source code), but honestly I don't even think I'm going to. I have little to no interest in doing anything for this site or it's members anymore.

Literally the only people who seem to have a good head on their shoulders here are the ogl devs. They're the only people I actually enjoy talking to outside of these forums, and the only people I have been sharing my recent projects with. Then you have people like TSN; saying they're the plague. Its hilarious.

Cheers, likely will be my last post on these boards.

EDIT:

Don't be an idiot.
The facade is a static reference only for the local player

Never afraid to admit when I've made a mistake. Checked again, and you are correct. My mistake.

Kyle
02-24-2016, 03:48 PM
EDIT:


Never afraid to admit when I've made a mistake. Checked again, and you are correct. My mistake.

That confuses me.. You had claimed you have it all hooked on your updater and it works for other players, now you say it doesn't. That implies that you don't have anything hooked and/or you just don't know what fields and methods do what?

Kasi
02-24-2016, 03:52 PM
IMO, it doesn't make sense that all players are passed to the client for reflection to hook. Maybe the players around you, but definitely not all players.

the bank
02-24-2016, 04:08 PM
IMO, it doesn't make sense that all players are passed to the client for reflection to hook. Maybe the players around you, but definitely not all players.

No of course not, only the current loaded players which can be accessed via a static Player[]. However, despite what I said earlier, playerFacade is a static field separate from the Player object that is only representative of the current player.


That confuses me.. You had claimed you have it all hooked on your updater and it works for other players, now you say it doesn't. That implies that you don't have anything hooked and/or you just don't know what fields and methods do what?

My mistake was giving an answer based solely from briefly looking at my updater output, and not actually referencing the client. I've gone ahead and PM'd you a copy of my latest rs3 updater log. If you require any more "proof" feel free to PM me back any gamepack you want and I will send you back the log for it.

Ross
02-24-2016, 05:39 PM
-snip-

I think it's okay to disagree with someone or for someone to be wrong, but maybe calling someone an idiot (for being wrong or less educated than you on a certain topic) sends a discussion in the wrong direction.

There are many, many good people here. Even TSN; used to be someone I really looked up to- and tbh it actually stung seeing his attitude towards this community since I really do feel like I'm a part (albeit small compared to what others have contributed) of this community. His comments just feel so personal.

Don't leave, just ignore the hostility and appreciate that some people take offense to things. When you contribute, there is a majority of people that will enjoy and appreciate it and then a vocal minority that may not. There are some people that hold grudges against those that don't deserve it. I know I was really looking forward to everything you were working on, so it would be sad to see you walk away.

Kyle
02-24-2016, 07:59 PM
My mistake was giving an answer based solely from briefly looking at my updater output, and not actually referencing the client. I've gone ahead and PM'd you a copy of my latest rs3 updater log. If you require any more "proof" feel free to PM me back any gamepack you want and I will send you back the log for it.

Ahh, so my latter presumption was correct.

Flight
02-28-2016, 03:03 PM
Flight maybe implement this into AL?

AeroLib has such a function inside of Highscores.simba (misc/connection/).

function getPlayerXP(Name: String; Skill: Integer): Integer;

Laquisha
02-29-2016, 06:00 AM
Wow, this thread escalated quickly.

Here we have another example of someone not liking someone else because they are potentially smarter than themselves. Although, it’s not just about being smart, it’s the fact that they display it in a condescending and arrogant way. There are people on these forums smarter than all of you guys on this thread combined, but they are well versed in modesty. We know the bank; has been around a while and has developed a few bots; he never misses a chance to let the whole world know these ‘credentials’. There is no doubt he has some skills, but he could put those skills to better use by helping others rather than putting them down. That’s not to say others are not at fault here. Some ‘high up’ people these forums attacked the shi*t out of the bank on this thread for something quite silly. The community’s loss I guess.

Harrier
02-29-2016, 07:27 AM
Wow, this thread escalated quickly.

Here we have another example of someone not liking someone else because they are potentially smarter than themselves. Although, it’s not just about being smart, it’s the fact that they display it in a condescending and arrogant way. There are people on these forums smarter than all of you guys on this thread combined, but they are well versed in modesty. We know the bank; has been around a while and has developed a few bots; he never misses a chance to let the whole world know these ‘credentials’. There is no doubt he has some skills, but he could put those skills to better use by helping others rather than putting them down. That’s not to say others are not at fault here. Some ‘high up’ people these forums attacked the shi*t out of the bank on this thread for something quite silly. The community’s loss I guess.
You have to remember some posts were edited to remove foul language and somewhere not.