├── CHANGELOG.md ├── README.md ├── screenshot ├── bt-fold.png ├── export.png ├── login.png └── magnet.png └── xuanfeng.user.js /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | 4 | ## 0.8.0 5 | - **FIXED** 修复新版接口导致无法下载的问题。 6 | 7 | ## 0.7.5 8 | - **FIXED** 修正加入secret token后老版aria RPC无法使用的问题。 9 | 10 | ## 0.7.4 11 | - **IMPROVED** 去掉了ARIA RPC的HTTP用户名/密码验证,改用推荐的Secret token验证。 12 | 13 | ## 0.7.3 14 | - **FIXED** 迅雷禁掉了magnet接口,使用自建接口 [#19](https://github.com/rhyzx/xuanfeng-userscript/issues/19) 15 | 16 | ## 0.7.2 17 | - **FIXED** 百度云开始收费导致磁力链解析服务失效,迁移到gae 18 | 19 | ## 0.7.1 20 | - **FIXED** bt文件夹折叠修复 21 | 22 | ## 0.7.0 23 | - **NEW** 解除了下载限速 thanks [@4023](https://userscripts.org/users/381599) 24 | 25 | ## 0.6.3 26 | - **FIXED** 导出失效修复 27 | 28 | ## 0.6.2 29 | - **FIXED** #13 修复了官方md5库改动导致自动登录失效并无限载入资源的问题 30 | 31 | ## 0.6.1 32 | - **FIXED** magnet修复 33 | 34 | 35 | ## 0.6.0 36 | 最近官方更新了代码导致导出功能坏掉了所以先紧急发布0.6版本 37 | 38 | - **NEW** orbit导出 39 | - **TODO** bt文件夹折叠也跟着坏掉了待下个修复 40 | - **TODO** magnet也坏了是因为 @binux 那边的的接口出问题了~ magnet比较重要 所以会尽快解决 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | XuanFengEx 2 | ========== 3 | **已失效,官方已屏蔽 http 的下载地址获取接口** 4 | 5 | QQ旋风Web版增强脚本 6 | 7 | 8 | 基于 @maplebeats 的[js_for_xf](https://github.com/maplebeats/js_for_xf) 9 | 10 | 11 | Features 12 | -------- 13 | 14 | - [x] UI精简 15 | - [x] Aria2命令/文件导出 16 | - [x] Aria2 RPC 17 | - [x] IDM文件导出 18 | - [x] Orbit文件导出 19 | - [x] 自动登录 20 | - [x] magnet链接支持 21 | - [x] bt任务文件夹折叠 22 | - [x] 限速解除 thanks [@4023](https://userscripts.org/users/381599) 23 | - [ ] 批量任务添加 24 | 25 | 26 | Screenshots 27 | ----------- 28 | 29 | ![Export](https://raw.github.com/rhyzx/xuanfeng-userscript/master/screenshot/export.png) 30 | ![Magnet](https://raw.github.com/rhyzx/xuanfeng-userscript/master/screenshot/magnet.png) 31 | ![Login](https://raw.github.com/rhyzx/xuanfeng-userscript/master/screenshot/login.png) 32 | ![BT Fold](https://raw.github.com/rhyzx/xuanfeng-userscript/master/screenshot/bt-fold.png) 33 | 34 | 35 | 36 | LICENSE 37 | ------- 38 | 39 | MIT 40 | -------------------------------------------------------------------------------- /screenshot/bt-fold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhyzx/xuanfeng-userscript/dddb4caf5d3e228c3ec96a2e6a21652d1c6451be/screenshot/bt-fold.png -------------------------------------------------------------------------------- /screenshot/export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhyzx/xuanfeng-userscript/dddb4caf5d3e228c3ec96a2e6a21652d1c6451be/screenshot/export.png -------------------------------------------------------------------------------- /screenshot/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhyzx/xuanfeng-userscript/dddb4caf5d3e228c3ec96a2e6a21652d1c6451be/screenshot/login.png -------------------------------------------------------------------------------- /screenshot/magnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rhyzx/xuanfeng-userscript/dddb4caf5d3e228c3ec96a2e6a21652d1c6451be/screenshot/magnet.png -------------------------------------------------------------------------------- /xuanfeng.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name XuanFengEx 3 | // @namespace https://github.com/rhyzx/xuanfeng-userscript 4 | // @version 0.8.0 5 | // @description QQ旋风网页版离线下载增强 6 | // @match http://lixian.qq.com/main.html* 7 | // @copyright 2016+, rhyzx 8 | // ==/UserScript== 9 | 10 | 11 | /** 12 | * export downloads 13 | */ 14 | injectScript(function () { 15 | // ====== 16 | 17 | var $ = window.jQuery // v1.6.1 18 | , msg = window.XF.widget.msgbox 19 | 20 | // export / rewrite 21 | $('#task_dl_local em').text('导出下载') 22 | EventHandler.task_batch2local = function (e) { 23 | if ($(e).hasClass('disabled_btn')) return 24 | msg.show('获取下载地址中...', 0, 5000) 25 | 26 | requestDownloadLinks(function (dls) { 27 | msg.hide() 28 | g_pop_export.setDownloads(dls) 29 | g_pop_export.show() 30 | }) 31 | } 32 | 33 | 34 | 35 | // get selected tasks' download link/cookie/filename 36 | // callback(dowloads) 37 | function requestDownloadLinks(callback) { 38 | var count = 0 39 | , downloads = [] 40 | 41 | // TODO? pre-check task status by 42 | // $.getJSON('/handler/lixian/get_lixian_items.php') 43 | $.Deferred().resolve(g_task_op.last_task_info) 44 | .done(function (res) { 45 | $.each(res, function (i, task) { 46 | // check 47 | if ( 48 | !$('#task_sel_' +task.mid).is(':checked')|| // user selected 49 | task.file_size !== task.comp_size || // download finished 50 | task.dl_status !== TASK_STATUS['ST_UL_OK'] 51 | ) return 52 | 53 | 54 | count++ 55 | $.post('/handler/lixian/get_http_url.php', { 56 | hash : task.hash 57 | , filename: task.file_name 58 | //, g_tk : getACSRFToken(cookie.get('skey', 'qq.com')) 59 | //, browser : 'other' 60 | }, null, 'json') 61 | .done(function (res) { 62 | count-- 63 | if (res && res.ret === 0) { 64 | // break speed limit 65 | // thanks @4023 https://userscripts.org/users/381599 66 | var url = res.data.com_url 67 | .replace('xflx.store.cd.qq.com:443', 'xfcd.ctfs.ftn.qq.com') 68 | .replace('xflx.sz.ftn.qq.com:80', 'sz.disk.ftn.qq.com') 69 | .replace('xflx.cd.ftn.qq.com:80', 'cd.ctfs.ftn.qq.com') 70 | .replace('xflxsrc.store.qq.com:443', 'xfxa.ctfs.ftn.qq.com') 71 | 72 | downloads.push({ 73 | url : url 74 | , cookie : res.data.com_cookie 75 | , filename : task.file_name 76 | }) 77 | } 78 | }) 79 | .fail(function () { 80 | msg.show('获取失败', 2, 2000) 81 | }) 82 | .always(function () { 83 | if (count === 0) { 84 | // sort according to filename 85 | downloads.sort(function (a, b) { 86 | return a.filename.localeCompare(b.filename) 87 | }) 88 | callback(downloads) 89 | } 90 | }) 91 | 92 | }) 93 | }) 94 | .fail(function () { 95 | msg.show('获取列表的接口坏了嘛?! 请联系脚本作者', 2, 2000) 96 | }) 97 | } 98 | window.requestDownloadLinks = requestDownloadLinks // export to global 99 | 100 | /// ===== 101 | }) 102 | 103 | 104 | /** 105 | * aria rpc 106 | */ 107 | injectScript(function recall() { 108 | // ====== 109 | 110 | var $ = window.jQuery 111 | , msg = window.XF.widget.msgbox 112 | 113 | 114 | // button 115 | var $export = $('#task_dl_local') 116 | var $rpc = $export.clone() 117 | .removeAttr('onclick') 118 | .attr('id', 'task_dl_rpc') 119 | .find('em').text('RPC').end() 120 | .insertAfter($export) 121 | 122 | // diable/enable botton 123 | $(document).click(function () { 124 | $export.hasClass('disabled_btn') 125 | ? $rpc.addClass('disabled_btn') 126 | : $rpc.removeClass('disabled_btn') 127 | }) 128 | 129 | 130 | $rpc.click(function (evt) { 131 | if ($rpc.hasClass('disabled_btn')) return 132 | 133 | var config = { 134 | url : localStorage.getItem('rpc-url') 135 | , token : localStorage.getItem('rpc-token') 136 | } 137 | if (config.url) { 138 | msg.show('获取下载地址中...', 0, 5000) 139 | requestDownloadLinks(function (dls) { 140 | msg.show('rpc请求中...', 0, 5000) 141 | 142 | rpc(dls, config) 143 | .done(function (res) { 144 | msg.show('成功', 1, 2000) 145 | }) 146 | .fail(function ($xhr, status, error) { 147 | msg.show('rpc请求失败,请检查设置,Message: ' +error, 2, 2000) 148 | g_pop_rpc.showConfig(config) 149 | }) 150 | }) 151 | } else { 152 | msg.show('rpc未设置', 3, 2000) 153 | g_pop_rpc.showConfig() // default url 154 | } 155 | }) 156 | 157 | 158 | function rpc(dls, config) { 159 | var data = [] 160 | $.each(dls, function (k, dl) { 161 | var ret = { 162 | jsonrpc : '2.0' 163 | , id : 'down_' +k 164 | , method : 'aria2.addUri' 165 | , params : [ 166 | [dl.url] 167 | , { 168 | out : dl.filename 169 | , header : 'Cookie: FTN5K=' +dl.cookie 170 | , continue: 'true' 171 | , split : '10' 172 | , 'max-connection-per-server' : '10' 173 | } 174 | ] 175 | } 176 | if (config.token) { 177 | ret.params.unshift('token:' +config.token) 178 | } 179 | data.push(ret) 180 | }) 181 | 182 | // return Deferred Obj 183 | return $.post(config.url, JSON.stringify(data)) 184 | // filter error 185 | .pipe(function (res, status, $xhr) { 186 | if (res[0].error) { 187 | return $.Deferred().reject($xhr, 'error', res[0].error.message) 188 | } 189 | }) 190 | } 191 | 192 | /// ===== 193 | }) 194 | 195 | 196 | /** 197 | * auto login 198 | */ 199 | injectScript(function recall() { 200 | // ====== 201 | 202 | // function from http://imgcache.qq.com/ptlogin/ver/10021/js/comm.js 203 | var hexchar2bin=function(str){var arr=[];for(var i=0;i>5]|=128<>>9<<4)+14]=n;var t=1732584193;var u=-271733879;var e=-1732584194;var v=271733878;for(var i=0;i>16)+(n>>16)+(t>>16);return a<<16|t&65535}function s(r,n){return r<>>32-n}function A(r){var n=Array();var a=(1<>5]|=(r.charCodeAt(u/t)&a)<>2]>>u%4*8+4&15)+t.charAt(n[u>>2]>>u%4*8&15)}return a}return u}(); 205 | 206 | var $ = window.jQuery 207 | , msg = window.XF.widget.msgbox 208 | , cookie = window.QZFL.cookie 209 | 210 | // rewrite 211 | QQXF.COMMON.backToLogin = function (time) { 212 | msg.hide() 213 | if (time === 13) return logout() // user click logout 214 | 215 | var uin = localStorage.getItem('uin') 216 | , passhex = localStorage.getItem('passhex') 217 | 218 | // autologin 219 | if (uin && passhex) { 220 | msg.show('自动登录中...', 0, 5000, true) 221 | checkVC(uin, function (code, vcode, vc) { 222 | if (code == '0') { // no captcha 223 | login(uin, passhex, vcode, vc) 224 | } else { // captcha 225 | g_pop_login.showVC(function (vcode) { 226 | login(uin, passhex, vcode, vc) 227 | }, uin) 228 | } 229 | }) 230 | } else { 231 | // self login 232 | g_pop_login.showLogin(function (uin, pass, vcode, vc, save) { 233 | var passhex = hexchar2bin( md5(pass) ) 234 | 235 | localStorage.setItem('uin', uin) 236 | if (save) { // save pass 237 | localStorage.setItem('passhex', passhex) 238 | } 239 | 240 | login(uin, passhex, vcode, vc) 241 | }, uin) 242 | } 243 | } 244 | 245 | // vc 246 | var vcallback 247 | function checkVC(uin, callback) { 248 | vcallback = callback 249 | $.getScript('http://check.ptlogin2.qq.com/check?uin=' +uin) 250 | } 251 | window.checkVC = checkVC // export 252 | // check vc callback 253 | //ptui_checkVC('0','!JTF','\x00\x00\x00\x00\x20\x56\x38\xb0'); 254 | window.ptui_checkVC = function (code, vcode, vc) { 255 | vcallback.apply(null, arguments) 256 | } 257 | 258 | // login main 259 | function login (uin, passhex, vcode, vc) { 260 | $.getScript(['http://ptlogin2.qq.com/login' 261 | , '?u=' +uin 262 | , '&p=' +md5( md5(passhex+vc) +vcode.toUpperCase() ) 263 | , '&verifycode=' +vcode 264 | 265 | // useles but necessary for request 266 | , '&u1=http%3A%2F%2Fqq.com&aid=1&h=1&from_ui=1&g=1' 267 | ].join('')) 268 | } 269 | 270 | // login callback 271 | // code? ? url ? info usr 272 | //ptuiCB('4','3','','0','登录失败,请重试。*', '100000'); 273 | window.ptuiCB = function (code, x, url, x2, tip, usr) { 274 | if (code == '0') { 275 | msg.show(tip, 1, 5000) 276 | } else { 277 | msg.show(tip, 2, 5000) 278 | localStorage.removeItem('passhex') 279 | } 280 | 281 | setTimeout(function () { 282 | window.location.reload() 283 | }, 800) 284 | } 285 | 286 | 287 | // logout main 288 | function logout() { 289 | cookie.del('uin', 'qq.com') 290 | cookie.del('skey', 'qq.com') 291 | localStorage.removeItem('uin') 292 | localStorage.removeItem('passhex') 293 | msg.show('已退出', 3, 2000) 294 | window.location.reload() 295 | } 296 | /// ===== 297 | }) 298 | 299 | 300 | /** 301 | * magnet 302 | */ 303 | injectScript(function () { 304 | // ====== 305 | var $ = window.jQuery 306 | , msg = window.XF.widget.msgbox 307 | 308 | 309 | // orignal code by binux 310 | // https://gist.github.com/binux/4585941 311 | $('#input_tips').text('请输入HTTP/eD2k/magnet链接').each(function () { 312 | var $tips = $(this) 313 | // rewrite 314 | var _info = EventHandler.set_hide_info 315 | 316 | , input = $('#dl_url_id').get(0) 317 | 318 | var isMagnet = /^magnet:\?/i 319 | EventHandler.set_hide_info = function () { 320 | var url = input.value//.replace(/,/g, '_') 321 | 322 | if ( isMagnet.test(url) ) { 323 | addMagnetTask(url) 324 | 325 | // clean up 326 | input.value = '' 327 | $tips.blur() 328 | } else { 329 | _info.apply(EventHandler, arguments) 330 | } 331 | 332 | } 333 | }) 334 | 335 | 336 | 337 | // mock bt upload function 338 | // extract show bt files select function 339 | var showFileList = (function () { 340 | var AjaxUpload = window.AjaxUpload 341 | var showFileList 342 | window.AjaxUpload = function ($e, options) { 343 | showFileList = options.onComplete 344 | } 345 | window.initTorrent() // call 346 | window.AjaxUpload = AjaxUpload // revert 347 | 348 | return showFileList 349 | })() 350 | 351 | 352 | function addMagnetTask(url) { 353 | window.g_pop_task.hide() 354 | msg.show('解析magnet链接中...', 0, 20000, true) 355 | 356 | $.ajax({ 357 | // callback name is hard coded 358 | url : 'http://pew.rhyzx.im/magnet?callback=?' 359 | , data : { u : url } 360 | , cache : true 361 | , dataType: 'jsonp' 362 | }).done(function (res) { 363 | showFileList(null, JSON.stringify({ 364 | ret : 0 365 | , name: res.name 366 | , hash: res.infoHash.toLowerCase() 367 | , files : res.files.map(function (item, i) { 368 | return { 369 | file_index : item.index 370 | , file_name : item.name 371 | , file_size : item.length_f 372 | , file_size_ori : item.length 373 | } 374 | }) 375 | })) 376 | }).fail(function ($xhr) { 377 | msg.show('解析magnet链接失败:' + $xhr.responseText, 2, 2000) 378 | }) 379 | } 380 | 381 | /// ===== 382 | }) 383 | 384 | 385 | /** 386 | * fold bt 387 | * TODO update bt info when task update 388 | */ 389 | injectScript(function () { 390 | // ====== 391 | 392 | var $ = window.jQuery 393 | , format = new CTaskParaFormat 394 | 395 | // fix bt fold 396 | var _showList = CTaskOp.prototype.showListFromCache 397 | CTaskOp.prototype.showListFromCache = function (firstGet) { 398 | _showList.call(this, true) // always firstGet 399 | } 400 | 401 | // rewrite 402 | // add url to new task 403 | var _getInfo = CTaskOp.prototype.getTaskTemplateInfo 404 | CTaskOp.prototype.getTaskTemplateInfo = function (task) { 405 | var info = _getInfo.apply(this, arguments) 406 | if (!task.task_type && !task.file_url) { 407 | info.task_org_url = task.bt_id 408 | } 409 | return info 410 | } 411 | 412 | // rewrite 413 | var _show = QQVIP.template.show 414 | QQVIP.template.show = function (options) { 415 | var taskList = options.JSON, newList = [] 416 | 417 | var bt // last bt task 418 | , key = 0 419 | for (var i=0, task; task=taskList[i++];) { 420 | // show full name 421 | task.task_short_file_name = task.task_file_name 422 | 423 | // bt task url pattern: hash_index 424 | // eg. task_org_url: "DB7B0F2264494DAFCD20CACB410399CC65230819_0" 425 | var hash = (task.task_org_url || '').split('_') 426 | if (hash.length > 1) { // is bt 427 | if (!bt || bt.hash !== hash[0]) { // new bt 428 | bt = { 429 | hash : hash[0] 430 | , count : 0 431 | , cloudplayer_status : 'player_hide' 432 | //, cloudplayer_url: '###' 433 | , eyun_status : 'eyun_hide' 434 | //, hash: '181674167CD5C63034A212F2BD120BE8A7D8E5E9' 435 | //, not_empty: '' 436 | , org_file_size : 0 437 | //, player_status: 'player_ok' 438 | //, player_url: 'id=181674167CD5C63034A212F2BD120BE8A7D8E5E9&uin=542521520' 439 | //, task_dl_local_class: '' 440 | , task_dl_speed : 'BT任务' 441 | , task_done_percent : '0%' 442 | //, task_done_percent_class: 'green' 443 | , task_file_name : '[BT]' +task.task_file_name 444 | , task_file_size : '0' 445 | , task_file_type : 'icon_bt' 446 | , task_id : 'bt_' +key++ // key for select 447 | , task_left_days : task.task_left_days 448 | //, task_org_url: '8DAB9FC87D97F44B3C613C4F75D09094E3291DB6_6' 449 | //, task_org_url_class: 'elem_hide' 450 | , task_row_status : 'bt_row' 451 | //, task_share_class: '' 452 | , task_short_file_name : '[BT]' +task.task_file_name 453 | , task_status : 'icon_bt_unfold' 454 | } 455 | newList.push(bt) 456 | } 457 | 458 | // add class for toggle display 459 | task.task_row_status = (task.task_row_status || '') +' bt_task_row ' + bt.task_id 460 | 461 | // update bt summary info 462 | bt.count++ 463 | bt.org_file_size += task.org_file_size 464 | bt.task_file_size = format.formatFilesize(bt.org_file_size) 465 | var percent = parseInt(bt.task_done_percent)/bt.count * (bt.count- 1) 466 | + parseInt(task.task_done_percent)/bt.count 467 | 468 | bt.task_done_percent = percent.toFixed(2) +'%' 469 | 470 | 471 | bt.task_done_percent_class = bt.task_done_percent === '100%' ? 'green' : '' 472 | 473 | } 474 | 475 | 476 | newList.push(task) 477 | } 478 | 479 | options.JSON = newList 480 | _show.call(QQVIP.template, options) 481 | } 482 | 483 | // rewrite 484 | // toggle bt tasks display 485 | var isBt = /^bt_/, $curr = $() 486 | EventHandler.task_op_display = function (obj, taskid) { 487 | var $e = $(obj) 488 | 489 | // bt row, toggle it's task list 490 | if (taskid.match(isBt)) { 491 | var $items = $('#task_info_body > .' +taskid) 492 | 493 | var show = !!$e.data('show') 494 | $e.data('show', !show) 495 | show ? $items.hide() : $items.show() 496 | 497 | // normal task, show info 498 | // default hanlder will clear DOM class 499 | // so show info by self code 500 | } else { 501 | EventHandler.get_http_url(taskid) // show normal download link 502 | $curr.removeClass('bg_curr') 503 | $curr = $e.parent().parent() 504 | 505 | // only show visible task's info 506 | if ($curr.is(':visible')) $curr.addClass('bg_curr') 507 | } 508 | } 509 | 510 | // select all in bt 511 | $(document).delegate('.bt_row .seltbox input', 'click', function () { 512 | var $items = $('#task_info_body > .' +this.id.slice(9)) // task_sel_bt_0 513 | $items.find('.seltbox input').attr('checked', this.checked) 514 | EventHandler.set_top_button() // enable/disable export btn 515 | }) 516 | 517 | 518 | /// ===== 519 | }) 520 | 521 | 522 | /** 523 | * TODO add multi task 524 | */ 525 | injectScript(function () { 526 | // ====== 527 | var $ = window.jQuery 528 | /// ===== 529 | }) 530 | 531 | 532 | 533 | /** 534 | * others 535 | */ 536 | injectScript(function () { 537 | // ====== 538 | var $ = window.jQuery 539 | 540 | // break normal download restrict 541 | EventHandler.httpDownload = function () { 542 | // big size download will be blocked by default 543 | // just clear this code 544 | } 545 | 546 | /// ===== 547 | }) 548 | 549 | 550 | 551 | 552 | 553 | /** 554 | * download dialogBox 555 | */ 556 | injectScript(function () { 557 | // ====== 558 | 559 | var $ = window.jQuery 560 | , xfDialog= window.xfDialog 561 | 562 | var $export = $((function () {/* 563 |
564 |

