Sign in to follow this  
Followers 0
huldu

String issues

49 posts in this topic

I ran into a problem extracting a value from a string. The string is this:

[23:30:10] You attack aimless boogey with your staff and hit for 69 (-12) damage!

Ive tried various ways to get the "69 (-12)" part out of that string and failed. I know it isnt that hard but however i do it i get it wrong.

Im trying to make a log parser if anyone was wondering. Theres alot more "different" lines but if one can figure out how to extract information from a string, it should be piece of cake with the rest. I looked thru code on another parser a long time ago and it had a totally different approack to the problem (it wasnt made in autoit). It just did a "complete scan" for something like this: You attack $monster with your $weapon and hit for $damage damage!. This was probably all wrong lol, but it was something like that... think it was made in C++. Gonna see if i can find it and post the "code" from it later.


"I'm paper, rock is fine, nerf scissors!!!"

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Found one but wasnt the one i were looking for but it worked in a similar way. Its a .pl file, <edit> just found out its a perl file </edit>. Took a snip from it to show how it worked:

#[20:02:11] The pixie imp dies!
    if (/ (?:The |An? )?(.+) dies!/){
        $stats{"monster_tot"}++;
        $dead_mobs{$1}++;

Looks kinda weird, but its not possible to do something like that in autoit?

Edited by huldu

"I'm paper, rock is fine, nerf scissors!!!"

Share this post


Link to post
Share on other sites

It's all about looking for special characters. Like if you know you are always looking for something that has the (##) in it then you can use something like the below code. You may have to put some aditional spaces or checking incase the Hit damage is over 100 then you'll have to grab one more diget and strip it out if its not a number.

$String = "[23:30:10] You attack aimless boogey with your staff and hit for 69 (-12) damage!"

$specChr = StringInStr($String, "(")
$endChr = StringInStr($String, ")")
if $specChr <> 0 Then
    $retrieve = StringMid($String, $specChr - 4, ($endChr + 1) - ($specChr - 4))
EndIf
MsgBox(0, "retrieved", $retrieve)

Share this post


Link to post
Share on other sites

Mikes is much more realistic, but you can only have 4 characters for the numbers...

I played around with it a bit... the code can be much better but this allows you to have as many 'number characters' as there is.

I may have time to simplify it later, but all in all... Mike is right, you have to look for the common 'unique' character there is that seperates the string.

#include <file.au3>
Local $Path = @DesktopDir & '\WordArray.txt'
Local $nArray = ''
_FileReadToArray($Path, $nArray)

$sString = GetMyExtraction($nArray)

For $i = 1 To UBound($sString) - 1
    MsgBox(0, 'Example', $sString[$i])
Next

Func GetMyExtraction(ByRef $aArray)
    Local $sLen = ''
    Local $sMid = ''
    Local $sMid2 = ''
    Local $ReturnString = ''
    Local $ExitCount = ''
    For $i = 1 To UBound($aArray) - 1
        $ExitCount = ''
        $sLen = StringLen($aArray[$i])
        For $x = 1 To $sLen
            $sMid = StringMid($aArray[$i], $x, 1)
            If $sMid = '[' Then
                Do
                    $x = $x + 1
                Until StringMid($aArray[$i], $x, 1) = ']'
            EndIf
            If StringIsDigit($sMid) Then
                For $y = $x To StringLen($aArray[$i])
                    $sMid2 = StringMid($aArray[$i], $y, 1)
                    Do
                        $y = $y + 1
                    Until StringMid($aArray[$i], $y, 1) = ')'
                    $ReturnString = $ReturnString & StringMid($aArray[$i], $x - StringLen($sMid2), $y - $x + 2) & Chr(01)
                    $ExitCount = 1
                    ExitLoop
                Next
            EndIf
            If $ExitCount = 1 Then ExitLoop
        Next
    Next
    Return StringSplit(StringTrimRight($ReturnString, 1), Chr(01))
EndFunc

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

I took a different approach to this making the assumption that the words "hit for" and damage!" surround the numbers you are trying to find. If that is not the case then simply ignore this effort

$parse1=StringSplit ($logline,"hit for",1)
$parse2=StringSplit($parse1[2],"damage!",1)
MsgBox(1,"points",$parse2[1])
Edited by SlimJim

Share this post


Link to post
Share on other sites

SmOke_N's code is great, but its really big hehe :o

The number can be anything from a single number to a four numbers (0-9999) like. Im looking into smoke's code to see if i can change it to accept other inputs aswell. I didnt think it would be so hard just to do something like this, guess i was wrong :geek:

Just so you get an idea what im trying to do (bit more examples):

[23:30:10]You perform your Figure Eight perfectly. (+31)

In the above line im taking out the (+31) - ie as in the game called "style damage"

[23:30:10] You attack aimless boogey with your staff and hit for 69 (-12) damage!

Code works great on this sofar, thanks!

[23:30:10] You prepare to perform a Double Strike!

This line isnt very important, so im probably gonna skip it.

[23:30:17] aimless boogey attacks you and you parry the blow!

Here im looking for the "you parry" part.

[23:30:17] You miss!

This where i look for the "You miss!"

[23:30:20] aimless boogey attacks you and you evade the blow!

Pretty much the same as the parry, just that im looking for the "you evade"

[23:30:24] aimless boogey attacks you and misses!

This is a bit more complicated i guess, because the goal is to get the monster doing the attack and that it missed.

[23:30:27] You critical hit for an additional 27 damage!

This part is kinda complicated, because "additnional" appears from different stuff in the game. Gonna need to use the whole line i guess to get the "27" part.

[23:30:36] You heal yourself for 37 hit points.

Im taking out the "37" part here, "heal yourself for " i guess.

[23:30:42] aimless boogey dies!

This im not too sure about, would haveto look for the " dies!" and save the "name" as a variable.

[23:30:42] You get 3,120,957 experience points. (1,040,319 instance bonus)

This looks a bit more complicated, here im looking for the amount of experiance recieved and the bonus experiance. In the game this can be, as we see above "instance" or "camp".

[23:30:42] You pick up 34 silver, and 9 copper pieces.

To be honest im not sure what to do here. The line "You pick up " is used when you pick up loot aswell. The cash dropped is in platina, silver and copper however. Maybe look for the "pieces." part but this was rather tricky.

[23:30:42] You deposit 69 copper pieces in your guild bank.

Not that interesting at the moment.

[23:30:42] aimless boogey drops a bag of coins, which you pick up.

Actually when looking at this line, the above (cash one) was probably unique. This is used when picking up loot. "bag of coins" would be something else, can be pretty much anything tho. Im probably gonna skip this out, its not really needed and a bit complicated.

[23:30:57] boogey runt attacks you and misses!

Here im looking at what monster attacks and that he misses, "attacks you and misses!".

[23:31:08] boogey runt hits your torso for 51 (-18) damage!

The same as above, but looking at a few more things. The "torso" im probably gonna skip out because this changes depending on where on the body the monster hits. Im probably just gonna go for the damage.

And thats it. Hopefully when i get this program working i can parse logs from the game ;) . My actual goal is to do this while in the game, and have the program "inform" me during the season, how many monsters ive killed, total dmg done, highest dmg done, cash collected, experiance gained etc.

