├── 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