IRC Bot script
[1/1] from: ptretter::norcom2000::com at: 9-Feb-2001 10:43
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
I have been working on an IRC Bot script. Currently its rather powerful but has along
way to go and needs alot of cleanup work done. Anyway I thought I would include it as
it may benefit others. You should copy all the files to the same directory. I have
more work to do on the bot commands and the connect function as well as dcc file send
operations.
Paul Tretter
EFNET #rebol
-- Attached file included as plaintext by Listar --
-- File: irc48.r
REBOL [
Title: "REBBOT"
Comment: {Still to do: botnet features.
- channel routing of bot output
- add support for MSN protocol
- add console view function to botcommands
- create timeout to handle dcc connection or other port connections
- need flood control for the dcc sessions and channel management.
- change the partyline to advertise to everyone partings.
- add channel limit controls
- add directory support
- add ctcp commands support
- add support for ident
- add ison support with nick stealer
- add link looker
- add partyline kicking
- create channel triggers and channel actions based on parsed data
- create connect routine for specified server.
}
version: "REBBOT 1.45 - Copyright 2001 by VeiN"
]
secure [file [allow write]]
irc-input-buffer: make string! 0
dcc-input-buffer: make string! 0
bot-channels: []
server-list: load %servers.txt
dcc-chat-flag: help-flag: message-flag: limit-flag: off
masters: make block! 0
trusted: make block! 0
whoisports: make block! 0
party-line: make block! 0
chan-flood-flag: off
chan-flood-list: make list! 0
protected: make block! 0
auto-op: make block! 0
dcc-open-client: banmask-flag: banhost-flag: none
secured: false
start: now/time
message-flag: off
recycle/on
dec2tuple: func [long] [
to-tuple reduce [
to-integer long / 16777216
to-integer long / 65536 // 256
to-integer long / 256 // 256
to-integer long // 256
]
]
error-proc: func [errormsg] [
write/append %error.log reduce [now newline probe errormsg/id newline errormsg/arg1 newline
newline]
]
interface: does [
create-defaults: false
config-query: Confirm "Would you like to load defaults? (Y or N) "
either config-query [
defaults: load %defaults.txt
botname: defaults/1
altbotname: defaults/2
botpassword: defaults/3
joinchannel: defaults/4
dversion: defaults/5
logging: defaults/6
][
botname: ask "Enter a name for the bot -> "
altbotname: ask "Enter an alternate name for the bot -> "
botpassword: ask "Enter password for bot -> "
joinchannel: ask "Enter initial channel for bot -> "
dversion: ask "Enter the default version reply for ctcp responses -> "
logging: Confirm "Would you like logging turned on? (Y or N) "
create-defaults: Confirm "Would you like to save these settings as default values? (Y
or N) "
]
if create-defaults [
save %defaults.txt reduce [botname altbotname botpassword joinchannel dversion logging]
]
]
connect: does [
system/schemes/default/timeout: 30
forever [foreach server server-list [
idents: open/direct/lines tcp://:113
ident-flag: on
print ["Connecting to " server]
irc-port: [
scheme: 'tcp
host: to-string server
port-id: 6667
]
ircserv: to-string server
either error? connect-error: try [irc-open-port: open/lines/direct/no-wait irc-port][
connect-error: disarm connect-error
error-proc connect-error
Print "Error Generated at CONNECT Function!"
][
system/schemes/default/timeout: 120
handshake
exit
]
]
if tail? server-list [server-list: head server-list]
connect
]
]
handshake: does [
insert irc-open-port rejoin ["NICK " botname]
insert irc-open-port "USER reb rebol.dyndns.org ircserv reb^/"
insert irc-open-port rejoin ["JOIN " joinchannel]
insert bot-channels joinchannel
]
getirc-port-data: does [
either error? getirc-port-data-error: try [irc-input-buffer: copy/part irc-open-port
1] [
getirc-port-data-error: disarm getirc-port-data-error
error-proc getirc-port-data-error
Print "Error Generated at GETIRC-PORT-DATA function!"
][
if type? irc-input-buffer = block! [irc-input-buffer: to-string irc-input-buffer]
if not tail? irc-input-buffer [
ircparser
print irc-input-buffer
pong
; notice-parser
protector
auto-op-func
privmsg-parser
whois-parser
]
]
]
ircparser: does [
if find/part irc-input-buffer ":" 1 [irc-input-buffer: remove head irc-input-buffer]
parse-all-irc-input-buffer: parse/all copy irc-input-buffer ""
parse-irc-input-buffer: parse irc-input-buffer ""
modecmd: parse-irc-input-buffer/2
direction: parse-irc-input-buffer/3
type-incoming: parse-irc-input-buffer/1
if type-incoming = ircserv [
server-incoming: make object! [
server: type-incoming/1
servcode: parse-irc-input-buffer/2
servmsg: if found? find copy irc-input-buffer ":" [
return find copy irc-input-buffer ":"
]
]
]
if type-incoming = "error" [
close irc-open-port
server-list: next server-list connect
]
if type-incoming = ircserv [if server-incoming/servcode = "433" [botname: altbotname
handshake]]
if not none? type-incoming [
if find type-incoming "!" [
header: parse copy irc-input-buffer "!@"
message-flag: on
message: make object! [
nick: header/1
username: header/2
host: header/3
mask: remove/part copy host ((length? first parse/all copy host ".") + 1)
data: if find irc-input-buffer ":" [
either not empty? find/tail irc-input-buffer ":" [
data: second parse/all copy irc-input-buffer ":"
][
data: none
]
]
dataparse: if data [dataparse: parse data ""]
]
]
]
]
irc-port-send: func [block][
append irc-open-port rejoin block
]
protector: does [
if all [message-flag not empty? protected][
if message/nick <> botname [
protected: head protected
if all [modecmd = "KICK"][
foreach item protected [if found? parse parse-irc-input-buffer/4 item [
irc-port-send ["MODE " parse-irc-input-buffer/3 " +b " message/nick]
irc-port-send ["Kick " parse-irc-input-buffer/3 " " message/nick]]
]
]
if all [modecmd = "MODE" parse-irc-input-buffer/4 = "-o"][
foreach item protected [if found? parse parse-irc-input-buffer/5 item [
irc-port-send ["MODE " parse-irc-input-buffer/3 " +b " message/nick]
irc-port-send ["Kick " parse-irc-input-buffer/3 " " message/nick]
irc-port-send ["MODE " parse-irc-input-buffer/3 " +o " parse-irc-input-buffer/5]]
]
]
if all [modecmd = "MODE" parse-irc-input-buffer/4 = "+b"][
foreach item protected [if found? parse parse-irc-input-buffer/5 item [
irc-port-send ["MODE " parse-irc-input-buffer/3 " +b " message/nick]
irc-port-send ["Kick " parse-irc-input-buffer/3 " " message/nick]
irc-port-send ["MODE " parse-irc-input-buffer/3 " -b " parse-irc-input-buffer/5]]
]
]
]
]
]
auto-op-func: does [
auto-op: head auto-op
if all [not empty? auto-op modecmd = "join"][
foreach item auto-op [if found? find auto-op message/nick [
irc-port-send ["MODE " (remove pick parse-irc-input-buffer 3) " +o " message/nick]]
]
]
]
notice-parser: does [
if secured [
if all [modecmd = "notice" type-incoming <> ircserv][
if all [message/dataparse/1 = "DCC" message/dataparse/2 = "chat"][
dcc-ip: copy message/dataparse/3
remove head dcc-ip
remove back tail dcc-ip
dcc-chat-flag: on
]
]
]
]
secured: does [
; this function verify's whether a nick is a master and is passed to other functions/commands
masters: head masters
trusted: head trusted
if message-flag [
if message/nick = botname [return true]
if found? find masters message/nick [
position: index? find masters message/nick
either message/host = first at trusted position [
return true
][
remove find masters message/nick
print ["removing " message/nick " from Masters list"]
remove first at trusted position
return false
]
]
if found? find trusted message/host [
position: index? find trusted message/host
either message/nick = first at masters position [
return true
][
remove find trusted message/host
print ["removing " message/host " from Trusted list"]
remove at masters position
return false
]
]
]
]
dcc-port-send: func [block][insert bot-port-send rejoin block]
dcc-parser: does [
if secured [
if dcc-chat-flag [
dcc-client-port: message/dataparse/5
if value? to-word message/nick [
if found? find waitports get to-word message/nick [
remove find waitports get to-word message/nick
close get to-word message/nick
]
]
if all[not none? dcc-client-port not none? dcc-ip][
dcc-connect: [
scheme: 'tcp
host: dcc-ip
port-id: to-integer dcc-client-port
user-data: message/nick
]
]
either error? error-dcc-open-client: try [dcc-open-client: open/lines/direct/no-wait
dcc-connect][
error-dcc-open-client: disarm error-dcc-open-client
error-proc error-dcc-open-client
Print "Error Generated at DCC-PARSER Function!"
][
insert dcc-open-client read %help.txt
dcctemp: make set-word! message/nick
mold dcctemp :dcc-open-client
append waitports get make word! message/nick
]
dcc-chat-flag: off
dcc-client-port: none
dcc-connect: none
dcc-open-client: none
]
]
]
bot-commands: does [
whoisports: head whoisports
party-line: head party-line
either error? error-bot-incoming: try [bot-incoming: parse dcc-input-buffer ""][
error-bot-incoming: disarm error-bot-incoming
error-proc error-bot-incoming
Print "Error Generated at BOT-COMMANDS Function!"
][
bot-parse-incoming: parse/all dcc-input-buffer " "
if bot-incoming/1 = ".ban" [irc-port-send ["MODE " bot-incoming/3 " +b " bot-incoming/2]]
if bot-incoming/1 = ".unban" [irc-port-send ["MODE " bot-incoming/3 " -b " bot-incoming/2]]
if bot-incoming/1 = ".banhost" [irc-port-send ["WHOIS " bot-incoming/2]
banhost-flag: bot-incoming/2
banhost-channel: bot-incoming/3
]
if bot-incoming/1 = ".banmask" [irc-port-send ["WHOIS " bot-incoming/2]
banmask-flag: bot-incoming/2
banmask-channel: bot-incoming/3
]
if bot-incoming/1 = ".kick" [irc-port-send ["kick " bot-incoming/3 " " bot-incoming/2]]
if bot-incoming/1 = ".uptime" [dcc-port-send [now/time - start]]
if bot-incoming/1 = ".shutdown" [
waitports: next head waitports
irc-port-send ["quit"]
close irc-open-port
foreach port waitports [close port]
halt
]
if bot-incoming/1 = ".lock" [irc-port-send ["MODE " bot-incoming/2 " +i "]]
if bot-incoming/1 = ".unlock" [irc-port-send ["MODE " bot-incoming/2 " -i"]]
if bot-incoming/1 = ".topic" [irc-port-send ["TOPIC " bot-incoming/2 " :" reform at bot-incoming
3]]
if bot-incoming/1 = ".secret" [irc-port-send ["MODE " bot-incoming/2 " +s"]]
if bot-incoming/1 = ".nosecret" [irc-port-send ["MODE " bot-incoming/2 " -s"]]
if bot-incoming/1 = ".invite" [irc-port-send ["INVITE " bot-incoming/2 " " bot-incoming/3]]
if bot-incoming/1 = ".time" [dcc-port-send [now/time]]
if bot-incoming/1 = ".date" [dcc-port-send [now/date]]
if all [bot-incoming/1 = ".unregister" bot-incoming/2 <> none][unregister bot-incoming/2]
if bot-incoming/1 = ".op" [irc-port-send ["MODE " bot-incoming/3 " +o " bot-incoming/2]]
if bot-incoming/1 = ".deop" [irc-port-send ["MODE " bot-incoming/3 " -o " bot-incoming/2]]
if bot-incoming/1 = ".voice" [irc-port-send ["MODE " bot-incoming/3 " +v " bot-incoming/2]]
if bot-incoming/1 = ".unvoice" [irc-port-send ["MODE " bot-incoming/3 " -v " bot-incoming/2]]
if bot-incoming/1 = ".join" [irc-port-send ["join " bot-incoming/2 " " bot-incoming/3]
insert bot-channels bot-incoming/2
]
if all [bot-incoming/1 = ".part" not none? bot-incoming/2][irc-port-send ["part " bot-incoming/2]
bot-channels: head bot-channels
if error? part-error: try [remove find bot-channels bot-incoming/2][
part-error: disarm part-error
dcc-port-send [bot-incoming/2 " is not in channels distribution"]
]
]
if bot-incoming/1 = ".masters" [dcc-port-send [masters]]
if bot-incoming/1 = ".trusted" [dcc-port-send [trusted]]
if bot-incoming/1 = ".say" [irc-port-send ["PRIVMSG " bot-incoming/2 " :" (at bot-parse-incoming
3)]]
if bot-incoming/1 = ".list" [dcc-port-send [bot-channels]]
if bot-incoming/1 = ".help" [dcc-port-send [read %help.txt]]
if bot-incoming/1 = ".change-nick" [irc-port-send ["NICK " bot-incoming/2]]
if bot-incoming/1 = ".key" [irc-port-send ["MODE " bot-incoming/2 " +k " bot-incoming/3]]
if bot-incoming/1 = ".unkey" [irc-port-send ["MODE " bot-incoming/2 " -k " bot-incoming/3]]
if bot-incoming/1 = ".change-password" [
botpassword: bot-incoming/2
dcc-port-send ["The BOT password has been changed to: " botpassword]
]
if bot-incoming/1 = ".send" [irc-port-send [(at bot-parse-incoming 2)]]
if bot-incoming/1 = ".comments" [dcc-port-send [system/script/header/comment]]
if bot-incoming/1 = ".ver" [dcc-port-send [system/script/header/version]]
if all [bot-incoming/1 = ".partyline" bot-incoming/2 = "on"][
either find party-line get to-word bot-port-send/user-data [dcc-port-send ["you are already
on the party line!"]
][
append party-line bot-port-send
party-line head party-line
foreach port party-line [
append port rejoin [bot-port-send/user-data " is now on the partyline!"]
]
]
]
if all [bot-incoming/1 = ".partyline" bot-incoming/2 = "off"][
party-line: head party-line
while [not tail? party-line][
partyindex: first party-line
if partyindex/user-data = bot-port-send/user-data [
remove party-line
dcc-port-send [bot-port-send/user-data ", you have PARTED the partyline!"]