导出下载

565 |
566 |
567 |
568 |

569 | 存为aria2文件 573 | 存为IDM文件 577 | 存为Orbit文件 581 |

582 |
583 | 584 |
585 |
586 |
587 |
588 |
589 |
590 | */}).toString().slice(16, -4)).appendTo('#popup_area') 591 | 592 | 593 | var $file = $export.find('.ex_file_aria') 594 | , $code = $export.find('.ex_code textarea:first') 595 | 596 | , $idm = $export.find('.ex_file_idm') 597 | , $orbit= $export.find('.ex_file_orbit') 598 | 599 | // setup dialog function 600 | var pop = window.g_pop_export = new xfDialog('ex_pop_export_dl') 601 | 602 | 603 | pop.setDownloads = function (dls) { 604 | var file = '', code = '', idm = '', orbit = '' 605 | 606 | for (var i=0, dl; dl=dls[i++];) { 607 | file += [ 608 | dl.url 609 | , ' header=Cookie: FTN5K=' +dl.cookie 610 | , ' out=' +dl.filename 611 | , ' continue=true' 612 | , ' max-connection-per-server=10' 613 | , ' split=10' 614 | , '\n' 615 | ].join('\n') 616 | 617 | code += [ 618 | 'aria2c -c -s10 -x10 -o ' 619 | , dl.filename 620 | , ' --header ' 621 | , 'Cookie: FTN5K=' +dl.cookie 622 | , ' ' 623 | , dl.url 624 | , '\n' 625 | ].join('\'') 626 | 627 | idm += [ 628 | '<' 629 | , dl.url //+dl.filename? 630 | , 'cookie: FTN5K=' +dl.cookie 631 | , '>' 632 | , '' 633 | ].join('\r\n') 634 | 635 | orbit += dl.url 636 | +'|' +dl.filename.replace(/\|/g, '_') 637 | +'||FTN5K=' +dl.cookie 638 | +'\r\n' 639 | } 640 | 641 | $file.attr('href', 'data:text/plain;charset=utf-8,' +encodeURIComponent(file)) 642 | $code.val(code) 643 | 644 | $idm.attr('href', 'data:text/plain;charset=utf-8,' +encodeURIComponent(idm)) 645 | $orbit.attr('href', 'data:text/plain;charset=utf-8,' +encodeURIComponent(orbit)) 646 | } 647 | 648 | /// ===== 649 | }) 650 | 651 | 652 | /** 653 | * rpc config dialogBox 654 | */ 655 | injectScript(function () { 656 | // ====== 657 | 658 | var $ = window.jQuery 659 | , xfDialog= window.xfDialog 660 | , msg = window.XF.widget.msgbox 661 | 662 | var $rpc = $((function () {/* 663 |
664 |

