GetIdByName userfunction (GetQuest, Skill And Buff Id)
Forum rules
Only post additional bot resources here. Please do not ask unrelated questions.
Only post additional bot resources here. Please do not ask unrelated questions.
GetIdByName userfunction (GetQuest, Skill And Buff Id)
So here's a userfunction I made. Only tested it for a bit so this is a beta release. It didn't crash client though and seems like the functions are doing what they're supposed to do.
EDIT: released v1.2 beta, it's now a lot faster than before because the search method has been changed.
Common in all functions:
- Search string is not case-sensitive.
- All functions print results as they are found in table format.
- All functions return values. If only a single match is found, it only returns the id (or system text if you're using GetSysText). If nothing is found, it returns false.
Syntax:
Limits are the Search Range limits
Exact Match can only be true or false, it defaults to true which means only exact matches will be processed, put false to process partial matches. Putting nothing or nil in the exact match argument will default to true.
GetIdByName(search string, exact match, first lower limit, first upper limit, second lower limit, second upper limit)
- By default, it has no range limits so it searches the whole range but it is limited to only process stuff that has Sys(digits)_name as their system text.
Examples:
GetIdByName("dragon") -- will not find any match, there's plenty of dragons in game but there's not one that has only the name dragon.
GetIdByName("dragon", false) -- finds 593 matches.
GetIdByName("dragon", false, 100000, 120000) -- matches found cut to 58 as the range has been cut down considerably.
GetIdByName("dragon", false, 100000, 120000, 230000, 300000) -- matches found back up to 121 with the added search range.
GetQuestId(search string, quest type filter, exact match, first lower limit, first upper limit, second lower limit, second upper limit)
- Quest type argument should be either "normal", "daily" or "public". Anything other than those will default to "all", in which case the bot will return every quest type.
- Prints matches in table format. The table includes the Level and the Type apart from the Name and Id.
- By default, it only processes ids between 420000 and 430000 coz that's where quests are, but you can override it anytime through the function's arguments. You can change the default values (420000 - 430000) permanently in the user options section of the file.
Examples:
GetQuestId("juice") -- will not find any match
GetQuestId("juice delivery") -- prints and returns the id 422917
GetQuestId("juice", nil, false) -- nil defaults to "all" and we only searched for partial match. Will return 5 matches displaying all quest types and all quests with juice in its name.
GetQuestId("juice", "daily", false) -- matches found cut to 1 as there is only 1 quest that has juice in its name and is a daily.
GetSkillId(search string, exact match, first lower limit, first upper limit, second lower limit, second upper limit)
- Prints matches in table format. The table includes the CastTime and the Range apart from the Name and Id.
- By default, it only processes ids between 490000 and 499999 coz (I think) that's where all the skills are, but you can override it anytime through the function's arguments. You can also change the default values (490000 - 499999) permanently in the user options section of the file.
For Examples, see GetIdByName, this function is exactly like GetIdByName except that it has a built-in range filter.
GetBuffId(search string, exact match, first lower limit, first upper limit, second lower limit, second upper limit)
- By default, it only processes ids in two ranges between 500000 and 500999 and 620000 and 630000 coz (I think) that's where all the buffs are, but you can override it anytime through the function's arguments. You can also change the default values permanently in the user options section of the file.
Same as GetSkillId. For Examples, see GetIdByName, this function is exactly like GetIdByName except that it has a built-in range filter.
GetSysText(search string, exact match)
- This is essentially the most powerful search, it has no limitations whatsoever so it processes every text it can read. This means you can also use GetSysText to search for skills, quests, buffs etc.
Examples:
GetSysText("regional event") -- will not find any match
GetSysText("regional event", false) -- finds 5 matches
GetSysText("regional event now restarting") -- no matches as it is missing a "!" to be exact
GetSysText("regional event now restarting", false) -- prints and returns SC_ZONE_PE_3TH_ST1START
GetSysText("regional event now restarting!") -- prints and returns SC_ZONE_PE_3TH_ST1START
EDIT: released v1.2 beta, it's now a lot faster than before because the search method has been changed.
Common in all functions:
- Search string is not case-sensitive.
- All functions print results as they are found in table format.
- All functions return values. If only a single match is found, it only returns the id (or system text if you're using GetSysText). If nothing is found, it returns false.
Syntax:
Limits are the Search Range limits
Exact Match can only be true or false, it defaults to true which means only exact matches will be processed, put false to process partial matches. Putting nothing or nil in the exact match argument will default to true.
GetIdByName(search string, exact match, first lower limit, first upper limit, second lower limit, second upper limit)
- By default, it has no range limits so it searches the whole range but it is limited to only process stuff that has Sys(digits)_name as their system text.
Examples:
GetIdByName("dragon") -- will not find any match, there's plenty of dragons in game but there's not one that has only the name dragon.
GetIdByName("dragon", false) -- finds 593 matches.
GetIdByName("dragon", false, 100000, 120000) -- matches found cut to 58 as the range has been cut down considerably.
GetIdByName("dragon", false, 100000, 120000, 230000, 300000) -- matches found back up to 121 with the added search range.
GetQuestId(search string, quest type filter, exact match, first lower limit, first upper limit, second lower limit, second upper limit)
- Quest type argument should be either "normal", "daily" or "public". Anything other than those will default to "all", in which case the bot will return every quest type.
- Prints matches in table format. The table includes the Level and the Type apart from the Name and Id.
- By default, it only processes ids between 420000 and 430000 coz that's where quests are, but you can override it anytime through the function's arguments. You can change the default values (420000 - 430000) permanently in the user options section of the file.
Examples:
GetQuestId("juice") -- will not find any match
GetQuestId("juice delivery") -- prints and returns the id 422917
GetQuestId("juice", nil, false) -- nil defaults to "all" and we only searched for partial match. Will return 5 matches displaying all quest types and all quests with juice in its name.
GetQuestId("juice", "daily", false) -- matches found cut to 1 as there is only 1 quest that has juice in its name and is a daily.
GetSkillId(search string, exact match, first lower limit, first upper limit, second lower limit, second upper limit)
- Prints matches in table format. The table includes the CastTime and the Range apart from the Name and Id.
- By default, it only processes ids between 490000 and 499999 coz (I think) that's where all the skills are, but you can override it anytime through the function's arguments. You can also change the default values (490000 - 499999) permanently in the user options section of the file.
For Examples, see GetIdByName, this function is exactly like GetIdByName except that it has a built-in range filter.
GetBuffId(search string, exact match, first lower limit, first upper limit, second lower limit, second upper limit)
- By default, it only processes ids in two ranges between 500000 and 500999 and 620000 and 630000 coz (I think) that's where all the buffs are, but you can override it anytime through the function's arguments. You can also change the default values permanently in the user options section of the file.
Same as GetSkillId. For Examples, see GetIdByName, this function is exactly like GetIdByName except that it has a built-in range filter.
GetSysText(search string, exact match)
- This is essentially the most powerful search, it has no limitations whatsoever so it processes every text it can read. This means you can also use GetSysText to search for skills, quests, buffs etc.
Examples:
GetSysText("regional event") -- will not find any match
GetSysText("regional event", false) -- finds 5 matches
GetSysText("regional event now restarting") -- no matches as it is missing a "!" to be exact
GetSysText("regional event now restarting", false) -- prints and returns SC_ZONE_PE_3TH_ST1START
GetSysText("regional event now restarting!") -- prints and returns SC_ZONE_PE_3TH_ST1START
Last edited by kenzu38 on Thu Oct 22, 2015 4:20 pm, edited 3 times in total.
Re: GetIdByName and GetQuestId userfunction
Haven't tried it but I do have a question, why have a table returned if more than 1 result but a single string if only 1 result, I ask because of how people will use it.
example.
If for some reason there is only 1 result the table.print won't work
on the other side of the coin if you assume it was a string and it was a table you get
So in order to not get errors people would need to check what type id is before trying to use it.
example.
Code: Select all
local id = GetIdByName("chill",620000,621000,false) table.print(id)
Code: Select all
Command> local id = "sometest" table.print(id)
onLoad error: [string "local id = "sometest" table.print(id)"]:1: Argument 1 passed to table.print() must be a table.
Code: Select all
Command> local id = {"sometest","someothertest"} print(id)
table: 02520EC8
Remember no matter you do in life to always have a little fun while you are at it ![Wink ;)](./images/smilies/icon_e_wink.gif)
wiki here http://www.solarstrike.net/wiki/index.php?title=Manual
![Wink ;)](./images/smilies/icon_e_wink.gif)
wiki here http://www.solarstrike.net/wiki/index.php?title=Manual
Re: GetIdByName and GetQuestId userfunction
So if a user doesn't know what range to check and checks the whole range, how long does it take ion average to run?
- Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
- I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
- How to: copy and paste in micromacro
________________________
Quote:- “They say hard work never hurt anybody, but I figure, why take the chance.”
- Ronald Reagan
Re: GetIdByName and GetQuestId userfunction
Yes they'll just have to type in extra code if they're not sure how many results they will get.lisa wrote:So in order to not get errors people would need to check what type id is before trying to use it.
I wanted to make things inline with the function name so I made it like that. You want to get an id, and id you will get (if there's only one result).
Anyway, I made it quickly so I never really had a lot of time to think things through. Now, though, I think people who will be using this will not put this in a WP most likely. And so the return values will probably never be used. But I still wanna make it return values so I will keep that functionality.
What I will add are prints as the function gets a match. It will print each result as they are found.
I also have some time right now to search for known ranges of buff ids and skill ids. I plan on adding GetSkillId and GetBuffId as well.
When I finish the new version, I will also explain more clearly a few things I might have missed.
GetQuestId is fast, probably 3 seconds tops. But when I tried the 620000 - 630000 range for buffs, it was slow even if it's only 10k ids like GetQuestId. Didn't really time it but it's probably more than a minute. So, I really need to post some notice on the OP to explain this to potential users.rock5 wrote:So if a user doesn't know what range to check and checks the whole range, how long does it take ion average to run?
Re: GetIdByName and GetQuestId userfunction
You could always do what we have done in the past and return an id as the first argument and a table for all matches in the second argument. Similar to player:findNearestNameOrId.kenzu38 wrote:Yes they'll just have to type in extra code if they're not sure how many results they will get.
I wanted to make things inline with the function name so I made it like that. You want to get an id, and id you will get (if there's only one result).
Hm... I wonder if it's possible to search in memory directly for the string and return the matching id. All you would have to do is search for the string in the text string range, find the matching the previous matching string which should be in the form of Sys123456_name, extract the id and return it. If that could work then it would be nearly as fast as GetIdName.kenzu38 wrote:GetQuestId is fast, probably 3 seconds tops. But when I tried the 620000 - 630000 range for buffs, it was slow even if it's only 10k ids like GetQuestId. Didn't really time it but it's probably more than a minute. So, I really need to post some notice on the OP to explain this to potential users.
If it can be done like that why haven't I added it in the past you might ask. I think it's because there is no need in a botting script for a GetNameId function. You could for instance use the function with the commandline script to get an id but then you would use the id in your waypoint files, you wouldn't use the function itself. You can get thing ids other ways so there wasn't really a need for that function. For instance you can use my ToolipIds addon. You could use the fdb extractor and language viewer. You could search in memory using Cheat Engine. It doesn't hurt to have another way to get the id but if it's going to take so long then it's not really useful if there are other faster ways.
- Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
- I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
- How to: copy and paste in micromacro
________________________
Quote:- “They say hard work never hurt anybody, but I figure, why take the chance.”
- Ronald Reagan
Re: GetIdByName and GetQuestId userfunction
Yea, I suppose I could do this. But I don't see the point now that I have added prints every time it finds a match.rock5 wrote:You could always do what we have done in the past and return an id as the first argument and a table for all matches in the second argument. Similar to player:findNearestNameOrId.
I don't fiddle with memory that much. Didn't even know there was a place in memory these strings are bundled together. I looked it up now with CE, and yea I suppose this will be quick if it somehow works. Problem I see in this though is if the clusters change addresses when there's a new patch. Then the function will need some maintenance work.rock5 wrote:Hm... I wonder if it's possible to search in memory directly for the string and return the matching id. All you would have to do is search for the string in the text string range, find the matching the previous matching string which should be in the form of Sys123456_name, extract the id and return it. If that could work then it would be nearly as fast as GetIdName.
Yea, I'm aware how people will be using the function. Like I said earlier:rock5 wrote:If it can be done like that why haven't I added it in the past you might ask. I think it's because there is no need in a botting script for a GetNameId function. You could for instance use the function with the commandline script to get an id but then you would use the id in your waypoint files, you wouldn't use the function itself.
Anyway, I made it quickly so I never really had a lot of time to think things through. Now, though, I think people who will be using this will not put this in a WP most likely.
GetIdByName is something I added after I completed GetQuestId and saw that it worked well. It was added just for its functionality and not for its efficiency. I myself just treat it as novelty. I wouldn't exclude it from the userfunction though since it's ready-made code and it's always good to have some ready-made codes however rarely you might need them.rock5 wrote:You can get thing ids other ways so there wasn't really a need for that function. For instance you can use my ToolipIds addon. You could use the fdb extractor and language viewer. You could search in memory using Cheat Engine. It doesn't hurt to have another way to get the id but if it's going to take so long then it's not really useful if there are other faster ways.
And as for GetQuestId, I think it's useful in some cases, that's why I took the time to code it. You'll have to meet the condition that you know at least a substantial part of the name though.
I think the tooltips addon is the best choice but with the addon, I think you'll have to mouse over the quest, so it's either you have to have the quest in the questbook or be near the NPC who gives it. But it's not always the case, and I think that is when GetQuestId steps in as the best alternative out of the methods you mentioned.
With CE and Language viewer, you won't always know right away which is the exact quest you're looking for since plenty of quests have the same names. But with GetQuestId's filter, that's not the case.
Anyway, I said earlier that I was planning to add GetSkillId and GetBuffId. Well, I finished coding it but decided to exclude GetSkillId since it was really slow. GetBuffId though is tolerable with just over a minute of waiting before you get the Id. Not the most efficient really, but once everything is substantiated in memory, the succeeding searches get a lot faster. So I'll release it for now since it's already been done. But I might redo it soon when I find a faster way of searching.
Re: GetIdByName and GetQuestId userfunction
No, not really. It would use the same addresses that getTEXT function uses so the address will always be correct (unless that patch is so radical that it breaks update.lua).kenzu38 wrote:I looked it up now with CE, and yea I suppose this will be quick if it somehow works. Problem I see in this though is if the clusters change addresses when there's a new patch. Then the function will need some maintenance work.
My favourite method is using the language viewer because it's the quickest to start up. I rarely start up the game these days. But you are correct, you can't tell which quest with the same name is the public/daily/normal quest so yours could be useful in that case.kenzu38 wrote:I think the tooltips addon is the best choice but with the addon, I think you'll have to mouse over the quest, so it's either you have to have the quest in the questbook or be near the NPC who gives it. But it's not always the case, and I think that is when GetQuestId steps in as the best alternative out of the methods you mentioned.
With CE and Language viewer, you won't always know right away which is the exact quest you're looking for since plenty of quests have the same names. But with GetQuestId's filter, that's not the case.
- Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
- I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
- How to: copy and paste in micromacro
________________________
Quote:- “They say hard work never hurt anybody, but I figure, why take the chance.”
- Ronald Reagan
Re: GetIdByName and GetQuestId userfunction
I got the urge to fiddle a bit so I copy and pasted some code, made a few modifications and came up with the following.
As I was coding it I realized that the function can be used to find any key string, not just ids. So I made 2 functions. startId and endId are optional if you want to specify a range.
printTEXTKeys(text) prints the key strings for any text and
printNameIds(text, startId, endId) prints the ids that match the text.
The limitations of these functions is that they are case sensitive although I've included the ability to use ? as a wildcard.
Example usage:
I'm not sure what you would want to do with it.
Code: Select all
local function collectKeys(text)
-- local function to find start of string byt finding the null before the string
local function findLastNull(address)
while memoryReadByte(getProc(), address) ~= 0 do
address = address - 1
end
return address
end
-- Start and end address of the text strings
local addressPtrsBase = memoryReadInt(getProc(), addresses.getTEXT)
local startloc = memoryReadInt(getProc(), addressPtrsBase + 0x268)
local endloc = memoryReadInt(getProc(), addressPtrsBase + 0x26C)
local searchlen = endloc - startloc
-- The pattern and mask. ? wild cards are supported.
local pattern = text
local mask = text:gsub("[^?]","x")
-- Search for all matches
local results={}
local searchloc = startloc
while searchloc < endloc do
local found = findPatternInProcess(getProc(), pattern, mask, searchloc, searchlen);
if found == 0 then
break
end
-- Search back for start of string
local textStartAddress = findLastNull(found)
if textStartAddress == nil then -- not found
break
end
-- Read full string
local tmpText = memoryReadString(getProc(), textStartAddress+1)
-- Search back for matching key string
local keyStartAddress = findLastNull(textStartAddress-1)
if keyStartAddress < startloc then -- The very first key isn't preceded by a null
keyStartAddress = startloc-1
end
-- Read key string
local tmpKey = memoryReadString(getProc(), keyStartAddress+1)
-- Print and add to results
table.insert(results,{Key=tmpKey, Name=tmpText})
-- Continue searching for more results
searchloc = textStartAddress+ #tmpText + 2
searchlen = endloc - searchloc
end
return results
end
function printTEXTKeys(text)
local results = collectKeys(text)
for i,v in pairs(results) do
print(v.Key, v.Name)
end
end
function printNameIds(text, startId, endId)
local results = collectKeys(text)
for i,v in pairs(results) do
local id = v.Key:match("^Sys(%d%d%d%d%d%d)_name$")
if id then id=tonumber(id) end
if id and (startId == nil or id >= startId) and (endId == nil or id <= endId) then
print(id,v.Name)
end
end
end
printTEXTKeys(text) prints the key strings for any text and
printNameIds(text, startId, endId) prints the ids that match the text.
The limitations of these functions is that they are case sensitive although I've included the ability to use ? as a wildcard.
Example usage:
Code: Select all
Command> printTEXTKeys("Regional event has ended")
SC_ZONE_PE_3TH_FAIL Regional event has ended.
SC_ZONE_PE_3TH_ST1OVER Regional event has ended successfully!
Command> printNameIds("wrapped Belt")
221544 Gold-wrapped Belt
- Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
- I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
- How to: copy and paste in micromacro
________________________
Quote:- “They say hard work never hurt anybody, but I figure, why take the chance.”
- Ronald Reagan
Re: GetIdByName and GetQuestId userfunction
Very nice. So, do you plan to release or integrate that to the bot?
Anyway, I think I'm gonna mess around with that local function, that's just what I needed for the GetSkillId I was planning to make.
Oh and btw, speaking of skills, I was looking at addresses.lua and I saw something that could be useful for my function but I haven't seen it get used anywhere else so I have no idea how to use it.
It's the SkillClass offset. First of all, is it the class that can use the said skill? If so, what's the data type you're looking for in memory and what are the expected values and the meaning of those values?
Anyway, I think I'm gonna mess around with that local function, that's just what I needed for the GetSkillId I was planning to make.
Oh and btw, speaking of skills, I was looking at addresses.lua and I saw something that could be useful for my function but I haven't seen it get used anywhere else so I have no idea how to use it.
It's the SkillClass offset. First of all, is it the class that can use the said skill? If so, what's the data type you're looking for in memory and what are the expected values and the meaning of those values?
Re: GetIdByName and GetQuestId userfunction
Because it's not used while botting I think I wont add it to the bot. Feel free to integrate it into your userfunction.kenzu38 wrote:Very nice. So, do you plan to release or integrate that to the bot?
Seeing as it's not used by the bot it's probably just some old obsolete value. I couldn't hazard a guess how it was used if at all. I tried looking in the repository log for any mention of it but couldn't find it.kenzu38 wrote:Oh and btw, speaking of skills, I was looking at addresses.lua and I saw something that could be useful for my function but I haven't seen it get used anywhere else so I have no idea how to use it.
It's the SkillClass offset. First of all, is it the class that can use the said skill? If so, what's the data type you're looking for in memory and what are the expected values and the meaning of those values?
- Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
- I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
- How to: copy and paste in micromacro
________________________
Quote:- “They say hard work never hurt anybody, but I figure, why take the chance.”
- Ronald Reagan
Re: GetIdByName and GetQuestId userfunction
Alright, thanks for the codes then. I'll help myself to them. I have an idea how to improve them a bit. That'll have to wait though, I'm busy right now with polishing some scripts I intend to release later.
Re: GetIdByName and GetQuestId userfunction
Alright, finally got some free time today so I had the time to work on this. It's now a lot faster thanks to rock's code. I made it case-insensitive by automatically subbing the first letters to ?. Not sure it will work on 100% of the text but I think it will probably work 99% of the time.
Who is online
Users browsing this forum: No registered users and 4 guests