PDA

View Full Version : How do I Retrieve and Parse Dungeon Logs



ElCarrot
08-25-2010, 06:45 PM
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

lostcalpolydude
08-25-2010, 06:58 PM
If you use firefox, http://forums.kingdomofloathing.com/vb/showthread.php?t=154123 is a greasemonkey script that does what you want. I don't think there's a mafia script that does this yet.

As for how to do it, I would suggest a relay override script, so it runs when you visit the page that has the data on it already.

ElCarrot
08-25-2010, 08:43 PM
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
08-25-2010, 09:19 PM
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!

lostcalpolydude
08-25-2010, 09:26 PM
Nope, the run has to be 690 turns or less for alveoli to drop.

Grotfang
08-25-2010, 10:56 PM
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.

lostcalpolydude
08-25-2010, 11:21 PM
Don't forget tickling and squeezing.

Grotfang
08-25-2010, 11:53 PM
Dinner and a movie first, I'd have thought, but indeed -- those are important too

StDoodle
08-26-2010, 01:14 AM
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
08-26-2010, 02:41 PM
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:



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
08-26-2010, 03:48 PM
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



REMOVED
It was pretty bad, see fix 2 post down

Grotfang
08-26-2010, 05:02 PM
I don't believe Mother Slime counts towards the total. Does this account for that?

mredge73
08-26-2010, 06:12 PM
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"



//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
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");
}

ElCarrot
08-30-2010, 08:52 PM
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
08-31-2010, 03:18 AM
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).