; makeTorrent Torrent Creator by Scab ; ; /maketorrent ; ; TODO: Add md5sum to info dict (configurable; isn't actually part of the original standard. would also make the script a lot slower) ; Automatic piece size determination to keep metafile size low(er) ; Support for announce-list metainfo (multitracker torrents) ; Support for making trackerless torrents ; List of last x used trackers alias maketorrent { dialog -m maketorrent maketorrent } menu menubar { - .&makeTorrent ..&Launch:maketorrent ..&Clear History:if ($input(Are you sure you want to clear the makeTorrent history?,ywd,makeTorrent)) { unset %maketorrent_last* %maketorrent_fullsize %maketorrent_lastpc | echo -esa * Cleared makeTorrent history. } ..- ..&Uninstall:if ($input(Are you sure you want to uninstall makeTorrent?,ywd,makeTorrent)) !unload -rs $qt($script) } on *:load:{ echo -esa * $maketorrentversion(local) loaded successfully. A menubar popup menu has been added. You can also launch the script using the /maketorrent command. } on *:unload:{ unset %maketorrent_* } dialog maketorrent { title "makeTorrent/0.2" size -1 -1 188 108 option dbu box "Source", 1, 4 2 180 36 button "Add file", 2, 102 24 37 9 button "Add folder", 3, 141 24 37 9 combo 4, 10 12 168 44, size drop box "Torrent Properties", 5, 4 42 180 48 edit "", 6, 46 52 132 10 edit "", 7, 46 64 132 10 text "Tracker:", 8, 10 53 35 7 text "Comment:", 9, 10 66 35 7 check "Private torrent", 10, 127 79 50 8 button "Create torrent", 11, 134 94 50 11 button "Close", 12, 95 94 37 11 text "", 13, 6 96 80 8 } on *:dialog:maketorrent:*:*:{ if ($devent == init) { mtlast5 if (%maketorrent_lasttracker) did -a $dname 6 %maketorrent_lasttracker if (%maketorrent_lastcomment) did -a $dname 7 %maketorrent_lastcomment if (%maketorrent_lastprivate == 1) did -c $dname 10 } if ($devent == sclick) { if ($did isnum 2-3) { if ($gettok(%maketorrent_last5,-1,124)) var %dir = $nofile($v1) else var %dir = $left($scriptdir,3) var %infile = $iif($did == 2,$$sfile(%dir,Select file,Open),$$sdir(%dir,Select folder)) mtlast5 %infile } elseif ($did == 10) set %maketorrent_lastprivate $did($did).state elseif ($did == 11) { var %in = $qt($did($dname,4).seltext), %tracker = $did($dname,6), %private = $iif($did($dname,10).state isnum 0-1,$v1,0), %comment = $did($dname,7) if (%tracker) { if ($exists(%in)) { ; unset vars if they remain from last time unset %maketorrent_fullsize unset %maketorrent_lastpc ; get size of file if ($isfile(%in)) set %maketorrent_fullsize $file(%in).size ; get size of dir elseif ($isdir(%in)) { var %i = 1 while ($findfile(%in,*,%i)) { dll $whilefix WhileFix . inc %maketorrent_fullsize $file($v1).size inc %i } } ; generate metainfo file if (%maketorrent_fullsize isnum) { _maketorrent $+(%tracker,$chr(124),%in,$chr(124),%private,$iif(%comment != $null,$+($chr(124),%comment))) } else !noop $input(Unexpected error.,ohd,Error) } else !noop $input(The source file/folder does not exist.,ohd,Error) } else !noop $input(You must specify a tracker.,ohd,Error) } elseif ($did == 12) dialog -x $dname } elseif ($devent == edit) { if ($did isnum 6-7) set %maketorrent_last [ $+ [ $replace($did,6,tracker,7,comment) ] ] $did($did) } } alias -l mtlast5 { if ($1) { set %maketorrent_last5 $addtok(%maketorrent_last5,$1-,124) if ($numtok(%maketorrent_last5,124) > 5) set %maketorrent_last5 $deltok(%maketorrent_last5,1,124) } if ($dialog(maketorrent)) { did -r maketorrent 4 var %x = $numtok(%maketorrent_last5,124) while (%x > 0) { dll $whilefix WhileFix . did -a maketorrent 4 $gettok(%maketorrent_last5,%x,124) dec %x } did -c maketorrent 4 1 } } ; /_maketorrent |||[comment] alias -l _maketorrent { if ($numtok($1-,124) > 1) { tokenize 124 $1- var %tracker = $1, %file = $qt($2), %private = $3, %comment = $4- if ($isfile($2)) var %type = file elseif ($isdir($2)) var %type = dir if (%type) { ; tracker data var %meta = d8:announce $+ $len(%tracker) $+ : $+ %tracker ; comment if (%comment != $null) var %meta = %meta $+ 7:comment $+ $len(%comment) $+ : $+ %comment ; creation data var %meta = %meta $+ 10:created by $+ $len($maketorrentversion) $+ : $+ $maketorrentversion $+ 13:creation datei $+ $ctime $+ e ; encoding ; there doesn't appear to be a reliable way of determining Windows' language setting for non-unicode programs from mIRC. var %meta = %meta $+ 8:encoding4:ANSI ; single-file torrent if (%type == file) { ; info dict (256KB piece size) var %lof = $lof(%file), %piecesize = 262144 var %meta = %meta $+ 4:infod6:lengthi $+ %lof $+ e4:name $+ $len($nopath(%file)) $+ : $+ $nopath(%file) $+ 12:piece lengthi $+ %piecesize $+ e ; pieces var %x = 0 while (%x <= %lof) { dll $whilefix WhileFix . bread %file %x %piecesize &piece var %hash = $sha1(&piece,1), %y = 1, %twentyb while (%y <= $len(%hash)) { dll $whilefix WhileFix . var %twentyb = %twentyb $base($mid(%hash,%y,2),16,10) inc %y 2 } bset &twentyb 1 %twentyb bcopy &pieces $calc(1 + $bvar(&pieces,0)) &twentyb 1 -1 bunset &twentyb inc %x %piecesize if ($dialog(maketorrent)) { var %pc = $round($calc((%x / %maketorrent_fullsize)*100),0) ; avoid updating the dialog unnecessarily (mainly reduces flickering) if (%pc != %maketorrent_lastpc) { set %maketorrent_lastpc %pc if (%x > %maketorrent_fullsize) var %pc = 100 else did -i maketorrent 13 1 Generating torrent file... %pc $+ % } } } bset -t &torrent 1 %meta $+ 6:pieces $+ $bvar(&pieces,0) $+ : } ; multi-file torrent elseif (%type == dir) { ; info dict (256KB piece size) bset -t &torrent 1 %meta $+ 4:infod5:filesl if ($dialog(maketorrent)) did -i maketorrent 13 1 Parsing directory structure... var %f = 1, %fn = $findfile(%file,*,0), %piecesize = 262144 ; findfile lists files before dirs. this needs to be switched around.. if ($window(@maketorrent_dirs)) window -c @maketorrent_dirs if ($window(@maketorrent_files)) window -c @maketorrent_files if ($window(@maketorrent)) window -c @maketorrent window -hs @maketorrent_dirs window -hs @maketorrent_files window -h @maketorrent ; separate files and folders while (%f <= %fn) { dll $whilefix WhileFix . var %ff = $findfile(%file,*,%f), %relativepath = $mid(%ff,$calc($len($noqt(%file)) + 1),$len(%ff)) if (\* iswm %relativepath) var %relativepath = $mid(%relativepath,2,$calc($len(%relativepath) - 1)) if (*\* iswm %relativepath) aline @maketorrent_dirs %ff else aline @maketorrent_files %ff inc %f } ; add all folders to new list var %i = 1 while (%i <= $line(@maketorrent_dirs,0)) { dll $whilefix WhileFix . aline @maketorrent $line(@maketorrent_dirs,%i) inc %i } ; add all files to new list var %i = 1 while (%i <= $line(@maketorrent_files,0)) { dll $whilefix WhileFix . aline @maketorrent $line(@maketorrent_files,%i) inc %i } ; proceed using @maketorrent as the file list ; generate metadata for files var %f = 1, %fn = $line(@maketorrent,0) while (%f <= %fn) { dll $whilefix WhileFix . var %ff = $line(@maketorrent,%f), %path = $mid(%ff,$calc($len($noqt(%file)) + 1),$len(%ff)), %lof = $lof(%ff) if (*\* iswm %path) { var %tok = 1, %toks = $numtok(%path,92), %out = d6:lengthi $+ %lof $+ e4:path while (%tok <= %toks) { dll $whilefix WhileFix . var %part = $gettok(%path,%tok,92) var %out = %out $+ $iif(%tok == 1,l) $+ $len(%part) $+ : $+ %part inc %tok } var %out = %out $+ ee bset -t &torrent $calc(1 + $bvar(&torrent,0)) %out } else bset -t &torrent $calc(1 + $bvar(&torrent,0)) d6:lengthi $+ %lof $+ e4:pathl $+ $len(%path) $+ : $+ %path $+ ee inc %f } ; end info dict bset -t &torrent $calc(1 + $bvar(&torrent,0)) e ; generate pieces var %filenr = 1, %pos = 0, %toread = %piecesize, %totread :read var %filename = $qt($line(@maketorrent,%filenr)) if ($isfile(%filename)) { bread %filename %pos %toread &read var %read = $bvar(&read,0) inc %totread %read if (%read == %toread) { if ($bvar(&piece,0) > 0) { bcopy &piece $calc(1 + $bvar(&piece,0)) &read 1 -1 } else bcopy &piece 1 &read 1 -1 ;generate piece :makepiece var %hash = $sha1(&piece,1), %y = 1, %twentyb while (%y <= $len(%hash)) { dll $whilefix WhileFix . var %twentyb = %twentyb $base($mid(%hash,%y,2),16,10) inc %y 2 } bset &twentyb 1 %twentyb bcopy &pieces $calc(1 + $bvar(&pieces,0)) &twentyb 1 -1 bunset &twentyb if ($dialog(maketorrent)) { var %pc = $round($calc((%totread / %maketorrent_fullsize)*100),0) ; avoid updating the dialog unnecessarily (mainly reduces flickering) if (%pc != %maketorrent_lastpc) { set %maketorrent_lastpc %pc if (%totread > %maketorrent_fullsize) var %pc = 100 else did -i maketorrent 13 1 Generating torrent file... %pc $+ % } } bunset &piece inc %pos %read var %toread = %piecesize goto read } else { bcopy &piece $calc(1 + $bvar(&piece,0)) &read 1 -1 dec %toread %read inc %filenr var %pos = 0 if (%filenr > $line(@maketorrent,0)) { goto makepiece } goto read } } ; other metadata var %name = $gettok($noqt(%file),-1,92) bset -t &torrent $calc(1 + $bvar(&torrent,0)) 4:name $+ $len(%name) $+ : $+ %name $+ 12:piece lengthi $+ %piecesize $+ e6:pieces $+ $bvar(&pieces,0) $+ : } bcopy &torrent $calc(1 + $bvar(&torrent,0)) &pieces 1 -1 if (%private == 1) bset -t &torrent $calc(1 + $bvar(&torrent,0)) 7:privatei1e bset -t &torrent $calc(1 + $bvar(&torrent,0)) ee var %saveas = $qt($sfile($+($iif($isdir($nofile(%file)),$nofile(%file),$left($scriptdir,3)),$iif(%name,%name,$nopath(%file)),.torrent),Save as,Save)), %isfile = $isfile(%saveas) if ((%saveas) && (!%isfile)) || ((%saveas) && (%isfile) && ($input(File already exists. Do you want to replace it?,ywd,File exists))) { if (%isfile) .remove %saveas bwrite %saveas 0 &torrent !noop $input(Successfully saved metainfo file.,oid,$maketorrentversion(local)) if ($dialog(maketorrent)) dialog -v maketorrent } else { !noop $input(Aborted.,ohd,Error) if ($dialog(maketorrent)) dialog -v maketorrent } } else { !noop $input(File/Directory not found.,ohd,Error) if ($dialog(maketorrent)) dialog -v maketorrent } } } alias -l maketorrentversion return makeTorrent $+ $iif($1 != local,(mIRC)) $+ /0.2 alias -l whilefix return $qt($+($scriptdir,WhileFix.dll)) ; EOF