├── .gitattributes ├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── README.md ├── dist ├── 秒传转存助手.meta.js └── 秒传转存助手.user.js ├── doc ├── README.md ├── 关于一键秒传.md ├── 关于脚本安装.md ├── 度盘接口错误码.txt ├── 度盘防和谐相关.md ├── 支持秒传格式.md └── 秒传生成相关.md ├── homePage.md ├── package-lock.json ├── package.json ├── src ├── app.tsx ├── baidu │ ├── common │ │ ├── const.tsx │ │ ├── generatebdlinkTask.tsx │ │ └── rapiduploadTask.tsx │ ├── legacyPage │ │ └── loader.tsx │ ├── loader.tsx │ ├── mobilePage │ │ └── loader.tsx │ ├── mobileSharePage │ │ └── loader.tsx │ ├── newPage │ │ └── loader.tsx │ ├── sharePage │ │ └── loader.tsx │ └── syncPage │ │ └── loader.tsx ├── common │ ├── ajax.tsx │ ├── const.tsx │ ├── duParser.tsx │ ├── injectStyle.tsx │ ├── swalBase.tsx │ ├── swalConfig.tsx │ └── utils.tsx ├── components │ └── updateInfo.html ├── css │ ├── app.css │ ├── app.scss │ └── mobile-app.css └── types │ ├── css.d.ts │ ├── html.d.ts │ ├── scss.d.ts │ └── types.d.ts ├── tsconfig.json └── webpack.config.js /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | custom: https://afdian.net/@mengzonefire -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .history 2 | .vscode 3 | .history 4 | node_modules 5 | dist/types 6 | sample 7 | test -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 百度网盘秒传转存助手 支持PC及移动端 永久无广告绿色版 2 | 3 | > 秒传链接脚本, 使用typescript + webpack重构 4 | > 5 | > Greasyfork版: [https://greasyfork.org/zh-CN/scripts/468633] 6 | > 7 | 8 | 9 | 10 | 百度网盘秒传链接转存及生成脚本,懂的都懂 11 | - 现时兼容性最高版本 (转存404率最低) 12 | - 支持移动端界面 13 | - 支持空文件夹 14 | - 无广告 15 | - 无任何恶意软件 16 | - 绝不窃取数据 17 | 18 | 请先禁止或卸载其他相关脚本以免冲突 19 | 20 | 移动端请使用火狐浏览器 (FireFox) 及暴力猴插件 (ViolentMonkey) 21 | 22 | PC版界面 23 | 24 | ![PC版界面](https://i.postimg.cc/G2VFDLzb/scn3.jpg "PC版界面") 25 | 26 | PC版分享页界面 27 | 28 | ![PC版分享页界面](https://i.postimg.cc/RCJQBtVh/scn4.jpg "PC版分享页界面") 29 | 30 | 移动版界面 31 | 32 | ![移动版界面1](https://i.postimg.cc/cHr76gRD/scn1.jpg "移动版界面1") 33 | ![移动版界面2](https://i.postimg.cc/MHBybCrV/scn2.jpg "移动版界面1") 34 | 35 | > 本脚本仅供参考和个人使用。使用者应自行承担一切风险和责任。 36 | > 37 | > 本软件不对使用者可能遭受的任何损害或误用负责。在使用本脚本前,请确保您已充分理解并同意此免责声明的内容。如有任何疑问或不明之处,请勿使用。 38 | > 39 | > 请谨慎使用本脚本,并在遵守相关法律法规的前提下合理使用。禁止用于传播非法内容。 40 | > 41 | > 任何因使用本软件引起的损失、损害或法律责任,概不负责。安装使用本脚本即表示您同意遵守以上规定。 42 | 43 | 注意dev分支为开发用, 安装脚本请用main分支的dist 44 | 45 | 感谢初代mengzonefire大佬伟大贡献 !!! 46 | 47 | ## Build Setup 48 | 49 | node: 16.17.0 50 | 51 | ``` bash 52 | # install dependencies 53 | npm install 54 | 55 | # build 56 | npm run build 57 | ``` 58 | -------------------------------------------------------------------------------- /dist/秒传转存助手.meta.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name 百度网盘秒传转存助手 支持PC及移动端 永久无广告绿色版 3 | // @version 3.1.5 4 | // @author tousakasp 5 | // @description 百度网盘秒传链接转存及生成 永久无广告绿色版 支持移动端界面 -- 再次感谢初代大佬伟大贡献 6 | // @match *://pan.baidu.com/disk/home* 7 | // @match *://pan.baidu.com/disk/main* 8 | // @match *://pan.baidu.com/disk/synchronization* 9 | // @match *://pan.baidu.com/s/* 10 | // @match *://yun.baidu.com/disk/home* 11 | // @match *://yun.baidu.com/disk/main* 12 | // @match *://yun.baidu.com/disk/synchronization* 13 | // @match *://yun.baidu.com/s/* 14 | // @match *://wangpan.baidu.com/disk/home* 15 | // @match *://wangpan.baidu.com/disk/main* 16 | // @match *://wangpan.baidu.com/disk/synchronization* 17 | // @match *://wangpan.baidu.com/s/* 18 | // @match *://pan.baidu.com/wap/home* 19 | // @license GPLv3 20 | // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABBUlEQVR4AZTTJRBUURTH4TtDwXuPdPrgbhHXiksf3CPucRNScHd3d3d3uO9bKeu7b79+fun8Q17CNHyMMUqaiPE4fEyYVjjGNKnNwQ4lpgV8lManEfwfosLHEGPU1N3ZnAv4qlT+NiQ56uPWSjKBrztUSnIaB66sY1vgxgxoMXB5NbsCB9rxcB5fN2M5/16nCFxeS6YTezpzsB1Pu/C2O7/78/99eYBYHXh+gqdHObGIK4GHgevjVIt1AgAnhvE4cGe8euoHbizgYuD2RGgx8O0RpwIPRmsmJDGqcrANd3pLo/qVr03hUlcpfSwf0/vD3JwkPdPK5/zhkOz+/f1FIDv/RcnOAEjywH/DhgADAAAAAElFTkSuQmCC 21 | // @namespace com.github.tousakasp 22 | // @homepageURL 23 | // @description:en input bdlink to get files or get bdlink for Baidu™ WebDisk. 24 | // @compatible firefox Violentmonkey 25 | // @compatible firefox Tampermonkey 26 | // @compatible chrome Violentmonkey 27 | // @compatible chrome Tampermonkey 28 | // @compatible edge Violentmonkey 29 | // @compatible edge Tampermonkey 30 | // @grant GM_setValue 31 | // @grant GM_getValue 32 | // @grant GM_deleteValue 33 | // @grant GM_setClipboard 34 | // @grant GM_addStyle 35 | // @grant GM_xmlhttpRequest 36 | // @grant GM_registerMenuCommand 37 | // @grant unsafeWindow 38 | // @run-at document-body 39 | // @connect baidu.com 40 | // @connect baidupcs.com 41 | // @connect unpkg.com 42 | // @connect * 43 | // @downloadURL https://raw.githubusercontent.com/tousakasp/rapid-upload-userscript-rinsp/main/dist/%E7%A7%92%E4%BC%A0%E8%BD%AC%E5%AD%98%E5%8A%A9%E6%89%8B.user.js 44 | // @updateURL https://cdn.jsdelivr.net/gh/tousakasp/rapid-upload-userscript-rinsp@main/dist/%E7%A7%92%E4%BC%A0%E8%BD%AC%E5%AD%98%E5%8A%A9%E6%89%8B.user.js 45 | // @require https://unpkg.com/jquery@3.7.0/dist/jquery.min.js 46 | // @require https://unpkg.com/js-base64@3.7.5/base64.js 47 | // @require https://unpkg.com/sweetalert2@11.4.8/dist/sweetalert2.min.js 48 | // @require https://unpkg.com/spark-md5@3.0.2/spark-md5.min.js 49 | // ==/UserScript== 50 | -------------------------------------------------------------------------------- /doc/README.md: -------------------------------------------------------------------------------- 1 | # rapid-upload-userscript-doc 2 | 3 | 此目录存放项目相关文档的markdown版本备档 4 | 5 | 目录下的所有文档均遵循 [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.zh) 协议 6 | 7 | - 文档开发已迁移到 [秒传文档v2](https://github.com/XTsat/rapid-upload-userscript-doc), 此目录下的markdown版本不会再继续更新, 故可能会存在过时内容 8 | 9 | 浏览用文档页: [载点1](https://mengzonefire.code.misakanet.cn/rapid-upload-userscript-doc/) [载点2](https://xtsat.github.io/rapid-upload-userscript-doc/) 10 | -------------------------------------------------------------------------------- /doc/关于一键秒传.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: "/about-bdlink" 3 | title: "一键秒传相关" 4 | --- 5 | 6 | 为了使秒传能像传统分享链接一样 (例如[https://pan.baidu.com/s/xxxxx](https://pan.baidu.com/s/xxxxx)), 实现单次点击即可跳转到网盘页面转存 7 | 8 | 秒传脚本自带了转存和生成 "**一键秒传**" 的功能: 9 | 10 | 1. 使用版本≥2.3.0的秒传脚本 ([脚本发布页](https://greasyfork.org/zh-CN/scripts/424574)), 点击生成秒传, 完成后点击 "**复制一键秒传**" 11 | 12 | ![](https://pic.rmb.bdstatic.com/bjh/bc4ce0e00904a2481577adb4249ef5a9.png) 13 | 14 | 2. 得到类似[https://pan.baidu.com/#bdlink=xxxxx](https://pan.baidu.com/#bdlink=ZDVhYWJlZmMzMjkwZjdhM2MwOTkxMjIyOGIxMzZkMGMjODIxYTlmMGQyN2ZjZDE5YzgwNDc0ZDIxNDBlZDJkODUjNjQ2NzY1OSMvdGVzdC5leGU=)的一串url链接, 即可像使用普通链接一样, 跳转到网盘页面直接转存 (使用该链接**同样需要**安装最新版秒传脚本) 15 | 16 | *使用已安装脚本的浏览器, 点击链接, 跳转到网盘页面, 自动弹出转存窗口并填充秒传链接: 17 | 18 | ![](https://pic.rmb.bdstatic.com/bjh/d90372a4c6192aaf186d9b544d220251.png) 19 | 20 | -------------------------------------------------------------------------------- /doc/关于脚本安装.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: "/install-userscript" 3 | title: "秒传脚本安装教程" 4 | --- 5 | 6 | 此文档提供 Win/安卓/MacOS 平台下的完整安装流程 7 | 8 | \*其他平台和**无法安装脚本**的用户可尝试使用 [秒传网页版](https://rapidacg.gmgard.moe/) 9 | 10 | \*教程仅为参考, 实际安装方案并不唯一 11 | 12 | 22.6.3 更新: 尽可能去除提供的软件下载链接, 改为对应官方发布地址 13 | 14 | --- 15 | 16 | ## Windows端 17 | 18 | ### 安装浏览器 19 | 20 | 安装下方**任意一个**浏览器, 该浏览器在下文称为 **A浏览器**: 21 | 22 | * [Edge](https://www.microsoft.com/zh-cn/edge) 23 | 24 | * [FireFox](https://www.mozilla.org/zh-CN/firefox/new/) 25 | 26 | * [Chrome](https://www.google.cn/chrome/) 27 | 28 | ### 安装 Tampermonkey 油猴插件 29 | 30 | 使用 **A浏览器** 访问下方的商店页面, 并安装插件 31 | 32 | * **Edge** -> [微软商店](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd) 33 | 34 | * **FireFox** -> [火狐商店](https://addons.mozilla.org/zh-CN/firefox/addon/tampermonkey/) 35 | 36 | * **Chrome** -> [谷歌商店](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo) (**可能无法访问**) 37 | 38 | ### 安装脚本 39 | 40 | - 使用 **A浏览器** 访问 [脚本页](https://greasyfork.org/zh-CN/scripts/424574) 点击 "安装此脚本"([图例1](https://pic.rmb.bdstatic.com/bjh/a6f3f140754b8e8bdeaae39992749d1e.png)) (若弹出**下载或代码页**, 请检查上一步是否正确完成), 正确的安装界面如图例所示: [图例2](https://pic.rmb.bdstatic.com/bjh/9d3d54e9dbcdb5ce9db25a9d8ee12dfe.jpeg) 41 | 42 | ### 使用脚本 43 | 44 | - 使用 **A浏览器** 访问 [百度网盘](https://pan.baidu.com/) 即可看到秒传按钮: [新版界面图例](https://pic.rmb.bdstatic.com/bjh/f0cd38fd5bf474a1ca73afe5ac767ebf.png) [旧版界面图例](https://pic.rmb.bdstatic.com/bjh/1cb5384f4b7cd3fc5a07b42ef45bfe93.png) 45 | 46 | --- 47 | 48 | ## 安卓端 49 | 50 | ### 安装浏览器 51 | 52 | 安装Kiwi浏览器: 53 | 54 | * [谷歌商店](https://play.google.com/store/apps/details?id=com.kiwibrowser.browser) (**可能无法访问**) 55 | 56 | * 本地安装(旧版本): [蓝奏云](https://wwe.lanzoui.com/ilaSts35jwh) 57 | 58 | ### 安装 Tampermonkey 油猴插件 59 | 60 | * 在线安装: [谷歌商店](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo) (**可能无法访问**) 61 | 62 | * 本地安装(旧版本): 63 | 1. 下载提供的油猴插件 crx 安装包(版本 4.13): [蓝奏云](https://wwe.lanzoui.com/iWtyfs3541g) 64 | 2. 打开 Kiwi 浏览器, 点击右上角 ┇ 按钮 [(图示 1)](https://pic.rmb.bdstatic.com/bjh/3cae4fb32add8b72e8b560e8f015c941.jpeg) , 点击 **扩展程序** 选项 [(图示 2)](https://pic.rmb.bdstatic.com/bjh/0d2710ac7721100eba72b34d519204ac.jpeg) 65 | 3. 打开右上角的 **开发者模式**, 点击 **Load(+)** 按钮, 选择第一步下载的 crx 文件 ( [图示 3](https://pic.rmb.bdstatic.com/bjh/a0d1c2edd2c8dd7bdf7da1c110768262.jpeg) ), 打开扩展页内的开关启用插件 ( [图示 4](https://pic.rmb.bdstatic.com/bjh/a27dc6a338dc75b77571a34a2204d69b.jpeg) ), 若弹出权限提示点确定 ( [图示 5](https://pic.rmb.bdstatic.com/bjh/9ea9dacc5eafb7b0b44b8a9faf9b5215.jpeg) ) 66 | 67 | ### 安装脚本 68 | 69 | - 使用 Kiwi 浏览器 访问 [脚本页](https://greasyfork.org/zh-CN/scripts/424574) 点击 "安装此脚本"([图例1](https://pic.rmb.bdstatic.com/bjh/a6f3f140754b8e8bdeaae39992749d1e.png)) (若弹出**下载或代码页**, 请检查上一步是否正确完成), 正确的安装界面如图例所示: [图例2](https://pic.rmb.bdstatic.com/bjh/9d3d54e9dbcdb5ce9db25a9d8ee12dfe.jpeg) 70 | 71 | ### 使用脚本 72 | 73 | - 使用 Kiwi 访问 [百度网盘](https://pan.baidu.com/), 并勾选 "右上角 ┇ 按钮 -> **桌面版网站**" 选项, 即可看到秒传按钮: [新版界面图例](https://pic.rmb.bdstatic.com/bjh/f0cd38fd5bf474a1ca73afe5ac767ebf.png) [旧版界面图例](https://pic.rmb.bdstatic.com/bjh/1cb5384f4b7cd3fc5a07b42ef45bfe93.png) 74 | 75 | --- 76 | 77 | ## MacOS端 78 | 79 | ### 安装浏览器 80 | 81 | 安装 [chrome浏览器](https://www.google.cn/chrome/) (脚本目前不兼容safari) 82 | 83 | ### 安装 Tampermonkey 油猴插件 84 | 85 | 使用 **chrome浏览器** 访问 [谷歌商店](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo) (**可能无法访问**), 并安装插件 86 | 87 | ### 安装脚本 88 | 89 | - 使用 **chrome浏览器** 访问 [脚本页](https://greasyfork.org/zh-CN/scripts/424574) 点击 "安装此脚本"([图例1](https://pic.rmb.bdstatic.com/bjh/a6f3f140754b8e8bdeaae39992749d1e.png)) (若弹出**下载或代码页**, 请检查上一步是否正确完成), 正确的安装界面如图例所示: [图例2](https://pic.rmb.bdstatic.com/bjh/9d3d54e9dbcdb5ce9db25a9d8ee12dfe.jpeg) 90 | 91 | ### 使用脚本 92 | 93 | - 使用 **chrome浏览器** 访问 [百度网盘](https://pan.baidu.com/) 即可看到秒传按钮: [新版界面图例](https://pic.rmb.bdstatic.com/bjh/f0cd38fd5bf474a1ca73afe5ac767ebf.png) [旧版界面图例](https://pic.rmb.bdstatic.com/bjh/1cb5384f4b7cd3fc5a07b42ef45bfe93.png) -------------------------------------------------------------------------------- /doc/度盘接口错误码.txt: -------------------------------------------------------------------------------- 1 | 文件数据API错误码 2 | 3 | HTTP状态码 错误码 错误信息 备注 4 | 200 0 no error 没有错误 5 | 400 3 Unsupported open api 不支持此接口 6 | 403 4 No permission to do this operation 没有权限执行此操作 7 | 403 5 Unauthorized client IP address IP未授权 8 | 503 31001 db query error 数据库查询错误 9 | 503 31002 db connect error 数据库连接错误 10 | 503 31003 db result set is empty 数据库返回空结果 11 | 503 31021 network error 网络错误 12 | 503 31022 can not access server 暂时无法连接服务器 13 | 400 31023 param error 输入参数错误 14 | 400 31024 app id is empty app id为空 15 | 503 31025 bcs error 后端存储错误 16 | 403 31041 bduss is invalid 用户的cookie不是合法的百度cookie 17 | 403 31042 user is not login 用户未登陆 18 | 403 31043 user is not active 用户未激活 19 | 403 31044 user is not authorized 用户未授权 20 | 403 31045 user not exists 用户不存在 21 | 403 31046 user already exists 用户已经存在 22 | 400 31061 file already exists 文件已经存在 23 | 400 31062 file name is invalid 文件名非法 24 | 400 31063 file parent path does not exist 文件父目录不存在 25 | 403 31064 file is not authorized 无权访问此文件 26 | 400 31065 directory is full 目录已满 27 | 403 31066 file does not exist 文件不存在 28 | 503 31067 file deal failed 文件处理出错 29 | 503 31068 file create failed 文件创建失败 30 | 503 31069 file copy failed 文件拷贝失败 31 | 503 31070 file delete failed 文件删除失败 32 | 503 31071 get file meta failed 不能读取文件元信息 33 | 503 31072 file move failed 文件移动失败 34 | 503 31073 file rename failed 文件重命名失败 35 | 503 31081 superfile create failed superfile创建失败 36 | 503 31082 superfile block list is empty superfile 块列表为空 37 | 503 31083 superfile update failed superfile 更新失败 38 | 503 31101 tag internal error tag系统内部错误 39 | 503 31102 tag param error tag参数错误 40 | 503 31103 tag database error tag系统错误 41 | 403 31110 access denied to set quota 未授权设置此目录配额 42 | 400 31111 quota only sopport 2 level directories 配额管理只支持两级目录 43 | 400 31112 exceed quota 超出配额 44 | 403 31113 the quota is bigger than one of its parent directorys 配额不能超出目录祖先的配额 45 | 403 31114 the quota is smaller than one of its sub directorys 配额不能比子目录配额小 46 | 503 31141 thumbnail failed, internal error 请求缩略图服务失败 47 | 401 110 Access token invalid or no longer valid Access Token不正确或者已经过期 48 | 400 31201 signature error 签名错误 49 | 400 31203 acl put error 设置acl失败 50 | 400 31204 acl query error 请求acl验证失败 51 | 400 31205 acl get error 获取acl失败 52 | 404 31079 File md5 not found, you should use upload API to upload the whole file. 未找到文件MD5,请使用上传API上传整个文件。 53 | 404 31202 object not exists 文件不存在 54 | 404 31206 acl get error acl不存在 55 | 400 31207 bucket already exists bucket已存在 56 | 400 31208 bad request 用户请求错误 57 | 500 31209 baidubs internal error 服务器错误 58 | 501 31210 not implement 服务器不支持 59 | 403 31211 access denied 禁止访问 60 | 503 31212 service unavailable 服务不可用 61 | 503 31213 service unavailable 重试出错 62 | 503 31214 put object data error 上传文件data失败 63 | 503 31215 put object meta error 上传文件meta失败 64 | 503 31216 get object data error 下载文件data失败 65 | 503 31217 get object meta error 下载文件meta失败 66 | 403 31218 storage exceed limit 容量超出限额 67 | 403 31219 request exceed limit 请求数超出限额 68 | 403 31220 transfer exceed limit 流量超出限额 69 | 500 31298 the value of KEY[VALUE] in pcs response headers is invalid 服务器返回值KEY非法 70 | 500 31299 no KEY in pcs response headers 服务器返回值KEY不存在 71 | 72 | BNDSDK_ERROR(-1), 73 | 3. BNDSDK_SUCCESS(0), 74 | 4. UNKNOWN_ERROR(1), 75 | 5. TASK_ERR_TIMEOUT(19), 76 | 6. TASK_ERR_DISK_SPACE(20), 77 | 7. TASK_ERR_FILE(21), 78 | 8. TASK_ERR_CHECKSUM(22), 79 | 9. TASK_ERR_SOURCE_FAIL(23), 80 | 10. TASK_ERR_RENAME_FAIL(24), 81 | 11. TASK_ERR_FILESYSTEM_INCAPABLE(25), 82 | 12. TASK_ERR_ALREADY_EXIST(26), 83 | 13. TASK_ERR_PCS_FAIL(27), 84 | 14. TASK_ERR_PCS_BDUSS_INVALID(28), 85 | 15. TASK_ERR_PCS_USER_UNLOGIN(29), 86 | 16. TASK_ERR_PCS_USER_UNAUTHORIZED(30), 87 | 17. TASK_ERR_PCS_USER_UNEXIST(31), 88 | 18. TASK_ERR_PCS_REQUEST_LINK_EXPIRED(32), 89 | 19. TASK_ERR_PCS_FILE_NOT_EXIST(33), 90 | 20. TASK_ERR_PCS_FILE_NOT_MATCH(34), 91 | 21. TASK_ERR_PCS_FILE_ILLEGAL(35), 92 | 22. TASK_ERR_PCS_FILE_INCOMPLETE(36), 93 | 23. TASK_ERR_PCS_AUTHORIZED_ERR(37), 94 | 24. TASK_ERR_OLD_FS_ADD_FILE_FAILED(38), 95 | 25. TASK_ERR_DLINK_ERROR(39), 96 | 26. TASK_ERR_FILE_METAS_CHANGED(40), 97 | 27. TASK_ERR_FS_ADD_FILE_FAILED(41), 98 | 28. TASK_ERR_M3U8_FAILED(42), 99 | 29. TASK_ERR_M3U8_RW_FAILED(43), 100 | 30. TASK_ERR_M3U8_PARSE_FAILED(44), 101 | 31. TASK_ERR_ADD_CHECKSUM_FAILED(45), 102 | 32. TASK_ERR_DLINK_REFRESH_ERROR(46), 103 | 33. TASK_ERR_OPEN_FAILED(47), 104 | 34. TASK_ERR_M3U8_SLICE_CHANGED(48), 105 | 35. TASK_ERR_TS_URL_FAIL(49), 106 | 36. TASK_ERR_PCS_HIT_ANTI_HOTLINKING(50), 107 | 37. TASK_ERR_PCS_HOTLINKING_FORBIDDEN(51), 108 | 38. TASK_EER_PCS_HIT_ANTI_RAND_ERROR(52), 109 | 39. TASK_ERR_STREAMING_NOT_INTEGRITY(53), 110 | 40. TASK_ERR_STREAMING_CONVERT_FAILED(54), 111 | 41. TASK_ERR_STREAMING_DURATION_TOO_LONG(55), 112 | 42. TASK_ERR_STREAMING_TS_CLEAN_UP(56), 113 | 43. TASK_ERR_STREAMING_VIDEO_NOT_SUPPORT(57), 114 | 44. TASK_ERR_STREAMING_CODE_RATE_NOT_SUPPORT(58), 115 | 45. TASK_ERR_STREAMING_FILE_NOT_VIDEO(59), 116 | 46. TASK_ERR_STREAMING_OTHER_ERROR(60), 117 | 47. TASK_ERR_PCS_OPERATE_NOT_ALLOWED(61), 118 | 48. TASK_ERR_PCS_PARAM_ERROR(62), 119 | 49. TASK_ERR_PCS_FORMAT_NOT_SUPPORT(63), 120 | 50. TASK_ERR_PCS_SIGN_ERROR(64), 121 | 51. TASK_ERR_STREAMING_API_PARAM_ERROR(65), 122 | 52. TASK_ERR_STREAMING_API_SAFEBOX_STOKEN_INVALID(66), 123 | 53. TASK_ERR_STREAMING_API_ADVERTISMENT(67), 124 | 54. TASK_ERR_STREAMING_PLAY_NO_AUTHORITY(68), 125 | 55. TASK_ERR_STREAMING_SERVER_INTERNAL_ERROR(69), 126 | 56. TASK_ERR_STREAMING_NO_FSID(70), 127 | 57. TASK_ERR_STREAMING_FILE_NOT_EXIST(71), 128 | 58. TASK_ERR_STREAMING_USER_NO_PERMISSION(72), 129 | 59. TASK_ERR_STREAMING_PCS_RETURN_406(73), 130 | 60. TASK_ERR_STREAMING_MBOX_GROUP_NOT_EXIST(74), 131 | 61. TASK_ERR_STREAMING_MBOX_USER_NOT_IN_GROUP(75), 132 | 62. TASK_ERR_STREAMING_MBOX_SHARE_NOT_EXIST(76), 133 | 63. TASK_ERR_STREAMING_MBOX_SHARE_USER_NO_PERMISSION(77), 134 | 64. TASK_ERR_STREAMING_PCS_FREQUENCY_ERROR(78), 135 | 65. TASK_ERR_STREAMING_QUERY_TIMEOUT(79), 136 | 66. TASK_ERR_STREAMING_QUERY_ERROR_DATA(80), 137 | 67. TASK_EER_PCS_HIT_CONCURRENT_TOO_MANY(81), 138 | 68. TASK_EER_GATEWAY_PASSPORT_ERROR(82), 139 | 69. TASK_EER_GATEWAY_RAND_PARAM_ERROR(83), 140 | 70. TASK_EER_SHARE_FILE_NO_DLINK_INFO(84), 141 | 71. PEER_MSG_TIMEOUT(85), 142 | 72. EXCEED_MAX_REQUEST_INTERVAL(86), 143 | 73. NORMAL_PEER_HANDSHAKE_TIMEOUT(87), 144 | 74. QUERY_APAAS_META_DLINK_FAILED(88), 145 | 75. TASK_ERR_TOO_MANY_TASKS(89), 146 | 76. SERVER_PROXY_QUERY_ERROR(90), 147 | 77. SERVER_PROXY_QUERY_ERROR_TIMEOUT(91), 148 | 78. SERVER_PROXY_QUERY_ERROR_DATA(92), 149 | 79. SERVER_PROXY_QUERY_BDUSS_ERROR(93), 150 | 80. SERVER_PROXY_QUERY_PARAM_ERROR(94), 151 | 81. SERVER_ACTIVE_CLOSE(138), 152 | 82. DELAY_SERVER_ACTIVE_CLOSE(139), 153 | 83. PEER_REQUEST_TIMEOUT(140), 154 | 84. READ_FILE_PIECE_DATA_ERROR(141), 155 | 85. FILE_NOT_EXIST(142), 156 | 86. PUNCH_REQUEST_TIMEOUT(143), 157 | 87. CHOKE_PEER(144), 158 | 88. LOG_UPLOAD_FAIL(145), 159 | 89. HTTP_STATUS_ERROR(146), 160 | 90. BLOCK_CHECKSUM_ERROR(147), 161 | 91. HANDSHEAKE_FGID_ERROR(148), 162 | 92. PCS_ERROR(149), 163 | 93. TOO_MUCH_LINK(150), 164 | 94. DECRYPT_FAILED(151), 165 | 95. HTTP_PEER_REQUEST_TIMEOUT(152), 166 | 96. ZERO_SPEED(153), 167 | 97. FILE_PADDING(154), 168 | 98. TASK_ALLOC_BLOCK_MEMORY_FAIL(155), 169 | 99. HTTP_CHOKE_PEER(156), 170 | 100. LOCATEDOWNLOAD_TIMEOUT(157), 171 | 101. HTTP_ACTIVE_CLOSE(158), 172 | 102. READ_FILE_PARAM_ERROR(159), 173 | 103. DATA_MISSING(160), 174 | 104. P2P_DECODE_ERROR(161), 175 | 105. TASK_ERR_DLINK_REFRESH_ERROR_EMPTY(162), 176 | 106. TASK_ERR_DLINK_REFRESH_ERROR_API(163), 177 | 107. TASK_DB_CHECKSUM_EMPTY(164), 178 | 108. PROCESS_COMMUNICATE_ERROR_ON_CREATE_TASK(165), 179 | 109. TASK_ERR_GET_DISK_SPARE_SIZE(166), 180 | 110. FF_TIMEOUT(200), 181 | 111. HTTP_NOT_FOUND(201), 182 | 112. RECV_HTTPS_URL(202), 183 | 113. SQL_FATAL_UNKNOWN(300), 184 | 114. SQL_RECORD_EXIST(301), 185 | 115. SQL_FATAL_LOCAL_PATH_EXIST(302), 186 | 116. SQL_FATAL_RECORD_NOT_EXIST(304), 187 | 117. SQL_FATAL_MORE_THAN_ONE_RECORDS(305), 188 | 118. SQL_FATAL_RECORD_NOT_MATCH(306), 189 | 119. SQL_FATAL_NO_COLUMN(307), 190 | 120. HTTP_DNS_REQUEST_TIMEOUT(401), 191 | 121. CREATE_DIR_ERROR(501), 192 | 122. DOWNLOAD_DATA_TIMEOUT(2001), 193 | 123. QUERY_DETECT_URL_TIMEOUT(2002), 194 | 124. QUERY_NO_URLS(2003), 195 | 125. NO_USABLE_URLS(2004), 196 | 126. PARSE_FIELD_ERROR(1000), 197 | 127. PARSE_INT_VALUE_ERROR(1001), 198 | 128. TASK_NOT_EXIST(1002), 199 | 129. TIMEOUT_ERROR(1003), 200 | 130. BNDSDK_NOTINIT(1004), 201 | 131. BNDSDK_LOADFAIL(1005), 202 | 132. BNDSDK_BADID(1006), 203 | 133. UNRESOLVED_ERROR(1007); -------------------------------------------------------------------------------- /doc/度盘防和谐相关.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: "/file-protect" 3 | title: "度盘防和谐相关" 4 | --- 5 | 6 | - 本文档不定时更新, 最后更新时间: **21.11.25** 7 | 8 | # 前言 9 | 10 | 由于旧版脚本 1.6.7 版本中的 修复下载 功能 已在 21 年 4 月上旬失效(官方封杀), 目前已经没有任何硬性的反和谐\*手段, 只能通过以往总结的一些软性手段实现防和谐. 11 | 12 | \* **和谐** 定义为 文件无法下载, 下载提示 **包含违规... / 下载失败1252017** 13 | 14 | 此文档用于记录已知的度盘和谐机制及解决方法, 可尽量分享给有需要的人. 15 | 16 | --- 17 | 18 | # 已知和谐机制&对策 19 | 20 | ## 在线解压导致的文件和谐: 21 | 22 | ### 机制: 23 | 24 | 已知在使用度盘的 "在线解压" 功能时, 会记录压缩包中的文件, 若包含已和谐的媒体文件(视频/图片等), 就会和谐压缩包文件. 25 | 26 | \* 此机制已验证, 验证过程见下方 **双压防和谐的对照验证** 27 | 28 | \* 通过此机制和谐的文件(仅限压缩文件), 使用网盘 **在线解压** 功能提取压缩包内的所有文件, 将至少有 1 个文件是和谐文件. 29 | 30 | ### 对策: 31 | 32 | 通过 "双层压缩"(详见下章) 规避 33 | 34 | --- 35 | 36 | ## 敏感账号分享导致的文件和谐 37 | 38 | #### 机制: 39 | 40 | 文件分享者的账号在达到一定的分享量&举报量后, 可能被标记为敏感账号, 敏感账号使用分享链分享的文件, 在达到一定的访问量(转存&下载, 数值大致为 50-100 范围)之后, 文件自动被和谐, 但使用秒传分享不受此机制影响(秒传不涉及传统的分享过程). 41 | 42 | \*此机制未经过实际验证, 仅为分析大量现象后得出的结论, 也无法明确判断账号是否为敏感 43 | 44 | ### 对策: 45 | 46 | 不使用分享链接的方式分享文件, 但无法排除&防止其他人使用分享链接分享该文件 47 | 48 | \*被此机制和谐的压缩文件, 可尝试通过 "在线解压" 提取压缩包内的文件, 大概率可以完整提取所有文件且均未和谐. 49 | 50 | --- 51 | 52 | ## 手动举报导致的文件和谐 53 | 54 | ### 机制: 55 | 56 | 使用分享链接分享文件后, 通过分享链接页面的举报按钮举报, 可能导致文件被和谐 57 | 58 | \*此机制未经过实际验证, 考虑到度盘的文件数量, 很难认为官方通过人工审查举报的文件, 猜测是举报到一定次数(一个账号只能举报同文件一次), 自动和谐文件 59 | 60 | ### 对策: 61 | 62 | 不使用分享链接的方式分享文件, 但无法排除&防止其他人使用分享链接分享该文件 63 | 64 | \*简单的道理: 不开分享链接就没有举报按钮 65 | 66 | \*被此机制和谐的压缩文件, 可尝试通过 "在线解压" 提取压缩包内的文件, 大概率可以完整提取所有文件且均未和谐. 67 | 68 | --- 69 | 70 | # 双层压缩 71 | 72 | 使用任意压缩格式将原压缩包再压缩一次, 经过测试发现可以有效防和谐, 双层压缩的压缩包在线解压后只有内层压缩包会被和谐, 而外层压缩不会被和谐(验证过程见下文). 73 | 74 | PS: 提供一个一键批量双层压缩的工具 (使用秒传转存): 75 | 76 | ```plain 77 | f2c3e6a533c9fc4e78293d082bbd5274#9804e9c75762a21f971ad8e9bc5ed576#15352276#auto_double_zip 批量双层压缩工具 v1.0.1.zip 78 | ``` 79 | 80 | \*工具源码: [项目主页](https://github.com/mengzonefire/auto_double_zip) 81 | 82 | 双压防和谐的对照验证过程: 83 | 84 | 1 组: 直接上传已和谐的视频文件 -> 文件和谐(无法下载) 85 | 86 | 2 组: 将视频文件压缩为 无加密zip -> 上传 -> 分享 -> 在线解压 -> 压缩包被和谐(无法下载) 87 | 88 | 3 组: 将 2 组的 zip 文件再压缩一次(无加密zip) -> 上传 -> 分享 -> 在线解压 -> 解压出来的内层 zip 被和谐, 但原压缩包未和谐. 89 | 90 | \*测试时间 2021.6.7, 使用度盘 PC 客户端测试 91 | 92 | 综上可知双层压缩(任意压缩格式, 甚至无加密zip) 可有效防止在线解压导致的文件和谐, 猜测原理为在线解压只扫描压缩包内的媒体文件而不扫描其他文件(例如压缩文件). 93 | 94 | 但手动举报导致的和谐目前还是无解. 95 | 96 | 97 | -------------------------------------------------------------------------------- /doc/支持秒传格式.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: "/format-support" 3 | date: "2021-11-09" 4 | title: "支持秒传格式" 5 | --- 6 | 7 | - 梦姬标准/标准码: 8 | 9 | ```plain 10 | 格式: [md5]#[md5s(可省略)]#[文件大小(byte)]#[文件名] (md5和md5s是字母数字组成的32个字符) 11 | 示例: 12 | D5AABEFC3290F7A3C09912228B136D0C#821A9F0D27FCD19C80474D2140ED2D85#6467659#test.exe 13 | 或 14 | d5aabefc3290f7a3c09912228b136d0c#821a9f0d27fcd19c80474d2140ed2d85#6467659#test.exe 15 | 或 16 | d5aabefc3290f7a3c09912228b136d0c#6467659#test.exe 17 | ``` 18 | 19 | - PanDL 格式: 20 | 21 | ```plain 22 | bdpan://dGVzdC5leGV8NjQ2NzY1OXxENUFBQkVGQzMyOTBGN0EzQzA5OTEyMjI4QjEzNkQwQ3w4MjFBOUYwRDI3RkNEMTlDODA0NzREMjE0MEVEMkQ4NQ== 23 | ``` 24 | 25 | - PCS-GO 格式: 26 | 27 | ```plain 28 | BaiduPCS-Go rapidupload -length=6467659 -md5=D5AABEFC3290F7A3C09912228B136D0C -slicemd5=821A9F0D27FCD19C80474D2140ED2D85 "/test.exe" 29 | ``` 30 | 31 | - 游侠格式(BDLINK......): 32 | 33 | ```plain 34 | BDLINKQkRGUwAHAAAA0/AgXQEAAABvU6INa3SryWsF1pGpw7ALjjjB7lz4B3zYkhccg7C38ToAAABXAG8AcgBsAGQALgBXAGEAcgAuAFoALgAyADAAMQAzAC4AVQBuAHIAYQB0AGUAZAAuAEMAdQB0 35 | ``` 36 | 37 | - 一键秒传链接(https://pan.baidu.com/#bdlink=......): 38 | 39 | \* 秒传脚本≥2.3.5 秒传网页版≥0.9 支持输入(输入转存窗口后会自动转换为上述的其他格式) 40 | 41 | ```plain 42 | https://pan.baidu.com/#bdlink=ZDVhYWJlZmMzMjkwZjdhM2MwOTkxMjIyOGIxMzZkMGMjODIxYTlmMGQyN2ZjZDE5YzgwNDc0ZDIxNDBlZDJkODUjNjQ2NzY1OSMvdGVzdC5leGU= 43 | ``` -------------------------------------------------------------------------------- /doc/秒传生成相关.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: "/generate-bdcode" 3 | title: "秒传链接生成教程" 4 | --- 5 | 6 | 秒传脚本自带 **生成秒传链接** 的功能, 此文档用于帮助用户解决相关问题. 7 | 8 | - 本文档不定时更新, 最后更新时间: **22.6.30** 9 | 10 | --- 11 | 12 | ## 常见错误码及解决方法 13 | 14 | ### 认证失败(#-6) 15 | 16 | 1. 若使用的浏览器为safari, 请改用mac版chrome(可参考 [脚本主页](https://greasyfork.org/zh-CN/scripts/424574) 提供的安装教程), 脚本目前**不兼容**safari 17 | 2. 若使用的浏览器为firefox(火狐), 且使用的油猴插件为Tampermonkey, 请尝试更换为 [Violentmonkey](https://addons.mozilla.org/zh-CN/firefox/addon/violentmonkey/)(暴力猴)再安装脚本 18 | 3. 尝试 刷新页面 或 重新登录度盘账号, 若无法解决请前往 [反馈页](https://greasyfork.org/zh-CN/scripts/424574/feedback) 反馈: 1.浏览器版本 2.油猴插件版本 3.出现问题时按F12->打开控制台(console)->截图 19 | 20 | ### 请求失败(#514) 21 | 22 | 1. 若生成时弹出**跨域提示**, 请选择允许: [图例](https://pic.rmb.bdstatic.com/bjh/763ff5014cca49237cb3ede92b5b7ac5.png) 23 | 2. 若生成时使用了网络代理工具, 请关闭代理工具再尝试生成 24 | 3. 尝试更新油猴插件到最新版本: [微软商店](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd) [火狐商店](https://addons.mozilla.org/zh-CN/firefox/addon/tampermonkey/) [谷歌商店](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)(**可能无法访问**) 25 | 26 | --- 27 | 28 | ### 接口限制访问(#403) 29 | 30 | 一般是账号问题, 可能是生成秒传过于频繁等各种原因导致的, 一般等待 24小时 即可解除, 也可尝试 更换账号 或 使用本地生成工具 [蓝奏云](https://wwe.lanzoui.com/b01u0yqvi) 密码:2233 31 | 32 | \* 百度接口不稳定也可能出现该问题, 可以手动重试几次 33 | 34 | --- 35 | 36 | ### 服务器错误(#502/#503) 37 | 38 | 一般是百度服务器暂时问题, 可使用本地生成工具 [蓝奏云](https://wwe.lanzoui.com/b01u0yqvi) 密码:2233 或 1-24小时 之后再试, 若依旧出现请前往 [反馈页](https://greasyfork.org/zh-CN/scripts/424574/feedback) 反馈 39 | 40 | --- 41 | 42 | ### 服务器错误(#500) 43 | 44 | 使用的账号被限制, 无法生成 3.9-4G 以上的文件 45 | 46 | 可使用本地生成工具 [蓝奏云](https://wwe.lanzoui.com/b01u0yqvi) 密码:2233 生成秒传, 或 更换账号/开通svip 即可解决 47 | 48 | --- 49 | 50 | ### md5 获取失败(#996) 51 | 52 | 1. 更新脚本到最新版本, 再尝试生成, 更新地址: [脚本页](https://greasyfork.org/zh-CN/scripts/424574) 53 | 2. IDM 拦截下载导致 "md5 获取失败", 解决方法: [图例 1](https://pic.rmb.bdstatic.com/bjh/df3eb220a36cd4d4de8995b6040511fd.png) , [图例 2](https://pic.rmb.bdstatic.com/bjh/d7959c6b10a1207fcbf53ee30666e929.png) 54 | 3. 迅雷 拦截下载导致 "md5 获取失败", 解决方法: 迅雷设置 -> [图例](https://pic.rmb.bdstatic.com/bjh/188178d196b485f54cd0959d81a0afbf.png) , 被其他下载工具拦截时同理 55 | 4. (推荐) 通过 本地生成工具 [蓝奏云](https://wwe.lanzoui.com/b01u0yqvi) 密码:2233 生成秒传, 并手动转存测试秒传有效性 (注意将转存成功的文件覆盖到原文件以防止删除转存文件后秒传失效) 56 | 57 | --- 58 | 59 | ### 秒传未生效(#404/#31190) 60 | 61 | #### 秒传转存者 62 | 63 | 1. 更新脚本到最新版本, 再尝试转存, 更新地址: [脚本页](https://greasyfork.org/zh-CN/scripts/424574) 64 | 2. 见下方 **秒传分享者** -> 2. & 5. 65 | 3. 将下方 **秒传分享者** 部分反馈给分享者 66 | 67 | #### 秒传分享者 68 | 69 | 1. (**重要**) 使用低于2.0.11版本的脚本生成秒传, 有小概率会生成错误秒传, 导致转存失败, 若出现该情况请 **更新脚本** 并 **重新生成** 70 | 2. 秒传可能延迟生效, 可等待一段时间(1-24 小时左右)再重试, 若不想等待或等待后依旧无效, 可尝试重传(4.) 71 | 3. 删除首次秒传转存的网盘文件可能导致秒传无效, 此时恢复删除的文件即可使秒传重新生效, 强烈建议使用脚本提供的 **测试秒传** 功能, 即可预防此情况. 72 | 4. 使用 度盘网页端 / 度盘客户端 重传文件, 再尝试转存 73 | 5. (**重要**) 标准码格式的秒传链接可以简化, 例如: 74 | ```plain 75 | D5AABEFC3290F7A3C09912228B136D0C#821A9F0D27FCD19C80474D2140ED2D85#6467659#test.exe 76 | ``` 77 | 可以简化为 (删除第二段md5, 可以正常转存): 78 | ```plain 79 | D5AABEFC3290F7A3C09912228B136D0C#6467659#test.exe 80 | ``` 81 | 但不能简化为 (删除第一段md5, 会导致上述报错, 无法转存): 82 | ```plain 83 | 821A9F0D27FCD19C80474D2140ED2D85#6467659#test.exe 84 | ``` 85 | --- 86 | 87 | ### 文件和谐 88 | 89 | 生成秒传提示如下弹窗, 或下载文件时提示 **包含违规... / 下载失败1252017**, 即文件被和谐, 不允许下载 (压缩包文件, 可尝试网盘的 **在线解压(云解压)** 功能获取部分可下载的文件) 90 | 91 | 文件被和谐 1: 92 | 93 | ![图例1](https://pic.rmb.bdstatic.com/bjh/ca690a39f6668dcaa38b0a01ddf78e20.png) 94 | ![图例2](https://pic.rmb.bdstatic.com/bjh/95b6be9e217d7270fb34076cc0fa6695.png) 95 | 96 | 文件被和谐 2: 97 | 98 | ![图例3](https://pic.rmb.bdstatic.com/bjh/3c182fdbccab1eec22ebc9ee91a40573.png) 99 | 100 | #### 预防方法 101 | 102 | 1. 使用 **双层压缩**, 可规避在线解压导致的和谐, 详见 **文件压缩方法** 章节 103 | 2. **不使用** "分享链接" 分享文件, 可一定程度上规避举报导致的和谐(不开分享链接就没有举报按钮), 但不排除其他人使用秒传转存文件后再开分享链接. 104 | 105 | 关于文件和谐的详细说明文档: [防和谐相关](/rapid-upload-userscript-doc/file-protect) 106 | 107 | --- 108 | 109 | ## 文件压缩方法 110 | 111 | 原压缩方法: 固实压缩+加密文件名 已无法防止在线解压, 也无法再防和谐, 目前有效方法请参考 **双层压缩**: 112 | 113 | ### 双层压缩 114 | 115 | 使用任意压缩格式将原压缩包再压缩一次, 经过测试验证可效防和谐, 双层压缩的压缩包在线解压后只有内层压缩包会被和谐, 而外层压缩包**不会被和谐**(验证过程见下文). 116 | 117 | \* 文件 "**被和谐**" 仅定义为**无法下载**, ≠ 无法分享 118 | 119 | PS: 提供一个一键批量双层压缩的工具 (使用秒传转存): 120 | 121 | ```plain 122 | f2c3e6a533c9fc4e78293d082bbd5274#9804e9c75762a21f971ad8e9bc5ed576#15352276#auto_double_zip 批量双层压缩工具 v1.0.1.zip 123 | ``` 124 | 125 | \*工具源码: [项目主页](https://github.com/mengzonefire/auto_double_zip) 126 | 127 | 双压防和谐的对照验证过程: 128 | 129 | 1 组: 直接上传已和谐的视频文件 -> 文件和谐(无法下载) 130 | 131 | 2 组: 将视频文件压缩为 无加密zip -> 上传 -> 分享 -> 在线解压 -> 压缩包被和谐(无法下载) 132 | 133 | 3 组: 将 2 组的 zip 文件再压缩一次(无加密zip) -> 上传 -> 分享 -> 在线解压 -> 解压出来的内层 zip 被和谐, 但原压缩包未和谐. 134 | 135 | \*测试时间 2021.6.7, 使用度盘 PC 客户端测试 136 | 137 | 综上可知双层压缩(任意压缩格式, 甚至无加密zip) 可有效防止在线解压导致的文件和谐, 但手动举报导致的和谐目前还是无解. 138 | 139 | --- -------------------------------------------------------------------------------- /homePage.md: -------------------------------------------------------------------------------- 1 | 若喜欢该脚本可前往 [爱发电](https://afdian.net/@mengzonefire) 支持作者 2 | 3 | ## 近期通知 4 | 5 | - 23.4.27: 23.4.25发布的 2.7.3, 2.7.4 这两个版本会生成错误的秒传, 错误秒传在文件上传者账号正常转存, 但在其他的账号会报错 秒传未生效#404 6 | - 出现此问题请更新 2.7.5 以上版本重新生成秒传 7 | - 关闭极速生成生成的完整版秒传则不受上述影响, 例如: d5aabefc3290f7a3c09912228b136d0c#821a9f0d27fcd19c80474d2140ed2d85#6467659#test.exe 8 | 9 | - 23.4.25: 转存秒传提示 #404更新2.7.4版本 (更新完**刷新一下度盘页面生效**, 若无效请**删除脚本重新安装**) 10 | 11 | - 23.3.24: 提供一个简易的分享链生成秒传的后端: [GitHub](https://github.com/mengzonefire/shareLink2bdLink) 12 | 13 | - 23.2.12: 完成了新脚本 [秒传链接提取Ultra](https://greasyfork.org/zh-CN/scripts/459862): 无需访问度盘主页, 直接转存页面上的秒传链接 14 | 15 | - 22.12.24: 从10.24开始, 疑似度盘服务端更新后未同步数据, 导致 使用旧PCS接口([PCS-GO](https://github.com/qjfoidnh/BaiduPCS-Go)等第三方客户端)上传的文件秒传全部失效(新旧文件均失效), 至今仍未恢复, 使用 官方客户端 和 官方网页端 上传的文件则不受影响 16 | - 如何恢复失效的秒传: 使用 官方客户端 / 官方网页端 重传文件即可 17 | 18 | - 21.10.16: 已将完整的秒传转存功能移植到 **秒传网页版工具**: [载点1](https://rapidacg.gmgard.moe/)(可能不是最新版) [载点2](https://mengzonefire.github.io/baidupan-rapidupload) [载点3](https://mengzonefire.code.misakanet.cn/baidupan-rapidupload) 19 | - 网页版无需安装插件, 点开即用, 支持所有平台, 推荐无法安装插件的用户使用, 工具源码托管在 [GitHub](https://github.com/mengzonefire/baidupan-rapidupload), 欢迎搭建分流 20 | 21 | ## 相关教程 22 | 23 | - 安装教程: [载点1](https://mengzonefire.code.misakanet.cn/rapid-upload-userscript-doc/document/Install/About) [载点2](https://xtsat.github.io/rapid-upload-userscript-doc/document/Install/About): 适用于 不能正常使用 不会安装 此脚本的用户 [Win/安卓/IOS/MAC] 24 | 25 | - 错误码文档: [载点1](https://mengzonefire.code.misakanet.cn/rapid-upload-userscript-doc/document/FAQ/错误代码) [载点2](https://xtsat.github.io/rapid-upload-userscript-doc/document/FAQ/错误代码): 适用于解决秒传 生成&分享 过程中遇到问题, 例如 秒传未生效 / md5获取失败 / 文件和谐 26 | 27 | ## 运行页面 28 | 29 | 脚本在如下页面运行: 30 | - 度盘新版主页: https://pan.baidu.com/disk/main 31 | - 度盘旧版主页: https://pan.baidu.com/disk/home?stayAtHome=true 32 | - 度盘同步空间页: https://pan.baidu.com/disk/synchronization# 33 | - 度盘文件分享页: https://pan.baidu.com/s/... 34 | 35 | ## 常见问题 36 | 37 | 1. 大部分国产浏览器有双内核, 使用时注意切换到 **chrome内核**, **ie内核** 下油猴插件是不运行的(会导致看不到秒传按钮) 38 | - 以 360浏览器 为例: [图例](https://p.sda1.dev/9/31e5d03209b255297cef46c6a591de18/Snipaste_2023-01-24_13-08-08.png) 39 | 40 | 2. 安装时请使用最新版本的油猴插件, 脚本不兼容版本低于4.9的油猴插件, 尽量参考上方提供的 **安装教程** 41 | 42 | 3. 若使用脚本时 秒传按钮 或 转存窗口 不显示、页面卡死无法操作 等, 尝试关闭广告拦截插件和同时运行的其他插件脚本 43 | - (**排查冲突**) 若无效再根据 **5.** 反馈 44 | 45 | 4. 下载转存的文件显示 "下载失败1252017" 等同**包含违规...**, 即文件已被和谐, 不允许下载 46 | 47 | 5. 若遇到其他问题, 请前往 [反馈页](https://greasyfork.org/zh-CN/scripts/424574/feedback) 反馈: 1.浏览器版本 2.油猴插件版本 3.出现问题时按F12->打开控制台(console)->截图 48 | 49 | ## 脚本说明 50 | 51 | - 秒传链接是一种通过模拟网盘自带秒传功能实现的文件分享方式(**非官方**), 其优点是可以**永久**保证分享有效性(在官方不限制秒传功能前提下), 且链接内不包含账号信息, 注意, 使用秒传链接分享文件**并没有**任何加速下载的效果, 且**无法取消分享** 52 | 53 | - 参考了初版秒传脚本 [仓库用度盘投稿助手](https://greasyfork.org/zh-CN/scripts/3285) 进行开发, 脚本源码托管在 [GitHub](https://github.com/mengzonefire/rapid-upload-userscript) 54 | 55 | - 支持批量提取(**换行分隔**), 支持 url 传参(**一键秒传**), 格式:`https://pan.baidu.com/#bdlink=[参数]`, [参数]为 base64 加密过的任意格式链接 (支持批量), 访问该链接后脚本会自动弹出秒传窗口, 并将[参数]base64解密, 添加到秒传输入框内 56 | 57 | - 支持新版度盘页面, 支持生成秒传, 网盘页面内选中 文件/文件夹后 即可看到秒传生成按钮 58 | 59 | ![](https://pic.rmb.bdstatic.com/bjh/f0cd38fd5bf474a1ca73afe5ac767ebf.png) 60 | 61 | ![](https://pic.rmb.bdstatic.com/bjh/1cb5384f4b7cd3fc5a07b42ef45bfe93.png) 62 | 63 | - 支持输入文件路径生成秒传, 在秒传输入框中输入gen即可进入生成页面 64 | 65 | - 支持设置主题样式, 在秒传输入框中输入set即可进入设置页面 66 | 67 | ## 常见秒传格式 68 | 69 |
70 | 点击展开 71 | 72 |
  • 梦姬标准/标准码: D5AABEFC3290F7A3C09912228B136D0C#821A9F0D27FCD19C80474D2140ED2D85#6467659#test.exe

  • PanDL格式: bdpan://dGVzdC5leGV8NjQ2NzY1OXxENUFBQkVGQzMyOTBGN0EzQzA5OTEyMjI4QjEzNkQwQ3w4MjFBOUYwRDI3RkNEMTlDODA0NzREMjE0MEVEMkQ4NQ==

  • PCS-GO格式: BaiduPCS-Go rapidupload -length=6467659 -md5=D5AABEFC3290F7A3C09912228B136D0C -slicemd5=821A9F0D27FCD19C80474D2140ED2D85 "/test.exe"

  • 游侠格式(BDLINK......): BDLINKQkRGUwAHAAAA0/AgXQEAAABvU6INa3SryWsF1pGpw7ALjjjB7lz4B3zYkhccg7C38ToAAABXAG8AcgBsAGQALgBXAGEAcgAuAFoALgAyADAAMQAzAC4AVQBuAHIAYQB0AGUAZAAuAEMAdQB0

