ClanBots

mredge73

Member
Hey guys, I am in the process of writing a clanbot/chatbot script. I have used Alhifar's cage bot as a jumping off point and already have learned a lot from the example. I realize that you guys probably use your clan bot as a selling point to get people into your clan so you haven't posted any of these types of scripts.
So here is a request, sort of.
I don't want anyone to go out and build any scripts, I am just interested in seeing how to write one myself through examples (if they exist). I am looking for a way to log the clan stash activity to see what people are putting in and taking out so I can make contest management automatic and flag looters, a way to automatically assign ranks based on karma, and something that can read/post the message board.
I am horrible with strings and all this has to work with strings; if you don't like posting your clan bots a few code excerpts will help. Thanks in advance.
 

Alhifar

Member
I'd highly reccomend learning to use regular expressions if you want to do any significant string parsing. It leaves your code much more readable, and sometimes makes it much more possible to find certain strings. for example, you could use something like:
Code:
matcher m_stash_put = create_matcher( "(.+?) \\(#(\\d+)\\) added (\\d+) (.+?)." , visit_url( "clan_log.php" ) );
if( m_stash_put.find() )
{
string player = m_stash_put.group( 1 );
int player_num = m_stash_put.group( 2 ).to_int();
int num_put = m_stash_put.group( 3 ).to_int();
item it_put = m_stash_put.group( 4 ).to_item();
}

to get various bits of information from your clan administration log. I wouldn't reccomend using that exact code; I could point out at least 2 flaws without even thinking about it, but it works as an example. Also note that I just quickly wrote up that regex, I'm not even sure it will work correctly. In any case, that information could be gotten through other means, but it would take at least 3-4 times as many lines, and with very little speed gained.
 

mredge73

Member
Ok, since I still do not understand the syntax for matchers.
After adding a "</a>" before added I could get some information out of it.

Code:
matcher m_stash_put = create_matcher( "(.+?) \\(#(\\d+)\\)</a> added (\\d+) (.+?)." , visit_url( "clan_log.php" ) );

I have 3 problems now that you may be able to help with:

1.
string player outputs everything before the the player's name including the player's name. If there is a way around this to just get the player's name that would help. Since it captures the player's id correctly, is there a way to convert the player's id to the player's name? I don't think there is a to_name function.

2. is there a way to convert string plurals of items to a non plural so it can work as a item type?

3. if it_put is left as a string, group(4) only captures the first letter of the string. I don't know enough about matcher to try to fix this.
 
Last edited:

Alhifar

Member
Like I said, I hadn't debugged the pattern, I figured it wouldn't necessarily work.

1) I forgot the timestamp before. A better pattern would be:
Code:
\\d{2}/\\d{2}/\\d{2}, \\d{2}:\\d{2}A|PM(.+?) \\(#(\\d+)\\)</a> added (\\d+) (.+?)\\.
You could then also capture the first section as a group to figure out when the person added the item.

2) There currently isn't. I thought that to_item() would work with plurals, but it currently doesn't.

3) I accidentally forgot to escape the . at the end; that was supposed to be a literal period, and was being treated as any character, causing the lazy + to only take one character from the . In any case, the above pattern should work, if I'm not mistaken.
 

mredge73

Member
ok just trying to decipher this so let me know if I get off:

\\d{2} is this how you signal a group of digits with 2 characters
A|PM can this be translated as AM or PM or is it A or P, M is a literal character
(.+?) is this how you do a string, what signifies the end of the string, is it another entry or literal character?
(\\d+) is this all digits until the next literal character
 

mredge73

Member
that is exactly what I needed, thanks
this task should get a little easier now,
hmm, now about those plurals...
 

mredge73

Member
I got the regular expression down for Stash Parcing!
">(\\d{2})/(\\d{2})/(\\d{2}), (\\d{2}):(\\d{2})(AM:|PM:) <(.+?)>(.+?) \\(#(\\d+)\\)</a> (added|took|contributed) (\\d+) (.+?)\\.<"

Found a Tool that helped a lot:
http://www.fileformat.info/tool/regex.htm

I also think I fixed my problem with the plurals:
http://kolmafia.us/showthread.php?p=13322#post13322


Test function if anyone is interested in working on a similar project:
Code:
string ClanLog= visit_url( "clan_log.php" );
int start=index_of( ClanLog , "Stash") +55;
ClanLog=substring(ClanLog, start);
matcher m_stash_put = create_matcher( ">(\\d{2})/(\\d{2})/(\\d{2}), (\\d{2}):(\\d{2})(AM:|PM:) <(.+?)>(.+?) \\(#(\\d+)\\)</a> (added|took|contributed) (\\d+) (.+?)\\.<" , ClanLog );
print("build matcher");
int I=0;
while( I<5 )//test only 5 iterations
{
m_stash_put.find();
print("find");
I=I+1;
string group1= m_stash_put.group( 1 );
string group2= m_stash_put.group( 2 );
string group3= m_stash_put.group( 3 );
string group4= m_stash_put.group( 4 );
string group5= m_stash_put.group( 5 );
string group6= m_stash_put.group( 6 );
string group7= m_stash_put.group( 7 );
string group8= m_stash_put.group( 8 );
string group9= m_stash_put.group( 9 );
string group10= m_stash_put.group( 10 );
string group11= m_stash_put.group( 11 );
string group12= m_stash_put.group( 12 );

print(group1,"blue");//month
print(group2,"purple");//day
print(group3,"olive");//year
print(group4,"green");//hour
print(group5,"blue");//minute
print(group6,"purple");//AM:|PM:
print(group7,"olive");//html expression of a character id
print(group8,"green");//player name
print(group9,"blue");//player ID
print(group10,"purple");//added|took|contributed
print(group11,"olive");//number
print(group12,"green");//item
}
 
Last edited:

zarqon

Well-known member
Wow nice! I haven't ever messed with regex -- it doesn't seem even close to human-readable. Thanks for the tips Alhifar, and thanks for sharing your result Edge.
 

Rinn

Developer
I don't think I've seen anything but the most simple regular expressions ever be close to human-readable.
 

Alhifar

Member
Have you seen what I was using before, for example in my run_choice() function? I'd consider the regex form much more readable. And in any case, I find most regexes fairly readable, you just have to think how the parser would think.
 

mredge73

Member
The tool that I found helps ALOT for testing before actually coding it.
You don't even have to worry about the java rules, you can just enter it regularly and it will give you the java expression and groups found out of any sample.

If you screw it up in your .ash code then mafia may hang or give you a debug log without prompting you of what exactly went wrong.
 
Top