[ Advanced Use ] Jerkbot is a very flexible script with jIRCii and Sleep behind it. With that comes the ability to add much more complex response commands within its files. If you are comfortable with Sleep and jIRCii's implementation and use within, you can use '/eval' command syntaxes built into jIRCii along with Jerkbot subroutines and global variables to execute complex single-line nested commands. You can find examples of '/eval' commands littered throughout response files in the default bot. * Note on using commands other than /msg, /notice or /describe in response files: Certain text modification functions may fail or error if you use commands such as /eval or /phrase and others incorrectly within response strings. There are also several safeguards built throughout the command structure and any associated module command structures to prevent misuse of the /eval command. Here are some advanced solutions to common, or not so common scenarios: Scenario: "Oops! I lost my password, but I don't want to destroy the password file and start over. :-O" Solution: From the client, use this command once: /eval jbcrypt("settings" . osp() . ".tmp.db") Result: The .tmp.db file under /settings/ will be decrypted and reverted to plaintext. In this format, you are then able to open up and remove the line in the password file containing your mask. In this state you will see a heavily salted/hashed pass string, and while you are unable to view/find your password in this state, you can remove the line that matches your host. Perform that command one more time, and the file is then re-encrypted. You can then set a new !pass on your bot after this. Scenario: You want your bot to op any owner/master/op in specific channels after they say something the first time. Solution: In sa_public.db, add this: #chan1,#chan2,#etc==*==/eval iff($sanick !isop $sachan, iff(chkmask($sanick, rdfile("bot_owner")) eq "true" || chkmask($sanick, rdfile("bot_masters")) eq "true" || chkmask($sanick, rdfile("bot_ops")) eq "true", call("/mode $sachan +o $sanick"), eval()), eval()) Result: this line of code checks that the user isn't already opped, and if they're not, check to see that they fit the owner/masters/ops criteria laid out and if so, gives them ops. (A similar line could also be used in sr_join, albeit with a lesser degree control over which channels to operate in and a possibilty of percentages.db settings overruling any consistency.) Scenario: You want your bot to read a random line from a text file online whenever a certain word is used. Solution: In sr_public.db, add this: *borat*==/eval call("/msg $pchan " . rand(readAll(exec("curl -s http://smacie.com/randomizer/borat.txt")))) Result: This particular example uses cURL to read a random line from the borat.txt file located at smacie.com. This method requires: Jerkbot running on a system with cURL installed. Note: you can use this or similar code for a multitude of site information. This next line of code fetches gallery and image titles from imgur.com when someone posts a link from the site... *imgur.com/*==/eval call("/msg $pchan " . strrep(readAll(exec("curl -s " . strrep(iff(strrep($pubp, "https", "http") hasmatch 'http?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)', "http://imgur.com " . getToken(tokenize(matched(), "."), 0), ""), " @\(\$null, \'", "", "\'\)", "")))[7], "", "", "\'", "\'", "\"", "\"")) Note: I ultimately ended up using this idea and turning it into the url.irc module. Scenario: If bot is addressed, have the bot say a user's nick before returning a mixed (created or learned) response... ie: ceph: i found a pebble today. Solution: In publicme.db, add this: /eval call("/msg $pchan " . filtxt("rtxt,lc,uc", "$pnick") . filtxt("rand", "<<,|:>> ") . filtxt("lc,uc,pself,ptxt", Pub_Resp_No_Trigger("mixed"))) Note: This could also be accomplished with '/msg !pchan !pnick<<,|:>> text here', as seen in the public.db file, which is much more simple but as you can see, does not have the degree of flexibility an /eval would allow. Scenario: A different bot in the channel uses the command character @, and you want jerkbot to use that cc only with a specific command (like "addquote") in order to add quotes to both bots. Solution: in sa_public.db, add this: #channel==@addquote *==/eval fileadd(getTokenFrom(tokenize($pubp," "), 1), "modules" . osp() . "quote" . osp() . "quotes.db") Result: ensures match incldes @addquote and performs a fileadd() with modified parameters to the quotes.db file. Scenario: You want random ridiculous infolines for a specific user when they join. Solution: In sr_join, add this: nick==/eval call("/msg !pchan [!joiner] " . filtxt($ftxm, mod_text("c1", "<>"))) Result: Uses Jerkbot's mod_text() function to colorize text for user on join. Scenario: You want random phrases chosen from learned matches for a specific joiner. Solution: In sr_join, add this: some_nickname==/eval call(match_response("*some_nickname*", "learned.db")) Result: Uses Jerkbot's match_response() function to match an item from learned.db. Scenario: You want the bot to automatically add a specific channel to its response channels when a specific person is idle for a certain amount of time, but you also want that channel removed when they are no longer idle. (This is a weird one, but i actually used it for one of my bots once. This method requires: bot residing in a channel with conversation activity. Solution: in sa_public, add this: #channel==*==/eval iff(getIdleTime("nickname") >= 600, iff("#channel" !in rdfile("bot_channels"), fileadd("#channel", "database" . osp() . "bot_channels.db", "respvar"), eval()), filerem(filesrch("#channel", "database" . osp() . "bot_channels.db", 1), "database" . osp() . "bot_channels.db", 1), eval()) Result: when someone (anyone) talks, if "nickname" is idle for 10 minutes or more, will add the channel allowing bot responses, but if nickname is not idle more than 10 minutes, it will remove that channel using a flag in filesrch() to return only the line item number for proper removal by filerem(). This one uses nested iff() statements and additional flags to suppress strings, and will require activity in a channel listed in its bot_channels.db file. You will want to keep a command that is this broad in nature down near the bottom of the script, so that it does not take precedence over the other commands. Scenario: two ways to build a '[] option1 [] option2' command. Solution 1: this will add a command to cmd.db. From irc, you can use this: !cmd add ALL @@ /[] !2- [] !4-==/eval call("/msg $cchan " . "\[\bX\b\] " . strrep(getToken(tokenize("!str", "\[\] "), 0), "]", "") . "\[ \] " . replace(getToken(tokenize("!str", "\[\]"), 1), " ", "", 1)),,/eval call("/msg $cchan " . "\[ \] " . strrep(getToken(tokenize("!str", "\[\] "), 0), "]", "") . "\[\bX\b\] " . replace(getToken(tokenize("!str", "\[\]"), 1), " ", "", 1)) (This method requires that you issue this as a command. ie: '![] yes [] no'.) Solution 2: this will add a response for sa_public. From irc, you can use this: !aphr sa_public #channel==\[\] *\[\] *==/eval call("/msg $sachan " . "\[\bX\b\]" . strrep(getToken(tokenize($pubp, "\[\] "), 0), "]", "") . "\[ \] " . replace(getToken(tokenize($pubp, "\[\]"), 1), " ", "", 1)),,/eval call("/msg $pchan " . "\[ \]" . strrep(getToken(tokenize($pubp, "\[\] "), 0), "]", "") . "\[\bX\b\] " . replace(getToken(tokenize($pubp, "\[\]"), 1), " ", "", 1)) (This method requires: channel be in the bot_channels.db file and spub in percentages.db be set at 200.) For cases where you want to leave spub at 200 and need some things to not always respond, include '/eval' and ',,' randomizer tokens in your code, ie: item==/eval,,/eval,,/response stuff (This example would give the bot a 1/3 chance to respond.) [In Closing] You have access to a plethora of options to choose how you want the bot to behave. Many of these examples are basically just code function extensions to the main script by applying scripting properties to the commands themselves. //EOF