Thanks for all the help btw :sorcerer:

If anyone can fill me up with more info about "string" manipulation id be very happy to hear about it!


"I'm paper, rock is fine, nerf scissors!!!"

Share this post


Link to post
Share on other sites

SmOke_N's code is great, but its really big hehe :o

The number can be anything from a single number to a four numbers (0-9999) like. Im looking into smoke's code to see if i can change it to accept other inputs aswell. I didnt think it would be so hard just to do something like this, guess i was wrong :geek:

Just so you get an idea what im trying to do (bit more examples):

And thats it. Hopefully when i get this program working i can parse logs from the game ;) . My actual goal is to do this while in the game, and have the program "inform" me during the season, how many monsters ive killed, total dmg done, highest dmg done, cash collected, experiance gained etc.

Thanks for all the help btw :sorcerer:

If anyone can fill me up with more info about "string" manipulation id be very happy to hear about it!

if you know pretty much all the lines you want to capture and since they are so different, I guess you should make a big Case statement and depending upon what line is displayed then parse and record the line as you see fit.


Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

You only want this type of return 69 (-12) right?

I mean all the other lines mean nothing to you? (I don't play these type of games so I guess I'm not understanding right)

Edit:

Ok, I tested this with a loop to make it interactive and times changing to make sure it only got the most current string like 69 (-12) or 1540 (-19) etc... Obviously you wouldn't use the loop, but hopefully you can see you just need the file path that it will be reading. At first, if you have more than one string like what your looking for, you'll get a multiple response, if it doesn't find a new time, it will return a blank string, if the time is new, and the string is there, it will return that string... you can manipulate it as you want

