How do I Retrieve and Parse Dungeon Logs

ElCarrot

New member
In the clan that I am in, we get a lot of people adventuring in the slime tube at various ML. Some at very high ML, some at very low ML. As a result, when mother slime is up, I can't be sure if we managed to keep the turn count under 690. If we did, then I know that I should wear my item find kit when killing mother slime, and maybe add in a couple item find buffs. Otherwise, I should just go ahead and maximize damage to kill Mother Slime.

So what I am looking for is a script that parses the current dungeon logs and figures out how many turns have been spent in the Slime Tube. The alternative is totaling it up manually (Which isn't hard - but annoying).

I've searched the forums for a script that does this and I haven't found one - so I figured I'd write one - but I'm not sure how to properly retrieve the current logs and parse them. So if anyone has any suggestions on how to do this, I could use some help.

Thanks
 

ElCarrot

New member
Thanks - that seems to work fairly well. If anyone knows of a good way to do this in an ASH file so that I can incorporate it into a slime-tube script it would be great.

e.g.
-After killing all slimes, check total turncount, and if turncount is low enough to get bonus items, then get item-find buffs before killing mother slime.

Thanks
 

slyz

Developer
The Mother Slime drops that are triggered by turncount are not affected by bonus item drop. Only the number of slimy alveoli that drop is affected (one for every +50% item drop bonus you have, with a minimum of 1), and those drop no matter what the turncount was.

EDIT: (This item only drops if The Slime Tube is completed in at most 690 turns)
Yay for misreading the wiki!
 
Last edited:

Grotfang

Developer
Sounds like a job for regex! The log messages are the same:

<username> (#<playerId>) defeated a Slime Tube monster x <number>
<username> (#<playerId>) was defeated by a Slime Tube monster x <number>

Mother Slime doesn't count, so add up the figures to grab a turncount.
 

StDoodle

Minion
I actually got that far in a long, convoluted attempt at automating loot distribution. It will take me some work, and probably some time, but I can probably excise the current slime tube info from what I've got.
 

mredge73

Member
Here is a first attempt at parsing the clan logs. The Regex should be close but the data will need some translating.
Here is my test code:

Code:
string ClanRaid= visit_url( "clan_raidlogs.php" );
matcher Raid = create_matcher( "(.+?) \\(#(\\d+)\\) (.+?) (.+?) \\((\\d+) (turns|turn)\\)" , ClanRaid );
print("build matcher");

int I=0;
while( I<5 )
{
Raid.find();
print("find");
I=I+1;
string group1= Raid.group( 1 );
string group2= Raid.group( 2 );
string group3= Raid.group( 3 );
string group4= Raid.group( 4 );
string group5= Raid.group( 5 );
string group6= Raid.group( 6 );

//print(group1,"blue");//name dump
print(group2,"purple");//ID
print(group3,"olive");//action
print(group4,"green");//super action
print(group5,"blue");//turns
//print(group6,"purple");// turn|turns dump
print("");
}
 

mredge73

Member
Here is an excerpt of what I am working on.
@ElCarrot this is what you are looking for, with some editing it can be shrunk down to just a couple of lines and return just the turncount

Code:
REMOVED
It was pretty bad, see fix 2 post down
 
Last edited:

mredge73

Member
I think I fixed my parser.
Should parse loot correctly as well, I accounted for Mother Slime's fights not effecting the turn count.
Try it out and let me know, it is brand new and needs some testing.
The Log is saved as a file in your data folder: "mredge73_RAID.txt"

Code:
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
record RaidEntry
{
    int ID; //ID
    string A;//action
    string EA;//extended action
    int TS;//turns spent
};
RaidEntry [int][int] RaidLog;//logger

//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
void ParseGroup(int Z, string PageData, )
{
    matcher RaidMatch; //Raid Matcher
    int E=1; //Entry Counter
    
    if(Z==9 || Z==11)
        RaidMatch= create_matcher( "(.+?) \\(#(\\d+)\\) distributed <b>(.+?)</b> to (.+?) \\(#(\\d+)\\)" , PageData );
    else
        RaidMatch= create_matcher( "(.+?) \\(#(\\d+)\\) (.+?) (.+?) \\((\\d+) (turns|turn)\\)" , PageData );
        
    while( RaidMatch.find() )
    {
        RaidLog[Z][E].ID=RaidMatch.group( 2 ).to_int();
        RaidLog[Z][E].A=RaidMatch.group( 3 );
        RaidLog[Z][E].EA=RaidMatch.group( 4 );
        RaidLog[Z][E].TS=RaidMatch.group( 5 ).to_int();
        E=E+1;
    }
}

void ParseRaidLogs ()
{    
    matcher Zone; //Zone Matcher
    string PageData; //PageData
    string Hobopolis;//PageData
    string SlimeTube;//PageData
    int Z=1; //Zone Counter    
        
    //capture and split pagedata
    PageData= visit_url( "clan_raidlogs.php" ); //Capture Page
    Zone= create_matcher("<b>Hobopolis:</b>(.+?)<b>The Slime Tube:</b>",PageData);
    if(Zone.find())    Hobopolis=Zone.group(1);
    Zone= create_matcher("<b>The Slime Tube:</b>(.+?)<b>Previous Clan Dungeon Runs:</b>",PageData);
    if(Zone.find())    SlimeTube=Zone.group(1);
        
    while (Z<=11)
    {
        switch (Z)
        {
            case 1:
            Zone= create_matcher( "<b>Exposure Esplanade:</b><blockquote>(.+?)</blockquote>" , Hobopolis ); break;
            case 2:
            Zone= create_matcher( "<b>The Heap:</b><blockquote>(.+?)</blockquote>" , Hobopolis ); break;
            case 3:
            Zone= create_matcher( "<b>Sewers:</b><blockquote>(.+?)</blockquote>" , Hobopolis ); break;
            case 4:
            Zone= create_matcher( "<b>The Ancient Hobo Burial Ground:</b><blockquote>(.+?)</blockquote>" , Hobopolis ); break;
            case 5:
            Zone= create_matcher( "<b>Miscellaneous</b><blockquote>(.+?)</blockquote>" , Hobopolis ); break;
            case 6:
            Zone= create_matcher( "<b>Town Square:</b><blockquote>(.+?)</blockquote>" , Hobopolis ); break;
            case 7:
            Zone= create_matcher( "<b>Burnbarrel Blvd.:</b><blockquote>(.+?)</blockquote>" , Hobopolis ); break;
            case 8:
            Zone= create_matcher( "<b>The Purple Light District:</b><blockquote>(.+?)</blockquote>" , Hobopolis ); break;
            case 9:
            Zone= create_matcher( "<p><b>Loot Distribution:</b><p><blockquote>(.+?)</blockquote>" , Hobopolis ); break;
            case 10:
            Zone= create_matcher( "<b>Miscellaneous</b><blockquote>(.+?)</blockquote>" ,  SlimeTube ); break;
            case 11:
            Zone= create_matcher( "<p><b>Loot Distribution:</b><p><blockquote>(.+?)</blockquote>" ,  SlimeTube ); break;
        }
        if(Zone.find())    ParseGroup(Z, Zone.group(1));
        Z=Z+1;
    }
    map_to_file(RaidLog, "mredge73_RAID.txt");
    //print("LogCaptured");
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
/*
Zones by Number
1=EE
2=Heap
3=Sewer
4=Burial
5=Misc
6=Town
7=BB
8=Purple
9=Hobo Loot
10=Slime
11=Slime Loot
*/
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
int TurnCount(int Z)
{
    ParseRaidLogs ();
    int Total=0;
    int C = Count (RaidLog[Z]);
    if(Z==9 || Z==11) return C;
    int E =    1;        
    while (E<=C)
    {
        if(Z==10 && contains_text(RaidLog[Z][E].EA, "Mother")) RaidLog[Z][E].TS=0;        
        Total=Total+RaidLog[Z][E].TS;
        E=E+1;
    }
    return Total;
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
int HoboTotal()
{
    ParseRaidLogs ();
    int Z=1;
    int Total=0;
    while (Z<=8)
    {
        int E =    1;    
        while (E<=Count (RaidLog[Z]))
        {
            Total=Total+RaidLog[Z][E].TS;
            E=E+1;
        }    
    Z=Z+1;
    }
    return Total;    
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
int SlimeTotal()
{ return TurnCount(10);}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
void main()
{
    print("Hobopolis Turn Count: "+HoboTotal());
    print("SlimeTube Turn Count: "+SlimeTotal());
    print("Done");
}
 
Last edited:

ElCarrot

New member
Thank you mredge73 - this works quite well. I am doing some testing - but so far it has performed perfectly. I haven't been able to test the following yet - but these test cases should still work.

1. If someone loses to mother slime
2. If someone gnaws through the bars in the CHUM cage
3. What if a clan doesn't have a hobo dungeon - but has a slime tube - will it error out (Because the variable Hobopolis might be a null string)

Note:
-When testing this, I automatically added an import for zlib.ash before realizing that there was no need to. I just found that funny.
-I had never used the Matcher object before - this script is a like a mini-tutorial on it - thanks.
 

mredge73

Member
1 untested, should work, I made it a special case in the TurnCount() function
2 confirmed, works correctly
3 untested, should work, the if() statement is used specifically to capture errors due to mismatches when using Zone.find().

It does have problems on archive logs, it will not parse them perfectly so I did not add the option to parse past logs. That could be a useful expansion or at least a good exercise for you if it is something you wish to take on. As for me, I am happy with my little parser (unless you find some bugs, bugs make me sad).
 
Top