├── .gitignore
├── LICENSE
├── README.md
├── README.pdf
├── database
└── robot.db
├── images
├── feizhai.jpg
└── ybb.jpg
├── main.js
├── mirai
├── mcl-installer-1.0.1-linux-amd64
├── mcl-installer-1.0.1-windows-amd64.exe
└── mirai-api-http-v1.9.8.mirai.jar
├── package-lock.json
├── package.json
├── scripts
├── middleWare.js
├── repair.js
├── spider.js
└── sql.js
└── test.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
131 |
132 | /node_modules
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 | Version 3, 19 November 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 Affero General Public License is a free, copyleft license for
11 | software and other kinds of works, specifically designed to ensure
12 | cooperation with the community in the case of network server software.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | our General Public Licenses are intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users.
19 |
20 | When we speak of free software, we are referring to freedom, not
21 | price. Our General Public Licenses are designed to make sure that you
22 | have the freedom to distribute copies of free software (and charge for
23 | them if you wish), that you receive source code or can get it if you
24 | want it, that you can change the software or use pieces of it in new
25 | free programs, and that you know you can do these things.
26 |
27 | Developers that use our General Public Licenses protect your rights
28 | with two steps: (1) assert copyright on the software, and (2) offer
29 | you this License which gives you legal permission to copy, distribute
30 | and/or modify the software.
31 |
32 | A secondary benefit of defending all users' freedom is that
33 | improvements made in alternate versions of the program, if they
34 | receive widespread use, become available for other developers to
35 | incorporate. Many developers of free software are heartened and
36 | encouraged by the resulting cooperation. However, in the case of
37 | software used on network servers, this result may fail to come about.
38 | The GNU General Public License permits making a modified version and
39 | letting the public access it on a server without ever releasing its
40 | source code to the public.
41 |
42 | The GNU Affero General Public License is designed specifically to
43 | ensure that, in such cases, the modified source code becomes available
44 | to the community. It requires the operator of a network server to
45 | provide the source code of the modified version running there to the
46 | users of that server. Therefore, public use of a modified version, on
47 | a publicly accessible server, gives the public access to the source
48 | code of the modified version.
49 |
50 | An older license, called the Affero General Public License and
51 | published by Affero, was designed to accomplish similar goals. This is
52 | a different license, not a version of the Affero GPL, but Affero has
53 | released a new version of the Affero GPL which permits relicensing under
54 | this license.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | TERMS AND CONDITIONS
60 |
61 | 0. Definitions.
62 |
63 | "This License" refers to version 3 of the GNU Affero General Public License.
64 |
65 | "Copyright" also means copyright-like laws that apply to other kinds of
66 | works, such as semiconductor masks.
67 |
68 | "The Program" refers to any copyrightable work licensed under this
69 | License. Each licensee is addressed as "you". "Licensees" and
70 | "recipients" may be individuals or organizations.
71 |
72 | To "modify" a work means to copy from or adapt all or part of the work
73 | in a fashion requiring copyright permission, other than the making of an
74 | exact copy. The resulting work is called a "modified version" of the
75 | earlier work or a work "based on" the earlier work.
76 |
77 | A "covered work" means either the unmodified Program or a work based
78 | on the Program.
79 |
80 | To "propagate" a work means to do anything with it that, without
81 | permission, would make you directly or secondarily liable for
82 | infringement under applicable copyright law, except executing it on a
83 | computer or modifying a private copy. Propagation includes copying,
84 | distribution (with or without modification), making available to the
85 | public, and in some countries other activities as well.
86 |
87 | To "convey" a work means any kind of propagation that enables other
88 | parties to make or receive copies. Mere interaction with a user through
89 | a computer network, with no transfer of a copy, is not conveying.
90 |
91 | An interactive user interface displays "Appropriate Legal Notices"
92 | to the extent that it includes a convenient and prominently visible
93 | feature that (1) displays an appropriate copyright notice, and (2)
94 | tells the user that there is no warranty for the work (except to the
95 | extent that warranties are provided), that licensees may convey the
96 | work under this License, and how to view a copy of this License. If
97 | the interface presents a list of user commands or options, such as a
98 | menu, a prominent item in the list meets this criterion.
99 |
100 | 1. Source Code.
101 |
102 | The "source code" for a work means the preferred form of the work
103 | for making modifications to it. "Object code" means any non-source
104 | form of a work.
105 |
106 | A "Standard Interface" means an interface that either is an official
107 | standard defined by a recognized standards body, or, in the case of
108 | interfaces specified for a particular programming language, one that
109 | is widely used among developers working in that language.
110 |
111 | The "System Libraries" of an executable work include anything, other
112 | than the work as a whole, that (a) is included in the normal form of
113 | packaging a Major Component, but which is not part of that Major
114 | Component, and (b) serves only to enable use of the work with that
115 | Major Component, or to implement a Standard Interface for which an
116 | implementation is available to the public in source code form. A
117 | "Major Component", in this context, means a major essential component
118 | (kernel, window system, and so on) of the specific operating system
119 | (if any) on which the executable work runs, or a compiler used to
120 | produce the work, or an object code interpreter used to run it.
121 |
122 | The "Corresponding Source" for a work in object code form means all
123 | the source code needed to generate, install, and (for an executable
124 | work) run the object code and to modify the work, including scripts to
125 | control those activities. However, it does not include the work's
126 | System Libraries, or general-purpose tools or generally available free
127 | programs which are used unmodified in performing those activities but
128 | which are not part of the work. For example, Corresponding Source
129 | includes interface definition files associated with source files for
130 | the work, and the source code for shared libraries and dynamically
131 | linked subprograms that the work is specifically designed to require,
132 | such as by intimate data communication or control flow between those
133 | subprograms and other parts of the work.
134 |
135 | The Corresponding Source need not include anything that users
136 | can regenerate automatically from other parts of the Corresponding
137 | Source.
138 |
139 | The Corresponding Source for a work in source code form is that
140 | same work.
141 |
142 | 2. Basic Permissions.
143 |
144 | All rights granted under this License are granted for the term of
145 | copyright on the Program, and are irrevocable provided the stated
146 | conditions are met. This License explicitly affirms your unlimited
147 | permission to run the unmodified Program. The output from running a
148 | covered work is covered by this License only if the output, given its
149 | content, constitutes a covered work. This License acknowledges your
150 | rights of fair use or other equivalent, as provided by copyright law.
151 |
152 | You may make, run and propagate covered works that you do not
153 | convey, without conditions so long as your license otherwise remains
154 | in force. You may convey covered works to others for the sole purpose
155 | of having them make modifications exclusively for you, or provide you
156 | with facilities for running those works, provided that you comply with
157 | the terms of this License in conveying all material for which you do
158 | not control copyright. Those thus making or running the covered works
159 | for you must do so exclusively on your behalf, under your direction
160 | and control, on terms that prohibit them from making any copies of
161 | your copyrighted material outside their relationship with you.
162 |
163 | Conveying under any other circumstances is permitted solely under
164 | the conditions stated below. Sublicensing is not allowed; section 10
165 | makes it unnecessary.
166 |
167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168 |
169 | No covered work shall be deemed part of an effective technological
170 | measure under any applicable law fulfilling obligations under article
171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
172 | similar laws prohibiting or restricting circumvention of such
173 | measures.
174 |
175 | When you convey a covered work, you waive any legal power to forbid
176 | circumvention of technological measures to the extent such circumvention
177 | is effected by exercising rights under this License with respect to
178 | the covered work, and you disclaim any intention to limit operation or
179 | modification of the work as a means of enforcing, against the work's
180 | users, your or third parties' legal rights to forbid circumvention of
181 | technological measures.
182 |
183 | 4. Conveying Verbatim Copies.
184 |
185 | You may convey verbatim copies of the Program's source code as you
186 | receive it, in any medium, provided that you conspicuously and
187 | appropriately publish on each copy an appropriate copyright notice;
188 | keep intact all notices stating that this License and any
189 | non-permissive terms added in accord with section 7 apply to the code;
190 | keep intact all notices of the absence of any warranty; and give all
191 | recipients a copy of this License along with the Program.
192 |
193 | You may charge any price or no price for each copy that you convey,
194 | and you may offer support or warranty protection for a fee.
195 |
196 | 5. Conveying Modified Source Versions.
197 |
198 | You may convey a work based on the Program, or the modifications to
199 | produce it from the Program, in the form of source code under the
200 | terms of section 4, provided that you also meet all of these conditions:
201 |
202 | a) The work must carry prominent notices stating that you modified
203 | it, and giving a relevant date.
204 |
205 | b) The work must carry prominent notices stating that it is
206 | released under this License and any conditions added under section
207 | 7. This requirement modifies the requirement in section 4 to
208 | "keep intact all notices".
209 |
210 | c) You must license the entire work, as a whole, under this
211 | License to anyone who comes into possession of a copy. This
212 | License will therefore apply, along with any applicable section 7
213 | additional terms, to the whole of the work, and all its parts,
214 | regardless of how they are packaged. This License gives no
215 | permission to license the work in any other way, but it does not
216 | invalidate such permission if you have separately received it.
217 |
218 | d) If the work has interactive user interfaces, each must display
219 | Appropriate Legal Notices; however, if the Program has interactive
220 | interfaces that do not display Appropriate Legal Notices, your
221 | work need not make them do so.
222 |
223 | A compilation of a covered work with other separate and independent
224 | works, which are not by their nature extensions of the covered work,
225 | and which are not combined with it such as to form a larger program,
226 | in or on a volume of a storage or distribution medium, is called an
227 | "aggregate" if the compilation and its resulting copyright are not
228 | used to limit the access or legal rights of the compilation's users
229 | beyond what the individual works permit. Inclusion of a covered work
230 | in an aggregate does not cause this License to apply to the other
231 | parts of the aggregate.
232 |
233 | 6. Conveying Non-Source Forms.
234 |
235 | You may convey a covered work in object code form under the terms
236 | of sections 4 and 5, provided that you also convey the
237 | machine-readable Corresponding Source under the terms of this License,
238 | in one of these ways:
239 |
240 | a) Convey the object code in, or embodied in, a physical product
241 | (including a physical distribution medium), accompanied by the
242 | Corresponding Source fixed on a durable physical medium
243 | customarily used for software interchange.
244 |
245 | b) Convey the object code in, or embodied in, a physical product
246 | (including a physical distribution medium), accompanied by a
247 | written offer, valid for at least three years and valid for as
248 | long as you offer spare parts or customer support for that product
249 | model, to give anyone who possesses the object code either (1) a
250 | copy of the Corresponding Source for all the software in the
251 | product that is covered by this License, on a durable physical
252 | medium customarily used for software interchange, for a price no
253 | more than your reasonable cost of physically performing this
254 | conveying of source, or (2) access to copy the
255 | Corresponding Source from a network server at no charge.
256 |
257 | c) Convey individual copies of the object code with a copy of the
258 | written offer to provide the Corresponding Source. This
259 | alternative is allowed only occasionally and noncommercially, and
260 | only if you received the object code with such an offer, in accord
261 | with subsection 6b.
262 |
263 | d) Convey the object code by offering access from a designated
264 | place (gratis or for a charge), and offer equivalent access to the
265 | Corresponding Source in the same way through the same place at no
266 | further charge. You need not require recipients to copy the
267 | Corresponding Source along with the object code. If the place to
268 | copy the object code is a network server, the Corresponding Source
269 | may be on a different server (operated by you or a third party)
270 | that supports equivalent copying facilities, provided you maintain
271 | clear directions next to the object code saying where to find the
272 | Corresponding Source. Regardless of what server hosts the
273 | Corresponding Source, you remain obligated to ensure that it is
274 | available for as long as needed to satisfy these requirements.
275 |
276 | e) Convey the object code using peer-to-peer transmission, provided
277 | you inform other peers where the object code and Corresponding
278 | Source of the work are being offered to the general public at no
279 | charge under subsection 6d.
280 |
281 | A separable portion of the object code, whose source code is excluded
282 | from the Corresponding Source as a System Library, need not be
283 | included in conveying the object code work.
284 |
285 | A "User Product" is either (1) a "consumer product", which means any
286 | tangible personal property which is normally used for personal, family,
287 | or household purposes, or (2) anything designed or sold for incorporation
288 | into a dwelling. In determining whether a product is a consumer product,
289 | doubtful cases shall be resolved in favor of coverage. For a particular
290 | product received by a particular user, "normally used" refers to a
291 | typical or common use of that class of product, regardless of the status
292 | of the particular user or of the way in which the particular user
293 | actually uses, or expects or is expected to use, the product. A product
294 | is a consumer product regardless of whether the product has substantial
295 | commercial, industrial or non-consumer uses, unless such uses represent
296 | the only significant mode of use of the product.
297 |
298 | "Installation Information" for a User Product means any methods,
299 | procedures, authorization keys, or other information required to install
300 | and execute modified versions of a covered work in that User Product from
301 | a modified version of its Corresponding Source. The information must
302 | suffice to ensure that the continued functioning of the modified object
303 | code is in no case prevented or interfered with solely because
304 | modification has been made.
305 |
306 | If you convey an object code work under this section in, or with, or
307 | specifically for use in, a User Product, and the conveying occurs as
308 | part of a transaction in which the right of possession and use of the
309 | User Product is transferred to the recipient in perpetuity or for a
310 | fixed term (regardless of how the transaction is characterized), the
311 | Corresponding Source conveyed under this section must be accompanied
312 | by the Installation Information. But this requirement does not apply
313 | if neither you nor any third party retains the ability to install
314 | modified object code on the User Product (for example, the work has
315 | been installed in ROM).
316 |
317 | The requirement to provide Installation Information does not include a
318 | requirement to continue to provide support service, warranty, or updates
319 | for a work that has been modified or installed by the recipient, or for
320 | the User Product in which it has been modified or installed. Access to a
321 | network may be denied when the modification itself materially and
322 | adversely affects the operation of the network or violates the rules and
323 | protocols for communication across the network.
324 |
325 | Corresponding Source conveyed, and Installation Information provided,
326 | in accord with this section must be in a format that is publicly
327 | documented (and with an implementation available to the public in
328 | source code form), and must require no special password or key for
329 | unpacking, reading or copying.
330 |
331 | 7. Additional Terms.
332 |
333 | "Additional permissions" are terms that supplement the terms of this
334 | License by making exceptions from one or more of its conditions.
335 | Additional permissions that are applicable to the entire Program shall
336 | be treated as though they were included in this License, to the extent
337 | that they are valid under applicable law. If additional permissions
338 | apply only to part of the Program, that part may be used separately
339 | under those permissions, but the entire Program remains governed by
340 | this License without regard to the additional permissions.
341 |
342 | When you convey a copy of a covered work, you may at your option
343 | remove any additional permissions from that copy, or from any part of
344 | it. (Additional permissions may be written to require their own
345 | removal in certain cases when you modify the work.) You may place
346 | additional permissions on material, added by you to a covered work,
347 | for which you have or can give appropriate copyright permission.
348 |
349 | Notwithstanding any other provision of this License, for material you
350 | add to a covered work, you may (if authorized by the copyright holders of
351 | that material) supplement the terms of this License with terms:
352 |
353 | a) Disclaiming warranty or limiting liability differently from the
354 | terms of sections 15 and 16 of this License; or
355 |
356 | b) Requiring preservation of specified reasonable legal notices or
357 | author attributions in that material or in the Appropriate Legal
358 | Notices displayed by works containing it; or
359 |
360 | c) Prohibiting misrepresentation of the origin of that material, or
361 | requiring that modified versions of such material be marked in
362 | reasonable ways as different from the original version; or
363 |
364 | d) Limiting the use for publicity purposes of names of licensors or
365 | authors of the material; or
366 |
367 | e) Declining to grant rights under trademark law for use of some
368 | trade names, trademarks, or service marks; or
369 |
370 | f) Requiring indemnification of licensors and authors of that
371 | material by anyone who conveys the material (or modified versions of
372 | it) with contractual assumptions of liability to the recipient, for
373 | any liability that these contractual assumptions directly impose on
374 | those licensors and authors.
375 |
376 | All other non-permissive additional terms are considered "further
377 | restrictions" within the meaning of section 10. If the Program as you
378 | received it, or any part of it, contains a notice stating that it is
379 | governed by this License along with a term that is a further
380 | restriction, you may remove that term. If a license document contains
381 | a further restriction but permits relicensing or conveying under this
382 | License, you may add to a covered work material governed by the terms
383 | of that license document, provided that the further restriction does
384 | not survive such relicensing or conveying.
385 |
386 | If you add terms to a covered work in accord with this section, you
387 | must place, in the relevant source files, a statement of the
388 | additional terms that apply to those files, or a notice indicating
389 | where to find the applicable terms.
390 |
391 | Additional terms, permissive or non-permissive, may be stated in the
392 | form of a separately written license, or stated as exceptions;
393 | the above requirements apply either way.
394 |
395 | 8. Termination.
396 |
397 | You may not propagate or modify a covered work except as expressly
398 | provided under this License. Any attempt otherwise to propagate or
399 | modify it is void, and will automatically terminate your rights under
400 | this License (including any patent licenses granted under the third
401 | paragraph of section 11).
402 |
403 | However, if you cease all violation of this License, then your
404 | license from a particular copyright holder is reinstated (a)
405 | provisionally, unless and until the copyright holder explicitly and
406 | finally terminates your license, and (b) permanently, if the copyright
407 | holder fails to notify you of the violation by some reasonable means
408 | prior to 60 days after the cessation.
409 |
410 | Moreover, your license from a particular copyright holder is
411 | reinstated permanently if the copyright holder notifies you of the
412 | violation by some reasonable means, this is the first time you have
413 | received notice of violation of this License (for any work) from that
414 | copyright holder, and you cure the violation prior to 30 days after
415 | your receipt of the notice.
416 |
417 | Termination of your rights under this section does not terminate the
418 | licenses of parties who have received copies or rights from you under
419 | this License. If your rights have been terminated and not permanently
420 | reinstated, you do not qualify to receive new licenses for the same
421 | material under section 10.
422 |
423 | 9. Acceptance Not Required for Having Copies.
424 |
425 | You are not required to accept this License in order to receive or
426 | run a copy of the Program. Ancillary propagation of a covered work
427 | occurring solely as a consequence of using peer-to-peer transmission
428 | to receive a copy likewise does not require acceptance. However,
429 | nothing other than this License grants you permission to propagate or
430 | modify any covered work. These actions infringe copyright if you do
431 | not accept this License. Therefore, by modifying or propagating a
432 | covered work, you indicate your acceptance of this License to do so.
433 |
434 | 10. Automatic Licensing of Downstream Recipients.
435 |
436 | Each time you convey a covered work, the recipient automatically
437 | receives a license from the original licensors, to run, modify and
438 | propagate that work, subject to this License. You are not responsible
439 | for enforcing compliance by third parties with this License.
440 |
441 | An "entity transaction" is a transaction transferring control of an
442 | organization, or substantially all assets of one, or subdividing an
443 | organization, or merging organizations. If propagation of a covered
444 | work results from an entity transaction, each party to that
445 | transaction who receives a copy of the work also receives whatever
446 | licenses to the work the party's predecessor in interest had or could
447 | give under the previous paragraph, plus a right to possession of the
448 | Corresponding Source of the work from the predecessor in interest, if
449 | the predecessor has it or can get it with reasonable efforts.
450 |
451 | You may not impose any further restrictions on the exercise of the
452 | rights granted or affirmed under this License. For example, you may
453 | not impose a license fee, royalty, or other charge for exercise of
454 | rights granted under this License, and you may not initiate litigation
455 | (including a cross-claim or counterclaim in a lawsuit) alleging that
456 | any patent claim is infringed by making, using, selling, offering for
457 | sale, or importing the Program or any portion of it.
458 |
459 | 11. Patents.
460 |
461 | A "contributor" is a copyright holder who authorizes use under this
462 | License of the Program or a work on which the Program is based. The
463 | work thus licensed is called the contributor's "contributor version".
464 |
465 | A contributor's "essential patent claims" are all patent claims
466 | owned or controlled by the contributor, whether already acquired or
467 | hereafter acquired, that would be infringed by some manner, permitted
468 | by this License, of making, using, or selling its contributor version,
469 | but do not include claims that would be infringed only as a
470 | consequence of further modification of the contributor version. For
471 | purposes of this definition, "control" includes the right to grant
472 | patent sublicenses in a manner consistent with the requirements of
473 | this License.
474 |
475 | Each contributor grants you a non-exclusive, worldwide, royalty-free
476 | patent license under the contributor's essential patent claims, to
477 | make, use, sell, offer for sale, import and otherwise run, modify and
478 | propagate the contents of its contributor version.
479 |
480 | In the following three paragraphs, a "patent license" is any express
481 | agreement or commitment, however denominated, not to enforce a patent
482 | (such as an express permission to practice a patent or covenant not to
483 | sue for patent infringement). To "grant" such a patent license to a
484 | party means to make such an agreement or commitment not to enforce a
485 | patent against the party.
486 |
487 | If you convey a covered work, knowingly relying on a patent license,
488 | and the Corresponding Source of the work is not available for anyone
489 | to copy, free of charge and under the terms of this License, through a
490 | publicly available network server or other readily accessible means,
491 | then you must either (1) cause the Corresponding Source to be so
492 | available, or (2) arrange to deprive yourself of the benefit of the
493 | patent license for this particular work, or (3) arrange, in a manner
494 | consistent with the requirements of this License, to extend the patent
495 | license to downstream recipients. "Knowingly relying" means you have
496 | actual knowledge that, but for the patent license, your conveying the
497 | covered work in a country, or your recipient's use of the covered work
498 | in a country, would infringe one or more identifiable patents in that
499 | country that you have reason to believe are valid.
500 |
501 | If, pursuant to or in connection with a single transaction or
502 | arrangement, you convey, or propagate by procuring conveyance of, a
503 | covered work, and grant a patent license to some of the parties
504 | receiving the covered work authorizing them to use, propagate, modify
505 | or convey a specific copy of the covered work, then the patent license
506 | you grant is automatically extended to all recipients of the covered
507 | work and works based on it.
508 |
509 | A patent license is "discriminatory" if it does not include within
510 | the scope of its coverage, prohibits the exercise of, or is
511 | conditioned on the non-exercise of one or more of the rights that are
512 | specifically granted under this License. You may not convey a covered
513 | work if you are a party to an arrangement with a third party that is
514 | in the business of distributing software, under which you make payment
515 | to the third party based on the extent of your activity of conveying
516 | the work, and under which the third party grants, to any of the
517 | parties who would receive the covered work from you, a discriminatory
518 | patent license (a) in connection with copies of the covered work
519 | conveyed by you (or copies made from those copies), or (b) primarily
520 | for and in connection with specific products or compilations that
521 | contain the covered work, unless you entered into that arrangement,
522 | or that patent license was granted, prior to 28 March 2007.
523 |
524 | Nothing in this License shall be construed as excluding or limiting
525 | any implied license or other defenses to infringement that may
526 | otherwise be available to you under applicable patent law.
527 |
528 | 12. No Surrender of Others' Freedom.
529 |
530 | If conditions are imposed on you (whether by court order, agreement or
531 | otherwise) that contradict the conditions of this License, they do not
532 | excuse you from the conditions of this License. If you cannot convey a
533 | covered work so as to satisfy simultaneously your obligations under this
534 | License and any other pertinent obligations, then as a consequence you may
535 | not convey it at all. For example, if you agree to terms that obligate you
536 | to collect a royalty for further conveying from those to whom you convey
537 | the Program, the only way you could satisfy both those terms and this
538 | License would be to refrain entirely from conveying the Program.
539 |
540 | 13. Remote Network Interaction; Use with the GNU General Public License.
541 |
542 | Notwithstanding any other provision of this License, if you modify the
543 | Program, your modified version must prominently offer all users
544 | interacting with it remotely through a computer network (if your version
545 | supports such interaction) an opportunity to receive the Corresponding
546 | Source of your version by providing access to the Corresponding Source
547 | from a network server at no charge, through some standard or customary
548 | means of facilitating copying of software. This Corresponding Source
549 | shall include the Corresponding Source for any work covered by version 3
550 | of the GNU General Public License that is incorporated pursuant to the
551 | following paragraph.
552 |
553 | Notwithstanding any other provision of this License, you have
554 | permission to link or combine any covered work with a work licensed
555 | under version 3 of the GNU General Public License into a single
556 | combined work, and to convey the resulting work. The terms of this
557 | License will continue to apply to the part which is the covered work,
558 | but the work with which it is combined will remain governed by version
559 | 3 of the GNU General Public License.
560 |
561 | 14. Revised Versions of this License.
562 |
563 | The Free Software Foundation may publish revised and/or new versions of
564 | the GNU Affero General Public License from time to time. Such new versions
565 | will be similar in spirit to the present version, but may differ in detail to
566 | address new problems or concerns.
567 |
568 | Each version is given a distinguishing version number. If the
569 | Program specifies that a certain numbered version of the GNU Affero General
570 | Public License "or any later version" applies to it, you have the
571 | option of following the terms and conditions either of that numbered
572 | version or of any later version published by the Free Software
573 | Foundation. If the Program does not specify a version number of the
574 | GNU Affero General Public License, you may choose any version ever published
575 | by the Free Software Foundation.
576 |
577 | If the Program specifies that a proxy can decide which future
578 | versions of the GNU Affero General Public License can be used, that proxy's
579 | public statement of acceptance of a version permanently authorizes you
580 | to choose that version for the Program.
581 |
582 | Later license versions may give you additional or different
583 | permissions. However, no additional obligations are imposed on any
584 | author or copyright holder as a result of your choosing to follow a
585 | later version.
586 |
587 | 15. Disclaimer of Warranty.
588 |
589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597 |
598 | 16. Limitation of Liability.
599 |
600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608 | SUCH DAMAGES.
609 |
610 | 17. Interpretation of Sections 15 and 16.
611 |
612 | If the disclaimer of warranty and limitation of liability provided
613 | above cannot be given local legal effect according to their terms,
614 | reviewing courts shall apply local law that most closely approximates
615 | an absolute waiver of all civil liability in connection with the
616 | Program, unless a warranty or assumption of liability accompanies a
617 | copy of the Program in return for a fee.
618 |
619 | END OF TERMS AND CONDITIONS
620 |
621 | How to Apply These Terms to Your New Programs
622 |
623 | If you develop a new program, and you want it to be of the greatest
624 | possible use to the public, the best way to achieve this is to make it
625 | free software which everyone can redistribute and change under these terms.
626 |
627 | To do so, attach the following notices to the program. It is safest
628 | to attach them to the start of each source file to most effectively
629 | state the exclusion of warranty; and each file should have at least
630 | the "copyright" line and a pointer to where the full notice is found.
631 |
632 |
633 | Copyright (C)
634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published by
637 | the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BiliBot
2 |
3 | bilibot是一个可以监控bilibiliUP直播以及动态的QQ机器人,并附有关键词回复等功能
4 |
5 | ## 二代目
6 |
7 | 在使用的酷Q框架关闭后,BiliBot二代目使用了另外一个框架——mirai
8 |
9 | BiliBot二代目使用的有:
10 |
11 | mirai:https://github.com/mamoe/mirai
12 |
13 | mirai-http-api:https://github.com/project-mirai/mirai-api-http
14 |
15 | node-mirai-sdk:https://github.com/RedBeanN/node-mirai
16 |
17 | # 环境配置
18 |
19 | (README.pdf中有图文解说)
20 |
21 | ## Java
22 |
23 | mirai运行需要java环境,所以首先要安装java环境
24 |
25 | ### linux之ubuntu安装java
26 |
27 | 进入ubuntu终端后在命令行输入`sudo apt install openjdk-11-jdk`
28 |
29 | 安装成功后输入`java -version`查看java版本,判断java是否安装成功
30 |
31 | ## node
32 |
33 | BiliBot二代目开发使用的框架为node的mirai-http-api插件,所以需要安装node.js
34 |
35 | ### linux之ubuntu安装node
36 |
37 | 教程地址:https://www.cnblogs.com/niuben/p/12938501.html
38 |
39 | 1.进入将要安装node的文件夹,输入以下命令下载node安装包:
40 |
41 | `wget https://nodejs.org/dist/v14.15.5/node-v14.15.5-linux-x64.tar.xz`
42 |
43 | 2.解压node安装包:
44 |
45 | `tar -xvf node-v14.15.5-linux-x64.tar.xz`
46 |
47 | 3.配置软连接,全局都可以使用node
48 |
49 | ```bash
50 | mv node-v14.15.5-linux-x64 node // 修改解压包名称
51 |
52 | ln -s /安装node的文件夹/node /usr/bin/node --将node源文件映射到usr/bin下的node文件
53 |
54 | ln -s /安装node的文件夹/node/bin/npm /usr/bin/npm
55 | ```
56 |
57 | 4.配置node文件安装路径
58 |
59 | ```bash
60 | mkdir node_global
61 |
62 | mkdir node_cache
63 |
64 | npm config set prefix "node_global"
65 |
66 | npm config set cache "node_cache"
67 | ```
68 |
69 | 5.查看node版本判断是否安装成功
70 |
71 | ```bash
72 | node -v
73 | ```
74 |
75 | # 运行
76 |
77 | ## 安装mirai
78 |
79 | 找到mirai文件夹,根据你的操作系统选择“mcl-installer-1.0.1-linux-amd64”或是“mcl-installer-1.0.1-windows-amd64.exe”,运行后再根据电脑的环境选择对应的版本
80 |
81 | ### window系统安装mcl
82 |
83 | 将“mcl-installer-1.0.1-windows-amd64.exe”放入向要安装mirai的文件夹中运行,再根据系统环境的选择对应的mirai安装包
84 |
85 | ### linux之ubuntu安装mcl
86 |
87 | 在ubuntu终端进入将要安装mirai的文件夹输入以下命令:
88 |
89 | ```bash
90 | curl -LJO https://github.com/iTXTech/mcl-installer/releases/download/v1.0.2/mcl-installer-1.0.2-linux-amd64
91 | sudo chmod +x mcl-installer-1.0.2-linux-amd64
92 | sudo ./mcl-installer-1.0.2-linux-amd64
93 | ```
94 |
95 | 再根据系统的环境选择对应的mirai安装包
96 |
97 | ## 安装mirai-http-api
98 |
99 | mirai安装完成后需要先运行一遍以生成“plugins”文件夹:
100 |
101 | 1.进入mirai的安装目录。
102 |
103 | 2.window系统需要在命令行中输入`.\mcl`运行mirai;
104 |
105 | linux系统则要在命令行中输入以下命令行:
106 |
107 | ```bash
108 | sudo chmod +x mcl
109 | sudo ./mcl
110 | ```
111 |
112 | 3.运行mcl后,输入`/autologin add bot的QQ号 bot的密码`,添加自动登陆的QQ号
113 |
114 | 4.接着安装mirai-api-http:退出mirai,将mirai文件夹中的“mirai-api-http-v1.9.8.mirai.jar”放入“/mirai安装文件夹/plugins”文件夹,再运行mcl就能使用mirai-http了
115 |
116 | 5.再对mirai-api-http进行配置,进入文件夹”/mirai的安装文件夹/config/net.mamoe.mirai-api-http/“,修改”setting.yml”配置文件中的authKey等信息
117 |
118 | ## 运行main.js
119 |
120 | 1.根据mirai的配置,在main.js中对main.js的配置进行自定义。
121 |
122 | 2.接着安装node项目的依赖项:
123 |
124 | ```bash
125 | sudo npm install --registry=https://registry.npm.taobao.org --unsafe-perm
126 | ```
127 |
128 | 3.接着在命令行中输入`node main.js`即可运行bot,输入`sudo nohup node main.js >/dev/null 2>&1 &`可以后台运行bot且不使用输出日志
129 |
130 | # 其它
131 |
132 | 后台运行mcl:`sudo nohup ./mcl >/dev/null 2>&1 &`,可以不使用输入日志
133 |
--------------------------------------------------------------------------------
/README.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenwed/biliBot/79a4b8fc0f3170367a1cc1a51355be5168e87cd6/README.pdf
--------------------------------------------------------------------------------
/database/robot.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenwed/biliBot/79a4b8fc0f3170367a1cc1a51355be5168e87cd6/database/robot.db
--------------------------------------------------------------------------------
/images/feizhai.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenwed/biliBot/79a4b8fc0f3170367a1cc1a51355be5168e87cd6/images/feizhai.jpg
--------------------------------------------------------------------------------
/images/ybb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenwed/biliBot/79a4b8fc0f3170367a1cc1a51355be5168e87cd6/images/ybb.jpg
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | const Mirai = require("node-mirai-sdk");
2 | // const { Plain, At } = Mirai.MessageComponent;
3 | const repair = require("./scripts/repair.js");
4 |
5 | /**
6 | * 服务端设置(*)
7 | * host: mirai-api-http 的地址和端口,默认是 http://127.0.0.1:8080
8 | * authKey: mirai-api-http 的 authKey,建议手动指定
9 | * qq: 当前 BOT 对应的 QQ 号
10 | * enableWebsocket: 是否开启 WebSocket,需要和 mirai-api-http 的设置一致
11 | */
12 | const bot = new Mirai({
13 | host: 'http://127.0.0.1:8080',
14 | authKey: '在mirai-api-http的setting.yml中自己定义的authkey',
15 | qq: 你的QQ号,
16 | enableWebsocket: false,
17 | });
18 |
19 | // auth 认证(*)
20 | bot.onSignal('authed', () => {
21 | console.log(`Authed with session key ${bot.sessionKey}`);
22 | bot.verify();
23 | });
24 |
25 | // session 校验回调
26 | bot.onSignal('verified', async () => {
27 | console.log(`Verified with session key ${bot.sessionKey}`);
28 |
29 | // 获取好友列表,需要等待 session 校验之后 (verified) 才能调用 SDK 中的主动接口
30 | const friendList = await bot.getFriendList();
31 | console.log(`There are ${friendList.length} friends in bot`);
32 | // 运行bilibili爬虫
33 | repair.startBiliSpider(bot);
34 | });
35 |
36 | // 接受消息,发送消息(*)
37 | bot.onMessage(async message => {
38 | const { type, sender, messageChain, reply, quoteReply, recall } = message;
39 |
40 | //如果为群组消息
41 | if (type === "GroupMessage") {
42 | repair.repairGroup(bot, message, sender, messageChain, reply, quoteReply, recall);
43 | }
44 | // 如果消息为好友消息,使用好友消息处理函数
45 | else if (type === "FriendMessage") {
46 | repair.repairPerson(bot, message, sender, messageChain, reply, quoteReply, recall);
47 | }
48 | });
49 |
50 | /* 开始监听消息(*)
51 | * 'all' - 监听好友和群
52 | * 'friend' - 只监听好友
53 | * 'group' - 只监听群
54 | * 'temp' - 只监听临时会话
55 | */
56 | bot.listen('all');
57 |
58 | // 退出前向 mirai-http-api 发送释放指令(*)
59 | process.on('exit', () => {
60 | bot.release();
61 | });
--------------------------------------------------------------------------------
/mirai/mcl-installer-1.0.1-linux-amd64:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenwed/biliBot/79a4b8fc0f3170367a1cc1a51355be5168e87cd6/mirai/mcl-installer-1.0.1-linux-amd64
--------------------------------------------------------------------------------
/mirai/mcl-installer-1.0.1-windows-amd64.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenwed/biliBot/79a4b8fc0f3170367a1cc1a51355be5168e87cd6/mirai/mcl-installer-1.0.1-windows-amd64.exe
--------------------------------------------------------------------------------
/mirai/mirai-api-http-v1.9.8.mirai.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wenwed/biliBot/79a4b8fc0f3170367a1cc1a51355be5168e87cd6/mirai/mirai-api-http-v1.9.8.mirai.jar
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bilibot",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "abbrev": {
8 | "version": "1.1.1",
9 | "resolved": "https://registry.npm.taobao.org/abbrev/download/abbrev-1.1.1.tgz",
10 | "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg="
11 | },
12 | "ajv": {
13 | "version": "6.12.6",
14 | "resolved": "https://registry.npm.taobao.org/ajv/download/ajv-6.12.6.tgz?cache=0&sync_timestamp=1613033036883&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv%2Fdownload%2Fajv-6.12.6.tgz",
15 | "integrity": "sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ=",
16 | "optional": true,
17 | "requires": {
18 | "fast-deep-equal": "^3.1.1",
19 | "fast-json-stable-stringify": "^2.0.0",
20 | "json-schema-traverse": "^0.4.1",
21 | "uri-js": "^4.2.2"
22 | }
23 | },
24 | "ansi-regex": {
25 | "version": "2.1.1",
26 | "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-2.1.1.tgz",
27 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
28 | },
29 | "aproba": {
30 | "version": "1.2.0",
31 | "resolved": "https://registry.npm.taobao.org/aproba/download/aproba-1.2.0.tgz",
32 | "integrity": "sha1-aALmJk79GMeQobDVF/DyYnvyyUo="
33 | },
34 | "are-we-there-yet": {
35 | "version": "1.1.5",
36 | "resolved": "https://registry.npm.taobao.org/are-we-there-yet/download/are-we-there-yet-1.1.5.tgz",
37 | "integrity": "sha1-SzXClE8GKov82mZBB2A1D+nd/CE=",
38 | "requires": {
39 | "delegates": "^1.0.0",
40 | "readable-stream": "^2.0.6"
41 | }
42 | },
43 | "asn1": {
44 | "version": "0.2.4",
45 | "resolved": "https://registry.npm.taobao.org/asn1/download/asn1-0.2.4.tgz",
46 | "integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=",
47 | "optional": true,
48 | "requires": {
49 | "safer-buffer": "~2.1.0"
50 | }
51 | },
52 | "assert-plus": {
53 | "version": "1.0.0",
54 | "resolved": "https://registry.npm.taobao.org/assert-plus/download/assert-plus-1.0.0.tgz",
55 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
56 | "optional": true
57 | },
58 | "asynckit": {
59 | "version": "0.4.0",
60 | "resolved": "https://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz",
61 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
62 | },
63 | "aws-sign2": {
64 | "version": "0.7.0",
65 | "resolved": "https://registry.npm.taobao.org/aws-sign2/download/aws-sign2-0.7.0.tgz",
66 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
67 | "optional": true
68 | },
69 | "aws4": {
70 | "version": "1.11.0",
71 | "resolved": "https://registry.npm.taobao.org/aws4/download/aws4-1.11.0.tgz?cache=0&sync_timestamp=1604101340021&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faws4%2Fdownload%2Faws4-1.11.0.tgz",
72 | "integrity": "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk=",
73 | "optional": true
74 | },
75 | "axios": {
76 | "version": "0.21.1",
77 | "resolved": "https://registry.npm.taobao.org/axios/download/axios-0.21.1.tgz?cache=0&sync_timestamp=1608609188013&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.21.1.tgz",
78 | "integrity": "sha1-IlY0gZYvTWvemnbVFu8OXTwJsrg=",
79 | "requires": {
80 | "follow-redirects": "^1.10.0"
81 | }
82 | },
83 | "balanced-match": {
84 | "version": "1.0.0",
85 | "resolved": "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz",
86 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
87 | },
88 | "bcrypt-pbkdf": {
89 | "version": "1.0.2",
90 | "resolved": "https://registry.npm.taobao.org/bcrypt-pbkdf/download/bcrypt-pbkdf-1.0.2.tgz",
91 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
92 | "optional": true,
93 | "requires": {
94 | "tweetnacl": "^0.14.3"
95 | }
96 | },
97 | "block-stream": {
98 | "version": "0.0.9",
99 | "resolved": "https://registry.npm.taobao.org/block-stream/download/block-stream-0.0.9.tgz",
100 | "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
101 | "optional": true,
102 | "requires": {
103 | "inherits": "~2.0.0"
104 | }
105 | },
106 | "brace-expansion": {
107 | "version": "1.1.11",
108 | "resolved": "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz?cache=0&sync_timestamp=1601898201980&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrace-expansion%2Fdownload%2Fbrace-expansion-1.1.11.tgz",
109 | "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=",
110 | "requires": {
111 | "balanced-match": "^1.0.0",
112 | "concat-map": "0.0.1"
113 | }
114 | },
115 | "caseless": {
116 | "version": "0.12.0",
117 | "resolved": "https://registry.npm.taobao.org/caseless/download/caseless-0.12.0.tgz",
118 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
119 | "optional": true
120 | },
121 | "chownr": {
122 | "version": "1.1.4",
123 | "resolved": "https://registry.npm.taobao.org/chownr/download/chownr-1.1.4.tgz",
124 | "integrity": "sha1-b8nXtC0ypYNZYzdmbn0ICE2izGs="
125 | },
126 | "code-point-at": {
127 | "version": "1.1.0",
128 | "resolved": "https://registry.npm.taobao.org/code-point-at/download/code-point-at-1.1.0.tgz",
129 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
130 | },
131 | "combined-stream": {
132 | "version": "1.0.8",
133 | "resolved": "https://registry.npm.taobao.org/combined-stream/download/combined-stream-1.0.8.tgz",
134 | "integrity": "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=",
135 | "requires": {
136 | "delayed-stream": "~1.0.0"
137 | }
138 | },
139 | "concat-map": {
140 | "version": "0.0.1",
141 | "resolved": "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz",
142 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
143 | },
144 | "console-control-strings": {
145 | "version": "1.1.0",
146 | "resolved": "https://registry.npm.taobao.org/console-control-strings/download/console-control-strings-1.1.0.tgz",
147 | "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
148 | },
149 | "core-util-is": {
150 | "version": "1.0.2",
151 | "resolved": "https://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz",
152 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
153 | },
154 | "dashdash": {
155 | "version": "1.14.1",
156 | "resolved": "https://registry.npm.taobao.org/dashdash/download/dashdash-1.14.1.tgz?cache=0&sync_timestamp=1601073602368&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdashdash%2Fdownload%2Fdashdash-1.14.1.tgz",
157 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
158 | "optional": true,
159 | "requires": {
160 | "assert-plus": "^1.0.0"
161 | }
162 | },
163 | "debug": {
164 | "version": "3.2.7",
165 | "resolved": "https://registry.npm.taobao.org/debug/download/debug-3.2.7.tgz?cache=0&sync_timestamp=1607566571506&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-3.2.7.tgz",
166 | "integrity": "sha1-clgLfpFF+zm2Z2+cXl+xALk0F5o=",
167 | "requires": {
168 | "ms": "^2.1.1"
169 | }
170 | },
171 | "deep-extend": {
172 | "version": "0.6.0",
173 | "resolved": "https://registry.npm.taobao.org/deep-extend/download/deep-extend-0.6.0.tgz",
174 | "integrity": "sha1-xPp8lUBKF6nD6Mp+FTcxK3NjMKw="
175 | },
176 | "delayed-stream": {
177 | "version": "1.0.0",
178 | "resolved": "https://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz",
179 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
180 | },
181 | "delegates": {
182 | "version": "1.0.0",
183 | "resolved": "https://registry.npm.taobao.org/delegates/download/delegates-1.0.0.tgz",
184 | "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
185 | },
186 | "detect-libc": {
187 | "version": "1.0.3",
188 | "resolved": "https://registry.npm.taobao.org/detect-libc/download/detect-libc-1.0.3.tgz",
189 | "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
190 | },
191 | "ecc-jsbn": {
192 | "version": "0.1.2",
193 | "resolved": "https://registry.npm.taobao.org/ecc-jsbn/download/ecc-jsbn-0.1.2.tgz",
194 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
195 | "optional": true,
196 | "requires": {
197 | "jsbn": "~0.1.0",
198 | "safer-buffer": "^2.1.0"
199 | }
200 | },
201 | "extend": {
202 | "version": "3.0.2",
203 | "resolved": "https://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz",
204 | "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=",
205 | "optional": true
206 | },
207 | "extsprintf": {
208 | "version": "1.3.0",
209 | "resolved": "https://registry.npm.taobao.org/extsprintf/download/extsprintf-1.3.0.tgz",
210 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
211 | "optional": true
212 | },
213 | "fast-deep-equal": {
214 | "version": "3.1.3",
215 | "resolved": "https://registry.npm.taobao.org/fast-deep-equal/download/fast-deep-equal-3.1.3.tgz",
216 | "integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=",
217 | "optional": true
218 | },
219 | "fast-json-stable-stringify": {
220 | "version": "2.1.0",
221 | "resolved": "https://registry.npm.taobao.org/fast-json-stable-stringify/download/fast-json-stable-stringify-2.1.0.tgz",
222 | "integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=",
223 | "optional": true
224 | },
225 | "follow-redirects": {
226 | "version": "1.13.2",
227 | "resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.13.2.tgz?cache=0&sync_timestamp=1611606737937&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.13.2.tgz",
228 | "integrity": "sha1-3XPI7/wScoulz0JZ12DqX7g+MUc="
229 | },
230 | "forever-agent": {
231 | "version": "0.6.1",
232 | "resolved": "https://registry.npm.taobao.org/forever-agent/download/forever-agent-0.6.1.tgz",
233 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
234 | "optional": true
235 | },
236 | "form-data": {
237 | "version": "3.0.0",
238 | "resolved": "https://registry.npm.taobao.org/form-data/download/form-data-3.0.0.tgz",
239 | "integrity": "sha1-MbfjnIXxNVtxOe4MZHzw3n+DxoI=",
240 | "requires": {
241 | "asynckit": "^0.4.0",
242 | "combined-stream": "^1.0.8",
243 | "mime-types": "^2.1.12"
244 | }
245 | },
246 | "fs-minipass": {
247 | "version": "1.2.7",
248 | "resolved": "https://registry.npm.taobao.org/fs-minipass/download/fs-minipass-1.2.7.tgz",
249 | "integrity": "sha1-zP+FcIQef+QmVpPaiJNsVa7X98c=",
250 | "requires": {
251 | "minipass": "^2.6.0"
252 | }
253 | },
254 | "fs.realpath": {
255 | "version": "1.0.0",
256 | "resolved": "https://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz",
257 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
258 | },
259 | "fstream": {
260 | "version": "1.0.12",
261 | "resolved": "https://registry.npm.taobao.org/fstream/download/fstream-1.0.12.tgz",
262 | "integrity": "sha1-Touo7i1Ivk99DeUFRVVI6uWTIEU=",
263 | "optional": true,
264 | "requires": {
265 | "graceful-fs": "^4.1.2",
266 | "inherits": "~2.0.0",
267 | "mkdirp": ">=0.5 0",
268 | "rimraf": "2"
269 | }
270 | },
271 | "gauge": {
272 | "version": "2.7.4",
273 | "resolved": "https://registry.npm.taobao.org/gauge/download/gauge-2.7.4.tgz",
274 | "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
275 | "requires": {
276 | "aproba": "^1.0.3",
277 | "console-control-strings": "^1.0.0",
278 | "has-unicode": "^2.0.0",
279 | "object-assign": "^4.1.0",
280 | "signal-exit": "^3.0.0",
281 | "string-width": "^1.0.1",
282 | "strip-ansi": "^3.0.1",
283 | "wide-align": "^1.1.0"
284 | }
285 | },
286 | "getpass": {
287 | "version": "0.1.7",
288 | "resolved": "https://registry.npm.taobao.org/getpass/download/getpass-0.1.7.tgz",
289 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
290 | "optional": true,
291 | "requires": {
292 | "assert-plus": "^1.0.0"
293 | }
294 | },
295 | "glob": {
296 | "version": "7.1.6",
297 | "resolved": "https://registry.npm.taobao.org/glob/download/glob-7.1.6.tgz?cache=0&sync_timestamp=1573203677246&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fglob%2Fdownload%2Fglob-7.1.6.tgz",
298 | "integrity": "sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=",
299 | "requires": {
300 | "fs.realpath": "^1.0.0",
301 | "inflight": "^1.0.4",
302 | "inherits": "2",
303 | "minimatch": "^3.0.4",
304 | "once": "^1.3.0",
305 | "path-is-absolute": "^1.0.0"
306 | }
307 | },
308 | "graceful-fs": {
309 | "version": "4.2.6",
310 | "resolved": "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.6.tgz",
311 | "integrity": "sha1-/wQLKwhTsjw9MQJ1I3BvGIXXa+4=",
312 | "optional": true
313 | },
314 | "har-schema": {
315 | "version": "2.0.0",
316 | "resolved": "https://registry.npm.taobao.org/har-schema/download/har-schema-2.0.0.tgz",
317 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
318 | "optional": true
319 | },
320 | "har-validator": {
321 | "version": "5.1.5",
322 | "resolved": "https://registry.npm.taobao.org/har-validator/download/har-validator-5.1.5.tgz?cache=0&sync_timestamp=1596082838391&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhar-validator%2Fdownload%2Fhar-validator-5.1.5.tgz",
323 | "integrity": "sha1-HwgDufjLIMD6E4It8ezds2veHv0=",
324 | "optional": true,
325 | "requires": {
326 | "ajv": "^6.12.3",
327 | "har-schema": "^2.0.0"
328 | }
329 | },
330 | "has-unicode": {
331 | "version": "2.0.1",
332 | "resolved": "https://registry.npm.taobao.org/has-unicode/download/has-unicode-2.0.1.tgz",
333 | "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
334 | },
335 | "http-signature": {
336 | "version": "1.2.0",
337 | "resolved": "https://registry.npm.taobao.org/http-signature/download/http-signature-1.2.0.tgz?cache=0&sync_timestamp=1600868441269&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-signature%2Fdownload%2Fhttp-signature-1.2.0.tgz",
338 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
339 | "optional": true,
340 | "requires": {
341 | "assert-plus": "^1.0.0",
342 | "jsprim": "^1.2.2",
343 | "sshpk": "^1.7.0"
344 | }
345 | },
346 | "iconv-lite": {
347 | "version": "0.4.24",
348 | "resolved": "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz?cache=0&sync_timestamp=1594184250387&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ficonv-lite%2Fdownload%2Ficonv-lite-0.4.24.tgz",
349 | "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=",
350 | "requires": {
351 | "safer-buffer": ">= 2.1.2 < 3"
352 | }
353 | },
354 | "ignore-walk": {
355 | "version": "3.0.3",
356 | "resolved": "https://registry.npm.taobao.org/ignore-walk/download/ignore-walk-3.0.3.tgz",
357 | "integrity": "sha1-AX4kRxhL/q3nwjjkrv3R6PlbHjc=",
358 | "requires": {
359 | "minimatch": "^3.0.4"
360 | }
361 | },
362 | "inflight": {
363 | "version": "1.0.6",
364 | "resolved": "https://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz",
365 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
366 | "requires": {
367 | "once": "^1.3.0",
368 | "wrappy": "1"
369 | }
370 | },
371 | "inherits": {
372 | "version": "2.0.4",
373 | "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz",
374 | "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w="
375 | },
376 | "ini": {
377 | "version": "1.3.8",
378 | "resolved": "https://registry.npm.taobao.org/ini/download/ini-1.3.8.tgz?cache=0&sync_timestamp=1607907801722&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fini%2Fdownload%2Fini-1.3.8.tgz",
379 | "integrity": "sha1-op2kJbSIBvNHZ6Tvzjlyaa8oQyw="
380 | },
381 | "is-fullwidth-code-point": {
382 | "version": "1.0.0",
383 | "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-1.0.0.tgz",
384 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
385 | "requires": {
386 | "number-is-nan": "^1.0.0"
387 | }
388 | },
389 | "is-typedarray": {
390 | "version": "1.0.0",
391 | "resolved": "https://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz",
392 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
393 | "optional": true
394 | },
395 | "isarray": {
396 | "version": "1.0.0",
397 | "resolved": "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz",
398 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
399 | },
400 | "isexe": {
401 | "version": "2.0.0",
402 | "resolved": "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz",
403 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
404 | "optional": true
405 | },
406 | "isstream": {
407 | "version": "0.1.2",
408 | "resolved": "https://registry.npm.taobao.org/isstream/download/isstream-0.1.2.tgz",
409 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
410 | "optional": true
411 | },
412 | "jsbn": {
413 | "version": "0.1.1",
414 | "resolved": "https://registry.npm.taobao.org/jsbn/download/jsbn-0.1.1.tgz",
415 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
416 | "optional": true
417 | },
418 | "json-schema": {
419 | "version": "0.2.3",
420 | "resolved": "https://registry.npm.taobao.org/json-schema/download/json-schema-0.2.3.tgz?cache=0&sync_timestamp=1609553686459&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson-schema%2Fdownload%2Fjson-schema-0.2.3.tgz",
421 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
422 | "optional": true
423 | },
424 | "json-schema-traverse": {
425 | "version": "0.4.1",
426 | "resolved": "https://registry.npm.taobao.org/json-schema-traverse/download/json-schema-traverse-0.4.1.tgz?cache=0&sync_timestamp=1607998035113&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson-schema-traverse%2Fdownload%2Fjson-schema-traverse-0.4.1.tgz",
427 | "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=",
428 | "optional": true
429 | },
430 | "json-stringify-safe": {
431 | "version": "5.0.1",
432 | "resolved": "https://registry.npm.taobao.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz",
433 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
434 | "optional": true
435 | },
436 | "jsprim": {
437 | "version": "1.4.1",
438 | "resolved": "https://registry.npm.taobao.org/jsprim/download/jsprim-1.4.1.tgz",
439 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
440 | "optional": true,
441 | "requires": {
442 | "assert-plus": "1.0.0",
443 | "extsprintf": "1.3.0",
444 | "json-schema": "0.2.3",
445 | "verror": "1.10.0"
446 | }
447 | },
448 | "mime-db": {
449 | "version": "1.45.0",
450 | "resolved": "https://registry.npm.taobao.org/mime-db/download/mime-db-1.45.0.tgz?cache=0&sync_timestamp=1600831145015&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-db%2Fdownload%2Fmime-db-1.45.0.tgz",
451 | "integrity": "sha1-zO7aIczXw6dF66LezVXUtz54eeo="
452 | },
453 | "mime-types": {
454 | "version": "2.1.28",
455 | "resolved": "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.28.tgz?cache=0&sync_timestamp=1609559894106&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-types%2Fdownload%2Fmime-types-2.1.28.tgz",
456 | "integrity": "sha1-EWDEdX6rLFNjiI4AUnPs950qDs0=",
457 | "requires": {
458 | "mime-db": "1.45.0"
459 | }
460 | },
461 | "minimatch": {
462 | "version": "3.0.4",
463 | "resolved": "https://registry.npm.taobao.org/minimatch/download/minimatch-3.0.4.tgz",
464 | "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
465 | "requires": {
466 | "brace-expansion": "^1.1.7"
467 | }
468 | },
469 | "minimist": {
470 | "version": "1.2.5",
471 | "resolved": "https://registry.npm.taobao.org/minimist/download/minimist-1.2.5.tgz?cache=0&sync_timestamp=1584060927134&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fminimist%2Fdownload%2Fminimist-1.2.5.tgz",
472 | "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI="
473 | },
474 | "minipass": {
475 | "version": "2.9.0",
476 | "resolved": "https://registry.npm.taobao.org/minipass/download/minipass-2.9.0.tgz",
477 | "integrity": "sha1-5xN2Ln0+Mv7YAxFc+T4EvKn8yaY=",
478 | "requires": {
479 | "safe-buffer": "^5.1.2",
480 | "yallist": "^3.0.0"
481 | }
482 | },
483 | "minizlib": {
484 | "version": "1.3.3",
485 | "resolved": "https://registry.npm.taobao.org/minizlib/download/minizlib-1.3.3.tgz",
486 | "integrity": "sha1-IpDeloGKNMKVUcio0wEha9Zahh0=",
487 | "requires": {
488 | "minipass": "^2.9.0"
489 | }
490 | },
491 | "mkdirp": {
492 | "version": "0.5.5",
493 | "resolved": "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.5.tgz?cache=0&sync_timestamp=1587535418745&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-0.5.5.tgz",
494 | "integrity": "sha1-2Rzv1i0UNsoPQWIOJRKI1CAJne8=",
495 | "requires": {
496 | "minimist": "^1.2.5"
497 | }
498 | },
499 | "ms": {
500 | "version": "2.1.3",
501 | "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.3.tgz?cache=0&sync_timestamp=1607433872491&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.3.tgz",
502 | "integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI="
503 | },
504 | "needle": {
505 | "version": "2.6.0",
506 | "resolved": "https://registry.npm.taobao.org/needle/download/needle-2.6.0.tgz",
507 | "integrity": "sha1-JNu1XyUJ4jJLSpnWH0E5ggE8zb4=",
508 | "requires": {
509 | "debug": "^3.2.6",
510 | "iconv-lite": "^0.4.4",
511 | "sax": "^1.2.4"
512 | }
513 | },
514 | "node-addon-api": {
515 | "version": "2.0.0",
516 | "resolved": "https://registry.npm.taobao.org/node-addon-api/download/node-addon-api-2.0.0.tgz?cache=0&sync_timestamp=1608165738569&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-addon-api%2Fdownload%2Fnode-addon-api-2.0.0.tgz",
517 | "integrity": "sha1-+a+413epFSUkSwF3XqDdvhElSDs="
518 | },
519 | "node-gyp": {
520 | "version": "3.8.0",
521 | "resolved": "https://registry.npm.taobao.org/node-gyp/download/node-gyp-3.8.0.tgz?cache=0&sync_timestamp=1602898543148&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-gyp%2Fdownload%2Fnode-gyp-3.8.0.tgz",
522 | "integrity": "sha1-VAMEJhwzDoDQ1e3OJTpoyzlkIYw=",
523 | "optional": true,
524 | "requires": {
525 | "fstream": "^1.0.0",
526 | "glob": "^7.0.3",
527 | "graceful-fs": "^4.1.2",
528 | "mkdirp": "^0.5.0",
529 | "nopt": "2 || 3",
530 | "npmlog": "0 || 1 || 2 || 3 || 4",
531 | "osenv": "0",
532 | "request": "^2.87.0",
533 | "rimraf": "2",
534 | "semver": "~5.3.0",
535 | "tar": "^2.0.0",
536 | "which": "1"
537 | }
538 | },
539 | "node-mirai-sdk": {
540 | "version": "0.2.3",
541 | "resolved": "https://registry.npm.taobao.org/node-mirai-sdk/download/node-mirai-sdk-0.2.3.tgz",
542 | "integrity": "sha1-o+BKZKLE6OIxNsr594tbl9oxF6I=",
543 | "requires": {
544 | "axios": "^0.21.1",
545 | "form-data": "^3.0.0",
546 | "ws": "^7.2.3"
547 | }
548 | },
549 | "node-pre-gyp": {
550 | "version": "0.11.0",
551 | "resolved": "https://registry.npm.taobao.org/node-pre-gyp/download/node-pre-gyp-0.11.0.tgz",
552 | "integrity": "sha1-2x8zIVJy9pLNOPAyOOPptHxd0FQ=",
553 | "requires": {
554 | "detect-libc": "^1.0.2",
555 | "mkdirp": "^0.5.1",
556 | "needle": "^2.2.1",
557 | "nopt": "^4.0.1",
558 | "npm-packlist": "^1.1.6",
559 | "npmlog": "^4.0.2",
560 | "rc": "^1.2.7",
561 | "rimraf": "^2.6.1",
562 | "semver": "^5.3.0",
563 | "tar": "^4"
564 | },
565 | "dependencies": {
566 | "nopt": {
567 | "version": "4.0.3",
568 | "resolved": "https://registry.npm.taobao.org/nopt/download/nopt-4.0.3.tgz?cache=0&sync_timestamp=1597649892953&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnopt%2Fdownload%2Fnopt-4.0.3.tgz",
569 | "integrity": "sha1-o3XK2dAv2SEnjZVMIlTVqlfhXkg=",
570 | "requires": {
571 | "abbrev": "1",
572 | "osenv": "^0.1.4"
573 | }
574 | },
575 | "tar": {
576 | "version": "4.4.13",
577 | "resolved": "https://registry.npm.taobao.org/tar/download/tar-4.4.13.tgz?cache=0&sync_timestamp=1610045888507&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftar%2Fdownload%2Ftar-4.4.13.tgz",
578 | "integrity": "sha1-Q7NkvFKIjVVSmGN7ENYHkCVKtSU=",
579 | "requires": {
580 | "chownr": "^1.1.1",
581 | "fs-minipass": "^1.2.5",
582 | "minipass": "^2.8.6",
583 | "minizlib": "^1.2.1",
584 | "mkdirp": "^0.5.0",
585 | "safe-buffer": "^5.1.2",
586 | "yallist": "^3.0.3"
587 | }
588 | }
589 | }
590 | },
591 | "nopt": {
592 | "version": "3.0.6",
593 | "resolved": "https://registry.npm.taobao.org/nopt/download/nopt-3.0.6.tgz?cache=0&sync_timestamp=1597649892953&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnopt%2Fdownload%2Fnopt-3.0.6.tgz",
594 | "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
595 | "optional": true,
596 | "requires": {
597 | "abbrev": "1"
598 | }
599 | },
600 | "npm-bundled": {
601 | "version": "1.1.1",
602 | "resolved": "https://registry.npm.taobao.org/npm-bundled/download/npm-bundled-1.1.1.tgz",
603 | "integrity": "sha1-Ht1XCGWpTNsbyCIHdeKUZsn7I0s=",
604 | "requires": {
605 | "npm-normalize-package-bin": "^1.0.1"
606 | }
607 | },
608 | "npm-normalize-package-bin": {
609 | "version": "1.0.1",
610 | "resolved": "https://registry.npm.taobao.org/npm-normalize-package-bin/download/npm-normalize-package-bin-1.0.1.tgz",
611 | "integrity": "sha1-bnmkHyP9I1wGIyGCKNp9nCO49uI="
612 | },
613 | "npm-packlist": {
614 | "version": "1.4.8",
615 | "resolved": "https://registry.npm.taobao.org/npm-packlist/download/npm-packlist-1.4.8.tgz?cache=0&sync_timestamp=1603319937404&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnpm-packlist%2Fdownload%2Fnpm-packlist-1.4.8.tgz",
616 | "integrity": "sha1-Vu5swTW5+YrT1Rwcldoiu7my7z4=",
617 | "requires": {
618 | "ignore-walk": "^3.0.1",
619 | "npm-bundled": "^1.0.1",
620 | "npm-normalize-package-bin": "^1.0.1"
621 | }
622 | },
623 | "npmlog": {
624 | "version": "4.1.2",
625 | "resolved": "https://registry.npm.taobao.org/npmlog/download/npmlog-4.1.2.tgz",
626 | "integrity": "sha1-CKfyqL9zRgR3mp76StXMcXq7lUs=",
627 | "requires": {
628 | "are-we-there-yet": "~1.1.2",
629 | "console-control-strings": "~1.1.0",
630 | "gauge": "~2.7.3",
631 | "set-blocking": "~2.0.0"
632 | }
633 | },
634 | "number-is-nan": {
635 | "version": "1.0.1",
636 | "resolved": "https://registry.npm.taobao.org/number-is-nan/download/number-is-nan-1.0.1.tgz?cache=0&sync_timestamp=1581061498787&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnumber-is-nan%2Fdownload%2Fnumber-is-nan-1.0.1.tgz",
637 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
638 | },
639 | "oauth-sign": {
640 | "version": "0.9.0",
641 | "resolved": "https://registry.npm.taobao.org/oauth-sign/download/oauth-sign-0.9.0.tgz",
642 | "integrity": "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU=",
643 | "optional": true
644 | },
645 | "object-assign": {
646 | "version": "4.1.1",
647 | "resolved": "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz",
648 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
649 | },
650 | "once": {
651 | "version": "1.4.0",
652 | "resolved": "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz",
653 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
654 | "requires": {
655 | "wrappy": "1"
656 | }
657 | },
658 | "os-homedir": {
659 | "version": "1.0.2",
660 | "resolved": "https://registry.npm.taobao.org/os-homedir/download/os-homedir-1.0.2.tgz",
661 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
662 | },
663 | "os-tmpdir": {
664 | "version": "1.0.2",
665 | "resolved": "https://registry.npm.taobao.org/os-tmpdir/download/os-tmpdir-1.0.2.tgz",
666 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
667 | },
668 | "osenv": {
669 | "version": "0.1.5",
670 | "resolved": "https://registry.npm.taobao.org/osenv/download/osenv-0.1.5.tgz",
671 | "integrity": "sha1-hc36+uso6Gd/QW4odZK18/SepBA=",
672 | "requires": {
673 | "os-homedir": "^1.0.0",
674 | "os-tmpdir": "^1.0.0"
675 | }
676 | },
677 | "path-is-absolute": {
678 | "version": "1.0.1",
679 | "resolved": "https://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz",
680 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
681 | },
682 | "performance-now": {
683 | "version": "2.1.0",
684 | "resolved": "https://registry.npm.taobao.org/performance-now/download/performance-now-2.1.0.tgz",
685 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
686 | "optional": true
687 | },
688 | "process-nextick-args": {
689 | "version": "2.0.1",
690 | "resolved": "https://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.1.tgz",
691 | "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I="
692 | },
693 | "psl": {
694 | "version": "1.8.0",
695 | "resolved": "https://registry.npm.taobao.org/psl/download/psl-1.8.0.tgz",
696 | "integrity": "sha1-kyb4vPsBOtzABf3/BWrM4CDlHCQ=",
697 | "optional": true
698 | },
699 | "punycode": {
700 | "version": "2.1.1",
701 | "resolved": "https://registry.npm.taobao.org/punycode/download/punycode-2.1.1.tgz",
702 | "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=",
703 | "optional": true
704 | },
705 | "qs": {
706 | "version": "6.5.2",
707 | "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.5.2.tgz?cache=0&sync_timestamp=1610598229410&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fqs%2Fdownload%2Fqs-6.5.2.tgz",
708 | "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=",
709 | "optional": true
710 | },
711 | "rc": {
712 | "version": "1.2.8",
713 | "resolved": "https://registry.npm.taobao.org/rc/download/rc-1.2.8.tgz?cache=0&sync_timestamp=1593529723659&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frc%2Fdownload%2Frc-1.2.8.tgz",
714 | "integrity": "sha1-zZJL9SAKB1uDwYjNa54hG3/A0+0=",
715 | "requires": {
716 | "deep-extend": "^0.6.0",
717 | "ini": "~1.3.0",
718 | "minimist": "^1.2.0",
719 | "strip-json-comments": "~2.0.1"
720 | }
721 | },
722 | "readable-stream": {
723 | "version": "2.3.7",
724 | "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.7.tgz",
725 | "integrity": "sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c=",
726 | "requires": {
727 | "core-util-is": "~1.0.0",
728 | "inherits": "~2.0.3",
729 | "isarray": "~1.0.0",
730 | "process-nextick-args": "~2.0.0",
731 | "safe-buffer": "~5.1.1",
732 | "string_decoder": "~1.1.1",
733 | "util-deprecate": "~1.0.1"
734 | }
735 | },
736 | "request": {
737 | "version": "2.88.2",
738 | "resolved": "https://registry.npm.taobao.org/request/download/request-2.88.2.tgz",
739 | "integrity": "sha1-1zyRhzHLWofaBH4gcjQUb2ZNErM=",
740 | "optional": true,
741 | "requires": {
742 | "aws-sign2": "~0.7.0",
743 | "aws4": "^1.8.0",
744 | "caseless": "~0.12.0",
745 | "combined-stream": "~1.0.6",
746 | "extend": "~3.0.2",
747 | "forever-agent": "~0.6.1",
748 | "form-data": "~2.3.2",
749 | "har-validator": "~5.1.3",
750 | "http-signature": "~1.2.0",
751 | "is-typedarray": "~1.0.0",
752 | "isstream": "~0.1.2",
753 | "json-stringify-safe": "~5.0.1",
754 | "mime-types": "~2.1.19",
755 | "oauth-sign": "~0.9.0",
756 | "performance-now": "^2.1.0",
757 | "qs": "~6.5.2",
758 | "safe-buffer": "^5.1.2",
759 | "tough-cookie": "~2.5.0",
760 | "tunnel-agent": "^0.6.0",
761 | "uuid": "^3.3.2"
762 | },
763 | "dependencies": {
764 | "form-data": {
765 | "version": "2.3.3",
766 | "resolved": "https://registry.npm.taobao.org/form-data/download/form-data-2.3.3.tgz",
767 | "integrity": "sha1-3M5SwF9kTymManq5Nr1yTO/786Y=",
768 | "optional": true,
769 | "requires": {
770 | "asynckit": "^0.4.0",
771 | "combined-stream": "^1.0.6",
772 | "mime-types": "^2.1.12"
773 | }
774 | }
775 | }
776 | },
777 | "rimraf": {
778 | "version": "2.7.1",
779 | "resolved": "https://registry.npm.taobao.org/rimraf/download/rimraf-2.7.1.tgz",
780 | "integrity": "sha1-NXl/E6f9rcVmFCwp1PB8ytSD4+w=",
781 | "requires": {
782 | "glob": "^7.1.3"
783 | }
784 | },
785 | "safe-buffer": {
786 | "version": "5.1.2",
787 | "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz",
788 | "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0="
789 | },
790 | "safer-buffer": {
791 | "version": "2.1.2",
792 | "resolved": "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz",
793 | "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo="
794 | },
795 | "sax": {
796 | "version": "1.2.4",
797 | "resolved": "https://registry.npm.taobao.org/sax/download/sax-1.2.4.tgz?cache=0&sync_timestamp=1593529670203&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsax%2Fdownload%2Fsax-1.2.4.tgz",
798 | "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk="
799 | },
800 | "semver": {
801 | "version": "5.3.0",
802 | "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.3.0.tgz?cache=0&sync_timestamp=1606854810932&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.3.0.tgz",
803 | "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
804 | },
805 | "set-blocking": {
806 | "version": "2.0.0",
807 | "resolved": "https://registry.npm.taobao.org/set-blocking/download/set-blocking-2.0.0.tgz",
808 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
809 | },
810 | "signal-exit": {
811 | "version": "3.0.3",
812 | "resolved": "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.3.tgz",
813 | "integrity": "sha1-oUEMLt2PB3sItOJTyOrPyvBXRhw="
814 | },
815 | "sqlite3": {
816 | "version": "5.0.0",
817 | "resolved": "https://registry.npm.taobao.org/sqlite3/download/sqlite3-5.0.0.tgz",
818 | "integrity": "sha1-G/7yFRxrxIo6sabBJgiLuN0jNWY=",
819 | "requires": {
820 | "node-addon-api": "2.0.0",
821 | "node-gyp": "3.x",
822 | "node-pre-gyp": "^0.11.0"
823 | }
824 | },
825 | "sshpk": {
826 | "version": "1.16.1",
827 | "resolved": "https://registry.npm.taobao.org/sshpk/download/sshpk-1.16.1.tgz",
828 | "integrity": "sha1-+2YcC+8ps520B2nuOfpwCT1vaHc=",
829 | "optional": true,
830 | "requires": {
831 | "asn1": "~0.2.3",
832 | "assert-plus": "^1.0.0",
833 | "bcrypt-pbkdf": "^1.0.0",
834 | "dashdash": "^1.12.0",
835 | "ecc-jsbn": "~0.1.1",
836 | "getpass": "^0.1.1",
837 | "jsbn": "~0.1.0",
838 | "safer-buffer": "^2.0.2",
839 | "tweetnacl": "~0.14.0"
840 | }
841 | },
842 | "string-width": {
843 | "version": "1.0.2",
844 | "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-1.0.2.tgz",
845 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
846 | "requires": {
847 | "code-point-at": "^1.0.0",
848 | "is-fullwidth-code-point": "^1.0.0",
849 | "strip-ansi": "^3.0.0"
850 | }
851 | },
852 | "string_decoder": {
853 | "version": "1.1.1",
854 | "resolved": "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz",
855 | "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
856 | "requires": {
857 | "safe-buffer": "~5.1.0"
858 | }
859 | },
860 | "strip-ansi": {
861 | "version": "3.0.1",
862 | "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-3.0.1.tgz",
863 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
864 | "requires": {
865 | "ansi-regex": "^2.0.0"
866 | }
867 | },
868 | "strip-json-comments": {
869 | "version": "2.0.1",
870 | "resolved": "https://registry.npm.taobao.org/strip-json-comments/download/strip-json-comments-2.0.1.tgz?cache=0&sync_timestamp=1594567555399&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-json-comments%2Fdownload%2Fstrip-json-comments-2.0.1.tgz",
871 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
872 | },
873 | "tar": {
874 | "version": "2.2.2",
875 | "resolved": "https://registry.npm.taobao.org/tar/download/tar-2.2.2.tgz?cache=0&sync_timestamp=1610045888507&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftar%2Fdownload%2Ftar-2.2.2.tgz",
876 | "integrity": "sha1-DKiEhWLHKZuLRG/2pNYM27I+3EA=",
877 | "optional": true,
878 | "requires": {
879 | "block-stream": "*",
880 | "fstream": "^1.0.12",
881 | "inherits": "2"
882 | }
883 | },
884 | "tough-cookie": {
885 | "version": "2.5.0",
886 | "resolved": "https://registry.npm.taobao.org/tough-cookie/download/tough-cookie-2.5.0.tgz",
887 | "integrity": "sha1-zZ+yoKodWhK0c72fuW+j3P9lreI=",
888 | "optional": true,
889 | "requires": {
890 | "psl": "^1.1.28",
891 | "punycode": "^2.1.1"
892 | }
893 | },
894 | "tunnel-agent": {
895 | "version": "0.6.0",
896 | "resolved": "https://registry.npm.taobao.org/tunnel-agent/download/tunnel-agent-0.6.0.tgz",
897 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
898 | "optional": true,
899 | "requires": {
900 | "safe-buffer": "^5.0.1"
901 | }
902 | },
903 | "tweetnacl": {
904 | "version": "0.14.5",
905 | "resolved": "https://registry.npm.taobao.org/tweetnacl/download/tweetnacl-0.14.5.tgz",
906 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
907 | "optional": true
908 | },
909 | "uri-js": {
910 | "version": "4.4.1",
911 | "resolved": "https://registry.npm.taobao.org/uri-js/download/uri-js-4.4.1.tgz?cache=0&sync_timestamp=1610237517218&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Furi-js%2Fdownload%2Furi-js-4.4.1.tgz",
912 | "integrity": "sha1-mxpSWVIlhZ5V9mnZKPiMbFfyp34=",
913 | "optional": true,
914 | "requires": {
915 | "punycode": "^2.1.0"
916 | }
917 | },
918 | "util-deprecate": {
919 | "version": "1.0.2",
920 | "resolved": "https://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz",
921 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
922 | },
923 | "uuid": {
924 | "version": "3.4.0",
925 | "resolved": "https://registry.npm.taobao.org/uuid/download/uuid-3.4.0.tgz?cache=0&sync_timestamp=1607458532020&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuuid%2Fdownload%2Fuuid-3.4.0.tgz",
926 | "integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=",
927 | "optional": true
928 | },
929 | "verror": {
930 | "version": "1.10.0",
931 | "resolved": "https://registry.npm.taobao.org/verror/download/verror-1.10.0.tgz",
932 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
933 | "optional": true,
934 | "requires": {
935 | "assert-plus": "^1.0.0",
936 | "core-util-is": "1.0.2",
937 | "extsprintf": "^1.2.0"
938 | }
939 | },
940 | "which": {
941 | "version": "1.3.1",
942 | "resolved": "https://registry.npm.taobao.org/which/download/which-1.3.1.tgz",
943 | "integrity": "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo=",
944 | "optional": true,
945 | "requires": {
946 | "isexe": "^2.0.0"
947 | }
948 | },
949 | "wide-align": {
950 | "version": "1.1.3",
951 | "resolved": "https://registry.npm.taobao.org/wide-align/download/wide-align-1.1.3.tgz",
952 | "integrity": "sha1-rgdOa9wMFKQx6ATmJFScYzsABFc=",
953 | "requires": {
954 | "string-width": "^1.0.2 || 2"
955 | }
956 | },
957 | "wrappy": {
958 | "version": "1.0.2",
959 | "resolved": "https://registry.npm.taobao.org/wrappy/download/wrappy-1.0.2.tgz",
960 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
961 | },
962 | "ws": {
963 | "version": "7.4.3",
964 | "resolved": "https://registry.npm.taobao.org/ws/download/ws-7.4.3.tgz",
965 | "integrity": "sha1-H5ZD3jSlQ7jtsSS9y8RXrlWm5c0="
966 | },
967 | "yallist": {
968 | "version": "3.1.1",
969 | "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-3.1.1.tgz",
970 | "integrity": "sha1-27fa+b/YusmrRev2ArjLrQ1dCP0="
971 | }
972 | }
973 | }
974 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bilibot",
3 | "version": "1.0.0",
4 | "description": "bilibili bot",
5 | "main": "main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/wenwed/biliBot.git"
12 | },
13 | "keywords": [
14 | "bilibili",
15 | "bot"
16 | ],
17 | "author": "wenwd",
18 | "license": "ISC",
19 | "bugs": {
20 | "url": "https://github.com/wenwed/biliBot/issues"
21 | },
22 | "homepage": "https://github.com/wenwed/biliBot#readme",
23 | "dependencies": {
24 | "axios": "^0.21.1",
25 | "node-mirai-sdk": "^0.2.3",
26 | "sqlite3": "^5.0.0"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/scripts/middleWare.js:
--------------------------------------------------------------------------------
1 | const sql = require("./sql.js");
2 | const axios = require("axios");
3 |
4 | //生成群组订阅列表
5 | exports.createGroupSubList = async (values) => {
6 | let repairWord = "";
7 | let index = 0;
8 | await sql.selectGroupAllSubInfoByType(values).then(rows => {
9 | rows.forEach(row => {
10 | index++;
11 | repairWord = repairWord + "\n" + index + " " + row.UID + " " + row.Name
12 | });
13 | })
14 | if (values[1] === 1)
15 | repairWord = `该群订阅了${index}位up主` + repairWord;
16 | else if (values[1] === 2)
17 | repairWord = `该群直播订阅了${index}位up主` + repairWord;
18 | else if (values[1] === 3)
19 | repairWord = `该群动态订阅了${index}位up主` + repairWord;
20 | return repairWord;
21 | }
22 |
23 | //为群组订阅一位UP主
24 | exports.subGroup = async (groupID, type, UID) => {
25 | // 判断用户输入的UID是不是数字
26 | if (isNaN(UID))
27 | return "UID应为数字";
28 |
29 | let repairWord = "";
30 | let UPName = "";
31 | let infoData = null;
32 | //判断该群组是否正在关注此UP主
33 | let values = [UID, groupID];
34 | await sql.selectGroupOneSub(values).then(rows => {
35 | if (rows.length === 1) {
36 | UPName = rows[0].Name;
37 | if (rows[0].Sub_Type === type) {
38 | repairWord = `该群已订阅${UPName}`;
39 | throw new Error("STOP");
40 | }
41 | else {
42 | values = [type, UID, groupID];
43 | sql.updateGroupSubType(values);
44 | repairWord = `已更新${UPName}的订阅类型`;
45 | throw new Error("STOP");
46 | }
47 | } else {
48 | values = [UID];
49 | return sql.selectUP(values);
50 | }
51 | }).then(rows => {
52 | if (rows.length === 1) {
53 | UPName = rows[0].Name;
54 | values = [UID, groupID, type]
55 | sql.addGroupSub(values);
56 | repairWord = `关注${UPName}成功`;
57 | throw new Error("STOP");
58 | } else {
59 | let infoURL = `https://api.bilibili.com/x/space/acc/info?mid=${UID}&jsonp=jsonp`;
60 | return axios.get(infoURL, {
61 | headers: {
62 | 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
63 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
64 | }
65 | })
66 | }
67 | }).then((res) => {
68 | infoData = res.data;
69 | if (infoData.code !== 0) {
70 | repairWord = "爬取信息出错,请检查UID是否正确";
71 | throw new Error("STOP");
72 | } else {
73 | // 向数据库中新增UP主信息
74 | infoData = infoData.data;
75 | let Name = infoData.name;
76 | let AID = null;
77 | if (infoData.live_room.roomStatus === 1)
78 | AID = infoData.live_room.roomid;
79 | let liveStatus = infoData.live_room.liveStatus;
80 | let liveStartTime = Math.round(new Date().getTime() / 1000);
81 | let lastNoticeTime = Math.round(new Date().getTime() / 1000);
82 | values = [UID, Name, AID, liveStatus, liveStartTime, lastNoticeTime]
83 | sql.addUP(values);
84 |
85 | // 向数据库中新增关注
86 | values = [UID, groupID, type];
87 | sql.addGroupSub(values);
88 | repairWord = `订阅${Name}成功`
89 | }
90 | }).catch(() => {
91 | // 之前throw的"STOP" error会直接跳转到这里
92 | if (repairWord === "")
93 | repairWord = "未知错误";
94 | })
95 | return repairWord;
96 | }
97 |
98 | // 删除某个群组对某个UP主的订阅
99 | exports.deleteGroupSub = async (groupID, UID) => {
100 | // 判断用户输入的UID是不是数字
101 | if (isNaN(UID))
102 | return "UID应为数字";
103 |
104 | let repairWord = "";
105 | let UPName = "";
106 | let values = [UID, groupID];
107 | let subNum = 0;
108 |
109 | // 先判断是否订阅
110 | await sql.selectGroupOneSub(values).then(rows => {
111 | if (rows.length === 0) {
112 | repairWord = `该群未订阅此UP主`;
113 | throw new Error("STOP");
114 | } else {
115 | UPName = rows[0].Name;
116 | return sql.deleteGroupSub(values);
117 | }
118 | }).then(() => {
119 | // 查找个人关注的数量
120 | values = [UID];
121 | return sql.selectPersonSubByUP(values);
122 | }).then(rows => {
123 | // 查找群组关注的数量
124 | subNum += rows.length;
125 | return sql.selectGroupSubByUP(values);
126 | }).then(rows => {
127 | subNum += rows.length;
128 | if (subNum !== 0) {
129 | repairWord = `取消订阅${UPName}成功`;
130 | throw new Error("STOP");
131 | } else {
132 | return sql.deleteUP(values);
133 | }
134 | }).then(() => {
135 | repairWord = `取消订阅${UPName}成功`;
136 | }).catch(err => {
137 | // 之前throw的"STOP" error会直接跳转到这里
138 | if (repairWord === "")
139 | repairWord = "未知错误";
140 | })
141 | return repairWord;
142 | }
143 |
144 | //生成个人订阅列表
145 | exports.createPersonSubList = async (values) => {
146 | let repairWord = "";
147 | let index = 0;
148 | await sql.selectPersonAllSubInfoByType(values).then(rows => {
149 | rows.forEach(row => {
150 | index++;
151 | repairWord = repairWord + "\n" + index + " " + row.UID + " " + row.Name
152 | });
153 | })
154 | if (values[1] === 1)
155 | repairWord = `你订阅了${index}位up主` + repairWord;
156 | else if (values[1] === 2)
157 | repairWord = `你直播订阅了${index}位up主` + repairWord;
158 | else if (values[1] === 3)
159 | repairWord = `你动态订阅了${index}位up主` + repairWord;
160 | return repairWord;
161 | }
162 |
163 | // 开启复读
164 | exports.startRepeat = async (values) => {
165 | let repairWord = "";
166 | await sql.selectGroupBanRepeat(values).then((rows) => {
167 | if (rows.length === 0) {
168 | repairWord = `该群组已开启复读功能`;
169 | throw new Error("STOP");
170 | } else {
171 | return sql.deleteGroupBanRepeat(values);
172 | }
173 | }).then(() => {
174 | repairWord = `开启复读功能`;
175 | }).catch(() => {
176 | if (repairWord === "") {
177 | repairWord = `未知错误`;
178 | }
179 | })
180 | return repairWord;
181 | }
182 |
183 | // 关闭复读
184 | exports.stopRepeat = async (values) => {
185 | let repairWord = "";
186 | await sql.selectGroupBanRepeat(values).then((rows) => {
187 | if (rows.length === 1) {
188 | repairWord = `该群组已关闭复读功能`;
189 | throw new Error("STOP");
190 | } else {
191 | return sql.addGroupBanRepeat(values);
192 | }
193 | }).then(() => {
194 | repairWord = `关闭复读功能`;
195 | }).catch(() => {
196 | if (repairWord === "") {
197 | repairWord = `未知错误`;
198 | }
199 | })
200 | return repairWord;
201 | }
202 |
203 | // 生成关键词列表
204 | exports.createGroupKeyWordsList = async (values) => {
205 | let repairWord = "";
206 | let index = 0;
207 | await sql.selectKeyWords(values).then(rows => {
208 | rows.forEach(row => {
209 | index++;
210 | repairWord = `${repairWord}\n${index} ${row.Key_Word}`;
211 | });
212 | })
213 | if (values[1] === 1) {
214 | repairWord = "该群添加了如下精确关键词:" + repairWord;
215 | } else {
216 | repairWord = "该群添加了如下模糊关键词:" + repairWord;
217 | }
218 | return repairWord;
219 | }
220 |
221 | // 添加关键词
222 | exports.addGroupKeyWords = async (groupID, keyWord, type, replyWord) => {
223 | let values = [groupID, keyWord];
224 | let repairWord = "";
225 | await sql.selectOneKeyWords(values).then(rows => {
226 | if (rows.length !== 0) {
227 | repairWord = "该群已添加此关键词";
228 | throw new Error("STOP");
229 | } else {
230 | values = [groupID, keyWord, replyWord, type];
231 | return sql.addKeyWords(values);
232 | }
233 | }).then(() => {
234 | repairWord = "添加成功";
235 | }).catch(err => {
236 | if (repairWord === "") {
237 | repairWord = "未知错误";
238 | }
239 | })
240 | return repairWord;
241 | }
242 |
243 | // 删除关键词
244 | exports.deleteGroupKeyWords = async (values) => {
245 | let repairword = "";
246 | await sql.selectOneKeyWords(values).then(rows => {
247 | if (rows.length === 0) {
248 | repairword = "该群未添加此关键词";
249 | throw new Error("STOP");
250 | } else {
251 | return sql.deleteKeyWords(values);
252 | }
253 | }).then(() => {
254 | repairword = "删除关键词成功";
255 | }).catch(err => {
256 | if (repairword === "") {
257 | repairword = "未知错误";
258 | }
259 | })
260 | return repairword;
261 | }
262 |
263 | //为个人订阅一位UP主
264 | exports.subPerson = async (personID, type, UID) => {
265 | // 判断用户输入的UID是不是数字
266 | if (isNaN(UID))
267 | return "UID应为数字";
268 |
269 | let repairWord = "";
270 | let UPName = "";
271 | let infoData = null;
272 | //判断该群组是否正在关注此UP主
273 | let values = [UID, personID];
274 | await sql.selectPersonOneSub(values).then(rows => {
275 | if (rows.length === 1) {
276 | UPName = rows[0].Name;
277 | if (rows[0].Sub_Type === type) {
278 | repairWord = `你已订阅${UPName}`;
279 | throw new Error("STOP");
280 | }
281 | else {
282 | values = [type, UID, personID];
283 | sql.updatePersonSubType(values);
284 | repairWord = `已更新${UPName}的关注类型`;
285 | throw new Error("STOP");
286 | }
287 | } else {
288 | values = [UID];
289 | return sql.selectUP(values);
290 | }
291 | }).then(rows => {
292 | if (rows.length === 1) {
293 | UPName = rows[0].Name;
294 | values = [UID, personID, type]
295 | sql.addPersonSub(values);
296 | repairWord = `订阅${UPName}成功`;
297 | throw new Error("STOP");
298 | } else {
299 | let infoURL = `https://api.bilibili.com/x/space/acc/info?mid=${UID}&jsonp=jsonp`;
300 | return axios.get(infoURL, {
301 | headers: {
302 | 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
303 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
304 | }
305 | })
306 | }
307 | }).then((res) => {
308 | infoData = res.data;
309 | if (infoData.code !== 0) {
310 | repairWord = "爬取信息出错,请检查UID是否正确";
311 | throw new Error("STOP");
312 | } else {
313 | // 向数据库中新增UP主信息
314 | infoData = infoData.data;
315 | let Name = infoData.name;
316 | let AID = null;
317 | if (infoData.live_room.roomStatus === 1)
318 | AID = infoData.live_room.roomid;
319 | let liveStatus = infoData.live_room.liveStatus;
320 | let liveStartTime = Math.round(new Date().getTime() / 1000);
321 | let lastNoticeTime = Math.round(new Date().getTime() / 1000);
322 | values = [UID, Name, AID, liveStatus, liveStartTime, lastNoticeTime]
323 | sql.addUP(values);
324 |
325 | // 向数据库中新增关注
326 | values = [UID, personID, type];
327 | sql.addPersonSub(values);
328 | repairWord = `订阅${Name}成功`
329 | }
330 | }).catch((err) => {
331 | // 之前throw的"STOP" error会直接跳转到这里
332 | if (repairWord === "")
333 | repairWord = "未知错误";
334 | })
335 | return repairWord;
336 | }
337 |
338 | // 删除某个个人对某个UP主的订阅
339 | exports.deletePersonSub = async (personID, UID) => {
340 | // 判断用户输入的UID是不是数字
341 | if (isNaN(UID))
342 | return "UID应为数字";
343 |
344 | let repairWord = "";
345 | let UPName = "";
346 | let values = [UID, personID];
347 | let subNum = 0;
348 |
349 | // 先判断是否订阅
350 | await sql.selectPersonOneSub(values).then(rows => {
351 | if (rows.length === 0) {
352 | repairWord = `你未订阅此UP主`;
353 | throw new Error("STOP");
354 | } else {
355 | UPName = rows[0].Name;
356 | return sql.deletePersonSub(values);
357 | }
358 | }).then(() => {
359 | // 查找个人关注的数量
360 | values = [UID];
361 | return sql.selectPersonSubByUP(values);
362 | }).then(rows => {
363 | // 查找群组关注的数量
364 | subNum += rows.length;
365 | return sql.selectGroupSubByUP(values);
366 | }).then(rows => {
367 | subNum += rows.length;
368 | if (subNum !== 0) {
369 | repairWord = `取消订阅${UPName}成功`;
370 | throw new Error("STOP");
371 | } else {
372 | return sql.deleteUP(values);
373 | }
374 | }).then(() => {
375 | repairWord = `取消订阅${UPName}成功`;
376 | }).catch(err => {
377 | // 之前throw的"STOP" error会直接跳转到这里
378 | if (repairWord === "")
379 | repairWord = "未知错误";
380 | })
381 | return repairWord;
382 | }
383 |
384 | // 勋章查询(API已失效)
385 | exports.searchBiliMedal = async (UID) => {
386 | // 判断UID是否为数字
387 | if (isNaN(UID)) {
388 | return "UID应为数字";
389 | }
390 |
391 | let infoURL = `http://101.201.64.44/breeze/user.t?uid=${UID}`;
392 | await axios.get(infoURL, {
393 | headers: {
394 | 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
395 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
396 | }
397 | }).then((res) => {
398 | console.log(res);
399 | })
400 | }
401 |
402 | // 添加todo
403 | exports.createTodo = async (todoText, groupID) => {
404 | if (!todoText) {
405 | return "请输入todo内容";
406 | }
407 | let repairWord = "";
408 | let values = [todoText, groupID, new Date().getTime()];
409 | await sql.addTodo(values).then((res) => {
410 | repairWord = `添加todo:${todoText} 成功`;
411 | })
412 | return repairWord;
413 | }
414 |
415 | // 获取todo列表
416 | exports.selectGroupTodo = async (groupID) => {
417 | let values = [groupID];
418 | let repairWord = "";
419 | await sql.selectTodo(values).then((res) => {
420 | repairWord = `当前有${res.length}个todo事项`;
421 | for (let i = 0; i < res.length; i++) {
422 | repairWord = `${repairWord}\n${res[i].todoID} ${res[i].todo_text}`;
423 | }
424 | })
425 | return repairWord;
426 | }
427 |
428 | // 完成todo
429 | exports.completeTodo = async (groupID, ID) => {
430 | // 判断用户输入的UID是不是数字
431 | if (isNaN(ID))
432 | return "todo的id应为数字";
433 |
434 | let values = [ID];
435 | let repairWord = "未知错误";
436 | await sql.selectOneTodo(values).then((res) => {
437 | if (res.length === 0) {
438 | repairWord = `没有此项todo或已完成`;
439 | throw new Error("STOP");
440 | } else if (res[0].Group_Number != groupID) {
441 | repairWord = `此项todo不属于该群组`;
442 | throw new Error("STOP");
443 | } else {
444 | return sql.deleteTodo(values)
445 | }
446 | }).then((result) => {
447 | repairWord = `已完成todo事项:${res[0].todo_text}`;
448 | }).catch((err) => {
449 | })
450 | return repairWord;
451 | }
452 |
453 | // 完成某个群组所有的todo
454 | exports.completeAllTodo = async (groupID) => {
455 | let values = [groupID];
456 | let repairWord = "";
457 | await sql.deleteAllTodo(values).then((res) => {
458 | repairWord = `已完成该群组所有的todo事项`;
459 | })
460 | return repairWord;
461 | }
--------------------------------------------------------------------------------
/scripts/repair.js:
--------------------------------------------------------------------------------
1 | const sql = require("./sql.js");
2 | const middleWare = require("./middleWare.js");
3 | const spider = require("./spider.js");
4 | const Mirai = require('node-mirai-sdk');
5 | const { Plain, At } = Mirai.MessageComponent;
6 |
7 | // 开始运行bilibili爬虫
8 | exports.startBiliSpider = async (bot) => {
9 | function sleep(time) {
10 | return new Promise((resolve) => setTimeout(resolve, time));
11 | }
12 | //更新UP主的动态时间
13 | spider.resetDynamicTime();
14 | // 五分钟运行一次爬虫
15 | while (true) {
16 | await sleep(300000).then(() => {
17 | spider.startLivingSpider(bot);
18 | spider.startDynamicSpider(bot);
19 | })
20 | }
21 | }
22 |
23 | // 回复群组消息
24 | exports.repairGroup = async (bot, message, sender, messageChain, reply, quoteReply, recall) => {
25 | // 从 messageChain 中提取文字内容
26 | let msg = '';
27 | messageChain.forEach(chain => {
28 | if (chain.type === 'Plain')
29 | msg += Plain.value(chain);
30 | });
31 |
32 | // 判断是否为bot指令
33 | if (msg.indexOf("!") === 0) {
34 | manageGroup(message, sender, messageChain, reply, quoteReply, recall, msg);
35 | return;
36 | }
37 |
38 | manageTodo(sender, reply, msg);
39 |
40 | let target = 0;
41 | messageChain.forEach(chain => {
42 | if (chain.type === 'At') {
43 | target = chain.target;
44 | }
45 | });
46 |
47 | // 群组聊天@了bot
48 | if (target === bot.qq) {
49 | if (msg === " " || msg === "") {
50 | sql.selectAllAtWords().then((rows) => {
51 | let len = rows.length;
52 | let ran = Math.floor(Math.random() * len);
53 | reply(rows[ran]["At_Word"]);
54 | return;
55 | })
56 | } else if (msg === "老婆" || msg === " 老婆") {
57 | bot.sendImageMessage("./images/feizhai.jpg", message);
58 | return;
59 | } else {
60 | bot.sendImageMessage("./images/ybb.jpg", message);
61 | return;
62 | }
63 | }
64 |
65 | // else if (msg.includes('引用我'))
66 | // quoteReply([At(sender.id), Plain('好的')]); // 或者: bot.quoteReply(messageChain, message)
67 |
68 | // 判断精确关键词
69 | let values = [sender.group.id, 1]
70 | sql.selectKeyWords(values).then(rows => {
71 | rows.forEach(element => {
72 | if (element.Key_Word === msg) {
73 | reply(element.Repair_Word);
74 | flag = true;
75 | return;
76 | }
77 | });
78 | })
79 |
80 | // 判断模糊关键词
81 | values = [sender.group.id, 2]
82 | sql.selectKeyWords(values).then(rows => {
83 | for (let i = 0; i < rows.length; i++) {
84 | if (msg.includes(rows[i].Key_Word)) {
85 | reply(rows[i].Repair_Word);
86 | return;
87 | }
88 | }
89 | })
90 |
91 | // 复读
92 | values = [sender.group.id]
93 | sql.selectGroupBanRepeat(values).then((rows) => {
94 | if (rows.length === 0) {
95 | // 复读模块
96 | let ran = Math.floor(Math.random() * 80);
97 | if (ran === 1) {
98 | let repeatWord = msg.replace(/你/g, "他").replace(/我/g, "你").replace(/bot/g, "我");
99 | reply(repeatWord);
100 | return;
101 | }
102 | }
103 | })
104 | }
105 |
106 | // 回复个人消息
107 | exports.repairPerson = (bot, message, sender, messageChain, reply, quoteReply, recall) => {
108 | let msg = '';
109 | messageChain.forEach(chain => {
110 | if (chain.type === 'Plain')
111 | msg += Plain.value(chain); // 从 messageChain 中提取文字内容
112 | });
113 |
114 | // 判断是否为bot指令
115 | if (msg.indexOf("!") === 0) {
116 | managePerson(message, sender, messageChain, reply, quoteReply, recall, msg);
117 | return;
118 | }
119 | }
120 |
121 | //处理bot的群组指令
122 | function manageGroup(message, sender, messageChain, reply, quoteReply, recall, msg) {
123 | // 使用空格切割字符串
124 | let instruct = msg.split(" ", 2);
125 | let length = 0;
126 | let repairWord = "";
127 |
128 | // 消息来源群组
129 | let groupID = sender.group.id;
130 | // 发送者的权限信息 OWNER,MEMBER,ADMINISTRATOR
131 | let permission = sender.permission;
132 |
133 | let values = [];
134 | let type = 0;
135 | let UID = "";
136 |
137 | switch (instruct[0]) {
138 | case "!help":
139 | repairWord = `!订阅 uid\n!订阅列表\n!直播订阅 uid\n!直播订阅列表
140 | !动态订阅 uid\n!动态订阅列表\n!取消订阅 uid
141 | todo 内容\ntodolist\ndeltodo id\ndelalltodo
142 | 需要管理员权限:\n!添加精确关键词 关键词 回复词\n!添加模糊关键词 关键词 回复词\n!删除关键词 关键词
143 | !精确关键词列表\n!模糊关键词列表\n!开启复读\n!关闭复读
144 | 当前版本:3.0.0\ngithub地址:https://github.com/wenwed/biliBot`;
145 | reply(repairWord);
146 | return;
147 |
148 | case "!订阅列表":
149 | values = [groupID, 1];
150 | middleWare.createGroupSubList(values).then(repairWord => {
151 | reply(repairWord);
152 | });
153 | return;
154 |
155 | case "!直播订阅列表":
156 | values = [groupID, 2];
157 | middleWare.createGroupSubList(values).then(repairWord => {
158 | reply(repairWord);
159 | });
160 | return;
161 |
162 | case "!动态订阅列表":
163 | values = [groupID, 3];
164 | middleWare.createGroupSubList(values).then(repairWord => {
165 | reply(repairWord);
166 | });
167 | return;
168 |
169 | case "!订阅":
170 | type = 1;
171 | UID = instruct[1];
172 | middleWare.subGroup(groupID, type, UID).then(repairWord => {
173 | reply(repairWord);
174 | })
175 | return;
176 |
177 | case "!直播订阅":
178 | type = 2;
179 | UID = instruct[1];
180 | middleWare.subGroup(groupID, type, UID).then(repairWord => {
181 | reply(repairWord);
182 | })
183 | return;
184 |
185 | case "!动态订阅":
186 | type = 3;
187 | UID = instruct[1];
188 | middleWare.subGroup(groupID, type, UID).then(repairWord => {
189 | reply(repairWord);
190 | })
191 | return;
192 |
193 | case "!取消订阅":
194 | UID = instruct[1];
195 | middleWare.deleteGroupSub(groupID, UID).then(repairWord => {
196 | reply(repairWord);
197 | })
198 | return;
199 |
200 | case "!精确关键词列表":
201 | if (permission !== "ADMINISTRATOR" && permission !== "OWNER") {
202 | reply("权限等级不足");
203 | return;
204 | }
205 | values = [groupID, 1];
206 | middleWare.createGroupKeyWordsList(values).then(repairWord => {
207 | reply(repairWord);
208 | })
209 | return;
210 |
211 | case "!模糊关键词列表":
212 | if (permission !== "ADMINISTRATOR" && permission !== "OWNER") {
213 | reply("权限等级不足");
214 | return;
215 | }
216 | values = [groupID, 2];
217 | middleWare.createGroupKeyWordsList(values).then(repairWord => {
218 | reply(repairWord);
219 | })
220 | return;
221 |
222 | case "!添加精确关键词":
223 | if (permission !== "ADMINISTRATOR" && permission !== "OWNER") {
224 | reply("权限等级不足");
225 | return;
226 | } else if (instruct.lenth === 1) {
227 | reply("请输入关键词");
228 | return;
229 | } else {
230 | // 判断前两个字符串加空格的长度,方便截取第三段
231 | length = instruct[0].length + instruct[1].length + 2;
232 | if (msg.substr(length) === "") {
233 | reply("请输入回复词");
234 | return;
235 | }
236 | }
237 | middleWare.addGroupKeyWords(groupID, instruct[1], 1, msg.substr(length)).then(repairWord => {
238 | reply(repairWord);
239 | })
240 | return;
241 |
242 | case "!添加模糊关键词":
243 | if (permission !== "ADMINISTRATOR" && permission !== "OWNER") {
244 | reply("权限等级不足");
245 | return;
246 | } else if (instruct.lenth === 1) {
247 | reply("请输入关键词");
248 | return;
249 | } else {
250 | // 判断前两个字符串加空格的长度,方便截取第三段
251 | length = instruct[0].length + instruct[1].length + 2;
252 | if (msg.substr(length) === "") {
253 | reply("请输入回复词");
254 | return;
255 | }
256 | }
257 | middleWare.addGroupKeyWords(groupID, instruct[1], 2, msg.substr(length)).then(repairWord => {
258 | reply(repairWord);
259 | })
260 | return;
261 |
262 | case "!删除关键词":
263 | if (permission !== "ADMINISTRATOR" && permission !== "OWNER") {
264 | reply("权限等级不足");
265 | return;
266 | } else if (instruct.lenth === 1) {
267 | reply("请输入关键词");
268 | return;
269 | }
270 | values = [groupID, instruct[1]];
271 | middleWare.deleteGroupKeyWords(values).then(repairWord => {
272 | reply(repairWord);
273 | })
274 | return;
275 |
276 | case "!开启复读":
277 | if (permission !== "ADMINISTRATOR" && permission !== "OWNER") {
278 | reply("权限等级不足");
279 | return;
280 | }
281 | values = [groupID];
282 | middleWare.startRepeat(values).then(repairWord => {
283 | reply(repairWord);
284 | })
285 | return;
286 |
287 | case "!关闭复读":
288 | if (permission !== "ADMINISTRATOR" && permission !== "OWNER") {
289 | reply("权限等级不足");
290 | return;
291 | }
292 | values = [groupID];
293 | middleWare.stopRepeat(values).then(repairWord => {
294 | reply(repairWord);
295 | })
296 | return;
297 | }
298 | }
299 |
300 | //处理bot的个人指令
301 | function managePerson(message, sender, messageChain, reply, quoteReply, recall, msg) {
302 | // 使用空格切割字符串
303 | let instruct = msg.split(" ", 2);
304 |
305 | let repairWord = "";
306 | let personID = sender.id;
307 |
308 | let values = [];
309 | let type = 0;
310 | let UID = "";
311 |
312 | switch (instruct[0]) {
313 | case "!help":
314 | repairWord = `!订阅 uid\n!订阅列表\n!直播订阅 uid\n!直播订阅列表\n
315 | !动态订阅 uid\n!动态订阅列表\n!取消订阅 uid\n!勋章查询 uid
316 | 当前版本:3.0.0\ngithub地址:https://github.com/wenwed/biliBot`;
317 | reply(repairWord);
318 | return;
319 |
320 | case "!订阅列表":
321 | values = [personID, 1];
322 | middleWare.createPersonSubList(values).then(repairWord => {
323 | reply(repairWord);
324 | })
325 | return;
326 |
327 | case "!直播订阅列表":
328 | values = [personID, 2];
329 | middleWare.createPersonSubList(values).then(repairWord => {
330 | reply(repairWord);
331 | })
332 | return;
333 |
334 | case "!动态订阅列表":
335 | values = [personID, 3];
336 | middleWare.createPersonSubList(values).then(repairWord => {
337 | reply(repairWord);
338 | })
339 | return;
340 |
341 | case "!订阅":
342 | type = 1;
343 | UID = instruct[1];
344 | middleWare.subPerson(personID, type, UID).then(repairWord => {
345 | reply(repairWord);
346 | })
347 | return;
348 |
349 | case "!直播订阅":
350 | type = 2;
351 | UID = instruct[1];
352 | middleWare.subPerson(personID, type, UID).then(repairWord => {
353 | reply(repairWord);
354 | })
355 | return;
356 |
357 | case "!动态订阅":
358 | type = 3;
359 | UID = instruct[1];
360 | middleWare.subPerson(personID, type, UID).then(repairWord => {
361 | reply(repairWord);
362 | })
363 | return;
364 |
365 | case "!取消订阅":
366 | UID = instruct[1];
367 | middleWare.deletePersonSub(personID, UID).then(repairWord => {
368 | reply(repairWord);
369 | })
370 | return;
371 |
372 | case "!勋章查询":
373 | reply("API已失效");
374 | // UID = instruct[1];
375 | // middleWare.searchBiliMedal(UID).then(repairWord => {
376 | // reply(repairWord);
377 | // })
378 | return;
379 | }
380 | }
381 |
382 | function manageTodo(sender, reply, msg) {
383 | // 使用空格切割字符串
384 | let instruct = msg.split(" ", 2);
385 | let order = instruct[0].toLowerCase();
386 | // 消息来源群组
387 | let groupID = sender.group.id;
388 | let permission = sender.permission;
389 |
390 | switch (order) {
391 | case "todo": {
392 | middleWare.createTodo(msg.substring(instruct[0].length + 1), groupID).then((repairWord) => {
393 | reply(repairWord);
394 | })
395 | return;
396 | }
397 | case "deltodo": {
398 | middleWare.completeTodo(groupID, instruct[1]).then((repairWord) => {
399 | reply(repairWord);
400 | })
401 | return;
402 | }
403 | case "todolist": {
404 | middleWare.selectGroupTodo(groupID).then((repairWord) => {
405 | reply(repairWord);
406 | })
407 | return;
408 | }
409 | case "delalltodo": {
410 | if (permission !== "ADMINISTRATOR" && permission !== "OWNER") {
411 | reply("权限等级不足");
412 | return;
413 | }
414 | middleWare.completeAllTodo(groupID).then((repairWord) => {
415 | reply(repairWord);
416 | })
417 | return;
418 | }
419 | }
420 | }
--------------------------------------------------------------------------------
/scripts/spider.js:
--------------------------------------------------------------------------------
1 | const sql = require("./sql.js");
2 | const axios = require("axios");
3 |
4 | function sleep(time) {
5 | return new Promise((resolve) => setTimeout(resolve, time));
6 | }
7 |
8 | // 直播间爬虫模块
9 | //启动前重置动态爬取时间防止刷屏
10 | exports.resetDynamicTime = () => {
11 | let values = [Math.round(new Date().getTime() / 1000)];
12 | sql.updateAllUPNoticeTime(values);
13 | }
14 |
15 | // 开始运行直播爬虫
16 | exports.startLivingSpider = async (bot) => {
17 | let rooms = {};
18 |
19 | //查询群组的全部订阅房间
20 | let values = [1];
21 | await sql.selectGroupRoomTospider(values).then(rows => {
22 | rows.forEach(row => {
23 | rooms[row.AID] = row.Live_Start_Time;
24 | });
25 | })
26 | //查询群组的直播订阅房间
27 | values = [2];
28 | await sql.selectGroupRoomTospider(values).then(rows => {
29 | rows.forEach(row => {
30 | rooms[row.AID] = row.Live_Start_Time;
31 | });
32 | })
33 | //查询个人的全部订阅房间
34 | values = [1];
35 | await sql.selectPersonRoomTospider(values).then(rows => {
36 | rows.forEach(row => {
37 | rooms[row.AID] = row.Live_Start_Time;
38 | });
39 | })
40 | //查询个人的直播订阅房间
41 | values = [2];
42 | await sql.selectPersonRoomTospider(values).then(rows => {
43 | rows.forEach(row => {
44 | rooms[row.AID] = row.Live_Start_Time;
45 | });
46 | })
47 |
48 | //开始爬取房间
49 | searchLivingRooms(bot, rooms);
50 | }
51 |
52 | async function searchLivingRooms(bot, rooms) {
53 | for (let AID in rooms) {
54 | // 每隔三秒爬取一次防止被限制
55 | await sleep(3000).then(() => {
56 | searchLivingRoom(bot, AID, rooms[AID]);
57 | })
58 | };
59 | }
60 |
61 | // 爬取直播间状态
62 | async function searchLivingRoom(bot, AID, lastStartTime) {
63 | let data = null;
64 | url = `https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?room_id=${AID}`;
65 | await axios.get(url, {
66 | headers: {
67 | 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
68 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
69 | }
70 | }).then(res => {
71 | data = res.data;
72 | })
73 | // 房间号错误直接返回
74 | if (data.code === -400) return;
75 |
76 | data = data.data;
77 | let live_status = data.room_info.live_status;
78 | let start_time = data.room_info.live_start_time;
79 | //正在直播且之前未查询过
80 | if (live_status === 1 && start_time !== lastStartTime) {
81 | let values = [start_time, AID];
82 | // 更新直播开始时间
83 | sql.updateUPLiveTime(values);
84 | // 根据不同的订阅类型发送消息
85 | values = [AID, 1];
86 | sql.selectGroupByAID(values).then(rows => {
87 | rows.forEach(row => {
88 | handleGroupLiving(bot, data, row.Group_Number);
89 | });
90 | })
91 | values = [AID, 2];
92 | sql.selectGroupByAID(values).then(rows => {
93 | rows.forEach(row => {
94 | handleGroupLiving(bot, data, row.Group_Number);
95 | });
96 | })
97 | values = [AID, 1];
98 | sql.selectPersonByAID(values).then(rows => {
99 | rows.forEach(row => {
100 | handlePersonLiving(bot, data, row.Person_Number);
101 | });
102 | })
103 | values = [AID, 2];
104 | sql.selectPersonByAID(values).then(rows => {
105 | rows.forEach(row => {
106 | handlePersonLiving(bot, data, row.Person_Number);
107 | });
108 | })
109 | }
110 | }
111 |
112 | // 发送群组消息
113 | function handleGroupLiving(bot, data, groupID) {
114 | try {
115 | let room = data.room_info;
116 | let UP = data.anchor_info.base_info.uname;
117 | let msg = `你关注的${UP}开播啦!${room.title},地址:https://live.bilibili.com/${room.room_id}`;
118 | bot.sendGroupMessage(msg, groupID);
119 | } catch (error) {
120 | }
121 | }
122 |
123 | //发送个人消息
124 | function handlePersonLiving(bot, data, PersonID) {
125 | try {
126 | let room = data.room_info;
127 | let UP = data.anchor_info.base_info.uname;
128 | let msg = `你关注的${UP}开播啦!${room.title},地址:https://live.bilibili.com/${room.room_id}`;
129 | bot.sendFriendMessage(msg, PersonID);
130 | } catch (error) {
131 | }
132 | }
133 |
134 | // 动态爬虫模块
135 | // 开始运行动态爬虫
136 | exports.startDynamicSpider = async (bot) => {
137 | let UPS = {};
138 |
139 | //查询群组的全部订阅
140 | let values = [1];
141 | await sql.selectGroupDynamicTospider(values).then(rows => {
142 | rows.forEach(row => {
143 | UPS[row.UID] = row.Last_Notice_Time;
144 | });
145 | })
146 | //查询群组的订阅动态
147 | values = [3];
148 | await sql.selectGroupDynamicTospider(values).then(rows => {
149 | rows.forEach(row => {
150 | UPS[row.UID] = row.Last_Notice_Time;
151 | });
152 | })
153 | //查询个人的全部订阅
154 | values = [1];
155 | await sql.selectPersonDynamicTospider(values).then(rows => {
156 | rows.forEach(row => {
157 | UPS[row.UID] = row.Last_Notice_Time;
158 | });
159 | })
160 | //查询个人的动态订阅
161 | values = [3];
162 | await sql.selectPersonDynamicTospider(values).then(rows => {
163 | rows.forEach(row => {
164 | UPS[row.UID] = row.Last_Notice_Time;
165 | });
166 | })
167 |
168 | //开始爬取动态
169 | searchNewDynamics(bot, UPS);
170 | }
171 |
172 | async function searchNewDynamics(bot, UPS) {
173 | for (let UID in UPS) {
174 | await sleep(3000).then(() => {
175 | searchNewDynamic(bot, UID, UPS[UID]);
176 | })
177 | };
178 | }
179 |
180 | // 爬取动态
181 | async function searchNewDynamic(bot, UID, lastNociceTime) {
182 | let data = null;
183 | url = `https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history?host_uid=${UID}`;
184 | await axios.get(url, {
185 | headers: {
186 | 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
187 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
188 | }
189 | }).then(res => {
190 | data = res.data.data;
191 | })
192 |
193 | // 如果有cards属性的话
194 | if (data.cards) {
195 | for (var i = 0; i < data.cards.length; i++) {
196 | let desc = data.cards[i].desc;
197 | let card = data.cards[i].card;
198 | let dynamicTime = desc.timestamp;
199 | if (dynamicTime > lastNociceTime) {
200 | let msg = processDynamic(desc, card);
201 | handleDynamicMessage(bot, msg, UID);
202 |
203 | // 更新动态查看时间
204 | let values = [Math.round(new Date().getTime() / 1000), UID];
205 | sql.updateUPNoticeTime(values);
206 | } else {
207 | break;
208 | }
209 | }
210 | }
211 | }
212 |
213 | // 根据动态的代码处理动态
214 | function processDynamic(desc, card) {
215 | // exports.processDynamic = (desc, card) => {
216 | card = JSON.parse(card);
217 | let dyamic_id = desc.dynamic_id_str;
218 | let type = desc.type;
219 | let uname = desc.user_profile.info.uname;
220 | let content = null;
221 | let res = "";
222 |
223 | // 转发动态
224 | if (type == 1) {
225 | let pre_dy_id = desc.pre_dy_id_str;
226 | let orig_type = desc.orig_type;
227 | content = card.item.content;
228 | // 转发带有图片的原创动态
229 | if (orig_type == 2) {
230 | res = `${uname}转发了动态:\nURL:https://t.bilibili.com/${dyamic_id}\n${content}`;
231 | let origin = JSON.parse(card.origin);
232 | let description = origin.item.description;
233 | let origin_name = origin.user.name;
234 | res = `${res}\n${origin_name}:\n${description}\nURL:https://t.bilibili.com/${pre_dy_id}`;
235 | }
236 | // 转发原创纯文字动态
237 | else if (orig_type == 4) {
238 | res = `${uname}转发了动态:\nURL:https://t.bilibili.com/${dyamic_id}\n${content}`;
239 | let origin = JSON.parse(card.origin);
240 | let origin_name = origin.user.uname;
241 | let origin_content = origin.item.content;
242 | res = `${res}\n${origin_name}:\n${origin_content}\nURL:https://t.bilibili.com/${pre_dy_id}`;
243 | }
244 | // 转发视频
245 | else if (orig_type == 8) {
246 | res = `${uname}转发了视频:\nURL:https://t.bilibili.com/${dyamic_id}\n${content}`;
247 | let origin = JSON.parse(card.origin);
248 | let aid = origin.aid;
249 | let title = origin.title;
250 | res = `${res}\n${title}\nURL:https://www.bilibili.com/video/av${aid}`;
251 | }
252 | // 转发直播间
253 | else if (orig_type == 4200) {
254 | res = `${uname}转发了直播间:\nURL:https://t.bilibili.com/${dyamic_id}\n${content}`;
255 | let origin = JSON.parse(card.origin);
256 | let rid = origin.roomid;
257 | let title = origin.title;
258 | res = `${res}\n${title} URL:https://live.bilibili.com/${rid}`;
259 | }
260 | // 转发专栏
261 | else if (orig_type == 64) {
262 | res = `${uname} 转发了专栏:\nURL:https://t.bilibili.com/${dyamic_id}\n${content}`;
263 | let origin = JSON.parse(card.origin);
264 | let rid = origin.id;
265 | let title = origin.title;
266 | res = `${res}\n${title}\nURL:https://www.bilibili.com/read/cv${rid}`;
267 | }
268 | // 转发收藏夹
269 | else if (orig_type == 4300) {
270 | res = `${uname}转发了收藏夹:\nURL:https://t.bilibili.com/${dyamic_id}\n${content}`;
271 | }
272 | // 转发发表使用挂件的动态
273 | else if (orig_type == 2048) {
274 | res = `${uname}转发了动态:\nURL:https://t.bilibili.com/${dyamic_id}\n${content}`;
275 | let origin = JSON.parse(card.origin);
276 | let origin_content = origin.vest.content;
277 | res = `${res}\n${origin_content}\nURL:https://t.bilibili.com/${pre_dy_id}`;
278 | }
279 | // 转发原动态已失效
280 | else if (orig_type == 1024) {
281 | res = `${uname}转发了动态:\nURL:https://t.bilibili.com/${dyamic_id}\n${content}`;
282 | let tips = card.item.tips;
283 | res = `${res}\nURL:https://t.bilibili.com/${dyamic_id}\n${tips}`;
284 | }
285 | }
286 | // 原创图片动态
287 | else if (type == 2) {
288 | description = card.item.description;
289 | res = `${uname}发表了新动态:\n${description}\nURL:https://t.bilibili.com/${dyamic_id}`;
290 | }
291 | // 原创文字动态
292 | else if (type == 4) {
293 | console.log(typeof card.item);
294 | content = card.item.content;
295 | res = `${uname}发表了新动态:\n${content}\nURL:https://t.bilibili.com/${dyamic_id}`;
296 | }
297 | // 发表视频
298 | else if (type == 8) {
299 | BVID = desc.bvid;
300 | title = card.title;
301 | res = `${uname}发表了新视频:\n${title}\nURL:https://www.bilibili.com/video/${BVID}`;
302 | }
303 | // 发表使用挂件的动态
304 | else if (type == 2048) {
305 | content = card.vest.content;
306 | res = `${uname}发表了新动态:\n${content}\nURL:https://t.bilibili.com/${dyamic_id}`;
307 | }
308 | // 发表专栏
309 | else if (type == 64) {
310 | title = card.title;
311 | rid = card.id;
312 | res = `${uname}发表了新的专栏:\n${title}\nURL:https://www.bilibili.com/read/cv${rid}`;
313 | }
314 | return res;
315 | }
316 |
317 | // 发送新动态消息
318 | function handleDynamicMessage(bot, msg, UID) {
319 | let values = [UID, 1];
320 | sql.selectGroupByUID(values).then(rows => {
321 | rows.forEach(row => {
322 | bot.sendGroupMessage(msg, row.Group_Number);
323 | });
324 | })
325 | values = [UID, 3];
326 | sql.selectGroupByUID(values).then(rows => {
327 | rows.forEach(row => {
328 | bot.sendGroupMessage(msg, row.Group_Number);
329 | });
330 | })
331 | values = [UID, 1];
332 | sql.selectPersonByUID(values).then(rows => {
333 | rows.forEach(row => {
334 | bot.sendFriendMessage(msg, row.Person_Number);
335 | });
336 | })
337 | values = [UID, 3];
338 | sql.selectPersonByUID(values).then(rows => {
339 | rows.forEach(row => {
340 | bot.sendFriendMessage(msg, row.Person_Number);
341 | });
342 | })
343 | }
--------------------------------------------------------------------------------
/scripts/sql.js:
--------------------------------------------------------------------------------
1 | const sqlite3 = require("sqlite3").verbose();
2 | console.log("Opened database successfully")
3 |
4 | // 创建一个执行sql语句的promise函数
5 | let query = (sql, values) => {
6 | return new Promise((resolve, reject) => {
7 | let db = new sqlite3.Database('./database/robot.db');
8 | var stmt = db.prepare(sql);
9 | stmt.all(values, (err, rows) => {
10 | if (err)
11 | reject(err);
12 | else {
13 | resolve(rows);
14 | }
15 | });
16 | stmt.finalize();
17 | db.close();
18 | })
19 | }
20 |
21 | // 创建up主表
22 | let UP = `CREATE TABLE IF NOT EXISTS UP
23 | (UID TEXT PRIMARY KEY NOT NULL,
24 | Name TEXT NOT NULL,
25 | AID TEXT,
26 | Live_Status TEXT NOT NULL,
27 | Last_Notice_Time INTEGER,
28 | Live_Start_Time INTEGER NOT NULL);`;
29 |
30 | // 创建群关注up主表
31 | // Sub_Type:1为直播&动态订阅,2为直播订阅,3为动态订阅
32 | let subGroup = `CREATE TABLE IF NOT EXISTS subGroup
33 | (UID TEXT NOT NULL,
34 | Group_Number TEXT NOT NULL,
35 | Sub_Type INTEGER,
36 | PRIMARY KEY(UID,Group_Number));`;
37 |
38 | // 创建个人关注up主表
39 | let subPerson = `CREATE TABLE IF NOT EXISTS subPerson
40 | (UID TEXT NOT NULL,
41 | Person_Number TEXT NOT NULL,
42 | Sub_Type INTEGER,
43 | PRIMARY KEY(UID,Person_Number));`
44 |
45 | // 创建关键词回复表
46 | let keyWords = `CREATE TABLE IF NOT EXISTS keyWords
47 | (Group_Number TEXT NOT NULL,
48 | Key_Word TEXT NOT NULL,
49 | Repair_Word TEXT NOT NULL,
50 | Key_Type INTEGER NOT NULL,
51 | PRIMARY KEY(Key_Word,Group_Number));`;
52 |
53 | // 创建群组@回复词表
54 | let atWords = `CREATE TABLE IF NOT EXISTS atWords
55 | (atWordID INTEGER PRIMARY KEY AUTOINCREMENT,
56 | At_Word TEXT NOT NULL);`;
57 |
58 | // 创建ban复读群组表
59 | let repeatBan = `CREATE TABLE IF NOT EXISTS repeatBan
60 | (Group_Number INTEGER PRIMARY KEY);`;
61 |
62 | // 创建todolist表
63 | let todos = `CREATE TABLE IF NOT EXISTS todos
64 | (todoID INTEGER PRIMARY KEY AUTOINCREMENT,
65 | todo_text TEXT NOT NULL,
66 | Group_Number TEXT NOT NULL,
67 | todo_time INTEGER);`;
68 |
69 | // 创建表
70 | let createTable = (sql) => {
71 | return query(sql, []);
72 | };
73 |
74 | createTable(UP);
75 | createTable(subGroup);
76 | createTable(subPerson);
77 | createTable(keyWords);
78 | createTable(atWords);
79 | createTable(repeatBan);
80 | createTable(todos);
81 |
82 | // 关键词模块
83 | // 给某个群添加关键词
84 | exports.addKeyWords = (values) => {
85 | let _sql = `INSERT INTO keyWords (Group_Number,Key_Word,Repair_Word,Key_Type) VALUES (?,?,?,?)`;
86 | return query(_sql, values);
87 | }
88 |
89 | // 查询某个群是否有某个关键词
90 | exports.selectOneKeyWords = (values) => {
91 | let _sql = `SELECT * FROM keyWords WHERE Group_Number=? AND Key_Word=?;`;
92 | return query(_sql, values);
93 | }
94 |
95 | // 查询一个群全部的精确或模糊关键词
96 | exports.selectKeyWords = (values) => {
97 | let _sql = `SELECT Key_Word, Repair_Word FROM keyWords WHERE Group_Number=? AND Key_Type=?;`;
98 | return query(_sql, values);
99 | }
100 |
101 | // 更新某个群的某个关键词的类型
102 | exports.updateKeyWords = (values) => {
103 | let _sql = `UPDATE keyWords SET Key_Type=? WHERE Group_Number=? AND Key_Word=?;`;
104 | return query(_sql, values);
105 | }
106 |
107 | // 删除某个群的某个关键词
108 | exports.deleteKeyWords = (values) => {
109 | let _sql = `DELETE FROM keyWords WHERE Group_Number=? AND Key_Word=?;`;
110 | return query(_sql, values);
111 | }
112 |
113 |
114 | // UP模块
115 | // 添加一个UP主
116 | exports.addUP = (values) => {
117 | let _sql = `INSERT INTO UP (UID,Name,AID,Live_Status,Live_Start_Time,Last_Notice_Time) VALUES (?,?,?,?,?,?);`;
118 | return query(_sql, values);
119 | }
120 |
121 | // 根据ID查询某个UP主的信息
122 | exports.selectUP = (values) => {
123 | let _sql = `SELECT * FROM UP WHERE UID=?;`;
124 | return query(_sql, values);
125 | }
126 |
127 | // 根据ID修改某个UP主的全部信息
128 | exports.updateUP = (values) => {
129 | let _sql = `UPDATE UP SET Name=?,AID=?,Live_Status=?,Dynamic_ID_Str=?,Live_Start_Time=?,Last_Notice_Time=? WHERE UID=?;`;
130 | return query(_sql, values);
131 | }
132 |
133 | // 根据ID修改上一次爬取某个UP主动态的时间
134 | exports.updateUPNoticeTime = (values) => {
135 | let _sql = `UPDATE UP SET Last_Notice_Time=? WHERE UID=?;`;
136 | return query(_sql, values);
137 | }
138 |
139 | // 重置所有UP主的爬取动态时间
140 | exports.updateAllUPNoticeTime = (values) => {
141 | let _sql = `UPDATE UP SET Last_Notice_Time=?;`;
142 | return query(_sql, values);
143 | }
144 |
145 | // 根据AID修改上一次某个UP主开始直播的时间
146 | exports.updateUPLiveTime = (values) => {
147 | let _sql = `UPDATE UP SET Live_Start_Time=? WHERE AID=?;`;
148 | return query(_sql, values);
149 | }
150 |
151 | //删除某个UP主
152 | exports.deleteUP = (values) => {
153 | let _sql = `DELETE FROM UP WHERE UID=?;`;
154 | return query(_sql, values);
155 | }
156 |
157 |
158 | // 个人关注模块
159 | // 添加个人关注
160 | exports.addPersonSub = (values) => {
161 | let _sql = `INSERT INTO subPerson (UID, Person_Number,Sub_Type) VALUES (?,?,?);`;
162 | return query(_sql, values);
163 | }
164 |
165 | // 查询某个个人对某个UP主的关注
166 | exports.selectPersonOneSub = (values) => {
167 | let _sql = `SELECT subPerson.Sub_Type,UP.Name FROM subPerson,UP
168 | WHERE subPerson.UID=? AND subPerson.UID=UP.UID AND Person_Number=?;`;
169 | return query(_sql, values);
170 | }
171 |
172 | // 查询某个人的全部关注
173 | exports.selectPersonAllSub = (values) => {
174 | let _sql = `SELECT * FROM subPerson WHERE UID=? AND Person_Number=?;`;
175 | return query(_sql, values);
176 | }
177 |
178 | // 查询某个群组的全部关注并获取UP主信息
179 | exports.selectPersonAllSubInfoByType = (values) => {
180 | let _sql = `SELECT UP.UID,UP.Name FROM subPerson,UP
181 | WHERE subPerson.Person_Number=? AND subPerson.UID=UP.UID AND Sub_Type=?;`;
182 | return query(_sql, values);
183 | }
184 |
185 | // 查询某个群组的全部直播或动态的关注
186 | exports.selectPersonSubByType = (values) => {
187 | let _sql = `SELECT * FROM subPerson WHERE UID=? AND Person_Number=? AND Sub_Type=?;`;
188 | return query(_sql, values);
189 | }
190 |
191 | // 查询某个人的全部直播或动态的关注
192 | exports.selectPersonSubByType = (values) => {
193 | let _sql = `SELECT * FROM subPerson WHERE UID=? AND Person_Number=? AND Sub_Type=?;`;
194 | return query(_sql, values);
195 | }
196 |
197 | // 修改某个人对某个UP的关注种类
198 | exports.updatePersonSubType = (values) => {
199 | let _sql = `UPDATE subPerson SET Sub_Type=? WHERE UID=? AND Person_Number=?;`;
200 | return query(_sql, values);
201 | }
202 |
203 | // 删除某个人对某个UP的关注
204 | exports.deletePersonSub = (values) => {
205 | let _sql = `DELETE FROM subPerson WHERE UID=? AND Person_Number=?;`;
206 | return query(_sql, values);
207 | }
208 |
209 |
210 | // 群组关注模块
211 | // 添加群组关注
212 | exports.addGroupSub = (values) => {
213 | let _sql = `INSERT INTO subGroup (UID, Group_Number,Sub_Type) VALUES (?,?,?);`;
214 | return query(_sql, values);
215 | }
216 |
217 | // 查询某个群组对某个UP主的关注
218 | exports.selectGroupOneSub = (values) => {
219 | let _sql = `SELECT subGroup.Sub_Type,UP.Name FROM subGroup,UP
220 | WHERE subGroup.UID=? AND subGroup.UID=UP.UID AND Group_Number=?;`;
221 | return query(_sql, values);
222 | }
223 |
224 | // 查询某个群组的全部关注
225 | exports.selectGroupAllSub = (values) => {
226 | let _sql = `SELECT * FROM subGroup WHERE Group_Number=?;`;
227 | return query(_sql, values);
228 | }
229 |
230 | // 查询某个群组的全部关注并获取UP主信息
231 | exports.selectGroupAllSubInfoByType = (values) => {
232 | let _sql = `SELECT UP.UID,UP.Name FROM subGroup,UP
233 | WHERE subGroup.Group_Number=? AND subGroup.UID=UP.UID AND Sub_Type=?;`;
234 | return query(_sql, values);
235 | }
236 |
237 | // 查询某个群组的全部直播或动态的关注
238 | exports.selectGroupSubByType = (values) => {
239 | let _sql = `SELECT * FROM subGroup WHERE UID=? AND Group_Number=? AND Sub_Type=?;`;
240 | return query(_sql, values);
241 | }
242 |
243 | // 修改某个群组对某个UP的关注种类
244 | exports.updateGroupSubType = (values) => {
245 | let _sql = `UPDATE subGroup SET Sub_Type=? WHERE UID=? AND Group_Number=?;`;
246 | return query(_sql, values);
247 | }
248 |
249 | // 删除某个群组对某个UP的关注
250 | exports.deleteGroupSub = (values) => {
251 | let _sql = `DELETE FROM subGroup WHERE UID=? AND Group_Number=?;`;
252 | return query(_sql, values);
253 | }
254 |
255 |
256 | // bilbili爬虫模块
257 | // 查询群组关注中需要爬取的房间
258 | exports.selectGroupRoomTospider = (values) => {
259 | let _sql = "SELECT AID,Live_Start_Time FROM UP,subGroup WHERE subGroup.UID=UP.UID AND subGroup.Sub_Type=?;";
260 | return query(_sql, values);
261 | }
262 |
263 | // 查询个人关注中需要爬取的房间
264 | exports.selectPersonRoomTospider = (values) => {
265 | let _sql = "SELECT AID,Live_Start_Time FROM UP,subPerson WHERE subPerson.UID=UP.UID AND subPerson.Sub_Type=?;";
266 | return query(_sql, values);
267 | }
268 |
269 | // 根据房间号和类型查找订阅的群组
270 | exports.selectGroupByAID = (values) => {
271 | let _sql = "SELECT Group_Number FROM subGroup,UP WHERE UP.UID=subGroup.UID AND UP.AID=? AND subGroup.Sub_Type=?;";
272 | return query(_sql, values);
273 | }
274 |
275 | // 根据房间号和类型查找订阅的个人
276 | exports.selectPersonByAID = (values) => {
277 | let _sql = "SELECT Person_Number FROM subPerson,UP WHERE UP.UID=subPerson.UID AND UP.AID=? AND subPerson.Sub_Type=?;";
278 | return query(_sql, values);
279 | }
280 |
281 | // 查询群组关注中需要爬取动态的UP主
282 | exports.selectGroupDynamicTospider = (values) => {
283 | let _sql = "SELECT UP.UID,Last_Notice_Time FROM UP,subGroup WHERE subGroup.UID=UP.UID AND subGroup.Sub_Type=?;";
284 | return query(_sql, values);
285 | }
286 |
287 | // 查询个人关注中需要爬取动态的UP主
288 | exports.selectPersonDynamicTospider = (values) => {
289 | let _sql = "SELECT UP.UID,Last_Notice_Time FROM UP,subPerson WHERE subPerson.UID=UP.UID AND subPerson.Sub_Type=?;";
290 | return query(_sql, values);
291 | }
292 |
293 | // 根据UID和类型查找订阅的群组
294 | exports.selectGroupByUID = (values) => {
295 | let _sql = "SELECT Group_Number FROM subGroup,UP WHERE UP.UID=subGroup.UID AND UP.UID=? AND subGroup.Sub_Type=?;";
296 | return query(_sql, values);
297 | }
298 |
299 | // 根据房间号和类型查找订阅的个人
300 | exports.selectPersonByUID = (values) => {
301 | let _sql = "SELECT Person_Number FROM subPerson,UP WHERE UP.UID=subPerson.UID AND UP.UID=? AND subPerson.Sub_Type=?;";
302 | return query(_sql, values);
303 | }
304 |
305 |
306 | // @bot回复词模块
307 | // 添加@bot后的回复词
308 | exports.addAtWords = (values) => {
309 | let _sql = `INSERT INTO atWords (At_Word) VALUES (?);`;
310 | return query(_sql, values);
311 | }
312 |
313 | // 查询全部的@bot回复词
314 | exports.selectAllAtWords = (values) => {
315 | let _sql = `SELECT * FROM atWords;`;
316 | return query(_sql, values);
317 | }
318 |
319 |
320 | // 复读模块
321 | // 添加群组复读
322 | exports.addGroupBanRepeat = (values) => {
323 | let _sql = `INSERT INTO repeatBan (Group_Number) VALUES (?);`;
324 | return query(_sql, values);
325 | }
326 |
327 | // 查询某个群组是否关闭复读
328 | exports.selectGroupBanRepeat = (values) => {
329 | let _sql = `SELECT * FROM repeatBan WHERE Group_Number=?;`;
330 | return query(_sql, values);
331 | }
332 |
333 | // 删除群组复读
334 | exports.deleteGroupBanRepeat = (values) => {
335 | let _sql = `DELETE FROM repeatBan WHERE Group_Number=?;`;
336 | return query(_sql, values);
337 | }
338 |
339 |
340 | // 其它模块
341 | // 查询某个UP主是否有关注的人
342 | exports.selectPersonSubByUP = (values) => {
343 | let _sql = `select * FROM subPerson WHERE UID=?;`;
344 | return query(_sql, values);
345 | }
346 |
347 | // 查询某个UP主是否有关注的群组
348 | exports.selectGroupSubByUP = (values) => {
349 | let _sql = `select * FROM subGroup WHERE UID=?;`;
350 | return query(_sql, values);
351 | }
352 |
353 | // todo模块
354 | // 添加todo
355 | exports.addTodo = (values) => {
356 | const _sql = `INSERT INTO todos (todo_text, Group_Number, todo_time) VALUES (?,?,?)`;
357 | return query(_sql, values);
358 | }
359 |
360 | // 查询某个todo
361 | exports.selectOneTodo = (values) => {
362 | const _sql = `SELECT * FROM todos WHERE todoID=?;`;
363 | return query(_sql, values)
364 | }
365 |
366 | // 查询todo
367 | exports.selectTodo = (values) => {
368 | const _sql = `SELECT * FROM todos WHERE Group_Number=? ORDER BY todo_time;`;
369 | return query(_sql, values);
370 | }
371 |
372 | // 分页查询todo
373 | exports.selectLimitTodo = (values) => {
374 | const _sql = `SELECT * FROM todos WHERE Group_Number=? ORDER BY todo_time LIMIT ?, ?;`;
375 | return query(_sql, values);
376 | }
377 |
378 | // 完成todo
379 | exports.deleteTodo = (values) => {
380 | const _sql = `DELETE FROM todos WHERE todoID=?;`;
381 | return query(_sql, values);
382 | }
383 |
384 | // 完成所有的todo
385 | exports.deleteAllTodo = (values) => {
386 | const _sql = `DELETE FROM todos WHERE Group_Number=?;`;
387 | return query(_sql, values);
388 | }
--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
1 | const sql = require("./scripts/sql.js");
2 | const middleWare = require("./scripts/middleWare.js");
3 |
4 | // let values = ["测试15", "114514", 1623700613591];
5 | // // console.log(values);
6 | // sql.addTodo(values).then((res) => {
7 | // console.log(res);
8 | // })
9 |
10 | // let values = ["114514"];
11 | // sql.selectTodo(values).then((res) => {
12 | // console.log(res);
13 | // })
14 |
15 | // let values = [1];
16 | // sql.deleteTodo(values).then((res) => {
17 | // console.log(res);
18 | // })
19 |
20 | // middleWare.createTodo("测试45", "114514").then((res) => {
21 | // console.log(res);
22 | // })
23 |
24 | // middleWare.selectGroupTodo("114514").then((res) => {
25 | // console.log(res);
26 | // })
27 |
28 | // middleWare.completeTodo(4).then((res) => {
29 | // console.log(res);
30 | // })
31 |
32 | // let msg = "todo ceshi ceshi";
33 | // let instruct = msg.split(" ", 2);
34 | // console.log(msg.substring(instruct[0].length + 1));
35 |
36 | // let values = [2]
37 | // sql.selectOneTodo(values).then((res) => {
38 | // console.log(res);
39 | // })
40 |
--------------------------------------------------------------------------------