#include <file.au3>
Global $LastTimeChecked = ''
Local $Path = @DesktopDir & '\WordArray.txt'

$Timer = TimerInit()
While 1
    If TimerDiff($Timer) / 1000 >= 2 Then
        $sString = GetMyExtraction($Path)
        For $i = 1 To UBound($sString) - 1
            MsgBox(0, 'Example', $sString[$i])
        Next
        $Timer = TimerInit()
    EndIf
    Sleep(100)
WEnd

Func GetMyExtraction($sFilePath)
    Local $aArray = ''
    _FileReadToArray($sFilePath, $aArray)
    Local $ReturnString = ''
    Local $TestTime = ''
    For $i = 1 To UBound($aArray) - 1
        $TestTime = StringMid($aArray[$i], StringInStr($aArray[$i], '[') + 1, StringInStr($aArray[$i], ']') - StringInStr($aArray[$i], '[') + 1)
        If $TestTime > $LastTimeChecked Then 
            $LastTimeChecked = $TestTime
            If StringInStr($aArray[$i], '(-') Then
                $ExitCount = ''
                Local $sString = StringTrimLeft($aArray[$i], StringInStr($aArray[$i], ']') - StringInStr($aArray[$i], '[') + 1)
                Local $sLen = StringLen($sString)
                For $x = 1 To $sLen
                    Local $sMid = StringMid($sString, $x, 1)
                    If StringIsDigit($sMid) Then
                        For $y = $x To StringLen($sString)
                            Local $sMid2 = StringMid($sString, $y, 1)
                            Do
                                $y = $y + 1
                            Until StringMid($sString, $y, 1) = ')'
                            $ReturnString = $ReturnString & StringMid($sString, $x - StringLen($sMid2), $y - $x + 2) & Chr(01)
                            $ExitCount = 1
                            ExitLoop
                        Next
                    EndIf
                    If $ExitCount = 1 Then ExitLoop
                Next
            EndIf
        EndIf
    Next
    Return StringSplit(StringTrimRight($ReturnString, 1), Chr(01))
EndFunc
Edited by SmOke_N

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Thank you for your help smoke!

I am actually looking for _all_ the lines i posted above. Im looking into your script to see how i can change it to accept other inputs, rather then just look for XX(-XX). Most likely i will remove the (-XX) part, as this part can change aswell, but its not that important to see how big the resists were at this time.

Im just a bit overrun by the sheer size of the script you posted, i was kinda expecting something alot more easier to understand :o. But im going thru your script to see what it does and when it does what.

Im probably gonna start off really easy and save the damage for later. I will try to rework some stuff in your script and make it read these lines:

[23:30:42]You get 3,120,957 experience points. (1,040,319 instance bonus)

To get the Experiance after "You get ", should be piece of cake i hope. I will look thru my logs to see if "You get " pops up anywhere else beside getting the experiance.