Aria RPC设置

665 |
666 |
667 |
668 |
669 |
670 |
671 |

672 |

673 |
674 |

675 | 确定 676 |

677 |
678 |

> aria2c --enable-rpc=true --rpc-allow-origin-all=true --rpc-secret=token

679 |
680 |
681 |
682 |
683 |
684 |
685 | */}).toString().slice(16, -4)).appendTo('#popup_area') 686 | 687 | var pop = window.g_pop_rpc = new xfDialog('ex_rpc_config') 688 | 689 | var elements = $rpc.find('form:first').get(0).elements 690 | , url = elements.url 691 | , token = elements.token 692 | 693 | 694 | pop.showConfig = function (config) { 695 | config = config || {} 696 | url.value = config.url || 'http://localhost:6800/jsonrpc' 697 | token.value = config.token || '' 698 | this.show() 699 | } 700 | 701 | $rpc.find('.ok:first').click(function () { 702 | pop.hide() 703 | localStorage.setItem('rpc-url', url.value) 704 | localStorage.setItem('rpc-token', token.value) 705 | }) 706 | 707 | /// ===== 708 | }) 709 | 710 | 711 | /** 712 | * login dialogBox 713 | */ 714 | injectScript(function () { 715 | // ====== 716 | 717 | var $ = window.jQuery 718 | , xfDialog= window.xfDialog 719 | , msg = window.XF.widget.msgbox 720 | 721 | var $login = $((function () {/* 722 |
723 |

