###################################################################################### # xdcc.irc # `butane (raffi@hick.org), requires jIRCii (v 12.07.04) #################################################################### JAY-EYE-ARE-CEE 2 # /load xdcc.irc within jircii # # xdcc.irc is a powerful and full featured(?) xdcc addon for the irc client jIRCii. # if you don't have jIRCii you can obtain a copy at the following website: # # http://jirc.hick.org/ <- primary site # http://jircii.leenux.net/ <- backup site # # anyways some of the features this xdcc has... # * very clean plist with optimal aligning, the look is based off of fphoenix.irc # which is a classic ircii xdcc script. # * full set of normal xdcc features: queue, minspeed, record speed, loadable/savable # xdcc offer lists. # * set of security features such as the ability to password lock a individual packet # and the ability to deny /ctcp xdcc list's (keep you from flooding off) # * solid sharing of xdcc data between multiple server connections # # I apologize this script sucks as an example, I hacked it out in a couple of hours over # a few days. Comments, organization, structure. A jedi craves not these things. # # jIRCii 11.25.04 as a minimum. # #----------------------------------------Okay I loaded this bad boy, how do I use it---- # okay heres a break down of the commands and syntax's # # /xdcc doffer # ^- deletes a pack or deletes all of em # # /xdcc offer # ^- offer a new pack # # /xdcc set [var] [value] # ^- sets a xdcc value (i.e. slots, minspeed etc) # xdcc set by itself shows the var's # # /xdcc pass [password] # ^- sets a password for pack, if you don't specify a pass # the password lock is removed # # /xdcc plist [target] # ^- sends an xdcc plist to the specified target # # /xdcc timer # ^- sets up a timer to /xdcc plist every n minutes # # for the rest of the commands just use '/xdcc' by itself and # it will give you a list, my local command setup isn't perfect # so don't kill me or nothing. # #----------------------------------------Change Log------------------------ # 12.07.04 # - made multi-server packet information sharing better. # - fixed some minor bugs # # 09.19.04 # - /xdcc offer now places into the editbox, rather than # pop up a dialog. # # 07.28.04 # - xdcc.irc will not send "no packets offered" message to a channel anymore # - packets are always now always saved/loaded into a default packet list # if none has been specified. # # # a set for what the XDCC related messages should look like to the user. # set XDCC_ECHO { return "\c13X\c6DCC\c14:\c15 $0-"; } # # our two events we respond to # on request { if (uc($1) eq "XDCC") { processRequest($nick, $2, $3, $4, $5); } } on privmsg { if (uc($1) eq "XDCC") { processRequest($nick, $2, $3, $4, $5); } } # process an XDCC request from a user sub processRequest { xdcc_load(xgv("loaded", "default-xlist")); if (uc($2) eq "LIST" && xgv("list", 1)) { call("/xdcc plist $1"); } else if (uc($2) eq "SEND") { if (left($3, 1) eq "#") { $pack = int(substr($3, 1)) - 1; } else { $pack = int($3) - 1; } if ($pack >= size(@XDCC_PACKETS) || $pack < 0) # make sure we're offering this pack { sendRaw("NOTICE $1 :no files offered as " . int($3)); return; } loadPacket(@XDCC_PACKETS[$pack]); if ($XDCC_PASS ne "" && $4 ne $XDCC_PASS) # make sure password is okay... { sendRaw("NOTICE $1 :a password is required in order to download this pack, /ctcp $me XDCC send # $+ $pack password"); } else if (openSlots() > 0) # we have open slots, lets send it... { $XDCC_GETS++; savePacket(); sendRaw("NOTICE $1 :\bSending\b you $XDCC_DESC which is $XDCC_SIZE"); xecho("Sending \" $+ $XDCC_DESC $+ \" to \u $+ $1 $+ \u"); call("/dcc send $1 $XDCC_FILE"); } else if (xgv("queue", 0) ne "0") # is the queue enabled? { if (openQueue() <= 0) { sendRaw("NOTICE $1 :All slots are full-- queue of " . xgv("queue", 0) . " is full. Try again later."); } else if (inQueue($1)) # if this is true, QUEUE_POS and XDCC_DESC will be set for us :) { sendRaw("NOTICE $1 :You are already in queue position $QUEUE_POS to receive: $XDCC_DESC"); } else { $XDCC_GETS++; savePacket(); push(@XDCC_QUEUE, $1 . ":::" . $XDCC_FILE); $QUEUE_POS = size(@XDCC_QUEUE); sendRaw("NOTICE $1 :\bDCC Limit reached:\b Will send you $XDCC_DESC $+ , which is one file, when a slot opens"); sendRaw("NOTICE $1 :You are in queue position $QUEUE_POS of " . xgv("queue", 0)); } } else { sendRaw("NOTICE $1 :Already sending max number of files."); } return; } } alias xdcc { xdcc_load(xgv("loaded", "default-xlist")); if (lc($1) eq "offer") { resetPacket(); $PACK = size(@XDCC_PACKETS) + 1; $oldPrompt = getWindowPrompt(getActiveWindow()); setInputText(getActiveWindow(), ""); _xdcc_get_file($2); # let the alias finish processing first... } else if (lc($1) eq "doffer") { if ($2 eq '*') { @XDCC_PACKETS = array(); xecho("removed all packs"); } else { loadPacket(@XDCC_PACKETS[$2 - 1]); removeAt(@XDCC_PACKETS, $2 - 1); xecho("removed pack \b $+ $2 $+ \b from offer list"); } xdcc_save(); } else if (lc($1) eq "save" && $2 ne "") { xdcc_save($2, 1); } else if (lc($1) eq "load" && $2 ne "") { xdcc_load($2, 1); } else if (lc($1) eq "set" && $2 eq "") { xecho("LIST - " . xgvPretty("list", 1)); xecho("MINSPEED - " . formatBytes(xgv("minspeed", 0)) . "/sec"); xecho("QUEUE - " . xgv("queue", 0) . " total slots"); xecho("SLOTS - " . xgv("slots", 10) . " total slots"); xecho("SRECORD - " . xgvPretty("srecord", 1)); xecho("Use /XDCC set var [value] <1 = on | 0 = off>"); } else if (lc($1) eq "help" && lc($2) eq "set") { xecho("LIST - allow users to xdcc list you"); xecho("MINSPEED - set required transfer speed"); xecho("QUEUE - set number of queue slots"); xecho("SLOTS - set total simultaneous gets allowed"); xecho("SRECORD - show transfer speed record in plist"); xecho("Use /XDCC set var [value] <1 = on | 0 = off>"); } else if (lc($1) eq "help" && $2 ne "") { if (lc($2) eq "timer") { xecho("TIMER - /xdcc timer "); xecho(" sets timer to send packet list to target every n minutes"); } else if (lc($2) eq "plist") { xecho("PLIST - /xdcc plist [target]"); xecho(" sends a packet listing to the specified target"); } else if (lc($2) eq "desc" || lc($2) eq "note" || lc($2) eq "pass") { $tt = uc($2); xecho("$[7]tt - /xdcc $2 "); xecho(" sets the $2 for packet n"); } else if ($2 ne "") { $tt = uc($2); xecho("$[7]tt - no help available, try guessing"); } } else if (lc($1) eq "set") { xsv(lc($2), $3); if (lc($2) eq "list" || lc($2) eq "srecord") { xecho("$2 set to " . xgvPretty($2, $3)); } else if (lc($2) eq "minspeed") { xecho("$2 set to " . formatBytes($3) . "/sec"); } else if (lc($2) eq "slots" || lc($2) eq "queue") { xecho("$2 set to " . xgv(lc($2), $3) . " slots"); } else { xecho("Set $2 to $3"); } } else if ($1 eq "plist") { if ($2 eq "") { xdcc_list($active); } else { xdcc_list($2); } } else if ($1 eq "list") { echo("# size gets description"); $idx = 1; foreach $packet (@XDCC_PACKETS) { loadPacket($packet); $sz = formatBytes(lof($XDCC_FILE)); if ($XDCC_PASS ne "") { $XDCC_DESC = "[\bpassword\b] $XDCC_DESC"; } echo("$[3]idx $[8]sz $[7]XDCC_GETS $XDCC_DESC"); if ($XDCC_NOTE ne "") { echo((" " x 21) . "\b^\b- $XDCC_NOTE"); } $idx++; } } else if ($1 eq "desc") { loadPacket(@XDCC_PACKETS[$2 - 1]); $XDCC_DESC = $3-; savePacket(); xecho("Description for pack $2 set to: $3-"); } else if ($1 eq "note") { loadPacket(@XDCC_PACKETS[$2 - 1]); $XDCC_NOTE = $3-; savePacket(); xecho("Note for pack $2 set to: $3-"); } else if ($1 eq "pass") { loadPacket(@XDCC_PACKETS[$2 - 1]); $XDCC_PASS = $3-; savePacket(); if ($3- eq "") { xecho("Password for pack $2 removed"); } else { xecho("Password for pack $2 set"); } } else if ($1 eq "timer") { if ($2 eq "off" || $2 == 0) { stopTimer($XDCC_TIMER); xecho("Stopped xdcc timer."); } else { xecho("timer set to plist to $3 every $2 minutes"); $XDCC_TIMER = addTimer(&xdcc_timer, $2 * 1000 * 60); $XDCC_TARGET = $3; } } else { xecho("SET - set different xdcc options"); xecho("LIST - show current packet list"); xecho("PLIST - sends pack list to nick/chan"); xecho("TIMER - sets a timer to plist to a nick/chan"); xecho("OFFER - adds a new pack"); xecho("DOFFER - deletes a pack"); xecho("NOTE - change the note for a pack"); xecho("DESC - change the description for a pack"); xecho("PASS - set a password for a pack"); xecho("Use /XDCC HELP [command] for more information"); } } # # xecho("text") - echos an XDCC related message to the user # sub xecho { echo(parseSet("XDCC_ECHO", $1)); } sub openSlots { return xgv("slots", 10) - getTotalSends(); } # # generateBanner() - generates the header for an xdcc packet listing # sub openQueue { $queueUsed = $queueSize - size(@XDCC_QUEUE); return $queueUsed; } sub generateBanner { $slotsUsed = openSlots(); $queueSize = xgv("queue", 0); $queueUsed = $queueSize - size(@XDCC_QUEUE); $pack = "pack"; if (size(@XDCC_PACKETS) > 1) { $pack = "packs"; } $banner = "\b**\b " . size(@XDCC_PACKETS) . " $pack \b**\b \b $+ $slotsUsed $+ \b of \b" . xgv("slots", 10) . "\b slots open"; if (int($queueSize) > 0) { $banner = "$banner $+ , queue \b $+ $queueUsed $+ / $+ $queueSize $+ \b"; } if (xgv("minspeed", 0) ne "0") { $minSpeed = formatBytes(xgv("minspeed", 0)); $banner = "$banner $+ , Min: \u $+ $minSpeed $+ \u/s"; } if (xgv("srecord", "1") ne "0") { $record = formatBytes(xgv("record", 0)); $banner = "$banner $+ , Record: \u $+ $record $+ \u/s"; } return $banner; } # # xdcc_list(target) - sends an xdcc list to the specified target # sub xdcc_list { if (size(@XDCC_PACKETS) == 0) { if (-ischannel $1) { xecho("no packs are being offered at this time."); } else { sendXMessage($1, "Sorry, no packs are being offered at this time."); } return; } sendXMessage($1, generateBanner()); setupAligns(); $index = 1; foreach $packet (@XDCC_PACKETS) { loadPacket($packet); sendXMessage($1, "\b# $+ $[$pack_maxlen]index $+ \b $[$gets_maxlen]XDCC_GETS $+ x [\u $+ $[$size_maxlen]XDCC_SIZE $+ \u] $XDCC_DESC"); if ($XDCC_NOTE ne "") { sendXMessage($1, "\r \r\b^\b- $XDCC_NOTE"); } $index++; } xdcc_load_snag(); sendXMessage($1, "Total Offered: \u $+ $total_size $+ \u Total Snagged: \u" . formatBytes($XDCC_SNAG) . "\u"); } # # setupAligns() - sets some variables for nice formatting of the xdcc packet list # sub setupAligns { $gets_maxlen = 0; $size_maxlen = 0; $total_size = 0; foreach $packet (@XDCC_PACKETS) { @blah = getPacket($packet); if (strlen(@blah[3]) > $gets_maxlen) { $gets_maxlen = strlen(@blah[3]); } if (strlen(@blah[4]) > $size_maxlen) { $size_maxlen = strlen(@blah[4]); } $total_size = $total_size + lof($packet); } $total_size = formatBytes($total_size); $pack_maxlen = strlen(size(@XDCC_PACKETS)); $size_maxlen = $size_maxlen * -1; $gets_maxlen = $gets_maxlen * -1; } # # getTotalSends() - a utility method for obtaining the total number of DCC Sends # sub getTotalSends { local('@conns $xx'); $xx = 0; @conns = getAllConnections(); foreach $var (@conns) { if (getConnectionType($var) eq "SEND" && getConnectionState($var) ne "CLOSED") { $xx++; } } return $xx; } # # sendXMessage(target, text) - a convienence method to make sure XDCC messages are only echo'd as being # sent if they are sent to a public channel. # sub sendXMessage { if (-ischannel $1) { sendMessage($1, $2); } else { sendRaw("PRIVMSG $1 : $+ $2"); } } # # functions for managing packet data... # # savePacket() - assumed $XDCC_FILE is set and other values... sub savePacket { $XDCC_SIZE = formatBytes(lof($XDCC_FILE)); xsv($XDCC_FILE, "$XDCC_FILE $+ === $+ $XDCC_DESC $+ === $+ $XDCC_NOTE $+ === $+ $XDCC_GETS $+ === $+ $XDCC_SIZE $+ === $+ $XDCC_PASS"); iff($1 eq "", xdcc_save(), ""); return $XDCC_FILE; } # loadPacket("filename") - uNF sub loadPacket { ($XDCC_FILE, $XDCC_DESC, $XDCC_NOTE, $XDCC_GETS, $XDCC_SIZE, $XDCC_PASS) = getPacket($1); } sub getPacket { return matches(xgv($1), '(.*?)===(.*?)===(.*?)===(.*?)===(.*?)===(.*?)'); } sub resetPacket { ($XDCC_FILE, $XDCC_DESC, $XDCC_NOTE, $XDCC_PASS) = ""; $XDCC_GETS = 0; $XDCC_SIZE = "0b"; } # # functions for getting XDCC information from the editbox # sub _xdcc_get_file { setWindowPrompt(getActiveWindow(), "Add file to pack # $+ $PACK : "); if ($1 eq "") { setInputText(getActiveWindow(), showFileDialog("Select file for pack")); } else { setInputText(getActiveWindow(), $1); } wait input { if ($1- eq "") { setWindowPrompt(getActiveWindow(), $oldPrompt); } else { $XDCC_FILE = $1-; _xdcc_get_description(); halt; } } } sub _xdcc_get_description { setWindowPrompt(getActiveWindow(), "Description of pack # $+ $PACK : "); wait input { if ($1- eq "") { setWindowPrompt(getActiveWindow(), $oldPrompt); } else { $XDCC_DESC = $1-; push(@XDCC_PACKETS, savePacket(1)); xdcc_save(); xecho("added pack #\b" . size(@XDCC_PACKETS) . "\b, \" $+ $XDCC_DESC $+ \" (\b" . formatBytes(lof($XDCC_FILE)) . "\b)"); _xdcc_get_note(); halt; } } } sub _xdcc_get_note { setWindowPrompt(getActiveWindow(), "Notes for pack # $+ $PACK : "); wait input { if ($1- ne "") { $XDCC_NOTE = $1-; savePacket(); xecho("added note to pack #\b" . size(@XDCC_PACKETS) . "\b: $XDCC_NOTE"); } setWindowPrompt(getActiveWindow(), $oldPrompt); halt; } } on send_complete { local('$conn'); $conn = getDCCConnection($this); # obtain a reference to the dcc connection, cumbersome I know... xdcc_load_snag(); $XDCC_SNAG = $XDCC_SNAG + getBytesSent($conn); xdcc_save_snag(); if (getTransferRate($conn) > xgv("record", 0)) { xsv("record", getTransferRate($conn)); $string = "\bNEW RECORD\b: " . formatBytes(xgv("record", 0)) . "/sec set by"; xecho("$string " . getDCCNickname($conn)); sendRaw("NOTICE " . getDCCNickname($conn) . " : $+ $string you!"); } checkQueue(); } on send_failed { checkQueue(); } sub xgv { return getProperty("xdcc." . lc($1), $2); } sub xgvPretty { if (xgv($1, $2) == 0) { return "Off"; } else { return "On"; } } sub xsv { setProperty("xdcc." . lc($1), $2); } sub checkMinSpeed { local('@conns $xx $minspeed $yy'); $minspeed = xgv("minspeed", 0); if ($minspeed == 0) { checkQueue(); return; # minspeed is disabled, i.e. don't use it!@ } @conns = getActiveConnections(); foreach $var (@conns) { if (getConnectionType($var) eq "SEND" && getTransferRate($var) < $minspeed && getDCCTotalTime($var) > 20) { $xx = formatBytes(getTransferRate($var)) . "/sec"; $yy = formatBytes($minspeed) . "/sec"; sendRaw("NOTICE " . getDCCNickname($var) . " :\bMINSPEED:\b $xx less than minspeed of $yy $+ : Closing connection."); xecho("closed send to " . getDCCNickname($var) . ", $xx less than minspeed of $yy"); closeDCC($var); } } checkQueue(); } # # queue related functions # sub checkQueue { while (size(@XDCC_QUEUE) > 0 && openSlots() > 0) { @temp = split(':::', shift(@XDCC_QUEUE)); loadPacket(@temp[1]); if (size(getChannels(@temp[0])) > 0) { sendRaw("NOTICE " . @temp[0] . " :\bSending\b you $XDCC_DESC which is $XDCC_SIZE"); xecho("Sending \" $+ $XDCC_DESC $+ \" to \u" . @temp[0] . "\u"); call("/dcc send " . @temp[0] . " " . $XDCC_FILE); } else { xecho("User: \"" . @temp[0] . "\" is not on any channels... grrr " . getChannels(@temp[0])); } } } # # inQueue(nick) - returns 1 if nickname is in queue # sub inQueue { local('@temp $var $x'); $x = 1; foreach $var (@XDCC_QUEUE) { @temp = split(":::", $var); if (@temp[0] eq $1) { loadPacket(@temp[1]); $QUEUE_POS = $x; return 1; } $x++; } return 0; } sub xdcc_timer { call("/xdcc plist $XDCC_TARGET"); } # # load/save functions # sub xdcc_save_snag { setProperty("snagged." . xgv("loaded", "default-xlist"), $XDCC_SNAG); } sub xdcc_load_snag { $XDCC_SNAG = getProperty("snagged." . xgv("loaded", "default-xlist"), 0); } sub xdcc_save { if (!-istrue $1) { xdcc_save(xgv("loaded", "default-xlist")); return; } setPropertyList("xlist. $+ $1", @XDCC_PACKETS); xdcc_save_snag(); if ($2) { xecho("saved " . size(@XDCC_PACKETS) . " packets to $1"); } xsv("loaded", $1); } sub xdcc_load { xdcc_load_snag(); @XDCC_PACKETS = getPropertyList("xlist. $+ $1"); if ($2) { xecho("loaded " . size(@XDCC_PACKETS) . " packets from $1"); xsv("loaded", $1); } } # # execute this stuff once the script is loaded... # # load last used packet list... xdcc_load(xgv("loaded", "default-xlist"), 1); # check minspeed every 30 seconds... repeating infinitely... checks queue as well $XDCC_TIMER2 = iff($XDCC_TIMER2 eq "", addTimer(&checkMinSpeed, 30 * 1000), $XDCC_TIMER2); # # some events to handle cleanup # on exit { xdcc_save(xgv("loaded", "default-xlist")); } on unload { iff($XDCC_TIMER, stopTimer($XDCC_TIMER), ""); iff($XDCC_TIMER2, stopTimer($XDCC_TIMER2), ""); }