73 | 74 |
75 | 76 | ## 待更新 77 | 78 | 1. ~~[给页面中的秒传添加一键秒传超链接](https://greasyfork.org/zh-CN/scripts/424574/discussions/127485)~~ (已完成, 见 [秒传链接提取Ultra](https://greasyfork.org/zh-CN/scripts/459862)) 79 | 80 |
81 | 已完成 [点击展开] 82 |
  1. 不少人反馈依赖加载失败, 找找更好的cdn替换unpkg(打算放弃使用cdn并内置所有依赖)(已完成)

  2. 尝试通过混合模式生成解决 “极速生成” 功能 生成部分md5错误的秒传的问题 (已完成)

  3. 尝试解决秒传转存v2接口在批量连续转存文件时出现转存结果错误的问题 (秒传正确但转存显示秒传未生效, 单独转存该文件又能正常转存) (已完成)

    • PS: “极速生成” 得到的简化版秒传只能通过v2接口转存
  4. 支持 新版度盘页面 下的 "生成秒传" 功能 (完成)
  5. 支持 阿里云盘 的秒传提取&生成 (废弃, 阿里官方限制了秒传接口)
  6. 支持 新版度盘页面 (完成)
  7. 修复设置为非默认主题时, 窗口内会出现警告标识的问题 (完成, 实际为主题包不适配旧版 sweetalert2)
  8. cdn.jsdelivr.net抽风有点严重, 尝试添加替代cdn (完成)
  9. 转存完成后的提示框添加转存成功列表(使用折叠框隐藏)(完成)