登录

724 |
725 |
726 |
727 |
728 |
729 | 733 | 740 |

741 | 742 | 746 |

747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 | */}).toString().slice(16, -4)).appendTo('#popup_area') 755 | 756 | var pop = window.g_pop_login = new xfDialog('login_win') 757 | 758 | var elements = $login.find('form:first').get(0).elements 759 | 760 | var $vcArea = $login.find('.ex_vc_area') 761 | , $loginArea = $login.find('.ex_login_area') 762 | 763 | var $vimg = $login.find('.ex_vimg').click(function () { 764 | // refresh captcha pic 765 | this.src = 'http://captcha.qq.com/getimage?uin=' 766 | +this.getAttribute('data-uin') 767 | +'&' +Date.now() 768 | }) 769 | 770 | 771 | var action, vc 772 | $login.find('.ex_login_btn').click(function () { 773 | pop.hide() 774 | msg.show('登录中...', 0, 5000, true) 775 | action() 776 | }) 777 | 778 | // only show vc dialog 779 | pop.showVC = function (callback, uin) { 780 | action = function () { 781 | callback(elements.vcode.value) 782 | } 783 | $loginArea.hide() 784 | $vcArea.show() 785 | $vimg.attr('data-uin', uin).click() 786 | pop.show() 787 | } 788 | 789 | 790 | // show login dialog 791 | pop.showLogin = function (callback, uin) { 792 | action = function () { 793 | callback(elements.uin.value, elements.pass.value, elements.vcode.value, vc, elements.save.checked) 794 | } 795 | pop.show() 796 | 797 | // set uin and checkVC 798 | if (uin) $(elements.uin).val(uin).change() 799 | } 800 | 801 | 802 | // check vc when qq changed 803 | $(elements.uin).change(function () { 804 | var uin = this.value 805 | if (uin.length > 4) { 806 | msg.show('检测帐号中...', 0, 5000) 807 | checkVC(uin, function (code, vcode, _vc) { 808 | msg.hide() 809 | vc = _vc 810 | 811 | if (code == '0') { // no captcha 812 | $vcArea.hide() 813 | elements.vcode.value = vcode 814 | } else { // need captcha 815 | $vcArea.show() 816 | $vimg.attr('data-uin', uin).click() // show pic 817 | } 818 | }) 819 | } 820 | }) 821 | 822 | /// ===== 823 | }) 824 | 825 | 826 | /** 827 | * overwrite CSS 828 | */ 829 | injectStyle((function () {/* 830 | .top, 831 | .search_box, 832 | #share_opt, 833 | #down_box { 834 | display: none !important; 835 | } 836 | #cont_wrap, #tbl_tpl_id, .box, .filename em { 837 | width: auto !important; 838 | } 839 | 840 | .main { 841 | width: auto; 842 | margin-left: 50px; 843 | margin-right: 50px; 844 | } 845 | .tablebox .tit_h th { 846 | background-repeat: repeat; 847 | } 848 | 849 | 850 | #ex_pop_export_dl { 851 | position: absolute; 852 | top: 200px; 853 | left: 50%; 854 | width: 640px; 855 | margin-left: -320px; 856 | text-align: left; 857 | color: #2d5b7c; 858 | z-index: 102; 859 | background: #FFF; 860 | overflow: hidden; 861 | } 862 | .ex_file { 863 | margin: 8px; 864 | } 865 | .ex_file a { 866 | display: inline-block; 867 | margin-right: 14px; 868 | outline: none; 869 | } 870 | .ex_code { 871 | margin: 0 8px; 872 | border: 1px solid #C7E2F1; 873 | border-raduis: 4px; 874 | } 875 | .ex_code textarea { 876 | width: 100%; 877 | height: 180px; 878 | font: 12px/1.5 monospace; 879 | border: none; 880 | } 881 | #login_win input { 882 | padding: 0 5px; 883 | width: 220px; 884 | background: #FFF; 885 | } 886 | #login_win .ex_vcode { 887 | display: inline-block; 888 | width: 80px; 889 | } 890 | #login_win .ex_check_box { 891 | width: 16px; 892 | } 893 | .ex_login_btn { 894 | float: none; 895 | } 896 | .ex_vimg { 897 | vertical-align: middle; 898 | } 899 | 900 | .bt_row { 901 | background: #f6fef8; 902 | } 903 | .bt_task_row { 904 | display: none; 905 | } 906 | .bt_task_row td:first-child , 907 | .bt_row td:first-child { 908 | border-left: 3px solid #9fe5b1; 909 | } 910 | .bt_task_row .seltbox input { 911 | margin-left: 20px; 912 | } 913 | .icon_bt { 914 | padding-left: 20px; 915 | height: 16px; 916 | line-height: 16px; 917 | font-style: normal; 918 | background-repeat: no-repeat; 919 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGrSURBVDjLxZO7ihRBFIa/6u0ZW7GHBUV0UQQTZzd3QdhMQxOfwMRXEANBMNQX0MzAzFAwEzHwARbNFDdwEd31Mj3X7a6uOr9BtzNjYjKBJ6nicP7v3KqcJFaxhBVtZUAK8OHlld2st7Xl3DJPVONP+zEUV4HqL5UDYHr5xvuQAjgl/Qs7TzvOOVAjxjlC+ePSwe6DfbVegLVuT4r14eTr6zvA8xSAoBLzx6pvj4l+DZIezuVkG9fY2H7YRQIMZIBwycmzH1/s3F8AapfIPNF3kQk7+kw9PWBy+IZOdg5Ug3mkAATy/t0usovzGeCUWTjCz0B+Sj0ekfdvkZ3abBv+U4GaCtJ1iEm6ANQJ6fEzrG/engcKw/wXQvEKxSEKQxRGKE7Izt+DSiwBJMUSm71rguMYhQKrBygOIRStf4TiFFRBvbRGKiQLWP29yRSHKBTtfdBmHs0BUpgvtgF4yRFR+NUKi0XZcYjCeCG2smkzLAHkbRBmP0/Uk26O5YnUActBp1GsAI+S5nRJJJal5K1aAMrq0d6Tm9uI6zjyf75dAe6tx/SsWeD//o2/Ab6IH3/h25pOAAAAAElFTkSuQmCC) 920 | } 921 | 922 | .bg_curr { 923 | pointer: normal !important; 924 | background: #d2eeff !important; 925 | } 926 | .bg_curr .p2 { 927 | display: block !important; 928 | } 929 | #ex_rpc_config { 930 | width: 460px; 931 | margin-left: -230px; 932 | } 933 | */}).toString().slice(16, -4)) // extract css in function 934 | 935 | 936 | 937 | 938 | 939 | // execute code in the content page scope 940 | function injectScript(source) { 941 | var script = document.createElement('script') 942 | script.setAttribute('type', 'text/javascript') 943 | script.textContent = ';(' + source.toString() + ')()' 944 | 945 | document.body.appendChild(script) 946 | document.body.removeChild(script) 947 | } 948 | 949 | // insert css 950 | function injectStyle(css) { 951 | var script = document.createElement('style') 952 | script.setAttribute('type', 'text/css') 953 | script.textContent = css 954 | document.head.appendChild(script) 955 | } 956 | --------------------------------------------------------------------------------