[23:38:38] You have completed your task and earn 41,612,760 experience!

This one im also looking into, but this is much easier since the line is always the same, tho the experiance changes of course.

Smoke, is there any way to "simplify" your script to make it.. more simple? :geek: Edited by huldu

"I'm paper, rock is fine, nerf scissors!!!"

Share this post


Link to post
Share on other sites

Thank you for your help smoke!

I am actually looking for _all_ the lines i posted above. Im looking into your script to see how i can change it to accept other inputs, rather then just look for XX(-XX). Most likely i will remove the (-XX) part, as this part can change aswell, but its not that important to see how big the resists were at this time.

Im just a bit overrun by the sheer size of the script you posted, i was kinda expecting something alot more easier to understand :geek:. But im going thru your script to see what it does and when it does what.

Im probably gonna start off really easy and save the damage for later. I will try to rework some stuff in your script and make it read these lines:

Smoke, is there any way to "simplify" your script to make it.. more simple? ;)

I'm 99.9% sure there is... but the question is ... am "I" going to do it? :o

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Its really tough going thru your script line by line to see what it actually does, alot of the stuff that you use i have no idea what it actually does :o

Up until here:

$TestTime = StringMid($aArray[$i], StringInStr($aArray[$i], '[') + 1, StringInStr($aArray[$i], ']') - StringInStr($aArray[$i], '[') + 1)

You check the first part of the string the [ ] for the "time", i assume.

After this it gets a bit more complicated!

If StringInStr($aArray[$i], '(-') Then
                $ExitCount = ''
                Local $sString = StringTrimLeft($aArray[$i], StringInStr($aArray[$i], ']') - StringInStr($aArray[$i], '[') + 1)
                Local $sLen = StringLen($sString)

By the looks of things the script starts looking for the '(-', i tried change this to something else but script does not proceed. Im not sure what the script does after it found the "event" in this case '(-'. Seems it "trims" the string to left and then checks it again? (really complicated!).

The last part of the function you use, i honestly have no idea what it does.

Edited by huldu

"I'm paper, rock is fine, nerf scissors!!!"

Share this post


Link to post
Share on other sites

You know what would be wonderful when your asking for stuff... Being precise on what it is that you want to accomplish.

I wrote the above, ganted it didn't take long, but it took time, but I wrote it of what you specifically asked for, you didn't give a long list like a few post down, and give the End Result that you are wanting to accomplish.

So, If I was asking for help, I would say:

I've got these strings:

'Sally is a blank, but her mother isn't any better'

'John slapped Sally for being a blank, and her mother for letting her be a blank'

'John gave Sallys Mother $10 to be a blank, and made Sally watch her being a blank'

I'm trying to figure out what Sally and Her mother is being, I only need the exact word, and I need to know if John had Money in any of his strings and if he did how much.

So I would need it to show as:

Blank

Blank

$10

Blank

Well then someone would quickly show me a stringsplit() method to achieve the 'Single word' and 'Single Sum'. And I could tweak it from there.

It's a Poor Example really, but it's 4:30 in the morning here, and I'm sure you get the point.


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

I am really sorry smoke i hope you can forgive me :o

When i wrote this topic i only had the "dmg" in mind, but after i posted it i had no idea if the script would be "easy" or complicated.

What the script is suppose to do is to parse a log for various strings and "extract" information from them. Its quite simple "the" idea really :geek:

Like this example:

[01:22:02]You get 4,516,866 experience points. (1,505,622 instance bonus)

But while it looks easy to make something out of that line, it tends to get more complicated when you code something. In the above line for example im looking to extract the amount of experiance gained. In this case that would be 4,516,866. The problem however is that the experiance you get can vary from as low as 1 number (for example 1 experiance) up to several billions of experiance! like (2,000,000,000).

I really appreciate people like yourself that helps people less knowledgeable like myself, without your kind we would be lost in coding! ;)

I thought the code would be the same, no matter what the "string" actually contained, which it doesnt. I thought i could change a few variables in your script to make it look for something else. But it turned out far harder then i expected.