83 |
84 | 85 | ## 秒传链接的获取方式 86 | 87 | 1. 使用秒传脚本自带的生成功能, 选中文件/文件夹, 再点击 "生成秒传" 88 | 89 | 2. 网页版秒传生成工具: [载点1](https://rapidacg.gmgard.moe/gen.html) [载点2](https://mengzonefire.github.io/baidupan-rapidupload/gen.html) [载点3](https://mengzonefire.code.misakanet.cn/baidupan-rapidupload/gen.html) 90 | 91 | 3. 本地秒传生成工具: [蓝奏云](https://wwe.lanzoui.com/b01u0yqvi) 密码:2233 92 | 93 | \*需要任意账号的网盘中存有至少一份文件才能保证秒传链接的有效性 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rapid-upload-userscript-rinsp", 3 | "version": "3.1.5", 4 | "description": "百度网盘秒传链接转存及生成 永久无广告绿色版 支持移动端界面 -- 再次感谢初代大佬伟大贡献", 5 | "main": "app.tsx", 6 | "scripts": { 7 | "build": "webpack --config webpack.config.js" 8 | }, 9 | "author": "tousakasp", 10 | "license": "GPLv3", 11 | "homepage": "", 12 | "dependencies": { 13 | "spark-md5": "3.0.2", 14 | "sweetalert2": "11.4.8", 15 | "js-base64": "3.7.5" 16 | }, 17 | "devDependencies": { 18 | "@types/jquery": "^3.5.6", 19 | "@types/spark-md5": "^3.0.2", 20 | "@types/tampermonkey": "^4.0.2", 21 | "css-loader": "^6.7.1", 22 | "mini-css-extract-plugin": "^2.6.0", 23 | "node-sass": "^7.0.3", 24 | "sass": "^1.49.9", 25 | "sass-loader": "^12.6.0", 26 | "text-loader": "^0.0.1", 27 | "ts-loader": "^9.2.5", 28 | "typescript": "^4.3.5", 29 | "webpack": "^5.76.0", 30 | "webpack-cli": "^4.8.0", 31 | "webpack-node-externals": "^3.0.0", 32 | "webpack-userscript": "^2.5.8" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/app.tsx: -------------------------------------------------------------------------------- 1 | import { injectStyle } from "./common/injectStyle"; 2 | import { Base64 } from 'js-base64'; 3 | 4 | /** 5 | * @description: 主函数入口 6 | */ 7 | function app(): void { 8 | Base64.extendString(); 9 | injectStyle(); 10 | } 11 | 12 | // 广告拦截插件会导致脚本报错跳出, 网页卡死, 故加入异常处理 13 | try { 14 | app(); 15 | } catch (error) { 16 | console.log(error); 17 | } 18 | -------------------------------------------------------------------------------- /src/baidu/common/const.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: mengzonefire 3 | * @LastEditors: tousakasp 4 | * @Description: 存放各种全局常量对象 5 | */ 6 | 7 | import Swalbase from "@/common/swalBase"; 8 | import GeneratebdlinkTask from "./generatebdlinkTask"; 9 | import RapiduploadTask from "./rapiduploadTask"; 10 | 11 | const host = location.host; 12 | export const listLimit = 10000; 13 | export const syncPathPrefix = "/_pcs_.workspace"; 14 | export const create_url = `https://${host}/api/create`; 15 | export const precreate_url = `https://${host}/api/precreate`; 16 | export const rapidupload_url = `https://${host}/api/rapidupload`; 17 | export const list_url = `https://${host}/rest/2.0/xpan/multimedia?method=listall&order=name&limit=${listLimit}&path=`; 18 | export const meta_url = `https://pcs.baidu.com/rest/2.0/pcs/file?app_id=778750&method=meta&path=`; 19 | export const meta_url2 = `https://${host}/api/filemetas?dlink=1&fsids=`; 20 | export const tpl_url = `https://${host}/share/tplconfig?fields=sign,timestamp&channel=chunlei&web=1&app_id=250528&clienttype=0`; 21 | export const sharedownload_url = `https://${host}/api/sharedownload?channel=chunlei&clienttype=12&web=1&app_id=250528`; 22 | export const sharelist_url = `https://${host}/share/list?showempty=0&num=${listLimit}&channel=chunlei&web=1&app_id=250528&clienttype=0`; 23 | export const syncdownload_url = `https://${host}/api/download`; 24 | export const pcs_url = 25 | "https://pcs.baidu.com/rest/2.0/pcs/file?app_id=778750&method=download"; 26 | export const illegalPathPattern = /[\\":*?<>|]/g; // 匹配路径中的非法字符 27 | export var getBdstoken: () => string; // 获取bdstoken的实现 28 | export function setGetBdstoken(func: () => string) { 29 | getBdstoken = func; 30 | } 31 | export var refreshList: () => void; // 刷新文件列表的实现 32 | export function setRefreshList(func: () => void) { 33 | refreshList = func; 34 | } 35 | export var getSelectedFileList: () => any; // 获取选中的文件列表的实现 36 | export function setGetSelectedFileList(func: () => any) { 37 | getSelectedFileList = func; 38 | } 39 | export var getShareFileList: () => any; 40 | export function setGetShareFileList(func: () => any) { 41 | getShareFileList = func; 42 | } 43 | export const swalInstance = new Swalbase( 44 | new RapiduploadTask(), 45 | new GeneratebdlinkTask() 46 | ); 47 | 48 | export function baiduErrno(errno: number) { 49 | switch (errno) { 50 | case 31045: 51 | case -6: 52 | return "认证失败, 请重新登入, 刷新页面"; 53 | case -7: 54 | return "转存路径含有非法字符, 请改名后重试"; 55 | case -8: 56 | return "路径下存在同名文件"; 57 | case -9: 58 | return "验证已过期, 请刷新页面"; 59 | case 400: 60 | return "请求错误"; 61 | case 9019: 62 | case 403: 63 | return "接口限制访问"; 64 | case 404: 65 | return "秒传未生效"; 66 | case 114: 67 | return "转存失败"; 68 | case 514: 69 | return "请求失败, 常见百度问题, 请稍后重试"; 70 | case 1919: 71 | return "文件已被和谐"; 72 | case 996: 73 | return "md5获取失败"; 74 | case 2: 75 | return "转存失败, 接口可能限制了IP, 请改IP重试, VPN海外IP更佳"; 76 | case -10: 77 | return "网盘容量已满"; 78 | case 500: 79 | case 502: 80 | case 503: 81 | return "服务器错误, 请稍后重试"; 82 | case 31066: 83 | case 909: 84 | return "路径不存在/云端文件已损坏"; 85 | case 900: 86 | return "路径为文件夹, 不支持生成秒传"; 87 | case 31039: 88 | return "转存失败, 秒传文件名冲突"; 89 | case 110: 90 | return "请先登录百度账号"; 91 | case 9013: 92 | return "账号被限制, 尝试 更换账号 或 等待一段时间再重试"; 93 | default: 94 | return "不明错误"; 95 | } 96 | } // 自定义百度api返回errno的报错 97 | -------------------------------------------------------------------------------- /src/baidu/common/generatebdlinkTask.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: mengzonefire 3 | * @LastEditors: tousakasp 4 | * @Description: 百度网盘 秒传生成任务实现 5 | */ 6 | 7 | import ajax from "@/common/ajax"; 8 | import { 9 | convertData, 10 | decryptMd5, 11 | getExtra, 12 | getLogid, 13 | getSurl, 14 | showAlert, 15 | } from "@/common/utils"; 16 | import { UA } from "@/common/const"; 17 | import { 18 | list_url, 19 | meta_url, 20 | meta_url2, 21 | pcs_url, 22 | tpl_url, 23 | sharedownload_url, 24 | sharelist_url, 25 | getBdstoken, 26 | listLimit, 27 | } from "./const"; 28 | // import { createFileV2 } from "./rapiduploadTask"; 29 | import SparkMD5 from "spark-md5"; 30 | import { rapiduploadCreateFile } from "./rapiduploadTask"; 31 | 32 | const listMinDelayMsec = 1000; 33 | const retryDelaySec = 30; 34 | 35 | // 普通生成: 36 | export default class GeneratebdlinkTask { 37 | isSharePage: boolean; // 分享页标记 38 | isGenView: boolean; // 生成页(秒传框输入gen)标记 39 | recursive: boolean; // 递归生成标记 40 | savePath: string; 41 | dirList: Array; 42 | selectList: Array; 43 | fileInfoList: Array; 44 | logid: string; 45 | surl: string; 46 | bdstoken: string; 47 | onFinish: (fileInfoList: Array) => void; 48 | onProcess: (i: number, fileInfoList: Array) => void; 49 | onProgress: (e: any, text?: string) => void; 50 | onHasDir: () => void; 51 | onHasNoDir: () => void; 52 | 53 | reset(): void { 54 | this.isGenView = false; 55 | this.isSharePage = false; 56 | this.recursive = false; 57 | this.savePath = ""; 58 | this.bdstoken = getBdstoken(); // 此处bdstoken不可删除, 会在下方createFileV2方法调用 59 | this.dirList = []; 60 | this.selectList = []; 61 | this.fileInfoList = []; 62 | this.onFinish = () => {}; 63 | this.onProcess = () => {}; 64 | this.onProgress = () => {}; 65 | this.onHasDir = () => {}; 66 | this.onHasNoDir = () => {}; 67 | } 68 | 69 | /** 70 | * @description: 执行新任务的初始化步骤 扫描选择的文件列表 71 | */ 72 | start(): void { 73 | if (this.isSharePage) { 74 | this.logid = getLogid(); 75 | this.surl = getSurl(); 76 | if (!this.surl) { 77 | showAlert( 78 | "surl获取失败" 79 | ); 80 | return; 81 | } 82 | this.parseShareFileList(); 83 | this.onHasNoDir(); 84 | } else { 85 | this.parseMainFileList(); 86 | if (this.dirList.length) this.onHasDir(); 87 | else this.onHasNoDir(); 88 | } 89 | } 90 | 91 | scanShareFile(i: number, page: number = 1, retryAllowed: number = 5): void { 92 | if (i >= this.dirList.length) { 93 | this.generateBdlink(0); 94 | return; 95 | } 96 | this.onProgress(false, `正在获取文件列表, 第${i + 1}个`); 97 | const shareid = unsafeWindow.yunData ? unsafeWindow.yunData.shareid : unsafeWindow.locals.shareid; 98 | const uk = unsafeWindow.yunData ? unsafeWindow.yunData.share_uk : unsafeWindow.locals.share_uk; 99 | ajax( 100 | { 101 | url: `${sharelist_url}&dir=${encodeURIComponent(this.dirList[i])}&logid=${this.logid}&shareid=${shareid}&uk=${uk}&page=${page}`, 102 | method: "GET", 103 | responseType: "json", 104 | }, 105 | (data) => { 106 | data = data.response; 107 | if (!data.errno) { 108 | if (!data.list.length) { 109 | // 返回列表为空, 即此文件夹文件全部扫描完成 110 | if (page === 1) { 111 | this.fileInfoList.push({ 112 | path: this.dirList[i] + '/', 113 | size: 0, 114 | fs_id: '', 115 | md5: '00000000000000000000000000000000', 116 | md5s: '00000000000000000000000000000000', 117 | }); 118 | } 119 | setTimeout(() => { 120 | this.scanShareFile(i + 1); 121 | }, listMinDelayMsec); 122 | } else { 123 | this.parseShareFileList(data.list); 124 | if (data.list.length >= listLimit) { 125 | setTimeout(() => { 126 | this.scanShareFile(i, page + 1); // 下一页 127 | }, listMinDelayMsec); 128 | } else { 129 | setTimeout(() => { 130 | this.scanShareFile(i + 1); 131 | }, listMinDelayMsec); 132 | } 133 | } 134 | } else { 135 | this.fileInfoList.push({ 136 | path: this.dirList[i], 137 | isdir: 1, 138 | errno: data.errno, 139 | }); // list接口访问失败, 添加失败信息 140 | setTimeout(() => { 141 | this.scanShareFile(i + 1); 142 | }, listMinDelayMsec); 143 | } 144 | }, 145 | (statusCode) => { 146 | if (statusCode === 400 && retryAllowed > 0) { // rate limit 147 | this.onProgress(false, `${retryDelaySec}秒后重试 ...`); 148 | setTimeout(() => { 149 | this.scanShareFile(i, page, retryAllowed - 1); 150 | }, listMinDelayMsec + retryDelaySec * 1000); 151 | } else { 152 | this.fileInfoList.push({ 153 | path: this.dirList[i], 154 | errno: statusCode, 155 | }); 156 | setTimeout(() => { 157 | this.scanShareFile(i + 1); 158 | }, listMinDelayMsec); 159 | } 160 | } 161 | ); 162 | } 163 | 164 | /** 165 | * @description: 选择的列表包含文件夹, 获取文件夹下的子文件 166 | * @param {number} i 条目index 167 | * @param {number} start 列表接口检索起点(即翻页参数) 168 | */ 169 | scanFile(i: number, start: number = 0, retryAllowed: number = 5): void { 170 | if (i >= this.dirList.length) { 171 | this.generateBdlink(0); 172 | return; 173 | } 174 | ajax( 175 | { 176 | url: `${list_url}${encodeURIComponent(this.dirList[i])}&recursion=${ 177 | this.recursive ? 1 : 0 178 | }&start=${start}`, 179 | method: "GET", 180 | responseType: "json", 181 | }, // list接口自带递归参数recursion 182 | (data) => { 183 | data = data.response; 184 | if (!data.errno) { 185 | if (!data.list.length) { 186 | // 返回列表为空, 即此文件夹文件全部扫描完成 187 | if (start === 0) { 188 | this.fileInfoList.push({ 189 | path: this.dirList[i] + '/', 190 | size: 0, 191 | fs_id: '', 192 | md5: '00000000000000000000000000000000', 193 | md5s: '00000000000000000000000000000000', 194 | }); 195 | } 196 | setTimeout(() => { 197 | this.scanFile(i + 1); 198 | }, listMinDelayMsec); 199 | } else { 200 | data.list.forEach((item: any) => { 201 | if (!item.isdir) { 202 | this.fileInfoList.push({ 203 | path: item.path, 204 | size: item.size, 205 | fs_id: item.fs_id, 206 | md5: "", 207 | md5s: "", 208 | }); // 筛选文件(isdir=0) 209 | } 210 | }); 211 | if (data.has_more) { 212 | setTimeout(() => { 213 | this.scanFile(i, start + listLimit); // 从下一个起点继续检索列表 214 | }, listMinDelayMsec); 215 | } else { 216 | setTimeout(() => { 217 | this.scanFile(i + 1); 218 | }, listMinDelayMsec); 219 | } 220 | } 221 | } else { 222 | this.fileInfoList.push({ 223 | path: this.dirList[i], 224 | isdir: 1, 225 | errno: data.errno, 226 | }); // list接口访问失败, 添加失败信息 227 | setTimeout(() => { 228 | this.scanFile(i + 1); 229 | }, listMinDelayMsec); 230 | } 231 | }, 232 | (statusCode) => { 233 | if (statusCode === 400 && retryAllowed > 0) { // rate limit 234 | this.onProgress(false, `${retryDelaySec}秒后重试 ...`); 235 | setTimeout(() => { 236 | this.scanFile(i, start, retryAllowed - 1); 237 | }, listMinDelayMsec + retryDelaySec * 1000); 238 | } else { 239 | this.fileInfoList.push({ 240 | path: this.dirList[i], 241 | errno: statusCode, 242 | }); 243 | setTimeout(() => { 244 | this.scanFile(i + 1); 245 | }, listMinDelayMsec); 246 | } 247 | } 248 | ); 249 | } 250 | 251 | /** 252 | * @description: 顺序执行生成任务 253 | * @param {number} i 254 | */ 255 | generateBdlink(i: number): void { 256 | // 保存任务进度数据, 分享页生成不保存 257 | if (!this.isSharePage) 258 | GM_setValue("unfinish", { 259 | file_info_list: this.fileInfoList, 260 | file_id: i, 261 | }); 262 | // 生成完成 263 | if (i >= this.fileInfoList.length) { 264 | this.onFinish(this.fileInfoList); 265 | return; 266 | } 267 | let file = this.fileInfoList[i]; 268 | if (file.fs_id === '') { 269 | this.generateBdlink(i + 1); 270 | } else { 271 | // 刷新弹窗内的任务进度 272 | this.onProcess(i, this.fileInfoList); 273 | // 跳过扫描失败的目录路径 274 | if (file.errno && file.isdir) { 275 | this.generateBdlink(i + 1); 276 | return; 277 | } 278 | // 普通生成步骤 279 | this.isSharePage ? this.getShareDlink(i) : this.getDlink(i); 280 | } 281 | } 282 | 283 | /** 284 | * @description: 获取文件信息: size, md5(可能错误), fs_id 285 | * @param {number} i 286 | */ 287 | getFileInfo(i: number): void { 288 | let file = this.fileInfoList[i]; 289 | ajax( 290 | { 291 | url: meta_url + encodeURIComponent(file.path), 292 | responseType: "json", 293 | method: "GET", 294 | }, 295 | (data) => { 296 | data = data.response; 297 | if (!data.error_code) { 298 | if (data.list[0].isdir) { 299 | console.log(1111); 300 | file.isdir = 1; 301 | file.errno = 900; 302 | this.generateBdlink(i + 1); 303 | return; 304 | } 305 | file.size = data.list[0].size; 306 | file.fs_id = data.list[0].fs_id; 307 | // 已开启极速生成, 直接取meta内的md5 308 | file.md5 = ""; 309 | file.md5s = ""; 310 | this.getDlink(i); 311 | } else { 312 | file.errno = data.error_code; 313 | this.generateBdlink(i + 1); 314 | } 315 | }, 316 | (statusCode) => { 317 | file.errno = statusCode === 404 ? 909 : statusCode; 318 | this.generateBdlink(i + 1); 319 | } 320 | ); 321 | } 322 | 323 | /** 324 | * @description: 获取分享页的文件dlink(下载直链) 325 | * @param {number} i 326 | */ 327 | getShareDlink(i: number): void { 328 | let sign: string, 329 | timestamp: number, 330 | file = this.fileInfoList[i], 331 | onFailed = (errno: number) => { 332 | file.errno = errno; 333 | this.checkMd5(i + 1); 334 | // md5为空只在分享单个文件时出现, 故无需考虑获取多文件md5(跳转generateBdlink), 直接跳转checkMd5即可 335 | }; 336 | function getTplconfig(file: FileInfo): void { 337 | ajax( 338 | { 339 | url: `${tpl_url}&surl=${this.surl}&logid=${this.logid}`, 340 | responseType: "json", 341 | method: "GET", 342 | }, 343 | (data) => { 344 | data = data.response; 345 | // 请求正常 346 | if (!data.errno) { 347 | sign = data.data.sign; 348 | timestamp = data.data.timestamp; 349 | getDlink.call(this, file); 350 | return; 351 | } 352 | // 请求报错 353 | onFailed(data.errno); 354 | }, 355 | onFailed 356 | ); 357 | } 358 | function getDlink(file: FileInfo): void { 359 | ajax( 360 | { 361 | url: `${sharedownload_url}&sign=${sign}×tamp=${timestamp}`, 362 | responseType: "json", 363 | method: "POST", 364 | data: convertData({ 365 | extra: getExtra(), 366 | logid: this.logid, 367 | fid_list: JSON.stringify([file.fs_id]), 368 | primaryid: unsafeWindow.yunData ? unsafeWindow.yunData.shareid : unsafeWindow.locals.shareid, 369 | uk: unsafeWindow.yunData ? unsafeWindow.yunData.share_uk : unsafeWindow.locals.share_uk, 370 | product: "share", 371 | encrypt: 0, 372 | }), 373 | }, 374 | (data) => { 375 | data = data.response; 376 | // 请求正常 377 | if (!data.errno) { 378 | this.downloadFileData(i, data.list[0].dlink); 379 | return; 380 | } 381 | // 请求报错 382 | onFailed(data.errno); 383 | }, 384 | onFailed 385 | ); 386 | } 387 | getTplconfig.call(this, file); 388 | } 389 | 390 | /** 391 | * @description: 获取文件dlink(下载直链) 392 | * @param {number} i 393 | */ 394 | getDlink(i: number): void { 395 | let file = this.fileInfoList[i]; 396 | 397 | // 使用生成页时仅有path没有fs_id, 跳转到获取fs_id 398 | if (!file.fs_id) { 399 | this.getFileInfo(i); 400 | return; 401 | } 402 | ajax( 403 | { 404 | url: meta_url2 + JSON.stringify([String(file.fs_id)]), 405 | responseType: "json", 406 | method: "GET", 407 | headers: { "User-Agent": UA }, 408 | }, 409 | (data) => { 410 | data = data.response; 411 | // 请求正常 412 | if (!data.errno) { 413 | this.downloadFileData(i, data.info[0].dlink); 414 | return; 415 | } 416 | // 请求报错 417 | file.errno = data.errno; 418 | this.generateBdlink(i + 1); 419 | }, 420 | (statusCode) => { 421 | file.errno = statusCode; 422 | this.generateBdlink(i + 1); 423 | } 424 | ); 425 | } 426 | 427 | /** 428 | * @description: 调用下载直链 429 | * @param {number} i 430 | * @param {string} dlink 431 | */ 432 | downloadFileData(i: number, dlink: string): void { 433 | let file = this.fileInfoList[i]; 434 | let dlSize = file.size < 262144 ? 1 : 262143; //slice-md5: 文件前256KiB的md5, size<256KiB则直接取md5即可, 无需下载文件数据 435 | ajax( 436 | { 437 | url: dlink, 438 | method: "GET", 439 | responseType: "arraybuffer", 440 | headers: { 441 | Range: `bytes=0-${dlSize}`, 442 | "User-Agent": UA, 443 | }, 444 | onprogress: this.onProgress, 445 | }, 446 | (data) => { 447 | this.onProgress({ loaded: 100, total: 100 }); // 100% 448 | this.parseDownloadData(i, data); 449 | }, 450 | (statusCode) => { 451 | if (statusCode === 404) file.errno = 909; 452 | else file.errno = statusCode; 453 | this.generateBdlink(i + 1); 454 | } 455 | ); 456 | } 457 | 458 | /** 459 | * @description: 解析直链请求返回的数据 460 | * @param {number} i 461 | * @param {any} data 462 | */ 463 | parseDownloadData(i: number, data: any): void { 464 | let file = this.fileInfoList[i]; 465 | console.log(`dl_url: ${data.finalUrl}`); // debug 466 | // 下载直链重定向到此域名, 判定为文件和谐 467 | if (data.finalUrl.includes("issuecdn.baidupcs.com")) { 468 | file.errno = 1919; 469 | this.generateBdlink(i + 1); 470 | return; 471 | } 472 | // 从下载接口获取md5, 此步骤可确保获取到正确md5 473 | let fileMd5 = data.responseHeaders.match(/content-md5: ([\da-f]{32})/i); 474 | if (fileMd5) file.md5 = fileMd5[1]; 475 | else if (file.size <= 3900000000 && !file.retry_996 && !this.isSharePage) { 476 | // 默认下载接口未拿到md5, 尝试使用旧下载接口, 旧接口请求文件size大于3.9G会返回403 477 | // 分享页的生成任务不要调用旧接口 478 | file.retry_996 = true; 479 | this.downloadFileData( 480 | i, 481 | pcs_url + `&path=${encodeURIComponent(file.path)}` 482 | ); 483 | return; 484 | } else { 485 | // 两个下载接口均未拿到md5, 失败跳出 486 | file.errno = 996; 487 | this.generateBdlink(i + 1); 488 | return; 489 | } 490 | // 获取md5s, "极速生成" 跳过此步 491 | if (file.size < 262144) file.md5s = file.md5; // 此时md5s=md5 492 | else { 493 | // 计算md5s 494 | let spark = new SparkMD5.ArrayBuffer(); 495 | spark.append(data.response); 496 | let sliceMd5 = spark.end(); 497 | file.md5s = sliceMd5; 498 | } 499 | let interval = this.fileInfoList.length > 1 ? 2000 : 1000; 500 | setTimeout(() => { 501 | this.generateBdlink(i + 1); 502 | }, interval); 503 | } 504 | 505 | /** 506 | * @description: "极速生成" 可能得到错误md5, 故执行验证步骤, 若验证不通过则执行普通生成 507 | * @param {number} i 508 | */ 509 | checkMd5(i: number): void { 510 | if (i >= this.fileInfoList.length) { 511 | this.onFinish(this.fileInfoList); 512 | return; 513 | } 514 | let file = this.fileInfoList[i]; 515 | // 跳过扫描失败的目录路径 516 | if (file.errno && file.isdir) { 517 | this.checkMd5(i + 1); 518 | return; 519 | } 520 | this.onProcess(i, this.fileInfoList); 521 | this.onProgress(false, "极速生成中..."); 522 | // this.isSharePage ? this.getShareDlink(i) : this.getDlink(i); 523 | // 23.4.27: 错误md5在文件上传者账号使用此接口正常转存, 在其他账号则报错#404(#31190), 导致生成秒传完全无法验证, 故弃用meta内的md5 524 | // 23.5.4: 发现错误md5只要改成大写, 在上传者账号就能正常返回#31190, 而正确md5则大小写都能正常转存, 故重新启用此验证过程 525 | // 主要是因为频繁请求直链接口获取正确md5会导致#9019错误(即账号被限制), 对大批量生成秒传有很大影响, 极速生成功能使用此验证则可以节约请求以避免此问题 526 | // 为避免百度后面又改接口导致生成错误秒传问题, 这个接口特性我会写个定时脚本每天测试一次, 出了问题就能即使更新 527 | // 目前发现是通过秒传拿到的文件再生成秒传不会有这问题, 上传的文件或通过分享转存的别人上传的文件则会有 528 | rapiduploadCreateFile.call( 529 | this, 530 | file, 531 | (data: any) => { 532 | data = data.response; 533 | if (0 === data.errno) this.checkMd5(i + 1); // md5验证成功 534 | else if (31190 === data.errno) { 535 | // md5验证失败, 执行普通生成, 仅在此处保存任务进度, 生成页不保存进度 536 | if (!this.isSharePage) 537 | GM_setValue("unfinish", { 538 | file_info_list: this.fileInfoList, 539 | file_id: i, 540 | isCheckMd5: true, 541 | }); 542 | this.isSharePage ? this.getShareDlink(i) : this.getDlink(i); 543 | } else { 544 | // 接口访问失败 545 | file.errno = data.errno; 546 | this.checkMd5(i + 1); 547 | } 548 | }, 549 | (statusCode: number) => { 550 | file.errno = statusCode; 551 | this.checkMd5(i + 1); 552 | }, 553 | 0, 554 | true 555 | ); 556 | } 557 | 558 | /** 559 | * @description: 用于解析度盘主页的文件列表数据 560 | */ 561 | parseMainFileList() { 562 | for (let item of this.selectList) { 563 | if (item.isdir) this.dirList.push(item.path); 564 | else 565 | this.fileInfoList.push({ 566 | path: item.path, 567 | size: item.size, 568 | fs_id: item.fs_id, 569 | // 已开启极速生成, 直接取meta内的md5 570 | md5: "", 571 | md5s: "", 572 | }); 573 | } 574 | } 575 | 576 | /** 577 | * @description: 用于解析分享页的文件列表数据 578 | */ 579 | parseShareFileList(list = this.selectList) { 580 | for (let item of list) { 581 | let path: string; 582 | if ("app_id" in item) 583 | path = item.isdir ? item.path : item.server_filename; 584 | else path = item.path; 585 | if ("/" !== path.charAt(0)) path = "/" + path; // 补齐路径开头的斜杠 586 | if (item.isdir) this.dirList.push(path); 587 | else 588 | this.fileInfoList.push({ 589 | path: path, 590 | size: item.size, 591 | fs_id: item.fs_id, 592 | md5: item.md5 && decryptMd5(item.md5.toLowerCase()), 593 | md5s: item.md5s && decryptMd5(item.md5s.toLowerCase()), 594 | }); 595 | } 596 | } 597 | } 598 | -------------------------------------------------------------------------------- /src/baidu/common/rapiduploadTask.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: mengzonefire 3 | * @LastEditors: tousakasp 4 | * @Description: 百度网盘 秒传转存任务实现 5 | */ 6 | 7 | import ajax from "@/common/ajax"; 8 | import { UA } from "@/common/const"; 9 | import { convertData, suffixChange } from "@/common/utils"; 10 | import { 11 | rapidupload_url, 12 | create_url, 13 | getBdstoken, 14 | illegalPathPattern, 15 | } from "./const"; 16 | export default class RapiduploadTask { 17 | savePath: string; 18 | isDefaultPath: boolean; 19 | fileInfoList: Array; 20 | bdstoken: string; 21 | onFinish: (fileInfoList: Array) => void; 22 | onProcess: (i: number, fileInfoList: Array) => void; 23 | 24 | reset(): void { 25 | this.bdstoken = getBdstoken(); 26 | console.log(`bdstoken状态: ${this.bdstoken ? "获取成功" : "获取失败"}`); // debug 27 | this.fileInfoList = []; 28 | this.savePath = ""; 29 | this.isDefaultPath = false; 30 | this.onFinish = () => {}; 31 | this.onProcess = () => {}; 32 | } 33 | 34 | start(): void { 35 | this.saveFileV2(0); 36 | } 37 | 38 | /** 39 | * @description: 转存秒传 接口2 40 | * @param {number} i 41 | */ 42 | saveFileV2(i: number): void { 43 | if (i >= this.fileInfoList.length) { 44 | this.onFinish(this.fileInfoList); 45 | return; 46 | } 47 | this.onProcess(i, this.fileInfoList); 48 | let file = this.fileInfoList[i]; 49 | let onFailed = (statusCode: number) => { 50 | file.errno = statusCode; 51 | this.saveFileV2(i + 1); 52 | }; 53 | if (file.path.endsWith("/") && file.size === 0) { 54 | createDir.call( 55 | this, 56 | file.path.replace(/\/+$/, ''), 57 | (data: any) => { 58 | data = data.response; 59 | file.errno = data.errno; 60 | this.saveFileV2(i + 1); 61 | }, 62 | onFailed 63 | ); 64 | return; 65 | } 66 | // 文件名为空 67 | if (file.path === "/") { 68 | file.errno = -7; 69 | this.saveFileV2(i + 1); 70 | return; 71 | } 72 | rapiduploadCreateFile.call( 73 | this, 74 | file, 75 | (data: any) => { 76 | console.info(JSON.stringify(data)) 77 | data = data.response; 78 | file.errno = 2 === data.errno ? 114 : data.errno; 79 | file.errno = 31190 === file.errno ? 404 : file.errno; 80 | this.saveFileV2(i + 1); 81 | }, 82 | onFailed 83 | ); 84 | } 85 | } 86 | export function createDir( 87 | path: string, 88 | onResponsed: (data: any) => void, 89 | onFailed: (statusCode: number) => void 90 | ): void { 91 | 92 | ajax( 93 | { 94 | url: `${create_url}${this.bdstoken ? "?bdstoken=" + this.bdstoken : ""}`, // bdstoken参数不能放在data里, 否则无效 95 | method: "POST", 96 | responseType: "json", 97 | data: convertData({ 98 | block_list: JSON.stringify([]), 99 | path: this.savePath + path, 100 | isdir: 1, 101 | rtype: 0, 102 | }), 103 | headers: { 104 | "User-Agent": UA, 105 | } 106 | }, 107 | (data) => { 108 | if (0 !== data.response.errno) { 109 | onFailed(data.response.errno); 110 | } else { 111 | onResponsed(data); 112 | } 113 | }, 114 | onFailed 115 | ); 116 | } 117 | 118 | const defaultRetryDelay = 200; 119 | const retryDelayIncrement = 100; 120 | const randomCaseRetryCount = 5; 121 | 122 | function generateRandomInt(max : number) { 123 | return Math.floor(Math.random() * (max + 1)); 124 | } 125 | 126 | function transformCase(str : string, mask : number) { 127 | let next = mask; 128 | return str.toLowerCase().split('').map(c => { 129 | if (c >= 'a' && c <= 'z') { 130 | if (next % 2 === 1) { 131 | c = c.toUpperCase(); 132 | } 133 | next = next >> 1; 134 | } 135 | return c; 136 | }) 137 | .join(''); 138 | } 139 | 140 | export function rapiduploadCreateFile( 141 | file: FileInfo, 142 | onResponsed: (data: any) => void, 143 | onFailed: (statusCode: number) => void, 144 | ): void { 145 | let charCount = file.md5.toLowerCase().split('').filter(c => c >= 'a' && c <= 'z').length; 146 | let maxCombination = 1 << charCount; 147 | let attempts = [ 148 | 0, // 小写成功率比较高 149 | maxCombination - 1, // 大写 150 | ]; 151 | let gen = randomCaseRetryCount; 152 | while (attempts.length < maxCombination && gen > 0) { 153 | let n : number; 154 | do { 155 | n = generateRandomInt(maxCombination - 1); 156 | } while (attempts.includes(n)); 157 | attempts.push(n); 158 | gen--; 159 | } 160 | 161 | tryRapiduploadCreateFile.call(this, file, onResponsed, onFailed, attempts, 0, defaultRetryDelay); 162 | } 163 | 164 | // 此接口测试结果如下: 错误md5->返回"errno": 31190, 正确md5+错误size->返回"errno": 2 165 | // 此外, 即使md5和size均正确, 连续请求时依旧有小概率返回"errno": 2, 故建议加入retry策略 166 | function tryRapiduploadCreateFile( 167 | file: FileInfo, 168 | onResponsed: (data: any) => void, 169 | onFailed: (statusCode: number) => void, 170 | attempts: number[], 171 | attemptIndex: number, 172 | retryDelay: number = 0, 173 | ): void { 174 | const contentMd5 = transformCase(file.md5, attempts[attemptIndex]); 175 | const sliceMd5 = file.md5s.toLowerCase(); 176 | 177 | ajax( 178 | { 179 | url: `${rapidupload_url}${this.bdstoken ? "?bdstoken=" + this.bdstoken : ""}`, // bdstoken参数不能放在data里, 否则无效 180 | method: "POST", 181 | responseType: "json", 182 | data: convertData({ 183 | path: this.savePath + file.path.replace(illegalPathPattern, "_"), 184 | "content-length": file.size, 185 | "content-md5": contentMd5, 186 | "slice-md5": sliceMd5, 187 | rtype: 0, // rtype=3覆盖文件, rtype=0则返回报错, 不覆盖文件, 默认为rtype=1 (自动重命名, 1和2是两种不同的重命名策略) 188 | }), 189 | headers: { 190 | "User-Agent": UA, 191 | } 192 | }, 193 | (data) => { 194 | // console.log(data.response); // debug 195 | if (31039 === data.response.errno && 31039 != file.errno) { 196 | file.errno = 31039; 197 | file.path = suffixChange(file.path); 198 | tryRapiduploadCreateFile.call(this, file, onResponsed, onFailed, attempts, attemptIndex); 199 | } else if (404 === data.response.errno && attempts.length > attemptIndex + 1) { 200 | //console.log(`转存接口错误, 重试${retry + 1}次: ${file.path}`); // debug 201 | setTimeout(() => { 202 | tryRapiduploadCreateFile.call(this, file, onResponsed, onFailed, attempts, attemptIndex + 1, retryDelay + retryDelayIncrement); 203 | }, retryDelay); 204 | } else if (0 !== data.response.errno) { 205 | onFailed(data.response.errno); 206 | } else onResponsed(data); 207 | }, 208 | onFailed 209 | ); 210 | } 211 | -------------------------------------------------------------------------------- /src/baidu/legacyPage/loader.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: mengzonefire 3 | * @Date: 2022-10-20 10:36:43 4 | * @LastEditTime: 2022-12-24 10:57:23 5 | * @LastEditors: mengzonefire 6 | * @Description: 旧版度盘界面loader入口: https://pan.baidu.com/disk/home?stayAtHome=true 7 | */ 8 | 9 | import { TAG, version } from "@/common/const"; 10 | import { 11 | setGetBdstoken, 12 | setGetShareFileList, 13 | setGetSelectedFileList, 14 | setRefreshList, 15 | swalInstance, 16 | } from "../common/const"; 17 | import { getSelectedFileListLegacy, getShareFileList } from "@/common/utils"; 18 | 19 | const htmlTagLegacy = "div.tcuLAu"; // 旧版界面秒传按钮的html父对象 20 | const htmlBtnRapidLegacy = // 旧版界面秒传按钮的html元素 21 | '秒传链接'; 22 | const htmlBtnGenLegacy = // 旧版界面秒传生成按钮的html元素 23 | '生成秒传'; 24 | 25 | export default function installLegacy() { 26 | console.info("%s version: %s DOM方式安装", TAG, version); 27 | setRefreshList(() => { 28 | // 旧版界面, 调用原生方法刷新文件列表, 无需重新加载页面 29 | unsafeWindow 30 | .require("system-core:system/baseService/message/message.js") 31 | .trigger("system-refresh"); 32 | }); 33 | setGetShareFileList(getShareFileList); 34 | setGetSelectedFileList(getSelectedFileListLegacy); 35 | setGetBdstoken(() => unsafeWindow.locals.get("bdstoken")); 36 | addBtn(); // DOM添加秒传按钮 37 | addGenBtn(); // DOM添加生成按钮 38 | $(document).on("click", "#bdlink_btn", () => { 39 | swalInstance.inputView(); 40 | }); // 绑定秒传按钮事件 41 | $(document).on("click", "#gen_bdlink_btn", () => { 42 | swalInstance.generatebdlinkTask.reset(); 43 | swalInstance.checkUnfinish(); 44 | }); // 绑定生成按钮事件 45 | } 46 | 47 | function getSystemContext() { 48 | return unsafeWindow.require("system-core:context/context.js") 49 | .instanceForSystem; 50 | } 51 | 52 | function addGenBtn() { 53 | let listTools = getSystemContext().Broker.getButtonBroker("listTools"); 54 | if (listTools && listTools.$box) 55 | $(listTools.$box).children("div").after(htmlBtnGenLegacy); 56 | else setTimeout(addGenBtn, 300); 57 | } 58 | 59 | function addBtn() { 60 | if ($(htmlTagLegacy).length) $(htmlTagLegacy).append(htmlBtnRapidLegacy); 61 | else setTimeout(addBtn, 100); 62 | } 63 | -------------------------------------------------------------------------------- /src/baidu/loader.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: mengzonefire 3 | * @LastEditors: tousakasp 4 | * @Description: 主函数入口 5 | */ 6 | 7 | import { 8 | locUrl, 9 | baiduNewPage, 10 | baiduSyncPage, 11 | baiduSharePage, 12 | baiduMobilePage, 13 | updateInfoVer, 14 | TAG, 15 | version, 16 | } from "@/common/const"; 17 | import { parseQueryLink } from "@/common/duParser"; 18 | import installNew from "./newPage/loader"; 19 | import installLegacy from "./legacyPage/loader"; 20 | import { swalInstance } from "./common/const"; 21 | import installSync from "./syncPage/loader"; 22 | import installShare from "./sharePage/loader"; 23 | import installMobile from "./mobilePage/loader"; 24 | import installMobileShare from "./mobileSharePage/loader"; 25 | import { isMobileVer } from "../common/utils"; 26 | 27 | export function loaderBaidu(): void { 28 | let load = () => { 29 | if (locUrl.includes(baiduNewPage)) { 30 | installNew(); 31 | } else if (locUrl.includes(baiduSharePage)) { 32 | if (isMobileVer()) { 33 | installMobileShare(); 34 | } else { 35 | installShare(); 36 | } 37 | } else if (locUrl.includes(baiduSyncPage)) { 38 | installSync(); 39 | } else if (isMobileVer() && locUrl.includes(baiduMobilePage)) { 40 | installMobile(); 41 | } else { 42 | installLegacy(); 43 | } 44 | 45 | // 进入页面后的弹窗任务 46 | let bdlink = parseQueryLink(locUrl); // 解析url中的秒传链接 47 | if (bdlink) { 48 | // 解析到秒传链接, 弹出转存窗口 49 | swalInstance.inputView(bdlink); 50 | } else if (!GM_getValue(`${updateInfoVer}_no_first`)) 51 | // 检查是否首次运行, 若是则弹出更新信息窗口 52 | swalInstance.updateInfo(() => { 53 | GM_setValue(`${updateInfoVer}_no_first`, true); 54 | }); 55 | 56 | // 预先绑定好按钮事件 57 | $(document).on("click", "#copy_fail_list", (btn) => { 58 | let listText = ""; 59 | for (let item of swalInstance.parseResult.failList) 60 | listText += item.path + "\n"; 61 | GM_setClipboard(listText); 62 | btn.target.innerText = "复制成功"; 63 | }); // 失败文件列表复制 64 | $(document).on("click", "#copy_success_list", (btn) => { 65 | let listText = ""; 66 | for (let item of swalInstance.parseResult.successList) 67 | listText += item.path + "\n"; 68 | GM_setClipboard(listText); 69 | btn.target.innerText = "复制成功"; 70 | }); // 成功文件列表复制 71 | $(document).on("click", "#copy_fail_branch_list", (btn) => { 72 | let ele = $(btn.target); 73 | GM_setClipboard( 74 | ele 75 | .parents("details.mzf_details_branch") 76 | .next()[0] 77 | .innerText.replace(/\n\n/g, "\n") 78 | ); 79 | btn.target.innerText = "复制成功"; 80 | }); // 失败文件分支列表复制 81 | 82 | try { 83 | // 添加油猴插件菜单按钮 84 | GM_registerMenuCommand("🕮 版本信息", () => { 85 | swalInstance.updateInfo(() => {}); 86 | }); 87 | GM_registerMenuCommand("⚙ 工具设置", () => { 88 | swalInstance.settingView(); 89 | }); 90 | GM_registerMenuCommand("⚡生成秒传(输入文件路径)", () => { 91 | swalInstance.genView(); 92 | }); 93 | } catch (_) { 94 | console.info( 95 | "%s version: %s 插件菜单添加失败, 使用的插件不支持GM_registerMenuCommand", 96 | TAG, 97 | version 98 | ); 99 | } 100 | }; 101 | // 绑定入口函数到dom事件 102 | const giveUpTime = Date.now() + 30000; 103 | function tryLoad() { 104 | if (["interactive", "complete"].includes(document.readyState)) { 105 | load(); 106 | } else if (giveUpTime > Date.now()) { 107 | setTimeout(tryLoad, 100); 108 | } else { 109 | console.warn('插件添加失败'); 110 | } 111 | } 112 | tryLoad(); 113 | } 114 | -------------------------------------------------------------------------------- /src/baidu/mobilePage/loader.tsx: -------------------------------------------------------------------------------- 1 | import { TAG, version } from "@/common/const"; 2 | import { 3 | setGetBdstoken, 4 | setGetShareFileList, 5 | setGetSelectedFileList, 6 | setRefreshList, 7 | swalInstance, 8 | } from "../common/const"; 9 | import { getShareFileList } from "@/common/utils"; 10 | 11 | const htmlBtnRapidNew = // 新版界面秒传按钮的html元素 12 | ''; 13 | 14 | export default function installMobile() { 15 | console.info("%s version: %s MobileVer方式安装", TAG, version); 16 | swalInstance.swalGlobalArgs = { 17 | heightAuto: false, 18 | scrollbarPadding: false, 19 | }; // 添加swal参数以防止新版界面下的body样式突变 20 | setRefreshList(() => document.location.reload()); 21 | setGetShareFileList(getShareFileList); 22 | setGetSelectedFileList(() => { 23 | const fileList : Array = $('.main-container > .multifile > .file-list')[0].__vue__.allFileList; 24 | return fileList.filter(item=>!!item.selected); 25 | }); 26 | setGetBdstoken(() => unsafeWindow.locals.bdstoken); 27 | $(document).on("click", "#bdlink_btn", () => { 28 | swalInstance.inputView(); 29 | }); // 绑定转存秒传按钮事件 30 | $(document).on("click", "#gen_bdlink_btn", () => { 31 | swalInstance.generatebdlinkTask.reset(); 32 | swalInstance.checkUnfinish(); 33 | }); // 绑定生成秒传按钮事件 34 | addBtn(); 35 | } 36 | 37 | function addBtn() { 38 | // 轮询添加按钮, 防止新版页面重复init时, 将按钮覆盖 39 | let target = $(".main-container > header"); 40 | if (target.length && !$("#bdlink_btn").length) 41 | target.append(htmlBtnRapidNew); 42 | let target2 = $(".main-container"); 43 | if (target2.length && !$("#gen_bdlink_btn").length) 44 | target2.append(''); 45 | setTimeout(addBtn, 500); 46 | } 47 | -------------------------------------------------------------------------------- /src/baidu/mobileSharePage/loader.tsx: -------------------------------------------------------------------------------- 1 | import { TAG, version } from "@/common/const"; 2 | import { 3 | setGetBdstoken, 4 | setGetShareFileList, 5 | setRefreshList, 6 | swalInstance, 7 | } from "../common/const"; 8 | 9 | export default function installMobileShare() { 10 | console.info("%s version: %s MobileVer方式安装", TAG, version); 11 | swalInstance.swalGlobalArgs = { 12 | heightAuto: false, 13 | scrollbarPadding: false, 14 | }; // 添加swal参数以防止新版界面下的body样式突变 15 | setRefreshList(() => document.location.reload()); 16 | setGetShareFileList(() => { 17 | const fileList : Array = $('.main-container > .multifile > .file-list')[0].__vue__.allFileList; 18 | return Array.from(fileList).map(item => { 19 | return Object.assign({}, item, { 20 | category: item.category * 1, 21 | fs_id: item.fs_id * 1, 22 | isdir: item.isdir * 1, 23 | local_ctime: item.local_ctime * 1, 24 | local_mtime: item.local_mtime * 1, 25 | server_ctime: item.server_ctime * 1, 26 | server_mtime: item.server_mtime * 1, 27 | size: item.size * 1, 28 | }); 29 | }); 30 | }); 31 | setGetBdstoken(() => unsafeWindow.locals.bdstoken); 32 | $(document).on("click", "#gen_bdlink_btn", () => { 33 | swalInstance.generatebdlinkTask.reset(); 34 | swalInstance.generatebdlinkTask.isSharePage = true; 35 | swalInstance.checkUnfinish(); 36 | }); // 绑定生成秒传按钮事件 37 | addBtn(); 38 | } 39 | 40 | function addBtn() { 41 | // 轮询添加按钮, 防止新版页面重复init时, 将按钮覆盖 42 | let target = $(".main-container"); 43 | if (target.length && !$("#gen_bdlink_btn").length) 44 | target.append('