' Adds quote to database. 'delete ' Deletes quote from database. ' [quote] [id] [#] {s/fromregex/to/|replace with |set text }&modulehelpend; if (isfunction_parsed(array('add quote', 'add'), $parsemsg, $args, $parsemsg_parsed, $args_parsed) or isfunction_parsed('quote_add', $msg, $args, $msg_parsed, $args_parsed)) { $file = 'module.commandshared.addquote.php'; if (_include($file)) include $file; } elseif (isfunction(array('delete', 'remove'), $parsemsg, $args)) do { // delete quote... not so complex... if in doubt, some comments below also count for this part $msghandled = true; $args = preg_replace('/^\s+(?:(?:number|#|quote)\s+)*/', '', $args); if (!($args = intval($args))) { msg($recipient, 'not a number :<', $from); break; } if ($args < 1) { msg($recipient, 'number at least 1 please.', $from); break; } if (count($GLOBALS['quotes']) < $args) { msg($recipient, 'I only have '.count($GLOBALS['quotes']).' quotes.', $from); break; } $deleted = array_splice($GLOBALS['quotes'], $args - 1, 1); msg($recipient, getsetting('genericdonemsg', $recipient).' '.$deleted[0], $from); writequotefindcache(); $quotefilename = dirname(__FILE__).dirsep.'quotes.txt'; $backupquotefilename = dirname(__FILE__).dirsep.'quotes-backup'.filemtime(dirname(__FILE__).dirsep.'quotes.txt').'.txt'; $cmd = (windows ? 'copy' : 'cp').' '.$quotefilename.' '.$backupquotefilename; logmsg('`'.$cmd.'`', DEBUG_LOG); system($cmd); $quotefile = fopen($quotefilename, 'w'); fwrite($quotefile, implode("\n", $GLOBALS['quotes'])); fclose($quotefile); unset($quotefile); } while (0); // Note to the reader: all variables ending in _parsed are arrays, where indices are formatparse-chunks. A formatparse-chunk consists of [0] = the text, [1-7] = various IRC formatting parameters, like bool bold, bool underline, colors, things. // formatparse_substr takes a formatparse-string ($..._parsed), one or two integer arguments, returns a new formatparse-string, works like substr(). // formatparse_cat takes * arguments, concatenates. // formatparse_toirc converts a formatparse-string to an ordinary string with irc markers (\x02, \x03, \x1F and all that stuff) // formatparse() parses an ordinary string with irc markers and converts to formatparse-string, this is done automagically before this script is included. // isfunction_parsed checks if the eggdrop got a command we're looking for, and returns the arguments passed into argument #3 and #5 // msg sends a message to a channel... that should be self-explanatory :) // The idea behind the whole formatparse was to have three kinds of IRC-strings. // - ordinary strings, no variable naming suffix, are PHP strings with no markers of any kind. // - IRC strings, suffix $..._irc, are PHP strings -with- IRC markers (bold - \x02, underline - \x1F, or whatever, I have constants for these) // - Formatparse-strings, suffix $..._parsed, are PHP arrays that should be handled by formatparse_...() functions rather than ordinary functions and operators // formatparse_... functions, input and output types: // formatparse() - in: irc string, out: formatparse-string // formatparse_substr() - in: formatparse-string, out: formatparse-string // formatparse_cat() - in: fp-string, out: fp-string // formatparse_toirc() - in: fp-string, out: irc-string // formatparse_toplain() - in: fp-string, out: plain string // formatparse_cheapstrip() - in: irc-string, out: plain string // there are probably other helpers that I forgot // Everything was written by me, Mortal, during the last couple of months elseif (isfunction_parsed(array('alter', 'change'), $parsemsg, $args, $parsemsg_parsed, $args_parsed)) do { $modadd_match = 0; // First regex check: Are we going to replace text? if (preg_match('/^\s*(?:quote\s+)?(?:number\s+)?#?(\d+)\s+replace\s+(?:"((?:\\\\"|.)*?)"|(\S+))\s+(?:with\s+)?(.*)$/i', $args, $args_, PREG_OFFSET_CAPTURE)) $modadd_match = 1; // 0 1 1 2 2 3 3 4 4 0 // Second regex check: Are we going to replace by regex? elseif (preg_match('/^\s*(?:quote\s+)?(?:number\s+)?#?(\d+)\s+[sr]\\/((?:\\\\\\/|.)*?)\\/((?:\\\\\\/|.)*?)\\/([imsxeADSUXu]*)$/i', $args, $args_, PREG_OFFSET_CAPTURE)) $modadd_match = 2; // 0 1 1 2 2 3 3 4 4 0 // Third regex check: Are we going to simply replace the whole old quote with an input text? (this corresponds to deleting and adding a new quote, except we keep the old id) elseif (preg_match('/^\s*(?:quote\s+)?(?:number\s+)?#?(\d+)\s+(?:set\s+)?(?:to\s+)?(?:"((?:\\\\"|.)*?)"|(.+))/i', $args, $args_, PREG_OFFSET_CAPTURE)) $modadd_match = 3; // 0 1 1 2 2 3 3 0 if ($modadd_match) { // If any of the above three checks passed, this will evaluate to true. // If we get erranous input, don't tell the user, just pass the line on to the other functions (which will probably trigger a random quote... hilarity ensues) if (!($quote = intval($args_[1][0]))) { //msg($recipient, 'not a number :<', $from); break; } if ($quote < 1) { //msg($recipient, 'number at least 1 please.', $from); break; } if (count($GLOBALS['quotes']) < $quote) { //msg($recipient, 'I only have '.count($GLOBALS['quotes']).' quotes.', $from); break; } // Get the quote we're going to change. $changed_from* won't be changed, it is used to show the user what they're replacing in the end. $changed_from_parsed = $changed_parsed = formatparse($GLOBALS['quotes'][$quote-1]); // formatparse_cheapstrip removes the IRC formatting from a string - it is like formatparse_toplain(formatparse('some string')), except we're not analysing anything, just removing the markers with preg_replace $changed_from = $changed = formatparse_cheapstrip($GLOBALS['quotes'][$quote-1]); if ($modadd_match === 1) { // replace certain parts if (empty($args_[$idx = 2][0])) $idx = 3; // if capture#2 didn't match anything, use capture#3 $what = formatparse_cheapstrip($args_[$idx][0]); // $what = what we're going to replace $what_parsed = formatparse_substr($args_parsed, $args_[$idx][1], strlen($what)); $what_irc = formatparse_toirc($what_parsed); // _irc is the way formatparse would format an IRC-string, we can't use the raw input string here since 1) we can't retrieve it, 2) we wouldn't be able to compare with the found strings $with = formatparse_cheapstrip($args_[$idx = 4][0]); // $with = what we're going to replace something with $with_parsed = formatparse_substr($args_parsed, $args_[$idx][1], strlen($with)); $pos = strrpos($changed, $what); // Initial finding. note that we use reverse strpos since we don't want to change the char-positions on anything we are going to alter later on do { $matched_parsed = formatparse_substr($changed_parsed, $pos, strlen($what)); $matched_irc = formatparse_toirc($matched_parsed); if ($matched_irc !== $what_irc) continue; // If what we found using plaintext doesn't match up with formatting, disregard the match. $before = substr($changed, 0, $pos); // Capture all text -before- what we matched $before_parsed = formatparse_substr($changed_parsed, 0, $pos); $thischanged = $with; // This is what we're replacing the found with $thischanged_parsed = $with_parsed; $after = substr($changed, $pos+strlen($thischanged)); // Capture all text -after- what we matched $after_parsed = formatparse_substr($changed_parsed, $pos+strlen($thischanged)); $changed = $before.$thischanged.$after; // Concatenate! $changed_parsed = formatparse_cat($before_parsed, $thischanged_parsed, $after_parsed); } while (($pos = strrpos($changed, $what, $pos)) !== false); } elseif ($modadd_match === 2) { // regex certain parts // This part looks a lot like part #1. Check the comments up there, and this will make sense (probably). $what = formatparse_cheapstrip($args_[$idx = 2][0]); $what_parsed = formatparse_substr($args_parsed, $args_[$idx][1], strlen($what)); $with = formatparse_cheapstrip($args_[$idx = 3][0]); $with_parsed = formatparse_substr($args_parsed, $args_[$idx][1], strlen($with)); $mod = $args_[$idx = 4][0]; $c = preg_match_all('/'.$what.'/'.$mod, $changed, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE); $what_irc = formatparse_toirc($what_parsed); for ($i = $c; $i--;) { // Loop from 0 <= $x <= $c-1 $matched_parsed = formatparse_substr($changed_parsed, $matches[$i][0][1], strlen($matches[$i][0][0])); $matched_irc = formatparse_toirc($matched_parsed); if ($matched_irc !== $what_irc) continue; $before = substr($changed, 0, $matches[$i][0][1]); $before_parsed = formatparse_substr($changed_parsed, 0, $matches[$i][0][1]); $thischanged = $with; $thischanged_parsed = $with_parsed; $after = substr($changed, $matches[$i][0][1]+strlen($matches[$i][0][0])); $after_parsed = formatparse_substr($changed_parsed, $matches[$i][0][1]+strlen($matches[$i][0][0])); $changed = $before.$thischanged.$after; $changed_parsed = formatparse_cat($before_parsed, $thischanged_parsed, $after_parsed); } } else { // Replace whole quote if (empty($args_[$idx = 2][0])) $idx = 3; $with = $args_[$idx][0]; $with_parsed = formatparse_substr($args_parsed, $args_[$idx][1], strlen($with)); $changed = $with; $changed_parsed = $with_parsed; } $GLOBALS['quotes'][$quote-1] = $changed_irc = formatparse_toirc($changed_parsed); // Convert to IRC-string msg($recipient, getsetting('genericdonemsg', $recipient).' '.$changed_irc, $from); // Tell the user $msghandled = true; // tell the parent script that we handled the line, and no other modules should handle the line writequotefindcache(); // index the quotes (for searcing, pretty cool module that I wrote a couple days ago) $quotefilename = dirname(__FILE__).dirsep.'quotes.txt'; // Here's where we hide the quotes $backupquotefilename = dirname(__FILE__).dirsep.'quotes-backup'.filemtime(dirname(__FILE__).dirsep.'quotes.txt').'.txt'; // gonna back up $cmd = (windows ? 'copy' : 'cp').' '.$quotefilename.' '.$backupquotefilename; // command to exec logmsg('`'.$cmd.'`', DEBUG_LOG); // log the command system($cmd); // Do it! $quotefile = fopen($quotefilename, 'w'); // write quotes.txt fwrite($quotefile, implode("\n", $GLOBALS['quotes'])); fclose($quotefile); unset($quotefile); } } while (0); ?>