Edited by huldu

"I'm paper, rock is fine, nerf scissors!!!"

Share this post


Link to post
Share on other sites

why not just use stringregexp ?

Cuz I suck at it, and no where as good at as you at it... I wondered when you would poke your head into this post and shed some wisdom!!

And, although that would be a simple solution, I still don't know all the stuff that he/she wants to extract.


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

I am really sorry smoke i hope you can forgive me :geek:

When i wrote this topic i only had the "dmg" in mind, but after i posted it i had no idea if the script would be "easy" or complicated.

What the script is suppose to do is to parse a log for various strings and "extract" information from them. Its quite simple "the" idea really ;)

Like this example:

But while it looks easy to make something out of that line, it tends to get more complicated when you code something. In the above line for example im looking to extract the amount of experiance gained. In this case that would be 4,516,866. The problem however is that the experiance you get can vary from as low as 1 number (for example 1 experiance) up to several billions of experiance! like (2,000,000,000).

I really appreciate people like yourself that helps people less knowledgeable like myself, without your kind we would be lost in coding! :sorcerer:

I thought the code would be the same, no matter what the "string" actually contained, which it doesnt. I thought i could change a few variables in your script to make it look for something else. But it turned out far harder then i expected.

Why don't you give every possible scenerio, and the exact extraction look you would like to achieve. That would help a bit (that was really the point of my post).

Ok, no more post till I see what you want, looks like I'm spamming the damn thing!! :o

Edit:

Dammit... I just noticed that you already did that!, I thought all that was a part of the damn return information you were getting from where ever.

Edited by SmOke_N

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

Ok sorry :o

Ill write exactly what i am looking for below here this time:

[01:22:02]You get 4,516,866 experience points. (1,505,622 instance bonus)

In the above im looking to extract the number of experiance gained. This value should then be saved as a variable (so it can be used to add with, to get a "total" experiance). The number can vary from as low as 1 experiance to several billions experiance, like 2,000,000,000. <EDIT> the (1,505,622 instance bonus) part is irrelevant, as it is already counted into the experiance </EDIT>

[23:38:38] You have completed your task and earn 41,612,760 experience!

In this line im looking to get the experiance aswell, its pretty much the same as experiance above. This value can be as low as 1 or several billions. This would also be saved as a variable to be "added" with another one, to get the "total" experiance gained.

For now this is basicly what i am looking for :geek:. The problem i am having with my limited knowledge is that i only know how to search for a "value" that is the same amout of numbers. If the numbers changed from, for example 1 to 100 my script wouldnt work.

<EDIT> Basicly the entire game log contains "numbers" in strings, i am interested in just extracting the numbers. For easier to understanding i will post the actual .log from the game, gonna decrease it in size tho so you can see how it looks </EDIT>

Edited by huldu

"I'm paper, rock is fine, nerf scissors!!!"

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

<sorry about this got a bit of lag, ignore this post>

Edited by huldu

"I'm paper, rock is fine, nerf scissors!!!"

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

Here is the chatlog (ive zipped it down in size).

The good thing in this game is that the "strings" are always the same, the only thing that actually change is the value. It can be damage, experiance, coin. Otherwise the lines are always the same.

chatlog.zip

Edited by huldu

"I'm paper, rock is fine, nerf scissors!!!"

Share this post


Link to post
Share on other sites

So is the path your thinking of?

$aGAmeArray = StringSplit('You perform your Figure Eight |You attack aimless boogey with your staff and hit for |' & _ 
'aimless boogey attacks you and |You miss!|aimless boogey attacks you and |You critical hit for an additional |' & _ 
'You heal yourself for | dies!| experience points. |You pick up |, which you pick up.| attacks you and misses!| hits your ', '|')

For $i = 1 To UBound($aGAmeArray) - 1
    MsgBox(0, 'Test', $aGAmeArray[$i])
Next
Then match from there?


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0