| 1 | ;;; This file is automatically loaded by Bobot++. This is required for |
| 2 | ;;; the bot to function. |
| 3 | |
| 4 | ;;; This file is covered by the GPL version 2 or (at your option) any |
| 5 | ;;; later version |
| 6 | |
| 7 | ;;; the-bot-module must be available to guile-user so that scripts |
| 8 | ;;; loaded with Interp::Load have access to the bot: procedures |
| 9 | (module-use! (resolve-module '(guile-user) #f) |
| 10 | the-bot-module) |
| 11 | |
| 12 | (use-modules (srfi srfi-1) |
| 13 | (srfi srfi-13)) |
| 14 | |
| 15 | (eval-when (compile load eval) |
| 16 | (set! %load-path (cons* (string-append (getenv "HOME") "/.bobotpp/scripts/") |
| 17 | bot:sys-scripts-dir |
| 18 | %load-path))) |
| 19 | |
| 20 | ;;; bot:log: Write as many messages as you want to the log. If the |
| 21 | ;;; arg is a thunk it will be executed and it's output will be |
| 22 | ;;; written to the log |
| 23 | (define-public (bot:log . messages) |
| 24 | (for-each |
| 25 | (lambda (x) |
| 26 | (if (thunk? x) |
| 27 | (display (x) (bot:logport)) |
| 28 | (display x (bot:logport)))) |
| 29 | messages) |
| 30 | (bot:flushport)) |
| 31 | |
| 32 | (define-public bot:load load-from-path) |
| 33 | |
| 34 | (define (module->string module) |
| 35 | (apply (lambda (s . rest) |
| 36 | (string-append |
| 37 | s |
| 38 | (apply string-append |
| 39 | (map (lambda (str) (string-append "/" str)) rest)))) |
| 40 | (map symbol->string module))) |
| 41 | |
| 42 | (define-public (bot:load-module module-spec) |
| 43 | (let ((new-module (make-module 31 (list the-bot-module))) |
| 44 | (old-module (current-module))) |
| 45 | (module-use! new-module the-bot-module) |
| 46 | (set-current-module new-module) |
| 47 | (bot:load (module->string module-spec)) |
| 48 | (set-current-module old-module) |
| 49 | new-module)) |
| 50 | |
| 51 | (define-public (bot:use-module module-spec) |
| 52 | (module-use! (current-module) |
| 53 | (bot:load-module module-spec))) |
| 54 | |
| 55 | ;;; REGEX UTILS |
| 56 | |
| 57 | ;;; match-not-channel adds a prefix regex to your regex so it doesn't |
| 58 | ;;; match the sender or channel in a PUBLIC message |
| 59 | (define-public (bot:match-not-channel regex) |
| 60 | (string-append "^[[:graph:]]*[&#+!][^ ,\a]+ [[:graph:][:space:]]*" |
| 61 | regex)) |
| 62 | |
| 63 | ;;; match-to-me matches text that was addressed to the bot with a |
| 64 | ;;; ':',',', or nothing after the bot name |
| 65 | |
| 66 | (define-public (bot:match-to-me regex) |
| 67 | (string-append (bot:match-not-channel (bot:getnickname)) |
| 68 | "[[:space:][:graph:]]*" regex)) |
| 69 | |
| 70 | (define-public (bot:sent-to-me? message) |
| 71 | (let ((to-me (make-regexp (bot:match-to-me "")))) |
| 72 | (if (regexp-exec to-me message) #t #f))) |
| 73 | |
| 74 | ;;;; string-utils |
| 75 | (define-public str-app string-append) ; shorter |
| 76 | |
| 77 | ;;; Message sending utils |
| 78 | |
| 79 | ;;; Returns the CTCP quoted message |
| 80 | ;;; Input _MUST NOT_ contain the trailing \r\n |
| 81 | ;;; (it is added by the message sending code) |
| 82 | (define-public (bot:ctcp-quote message) |
| 83 | ;; TODO: Not very efficient, it may be worth reimplementing |
| 84 | (let ((ls (string->list message))) |
| 85 | (string-concatenate |
| 86 | (map (lambda (chr) ; CTCP level quoting |
| 87 | (case (char->integer chr) |
| 88 | ((#o134) (string (integer->char #o134) (integer->char |
| 89 | #o134))) |
| 90 | ((#o01) (string (integer->char #o134) #\a)) ; X-DELIM |
| 91 | (else (string chr)))) |
| 92 | (string->list |
| 93 | (string-concatenate |
| 94 | (map (lambda (chr) ; Low-level |
| 95 | (let ((m-quote (integer->char #o20))) |
| 96 | (case chr |
| 97 | ((m-quote) (string m-quote m-quote)) |
| 98 | ((#\nul) (string m-quote #\0)) |
| 99 | ((#\nl) (string m-quote #\n)) |
| 100 | ((#\cr) (string m-quote #\r)) |
| 101 | (else (string chr))))) |
| 102 | ls))))))) |
| 103 | |
| 104 | ;;; bot:channel-users user object accessors |
| 105 | (define-public (bot:channel-user-nick cu) |
| 106 | (first cu)) |
| 107 | |
| 108 | (define-public (bot:channel-user-user/host cu) |
| 109 | (second cu)) |
| 110 | |
| 111 | (define-public (bot:channel-user-mode cu) |
| 112 | (third cu)) |
| 113 | |
| 114 | (define-public (bot:channel-user-has-modes? cu . modes) |
| 115 | (let ((mode (apply logior modes))) |
| 116 | (= (logand (bot:channel-user-mode cu)) mode mode))) |
| 117 | |
| 118 | (define-public (bot:channel-user-op? cu) |
| 119 | (bot:channel-user-has-modes? cu bot:mode/op)) |
| 120 | |
| 121 | (define-public (bot:channel-user-voice? cu) |
| 122 | (bot:channel-user-has-modes? cu bot:mode/voice)) |
| 123 | |
| 124 | (define-public (bot:channel-user-away? cu) |
| 125 | (bot:channel-user-has-modes? cu bot:mode/away)) |
| 126 | |
| 127 | (define-public (bot:channel-user-ircop? cu) |
| 128 | (bot:channel-user-has-modes? cu bot:mode/op)) |
| 129 | |
| 130 | ;;; DEPRECATED FUNCTION NAMES |
| 131 | ;;; These are provided for backwards compatibility |
| 132 | ;;; and will be removed in the 3.0 release |
| 133 | (begin-deprecated |
| 134 | |
| 135 | (define-macro (_deprecated-fun old-name new-name) |
| 136 | `(define-public ,old-name |
| 137 | (lambda args |
| 138 | (let ((old-error |
| 139 | (set-current-error-port (bot:logport)))) |
| 140 | (issue-deprecation-warning |
| 141 | (string-append |
| 142 | (symbol->string ',old-name) |
| 143 | " is a deprecated function. Please use " |
| 144 | (symbol->string ',new-name) " instead.")) |
| 145 | (bot:flushport) |
| 146 | (set-current-error-port old-error)) |
| 147 | (apply ,new-name args)))) |
| 148 | |
| 149 | (_deprecated-fun bot-load bot:load) |
| 150 | (_deprecated-fun bot-action bot:action) |
| 151 | (_deprecated-fun bot-adduser bot:adduser) |
| 152 | (_deprecated-fun bot-addserver bot:addserver) |
| 153 | (_deprecated-fun bot-addshit bot:addshit) |
| 154 | (_deprecated-fun bot-ban bot:ban) |
| 155 | (_deprecated-fun bot-cycle bot:cycle) |
| 156 | (_deprecated-fun bot-deban bot:deban) |
| 157 | (_deprecated-fun bot-delserver bot:delserver) |
| 158 | (_deprecated-fun bot-deluser bot:deluser) |
| 159 | (_deprecated-fun bot-delshit bot:delshit) |
| 160 | (_deprecated-fun bot-deop bot:deop) |
| 161 | (_deprecated-fun bot-die bot:die) |
| 162 | (_deprecated-fun bot-do bot:do) |
| 163 | (_deprecated-fun bot-invite bot:invite) |
| 164 | (_deprecated-fun bot-join bot:join) |
| 165 | (_deprecated-fun bot-keep bot:keep) |
| 166 | (_deprecated-fun bot-kick bot:kick) |
| 167 | (_deprecated-fun bot-kickban bot:kickban) |
| 168 | (_deprecated-fun bot-lock bot:lock) |
| 169 | (_deprecated-fun bot-logport bot:logport) |
| 170 | (_deprecated-fun bot-mode bot:mode) |
| 171 | (_deprecated-fun bot-msg bot:msg) |
| 172 | (_deprecated-fun bot-nextserver bot:nextserver) |
| 173 | (_deprecated-fun bot-nick bot:nick) |
| 174 | (_deprecated-fun bot-op bot:op) |
| 175 | (_deprecated-fun bot-part bot:part) |
| 176 | (_deprecated-fun bot-reconnect bot:reconnect) |
| 177 | (_deprecated-fun bot-say bot:say) |
| 178 | (_deprecated-fun bot-server bot:server) |
| 179 | (_deprecated-fun bot-setversion bot:setversion) |
| 180 | (_deprecated-fun bot-tban bot:tban) |
| 181 | (_deprecated-fun bot-tkban bot:tkban) |
| 182 | (_deprecated-fun bot-topic bot:topic) |
| 183 | (_deprecated-fun bot-unlock bot:unlock) |
| 184 | (_deprecated-fun bot-getnickname bot:getnickname) |
| 185 | (_deprecated-fun bot-getserver bot:getserver) |
| 186 | (_deprecated-fun bot-getserverlist bot:getserverlist) |
| 187 | (_deprecated-fun bot-flush bot:flush) |
| 188 | (_deprecated-fun bot-flushport bot:flushport) |
| 189 | (_deprecated-fun bot-random bot:random) |
| 190 | (_deprecated-fun bot-addcommand bot:addcommand) |
| 191 | (_deprecated-fun bot-delcommand bot:delcommand) |
| 192 | (_deprecated-fun bot-addhook bot:addhook) |
| 193 | (_deprecated-fun bot-addtimer bot:addtimer) |
| 194 | (_deprecated-fun bot-deltimer bot:deltimer) |
| 195 | |
| 196 | (define-public hooks/leave hooks/part)) |