├── LICENSE ├── README.md ├── blash.cmd └── copilot-agent.cmd /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 | ## 工具列表 2 | 3 | ### 1. [blash.cmd](https://github.com/wzdnzd/batches/blob/main/blash.cmd) 4 | 5 | > 基于 [Clash](https://github.com/zhongfly/Clash-premium-backup/releases) 或 [Mihomo](https://github.com/MetaCubeX/mihomo) 的网络代理命令行管理工具 6 | 7 | 使用方法:blash.cmd [功能选项] [其他参数],支持 `-` 和 `--` 两种模式 8 | 9 | 10 | 11 | 功能选项 12 | 13 | | 短参数 | 长参数 | 功能 | 14 | | ------ | ------------ | ---------------------------------------------------------------- | 15 | | `-f` | `--fix` | 检查并尝试修复代理网络 | 16 | | `-h` | `--help` | 打印帮助信息 | 17 | | `-i` | `--init` | 利用 `--conf` 提供的配置文件或订阅地址创建代理网络 | 18 | | `-k` | `--kill` | 退出网络代理程序 | 19 | | `-o` | `--overload` | 重新加载配置文件 | 20 | | `-p` | `--purge` | 关闭系统代理并禁止程序开机自启,取消自动更新 | 21 | | `-r` | `--restart` | 重启网络代理程序 | 22 | | `-t` | `--test` | 测试代理网络是否可用 | 23 | | `-u` | `--update` | 更新所有组件,包括 clash.exe、订阅、代理规则以及 IP 地址数据库等 | 24 | 25 | 其他参数 26 | 27 | | 短参数 | 长参数 | 功能 | 28 | | ------ | -------------- | ----------------------------------------------------------------------------------------------------------- | 29 | | `-a` | `--alpha` | 是否允许使用预览版,默认为稳定版,搭配 `-i` 或者 `-u` 使用 | 30 | | `-b` | `--brief` | 精简模式运行,没有明确配置dashboard情况下,无法使用可视化页面 | 31 | | `-c` | `--conf` | 配置文件,支持本地配置文件和订阅链接,默认为当前目录下的 `config.yaml` | 32 | | `-d` | `--daemon` | 后台静默执行,禁止打印日志 | 33 | | `-e` | `--exclude` | 更新时跳过代理集中配置的订阅 | 34 | | `-g` | `--generate` | 重新生成自动检查更新的脚本,搭配 `-u` 使用 | 35 | | `-m` | `--meta` | 如果配置兼容,使用 [mihomo](https://github.com/MetaCubeX/mihomo) 代替 clash.premium,搭配 `-i` 或 `-u` 使用 | 36 | | `-n` | `--native` | 强制使用 clash.premium,搭配 `-i` 或 `-u` 使用 | 37 | | `-q` | `--quick` | 仅更新新订阅和代理规则,搭配 `-u` 使用 | 38 | | `-s` | `--show` | 新窗口中执行,默认为当前窗口 | 39 | | `-w` | `--workspace` | 代理程序运行路径,默认为当前脚本所在目录 | 40 | | `-x` | `--metacubexd` | 使用 [metacubexd](https://github.com/MetaCubeX/metacubexd) 控制面板,搭配 `-i` 或 `-u` 使用 | 41 | | `-y` | `--yacd` | 使用 [yacd](https://github.com/MetaCubeX/Yacd-meta) 控制面板,搭配 `-i` 或 `-u` 使用 | 42 | 43 | 44 | 45 | ### 2. [copilot-agent.cmd](https://github.com/wzdnzd/batches/blob/main/copilot-agent.cmd) 46 | 47 | > 基于 [override](https://github.com/linux-do/override) 和 [cocopilot](https://cocopilot.org/dash) 实现的 [Github Copilot](https://github.com/features/copilot) Agent 命令行管理工具 48 | 49 | 使用方法:copilot-agent.cmd [功能选项] [其他参数],支持 `-` 和 `--` 两种模式 50 | 51 | 52 | 53 | 功能选项 54 | 55 | | 短参数 | 长参数 | 功能 | 56 | | ------ | ----------- | --------------------------------------------------------------------------------------------------------------- | 57 | | `-e` | `--env` | 设置环境变量,配合 `-a`、`-b` 以及 `-l` 使用 | 58 | | `-g` | `--github` | 打印 [override 项目](https://github.com/linux-do/override) 及 [cocopilot 平台](https://cocopilot.org/dash) 地址 | 59 | | `-h` | `--help` | 打印帮助信息 | 60 | | `-p` | `--purge` | 禁止服务开机自启、自动更新及环境变量设置等 | 61 | | `-q` | `--quit` | 退出服务 | 62 | | `-r` | `--restart` | 重启服务 | 63 | | `-s` | `--start` | 启动服务 | 64 | | `-u` | `--update` | 检查并更新 `override.exe` 可执行程序 | 65 | 66 | 其他参数 67 | 68 | | 短参数 | 长参数 | 功能 | 69 | | ------ | --------------- | ----------------------------------------------------- | 70 | | `-a` | `--all` | 为所有用户设置环境变量,默认只对当前用户有效 | 71 | | `-b` | `--base` | 接口地址,默认为 `https://cocopilot.org` | 72 | | `-d` | `--display` | 前台运行,默认启动守护进程静默执行 | 73 | | `-f` | `--filename` | 可执行程序文件名,默认为 `override.exe` | 74 | | `-i` | `--interactive` | 新窗口中执行,不隐藏窗口 | 75 | | `-l` | `--link` | API 接口子路径,默认为空 | 76 | | `-w` | `--workspace` | `override.exe` 所在文件夹路径,默认为当前脚本所在目录 | 77 | -------------------------------------------------------------------------------- /blash.cmd: -------------------------------------------------------------------------------- 1 | @REM author: wzdnzd 2 | @REM date: 2022-08-24 3 | @REM describe: network proxy controller for clash 4 | 5 | @echo off & PUSHD %~DP0 & cd /d "%~dp0" 6 | 7 | @REM change encoding 8 | chcp 65001 >nul 2>nul 9 | 10 | @REM https://blog.csdn.net/sanqima/article/details/37818115 11 | setlocal enableDelayedExpansion 12 | 13 | @REM output with color 14 | call :setESC 15 | 16 | @REM call workflow 17 | goto :workflow 18 | 19 | 20 | @REM ######################## 21 | @REM function define blow ### 22 | @REM ######################## 23 | 24 | @REM process pipeline 25 | :workflow 26 | @REM batch file name 27 | set "batname=%~nx0" 28 | 29 | @REM microsoft terminal displays differently from cmd and powershell 30 | @REM call :ismsterminal msterminal 31 | set "msterminal=1" 32 | 33 | @REM enable create shortcut 34 | set "enableshortcut=1" 35 | 36 | @REM enable download config from remote 37 | set "enableremoteconf=1" 38 | set "remoteurl=" 39 | 40 | @REM validate configuration files before starting 41 | set "verifyconf=0" 42 | 43 | @REM check and update wintun.dll 44 | set "checkwintun=0" 45 | 46 | @REM info color 47 | set "infocolor=92" 48 | set "warncolor=93" 49 | 50 | if "!msterminal!" == "1" ( 51 | set "infocolor=95" 52 | set "warncolor=97" 53 | ) 54 | 55 | @REM print heart 56 | set "customize=0" 57 | set "drawheart=0" 58 | 59 | @REM exit flag 60 | set "shouldexit=0" 61 | 62 | @REM init 63 | set "initflag=0" 64 | 65 | @REM configuration file name 66 | set "configuration=config.yaml" 67 | 68 | @REM subscription link 69 | set "sublink=" 70 | set "isweblink=0" 71 | 72 | @REM check 73 | set "testflag=0" 74 | 75 | @REM repair 76 | set "repair=0" 77 | 78 | @REM only reload 79 | set "reloadonly=0" 80 | 81 | @REM restart clash.exe 82 | set "restartflag=0" 83 | 84 | @REM close proxy 85 | set "killflag=0" 86 | 87 | @REM update 88 | set "updateflag=0" 89 | 90 | @REM purge 91 | set "purgeflag=0" 92 | 93 | @REM only update subscriptions and rulesets 94 | set "quickflag=0" 95 | 96 | @REM don't update subscription 97 | set "exclude=0" 98 | 99 | @REM use clash.meta 100 | set "clashmeta=0" 101 | 102 | @REM use clash.premium 103 | set "clashpremium=0" 104 | 105 | @REM alpha version allowed 106 | set "alpha=0" 107 | 108 | @REM simplified mode 109 | set "brief=0" 110 | 111 | @REM regenerates auto update script 112 | set "regenerate=0" 113 | 114 | @REM yacd dashboard, see https://github.com/MetaCubeX/Yacd-meta or https://github.com/haishanh/yacd 115 | set "yacd=0" 116 | 117 | @REM metacubexd, see https://github.com/MetaCubeX/metacubexd 118 | set "metacubexd=0" 119 | 120 | @REM run on background 121 | set "asdaemon=0" 122 | 123 | @REM show window 124 | set "show=0" 125 | 126 | @REM setting workspace 127 | set "dest=" 128 | 129 | @REM network proxy registry configuration path 130 | set "proxyregpath=HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" 131 | 132 | @REM autostart registry configuration path 133 | set "autostartregpath=HKCU\Software\Microsoft\Windows\CurrentVersion\Run" 134 | set "startupapproved=HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run" 135 | 136 | @REM parse arguments 137 | call :argsparse %* 138 | 139 | @REM invalid arguments 140 | if "!shouldexit!" == "1" exit /b 1 141 | 142 | @REM regular file path 143 | if "!dest!" == "" set "dest=%~dp0" 144 | call :pathregular dest "!dest!" 145 | 146 | @REM auto start vb script 147 | set "startupvbs=!dest!\startup.vbs" 148 | 149 | @REM auto update vb script 150 | set "updatevbs=!dest!\update.vbs" 151 | 152 | @REM draw a heart 153 | if "!drawheart!"== "1" goto :printheart 154 | 155 | @REM close network proxy 156 | if "!killflag!" == "1" goto :closeproxy 157 | 158 | @REM clean all setting 159 | if "!purgeflag!" == "1" goto :purge 160 | 161 | @REM prevent precheck if no action 162 | if "!reloadonly!" == "0" if "!restartflag!" == "0" if "!repair!" == "0" if "!testflag!" == "0" if "!updateflag!" == "0" if "!initflag!" == "0" ( 163 | @REM @echo [%ESC%[91m错误%ESC%[0m] 必须包含 [%ESC%[!warncolor!m-f%ESC%[0m %ESC%[!warncolor!m-i%ESC%[0m %ESC%[!warncolor!m-k%ESC%[0m %ESC%[!warncolor!m-r%ESC%[0m %ESC%[!warncolor!m-t%ESC%[0m %ESC%[!warncolor!m-u%ESC%[0m] 中的一种操作 164 | @REM @echo. 165 | 166 | if "!shouldexit!" == "0" goto :usage 167 | exit /b 168 | ) 169 | 170 | @REM config file path 171 | call :precheck configfile 172 | if "!configfile!" == "" exit /b 1 173 | 174 | @REM connectivity test 175 | if "!testflag!" == "1" ( 176 | call :checkconnect available 1 177 | exit /b 178 | ) 179 | 180 | @REM reload config 181 | if "!reloadonly!" == "1" goto :reload 182 | 183 | @REM update 184 | if "!restartflag!" == "1" goto :restartprogram 185 | 186 | @REM check issues 187 | if "!repair!" == "1" goto :resolveissues 188 | 189 | @REM update 190 | if "!updateflag!" == "1" goto :updateplugins 191 | 192 | @REM init 193 | if "!initflag!" == "1" goto :initialize 194 | 195 | @REM unknown command 196 | @REM if "!shouldexit!" == "0" goto :usage 197 | 198 | exit /b 199 | 200 | 201 | @REM check if the configuration file exists 202 | :precheck 203 | set "%~1=" 204 | set "subfile=!temp!\clashsub.yaml" 205 | 206 | @REM absolute path 207 | call :pathconvert conflocation "!configuration!" 208 | call :pathregular conflocation "!conflocation!" 209 | 210 | if "!conflocation!" == "" ( 211 | @echo [%ESC%[91m错误%ESC%[0m] 配置文件路径%ESC%[91m无效%ESC%[0m 212 | exit /b 1 213 | ) 214 | 215 | @REM cannot contain whitespace in path 216 | if "!conflocation!" NEQ "!conflocation: =!" ( 217 | @echo [%ESC%[91m错误%ESC%[0m] 无效的配置文件 "%ESC%[!warncolor!m!conflocation!%ESC%[0m", 路径不能包含%ESC%[!warncolor!m空格%ESC%[0m 218 | exit /b 1 219 | ) 220 | 221 | if "!isweblink!" == "1" ( 222 | if exist "!conflocation!" ( 223 | set "tips=[%ESC%[!warncolor!m警告%ESC%[0m] %ESC%[!warncolor!m已存在%ESC%[0m配置文件 "%ESC%[!warncolor!m!conflocation!%ESC%[0m" 会被%ESC%[91m覆盖%ESC%[0m,是否继续? (%ESC%[!warncolor!mY%ESC%[0m/%ESC%[!warncolor!mN%ESC%[0m) " 224 | if "!msterminal!" == "1" ( 225 | choice /t 6 /d n /n /m "!tips!" 226 | ) else ( 227 | set /p "=!tips!" nul 2>nul 235 | 236 | set "statuscode=000" 237 | for /f %%a in ('curl --retry 3 --retry-max-time 30 -m 60 --connect-timeout 30 -L -s -o "!subfile!" -w "%%{http_code}" -H "User-Agent: Clash" "!sublink!"') do set "statuscode=%%a" 238 | 239 | @REM download success 240 | if "!statuscode!" == "200" ( 241 | set "filesize=0" 242 | if exist "!subfile!" (for %%a in ("!subfile!") do set "filesize=%%~za") 243 | if !filesize! GTR 64 ( 244 | @REM validate 245 | set "content=" 246 | for /f "tokens=*" %%a in ('findstr /i /r /c:"^external-controller:[ ][ ]*.*:[0-9][0-9]*.*" !subfile!') do set "content=%%a" 247 | if "!content!" == "" ( 248 | @echo [%ESC%[91m错误%ESC%[0m] 订阅 "%ESC%[!warncolor!m!sublink!%ESC%[0m" 无效,请检查确认 249 | exit /b 1 250 | ) 251 | 252 | del /f /q "!conflocation!" >nul 2>nul 253 | call :splitpath filepath filename "!conflocation!" 254 | call :makedirs success "!filepath!" 255 | if "!success!" == "0" ( 256 | @echo [%ESC%[91m错误%ESC%[0m] 创建文件夹 "%ESC%[!warncolor!m!filepath!%ESC%[0m" %ESC%[91m失败%ESC%[0m,请确认路径是否合法 257 | exit /b 1 258 | ) 259 | 260 | move "!subfile!" "!conflocation!" >nul 2>nul 261 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 订阅下载%ESC%[!infocolor!m成功%ESC%[0m 262 | 263 | @REM 保存订阅链接 264 | @echo !sublink! > "!filepath!\subscriptions.txt" 265 | ) else ( 266 | @REM output is empty 267 | set "statuscode=000" 268 | ) 269 | ) 270 | 271 | if "!statuscode!" NEQ "200" ( 272 | @echo [%ESC%[91m错误%ESC%[0m] 订阅下载%ESC%[91m失败%ESC%[0m, 请检查确认此订阅是否有效 273 | exit /b 1 274 | ) 275 | ) 276 | 277 | if not exist "!conflocation!" ( 278 | @echo [%ESC%[91m错误%ESC%[0m] 配置文件 "%ESC%[!warncolor!m!conflocation!%ESC%[0m" %ESC%[91m不存在%ESC%[0m 279 | goto :eof 280 | ) 281 | 282 | @REM validate 283 | set "content=" 284 | for /f "tokens=1* delims=:" %%a in ('findstr /i /r /c:"^proxy-groups:[ ]*" "!conflocation!"') do set "content=%%a" 285 | call :trim content "!content!" 286 | if "!content!" NEQ "proxy-groups" ( 287 | @echo [%ESC%[91m错误%ESC%[0m] %ESC%[91m无效%ESC%[0m的配置文件 "%ESC%[!warncolor!m!conflocation!%ESC%[0m" 288 | exit /b 1 289 | ) 290 | 291 | set "%~1=!conflocation!" 292 | goto :eof 293 | 294 | 295 | @REM Initialize network proxy 296 | :initialize 297 | set "tips=[%ESC%[!warncolor!m提示%ESC%[0m] 网络代理程序将在目录 "%ESC%[!warncolor!m!dest!%ESC%[0m" 安装并运行,是否继续?(%ESC%[!warncolor!mY%ESC%[0m/%ESC%[!warncolor!mN%ESC%[0m) " 298 | if "!msterminal!" == "1" ( 299 | choice /t 5 /d n /n /m "!tips!" 300 | ) else ( 301 | set /p "=!tips!" nul 2>nul 379 | ) 380 | ) 381 | 382 | @echo [%ESC%[91m错误%ESC%[0m] 问题修复%ESC%[91m失败%ESC%[0m, 网络代理仍%ESC%[91m无法%ESC%[0m使用, 请尝试其他方法 383 | goto :eof 384 | 385 | 386 | @REM check if the network is available 387 | :checkwapper 388 | set "%~1=1" 389 | call :trim loglevel "%~2" 390 | if "!loglevel!" == "" set "loglevel=1" 391 | 392 | call :isavailable available 0 "https://www.baidu.com" "" 393 | if "!available!" == "0" ( 394 | @echo [%ESC%[91m错误%ESC%[0m] 网络%ESC%[91m不可用%ESC%[0m, 但代理程序%ESC%[91m并未运行%ESC%[0m,请检查你的%ESC%[!warncolor!m本地网络%ESC%[0m是否正常 395 | 396 | @REM should terminate 397 | set "%~1=0" 398 | exit /b 399 | ) 400 | 401 | if "!loglevel!" == "1" ( 402 | @echo [%ESC%[!warncolor!m提示%ESC%[0m] 网络代理%ESC%[91m没有开启%ESC%[0m, 推荐选择 %ESC%[!warncolor!mRestart%ESC%[0m 开启 403 | ) 404 | goto :eof 405 | 406 | 407 | @REM update workflow 408 | :updateplugins 409 | set "downloaded=0" 410 | 411 | if "!quickflag!" == "1" ( 412 | call :quickupdate modified 413 | if "!modified!" == "0" (exit /b 0) else (set "downloaded=1") 414 | ) 415 | 416 | @REM run as admin 417 | if "!asdaemon!" == "1" ( 418 | cacls "%SystemDrive%\System Volume Information" >nul 2>&1 || (start "" mshta vbscript:CreateObject^("Shell.Application"^).ShellExecute^("%~snx0"," %*","","runas",!show!^)^(window.close^)&exit /b) 419 | ) 420 | 421 | @REM prepare all plugins 422 | call :prepare changed 1 !downloaded! 423 | 424 | @REM no new version found 425 | if "!changed!" == "0" ( 426 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 当前已是最新版本,无需更新 427 | ) else ( 428 | @REM wait for overwrite files 429 | timeout /t 1 /nobreak >nul 2>nul 430 | ) 431 | 432 | @REM postclean 433 | call :cleanworkspace "!temp!" 434 | 435 | @REM startup 436 | call :startclash 437 | 438 | @REM regenerate auto update script 439 | if "!regenerate!" == "1" call :generateupdatevbs 440 | 441 | goto :eof 442 | 443 | 444 | @REM parse and validate arguments 445 | :argsparse 446 | set result=false 447 | 448 | if "%1" == "-a" set result=true 449 | if "%1" == "--alpha" set result=true 450 | if "!result!" == "true" ( 451 | set "alpha=1" 452 | set result=false 453 | shift & goto :argsparse 454 | ) 455 | 456 | if "%1" == "-b" set result=true 457 | if "%1" == "--brief" set result=true 458 | if "!result!" == "true" ( 459 | set "brief=1" 460 | set result=false 461 | shift & goto :argsparse 462 | ) 463 | 464 | if "%1" == "-c" set result=true 465 | if "%1" == "--conf" set result=true 466 | if "!result!" == "true" ( 467 | @REM validate argument 468 | call :trim subscription "%~2" 469 | 470 | if "!subscription!" == "" set result=false 471 | if "!subscription:~0,2!" == "--" set result=false 472 | if "!subscription:~0,1!" == "-" set result=false 473 | 474 | if "!result!" == "false" ( 475 | @echo [%ESC%[91m错误%ESC%[0m] 如果指定参数 "%ESC%[!warncolor!m--conf%ESC%[0m" 或者 "%ESC%[!warncolor!m-c%ESC%[0m" 则必须提供有效的%ESC%[!warncolor!m配置文件%ESC%[0m或%ESC%[!warncolor!m订阅%ESC%[0m 476 | @echo. 477 | goto :usage 478 | ) 479 | 480 | if "!subscription:~0,8!" == "https://" set "isweblink=1" 481 | if "!subscription:~0,7!" == "http://" set "isweblink=1" 482 | if "!isweblink!" == "1" ( 483 | set "invalid=0" 484 | 485 | @REM include '"' see https://stackoverflow.com/questions/46238709/how-to-detect-if-input-is-quote 486 | @echo !subscription! | findstr /i /r /c:"\"^" >nul && (set "invalid=1") 487 | 488 | @REM contain whitespace 489 | if "!subscription!" neq "!subscription: =!" set "invalid=1" 490 | @REM match url 491 | echo "!subscription!" | findstr /i /r /c:^"\"http.*://.*[a-zA-Z0-9][a-zA-Z0-9]*\"^" >nul 2>nul || (set "invalid=1") 492 | 493 | if "!invalid!" == "1" ( 494 | set "shouldexit=1" 495 | 496 | @echo [%ESC%[91m错误%ESC%[0m] 无效的订阅链接 "%ESC%[!warncolor!m!subscription!%ESC%[0m" 497 | @echo. 498 | goto :eof 499 | ) 500 | set "sublink=!subscription!" 501 | ) else ( 502 | set "invalid=1" 503 | if "!subscription:~-5!" == ".yaml" (set "invalid=0") else ( 504 | if "!subscription:~-4!" == ".yml" (set "invalid=0") 505 | ) 506 | if "!invalid!" == "0" ( 507 | set "configuration=!subscription!" 508 | ) else ( 509 | set "shouldexit=1" 510 | 511 | @echo [%ESC%[91m错误%ESC%[0m] 无效的配置文件 "%ESC%[!warncolor!m!subscription!%ESC%[0m",仅支持 "%ESC%[!warncolor!m.yaml%ESC%[0m" 和 "%ESC%[!warncolor!m.yml%ESC%[0m" 格式 512 | @echo. 513 | goto :eof 514 | ) 515 | ) 516 | shift & shift & goto :argsparse 517 | ) 518 | 519 | if "%1" == "-d" set result=true 520 | if "%1" == "--daemon" set result=true 521 | if "!result!" == "true" ( 522 | set "asdaemon=1" 523 | set result=false 524 | shift & goto :argsparse 525 | ) 526 | 527 | if "%1" == "-e" set result=true 528 | if "%1" == "--exclude" set result=true 529 | if "!result!" == "true" ( 530 | set "exclude=1" 531 | set result=false 532 | shift & goto :argsparse 533 | ) 534 | 535 | if "%1" == "-f" set result=true 536 | if "%1" == "--fix" set result=true 537 | if "!result!" == "true" ( 538 | set "repair=1" 539 | set result=false 540 | shift & goto :argsparse 541 | ) 542 | 543 | if "%1" == "-g" set result=true 544 | if "%1" == "--generate" set result=true 545 | if "!result!" == "true" ( 546 | set "regenerate=1" 547 | set result=false 548 | shift & goto :argsparse 549 | ) 550 | 551 | if "%1" == "-h" set result=true 552 | if "%1" == "--help" set result=true 553 | if "!result!" == "true" ( 554 | call :usage 555 | ) 556 | 557 | if "%1" == "-i" set result=true 558 | if "%1" == "--init" set result=true 559 | if "!result!" == "true" ( 560 | set "initflag=1" 561 | set result=false 562 | shift & goto :argsparse 563 | ) 564 | 565 | if "%1" == "-k" set result=true 566 | if "%1" == "--kill" set result=true 567 | if "!result!" == "true" ( 568 | set "killflag=1" 569 | set result=false 570 | shift & goto :argsparse 571 | ) 572 | 573 | if "%1" == "-l" set result=true 574 | if "%1" == "--love" set result=true 575 | if "!result!" == "true" ( 576 | if "!customize!" == "1" ( 577 | set "drawheart=1" 578 | set result=false 579 | shift & goto :argsparse 580 | ) else ( 581 | @echo [%ESC%[91m错误%ESC%[0m] 未知参数:%ESC%[91m%1%ESC%[0m 582 | @echo. 583 | goto :usage 584 | ) 585 | ) 586 | 587 | if "%1" == "-m" set result=true 588 | if "%1" == "--meta" set result=true 589 | if "!result!" == "true" ( 590 | set "clashmeta=1" 591 | set result=false 592 | shift & goto :argsparse 593 | ) 594 | 595 | if "%1" == "-n" set result=true 596 | if "%1" == "--native" set result=true 597 | if "!result!" == "true" ( 598 | set "clashpremium=1" 599 | set result=false 600 | shift & goto :argsparse 601 | ) 602 | 603 | if "%1" == "-o" set result=true 604 | if "%1" == "--overload" set result=true 605 | if "!result!" == "true" ( 606 | set "reloadonly=1" 607 | set result=false 608 | shift & goto :argsparse 609 | ) 610 | 611 | if "%1" == "-p" set result=true 612 | if "%1" == "--purge" set result=true 613 | if "!result!" == "true" ( 614 | set "purgeflag=1" 615 | set result=false 616 | shift & goto :argsparse 617 | ) 618 | 619 | if "%1" == "-q" set result=true 620 | if "%1" == "--quick" set result=true 621 | if "!result!" == "true" ( 622 | set "quickflag=1" 623 | set result=false 624 | shift & goto :argsparse 625 | ) 626 | 627 | if "%1" == "-r" set result=true 628 | if "%1" == "--restart" set result=true 629 | if "!result!" == "true" ( 630 | set "restartflag=1" 631 | set result=false 632 | shift & goto :argsparse 633 | ) 634 | 635 | if "%1" == "-s" set result=true 636 | if "%1" == "--show" set result=true 637 | if "!result!" == "true" ( 638 | set "show=1" 639 | set result=false 640 | shift & goto :argsparse 641 | ) 642 | 643 | if "%1" == "-t" set result=true 644 | if "%1" == "--test" set result=true 645 | if "!result!" == "true" ( 646 | set "testflag=1" 647 | set result=false 648 | shift & goto :argsparse 649 | ) 650 | 651 | if "%1" == "-u" set result=true 652 | if "%1" == "--update" set result=true 653 | if "!result!" == "true" ( 654 | set "updateflag=1" 655 | set result=false 656 | shift & goto :argsparse 657 | ) 658 | 659 | if "%1" == "-w" set result=true 660 | if "%1" == "--workspace" set result=true 661 | if "!result!" == "true" ( 662 | @REM validate argument 663 | call :trim param "%~2" 664 | if "!param!" == "" set result=false 665 | if "!param:~0,2!" == "--" set result=false 666 | if "!param:~0,1!" == "-" set result=false 667 | 668 | if "!result!" == "false" ( 669 | @echo [%ESC%[91m错误%ESC%[0m] 无效的参数,如果指定 "%ESC%[!warncolor!m--workspace%ESC%[0m","%ESC%[!warncolor!m!param!%ESC%[0m",则需提供有效的路径 670 | @echo. 671 | goto :usage 672 | ) 673 | 674 | call :pathconvert directory "!param!" 675 | if not exist "!directory!" ( 676 | call :makedirs success "!directory!" 677 | if "!success!" == "1" (rd "!directory!" /s /q >nul 2>nul) else (set "shouldexit=1") 678 | ) 679 | 680 | if "!shouldexit!" == "1" ( 681 | @echo [%ESC%[91m错误%ESC%[0m] 参数 "%ESC%[!warncolor!m--workspace%ESC%[0m" 指定的文件夹路径 "%ESC%[!warncolor!m!directory!%ESC%[0m" %ESC%[91m无效%ESC%[0m 682 | @echo. 683 | goto :eof 684 | ) 685 | 686 | set "dest=!directory!" 687 | set result=false 688 | shift & shift & goto :argsparse 689 | ) 690 | 691 | if "%1" == "-x" set result=true 692 | if "%1" == "--metacubexd" set result=true 693 | if "!result!" == "true" ( 694 | set "yacd=0" 695 | set "metacubexd=1" 696 | set result=false 697 | shift & goto :argsparse 698 | ) 699 | 700 | if "%1" == "-y" set result=true 701 | if "%1" == "--yacd" set result=true 702 | if "!result!" == "true" ( 703 | set "yacd=1" 704 | set "metacubexd=0" 705 | set result=false 706 | shift & goto :argsparse 707 | ) 708 | 709 | @REM will throw exception if this code not in here or delete it or merge with . why? 710 | if "%1" == "" goto :eof 711 | 712 | if "%1" NEQ "" ( 713 | call :trim syntax "%~1" 714 | if "!syntax!" == "goto" ( 715 | call :trim funcname "%~2" 716 | if "!funcname!" == "" ( 717 | @echo [%ESC%[91m错误%ESC%[0m] 无效的语法,调用 "%ESC%[!warncolor!mgoto%ESC%[0m" 时必须提供函数名 718 | goto :usage 719 | ) 720 | 721 | for /f "tokens=1-2,* delims= " %%a in ("%*") do set "params=%%c" 722 | if "!params!" == "" ( 723 | call !funcname! 724 | exit /b 725 | ) else ( 726 | call !funcname! !params! 727 | exit /b 728 | ) 729 | ) 730 | 731 | @echo [%ESC%[91m错误%ESC%[0m] 未知参数:%ESC%[91m%1%ESC%[0m 732 | @echo. 733 | goto :usage 734 | ) 735 | 736 | goto :eof 737 | 738 | 739 | @REM help 740 | :usage 741 | @echo 使用方法:!batname! [%ESC%[!warncolor!m功能选项%ESC%[0m] [%ESC%[!warncolor!m其他参数%ESC%[0m],支持 %ESC%[!warncolor!m-%ESC%[0m 和 %ESC%[!warncolor!m--%ESC%[0m 两种模式 742 | @echo. 743 | @echo 功能选项: 744 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 745 | @echo -f, --fix 检查并尝试修复代理网络 746 | @echo -h, --help 打印帮助信息 747 | @echo -i, --init 利用 %ESC%[!warncolor!m--conf%ESC%[0m 提供的配置文件创建代理网络 748 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 749 | @echo -k, --kill 退出网络代理程序 750 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 751 | if "!customize!" == "1" ( 752 | @echo -l, --love 当然是大声告诉我宝我爱她啦🤪🤪🤪 753 | ) 754 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 755 | @echo -o, --overload 重新加载配置文件 756 | @echo -p, --purge 关闭系统代理并禁止程序开机自启,取消自动更新 757 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 758 | @echo -r, --restart 重启网络代理程序 759 | @echo -t, --test 测试代理网络是否可用 760 | @echo -u, --update 更有所有组件,包括 clash.exe、订阅、代理规则以及 IP 地址数据库等 761 | echo. 762 | @echo 其他参数: 763 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 764 | @echo -a, --alpha 是否允许使用预览版,默认为稳定版,搭配 %ESC%[!warncolor!m-i%ESC%[0m 或者 %ESC%[!warncolor!m-u%ESC%[0m 使用 765 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 766 | @echo -b, --brief 精简模式运行,没有明确配置dashboard情况下,无法使用可视化页面 767 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 768 | @echo -c, --conf 配置文件,支持本地配置文件和订阅链接,默认为当前目录下的 %ESC%[!warncolor!mconfig.yaml%ESC%[0m 769 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 770 | @echo -d, --daemon 后台静默执行,禁止打印日志 771 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 772 | @echo -e, --exclude 更新时跳过代理集中配置的订阅 773 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 774 | @echo -g, --generate 重新生成自动检查更新的脚本,搭配 %ESC%[!warncolor!m-u%ESC%[0m 使用 775 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 776 | @echo -m, --meta 如果配置兼容,使用 clash.meta 代替 clash.premium,搭配 %ESC%[!warncolor!m-i%ESC%[0m 或 %ESC%[!warncolor!m-u%ESC%[0m 使用 777 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 778 | @echo -n, --native 强制使用 clash.premium,搭配 %ESC%[!warncolor!m-i%ESC%[0m 或 %ESC%[!warncolor!m-u%ESC%[0m 使用 779 | @echo -q, --quick 仅更新新订阅和代理规则,搭配 %ESC%[!warncolor!m-u%ESC%[0m 使用 780 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 781 | @echo -s, --show 新窗口中执行,默认为当前窗口 782 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 783 | @echo -w, --workspace 代理程序运行路径,默认为当前脚本所在目录 784 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 785 | @echo -x, --metacubexd 使用 %ESC%[!warncolor!mmetacubexd%ESC%[0m 控制面板,搭配 %ESC%[!warncolor!m-i%ESC%[0m 或 %ESC%[!warncolor!m-u%ESC%[0m 使用 786 | @REM @echo. if this line contains Chinese output, it will be garbled. Why? ? ? >_< 787 | @echo -y, --yacd 使用 %ESC%[!warncolor!myacd%ESC%[0m 控制面板,搭配 %ESC%[!warncolor!m-i%ESC%[0m 或 %ESC%[!warncolor!m-u%ESC%[0m 使用 788 | @echo. 789 | 790 | set "shouldexit=1" 791 | goto :eof 792 | 793 | 794 | @REM draw heart 795 | :printheart 796 | set "wthitespace=" 797 | 798 | @echo. 799 | @echo !wthitespace! ********* ********* 800 | @echo !wthitespace! ***************** ***************** 801 | @echo !wthitespace! ***************************************** 802 | @echo !wthitespace! ******************************************* 803 | @echo !wthitespace!********************************************* 804 | @echo !wthitespace!********************************************** 805 | @echo !wthitespace!********************************************** 806 | @echo !wthitespace!********************************************** 807 | if "!msterminal!" == "1" ( 808 | @echo !wthitespace!*********** %ESC%[91m我的宝,我爱你 ♥♥♥%ESC%[0m ************* 809 | ) else ( 810 | @echo !wthitespace!*********** %ESC%[91m我的宝,我爱你 ♥♥♥%ESC%[0m *************** 811 | ) 812 | 813 | @echo !wthitespace!********** *********** 814 | @echo !wthitespace! ******** %ESC%[91m因为有你,生活可爱了许多%ESC%[0m ********* 815 | @echo !wthitespace! ***************************************** 816 | @echo !wthitespace! *************************************** 817 | @echo !wthitespace! ************************************* 818 | @echo !wthitespace! *********************************** 819 | @echo !wthitespace! ********************************* 820 | @echo !wthitespace! ***************************** 821 | @echo !wthitespace! ************************* 822 | @echo !wthitespace! ********************* 823 | @echo !wthitespace! *************** 824 | @echo !wthitespace! ********* 825 | @echo !wthitespace! *** 826 | @echo !wthitespace! * 827 | @echo. 828 | exit /b 829 | goto :eof 830 | 831 | 832 | @REM confirm download url and filename according parameters 833 | :versioned 834 | set "%~1=0" 835 | set "content=" 836 | set "needgeosite=0" 837 | 838 | @REM yacd dashboard 839 | if "!metacubexd!" == "0" if "!dashboard!" NEQ "" if exist "!dashboard!\yacd.ico" ( 840 | set "yacd=1" 841 | set "metacubexd=0" 842 | ) 843 | 844 | @REM metacubexd dashboard 845 | if "!yacd!" == "0" if "!dashboard!" NEQ "" if exist "!dashboard!\maskable-icon-512x512.png" ( 846 | set "yacd=0" 847 | set "metacubexd=1" 848 | ) 849 | 850 | @REM force use clash.premium 851 | if "!clashpremium!" == "1" ( 852 | set "clashmeta=0" 853 | goto :eof 854 | ) 855 | 856 | for /f "tokens=*" %%i in ('findstr /i /r "GEOSITE,.*" "!configfile!"') do set "content=!content!;%%i" 857 | call :searchrules notfound "!content!" 858 | 859 | if "!notfound!" == "1" ( 860 | for /f "tokens=*" %%i in ('findstr /i /r "SUB-RULE,.* AND,.* OR,.* NOT,.* IN-TYPE,.*" "!configfile!"') do set "content=!content!;%%i" 861 | call :searchrules notfound "!content!" 862 | ) else ( 863 | set "needgeosite=1" 864 | ) 865 | 866 | @REM rulesets include GEOSITE, must be clash.meta 867 | if "!notfound!" == "0" (set "clashmeta=1") 868 | if "!clashmeta!" == "1" ( 869 | set "%~1=!needgeosite!" 870 | set "clashpremium=0" 871 | goto :eof 872 | ) 873 | 874 | @REM clash.meta not support SCRIPT rule 875 | set "content=" 876 | for /f "tokens=*" %%i in ('findstr /i /r "SCRIPT,.*" "!configfile!"') do set "content=!content!;%%i" 877 | call :searchrules notfound "!content!" 878 | 879 | @REM rulesets include SCRIPT, must be clash.premium 880 | if "!notfound!" == "0" ( 881 | set "clashmeta=0" 882 | set "clashpremium=1" 883 | goto :eof 884 | ) 885 | 886 | @REM include sniffer, must be clash.meta 887 | for /f "tokens=1* delims=:" %%a in ('findstr /i /r /c:"sniffer:[ ]*" "!configfile!"') do ( 888 | call :trim sniffer %%a 889 | if "!sniffer!" == "sniffer" ( 890 | set "clashmeta=1" 891 | set "clashpremium=0" 892 | goto :eof 893 | ) 894 | ) 895 | 896 | @REM proxy-groups include exclude-filter, must be clash.meta 897 | for /f "tokens=1* delims=:" %%a in ('findstr /i /r /c:"^[ ][ ]*exclude-filter:[ ][ ]*.*" "!configfile!"') do ( 898 | call :trim excludekey %%a 899 | 900 | if /i "!excludekey:~0,1!" NEQ "#" ( 901 | set "clashmeta=1" 902 | set "clashpremium=0" 903 | goto :eof 904 | ) 905 | ) 906 | 907 | @REM include vless or hysteria, must be clash.meta 908 | call :trim subfiles "%~2" 909 | 910 | set "subfiles=!configfile!,!subfiles!" 911 | set "tempfile=!temp!\clashproxies.txt" 912 | set "regex=^\s+(type:\s+(vless|hysteria)|client-fingerprint:\s+|flow:\s+xtls-).*" 913 | 914 | del /f /q "!tempfile!" >nul 2>nul 915 | for %%f in (!subfiles!) do ( 916 | if "%%f" NEQ "" if exist %%f ( 917 | call :findby "%%f" "!regex!" "!tempfile!" 1 918 | if exist "!tempfile!" ( 919 | set "clashmeta=1" 920 | set "clashpremium=0" 921 | del /f /q "!tempfile!" >nul 2>nul 922 | goto :eof 923 | ) 924 | ) 925 | ) 926 | 927 | @REM proxy-groups include filter, must be clash.meta 928 | @REM set "tempfile=!temp!\clashproxygroups.txt" 929 | @REM set "regex=^\s+type:\s+(select|url-test|fallback|load-balance|relay).*" 930 | 931 | @REM del /f /q "!tempfile!" >nul 2>nul 932 | @REM call :findby "!configfile!" "!regex!" "!tempfile!" 10 933 | @REM if exist "!tempfile!" ( 934 | @REM for /f "tokens=1* delims=:" %%a in ('findstr /i /r /c:"^[ ][ ]*filter:[ ][ ]*.*" "!tempfile!"') do ( 935 | @REM call :trim includekey %%a 936 | @REM if /i "!includekey:~0,1!" NEQ "#" ( 937 | @REM set "clashmeta=1" 938 | @REM set "clashpremium=0" 939 | @REM del /f /q "!tempfile!" >nul 2>nul 940 | @REM goto :eof 941 | @REM ) 942 | @REM ) 943 | 944 | @REM del /f /q "!tempfile!" >nul 2>nul 945 | @REM ) 946 | 947 | @REM old edittion 948 | if exist "!dest!\clash.exe" ("!dest!\clash.exe" -v | findstr /i "Meta" >nul 2>nul && ( 949 | set "clashmeta=1" 950 | set "clashpremium=0" 951 | ) 952 | ) 953 | goto :eof 954 | 955 | 956 | @REM quickly update subscriptions and rulesets 957 | :quickupdate 958 | set "%~1=0" 959 | 960 | @REM configration 961 | call :updateconfig 1 962 | 963 | @REM subscriptions 964 | if "!exclude!" == "0" call :updatesubs subfiles 1 965 | 966 | @REM rulesets 967 | call :updaterules 1 968 | 969 | @REM detect new edition 970 | set "clashedition=0" 971 | if exist "!dest!\clash.exe" ("!dest!\clash.exe" -v | findstr /i "Meta" >nul 2>nul && (set "clashedition=1")) 972 | call :versioned geositeneed !subfiles! 973 | 974 | if "!clashedition!" NEQ "!clashmeta!" ( 975 | set "%~1=1" 976 | if "!clashmeta!" == "1" ( 977 | set "oldedition=clash.premium" 978 | set "newedition=clash.meta" 979 | ) else ( 980 | set "oldedition=clash.meta" 981 | set "newedition=clash.premium" 982 | ) 983 | @echo [%ESC%[!warncolor!m提示%ESC%[0m] 配置%ESC%[91m不兼容%ESC%[0m,代理程序需从 %ESC%[!warncolor!m!oldedition!%ESC%[0m 切换至 %ESC%[!warncolor!m!newedition!%ESC%[0m 984 | goto :eof 985 | ) 986 | 987 | @REM reload 988 | if "!changed!" == "1" (goto :reload) else (goto :eof) 989 | 990 | 991 | @REM check if special rules are included 992 | :searchrules 993 | set "%~1=1" 994 | set "rulesets=%~2" 995 | 996 | for /F "tokens=1* delims=;" %%f in ("!rulesets!") do ( 997 | :: set "rule=%%f" 998 | call :trim rule "%%f" 999 | if /i "!rule:~0,1!"=="-" ( 1000 | set "%~1=0" 1001 | goto :eof 1002 | ) 1003 | 1004 | if "%%g" NEQ "" call :searchrules %~1 "%%g" 1005 | ) 1006 | goto :eof 1007 | 1008 | 1009 | @REM update subscriptions 1010 | :updatesubs 1011 | call :trim force "%~2" 1012 | if "!force!" == "" set "force=1" 1013 | 1014 | if "!force!" == "1" ( 1015 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 检查并更新订阅,仅刷新 %ESC%[!warncolor!mHTTP%ESC%[0m 类型的订阅 1016 | ) 1017 | 1018 | call :filerefresh changed "^\s+(health-check:(\s+)?|<<:\s+\*.*)$|^proxy-providers:(\s+)?$" "www.gstatic.com cp.cloudflare.com" "!force!" subfiles "proxies" 1019 | set "%~1=!subfiles!" 1020 | goto :eof 1021 | 1022 | 1023 | :splitpath 1024 | set "%~1=%~dp3" 1025 | set "%~2=%~nx3" 1026 | 1027 | if "!%~1:~-1!" == "\" set "%~1=!%~1:~0,-1!" 1028 | goto :eof 1029 | 1030 | 1031 | @REM to absolute path 1032 | :pathconvert 1033 | call :trim filepath %~2 1034 | set "%~1=" 1035 | 1036 | if "!filepath!" == "" goto :eof 1037 | 1038 | @echo "!filepath!" | findstr ":" >nul 2>nul && ( 1039 | set "%~1=!filepath!" 1040 | goto :eof 1041 | ) || ( 1042 | if "!dest!" NEQ "" (set "basedir=!dest!") else (set "basedir=%~dp0") 1043 | if "!basedir:~-1!" == "\" set "basedir=!basedir:~0,-1!" 1044 | 1045 | if "!filepath!" == "." ( 1046 | set "%~1=!basedir!" 1047 | goto :eof 1048 | ) 1049 | 1050 | set "filepath=!filepath:/=\!" 1051 | if "!filepath:~0,3!" == ".\\" ( 1052 | set "%~1=!basedir!\!filepath:~3!" 1053 | ) else if "!filepath:~0,2!" == ".\" ( 1054 | set "%~1=!basedir!\!filepath:~2!" 1055 | ) else ( 1056 | set "%~1=!basedir!\!filepath!" 1057 | ) 1058 | ) 1059 | goto :eof 1060 | 1061 | 1062 | @REM connectivity 1063 | :checkconnect 1064 | @REM running status 1065 | set "%~1=0" 1066 | call :trim output "%~2" 1067 | if "!output!" == "" set "output=1" 1068 | 1069 | call :isrunning status 1070 | if "!status!" == "0" ( 1071 | if "!output!" == "1" ( 1072 | @echo [%ESC%[!warncolor!m提示%ESC%[0m] 网络%ESC%[91m不可用%ESC%[0m,代理程序%ESC%[91m已退出%ESC%[0m 1073 | ) 1074 | 1075 | goto :eof 1076 | ) 1077 | 1078 | @REM call :systemproxy server 1079 | call :generateproxy server 1080 | 1081 | @REM detect network is available 1082 | call :isavailable status "!output!" "https://www.google.com" "!server!" 1083 | set "%~1=!status!" 1084 | goto :eof 1085 | 1086 | 1087 | @REM check network 1088 | :isavailable 1089 | set "%~1=0" 1090 | call :trim output "%~2" 1091 | call :trim url "%~3" 1092 | call :trim proxyserver "%~4" 1093 | 1094 | if "!output!" == "" set "output=1" 1095 | if "!url!" == "" set "url=https://www.google.com" 1096 | 1097 | @REM check 1098 | set "statuscode=000" 1099 | if "!proxyserver!" == "" ( 1100 | for /f %%a in ('curl --retry 3 --retry-max-time 10 -m 5 --connect-timeout 5 -L -s -o nul -w "%%{http_code}" "!url!"') do set "statuscode=%%a" 1101 | ) else ( 1102 | for /f %%a in ('curl -x !proxyserver! --retry 3 --retry-max-time 10 -m 5 --connect-timeout 5 -L -s -o nul -w "%%{http_code}" "!url!"') do set "statuscode=%%a" 1103 | ) 1104 | 1105 | if "!statuscode!" == "200" ( 1106 | set "%~1=1" 1107 | if "!output!" == "1" ( 1108 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 代理网络不存在问题,能够%ESC%[!infocolor!m正常%ESC%[0m使用 1109 | ) 1110 | ) else ( 1111 | set "%~1=0" 1112 | if "!output!" == "1" ( 1113 | call :postprocess 1114 | 1115 | @echo [%ESC%[!warncolor!m提示%ESC%[0m] 代理网络%ESC%[91m不可用%ESC%[0m,可%ESC%[!warncolor!m再次测试%ESC%[0m或使用命令 "%ESC%[!warncolor!m!batname! -o%ESC%[0m" %ESC%[!warncolor!m重载%ESC%[0m 或者 "%ESC%[!warncolor!m!batname! -r%ESC%[0m" %ESC%[!warncolor!m重启%ESC%[0m 或者 "%ESC%[!warncolor!m!batname! -f%ESC%[0m" %ESC%[!warncolor!m修复%ESC%[0m 1116 | ) 1117 | ) 1118 | goto :eof 1119 | 1120 | 1121 | @REM query proxy address 1122 | :generateproxy 1123 | set "%~1=" 1124 | 1125 | call :systemproxy server 1126 | if "!server!" NEQ "" ( 1127 | set "%~1=!server!" 1128 | goto :eof 1129 | ) 1130 | 1131 | @REM extract from config file 1132 | if exist "!configfile!" ( 1133 | call :istunenabled enabled 1134 | if "!enabled!" == "1" goto :eof 1135 | call :extractport port 1136 | if "!port!" == "" goto :eof 1137 | 1138 | set "tips=[%ESC%[!warncolor!m提示%ESC%[0m] 系统代理%ESC%[91m未配置%ESC%[0m,是否设置?(%ESC%[!warncolor!mY%ESC%[0m/%ESC%[!warncolor!mN%ESC%[0m) " 1139 | if "!msterminal!" == "1" ( 1140 | choice /t 5 /d y /n /m "!tips!" 1141 | ) else ( 1142 | set /p "=!tips!" 1156 | set "%~1=0" 1157 | call :trim directory "%~2" 1158 | if "!directory!" == "" ( 1159 | @echo [%ESC%[!warncolor!m警告%ESC%[0m] 路径为空,创建目录失败 1160 | goto :eof 1161 | ) 1162 | 1163 | if not exist "!directory!" ( 1164 | mkdir "!directory!" 1165 | if "!errorlevel!" == "0" set "%~1=1" 1166 | ) else (set "%~1=1") 1167 | goto :eof 1168 | 1169 | 1170 | @REM tun enabled 1171 | :istunenabled 1172 | set "%~1=0" 1173 | set "text=" 1174 | 1175 | @REM not work in batch but works fine in cmd, why? 1176 | @REM for /f "tokens=*" %%a in ('findstr /i /r /c:"^tun:[ ]*" "!configfile!"') do set "text=%%a" 1177 | 1178 | for /f "tokens=1* delims=:" %%a in ('findstr /i /r /c:"tun:[ ]*" "!configfile!"') do set "text=%%a" 1179 | 1180 | @REM not required 1181 | call :trim text "!text!" 1182 | if "!text!" == "tun" set "%~1=1" 1183 | goto :eof 1184 | 1185 | 1186 | @REM wintun 1187 | :downloadwintun 1188 | set "%~1=0" 1189 | 1190 | call :trim force "%~2" 1191 | if "!force!" == "" set "force=0" 1192 | 1193 | @REM has been integrated in clash.meta 1194 | if "!clashmeta!" == "1" exit /b 1195 | 1196 | @REM check if required 1197 | call :istunenabled enabled 1198 | if "!enabled!" == "0" exit /b 1199 | 1200 | if "!force!" == "0" set "checkwintun=0" 1201 | 1202 | @REM exists 1203 | if exist "!dest!\wintun.dll" if "!checkwintun!" == "0" goto :eof 1204 | 1205 | set "content=" 1206 | set "wintunurl=https://www.wintun.net" 1207 | 1208 | for /f delims^=^"^ tokens^=2 %%a in ('curl --retry 5 --retry-max-time 60 --connect-timeout 15 -s -L "!wintunurl!" ^| findstr /i /r "builds/wintun-.*.zip"') do set "content=%%a" 1209 | call :trim content !content! 1210 | 1211 | if "!content!" == "" ( 1212 | @echo [%ESC%[!warncolor!m警告%ESC%[0m] 无法获取 wintun 下载链接 1213 | goto :eof 1214 | ) 1215 | 1216 | call :get_arch arch_version 1217 | if "!arch_version!" == "386" ( 1218 | set "arch_version=x86" 1219 | ) else if "!arch_version!" == "armv7" ( 1220 | set "arch_version=arm" 1221 | ) 1222 | 1223 | set "wintunurl=!wintunurl!/!content!" 1224 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 开始下载 wintun,下载链接:"!wintunurl!" 1225 | 1226 | call :retrydownload "!wintunurl!" "!temp!\wintun.zip" 1227 | if exist "!temp!\wintun.zip" ( 1228 | @REM unzip 1229 | tar -xzf "!temp!\wintun.zip" -C !temp! >nul 2>nul 1230 | 1231 | @REM clean workspace 1232 | del /f /q "!temp!\wintun.zip" >nul 2>nul 1233 | 1234 | set "wintunfile=!temp!\wintun\bin\!arch_version!\wintun.dll" 1235 | if exist "!wintunfile!" ( 1236 | @REM compare and update 1237 | call :md5compare diff "!wintunfile!" "!dest!\wintun.dll" 1238 | if "!diff!" == "1" ( 1239 | set "%~1=1" 1240 | 1241 | @REM delete if exist 1242 | del /f /q "!dest!\wintun.dll" >nul 2>nul 1243 | move "!wintunfile!" "!dest!" >nul 2>nul 1244 | ) 1245 | ) else ( 1246 | @echo [%ESC%[!warncolor!m警告%ESC%[0m] 下载 wintun 成功,但未找到 wintun.dll 1247 | ) 1248 | ) else ( 1249 | @echo [%ESC%[!warncolor!m警告%ESC%[0m] wintun 下载失败,请确认下载链接是否正确 1250 | ) 1251 | goto :eof 1252 | 1253 | 1254 | @REM download binary file and data 1255 | :donwloadfiles 1256 | set "%~1=" 1257 | call :trim outenable "%~2" 1258 | if "!outenable!" == "" set "outenable=1" 1259 | 1260 | @REM deprecated and no longer needed, so set it to 0 1261 | set "outenable=0" 1262 | 1263 | if "!outenable!" == "1" ( 1264 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 开始下载 clash.exe、域名及 IP 地址等数据 1265 | ) 1266 | 1267 | set "dfiles=" 1268 | 1269 | @REM download clash 1270 | if "!clashurl!" NEQ "" ( 1271 | if /i "!clashurl:~0,8!" NEQ "https://" ( 1272 | @echo [%ESC%[91m错误%ESC%[0m] clash.exe 下载地址解析失败:"!clashurl!" 1273 | ) else ( 1274 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 开始下载 %ESC%[!warncolor!mclash.exe%ESC%[0m 至 %ESC%[!warncolor!m!dest!%ESC%[0m 1275 | 1276 | call :retrydownload "!clashurl!" "!temp!\clash.zip" 1277 | if exist "!temp!\clash.zip" ( 1278 | @REM unzip 1279 | tar -xzf "!temp!\clash.zip" -C !temp! >nul 2>nul 1280 | 1281 | @REM clean workspace 1282 | del /f /q "!temp!\clash.zip" 1283 | ) else ( 1284 | @echo [%ESC%[91m错误%ESC%[0m] clash.exe 下载失败,下载链接:"!clashurl!" 1285 | ) 1286 | 1287 | if exist "!temp!\!clashexe!" ( 1288 | @REM rename file 1289 | ren "!temp!\!clashexe!" clash.exe 1290 | 1291 | set "dfiles=clash.exe" 1292 | ) else ( 1293 | @echo [%ESC%[91m错误%ESC%[0m] "!temp!\!clashexe!" 不存在,下载链接:"!clashurl!" 1294 | ) 1295 | ) 1296 | ) 1297 | 1298 | @REM download Country.mmdb 1299 | if "!countryurl!" NEQ "" ( 1300 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 开始下载 %ESC%[!warncolor!m!countryfile!%ESC%[0m 至 %ESC%[!warncolor!m!dest!%ESC%[0m 1301 | 1302 | call :retrydownload "!countryurl!" "!temp!\!countryfile!" 1303 | if exist "!temp!\!countryfile!" ( 1304 | if "!dfiles!" == "" ( 1305 | set "dfiles=!countryfile!" 1306 | ) else ( 1307 | set "dfiles=!dfiles!;!countryfile!" 1308 | ) 1309 | ) else ( 1310 | @echo [%ESC%[91m错误%ESC%[0m] "!temp!\!countryfile!" 不存在,下载链接:"!countryurl!" 1311 | ) 1312 | ) 1313 | 1314 | @REM download GeoSite.dat 1315 | if "!geositeurl!" NEQ "" ( 1316 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 开始下载 %ESC%[!warncolor!m!geositefile!%ESC%[0m 至 %ESC%[!warncolor!m!dest!%ESC%[0m 1317 | 1318 | call :retrydownload "!geositeurl!" "!temp!\!geositefile!" 1319 | if exist "!temp!\!geositefile!" ( 1320 | if "!dfiles!" == "" ( 1321 | set "dfiles=!geositefile!" 1322 | ) else ( 1323 | set "dfiles=!dfiles!;!geositefile!" 1324 | ) 1325 | ) else ( 1326 | @echo [%ESC%[91m错误%ESC%[0m] "!temp!\!geositefile!" 不存在,下载链接:"!geositeurl!" 1327 | ) 1328 | ) 1329 | 1330 | @REM download GeoIP.dat 1331 | if "!geoipurl!" NEQ "" ( 1332 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 开始下载 %ESC%[!warncolor!m!geoipfile!%ESC%[0m 至 %ESC%[!warncolor!m!dest!%ESC%[0m 1333 | 1334 | call :retrydownload "!geoipurl!" "!temp!\!geoipfile!" 1335 | if exist "!temp!\!geoipfile!" ( 1336 | if "!dfiles!" == "" ( 1337 | set "dfiles=!geoipfile!" 1338 | ) else ( 1339 | set "dfiles=!dfiles!;!geoipfile!" 1340 | ) 1341 | ) else ( 1342 | @echo [%ESC%[91m错误%ESC%[0m] "!temp!\!geoipfile!" 不存在,下载链接:"!geoipurl!" 1343 | ) 1344 | ) 1345 | 1346 | set "%~1=!dfiles!" 1347 | goto :eof 1348 | 1349 | 1350 | @REM download with retry 1351 | :retrydownload 1352 | set maxretries=3 1353 | call :trim downloadurl "%~1" 1354 | call :trim savepath "%~2" 1355 | 1356 | if "!downloadurl!" == "" goto :eof 1357 | if "!savepath!" == "" goto :eof 1358 | 1359 | set /a "count=0" 1360 | 1361 | :retry 1362 | if !count! GEQ !maxretries! ( 1363 | @echo [%ESC%[91m错误%ESC%[0m] 文件 %ESC%[!warncolor!m!savepath!%ESC%[0m 下载失败,已达最大重试次数,请尝试再次执行此命令 1364 | goto :eof 1365 | ) 1366 | 1367 | curl.exe --retry 5 --retry-max-time 120 --connect-timeout 20 -s -L -C - -o "!savepath!" "!downloadurl!" 1368 | set "failflag=!errorlevel!" 1369 | if not exist "!savepath!" set "failflag=1" 1370 | 1371 | if "!failflag!" NEQ "0" ( 1372 | set /a "count+=1" 1373 | 1374 | @echo [%ESC%[!warncolor!m提示%ESC%[0m] 文件下载失败,正在进行第 %ESC%[!warncolor!m!count!%ESC%[0m 次重试,下载链接:!downloadurl! 1375 | goto :retry 1376 | ) 1377 | goto :eof 1378 | 1379 | 1380 | @REM compare 1381 | :detect 1382 | set "%~1=0" 1383 | set "filenames=%~2" 1384 | 1385 | for %%a in (!filenames!) do ( 1386 | set "fname=%%a" 1387 | 1388 | if not exist "!temp!\!fname!" ( 1389 | @echo [%ESC%[91m错误%ESC%[0m] %ESC%[!warncolor!m!fname!%ESC%[0m 下载成功,但在 "!temp!" 文件夹下未找到,请确认是否已被删除 1390 | goto :eof 1391 | ) 1392 | 1393 | if "!repair!" == "1" ( 1394 | @REM delete for triggering upgrade 1395 | del /f /q "!dest!\!fname!" >nul 2>nul 1396 | ) 1397 | 1398 | @REM found new file 1399 | if not exist "!dest!\!fname!" ( 1400 | set "%~1=1" 1401 | call :upgrade "!filenames!" 1402 | exit /b 1403 | ) 1404 | 1405 | @REM compare and update 1406 | call :md5compare diff "!temp!\!fname!" "!dest!\!fname!" 1407 | if "!diff!" == "1" ( 1408 | set "%~1=1" 1409 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 发现新版本,文件名:%ESC%[!warncolor!m!fname!%ESC%[0m 1410 | call :upgrade "!filenames!" 1411 | exit /b 1412 | ) 1413 | ) 1414 | goto :eof 1415 | 1416 | 1417 | @REM compare file with md5 1418 | :md5compare 1419 | set "%~1=0" 1420 | 1421 | call :trim source "%~2" 1422 | call :trim target "%~3" 1423 | 1424 | if not exist "!source!" if not exist "!target!" goto :eof 1425 | if not exist "!source!" goto :eof 1426 | if not exist "!target!" ( 1427 | set "%~1=1" 1428 | goto :eof 1429 | ) 1430 | 1431 | @REM source md5 1432 | set "original=" & for /F "skip=1 delims=" %%h in ('2^> nul CertUtil -hashfile "!source!" MD5') do if not defined original set "original=%%h" 1433 | @REM target md5 1434 | set "received=" & for /F "skip=1 delims=" %%h in ('2^> nul CertUtil -hashfile "!target!" MD5') do if not defined received set "received=%%h" 1435 | 1436 | if "!original!" NEQ "!received!" (set "%~1=1") 1437 | goto :eof 1438 | 1439 | 1440 | @REM update clash.exe and data 1441 | :upgrade 1442 | call :trim filenames "%~1" 1443 | if "!filenames!" == "" goto :eof 1444 | 1445 | @REM make sure the file exists 1446 | set "existfiles=" 1447 | for %%a in (!filenames!) do ( 1448 | if exist "!temp!\%%a" ( 1449 | if "!existfiles!" == "" ( 1450 | set "existfiles=%%a" 1451 | ) else ( 1452 | set "existfiles=!existfiles!;%%a" 1453 | ) 1454 | ) 1455 | ) 1456 | 1457 | @REM file missing 1458 | if "!existfiles!" == "" goto :terminate 1459 | 1460 | @REM stop clash 1461 | call :killprocesswrapper 1462 | 1463 | @REM copy file 1464 | for %%a in (!filenames!) do ( 1465 | set "fname=%%a" 1466 | 1467 | @REM delete if old file exists 1468 | if exist "!dest!\!fname!" ( 1469 | del /f /q "!dest!\!fname!" >nul 2>nul 1470 | ) 1471 | 1472 | @REM move new file to dest 1473 | move "!temp!\!fname!" "!dest!" >nul 2>nul 1474 | ) 1475 | goto :eof 1476 | 1477 | 1478 | @REM start 1479 | :startclash 1480 | call :isrunning status 1481 | 1482 | if "!status!" == "0" ( 1483 | @REM startup clash 1484 | call :executewrapper 0 1485 | ) else ( 1486 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 订阅和代理规则更新完毕,即将重新加载 1487 | goto :reload 1488 | ) 1489 | goto :eof 1490 | 1491 | 1492 | @REM privilege escalation 1493 | :privilege 1494 | set "hidewindow=0" 1495 | set "operation=%~1" 1496 | if "!operation!" == "" ( 1497 | @echo [%ESC%[91m错误%ESC%[0m] 非法操作,必须指定函数名 1498 | exit /b 1 1499 | ) 1500 | 1501 | @REM parse window parameter 1502 | call :trim param "%~2" 1503 | set "display=" & for /f "delims=0123456789" %%i in ("!param!") do set "display=%%i" 1504 | if defined display (set "hidewindow=0") else (set "hidewindow=!param!") 1505 | if "!hidewindow!" NEQ "0" set "hidewindow=1" 1506 | 1507 | cacls "%SystemDrive%\System Volume Information" >nul 2>&1 && ( 1508 | if "!hidewindow!" == "1" ( 1509 | !operation! 1510 | exit /b 1511 | ) else ( 1512 | start "" mshta vbscript:CreateObject^("Shell.Application"^).ShellExecute^("%~snx0","%~1","","runas",0^)^(window.close^)&exit /b 1513 | ) 1514 | ) || (start "" mshta vbscript:CreateObject^("Shell.Application"^).ShellExecute^("%~snx0","%~1","","runas",!hidewindow!^)^(window.close^)&exit /b) 1515 | goto :eof 1516 | 1517 | 1518 | @REM execute 1519 | :execute 1520 | call :trim cfile "%~1" 1521 | if "!cfile:~0,13!" == "goto :execute" ( 1522 | for /f "tokens=1-4 delims= " %%a in ("!cfile!") do set "cfile=%%c" 1523 | ) 1524 | 1525 | if "!cfile!" == "" ( 1526 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 配件文件路径无效,无法启动代理程序 1527 | goto :eof 1528 | ) 1529 | 1530 | @REM privilege escalation 1531 | call :nopromptrunas success 1532 | 1533 | call :splitpath filepath filename "!cfile!" 1534 | "!filepath!\clash.exe" -d "!filepath!" -f "!cfile!" 1535 | goto :eof 1536 | 1537 | 1538 | @REM ensure all plugins exist 1539 | :prepare 1540 | set "%~1=0" 1541 | 1542 | call :trim downforce "%~2" 1543 | if "!downforce!" == "" set "downforce=0" 1544 | 1545 | call :trim downloaded "%~3" 1546 | if "!downloaded!" == "" set "downloaded=0" 1547 | 1548 | @REM check and update configration 1549 | if "!downloaded!" == "0" call :updateconfig "!downforce!" 1550 | 1551 | @REM parse api server path 1552 | call :extractserver clashserver 1553 | 1554 | @REM dashboard directory name 1555 | call :extractpath dashboard 1556 | 1557 | @REM update subscriptions 1558 | if "!downloaded!" == "0" if "!exclude!" == "0" call :updatesubs subfiles "!downforce!" 1559 | 1560 | @REM confirm download url and filename 1561 | call :versioned geositeneed !subfiles! 1562 | 1563 | @REM clash.core or clash.premium is not available now 1564 | if "!clashpremium!" == "1" if not exist "!dest!\clash.exe" ( 1565 | @echo [%ESC%[91m错误%ESC%[0m] 代理程序 %ESC%[!warncolor!mclash.core%ESC%[0m 或 %ESC%[!warncolor!mclash.premium%ESC%[0m 暂时 %ESC%[91m无法使用%ESC%[0m,请选择 %ESC%[!warncolor!mclah.meta%ESC%[0m 1566 | exit /b 1 1567 | ) 1568 | 1569 | if "!clashpremium!" == "0" if "!clashmeta!" == "0" ( 1570 | set "clashmeta=1" 1571 | if exist "!dest!\clash.exe" ("!dest!\clash.exe" -v | findstr /i "Meta" >nul 2>nul || ( 1572 | set "clashpremium=1" 1573 | set "clashmeta=0" 1574 | ) 1575 | ) 1576 | ) 1577 | 1578 | @REM confirm donwload url 1579 | call :confirmurl "!downforce!" "!geositeneed!" 1580 | 1581 | @REM precleann workspace 1582 | call :cleanworkspace "!temp!" 1583 | 1584 | @REM update dashboard 1585 | if "!downloaded!" == "0" call :dashboardupdate "!downforce!" 1586 | 1587 | @REM update rulefiles 1588 | if "!downloaded!" == "0" call :updaterules "!downforce!" 1589 | 1590 | @REM wintun.dll 1591 | call :downloadwintun newwintun "!downforce!" 1592 | set "%~1=!newwintun!" 1593 | 1594 | @REM download clah.exe and geoip.data and so on 1595 | call :donwloadfiles filenames "!downforce!" 1596 | 1597 | @REM judge file changed with md5 1598 | call :detect changed "!filenames!" 1599 | if "!changed!" == "1" set "%~1=!changed!" 1600 | 1601 | goto :eof 1602 | 1603 | 1604 | @REM config autostart and auto update 1605 | :postprocess 1606 | call :privilege "goto :nopromptrunas" 0 1607 | 1608 | @REM tips 1609 | call :outputhint 1610 | 1611 | @REM allow auto start when user login 1612 | call :autostart 1613 | 1614 | @REM allow auto check update 1615 | call :autoupdate 1616 | 1617 | @REM create shortcut on desktop 1618 | call :adddesktop 1619 | goto :eof 1620 | 1621 | 1622 | @REM parse clash server path 1623 | :extractserver 1624 | set "%~1=" 1625 | call :parsevalue serverhost "external-controller:[ ][ ]*" 1626 | if "!serverhost!" NEQ "" if "!serverhost:~0,1!" == ":" set "serverhost=127.0.0.1!serverhost!" 1627 | 1628 | set "%~1=http://!serverhost!" 1629 | goto :eof 1630 | 1631 | 1632 | @REM privilege escalation 1633 | :executewrapper 1634 | call :trim shouldcheck "%~1" 1635 | if "!shouldcheck!" == "" set "shouldcheck=0" 1636 | if "!shouldcheck!" == "1" (call :prepare changed 0 0) 1637 | 1638 | @REM verify config 1639 | if not exist "!dest!\clash.exe" ( 1640 | @echo [%ESC%[91m错误%ESC%[0m] 网络代理启动%ESC%[91m失败%ESC%[0m,"%ESC%[!warncolor!m!dest!\clash.exe%ESC%[0m" 缺失 1641 | goto :eof 1642 | ) 1643 | 1644 | if not exist "!configfile!" ( 1645 | @echo [%ESC%[91m错误%ESC%[0m] 网络代理启动%ESC%[91m失败%ESC%[0m,配置文件 "%ESC%[!warncolor!m!configfile!%ESC%[0m" 不存在 1646 | goto :eof 1647 | ) 1648 | 1649 | if "!verifyconf!" == "1" ( 1650 | set "testoutput=!temp!\clashtestout.txt" 1651 | del /f /q "!testoutput!" >nul 2>nul 1652 | 1653 | @REM test config file 1654 | "!dest!\clash.exe" -d "!dest!" -t "!configfile!" > "!testoutput!" 1655 | 1656 | @REM failed 1657 | if !errorlevel! NEQ 0 ( 1658 | set "messages=" 1659 | if exist "!testoutput!" ( 1660 | for /f "tokens=1* delims==" %%a in ('findstr /i /r /c:"[ ]ERR[ ]\[config\][ ].*" "!testoutput!"') do set "messages=%%b" 1661 | del /f /q "!testoutput!" >nul 2>nul 1662 | ) 1663 | 1664 | if "!messages!" == "" set "messages=文件校验失败,%ESC%[!warncolor!mclash.exe%ESC%[0m 或配置文件 %ESC%[!warncolor!m!configfile!%ESC%[0m 存在问题" 1665 | @echo [%ESC%[91m错误%ESC%[0m] 网络代理启动%ESC%[91m失败%ESC%[0m,配置文件 "%ESC%[!warncolor!m!configfile!%ESC%[0m" 存在错误 1666 | @echo [%ESC%[91m错误%ESC%[0m] 错误信息:"!messages!" 1667 | exit /b 1 1668 | ) 1669 | 1670 | @REM delete test output 1671 | del /f /q "!testoutput!" >nul 2>nul 1672 | ) 1673 | 1674 | @REM run clash.exe with config 1675 | call :privilege "goto :execute !configfile!" !show! 1676 | 1677 | for /l %%i in (1,1,6) do ( 1678 | @REM check running status 1679 | call :isrunning status 1680 | if "!status!" == "1" ( 1681 | @REM abnormal detect 1682 | call :abnormal state 1683 | 1684 | if "!state!" == "1" ( 1685 | set "tips=[%ESC%[!warncolor!m警告%ESC%[0m] 代理进程%ESC%[91m异常%ESC%[0m,需%ESC%[91m删除并重新下载%ESC%[0m %ESC%[!warncolor!m!dest!\clash.exe%ESC%[0m,是否继续?(%ESC%[!warncolor!mY%ESC%[0m/%ESC%[!warncolor!mN%ESC%[0m) " 1686 | if "!msterminal!" == "1" ( 1687 | choice /t 5 /d y /n /m "!tips!" 1688 | ) else ( 1689 | set /p "=!tips!" nul 2>nul 1695 | 1696 | @REM download and restart 1697 | goto :restartprogram 1698 | ) else ( 1699 | @echo [%ESC%[91m错误%ESC%[0m] 代理程序启动%ESC%[91m失败%ESC%[0m,请检查代理程序 %ESC%[!warncolor!m!dest!\clash.exe%ESC%[0m 是否完好 1700 | goto :eof 1701 | ) 1702 | ) else ( 1703 | if "!dashboard!" == "" ( 1704 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 代理程序启动%ESC%[!infocolor!m成功%ESC%[0m 1705 | ) else ( 1706 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 代理程序启动%ESC%[!infocolor!m成功%ESC%[0m,可在浏览器中访问 %ESC%[!warncolor!m!clashserver!/ui%ESC%[0m 查看详细信息 1707 | ) 1708 | call :postprocess 1709 | exit /b 1710 | ) 1711 | ) else ( 1712 | @REM waiting 1713 | timeout /t 1 /nobreak >nul 2>nul 1714 | ) 1715 | ) 1716 | 1717 | @echo [%ESC%[91m错误%ESC%[0m] 代理程序启动%ESC%[91m失败%ESC%[0m,请检查配置 %ESC%[91m!configuration!%ESC%[0m 是否正确 1718 | goto :eof 1719 | 1720 | 1721 | @REM search port on config file with keyword 1722 | :searchport 1723 | set "%~1=" 1724 | set "content=" 1725 | call :trim key "%~2" 1726 | if "!key!" == "" goto :eof 1727 | 1728 | @REM search 1729 | for /f "tokens=1* delims=:" %%a in ('findstr /i /r /c:"^^!key!:[ ][ ]*[0-9][0-9]*" "!configfile!"') do set "content=%%b" 1730 | if "!content!" == "" goto :eof 1731 | 1732 | call :trim port "!content!" 1733 | if "!port!" NEQ "" set "%~1=!port!" 1734 | goto :eof 1735 | 1736 | 1737 | @REM extract proxy port 1738 | :extractport 1739 | set "%~1=7890" 1740 | set "keys=mixed-port;port;socks-port" 1741 | for %%a in (!keys!) do ( 1742 | call :searchport port "%%a" 1743 | if "!port!" NEQ "" ( 1744 | set "%~1=!port!" 1745 | exit /b 1746 | ) 1747 | ) 1748 | goto :eof 1749 | 1750 | 1751 | @REM print warning if tun is disabled 1752 | :outputhint 1753 | call :istunenabled enabled 1754 | call :systemproxy server 1755 | if "!enabled!" == "1" ( 1756 | if "!server!" NEQ "" ( 1757 | @echo [%ESC%[!warncolor!m提示%ESC%[0m] 程序正以 %ESC%[!warncolor!mtun%ESC%[0m 模式运行,系统代理设置已被禁用 1758 | call :disableproxy 1759 | ) 1760 | goto :eof 1761 | ) 1762 | 1763 | call :extractport proxyport 1764 | if "!proxyport!" == "" set "proxyport=7890" 1765 | 1766 | @REM set proxy 1767 | set "proxyserver=127.0.0.1:!proxyport!" 1768 | if "!proxyserver!" NEQ "!server!" ( 1769 | set "tips=[%ESC%[!warncolor!m提示%ESC%[0m] 系统代理%ESC%[91m未配置%ESC%[0m,是否设置?(%ESC%[!warncolor!mY%ESC%[0m/%ESC%[!warncolor!mN%ESC%[0m) " 1770 | if "!msterminal!" == "1" ( 1771 | choice /t 5 /d y /n /m "!tips!" 1772 | ) else ( 1773 | set /p "=!tips!" 网络和 Internet -^> 代理%ESC%[0m" 确认是否已设置为 "%ESC%[!warncolor!m!proxyserver!%ESC%[0m" 1781 | goto :eof 1782 | 1783 | 1784 | @REM restart program 1785 | :restartprogram 1786 | @REM check running status 1787 | call :isrunning status 1788 | if "!status!" == "1" ( 1789 | @REM kill process 1790 | call :killprocesswrapper 1791 | 1792 | @REM check running status 1793 | call :isrunning status 1794 | 1795 | if "!status!" == "1" ( 1796 | @echo [%ESC%[91m错误%ESC%[0m] 无法关闭进程,代理程序重启%ESC%[91m失败%ESC%[0m,请到%ESC%[91m任务管理中心%ESC%[0m手动退出 %ESC%[!warncolor!mclash.exe%ESC%[0m 1797 | goto :eof 1798 | ) 1799 | ) 1800 | 1801 | @REM if alpha=1 may cause clash.premiun download failure 1802 | if "!clashpremiun!" == "1" set "alpha=0" 1803 | 1804 | @REM startup 1805 | call :executewrapper 1 1806 | exit /b 1807 | 1808 | 1809 | @REM run as admin 1810 | :killprocesswrapper 1811 | call :isrunning status 1812 | if "!status!" == "0" goto :eof 1813 | 1814 | call :privilege "goto :killprocess" 0 1815 | 1816 | @REM detect 1817 | for /l %%i in (1,1,6) do ( 1818 | call :isrunning status 1819 | if "!status!" == "0" ( 1820 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 代理程序关闭%ESC%[!infocolor!m成功%ESC%[0m,可使用 "%ESC%[!warncolor!m!batname! -r%ESC%[0m" 命令重启 1821 | 1822 | @REM disable proxy 1823 | @REM call :istunenabled enabled 1824 | @REM if "!enabled!" == "0" call :disableproxy 1825 | 1826 | call :disableproxy 1827 | exit /b 1828 | ) else ( 1829 | @REM wait a moment 1830 | timeout /t 1 /nobreak >nul 2>nul 1831 | ) 1832 | ) 1833 | 1834 | @echo [%ESC%[91m错误%ESC%[0m] 代理程序关闭%ESC%[91m失败%ESC%[0m,请到%ESC%[91m任务管理中心%ESC%[0m手动退出 %ESC%[!warncolor!mclash.exe%ESC%[0m 1835 | goto :eof 1836 | 1837 | 1838 | @REM stop 1839 | :killprocess 1840 | tasklist | findstr /i "clash.exe" >nul 2>nul && taskkill /im "clash.exe" /f >nul 2>nul 1841 | set "exitcode=!errorlevel!" 1842 | 1843 | @REM no prompt 1844 | call :nopromptrunas success 1845 | 1846 | @REM detect 1847 | for /l %%i in (1,1,6) do ( 1848 | @REM detect running status 1849 | call :isrunning status 1850 | if "!status!" == "0" ( 1851 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 网络代理已关闭 1852 | goto :eof 1853 | ) else ( 1854 | @REM waiting for release 1855 | timeout /t 1 /nobreak >nul 2>nul 1856 | ) 1857 | ) 1858 | 1859 | @echo [%ESC%[91m错误%ESC%[0m] 网络代理关闭失败,请到%ESC%[91m任务管理中心%ESC%[0m手动结束 %ESC%[!warncolor!mclash.exe%ESC%[0m 进程 1860 | goto :eof 1861 | 1862 | 1863 | @REM delect running status 1864 | :isrunning 1865 | tasklist | findstr /i "clash.exe" >nul 2>nul && set "%~1=1" || set "%~1=0" 1866 | goto :eof 1867 | 1868 | 1869 | @REM check clash.exe process is normal 1870 | :abnormal 1871 | set "%~1=1" 1872 | 1873 | @REM memory usage 1874 | set "usage=" 1875 | 1876 | for /f "tokens=5 delims= " %%a in ('tasklist /nh ^|findstr /i clash.exe') do set "usage=%%a" 1877 | if "!usage!" NEQ "" ( 1878 | @REM remove comma from number 1879 | set "usage=!usage:,=!" 1880 | 1881 | if !usage! GTR 5120 (set "%~1=0") 1882 | ) 1883 | 1884 | goto :eof 1885 | 1886 | 1887 | @REM get donwload url 1888 | :confirmurl 1889 | @REM country data 1890 | call :trim force "%~1" 1891 | if "!force!" == "" set "force=0" 1892 | 1893 | @REM dashboard 1894 | if "!metacubexd!" == "1" set "yacd=0" 1895 | 1896 | call :trim geositeflag "%~2" 1897 | if "!geositeflag!" == "" set "geositeflag=0" 1898 | 1899 | set "needdownload=0" 1900 | set "countryurl=https://raw.githubusercontent.com/Hackl0us/GeoIP2-CN/release/Country.mmdb" 1901 | 1902 | @REM geosite/geoip filename 1903 | set "countryfile=Country.mmdb" 1904 | set "geositefile=GeoSite.dat" 1905 | set "geoipfile=GeoIP.dat" 1906 | 1907 | @REM dashboard url 1908 | set "dashboardurl=https://github.com/Dreamacro/clash-dashboard/archive/refs/heads/gh-pages.zip" 1909 | set "dashdirectory=clash-dashboard-gh-pages" 1910 | 1911 | set "clashurl=" 1912 | 1913 | @REM get os and cpu version 1914 | call :get_arch arch_version 1915 | if "!arch_version!" == "" ( 1916 | @echo [%ESC%[91m错误%ESC%[0m] 未知 操作系统 及 CPU 架构信息,获取 clash 下载链接失败 1917 | goto :eof 1918 | ) 1919 | 1920 | @REM determine whether to download clash.exe 1921 | if not exist "!dest!\clash.exe" (set "needdownload=1") else (set "needdownload=!force!") 1922 | 1923 | if "!clashmeta!" == "0" ( 1924 | @echo [%ESC%[!warncolor!m提示%ESC%[0m] %ESC%[!warncolor!mclash.premium%ESC%[0m 暂%ESC%[!warncolor!m不提供%ESC%[0m下载,建议切使用 %ESC%[!warncolor!m-m%ESC%[0m 或 %ESC%[!warncolor!m--meta%ESC%[0m 换到 %ESC%[!warncolor!mclash.meta%ESC%[0m 1925 | 1926 | set "clashexe=clash-windows-!arch_version!.exe" 1927 | 1928 | if "!needdownload!" == "1" ( 1929 | if "!alpha!" == "0" ( 1930 | for /f "tokens=1* delims=:" %%a in ('curl --retry 5 -s -L "https://api.github.com/repos/Dreamacro/clash/releases/tags/premium" ^| findstr /i /r /c:"https://github.com/Dreamacro/clash/releases/download/premium/clash-windows-!arch_version!-[^v][^3].*.zip"') do set "clashurl=%%b" 1931 | 1932 | @REM remove whitespace 1933 | call :trim clashurl "!clashurl!" 1934 | if !clashurl! == "" ( 1935 | @echo [%ESC%[91m错误%ESC%[0m] 获取 clash.premium 下载链接失败 1936 | goto :eof 1937 | ) 1938 | set "clashurl=!clashurl:~1,-1!" 1939 | ) else ( 1940 | @echo [%ESC%[!warncolor!m警告%ESC%[0m] %ESC%[!warncolor!mclash.premium%ESC%[0m 预览版下载链接可能%ESC%[91m无法访问%ESC%[0m,想要使用该版本请确保网络正常 1941 | set "clashurl=https://release.dreamacro.workers.dev/latest/clash-windows-!arch_version!-latest.zip" 1942 | ) 1943 | ) 1944 | 1945 | if "!yacd!" == "1" ( 1946 | set "dashboardurl=https://github.com/haishanh/yacd/archive/refs/heads/gh-pages.zip" 1947 | set "dashdirectory=yacd-gh-pages" 1948 | ) 1949 | 1950 | if "!metacubexd!" == "1" ( 1951 | set "dashboardurl=https://github.com/MetaCubeX/metacubexd/archive/refs/heads/gh-pages.zip" 1952 | set "dashdirectory=metacubexd-gh-pages" 1953 | ) 1954 | ) else ( 1955 | set "clashexe=mihomo-windows-!arch_version!.exe" 1956 | set "geositeurl=https://raw.githubusercontent.com/Loyalsoldier/domain-list-custom/release/geosite.dat" 1957 | set "geoipurl=https://raw.githubusercontent.com/Loyalsoldier/geoip/release/geoip-only-cn-private.dat" 1958 | 1959 | if "!needdownload!" == "1" ( 1960 | if "!alpha!" == "1" ( 1961 | for /f "tokens=1* delims=:" %%a in ('curl --retry 5 -s -L "https://api.github.com/repos/MetaCubeX/mihomo/releases?prerelease=true&per_page=10" ^| findstr /i /r "https://github.com/MetaCubeX/mihomo/releases/download/Prerelease-Alpha/mihomo-windows-!arch_version!-alpha-.*.zip"') do set "clashurl=%%b" 1962 | ) else ( 1963 | for /f "tokens=1* delims=:" %%a in ('curl --retry 5 -s -L "https://api.github.com/repos/MetaCubeX/mihomo/releases/latest?per_page=1" ^| findstr /i /r "https://github.com/MetaCubeX/mihomo/releases/download/.*/mihomo-windows-!arch_version!-.*.zip"') do set "clashurl=%%b" 1964 | ) 1965 | 1966 | call :trim clashurl "!clashurl!" 1967 | if !clashurl! == "" ( 1968 | if "!alpha!" == "1" (set "version=预览版") else (set "version=稳定版") 1969 | @echo [%ESC%[91m错误%ESC%[0m] 获取 clash.meta 下载链接失败,版本:"!version!" 1970 | goto :eof 1971 | ) 1972 | 1973 | set "clashurl=!clashurl:~1,-1!" 1974 | ) 1975 | 1976 | @REM geosite.data download url 1977 | if "!geositeflag!" == "0" ( 1978 | set "geositeurl=" 1979 | ) else ( 1980 | for /f "tokens=1* delims=:" %%a in ('findstr /i /r /c:"^[ ][ ]*geosite:[ ][ ]*" "!configfile!"') do ( 1981 | call :trim geositekey %%a 1982 | 1983 | @REM commented 1984 | if /i "!geositekey:~0,1!" NEQ "#" call :trim geositeurl %%b 1985 | ) 1986 | ) 1987 | 1988 | @REM geodata-mode 1989 | set "geodatamode=false" 1990 | for /f "tokens=1,2 delims=:" %%a in ('findstr /i /r /c:"^geodata-mode:[ ][ ]*" "!configfile!"') do ( 1991 | call :trim gmn %%a 1992 | 1993 | @REM commented 1994 | if /i "!gmn:~0,1!" NEQ "#" call :trim geodatamode %%b 1995 | ) 1996 | 1997 | @REM geoip.data 1998 | if "!geodatamode!" == "false" ( 1999 | set "geoipurl=" 2000 | 2001 | for /f "tokens=1* delims=:" %%a in ('findstr /i /r /c:"^[ ][ ]*mmdb:[ ][ ]*" "!configfile!"') do ( 2002 | call :trim mmdbkey %%a 2003 | 2004 | @REM commented 2005 | if /i "!mmdbkey:~0,1!" NEQ "#" call :trim countryurl %%b 2006 | ) 2007 | ) else ( 2008 | set "countryurl=" 2009 | 2010 | for /f "tokens=1* delims=:" %%a in ('findstr /i /r /c:"^[ ][ ]*geoip:[ ][ ]*http.*://" "!configfile!"') do ( 2011 | call :trim geoipkey %%a 2012 | 2013 | @REM commented 2014 | if /i "!geoipkey:~0,1!" NEQ "#" call :trim geoipurl %%b 2015 | ) 2016 | ) 2017 | 2018 | if "!yacd!" == "1" ( 2019 | set "dashboardurl=https://github.com/MetaCubeX/Yacd-meta/archive/refs/heads/gh-pages.zip" 2020 | set "dashdirectory=Yacd-meta-gh-pages" 2021 | ) else ( 2022 | set "dashboardurl=https://github.com/MetaCubeX/metacubexd/archive/refs/heads/gh-pages.zip" 2023 | set "dashdirectory=metacubexd-gh-pages" 2024 | ) 2025 | ) 2026 | 2027 | @REM clashurl 2028 | call :generateurl clashurl "!clashurl!" "clash.exe" "!force!" 2029 | 2030 | @REM dashboardurl 2031 | if "!dashboard!" == "" ( 2032 | @REM don't need dashboard 2033 | set "dashboardurl=" 2034 | ) else ( 2035 | set "needdash=!force!" 2036 | if not exist "!dashboard!\index.html" set "needdash=1" 2037 | if "!needdash!" == "0" ( 2038 | set "dashboardurl=" 2039 | ) else ( 2040 | call :ghproxywrapper dashboardurl !dashboardurl! 2041 | ) 2042 | ) 2043 | 2044 | @REM countryurl 2045 | call :generateurl countryurl "!countryurl!" "!countryfile!" "!force!" 2046 | 2047 | @REM geositeurl 2048 | call :generateurl geositeurl "!geositeurl!" "!geositefile!" "!force!" 2049 | 2050 | @REM geoipurl 2051 | call :generateurl geoipurl "!geoipurl!" "!geoipfile!" "!force!" 2052 | goto :eof 2053 | 2054 | 2055 | @REM generate real download url 2056 | :generateurl 2057 | set "%~1=" 2058 | 2059 | call :trim url "%~2" 2060 | if "!url!" == "" goto :eof 2061 | 2062 | call :trim filename "%~3" 2063 | if "!filename!" == "" goto :eof 2064 | 2065 | if not exist "!dest!\!filename!" (set "needdownload=1") else (set "needdownload=!force!") 2066 | if "!needdownload!" == "0" goto :eof 2067 | 2068 | call :ghproxywrapper downloadurl !url! 2069 | 2070 | set "%~1=!downloadurl!" 2071 | goto :eof 2072 | 2073 | 2074 | @REM get cpu and os version, see: https://github.com/MetaCubeX/mihomo/releases 2075 | :get_arch 2076 | set "%~1=" 2077 | if "!PROCESSOR_ARCHITECTURE!" == "AMD64" ( 2078 | set "%~1=amd64" 2079 | ) else if "!PROCESSOR_ARCHITECTURE!" == "ARM64" ( 2080 | set "%~1=arm64" 2081 | ) else if "!PROCESSOR_ARCHITECTURE!" == "X86" ( 2082 | set "%~1=386" 2083 | ) else (set "%~1=armv7") 2084 | 2085 | goto :eof 2086 | 2087 | 2088 | @REM leading and trailing whitespace 2089 | :trim 2090 | set "rawtext=%~2" 2091 | set "%~1=" 2092 | if "!rawtext!" == "" goto :eof 2093 | 2094 | for /f "tokens=* delims= " %%a in ("!rawtext!") do set "rawtext=%%a" 2095 | 2096 | @REM for /l %%a in (1,1,100) do if "!rawtext:~-1!"==" " set "rawtext=!rawtext:~0,-1!" 2097 | 2098 | @REM for speed, iteration set to 10 2099 | for /l %%a in (1,1,10) do if "!rawtext:~-1!"==" " set "rawtext=!rawtext:~0,-1!" 2100 | 2101 | set "%~1=!rawtext!" 2102 | goto :eof 2103 | 2104 | 2105 | @REM wrapper github 2106 | :ghproxywrapper 2107 | set "%~1=" 2108 | call :trim rawurl %~2 2109 | if "!rawurl!" == "" goto :eof 2110 | 2111 | @REM github proxy list: https://github.com/XIU2/UserScript/blob/master/GithubEnhanced-High-Speed-Download.user.js 2112 | set proxy_urls[0]=https://mirror.ghproxy.com 2113 | set proxy_urls[1]=https://github.moeyy.xyz 2114 | set proxy_urls[2]=https://gh.ddlc.top 2115 | set proxy_urls[3]=https://hub.gitmirror.com 2116 | set proxy_urls[4]=https://proxy.api.030101.xyz 2117 | 2118 | @REM random [0, 4] 2119 | set /a num=!random! %% 5 2120 | set "ghproxy=!proxy_urls[%num%]!" 2121 | 2122 | @REM github proxy 2123 | if "!rawurl:~0,18!" == "https://github.com" set "rawurl=!ghproxy!/!rawurl!" 2124 | if "!rawurl:~0,33!" == "https://raw.githubusercontent.com" set "rawurl=!ghproxy!/!rawurl!" 2125 | if "!rawurl:~0,34!" == "https://gist.githubusercontent.com" set "rawurl=!ghproxy!/!rawurl!" 2126 | 2127 | set "%~1=!rawurl!" 2128 | goto :eof 2129 | 2130 | 2131 | @REM search keywords with powershell 2132 | :findby 2133 | call :trim filepath %~1 2134 | if "!filepath!" == "" goto :eof 2135 | 2136 | set "regex=%~2" 2137 | if "!regex!" == "" goto :eof 2138 | 2139 | call :trim result %~3 2140 | if "!result!" == "" goto :eof 2141 | 2142 | call :trim context %~4 2143 | if not defined context (set "context=5") 2144 | 2145 | powershell -command "& {&'Get-Content' '!filepath!' | &'Select-String' -Pattern '!regex!' -Context !context!,!context! | &'Set-Content' -Encoding 'utf8' '!result!'}"; 2146 | goto :eof 2147 | 2148 | 2149 | @REM remove leading and trailing quotes 2150 | :removequotes 2151 | set "%~1=" 2152 | call :trim str "%~2" 2153 | if "!str!" == "" goto :eof 2154 | 2155 | if !str:~0^,1!!str:~-1! equ "" set "str=!str:~1,-1!" 2156 | if "!str:~0,1!!str:~0,1!" == "''" set "str=!str:~1!" 2157 | if "!str:~-1!!str:~-1!" == "''" set "str=!str:~0,-1!" 2158 | set "%~1=!str!" 2159 | goto :eof 2160 | 2161 | 2162 | @REM query value from yaml 2163 | :parsevalue 2164 | set "%~1=" 2165 | set "regex=%~2" 2166 | if "!regex!" == "" goto :eof 2167 | 2168 | set "key=" 2169 | set "text=" 2170 | for /f "tokens=1* delims=:" %%a in ('findstr /i /r /c:"!regex!" "!configfile!"') do ( 2171 | set "key=%%a" 2172 | set "text=%%b" 2173 | ) 2174 | 2175 | call :trim key "!key!" 2176 | if "!key!" == "" goto :eof 2177 | @REM commened 2178 | if "!key:~0,1!" == "#" goto :eof 2179 | 2180 | call :removequotes value "!text!" 2181 | set "%~1=!value!" 2182 | goto :eof 2183 | 2184 | 2185 | @REM reload config 2186 | :reload 2187 | if not exist "!configfile!" goto :eof 2188 | 2189 | @REM parse api server path 2190 | if "!clashserver!" == "" call :extractserver clashserver 2191 | 2192 | if "!clashserver!" == "" ( 2193 | @echo [%ESC%[91m错误%ESC%[0m] %ESC%[91m不支持%ESC%[0m重载,可使用 "%ESC%[!warncolor!m!batname! -r%ESC%[0m" 重启或者在文件 "%ESC%[!warncolor!m!configfile!%ESC%[0m" 配置 "%ESC%[!warncolor!mexternal-controller%ESC%[0m" 属性以启用该功能 2194 | goto :eof 2195 | ) 2196 | 2197 | set "clashapi=!clashserver!/configs?force=true" 2198 | 2199 | @REM secret 2200 | call :parsevalue secret "secret:[ ][ ]*" 2201 | 2202 | @REM running detect 2203 | call :isrunning status 2204 | 2205 | if "!status!" == "1" ( 2206 | @REM '\' to '\\' 2207 | set "filepath=!configfile:\=\\!" 2208 | 2209 | @REM call api for reload 2210 | set "statuscode=000" 2211 | set "output=!temp!\clashout.txt" 2212 | if exist "!output!" del /f /q "!output!" >nul 2>nul 2213 | 2214 | if "!secret!" NEQ "" ( 2215 | for /f %%a in ('curl --retry 3 -L -s -o "!output!" -w "%%{http_code}" -H "Content-Type: application/json" -H "Authorization: Bearer !secret!" -X PUT -d "{""path"":""!filepath!""}" "!clashapi!"') do set "statuscode=%%a" 2216 | ) else ( 2217 | for /f %%a in ('curl --retry 3 -L -s -o "!output!" -w "%%{http_code}" -H "Content-Type: application/json" -X PUT -d "{""path"":""!filepath!""}" "!clashapi!"') do set "statuscode=%%a" 2218 | ) 2219 | 2220 | if "!statuscode!" == "204" ( 2221 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 网络代理程序重载%ESC%[!infocolor!m成功%ESC%[0m,祝你使用愉快 2222 | call :postprocess 2223 | ) else if "!statuscode!" == "401" ( 2224 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] %ESC%[!warncolor!msecret%ESC%[0m 已被修改,请使用 "%ESC%[!warncolor!m!batname! -r%ESC%[0m" 重启 2225 | ) else ( 2226 | set "content=" 2227 | 2228 | if exist "!output!" ( 2229 | @REM read output 2230 | for /f "delims=" %%a in (!output!) do set "content=%%a" 2231 | ) 2232 | 2233 | @echo [%ESC%[91m错误%ESC%[0m] 网络代理程序重载%ESC%[91m失败%ESC%[0m,请检查配置文件 "%ESC%[!warncolor!m!configfile!%ESC%[0m" 是否有效 2234 | if "!content!" NEQ "" ( 2235 | @echo [%ESC%[91m错误%ESC%[0m] 错误信息:"!content!" 2236 | ) 2237 | 2238 | @echo. 2239 | ) 2240 | 2241 | @REM delete 2242 | del /f /q "!output!" >nul 2>nul 2243 | ) else ( 2244 | @echo [%ESC%[91m错误%ESC%[0m] 网络代理程序%ESC%[91m未启动%ESC%[0m,可使用命令 "%ESC%[!warncolor!m!batname! -r%ESC%[0m" 启动 2245 | ) 2246 | goto :eof 2247 | 2248 | 2249 | @REM update config 2250 | :updateconfig 2251 | call :trim force "%~1" 2252 | if "!force!" == "" set "force=1" 2253 | if exist "!configfile!" if "!force!" == "0" goto :eof 2254 | 2255 | set "downloadpath=!temp!\clashconf.yaml" 2256 | del /f /q "!downloadpath!" >nul 2>nul 2257 | 2258 | @REM extract remote config url 2259 | set "subfile=!dest!\subscriptions.txt" 2260 | set "subscription=" 2261 | 2262 | if exist "!subfile!" ( 2263 | for /f "tokens=*" %%a in ('findstr /i /r /c:"^http.*://" "!subfile!"') do set "subscription=%%a" 2264 | if "!subscription!" NEQ "" ( 2265 | call :trim subscription "!subscription!" 2266 | if "!subscription:~0,1!" NEQ "#" set "remoteurl=!subscription!" 2267 | ) 2268 | ) 2269 | 2270 | if "!enableremoteconf!" == "1" if "!remoteurl!" NEQ "" ( 2271 | curl.exe --retry 5 --retry-max-time 90 -m 120 --connect-timeout 15 -H "User-Agent: Clash" -s -L -C - "!remoteurl!" > "!downloadpath!" 2272 | if not exist "!downloadpath!" ( 2273 | @echo [%ESC%[!warncolor!m警告%ESC%[0m] 配置文件下载失败,如有需要,请重试或点击 %ESC%[!warncolor!m!remoteurl!%ESC%[0m 手动下载并替换 2274 | goto :eof 2275 | ) 2276 | 2277 | if exist "!dest!\clash.exe" ( 2278 | @REM check file 2279 | for %%a in ("!downloadpath!") do set "filesize=%%~za" 2280 | if !filesize! LSS 32 ( 2281 | del /f /q "!downloadpath!" >nul 2>nul 2282 | @echo [%ESC%[!warncolor!m警告%ESC%[0m] 配置文件下载失败,如有需要,请重试或点击 %ESC%[!warncolor!m!remoteurl!%ESC%[0m 手动下载并替换 2283 | exit /b 1 2284 | ) 2285 | 2286 | @REM test config file 2287 | "!dest!\clash.exe" -d "!dest!" -t -f "!downloadpath!" >nul 2>nul 2288 | 2289 | @REM failed 2290 | if !errorlevel! NEQ 0 ( 2291 | @echo [%ESC%[91m错误%ESC%[0m] 配置文件 %ESC%[!warncolor!m!remoteurl!%ESC%[0m 存在错误,无法更新 2292 | del /f /q "!downloadpath!" >nul 2>nul 2293 | exit /b 1 2294 | ) 2295 | ) 2296 | 2297 | @REM compare with md5 2298 | call :md5compare diff "!downloadpath!" "!configfile!" 2299 | if "!diff!" == "0" ( 2300 | del /f /q "!downloadpath!" >nul 2>nul 2301 | goto :eof 2302 | ) 2303 | 2304 | set "backupfile=config.yaml.bak" 2305 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 发现较新配置,原有文件将备份为 %ESC%[!warncolor!m!dest!\!backupfile!%ESC%[0m 2306 | 2307 | @REM backup 2308 | del /f /q "!dest!\!backupfile!" >nul 2>nul 2309 | ren "!configfile!" !backupfile! 2310 | 2311 | @REM move new configration file to dest 2312 | move "!downloadpath!" "!configfile!" >nul 2>nul 2313 | ) 2314 | goto :eof 2315 | 2316 | 2317 | @REM update rules 2318 | :updaterules 2319 | call :trim force "%~1" 2320 | if "!force!" == "" set "force=1" 2321 | 2322 | if "!force!" == "1" ( 2323 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 开始检查并更新类型为 %ESC%[!warncolor!mHTTP%ESC%[0m 的代理规则 2324 | ) 2325 | 2326 | call :filerefresh changed "^\s+behavior:\s+.*" "www.gstatic.com cp.cloudflare.com" "!force!" rulefiles "payload" 2327 | goto :eof 2328 | 2329 | 2330 | @REM refresh subsribe and rulesets 2331 | :filerefresh 2332 | set "%~1=0" 2333 | set "regex=%~2" 2334 | set "%~5=" 2335 | 2336 | call :trim filter "%~3" 2337 | if "!filter!" == "" set "filter=www.gstatic.com cp.cloudflare.com" 2338 | 2339 | call :trim check "%~6" 2340 | 2341 | call :trim force "%~4" 2342 | if "!force!" == "" set "force=1" 2343 | 2344 | if "!regex!" == "" ( 2345 | @echo [%ESC%[!warncolor!m警告%ESC%[0m] 未指定关键信息,跳过更新 2346 | goto :eof 2347 | ) 2348 | 2349 | set texturls= 2350 | set localfiles= 2351 | 2352 | if not exist "!configfile!" goto :eof 2353 | 2354 | @REM temp file 2355 | set "tempfile=!temp!\clashupdate.txt" 2356 | set "filepaths=" 2357 | 2358 | call :findby "!configfile!" "!regex!" "!tempfile!" 5 2359 | if not exist "!tempfile!" ( 2360 | if "!force!" == "0" goto :eof 2361 | 2362 | @echo [%ESC%[!warncolor!m警告%ESC%[0m] 未发现订阅或代理规则相关配置,跳过更新,文件:"!configfile!" 2363 | goto :eof 2364 | ) 2365 | 2366 | @REM urls and file path 2367 | for /f "tokens=1* delims=:" %%i in ('findstr /i /r /c:"^[ ][ ]*url:[ ][ ]*http.*://.*" !tempfile!') do ( 2368 | call :trim propertity %%i 2369 | if "!propertity:~0,1!" NEQ "#" ( 2370 | @echo "%%j" | findstr /i "!filter!" >nul 2>nul || set "texturls=!texturls!,%%j" 2371 | ) 2372 | ) 2373 | 2374 | for /f "tokens=1* delims=:" %%i in ('findstr /i /r /c:"^[ ][ ]*path:[ ][ ]*.*" !tempfile!') do ( 2375 | call :trim propertity %%i 2376 | if "!propertity:~0,1!" NEQ "#" ( 2377 | set "localfiles=!localfiles!,%%j" 2378 | ) 2379 | ) 2380 | 2381 | for %%r in (!localfiles!) do ( 2382 | @REM generate file path 2383 | call :pathconvert tfile %%r 2384 | if "!tfile!" == "" ( 2385 | @echo [%ESC%[91m错误%ESC%[0m] 配置无效,订阅或代理规则更新失败 2386 | goto :eof 2387 | ) 2388 | 2389 | set "filepaths=!filepaths!,!tfile!" 2390 | for /f "tokens=1* delims=," %%u in ("!texturls!") do ( 2391 | call :trim url %%u 2392 | set "texturls=%%v" 2393 | 2394 | if /i "!url:~0,8!"=="https://" ( 2395 | @REM ghproxy 2396 | call :ghproxywrapper url !url! 2397 | 2398 | set "needdownload=0" 2399 | if not exist "!tfile!" set "needdownload=1" 2400 | if "!force!" == "1" set "needdownload=1" 2401 | @REM should download 2402 | if "!needdownload!" == "1" ( 2403 | @REM get directory 2404 | call :splitpath filepath filename "!tfile!" 2405 | 2406 | @REM mkdir if not exists 2407 | call :makedirs success "!filepath!" 2408 | 2409 | @REM request and save 2410 | del /f /q "!temp!\!filename!" >nul 2>nul 2411 | call :retrydownload "!url!" "!temp!\!filename!" 2412 | 2413 | @REM check file size 2414 | set "filesize=0" 2415 | if exist "!temp!\!filename!" ( 2416 | for %%a in ("!temp!\!filename!") do set "filesize=%%~za" 2417 | ) 2418 | 2419 | @REM check file content 2420 | call :verify match "!temp!\!filename!" "!check!" 2421 | 2422 | if !filesize! GTR 16 if "!match!" == "1" ( 2423 | @REM delete if old file exists 2424 | del /f /q "!tfile!" >nul 2>nul 2425 | 2426 | @REM move new file to dest 2427 | move "!temp!\!filename!" "!filepath!" >nul 2>nul 2428 | 2429 | @REM changed status 2430 | set "%~1=1" 2431 | ) else ( 2432 | @echo [%ESC%[91m错误%ESC%[0m] 文件 %ESC%[!warncolor!m!filename!%ESC%[0m 下载失败,下载链接:"!url!" 2433 | ) 2434 | ) 2435 | ) 2436 | ) 2437 | ) 2438 | 2439 | set "%~5=!filepaths!" 2440 | @REM delete tempfile 2441 | if exist "!tempfile!" del /f /q "!tempfile!" >nul 2>nul 2442 | goto :eof 2443 | 2444 | 2445 | @REM extract dashboard path 2446 | :extractpath 2447 | set "%~1=" 2448 | 2449 | if not exist "!configfile!" goto :eof 2450 | 2451 | set "keyname=" 2452 | set "content=" 2453 | for /f "tokens=1,* delims=:" %%a in ('findstr /i /r /c:"external-ui:[ ][ ]*" "!configfile!"') do ( 2454 | set "keyname=%%a" 2455 | set "content=%%b" 2456 | ) 2457 | 2458 | @REM not found 'external-ui' configuration in config file 2459 | call :trim keyname "!keyname!" 2460 | 2461 | if "!keyname!" NEQ "external-ui" ( 2462 | set "flag=1" 2463 | if "!keyname!" NEQ "" set "flag=0" 2464 | if "!brief!" == "1" set "flag=0" 2465 | if "!clashserver!" == "" set "flag=0" 2466 | 2467 | if "!flag!" == "0" goto :eof 2468 | 2469 | set "tmpconfig=!configfile!.tmp" 2470 | 2471 | @REM append 'external-ui' configuration 2472 | @echo external-ui: dashboard > "!tmpconfig!" 2473 | type "!configfile!" >> "!tmpconfig!" 2474 | 2475 | @REM replace config file 2476 | del /f /q "!configfile!" >nul 2>nul 2477 | move "!tmpconfig!" "!configfile!" >nul 2>nul 2478 | 2479 | @REM reset 2480 | set "tmpconfig=" 2481 | set "content=dashboard" 2482 | ) 2483 | 2484 | call :trim content "!content!" 2485 | if "!content!" == "" goto :eof 2486 | 2487 | call :pathconvert directory "!content!" 2488 | set "%~1=!directory!" 2489 | goto :eof 2490 | 2491 | 2492 | @REM check file is validate 2493 | :verify 2494 | set "%~1=0" 2495 | call :trim candidate "%~2" 2496 | if not exist "!candidate!" goto :eof 2497 | 2498 | call :trim check "%~3" 2499 | 2500 | if "!check!" == "" ( 2501 | set "%~1=1" 2502 | goto :eof 2503 | ) 2504 | 2505 | set "text=" 2506 | for /f "tokens=1* delims=:" %%a in ('findstr /i /r /c:"!check!:[ ]*" "!candidate!"') do set "text=%%a" 2507 | 2508 | @REM not required 2509 | call :trim text "!text!" 2510 | 2511 | if "!text!" == "!check!" set "%~1=1" 2512 | goto :eof 2513 | 2514 | 2515 | @REM upgrade dashboard 2516 | :dashboardupdate 2517 | call :trim force "%~1" 2518 | if "!force!" == "" set "force=0" 2519 | 2520 | if "!dashboardurl!" == "" ( 2521 | if "!force!" == "0" goto :eof 2522 | 2523 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 控制面板%ESC%[!warncolor!m未启用%ESC%[0m,跳过更新 2524 | goto :eof 2525 | ) 2526 | 2527 | if "!dashboard!" == "" ( 2528 | @echo [%ESC%[91m错误%ESC%[0m] 无法获取控制面板保存路径 2529 | goto :eof 2530 | ) 2531 | 2532 | @REM exists 2533 | if exist "!dashboard!\index.html" if "!force!" == "0" goto :eof 2534 | call :makedirs success "!dashboard!" 2535 | 2536 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 开始下载并更新控制面板 2537 | call :retrydownload "!dashboardurl!" "!temp!\dashboard.zip" 2538 | 2539 | if not exist "!temp!\dashboard.zip" ( 2540 | @echo [%ESC%[!warncolor!m警告%ESC%[0m] 控制面板下载失败,下载链接:"!dashboardurl!" 2541 | goto :eof 2542 | ) 2543 | 2544 | @REM unzip 2545 | tar -xzf "!temp!\dashboard.zip" -C !temp! >nul 2>nul 2546 | del /f /q "!temp!\dashboard.zip" >nul 2>nul 2547 | 2548 | @REM base path and directory name 2549 | call :splitpath dashpath dashname "!dashboard!" 2550 | if "!dashpath!" == "" ( 2551 | @echo [%ESC%[91m错误%ESC%[0m] 无法获取控制面板保存路径 2552 | goto :eof 2553 | ) 2554 | 2555 | if "!dashname!" == "" ( 2556 | @echo [%ESC%[91m错误%ESC%[0m] 无法获取控制面板文件夹名 2557 | goto :eof 2558 | ) 2559 | 2560 | @REM rename 2561 | ren "!temp!\!dashdirectory!" !dashname! 2562 | 2563 | @REM replace if dashboard download success 2564 | dir /a /s /b "!temp!\!dashname!" | findstr . >nul && ( 2565 | call :replacedir "!temp!\!dashname!" "!dashboard!" 2566 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 控制面板已更新至最新版本 2567 | ) || ( 2568 | @echo [%ESC%[!warncolor!m警告%ESC%[0m] 控制面板下载失败,下载链接:"!dashboardurl!" 2569 | ) 2570 | goto :eof 2571 | 2572 | 2573 | @REM overwrite files 2574 | :replacedir 2575 | set "src=%~1" 2576 | set "target=%~2" 2577 | 2578 | if "!src!" == "" ( 2579 | @echo [%ESC%[!warncolor!m警告%ESC%[0m] 移动失败,源文件夹路径为空 2580 | goto :eof 2581 | ) 2582 | 2583 | if "!target!" == "" ( 2584 | @echo [%ESC%[!warncolor!m警告%ESC%[0m] 移动失败,目标路径为空 2585 | goto :eof 2586 | ) 2587 | 2588 | if not exist "!src!" ( 2589 | @echo [%ESC%[91m错误%ESC%[0m] 文件夹移动失败,源文件夹不存在:"!src!" 2590 | goto :eof 2591 | ) 2592 | 2593 | @REM delete old folder if exists 2594 | if exist "!target!" rd "!target!" /s /q >nul 2>nul 2595 | 2596 | @REM copy to dest 2597 | xcopy "!src!" "!target!" /h /e /y /q /i >nul 2>nul 2598 | 2599 | @REM delete source dashboard 2600 | rd "!src!" /s /q >nul 2>nul 2601 | goto :eof 2602 | 2603 | 2604 | @REM delete if file exists 2605 | :cleanworkspace 2606 | set "directory=%~1" 2607 | if "!directory!" == "" set "directory=!temp!" 2608 | 2609 | if exist "!directory!\clash.zip" del /f /q "!directory!\clash.zip" >nul 2610 | if exist "!directory!\clash.exe" del /f /q "!directory!\clash.exe" >nul 2611 | 2612 | @REM wintun 2613 | if exist "!directory!\wintun.zip" del /f /q "!directory!\wintun.zip" 2614 | if exist "!directory!\wintun" rd "!directory!\wintun" /s /q >nul 2>nul 2615 | 2616 | if "!clashexe!" NEQ "" ( 2617 | if exist "!directory!\!clashexe!" del /f /q "!directory!\!clashexe!" >nul 2618 | ) 2619 | 2620 | if "!countryfile!" NEQ "" ( 2621 | if exist "!directory!\!countryfile!" del /f /q "!directory!\!countryfile!" >nul 2622 | ) 2623 | 2624 | if "!geositefile!" NEQ "" ( 2625 | if exist "!directory!\!geositefile!" del /f /q "!directory!\!geositefile!" >nul 2626 | ) 2627 | 2628 | if "!geoipfile!" NEQ "" ( 2629 | if exist "!directory!\!geoipfile!" del /f /q "!directory!\!geoipfile!" >nul 2630 | ) 2631 | 2632 | @REM delete directory 2633 | if "!dashdirectory!" NEQ "" ( 2634 | if exist "!directory!\!dashdirectory!" rd "!directory!\!dashdirectory!" /s /q >nul 2635 | ) 2636 | 2637 | if "!dashboard!" == "" goto :eof 2638 | if exist "!directory!\!dashboard!.zip" del /f /q "!directory!\!dashboard!.zip" >nul 2639 | if exist "!directory!\!dashboard!" rd "!directory!\!dashboard!" /s /q >nul 2>nul 2640 | goto :eof 2641 | 2642 | 2643 | @REM replace '\\' to '\' for directory 2644 | :pathregular 2645 | set "%~1=" 2646 | call :trim directory "%~2" 2647 | 2648 | if "!directory!" == "" goto :eof 2649 | 2650 | @REM '\\' to '\' 2651 | set "directory=!directory:\\=\!" 2652 | 2653 | @REM '/' to '\' 2654 | set "directory=!directory:/=\!" 2655 | 2656 | @REM remove last '\' 2657 | if "!directory:~-1!" == "\" set "directory=!directory:~0,-1!" 2658 | set "%~1=!directory!" 2659 | goto :eof 2660 | 2661 | 2662 | @REM define exit function 2663 | :terminate 2664 | @echo [%ESC%[91m错误%ESC%[0m] 更新失败,代理程序、域名及 IP 地址数据库或控制面板缺失 2665 | call :cleanworkspace "!temp!" 2666 | exit /b 1 2667 | goto :eof 2668 | 2669 | 2670 | @REM close 2671 | :closeproxy 2672 | call :isrunning status 2673 | if "!status!" == "0" ( 2674 | @echo [%ESC%[!infocolor!m信息%ESC%[0m] 网络代理程序%ESC%[!warncolor!m未运行%ESC%[0m,无须关闭 2675 | goto :eof 2676 | ) 2677 | 2678 | set "tips=[%ESC%[!warncolor!m警告%ESC%[0m] 此操作将会关闭代理网络,是否继续?(%ESC%[!warncolor!mY%ESC%[0m/%ESC%[!warncolor!mN%ESC%[0m) " 2679 | if "!msterminal!" == "1" ( 2680 | choice /t 6 /d y /n /m "!tips!" 2681 | ) else ( 2682 | set /p "=!tips!" 2700 | call :trim server "%~1" 2701 | if "!server!" == "" goto :eof 2702 | 2703 | reg add "!proxyregpath!" /v ProxyEnable /t REG_DWORD /d 1 /f >nul 2>nul 2704 | reg add "!proxyregpath!" /v ProxyServer /t REG_SZ /d "!server!" /f >nul 2>nul 2705 | reg add "!proxyregpath!" /v ProxyOverride /t REG_SZ /d "" /f >nul 2>nul 2706 | goto :eof 2707 | 2708 | 2709 | @REM cancel proxy 2710 | :disableproxy 2711 | reg add "!proxyregpath!" /v ProxyServer /t REG_SZ /d "" /f >nul 2>nul 2712 | reg add "!proxyregpath!" /v ProxyEnable /t REG_DWORD /d 0 /f >nul 2>nul 2713 | reg add "!proxyregpath!" /v ProxyOverride /t REG_SZ /d "" /f >nul 2>nul 2714 | goto :eof 2715 | 2716 | 2717 | @REM query proxy status 2718 | :systemproxy 2719 | set "%~1=" 2720 | 2721 | @REM enabled 2722 | call :regquery enable "!proxyregpath!" "ProxyEnable" "REG_DWORD" 2723 | if "!enable!" NEQ "0x1" goto :eof 2724 | 2725 | @REM proxy server 2726 | call :regquery server "!proxyregpath!" "ProxyServer" "REG_SZ" 2727 | if "!server!" NEQ "" set "%~1=!server!" 2728 | goto :eof 2729 | 2730 | 2731 | @REM auto start when user login 2732 | :autostart 2733 | call :regquery exename "!autostartregpath!" "Clash" "REG_SZ" 2734 | if "!startupvbs!" NEQ "!exename!" ( 2735 | set "tips=[%ESC%[!warncolor!m提示%ESC%[0m] 是否允许网络代理程序开机自启?(%ESC%[!warncolor!mY%ESC%[0m/%ESC%[!warncolor!mN%ESC%[0m) " 2736 | if "!msterminal!" == "1" ( 2737 | choice /t 5 /d y /n /m "!tips!" 2738 | ) else ( 2739 | set /p "=!tips!" 2763 | set "%~1=0" 2764 | call :regquery exename "!autostartregpath!" "Clash" "REG_SZ" 2765 | 2766 | if "!exename!" == "" ( 2767 | set "%~1=1" 2768 | ) else ( 2769 | set "shoulddelete=1" 2770 | if "!startupvbs!" NEQ "!exename!" ( 2771 | set "tips=[%ESC%[!warncolor!m警告%ESC%[0m] 发现相同名字但执行路径不同的配置,是否继续?(%ESC%[!warncolor!mY%ESC%[0m/%ESC%[!warncolor!mN%ESC%[0m) " 2772 | if "!msterminal!" == "1" ( 2773 | choice /t 5 /d n /n /m "!tips!" 2774 | ) else ( 2775 | set /p "=!tips!" nul 2>nul 2782 | if "!errorlevel!" == "0" set "%~1=1" 2783 | 2784 | @REM disable 2785 | reg delete "!startupapproved!" /v "Clash" /f >nul 2>nul 2786 | ) 2787 | ) 2788 | goto :eof 2789 | 2790 | 2791 | @REM add scheduled tasks 2792 | :autoupdate 2793 | call :trim refresh "%~1" 2794 | if "!refresh!" == "" set "refresh=0" 2795 | set "taskname=ClashUpdater" 2796 | 2797 | call :taskstatus ready "!taskname!" 2798 | if "!refresh!" == "1" set "ready=0" 2799 | 2800 | if "!ready!" == "0" ( 2801 | set "tips=[%ESC%[!warncolor!m提示%ESC%[0m] 是否设置自动检查更新代理应用及规则?(%ESC%[!warncolor!mY%ESC%[0m/%ESC%[!warncolor!mN%ESC%[0m) " 2802 | if "!msterminal!" == "1" ( 2803 | choice /t 5 /d n /n /m "!tips!" 2804 | ) else ( 2805 | set /p "=!tips!" 2844 | set "%~1=0" 2845 | call :trim exename "%~2" 2846 | if "!exename!" == "" goto :eof 2847 | 2848 | call :trim taskname "%~3" 2849 | if "!taskname!" == "" goto :eof 2850 | 2851 | @REM input start time 2852 | call :scheduletime starttime 2853 | 2854 | @REM create 2855 | schtasks /create /tn "!taskname!" /tr "!exename!" /sc daily /mo 1 /ri 480 /st !starttime! /du 0012:00 /f >nul 2>nul 2856 | if "!errorlevel!" == "0" set "%~1=1" 2857 | goto :eof 2858 | 2859 | 2860 | @REM prompt user input task start time 2861 | :scheduletime