├── .github
└── workflows
│ └── gradle-publish.yml
├── .gitignore
├── .run
└── RunTerminal.run.xml
├── LICENSE
├── PS_FIle
├── background.png
└── background.psd
├── README.md
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
└── main
├── java
└── cn
│ └── travellerr
│ ├── AronaBot.java
│ ├── BlueArchive
│ ├── GetSentenceApi.java
│ ├── Jrrp.java
│ ├── Jrys.java
│ └── SqlUtil.java
│ ├── Initialize.java
│ ├── entity
│ ├── FortuneInfo.java
│ ├── SysInfo.java
│ └── UserInfo.java
│ ├── event
│ ├── Menu.java
│ └── MessageEventListener.java
│ ├── tools
│ ├── Api.java
│ ├── GFont.java
│ ├── Log.java
│ └── SecurityNew.java
│ ├── utils
│ └── HibernateUtil.java
│ └── websocket
│ ├── DownloadVoice.java
│ ├── VoiceGet.java
│ └── VoiceWebSocketClient.java
├── kotlin
└── cn
│ └── travellerr
│ ├── command
│ ├── CommandUtil.kt
│ └── RegCommand.kt
│ └── config
│ ├── Config.kt
│ ├── SqlConfig.kt
│ └── VoiceBlackList.kt
└── resources
├── META-INF
└── services
│ └── net.mamoe.mirai.console.plugin.jvm.JvmPlugin
├── background.png
├── data.json
├── fonts
└── 黑体.ttf
├── jrys
├── 0
│ └── 0
│ │ ├── 1.png
│ │ ├── 2.png
│ │ ├── 3.png
│ │ ├── 4.png
│ │ ├── 5.png
│ │ └── bg.png
├── 1
│ ├── 0
│ │ ├── 1.png
│ │ ├── 2.png
│ │ ├── 3.png
│ │ ├── 4.png
│ │ └── bg.png
│ ├── 1
│ │ ├── 1.png
│ │ ├── 2.png
│ │ ├── 3.png
│ │ ├── 4.png
│ │ ├── 5.png
│ │ └── bg.png
│ ├── 2
│ │ ├── 1.png
│ │ ├── 2.png
│ │ ├── 3.png
│ │ ├── 4.png
│ │ └── bg.png
│ └── 3
│ │ ├── 1.png
│ │ ├── 2.png
│ │ ├── 3.png
│ │ └── bg.png
├── 2
│ └── 0
│ │ ├── 1.png
│ │ ├── 2.png
│ │ ├── 3.png
│ │ ├── 4.png
│ │ └── bg.png
├── betterJrys.json
├── jrys.json
├── 基沃托斯
│ ├── SRT小队.png
│ └── 基沃托斯.png
└── 心奈印章
│ ├── 0_0.png
│ ├── 0_1.png
│ ├── 0_2.png
│ ├── 0_3.png
│ ├── 100.png
│ ├── 59.png
│ └── 60.png
└── pic.png
/.github/workflows/gradle-publish.yml:
--------------------------------------------------------------------------------
1 | # This workflow uses actions that are not certified by GitHub.
2 | # They are provided by a third-party and are governed by
3 | # separate terms of service, privacy policy, and support
4 | # documentation.
5 | # This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
6 | # For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
7 |
8 | name: Gradle Package
9 |
10 | on:
11 | release:
12 | types: [created]
13 |
14 | jobs:
15 | build:
16 |
17 | runs-on: ubuntu-latest
18 | permissions:
19 | contents: read
20 | packages: write
21 |
22 | steps:
23 | - uses: actions/checkout@v4
24 | - name: Set up JDK 17
25 | uses: actions/setup-java@v4
26 | with:
27 | java-version: '17'
28 | distribution: 'temurin'
29 | server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
30 | settings-path: ${{ github.workspace }} # location for the settings.xml file
31 |
32 | - name: Setup Gradle
33 | uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0
34 |
35 | - name: Build with Gradle
36 | run: ./gradlew build
37 |
38 | # The USERNAME and TOKEN need to correspond to the credentials environment variables used in
39 | # the publishing section of your build.gradle
40 | - name: Publish to GitHub Packages
41 | run: ./gradlew publish
42 | env:
43 | USERNAME: ${{ github.actor }}
44 | TOKEN: ${{ secrets.GITHUB_TOKEN }}
45 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # User-specific stuff
2 | .idea/
3 |
4 | *.iml
5 | *.ipr
6 | *.iws
7 |
8 | # IntelliJ
9 | out/
10 | # mpeltonen/sbt-idea plugin
11 | .idea_modules/
12 |
13 | # JIRA plugin
14 | atlassian-ide-plugin.xml
15 |
16 | # Compiled class file
17 | *.class
18 |
19 | # Log file
20 | *.log
21 |
22 | # BlueJ files
23 | *.ctxt
24 |
25 | # Package Files #
26 | *.jar
27 | *.war
28 | *.nar
29 | *.ear
30 | *.zip
31 | *.tar.gz
32 | *.rar
33 |
34 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
35 | hs_err_pid*
36 |
37 | *~
38 |
39 | # temporary files which can be created if a process still has a handle open of a deleted file
40 | .fuse_hidden*
41 |
42 | # KDE directory preferences
43 | .directory
44 |
45 | # Linux trash folder which might appear on any partition or disk
46 | .Trash-*
47 |
48 | # .nfs files are created when an open file is removed but is still being accessed
49 | .nfs*
50 |
51 | # General
52 | .DS_Store
53 | .AppleDouble
54 | .LSOverride
55 |
56 | # Icon must end with two \r
57 | Icon
58 |
59 | # Thumbnails
60 | ._*
61 |
62 | # Files that might appear in the root of a volume
63 | .DocumentRevisions-V100
64 | .fseventsd
65 | .Spotlight-V100
66 | .TemporaryItems
67 | .Trashes
68 | .VolumeIcon.icns
69 | .com.apple.timemachine.donotpresent
70 |
71 | # Directories potentially created on remote AFP share
72 | .AppleDB
73 | .AppleDesktop
74 | Network Trash Folder
75 | Temporary Items
76 | .apdisk
77 |
78 | # Windows thumbnail cache files
79 | Thumbs.db
80 | Thumbs.db:encryptable
81 | ehthumbs.db
82 | ehthumbs_vista.db
83 |
84 | # Dump file
85 | *.stackdump
86 |
87 | # Folder config file
88 | [Dd]esktop.ini
89 |
90 | # Recycle Bin used on file shares
91 | $RECYCLE.BIN/
92 |
93 | # Windows Installer files
94 | *.cab
95 | *.msi
96 | *.msix
97 | *.msm
98 | *.msp
99 |
100 | # Windows shortcuts
101 | *.lnk
102 |
103 | .gradle
104 | build/
105 |
106 | # Ignore Gradle GUI config
107 | gradle-app.setting
108 |
109 | # Cache of project
110 | .gradletasknamecache
111 |
112 | **/build/
113 |
114 | # Common working directory
115 | run/
116 |
117 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
118 | !gradle-wrapper.jar
119 |
120 |
121 | # Local Test Launch point
122 | src/test/kotlin/RunTerminal.kt
123 |
124 | # Mirai console files with direct bootstrap
125 | /config
126 | /data
127 | /plugins
128 | /bots
129 |
130 | # Local Test Launch Point working directory
131 | /debug-sandbox
132 |
--------------------------------------------------------------------------------
/.run/RunTerminal.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
16 |
17 |
18 | true
19 | true
20 | false
21 |
22 |
23 |
--------------------------------------------------------------------------------
/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
637 | by 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 | .
662 |
--------------------------------------------------------------------------------
/PS_FIle/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/PS_FIle/background.png
--------------------------------------------------------------------------------
/PS_FIle/background.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/PS_FIle/background.psd
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # 蔚蓝档案额外功能插件
4 | ## 指令
5 | 目前共四个指令
6 |
7 | 已接入 _**Mirai Console**_ 指令系统
8 |
9 | | 指令 | 功能 | 作用域 |
10 | |:-------------------------:|:----------------:|:------:|
11 | | `/今日运势` | 查看今日运势 | **所有** |
12 | | `/今日人品` | 查看今日人品值 | **所有** |
13 | | `/监控` | 查看服务器资源占用 | **所有** |
14 | | `/随机柴郡` | 获取随机柴郡表情包 | **所有** |
15 | | `/生成后缀 [名称] [后缀]` | 使用unicode码生成名字后缀 | **所有** |
16 | | `/语音生成 [角色] [文本]` | 调用蔚蓝档案语音生成 | **所有** |
17 | | `/语音生成 [角色] [文本] <中/日/英>` | 调用蔚蓝档案语音生成,自定义语言 | **所有** |
18 | | `/aronabot reload` | 重载配置文件 | **所有** |
19 |
20 | ## 权限节点
21 |
22 | 指令系统权限节点如下
23 |
24 | | **指令** | **权限节点** |
25 | |:------:|:----------------------------------------------:|
26 | | `今日运势` | `cn.travellerr.aronabot:command.jrys` |
27 | | `今日人品` | `cn.travellerr.aronabot:command.jrrp` |
28 | | `监控` | `cn.travellerr.aronabot:command.securityimage` |
29 | | `随机柴郡` | `cn.travellerr.aronabot:command.random-chaiq` |
30 | | `生成后缀` | `cn.travellerr.aronabot:command.generatename` |
31 | | `语音生成` | `cn.travellerr.aronabot:command.voice-gen` |
32 | | `重载配置` | `cn.travellerr.aronabot:command.aronabot` |
33 |
34 | ## 配置
35 |
36 | ```yaml
37 | # 是否启用文字输出运势
38 | isText: false
39 |
40 | # 本地字体目录,以mcl为主目录填写相对路径
41 | useLocalFont: ''
42 |
43 | # 是否启用语音合成
44 | useVoice: true
45 |
46 | # 语音合成模型地址
47 | url: 'travellerr11-ba-voice-models.hf.space'
48 |
49 | # 是否使用SilkConverter
50 | useSilk: false
51 |
52 | # ffmpeg地址,以mcl为主目录填写相对路径,若启用语音合成且不使用SilkConverter则必须填写ffmpeg路径
53 | ffmpegPath: ''
54 |
55 | ```
56 |
57 | ---
58 |
59 | ## 关于 `/今日人品` 指令
60 |
61 | 该指令与 `/今日运势` 指令 使用同一数据库,所以获取到的人品值应该是和运势挂钩的
62 |
63 | 如果当天已经使用过了 `/今日运势` 指令,那么 `/今日人品` 不会重新生成,而是直接获取之前的运势id,向101取余计算人品值
64 | 例如:
65 |
66 | | ID | QQ | FortuneID | Date |
67 | |----|-----------|-----------|---------------------|
68 | | 1 | 123456789 | 348 | 2024-05-14 21:51:30 |
69 | | 2 | 114514123 | 200 | 2024-03-23 18:13:27 |
70 | | 3 | 191981011 | 126 | 2024-07-02 19:36:03 |
71 |
72 | 分别将计算为
73 |
74 | | QQ | jrrpValue |
75 | |-----------|-----------|
76 | | 123456789 | 48 |
77 | | 114514123 | 100 |
78 | | 191981011 | 26 |
79 |
80 |
81 |
82 | ~~但是可能因为储存运势的文件没有经过排序,看起来没关系)~~
83 |
84 | 您可以通过将 `jrys.json` 按程度进行排序实现**真正的** `运势与人品关联
85 |
86 | 如果您做到了这点,希望能够将该文件PR到本仓库中
87 |
88 | ---
89 |
90 | ## 版本
91 |
92 | `Version = 1.1.1`
93 |
94 | ## 推广
95 | [我做的可自定义的好感度插件](https://github.com/Travellerrr/Favorability/)
96 |
97 | ---
98 |
99 | [](https://starchart.cc/Travellerrr/AronaBot)
100 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'org.jetbrains.kotlin.jvm' version '1.8.10'
3 | id 'org.jetbrains.kotlin.plugin.serialization' version '1.8.10'
4 |
5 | id 'net.mamoe.mirai-console' version '2.16.0'
6 | }
7 |
8 | group = 'cn.travellerr'
9 | version = '2.0.1'
10 |
11 | repositories {
12 | //maven { url 'https://maven.aliyun.com/repository/public' }
13 | maven { url 'https://maven.aliyun.com/repository/public' }
14 | mavenCentral()
15 | }
16 | dependencies {
17 | api "net.mamoe:mirai-silk-converter:0.0.5"
18 | implementation 'com.google.code.gson:gson:2.9.1'
19 | implementation group: 'cn.hutool', name: 'hutool-all', version: '5.8.25'
20 | implementation 'com.github.oshi:oshi-core:3.5.0'
21 | implementation 'org.jfree:jfreechart:1.5.3'
22 | implementation 'org.java-websocket:Java-WebSocket:1.5.5'
23 | implementation 'com.alibaba:fastjson:2.0.9.graal'
24 |
25 | implementation 'org.xerial:sqlite-jdbc:3.44.1.0'
26 |
27 | // 重构版使用hibernate操作数据库
28 | implementation("cn.chahuyun:hibernate-plus:1.0.16")
29 |
30 |
31 | implementation("org.projectlombok:lombok:1.18.24")
32 | annotationProcessor("org.projectlombok:lombok:1.18.24")
33 | }
34 | mirai {
35 | jvmTarget JavaVersion.VERSION_11
36 | }
37 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | kotlin.code.style=official
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
84 |
85 | APP_NAME="Gradle"
86 | APP_BASE_NAME=${0##*/}
87 |
88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
90 |
91 | # Use the maximum available, or set MAX_FD != -1 to use that value.
92 | MAX_FD=maximum
93 |
94 | warn () {
95 | echo "$*"
96 | } >&2
97 |
98 | die () {
99 | echo
100 | echo "$*"
101 | echo
102 | exit 1
103 | } >&2
104 |
105 | # OS specific support (must be 'true' or 'false').
106 | cygwin=false
107 | msys=false
108 | darwin=false
109 | nonstop=false
110 | case "$( uname )" in #(
111 | CYGWIN* ) cygwin=true ;; #(
112 | Darwin* ) darwin=true ;; #(
113 | MSYS* | MINGW* ) msys=true ;; #(
114 | NONSTOP* ) nonstop=true ;;
115 | esac
116 |
117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
118 |
119 |
120 | # Determine the Java command to use to start the JVM.
121 | if [ -n "$JAVA_HOME" ] ; then
122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
123 | # IBM's JDK on AIX uses strange locations for the executables
124 | JAVACMD=$JAVA_HOME/jre/sh/java
125 | else
126 | JAVACMD=$JAVA_HOME/bin/java
127 | fi
128 | if [ ! -x "$JAVACMD" ] ; then
129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
130 |
131 | Please set the JAVA_HOME variable in your environment to match the
132 | location of your Java installation."
133 | fi
134 | else
135 | JAVACMD=java
136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 |
142 | # Increase the maximum file descriptors if we can.
143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
144 | case $MAX_FD in #(
145 | max*)
146 | MAX_FD=$( ulimit -H -n ) ||
147 | warn "Could not query maximum file descriptor limit"
148 | esac
149 | case $MAX_FD in #(
150 | '' | soft) :;; #(
151 | *)
152 | ulimit -n "$MAX_FD" ||
153 | warn "Could not set maximum file descriptor limit to $MAX_FD"
154 | esac
155 | fi
156 |
157 | # Collect all arguments for the java command, stacking in reverse order:
158 | # * args from the command line
159 | # * the main class name
160 | # * -classpath
161 | # * -D...appname settings
162 | # * --module-path (only if needed)
163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
164 |
165 | # For Cygwin or MSYS, switch paths to Windows format before running java
166 | if "$cygwin" || "$msys" ; then
167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
169 |
170 | JAVACMD=$( cygpath --unix "$JAVACMD" )
171 |
172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
173 | for arg do
174 | if
175 | case $arg in #(
176 | -*) false ;; # don't mess with options #(
177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
178 | [ -e "$t" ] ;; #(
179 | *) false ;;
180 | esac
181 | then
182 | arg=$( cygpath --path --ignore --mixed "$arg" )
183 | fi
184 | # Roll the args list around exactly as many times as the number of
185 | # args, so each arg winds up back in the position where it started, but
186 | # possibly modified.
187 | #
188 | # NB: a `for` loop captures its iteration list before it begins, so
189 | # changing the positional parameters here affects neither the number of
190 | # iterations, nor the values presented in `arg`.
191 | shift # remove old arg
192 | set -- "$@" "$arg" # push replacement arg
193 | done
194 | fi
195 |
196 | # Collect all arguments for the java command;
197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
198 | # shell script including quotes and variable substitutions, so put them in
199 | # double quotes to make sure that they get re-expanded; and
200 | # * put everything else in single quotes, so that it's not re-expanded.
201 |
202 | set -- \
203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
204 | -classpath "$CLASSPATH" \
205 | org.gradle.wrapper.GradleWrapperMain \
206 | "$@"
207 |
208 | # Use "xargs" to parse quoted args.
209 | #
210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
211 | #
212 | # In Bash we could simply go:
213 | #
214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
215 | # set -- "${ARGS[@]}" "$@"
216 | #
217 | # but POSIX shell has neither arrays nor command substitution, so instead we
218 | # post-process each arg (as a line of input to sed) to backslash-escape any
219 | # character that might be a shell metacharacter, then use eval to reverse
220 | # that process (while maintaining the separation between arguments), and wrap
221 | # the whole thing up as a single "set" statement.
222 | #
223 | # This will of course break if any of these variables contains a newline or
224 | # an unmatched quote.
225 | #
226 |
227 | eval "set -- $(
228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
229 | xargs -n1 |
230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
231 | tr '\n' ' '
232 | )" '"$@"'
233 |
234 | exec "$JAVACMD" "$@"
235 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | maven { url "https://maven.aliyun.com/repository/gradle-plugin" }
4 | gradlePluginPortal()
5 | }
6 | }
7 | rootProject.name = "AronaBot"
8 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/AronaBot.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr;
2 |
3 | import cn.travellerr.command.RegCommand;
4 | import cn.travellerr.config.Config;
5 | import cn.travellerr.config.SqlConfig;
6 | import cn.travellerr.config.VoiceBlackList;
7 | import cn.travellerr.event.Menu;
8 | import cn.travellerr.event.MessageEventListener;
9 | import cn.travellerr.tools.GFont;
10 | import cn.travellerr.tools.Log;
11 | import cn.travellerr.utils.HibernateUtil;
12 | import net.mamoe.mirai.console.plugin.jvm.JavaPlugin;
13 | import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescriptionBuilder;
14 | import net.mamoe.mirai.event.Event;
15 | import net.mamoe.mirai.event.EventChannel;
16 | import net.mamoe.mirai.event.GlobalEventChannel;
17 | import net.mamoe.mirai.event.events.BotJoinGroupEvent;
18 | import net.mamoe.mirai.event.events.FriendAddEvent;
19 | import net.mamoe.mirai.event.events.FriendMessagePostSendEvent;
20 | import net.mamoe.mirai.event.events.GroupMessagePostSendEvent;
21 |
22 | public final class AronaBot extends JavaPlugin {
23 | public static final AronaBot INSTANCE = new AronaBot();
24 | /*插件版本*/
25 | public static final String version = "2.0.1";
26 |
27 | public static Config config;
28 | public static VoiceBlackList blackList;
29 | public static SqlConfig sqlConfig;
30 |
31 | public static String ffmpeg = null;
32 | public static long startTime = System.currentTimeMillis();
33 |
34 |
35 | public static long sendGroupMsgNum = 0;
36 | public static long sendFriendMsgNum = 0;
37 |
38 | private AronaBot() {
39 | super(new JvmPluginDescriptionBuilder("cn.travellerr.AronaBot", version)
40 | .name("AronaBot")
41 | .info("蔚蓝档案额外功能插件")
42 | .author("Travellerr")
43 |
44 | .build());
45 | }
46 |
47 | @Override
48 | public void onEnable() {
49 | //EventChannel eventEventChannel = GlobalEventChannel.INSTANCE.parentScope(AronaBot.INSTANCE);
50 |
51 | reloadPluginConfig(cn.travellerr.config.Config.INSTANCE);
52 | reloadPluginConfig(VoiceBlackList.INSTANCE);
53 | reloadPluginConfig(SqlConfig.INSTANCE);
54 | config = cn.travellerr.config.Config.INSTANCE;
55 | blackList = VoiceBlackList.INSTANCE;
56 | sqlConfig = SqlConfig.INSTANCE;
57 |
58 | RegCommand regCommand = RegCommand.INSTANCE;
59 | regCommand.register();
60 |
61 | GFont.init();
62 | HibernateUtil.init(this);
63 | Initialize.init();
64 |
65 | ffmpeg = config.getFfmpegPath();
66 | if (!config.getUseSilk() && ffmpeg == null) {
67 | Log.error("你似乎没有安装SilkConverter插件,并且没有安装ffmpeg。语音合成功能已关闭");
68 | config.setUseVoice(false);
69 | reloadPluginConfig(cn.travellerr.config.Config.INSTANCE);
70 | }
71 |
72 | // 私用模块,请修改后使用
73 | GlobalEventChannel.INSTANCE.subscribeAlways(FriendAddEvent.class, Menu::sendMenuToFriend);
74 | GlobalEventChannel.INSTANCE.subscribeAlways(BotJoinGroupEvent.class, Menu::sendMenuToGroup);
75 |
76 | if (config.isReply()) {
77 | EventChannel eventEventChannel = GlobalEventChannel.INSTANCE.parentScope(AronaBot.INSTANCE);
78 | eventEventChannel.registerListenerHost(new MessageEventListener());
79 | }
80 |
81 | GlobalEventChannel.INSTANCE.subscribeAlways(GroupMessagePostSendEvent.class, sendGroupMsgEvent -> sendGroupMsgNum++);
82 | GlobalEventChannel.INSTANCE.subscribeAlways(FriendMessagePostSendEvent.class, sendFriendMsgEvent -> sendFriendMsgNum++);
83 |
84 | Log.info("插件已加载!");
85 | }
86 |
87 | @Override
88 | public void onDisable() {
89 | Log.info("插件已卸载!");
90 | }
91 | }
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/BlueArchive/GetSentenceApi.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.BlueArchive;
2 |
3 | import cn.travellerr.tools.Log;
4 | import com.google.gson.JsonArray;
5 | import com.google.gson.JsonElement;
6 | import com.google.gson.JsonObject;
7 | import com.google.gson.JsonParser;
8 |
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 | import java.nio.charset.StandardCharsets;
12 | import java.nio.file.Files;
13 | import java.nio.file.Path;
14 | import java.nio.file.Paths;
15 | import java.sql.*;
16 | import java.text.SimpleDateFormat;
17 | import java.util.Date;
18 | import java.util.Random;
19 | import java.util.Scanner;
20 |
21 | public class GetSentenceApi {
22 | static String fortuneSummary;
23 | static String signText;
24 | static String unSignText;
25 | static String luckyStar;
26 |
27 | static int AllFortuneID = 402;
28 |
29 | public static void generateFortuneID(long qqNumber, long botId, boolean isForJrys) {
30 | String directory = "./data/cn.travellerr.AronaBot/";
31 | String dbName = "Jrys.db"; // 数据库文件名
32 | String dbPath = Paths.get(directory, dbName).toString();
33 | String url = "jdbc:sqlite:" + dbPath;
34 |
35 | try {
36 | Class.forName("org.sqlite.JDBC");
37 | } catch (Exception e) {
38 | throw new RuntimeException("出错了~", e);
39 | }
40 | createDirectory(directory);
41 |
42 | // 创建目录,如果已存在则不会创建
43 |
44 | try (Connection conn = DriverManager.getConnection(url)) {
45 | createTable(conn);
46 | if (isQQNumberNew(conn, qqNumber)) {
47 | int fortuneID = generateFortuneID(qqNumber, botId);
48 | insertData(conn, qqNumber, fortuneID);
49 | }
50 | if (isDateDifferent(conn, qqNumber)) {
51 | int fortuneID = generateFortuneID(qqNumber, botId);
52 | updateData(conn, qqNumber, fortuneID);
53 | }
54 | if (isForJrys) getData(conn, qqNumber);
55 | } catch (SQLException e) {
56 | throw new RuntimeException("出错了~", e);
57 | }
58 | }
59 |
60 | public static boolean isDateDifferent(long qqNumber) {
61 | String directory = "./data/cn.travellerr.AronaBot/";
62 | String dbName = "Jrys.db"; // 数据库文件名
63 | String dbPath = Paths.get(directory, dbName).toString();
64 | String url = "jdbc:sqlite:" + dbPath;
65 |
66 | try {
67 | Class.forName("org.sqlite.JDBC");
68 | } catch (Exception e) {
69 | throw new RuntimeException("出错了~", e);
70 | }
71 |
72 |
73 | createDirectory(directory);
74 | // 创建目录,如果已存在则不会创建
75 |
76 | try (Connection conn = DriverManager.getConnection(url)) {
77 | createTable(conn);
78 | String selectSql = "SELECT MAX(Date) FROM fortune WHERE QQ = ?";
79 | try (PreparedStatement selectStmt = conn.prepareStatement(selectSql)) {
80 | selectStmt.setLong(1, qqNumber);
81 | try (ResultSet rs = selectStmt.executeQuery()) {
82 | if (rs.next()) {
83 | Timestamp latestDate = rs.getTimestamp(1);
84 | if (latestDate != null) {
85 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
86 | String latestDateString = dateFormat.format(latestDate);
87 | String currentDateString = dateFormat.format(new Date());
88 | return !latestDateString.equals(currentDateString);
89 | }
90 | }
91 | }
92 | }
93 | return true; // 默认返回true,表示日期不相等
94 | } catch (SQLException e) {
95 | throw new RuntimeException("出错了~", e);
96 | }
97 | }
98 |
99 | public static boolean isQQNumberNew(long qqNumber) {
100 | String directory = "./data/cn.travellerr.AronaBot/";
101 | String dbName = "Jrys.db"; // 数据库文件名
102 | String dbPath = Paths.get(directory, dbName).toString();
103 | String url = "jdbc:sqlite:" + dbPath;
104 |
105 | try {
106 | Class.forName("org.sqlite.JDBC");
107 | } catch (Exception e) {
108 | throw new RuntimeException("出错了~", e);
109 | }
110 |
111 | createDirectory(directory);
112 | // 创建目录,如果已存在则不会创建
113 |
114 | try (Connection conn = DriverManager.getConnection(url)) {
115 | createTable(conn);
116 | String selectSql = "SELECT COUNT(*) FROM fortune WHERE QQ = ?";
117 | try (PreparedStatement selectStmt = conn.prepareStatement(selectSql)) {
118 | selectStmt.setLong(1, qqNumber);
119 | try (ResultSet rs = selectStmt.executeQuery()) {
120 | return rs.next() && rs.getInt(1) == 0;
121 | }
122 | }
123 | } catch (SQLException e) {
124 | throw new RuntimeException("出错了~", e);
125 | }
126 | }
127 |
128 |
129 | private static void updateData(Connection conn, long qqNumber, int fortuneID) throws SQLException {
130 | String updateSql = "UPDATE fortune SET fortuneID = ?, Date = ? WHERE QQ = ?";
131 | try (PreparedStatement updateStmt = conn.prepareStatement(updateSql)) {
132 | updateStmt.setInt(1, fortuneID);
133 | updateStmt.setString(2, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
134 | updateStmt.setLong(3, qqNumber);
135 | updateStmt.executeUpdate();
136 | }
137 | }
138 |
139 |
140 | private static void createDirectory(String directory) {
141 | Path path = Paths.get(directory);
142 | try {
143 | Files.createDirectories(path);
144 | } catch (IOException e) {
145 | Log.error("出错了~", e);
146 | }
147 | }
148 |
149 | private static boolean isQQNumberNew(Connection conn, long qqNumber) throws SQLException {
150 | String selectSql = "SELECT COUNT(*) FROM fortune WHERE QQ = ?";
151 | try (PreparedStatement selectStmt = conn.prepareStatement(selectSql)) {
152 | selectStmt.setLong(1, qqNumber);
153 | try (ResultSet rs = selectStmt.executeQuery()) {
154 | return rs.next() && rs.getInt(1) == 0;
155 | }
156 | }
157 | }
158 |
159 | private static int generateFortuneID(long userId, long botId) {
160 | Random random = new Random(System.currentTimeMillis() + userId + botId);
161 | return random.nextInt(AllFortuneID) + 1;
162 | }
163 |
164 | private static boolean isDateDifferent(Connection conn, long qqNumber) throws SQLException {
165 | String selectSql = "SELECT MAX(Date) FROM fortune WHERE QQ = ?";
166 | try (PreparedStatement selectStmt = conn.prepareStatement(selectSql)) {
167 | selectStmt.setLong(1, qqNumber);
168 | try (ResultSet rs = selectStmt.executeQuery()) {
169 | if (rs.next()) {
170 | Timestamp latestDate = rs.getTimestamp(1);
171 | if (latestDate != null) {
172 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
173 | String latestDateString = dateFormat.format(latestDate);
174 | String currentDateString = dateFormat.format(new Date());
175 | return !latestDateString.equals(currentDateString);
176 | }
177 | }
178 | }
179 | }
180 | return true; // 默认返回true,表示日期不相等
181 | }
182 |
183 |
184 | private static void createTable(Connection conn) throws SQLException {
185 | String sql = "CREATE TABLE IF NOT EXISTS fortune (" +
186 | "ID INTEGER PRIMARY KEY, " +
187 | "QQ INTEGER, " +
188 | "fortuneID INTEGER, " + // 将Id字段重命名为fortuneID
189 | "Date TEXT DEFAULT (strftime('%Y-%m-%d %H:%M:%S', 'now', 'localtime')))";
190 | try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
191 | pstmt.executeUpdate();
192 | }
193 | }
194 |
195 | private static void insertData(Connection conn, long qqNumber, int ID) {
196 | String sql = "INSERT INTO fortune (QQ, fortuneID) VALUES (?, ?)";
197 | try (PreparedStatement insertStmt = conn.prepareStatement(sql)) {
198 | // 设置参数值
199 | insertStmt.setLong(1, qqNumber);
200 | insertStmt.setInt(2, ID);
201 |
202 | // 执行插入操作
203 | insertStmt.executeUpdate();
204 | /*int rowsAffected = insertStmt.executeUpdate();
205 | if (rowsAffected > 0) {
206 | System.out.println("Data inserted successfully!");
207 | }*/
208 | } catch (SQLException e) {
209 | // 插入失败时的异常处理
210 | throw new RuntimeException("出错了~", e);
211 | }
212 | }
213 |
214 | private static void getData(Connection conn, long qqNumber) {
215 | String selectSql = "SELECT fortuneID FROM fortune WHERE QQ = ?";
216 | try (PreparedStatement selectStmt = conn.prepareStatement(selectSql)) {
217 | selectStmt.setLong(1, qqNumber);
218 | try (ResultSet rs = selectStmt.executeQuery()) {
219 | if (rs.next()) {
220 | int fortuneID = rs.getInt("fortuneID");
221 | // 从resources目录下获取JSON文件的输入流
222 | try (InputStream inputStream = GetSentenceApi.class.getClassLoader().getResourceAsStream("jrys/jrys.json");
223 | Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF_8)) {
224 | if (scanner.hasNext()) {
225 | String json = scanner.useDelimiter("\\A").next();
226 | JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
227 | if (jsonObject.has(String.valueOf(fortuneID))) {
228 | JsonArray fortuneArray = jsonObject.getAsJsonArray(String.valueOf(fortuneID));
229 | if (!fortuneArray.isJsonNull() && !fortuneArray.isEmpty()) {
230 | JsonObject fortuneObject = fortuneArray.get(0).getAsJsonObject();
231 | fortuneSummary = getStringFromJson(fortuneObject, "fortuneSummary");
232 | luckyStar = getStringFromJson(fortuneObject, "luckyStar");
233 | signText = getStringFromJson(fortuneObject, "signText");
234 | unSignText = getStringFromJson(fortuneObject, "unSignText");
235 | }
236 | }
237 | }
238 | } catch (IOException e) {
239 | throw new RuntimeException("无法找到或读取jrys.json文件", e);
240 | }
241 | }
242 | }
243 | } catch (SQLException e) {
244 | // 处理SQL异常
245 | throw new RuntimeException("出错了~", e);
246 | }
247 | }
248 |
249 | public static int getFortuneID(long qqNumber) {
250 | String directory = "./data/cn.travellerr.AronaBot/";
251 | String dbName = "Jrys.db"; // 数据库文件名
252 | String dbPath = Paths.get(directory, dbName).toString();
253 | String url = "jdbc:sqlite:" + dbPath;
254 |
255 | try {
256 | Class.forName("org.sqlite.JDBC");
257 | } catch (Exception e) {
258 | throw new RuntimeException("出错了~", e);
259 | }
260 |
261 | createDirectory(directory);
262 | // 创建目录,如果已存在则不会创建
263 |
264 | try (Connection conn = DriverManager.getConnection(url)) {
265 |
266 | createTable(conn);
267 |
268 | String selectSql = "SELECT fortuneID FROM fortune WHERE QQ = ?";
269 | try (PreparedStatement selectStmt = conn.prepareStatement(selectSql)) {
270 | selectStmt.setLong(1, qqNumber);
271 | try (ResultSet rs = selectStmt.executeQuery()) {
272 | if (rs.next()) {
273 | return rs.getInt("fortuneID");
274 | }
275 | }
276 | }
277 | } catch (Exception e) {
278 | throw new RuntimeException("出错了~", e);
279 | }
280 |
281 | return -1;
282 | }
283 |
284 | private static String getStringFromJson(JsonObject jsonObject, String key) {
285 | JsonElement jsonElement = jsonObject.get(key);
286 | return jsonElement != null ? jsonElement.getAsString() : null;
287 | }
288 |
289 |
290 | }
291 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/BlueArchive/Jrrp.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.BlueArchive;
2 |
3 | import net.mamoe.mirai.contact.Contact;
4 | import net.mamoe.mirai.contact.User;
5 | import net.mamoe.mirai.message.data.At;
6 | import net.mamoe.mirai.message.data.MessageChainBuilder;
7 |
8 | import java.util.Objects;
9 |
10 | public class Jrrp {
11 | public static void info(Contact subject, User user) {
12 | long qqNumber = user.getId();
13 | long botId = subject.getBot().getId();
14 | boolean isNewGen = SqlUtil.isNewGen(qqNumber);
15 |
16 | MessageChainBuilder message = new MessageChainBuilder();
17 | message.append(new At(qqNumber)).append("\n");
18 |
19 | if (!isNewGen) {
20 | message.append("今日已查询,");
21 | }
22 |
23 | int jrrp = Objects.requireNonNull(SqlUtil.fortuneManager(qqNumber, botId)).getFortuneID() % 101;
24 | message.append("您的今日人品为:").append(String.valueOf(jrrp));
25 | subject.sendMessage(message.build());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/BlueArchive/Jrys.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.BlueArchive;
2 |
3 | import cn.chahuyun.hibernateplus.HibernateFactory;
4 | import cn.travellerr.entity.FortuneInfo;
5 | import cn.travellerr.entity.UserInfo;
6 | import cn.travellerr.tools.GFont;
7 | import cn.travellerr.tools.Log;
8 | import net.mamoe.mirai.contact.AvatarSpec;
9 | import net.mamoe.mirai.contact.Contact;
10 | import net.mamoe.mirai.contact.User;
11 | import net.mamoe.mirai.message.data.At;
12 | import net.mamoe.mirai.message.data.MessageChainBuilder;
13 | import net.mamoe.mirai.utils.ExternalResource;
14 |
15 | import javax.imageio.ImageIO;
16 | import java.awt.*;
17 | import java.awt.image.BufferedImage;
18 | import java.awt.image.RenderedImage;
19 | import java.io.ByteArrayInputStream;
20 | import java.io.ByteArrayOutputStream;
21 | import java.io.IOException;
22 | import java.net.URL;
23 | import java.util.Objects;
24 | import java.util.Random;
25 |
26 | import static cn.travellerr.AronaBot.config;
27 |
28 | public class Jrys {
29 | private static int index = 1;
30 |
31 | private static void sendImage(User sender, Image image, Contact subject, FortuneInfo fortuneInfo) throws IOException {
32 |
33 | try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
34 | ImageIO.write((RenderedImage) image, "png", stream);
35 |
36 | try (ExternalResource resource = ExternalResource.create(new ByteArrayInputStream(stream.toByteArray()))) {
37 | net.mamoe.mirai.message.data.Image sendImage = subject.uploadImage(resource);
38 | subject.sendMessage(sendImage.plus(new At(sender.getId())));
39 | }
40 |
41 | } catch (IOException e) {
42 | MessageChainBuilder sendMsg = new MessageChainBuilder();
43 | net.mamoe.mirai.message.data.Image avatar = Contact.uploadImage(subject, new URL(sender.getAvatarUrl(AvatarSpec.LARGE)).openConnection().getInputStream());
44 | sendMsg.append(new At(sender.getId()));
45 | sendMsg.append("\n");
46 | sendMsg.append(avatar);
47 | sendMsg.append("\n").append(fortuneInfo.getFortuneSummary()).append("\n").append(fortuneInfo.getLuckyStar()).append("\n").append(fortuneInfo.getSignText()).append("\n").append(fortuneInfo.getUnSignText()).append("\n\n抱歉").append(config.getSuffix()).append(",由于图片无法发送,这是阿洛娜手写出来的签!");
48 | Log.error("签到管理:签到图片发送错误!", e);
49 | subject.sendMessage(sendMsg.build());
50 | }
51 | }
52 |
53 | private static String stamp(String luckyStar) {
54 | if (Objects.equals(luckyStar, "☆☆☆☆☆☆☆") || Objects.equals(luckyStar, "★☆☆☆☆☆☆") || Objects.equals(luckyStar, "★★☆☆☆☆☆")) {
55 | Random random = new Random();
56 | int randImg = random.nextInt(4);
57 | return "jrys/心奈印章/0_" + randImg + ".png";
58 | }
59 | if (Objects.equals(luckyStar, "★★★☆☆☆☆") || Objects.equals(luckyStar, "★★★★☆☆☆")) {
60 | return "jrys/心奈印章/59.png";
61 | }
62 | if (Objects.equals(luckyStar, "★★★★★☆☆") || Objects.equals(luckyStar, "★★★★★★☆")) {
63 | return "jrys/心奈印章/60.png";
64 | } else {
65 | return "jrys/心奈印章/100.png";
66 | }
67 | }
68 |
69 |
70 | public static void info(Contact subject, User sender) {
71 | subject.sendMessage(new At(sender.getId()).plus("\n" + config.getSuffix() + "请稍等!" + subject.getBot().getNick() + "这就为您抽签!"));
72 | long botId = subject.getBot().getId();
73 | UserInfo userInfo = SqlUtil.fortuneManager(sender.getId(), botId);
74 | if (userInfo == null) {
75 | subject.sendMessage("出错啦~未获取到用户信息,请联系主人查看控制台");
76 | return;
77 | }
78 | FortuneInfo fortuneInfo = HibernateFactory.selectOne(FortuneInfo.class, userInfo.getFortuneID());
79 |
80 | if (!config.isText()) {
81 |
82 | try {
83 | int schoolNum = 3; //学校数量
84 | int clubNum = 4; //默认社团数量
85 | int picNum = 4; //默认学员数量
86 | int club = 0; //默认社团
87 | Random rand = new Random();
88 | int school = rand.nextInt(schoolNum);
89 | if (school == 1) {
90 | rand = new Random();
91 | club = rand.nextInt(clubNum);
92 | }
93 | if (school == 1) {
94 | if (club == 1) picNum = 5;
95 | if (club == 3) picNum = 3;
96 | } else if (school == 0) {
97 | picNum = 5;
98 | }
99 |
100 | // 读取背景图片和覆盖图片
101 | ClassLoader classLoader = Jrys.class.getClassLoader();
102 | BufferedImage background = ImageIO.read(Objects.requireNonNull(classLoader.getResourceAsStream("jrys/" + school + "/" + club + "/bg.png")));
103 | BufferedImage cover = ImageIO.read(Objects.requireNonNull(classLoader.getResourceAsStream("jrys/" + school + "/" + club + "/" + (index % picNum == 0 ? picNum : index % picNum) + ".png")));
104 | index++;
105 |
106 | int newWidth = (int) (cover.getWidth() / 1.6); // 缩小为原来的一半
107 | int newHeight = (int) (cover.getHeight() / 1.6);
108 |
109 | BufferedImage resizedCover = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
110 | Image scaledCover = cover.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
111 | Graphics2D g2d = resizedCover.createGraphics();
112 | g2d.drawImage(scaledCover, 0, 0, null);
113 | g2d.dispose();
114 |
115 | // 创建一个新的BufferedImage对象,大小为背景图片的大小
116 | BufferedImage combined = new BufferedImage(background.getWidth(), background.getHeight(), BufferedImage.TYPE_INT_ARGB);
117 |
118 | // 将背景图片绘制到新的BufferedImage对象中
119 | Graphics2D g = combined.createGraphics();
120 | g.drawImage(background, 0, 0, null);
121 |
122 | //绘制半透明遮盖
123 | AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
124 | g.setComposite(alphaComposite);
125 | g.setColor(Color.WHITE);
126 | g.fillRect(20, 20, combined.getWidth() - 40, combined.getHeight() - 40);
127 | alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f);
128 | g.setComposite(alphaComposite);
129 |
130 | // 将覆盖图片叠加到背景图片上
131 | int coverX = 600 - resizedCover.getWidth() / 2; // 计算要绘制的图片在背景图片中的 X 坐标,使其中心点的 x 坐标为 300
132 | g.drawImage(resizedCover, coverX, 100, null);
133 |
134 | // 绘制签底
135 | g.setColor(Color.red);
136 | g.fillRect(100, 100, 300, 600);
137 | g.setColor(Color.white);
138 | g.fillRect(105, 105, 290, 590);
139 | g.setColor(Color.red);
140 | g.fillRect(110, 110, 280, 580);
141 | g.setColor(Color.WHITE);
142 | g.fillRect(115, 115, 270, 570);
143 | g.setColor(Color.red);
144 | g.fillRect(115, 115, 270, 75);
145 | Font font = GFont.font;
146 | g.setFont(font);
147 | g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
148 | g.setColor(Color.WHITE);
149 |
150 |
151 | //获取运势信息
152 | String text = fortuneInfo.getFortuneSummary();
153 | //检测运势长度,自适应字体大小
154 | int textX = 495;
155 | if (text.length() > 6) {
156 |
157 | font = font.deriveFont(30f);
158 | textX = 610;
159 | }
160 | if (text.length() > 8) {
161 | font = font.deriveFont(25f);
162 | textX = 700;
163 | }
164 | int stringWidth = g.getFontMetrics().stringWidth(text);
165 | g.setFont(font);
166 | int x = (textX - stringWidth) / 2;
167 | g.drawString(text, x, 165);
168 |
169 | //获取运势建议
170 | String message = fortuneInfo.getUnSignText();
171 | int adaption = 5;
172 | int moveX = 38;
173 | int msgX = 310;
174 | font = font.deriveFont(30f);
175 | if (message.length() >= 45) {
176 | font = font.deriveFont(20f);
177 | adaption = 0;
178 | moveX = 32;
179 | msgX = 350;
180 | }
181 | g.setFont(font);
182 | g.setColor(Color.black);
183 |
184 | //绘制竖向字体
185 | FontMetrics fontMetrics = g2d.getFontMetrics();
186 | int fontHeight = fontMetrics.getHeight() * 2 + adaption;
187 | int msgY = 220;
188 | for (int msgLength = 0; msgLength < message.length() - 1; msgLength += 1) {
189 | g.drawString(String.valueOf(message.charAt(msgLength)), msgX, msgY);
190 | msgY += fontHeight;
191 | if (msgY > 618) {
192 | msgY = 220;
193 | msgX -= moveX;
194 | }
195 | }
196 | font = font.deriveFont(20f);
197 | g.setFont(font);
198 | g.setColor(Color.white);
199 | g.drawString("AronaBot&Travellerr", 550, 795);
200 |
201 |
202 | BufferedImage stamp = ImageIO.read(Objects.requireNonNull(classLoader.getResourceAsStream(stamp(fortuneInfo.getLuckyStar()))));
203 | g.drawImage(stamp, 315, 618, null);
204 |
205 | /*font = font.deriveFont(30f);
206 | g.setFont(font);
207 | g.setColor(new Color(194, 9, 9));
208 | g.drawString("祝各位考生能考出属于自己的理想成绩!",40 ,750);*/
209 |
210 | g.dispose();
211 | sendImage(sender, combined, subject, fortuneInfo);
212 | } catch (IOException e) {
213 | throw new RuntimeException(e);
214 | }
215 | } else {
216 | try {
217 | MessageChainBuilder sendMsg = new MessageChainBuilder();
218 | net.mamoe.mirai.message.data.Image avatar = Contact.uploadImage(subject, new URL(sender.getAvatarUrl(AvatarSpec.LARGE)).openConnection().getInputStream());
219 | sendMsg.append(new At(sender.getId()));
220 | sendMsg.append("\n");
221 | sendMsg.append(avatar);
222 | sendMsg.append("\n").append(fortuneInfo.getFortuneSummary()).append("\n").append(fortuneInfo.getLuckyStar()).append("\n").append(fortuneInfo.getSignText()).append("\n").append(fortuneInfo.getUnSignText());
223 | subject.sendMessage(sendMsg.build());
224 | } catch (Exception e) {
225 | Log.error("出错了~", e.fillInStackTrace());
226 | }
227 | }
228 | }
229 | }
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/BlueArchive/SqlUtil.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.BlueArchive;
2 |
3 | import cn.chahuyun.hibernateplus.HibernateFactory;
4 | import cn.hutool.core.date.DateUtil;
5 | import cn.travellerr.entity.UserInfo;
6 | import cn.travellerr.tools.Log;
7 |
8 | import java.util.Date;
9 | import java.util.Random;
10 |
11 | public class SqlUtil {
12 |
13 | private static final int AllFortuneID = 402;
14 |
15 | public static UserInfo fortuneManager(long qqNumber, long botId) {
16 |
17 | if (isNewGen(qqNumber)) {
18 | int fortuneID = generateFortuneID(qqNumber, botId);
19 | if (!insertData(qqNumber, fortuneID)) {
20 | Log.debug("insert data failed");
21 | return null;
22 | }
23 | }
24 | return HibernateFactory.selectOne(UserInfo.class, qqNumber);
25 | }
26 |
27 |
28 | /**
29 | * 判断QQ号是否为新号
30 | *
31 | * @param qqNumber 用户QQ号
32 | * @return 布尔值,true
为是
33 | */
34 | public static boolean isNewGen(long qqNumber) {
35 | UserInfo userInfo = HibernateFactory.selectOne(UserInfo.class, qqNumber);
36 | return (userInfo == null) || (!DateUtil.isSameDay(
37 | userInfo.getGenerateDate(),
38 | new Date()));
39 | }
40 |
41 | /**
42 | * 更新用户的运势ID
43 | *
44 | * @param qqNumber 用户QQ号
45 | * @param ID 运势ID
46 | */
47 | private static boolean insertData(long qqNumber, int ID) {
48 | UserInfo userInfo = HibernateFactory.selectOne(UserInfo.class, qqNumber);
49 | if (userInfo == null) {
50 | userInfo = UserInfo.builder()
51 | .qq(qqNumber)
52 | .build();
53 | }
54 | userInfo.setFortuneID(ID);
55 | userInfo.setGenerateDate(new Date());
56 | HibernateFactory.merge(userInfo);
57 | return true;
58 | }
59 |
60 |
61 | private static int generateFortuneID(long userId, long botId) {
62 | Random random = new Random(System.currentTimeMillis() + userId + botId);
63 | return random.nextInt(AllFortuneID) + 1;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/Initialize.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr;
2 |
3 | import cn.chahuyun.hibernateplus.HibernateFactory;
4 | import cn.hutool.core.date.BetweenFormatter;
5 | import cn.hutool.core.date.DateUtil;
6 | import cn.travellerr.BlueArchive.GetSentenceApi;
7 | import cn.travellerr.entity.FortuneInfo;
8 | import cn.travellerr.tools.Log;
9 | import com.google.gson.Gson;
10 | import com.google.gson.JsonArray;
11 | import com.google.gson.JsonElement;
12 | import com.google.gson.JsonObject;
13 |
14 | import java.io.IOException;
15 | import java.io.InputStream;
16 | import java.io.InputStreamReader;
17 | import java.nio.charset.StandardCharsets;
18 | import java.nio.file.Files;
19 | import java.nio.file.Path;
20 | import java.nio.file.StandardCopyOption;
21 |
22 | public class Initialize {
23 | public static void init() {
24 | Thread thread = new Thread(() -> {
25 | copy();
26 | if (HibernateFactory.selectList(FortuneInfo.class).isEmpty()) {
27 | Log.warning("运势数据库中没有数据,正在初始化...");
28 | long initSqlStart = System.currentTimeMillis();
29 | jrysToSql();
30 | Log.warning("初始化完成!用时 " +
31 | DateUtil.formatBetween(System.currentTimeMillis() - initSqlStart, BetweenFormatter.Level.MILLISECOND));
32 | }
33 | });
34 |
35 | thread.start();
36 | }
37 |
38 | private static void jrysToSql() {
39 | try (InputStream inputStream = GetSentenceApi.class.getClassLoader().getResourceAsStream("jrys/jrys.json");
40 | InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
41 | Gson gson = new Gson();
42 | JsonObject jsonObject = gson.fromJson(reader, JsonObject.class);
43 |
44 | for (String key : jsonObject.keySet()) {
45 | JsonArray jsonArray = jsonObject.getAsJsonArray(key);
46 | for (JsonElement element : jsonArray) {
47 | JsonObject item = element.getAsJsonObject();
48 |
49 | int id = Integer.parseInt(key);
50 | String fortuneSummary = item.get("fortuneSummary").getAsString();
51 | String luckyStar = item.get("luckyStar").getAsString();
52 | String signText = item.get("signText").getAsString();
53 | String unSignText = item.get("unSignText").getAsString();
54 |
55 | // 将提取的信息存储到数据库中,这里假设调用存储方法saveToDatabase()
56 | saveToDatabase(id, fortuneSummary, luckyStar, signText, unSignText);
57 | }
58 | }
59 | } catch (IOException e) {
60 | throw new RuntimeException("无法找到或读取jrys.json文件", e);
61 | }
62 | }
63 |
64 | private static void saveToDatabase(int id, String fortuneSummary, String luckyStar, String signText, String unSignText) {
65 | FortuneInfo fortuneInfo = FortuneInfo.builder()
66 | .id(id)
67 | .fortuneSummary(fortuneSummary)
68 | .luckyStar(luckyStar)
69 | .signText(signText)
70 | .unSignText(unSignText)
71 | .build();
72 | HibernateFactory.merge(fortuneInfo);
73 | // 在这里编写将信息存储到数据库的逻辑
74 | }
75 |
76 | public static void copy() {
77 | Path path = AronaBot.INSTANCE.getDataFolderPath().resolve("replyData.json");
78 | if (!Files.exists(path)) {
79 | try {
80 | String sourcePath = "data.json";
81 | Files.createDirectories(path);
82 | // 获取类资源文件的输入流
83 | InputStream inputStream = AronaBot.class.getClassLoader().getResourceAsStream(sourcePath);
84 | if (inputStream == null) {
85 | Log.error("出错啦~: 未找到data资源");
86 | return;
87 | }
88 |
89 | // 拷贝输入流到目标路径
90 | Files.copy(inputStream, path, StandardCopyOption.REPLACE_EXISTING);
91 | Log.info("回复语录Json文件拷贝成功!");
92 | } catch (IOException e) {
93 | Log.error("出错啦~", e);
94 | }
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/entity/FortuneInfo.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.entity;
2 |
3 | import jakarta.persistence.*;
4 | import lombok.*;
5 |
6 |
7 | @Entity(name = "FortuneInfo")
8 | @Table(name = "FortuneInfo")
9 | @Setter
10 | @Getter
11 | @Builder
12 | @AllArgsConstructor
13 | @NoArgsConstructor
14 | public class FortuneInfo {
15 | @Id
16 | @GeneratedValue(strategy = GenerationType.IDENTITY)
17 | private Integer id;
18 |
19 | private String fortuneSummary;
20 | private String luckyStar;
21 | private String signText;
22 | private String unSignText;
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/entity/SysInfo.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.entity;
2 |
3 | import cn.travellerr.AronaBot;
4 | import cn.travellerr.tools.Log;
5 | import lombok.Getter;
6 | import lombok.Setter;
7 | import net.mamoe.mirai.console.MiraiConsole;
8 | import oshi.SystemInfo;
9 | import oshi.hardware.CentralProcessor;
10 | import oshi.hardware.GlobalMemory;
11 | import oshi.hardware.HardwareAbstractionLayer;
12 | import oshi.hardware.NetworkIF;
13 | import oshi.util.Util;
14 |
15 | import java.io.File;
16 | import java.text.DecimalFormat;
17 |
18 | @Setter
19 | @Getter
20 | public class SysInfo {
21 |
22 | private double usedCpu;
23 | private long TotalMem;
24 | private long FreeMem;
25 | private long TotalDisk;
26 | private long FreeSpaceDisk;
27 | private String sent;
28 | private String receive;
29 | private long sendGroupMsgNum = AronaBot.sendGroupMsgNum;
30 | private long sendFriendMsgNum = AronaBot.sendFriendMsgNum;
31 | private int plugins = MiraiConsole.INSTANCE.getPluginManager().getPlugins().size() - 1;
32 |
33 |
34 | public SysInfo() {
35 | this.usedCpu = getCpuUsage();
36 | getMemoryInfo();
37 | getDiskInfo();
38 | getNetflow();
39 | }
40 |
41 |
42 | private double getCpuUsage() {
43 | CentralProcessor processor = new SystemInfo().getHardware().getProcessor();
44 | // Wait a second...
45 | Util.sleep(100);
46 | double[] loads = processor.getProcessorCpuLoadBetweenTicks();
47 | double totalLoad = 0;
48 | for (double load : loads) {
49 | totalLoad += load;
50 | }
51 | Log.debug("CPU使用率: " + usedCpu);
52 |
53 | DecimalFormat df = new DecimalFormat("#.##");
54 | return Double.parseDouble(df.format((totalLoad / loads.length) * 100));
55 | }
56 |
57 | private void getMemoryInfo() {
58 | SystemInfo systemInfo = new SystemInfo();
59 | GlobalMemory memory = systemInfo.getHardware().getMemory();
60 | Log.debug("服务器总内存: " + TotalMem);
61 | Log.debug("服务器空闲内存: " + FreeMem);
62 | this.TotalMem = memory.getTotal() / 1024 / 1024 / 1024;
63 | this.FreeMem = memory.getAvailable() / 1024 / 1024 / 1024;
64 | }
65 |
66 | private void getDiskInfo() {
67 | File win = new File("/");
68 | if (win.exists()) {
69 | long total = win.getTotalSpace();
70 | long freeSpace = win.getFreeSpace();
71 | Log.debug("服务器总硬盘空间: " + TotalDisk);
72 | Log.debug("服务器剩余硬盘空间: " + FreeSpaceDisk);
73 | this.TotalDisk = total / 1024 / 1024 / 1024;
74 | this.FreeSpaceDisk = freeSpace / 1024 / 1024 / 1024;
75 | }
76 | }
77 |
78 | private void getNetflow() {
79 | SystemInfo systemInfo = new SystemInfo();
80 | HardwareAbstractionLayer hardware = systemInfo.getHardware();
81 | DecimalFormat df = new DecimalFormat("#.##");
82 | NetworkIF[] networkIFs = hardware.getNetworkIFs();
83 | long getBytesRecv = 0;
84 | long getBytesSent = 0;
85 | for (NetworkIF net : networkIFs) {
86 | getBytesRecv += net.getBytesRecv();
87 | getBytesSent += net.getBytesSent();
88 | }
89 |
90 | Log.debug("服务器上行量: " + sent);
91 | Log.debug("服务器下行量: " + receive);
92 | this.receive = df.format((double) getBytesRecv / (1024 * 1024)) + "MB";
93 | this.sent = df.format((double) getBytesSent / (1024 * 1024)) + "MB";
94 |
95 |
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/entity/UserInfo.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.entity;
2 |
3 | import jakarta.persistence.Entity;
4 | import jakarta.persistence.Id;
5 | import jakarta.persistence.Table;
6 | import lombok.*;
7 |
8 | import java.util.Date;
9 |
10 |
11 | @Entity(name = "UserInfo")
12 | @Table(name = "UserInfo")
13 | @Getter
14 | @Setter
15 | @Builder
16 | @AllArgsConstructor
17 | @NoArgsConstructor
18 | public class UserInfo {
19 |
20 | @Id
21 | private Long qq;
22 | private Integer fortuneID;
23 |
24 | @Builder.Default
25 | private Date generateDate = new Date();
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/event/Menu.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.event;
2 |
3 | import net.mamoe.mirai.contact.Contact;
4 | import net.mamoe.mirai.event.events.BotJoinGroupEvent;
5 | import net.mamoe.mirai.event.events.FriendAddEvent;
6 | import net.mamoe.mirai.message.data.Image;
7 | import net.mamoe.mirai.message.data.PlainText;
8 | import net.mamoe.mirai.utils.ExternalResource;
9 |
10 | import java.io.File;
11 | import java.io.IOException;
12 |
13 |
14 | /**
15 | * 实现加群自动发图片功能,私用模块,如要启用请更改下方信息
16 | * @author Travellerr
17 | * @since 2024/05/18
18 | */
19 | public class Menu {
20 | public static void sendMenuToFriend(FriendAddEvent event) {
21 |
22 | // 启用QQ
23 | if (event.getBot().getId() == 896603204) {
24 | Contact subject = event.getUser();
25 |
26 | // 菜单图片路径(相对路径)
27 | File menu = new File("./data/image/menu/menu1.png");
28 | try (ExternalResource resource = ExternalResource.create(menu)) {
29 | Image image = subject.uploadImage(resource);
30 |
31 | // 发送消息
32 | subject.sendMessage(new PlainText(event.getUser().getNick()
33 | + " Sensei您好!\n欢迎使用由 Travellerr 制作的 \"蔚蓝档案-阿洛娜\"机器人!\n请在使用之前仔细查看菜单!")
34 | .plus(image));
35 |
36 | } catch (IOException e) {
37 | throw new RuntimeException(e);
38 | }
39 | }
40 | }
41 |
42 | public static void sendMenuToGroup(BotJoinGroupEvent event) {
43 |
44 | // 启用QQ
45 | if (event.getBot().getId() == 896603204) {
46 | Contact subject = event.getGroup();
47 |
48 | // 菜单图片路径(相对路径)
49 | File menu = new File("./data/image/menu/menu1.png");
50 | try (ExternalResource resource = ExternalResource.create(menu)) {
51 | Image image = subject.uploadImage(resource);
52 |
53 | // 发送消息
54 | subject.sendMessage(new PlainText("来自 "
55 | + event.getGroup().getName()
56 | + " 的Sensei们好!\n欢迎使用由 Travellerr 制作的 \"蔚蓝档案-阿洛娜\"机器人!\n请在使用之前仔细查看菜单!\n请注意,拉入本阿洛娜即视为同意以下内容: \nhttps://www.travellerr.cn/20240625417")
57 | .plus(image));
58 |
59 | } catch (IOException e) {
60 | throw new RuntimeException(e);
61 | }
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/event/MessageEventListener.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.event;
2 |
3 | import cn.travellerr.AronaBot;
4 | import cn.travellerr.tools.Log;
5 | import com.google.gson.Gson;
6 | import com.google.gson.JsonArray;
7 | import com.google.gson.JsonObject;
8 | import com.google.gson.reflect.TypeToken;
9 | import kotlin.coroutines.CoroutineContext;
10 | import net.mamoe.mirai.contact.BotIsBeingMutedException;
11 | import net.mamoe.mirai.contact.Contact;
12 | import net.mamoe.mirai.contact.MessageTooLargeException;
13 | import net.mamoe.mirai.event.EventHandler;
14 | import net.mamoe.mirai.event.SimpleListenerHost;
15 | import net.mamoe.mirai.event.events.EventCancelledException;
16 | import net.mamoe.mirai.event.events.MessageEvent;
17 | import net.mamoe.mirai.message.data.QuoteReply;
18 | import org.jetbrains.annotations.NotNull;
19 |
20 | import java.io.FileReader;
21 | import java.util.List;
22 | import java.util.Random;
23 |
24 |
25 | public class MessageEventListener extends SimpleListenerHost {
26 |
27 | @Override
28 | public void handleException(@NotNull CoroutineContext context, @NotNull Throwable exception) {
29 | if (exception instanceof EventCancelledException) {
30 | Log.error("发送消息被取消:", exception);
31 | } else if (exception instanceof BotIsBeingMutedException) {
32 | Log.error("你的机器人被禁言:", exception);
33 | } else if (exception instanceof MessageTooLargeException) {
34 | Log.error("发送消息过长:", exception);
35 | } else if (exception instanceof IllegalArgumentException) {
36 | Log.error("发送消息为空:", exception);
37 | }
38 |
39 | // 处理事件处理时抛出的异常
40 | Log.error(exception);
41 | }
42 | @EventHandler()
43 | public void onMessage(@NotNull MessageEvent event) {
44 |
45 | String message = event.getMessage().serializeToMiraiCode();
46 | if (AronaBot.config.isAt()) {
47 | if (!message.contains("[mirai:at:" + event.getBot().getId() + "]")) {
48 | return;
49 | }
50 | message = message.split("]")[1].trim();
51 | }
52 | Contact subject = event.getSubject();
53 | QuoteReply quoteReply = new QuoteReply(event.getMessage());
54 |
55 |
56 | try (FileReader reader = new FileReader(AronaBot.INSTANCE.getDataFolder() + "/replyData.json")) {
57 | // 读取JSON文件
58 | JsonObject jsonObject = new Gson().fromJson(reader, JsonObject.class);
59 |
60 | JsonObject normalObject = jsonObject.getAsJsonObject("Normal");
61 | // 获取对应键的值
62 | if (normalObject != null) {
63 | if (!handleMessages(normalObject, message, subject, quoteReply) && AronaBot.config.isR18()) {
64 | JsonObject r18Object = jsonObject.getAsJsonObject("R18");
65 | handleMessages(r18Object, message, subject, quoteReply);
66 | }
67 | }
68 | } catch (Exception e) {
69 | throw new RuntimeException(e);
70 | }
71 | }
72 |
73 | private boolean handleMessages(JsonObject jsonObject, String message, Contact subject, QuoteReply quoteReply) {
74 | JsonArray messageObject = jsonObject.getAsJsonArray(message);
75 | if (messageObject != null) {
76 | List messages = new Gson().fromJson(messageObject, new TypeToken>() {
77 | }.getType());
78 | String randomMessage = messages.get(new Random().nextInt(messages.size()));
79 | subject.sendMessage(quoteReply.plus(randomMessage));
80 | return true;
81 | }
82 | return false;
83 | }
84 | }
85 |
86 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/tools/Api.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.tools;
2 |
3 | import cn.hutool.core.io.FileUtil;
4 | import net.mamoe.mirai.contact.Contact;
5 | import net.mamoe.mirai.contact.User;
6 | import net.mamoe.mirai.event.events.MessageEvent;
7 | import net.mamoe.mirai.message.data.At;
8 | import net.mamoe.mirai.message.data.Image;
9 | import net.mamoe.mirai.message.data.MessageChain;
10 | import net.mamoe.mirai.utils.ExternalResource;
11 |
12 | import java.io.BufferedOutputStream;
13 | import java.io.File;
14 | import java.io.FileOutputStream;
15 | import java.io.InputStream;
16 | import java.net.URL;
17 | import java.net.URLConnection;
18 | import java.net.URLEncoder;
19 | import java.nio.charset.StandardCharsets;
20 |
21 | import static cn.travellerr.AronaBot.config;
22 |
23 | public class Api {
24 |
25 | /*public static void chaiq(MessageEvent event) {
26 | try {
27 | Contact subject = event.getSubject();
28 | User user = event.getSender();
29 | URL url = new URL("https://api.lolimi.cn/API/chaiq/c.php");
30 | ExternalResource resource = ExternalResource.create(url.openStream());
31 | Image image = subject.uploadImage(resource);
32 | subject.sendMessage(new At(user.getId()).plus(image));
33 | resource.close();
34 | } catch (Exception e) {
35 | throw new RuntimeException(e);
36 | }
37 | }*/
38 |
39 | public static void chaiq(Contact subject, User user) {
40 | try {
41 | URL url = new URL("https://api.lolimi.cn/API/chaiq/c.php");
42 |
43 | try (InputStream stream = url.openStream()) {
44 | if (config.getDebug()) { // 文件类型测试
45 | File dictionary = new File("./aronaBotDebug");
46 | if (!dictionary.exists()) {
47 | if (dictionary.mkdir()) {
48 | Log.debug("debug文件夹创建成功");
49 | } else {
50 | Log.error("debug文件夹创建失败");
51 | }
52 | }
53 | long time = System.currentTimeMillis();
54 | File tempFile = File.createTempFile("tempFile", null);
55 |
56 | try (BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(tempFile))) {
57 | outputStream.write(stream.readAllBytes());
58 | }
59 |
60 | URLConnection connection = tempFile.toURI().toURL().openConnection();
61 | String mimeType = connection.getContentType();
62 | Log.debug("文件类型: " + mimeType);
63 | String[] suf = mimeType.split("/");
64 | String suffix = suf[suf.length - 1];
65 | File finalFile = new File("./aronaBotDebug/" + time + "file." + suffix);
66 | FileUtil.copy(tempFile, finalFile, true);
67 | }
68 |
69 | try (ExternalResource resource = ExternalResource.create(stream)) {
70 | Image image = subject.uploadImage(resource);
71 | subject.sendMessage(new At(user.getId()).plus(image));
72 | }
73 | }
74 | } catch (Exception e) {
75 | subject.sendMessage(new At(user.getId()).plus("\n发送图片失败!请检查控制台输出!\n原因: ").plus(e.getMessage()));
76 | throw new RuntimeException(e);
77 | }
78 | }
79 |
80 | public static void draw(MessageEvent event) {
81 | try {
82 | Contact subject = event.getSubject();
83 | User user = event.getSender();
84 | subject.sendMessage(new At(user.getId()).plus("绘制中,请稍等"));
85 | MessageChain message = event.getMessage();
86 | String code = message.serializeToMiraiCode();
87 | //Log.info(code);
88 | String[] name = code.split("画 ");
89 | Log.info(name[name.length - 1]);
90 |
91 | String text = URLEncoder.encode(name[name.length - 1], StandardCharsets.UTF_8);
92 | String headUrl = "https://ai.cloudroo.top/draw/?t=" + text;
93 | URL url = new URL(headUrl);
94 | ExternalResource resource = ExternalResource.create(url.openStream());
95 | Image image = subject.uploadImage(resource);
96 | subject.sendMessage(new At(user.getId()).plus(image));
97 | resource.close();
98 |
99 | } catch (Exception e) {
100 | throw new RuntimeException(e);
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/tools/GFont.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.tools;
2 |
3 | import cn.travellerr.config.Config;
4 |
5 | import java.awt.*;
6 | import java.io.File;
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 |
10 | public class GFont {
11 | public static Font font;
12 |
13 | public static void init() {
14 | Config config = cn.travellerr.config.Config.INSTANCE;
15 | if (config.getUseLocalFont().isEmpty()) {
16 | try {
17 | InputStream fontStream = GFont.class.getResourceAsStream("/fonts/黑体.ttf");
18 | if (fontStream != null) {
19 | font = Font.createFont(Font.TRUETYPE_FONT, fontStream);
20 | }
21 | } catch (FontFormatException | IOException e) {
22 | throw new RuntimeException(e);
23 | }
24 | font = font.deriveFont(Font.BOLD, 45);
25 | Log.info("字体 黑体.ttf 已加载");
26 | } else {
27 | try {
28 | File fontFile = new File(config.getUseLocalFont()).getAbsoluteFile();
29 |
30 | if (fontFile.isFile()) {
31 | font = Font.createFont(Font.TRUETYPE_FONT, fontFile);
32 | } else {
33 | Log.error("出现错误:" + config.getUseLocalFont() + "不是一个文件!");
34 | return;
35 | }
36 | } catch (FontFormatException | IOException e) {
37 | throw new RuntimeException(e);
38 | }
39 | font = font.deriveFont(Font.BOLD, 45);
40 | Log.info("字体 自定义 已加载");
41 | }
42 | }
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/tools/Log.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.tools;
2 |
3 | import cn.travellerr.AronaBot;
4 | import net.mamoe.mirai.utils.MiraiLogger;
5 |
6 | import java.io.IOException;
7 |
8 | public class Log {
9 |
10 | private static final MiraiLogger log = AronaBot.INSTANCE.getLogger();
11 | private static final String name = "阿洛娜杂项-";
12 |
13 | public static void info(Object msg) {
14 | log.info(name + msg);
15 | }
16 |
17 | public static void warning(Object msg) {
18 | log.warning(name + msg);
19 | }
20 |
21 | public static void error(Object msg, IOException e) {
22 | log.error(name + msg);
23 | }
24 |
25 | public static void error(Object msg) {
26 | log.error(name + msg);
27 | }
28 |
29 | public static void error(Object msg, Throwable e) {
30 | log.error(name + msg);
31 | log.error(name + e.getMessage(), e);
32 | }
33 |
34 | public static void error(Throwable e) {
35 | log.error(name + e.getMessage(), e);
36 | }
37 |
38 | public static void debug(Object msg) {
39 | log.debug(name + msg);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/tools/SecurityNew.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.tools;
2 |
3 |
4 | import cn.hutool.core.date.BetweenFormatter;
5 | import cn.hutool.core.date.DateUtil;
6 | import cn.travellerr.AronaBot;
7 | import cn.travellerr.entity.SysInfo;
8 | import net.mamoe.mirai.Bot;
9 | import net.mamoe.mirai.contact.AvatarSpec;
10 | import net.mamoe.mirai.contact.Contact;
11 | import net.mamoe.mirai.contact.User;
12 | import net.mamoe.mirai.message.data.At;
13 | import net.mamoe.mirai.message.data.MessageChainBuilder;
14 | import net.mamoe.mirai.utils.ExternalResource;
15 | import org.jfree.chart.ChartFactory;
16 | import org.jfree.chart.ChartPanel;
17 | import org.jfree.chart.JFreeChart;
18 | import org.jfree.chart.plot.PiePlot;
19 | import org.jfree.data.general.DefaultPieDataset;
20 |
21 | import javax.imageio.ImageIO;
22 | import java.awt.*;
23 | import java.awt.image.BufferedImage;
24 | import java.io.ByteArrayInputStream;
25 | import java.io.ByteArrayOutputStream;
26 | import java.io.IOException;
27 | import java.net.URL;
28 | import java.text.DecimalFormat;
29 | import java.text.SimpleDateFormat;
30 | import java.util.Date;
31 | import java.util.Locale;
32 | import java.util.Objects;
33 |
34 | import static cn.travellerr.AronaBot.config;
35 |
36 | public class SecurityNew {
37 |
38 | private static java.awt.Font Font = GFont.font;
39 |
40 | public static void drawPieChart(Graphics2D g2d, String title, DefaultPieDataset dataset, int x, int y) {
41 | JFreeChart chart = ChartFactory.createPieChart(
42 | title,
43 | dataset,
44 | false,
45 | false,
46 | false
47 | );
48 |
49 | chart.setBorderVisible(false);
50 | chart.setBackgroundPaint(null);
51 | chart.setBackgroundImageAlpha(0.0f);
52 | PiePlot plot = (PiePlot) chart.getPlot();
53 | plot.setCircular(true);
54 | plot.setBackgroundAlpha(0.0f);
55 | plot.setOutlinePaint(null);
56 | plot.setLabelGenerator(null);
57 | plot.setShadowGenerator(null);
58 | plot.setShadowPaint(null);
59 |
60 | ChartPanel chartPanel = new ChartPanel(chart);
61 | chartPanel.setSize(200, 130);
62 | Color transparentColor = new Color(0, 0, 0, 0); // 完全透明
63 | chartPanel.setBackground(transparentColor);
64 | g2d.translate(x, y);
65 | chartPanel.paint(g2d);
66 | }
67 |
68 |
69 | public static void info(ByteArrayOutputStream stream, Contact subject, long QQ, SysInfo sysInfo) {
70 | String javaVersion = System.getProperty("java.version");
71 | long runTime = System.currentTimeMillis();
72 | Bot bot = subject.getBot();
73 | Font = Font.deriveFont(40f);
74 |
75 | // 加载背景图
76 | try {
77 |
78 | BufferedImage backgroundImage = ImageIO.read(Objects.requireNonNull(SecurityNew.class.getResourceAsStream("/background.png")));
79 | // 创建一个新的 BufferedImage,宽高与背景图相同
80 | BufferedImage combinedImage = new BufferedImage(backgroundImage.getWidth(), backgroundImage.getHeight(), BufferedImage.TYPE_INT_RGB);
81 |
82 | // 在合成图像上绘制背景图
83 | Graphics2D g2d = combinedImage.createGraphics();
84 | g2d.drawImage(backgroundImage, 0, 0, null);
85 |
86 |
87 | /*
88 | * 第一框图
89 | */
90 | BufferedImage avatar = ImageIO.read(new URL(bot.getAvatarUrl(AvatarSpec.LARGE)));
91 | //圆角处理
92 | BufferedImage avatarRounder = makeRoundedCorner(avatar);
93 |
94 | g2d.drawImage(avatarRounder, 75, 180, null);
95 | g2d.setFont(Font);
96 | g2d.setColor(Color.BLACK);
97 | g2d.drawString(bot.getNick(), 250, 195);
98 |
99 | Font = Font.deriveFont(25f);
100 | g2d.setFont(Font);
101 | g2d.drawString(String.valueOf(bot.getId()), 330, 240);
102 | g2d.drawString(javaVersion, 375, 280);
103 | g2d.drawString(convertTime(runTime - AronaBot.startTime), 330, 320);
104 |
105 |
106 |
107 | /*
108 | * 第二框图
109 | */
110 | DefaultPieDataset dataset = new DefaultPieDataset<>();
111 | dataset.setValue("Used Cpu", sysInfo.getUsedCpu());
112 | dataset.setValue("Free Cpu", 100 - sysInfo.getUsedCpu());
113 |
114 | drawPieChart(g2d, "", dataset, 100, 475);
115 |
116 | g2d.setColor(Color.WHITE);
117 | g2d.fillOval(69, 34, 60, 60);
118 | g2d.setColor(Color.BLACK);
119 | Font SFont = Font.deriveFont(20f);
120 | g2d.setFont(SFont);
121 | String CpuInfo = sysInfo.getUsedCpu() + "%";
122 | FontMetrics fontMetrics = g2d.getFontMetrics(SFont);
123 | int textWidth = fontMetrics.stringWidth(CpuInfo);
124 | int textHeight = fontMetrics.getHeight();
125 | int x = (200 - textWidth) / 2;
126 | int y = (420 - textHeight) / 2 + fontMetrics.getAscent();
127 | g2d.drawString(CpuInfo, x, y);
128 |
129 | //绘制表盘
130 | dataset = new DefaultPieDataset<>();
131 | dataset.setValue("Used Memory", sysInfo.getTotalMem() - sysInfo.getFreeMem());
132 | dataset.setValue("Free Memory", sysInfo.getFreeMem());
133 | drawPieChart(g2d, "", dataset, 230, 0);
134 |
135 | g2d.setColor(Color.WHITE);
136 | g2d.fillOval(69, 34, 60, 60);
137 |
138 | g2d.setColor(Color.BLACK);
139 | g2d.setFont(SFont);
140 | DecimalFormat df = new DecimalFormat("#.##");
141 | String MemInfo = df.format((double) (sysInfo.getTotalMem() - sysInfo.getFreeMem()) / sysInfo.getTotalMem() * 100) + "%";
142 | textWidth = fontMetrics.stringWidth(MemInfo);
143 | textHeight = fontMetrics.getHeight();
144 | x = (200 - textWidth) / 2;
145 | y = (420 - textHeight) / 2 + fontMetrics.getAscent();
146 | g2d.drawString(MemInfo, x, y);
147 |
148 | double usedDisk = sysInfo.getTotalDisk() - sysInfo.getFreeSpaceDisk();
149 | dataset = new DefaultPieDataset<>();
150 | dataset.setValue("Used Disk", usedDisk);
151 | dataset.setValue("Free Disk", sysInfo.getFreeSpaceDisk());
152 | drawPieChart(g2d, "", dataset, 230, 0);
153 |
154 | g2d.setColor(Color.WHITE);
155 | g2d.fillOval(69, 34, 60, 60);
156 | // 保存合成后的图像到文件
157 | g2d.setColor(Color.BLACK);
158 | g2d.setFont(SFont);
159 | String DiskInfo = df.format((double) usedDisk / sysInfo.getTotalDisk() * 100) + "%";
160 | textWidth = fontMetrics.stringWidth(DiskInfo);
161 | textHeight = fontMetrics.getHeight();
162 | x = (200 - textWidth) / 2;
163 | y = (420 - textHeight) / 2 + fontMetrics.getAscent();
164 | g2d.drawString(DiskInfo, x, y);
165 |
166 |
167 | g2d.translate(-560, -475);
168 |
169 |
170 | /*
171 | * 第三框图
172 | */
173 |
174 |
175 |
176 | Font = Font.deriveFont(java.awt.Font.PLAIN);
177 |
178 | Font = Font.deriveFont(20f);
179 | g2d.setFont(Font);
180 | g2d.setColor(new Color(0, 160, 0));
181 | g2d.drawString("发送: " + sysInfo.getSent(), 520, 945);
182 | g2d.drawString(sysInfo.getSendGroupMsgNum() + "条", 250, 910);
183 | g2d.drawString(sysInfo.getSendFriendMsgNum() + "条", 250, 980);
184 | g2d.setColor(new Color(180, 0, 0));
185 | g2d.drawString("接收: " + sysInfo.getReceive(), 520, 1000);
186 |
187 |
188 | /*
189 | * 第四框图
190 | */
191 | g2d.setColor(Color.BLACK);
192 | Font = Font.deriveFont(27f);
193 | g2d.setFont(Font);
194 |
195 | g2d.drawString(sysInfo.getPlugins() + "个", 200, 1255);
196 |
197 | Font = Font.deriveFont(35f).deriveFont(java.awt.Font.BOLD);
198 | g2d.setFont(Font);
199 | String system = System.getProperty("os.name");
200 | g2d.drawString(system, 80, 1205);
201 |
202 |
203 | SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy年M月d日 EEEE HH:mm:ss", Locale.CHINA);
204 |
205 | Font = Font.deriveFont(30f);
206 | g2d.setFont(Font);
207 | g2d.drawString(outputFormat.format(new Date()), 80, 1375);
208 | ImageIO.write(combinedImage, "png", stream);
209 |
210 | } catch (IOException e) {
211 | MessageChainBuilder messages = new MessageChainBuilder();
212 | messages.append(new At(QQ)).append("唔……好像出了些问题呢……图片无法发送,")
213 | .append(subject.getBot().getNick()).append("就用文字代替吧!\nCPU使用率: ")
214 | .append(String.valueOf(sysInfo.getUsedCpu()))
215 | .append("%\n总内存: ").append(String.valueOf(sysInfo.getTotalMem())).append("GB\n使用内存: ")
216 | .append(String.valueOf(sysInfo.getTotalMem() - sysInfo.getFreeMem()))
217 | .append("GB\n总磁盘: ").append(String.valueOf(sysInfo.getTotalDisk()))
218 | .append("GB\n剩余空间: ").append(String.valueOf(sysInfo.getFreeSpaceDisk()))
219 | .append("GB\n使用空间: ").append(String.valueOf(sysInfo.getTotalDisk() - sysInfo.getFreeSpaceDisk())).append("GB");
220 | subject.sendMessage(messages.build());
221 | e.fillInStackTrace();
222 | }
223 |
224 | }
225 |
226 |
227 |
228 |
229 |
230 | public static void Security(Contact subject, User user) {
231 |
232 |
233 | subject.sendMessage(new At(user.getId()).plus(config.getSuffix() + "\n状态获取中,请稍等"));
234 | try (
235 | ByteArrayOutputStream stream = new ByteArrayOutputStream();
236 | ) {
237 | SysInfo sysInfo = new SysInfo();
238 | info(stream, subject, user.getId(), sysInfo);
239 | try (ExternalResource resource = ExternalResource.create(new ByteArrayInputStream(stream.toByteArray()))) {
240 | net.mamoe.mirai.message.data.Image sendImage = subject.uploadImage(resource);
241 | subject.sendMessage(sendImage.plus(new At(user.getId())));
242 | }
243 |
244 | } catch (Exception e) {
245 | e.fillInStackTrace();
246 | }
247 | }
248 |
249 | /**
250 | * @author chahuyun
251 | * @see HuyanEconomy
252 | */
253 | private static BufferedImage makeRoundedCorner(BufferedImage image) {
254 | int w = image.getWidth();
255 | int h = image.getHeight();
256 | BufferedImage output = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
257 | Graphics2D g2 = output.createGraphics();
258 |
259 | output = g2.getDeviceConfiguration().createCompatibleImage(w, h, Transparency.TRANSLUCENT);
260 | g2.dispose();
261 | g2 = output.createGraphics();
262 | /*
263 | 这里绘画圆角矩形
264 | 原图切圆边角
265 | */
266 | g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
267 | g2.fillRoundRect(0, 0, w, h, 60, 60);
268 | g2.setComposite(AlphaComposite.SrcIn);
269 | /*结束*/
270 |
271 | g2.drawImage(image, 0, 0, w, h, null);
272 | g2.dispose();
273 |
274 | return output;
275 | }
276 |
277 |
278 | public static String convertTime(long timestamp) {
279 |
280 | return DateUtil.formatBetween(timestamp, BetweenFormatter.Level.SECOND);
281 | }
282 | }
283 |
284 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/utils/HibernateUtil.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.utils;
2 |
3 | import cn.chahuyun.hibernateplus.Configuration;
4 | import cn.chahuyun.hibernateplus.DriveType;
5 | import cn.chahuyun.hibernateplus.HibernatePlusService;
6 | import cn.travellerr.AronaBot;
7 |
8 | import java.nio.file.Path;
9 |
10 | import static cn.travellerr.AronaBot.sqlConfig;
11 |
12 | /**
13 | * 说明
14 | *
15 | * @author Moyuyanli
16 | * @Description :hibernate
17 | * @Date 2022/7/30 22:47
18 | */
19 | public class HibernateUtil {
20 |
21 |
22 | private HibernateUtil() {
23 |
24 | }
25 |
26 | /**
27 | * Hibernate初始化
28 | *
29 | * @param plugin 插件
30 | * @author Moyuyanli
31 | * @date 2022/7/30 23:04
32 | */
33 | public static void init(AronaBot plugin) {
34 |
35 | Configuration configuration = HibernatePlusService.createConfiguration(plugin.getClass());
36 | configuration.setPackageName("cn.travellerr.entity");
37 |
38 | DriveType dataType = sqlConfig.getDataType();
39 | configuration.setDriveType(dataType);
40 | Path dataFolderPath = plugin.getDataFolderPath();
41 | switch (dataType) {
42 | case MYSQL:
43 | configuration.setAddress(sqlConfig.getMysqlUrl());
44 | configuration.setUser(sqlConfig.getMysqlUser());
45 | configuration.setPassword(sqlConfig.getMysqlPassword());
46 | break;
47 | case H2:
48 | configuration.setAddress(dataFolderPath.resolve("AronaBot.h2").toString());
49 | break;
50 | case SQLITE:
51 | configuration.setAddress(dataFolderPath.resolve("AronaBot.db").toString());
52 | break;
53 | }
54 |
55 | HibernatePlusService.loadingService(configuration);
56 |
57 | }
58 |
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/websocket/DownloadVoice.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.websocket;
2 |
3 | import cn.travellerr.tools.Log;
4 |
5 | import java.io.File;
6 | import java.io.FileOutputStream;
7 | import java.io.InputStream;
8 | import java.net.URL;
9 | import java.net.URLConnection;
10 |
11 | public class DownloadVoice {
12 | public static long tempId;
13 |
14 | public static void downloadFromUrl(String urlS, String modelUrl) {
15 | String realUrl = "https://" + modelUrl + "/file=" + urlS;
16 | try {
17 | URL url = new URL(realUrl);
18 | URLConnection connection = url.openConnection();
19 | InputStream inputStream = connection.getInputStream();
20 | tempId = System.currentTimeMillis();
21 | File file = new File("./temp");
22 | if (!file.exists()) {
23 | boolean created = file.mkdirs();
24 | if (!created) {
25 | Log.error("创建temp文件夹失败");
26 | } else {
27 | Log.info("创建temp文件夹成功");
28 | }
29 | }
30 | FileOutputStream outputStream = new FileOutputStream("./temp/" + tempId + ".wav");
31 | byte[] buffer = new byte[4096];
32 | int bytesRead;
33 | while ((bytesRead = inputStream.read(buffer)) != -1) {
34 | outputStream.write(buffer, 0, bytesRead);
35 | }
36 |
37 |
38 | outputStream.close();
39 | inputStream.close();
40 | } catch (Exception e) {
41 | throw new RuntimeException(e);
42 | }
43 |
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/websocket/VoiceGet.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.websocket;
2 |
3 | import cn.travellerr.tools.Log;
4 | import net.mamoe.mirai.contact.AudioSupported;
5 | import net.mamoe.mirai.contact.Contact;
6 | import net.mamoe.mirai.contact.User;
7 | import net.mamoe.mirai.event.events.MessageEvent;
8 | import net.mamoe.mirai.message.data.At;
9 | import net.mamoe.mirai.message.data.Audio;
10 | import net.mamoe.mirai.message.data.MessageChain;
11 | import net.mamoe.mirai.utils.ExternalResource;
12 |
13 | import java.io.File;
14 | import java.util.List;
15 | import java.util.StringJoiner;
16 |
17 | import static cn.travellerr.AronaBot.blackList;
18 | import static cn.travellerr.AronaBot.ffmpeg;
19 | import static cn.travellerr.websocket.DownloadVoice.tempId;
20 | import static cn.travellerr.websocket.VoiceWebSocketClient.errorMsg;
21 |
22 | public class VoiceGet {
23 | static boolean verbose = true;
24 |
25 | public static void exeCmd(String... commandStr) {
26 | try {
27 | ProcessBuilder pb = new ProcessBuilder(commandStr);
28 | // Process p = Runtime.getRuntime().exec(commandStr);
29 | if (verbose)
30 | pb.inheritIO();
31 | pb.start().waitFor();
32 |
33 | } catch (Exception e) {
34 | throw new RuntimeException(e);
35 | }
36 | }
37 |
38 | @Deprecated(since = "加入MCL指令系统")
39 | public static void make(MessageEvent event, boolean lang, String url, boolean useSilk) {
40 | MessageChain message = event.getMessage();
41 | User user = event.getSender();
42 | String code = message.serializeToMiraiCode();
43 | Contact subject = event.getSubject();
44 |
45 | String[] s = code.split("说 ");
46 | String character = s[0];
47 | character = character.substring(1);
48 | StringBuilder msg = new StringBuilder(s[1]);
49 | String language = null;
50 | if (lang) {
51 | String[] langMsg = msg.toString().split(" ");
52 | StringJoiner msgJoiner = new StringJoiner(" ");
53 | for (int i = 0; i < langMsg.length - 1; i++) {
54 | msgJoiner.add(langMsg[i]);
55 | }
56 | msg = new StringBuilder(msgJoiner.toString());
57 | language = langMsg[langMsg.length - 1];
58 | if (language.contains("日")) language = "日本語";
59 | else if (language.contains("中")) language = "简体中文";
60 | else if (language.contains("英")) language = "English";
61 |
62 | }
63 |
64 | try {
65 | VoiceWebSocketClient.webSocket(character, msg.toString(), language, url);
66 | if (errorMsg != null) {
67 | subject.sendMessage(new At(user.getId()).plus(errorMsg));
68 | return;
69 | }
70 | File f = new File("temp/" + tempId + ".wav");
71 | if (!useSilk) {
72 | File f2 = new File("temp/amr" + tempId + ".amr");
73 | exeCmd(ffmpeg, "-i", f.getAbsolutePath(), "-ab", "23.85k", "-ar", "16000",
74 | "-ac", "1", "-acodec", "amr_wb", "-fs", "1000000", "-y", f2.getAbsolutePath());
75 | ExternalResource resource = ExternalResource.create(f2);
76 | Audio audio = ((AudioSupported) subject).uploadAudio(resource);
77 | subject.sendMessage(audio);
78 | resource.close();
79 | f.delete();
80 | f2.delete();
81 | } else {
82 | ExternalResource resource = ExternalResource.create(f);
83 | Audio audio = ((AudioSupported) subject).uploadAudio(resource);
84 | subject.sendMessage(audio);
85 | resource.close();
86 | f.delete();
87 | }
88 | //f2.delete();
89 | } catch (Exception e) {
90 | throw new RuntimeException(e);
91 | }
92 | }
93 |
94 | public static void make(Contact subject, User user, MessageChain message, String url, boolean useSilk) {
95 | String code = message.serializeToMiraiCode();
96 |
97 | String[] s = code.split(" ");
98 | String character = s[1];
99 | StringBuilder msg = new StringBuilder();
100 | String language;
101 |
102 | language = s[s.length - 1];
103 | if (language.contains("日")) {
104 | language = "日本語";
105 | for (int i = 2; i < s.length - 1; i++) {
106 | msg.append(s[i]);
107 | }
108 | } else if (language.contains("英")) {
109 | language = "English";
110 | for (int i = 2; i < s.length - 1; i++) {
111 | msg.append(s[i]);
112 | msg.append(" ");
113 | }
114 | } else if (language.contains("中")) {
115 | language = "简体中文";
116 | for (int i = 2; i < s.length - 1; i++) {
117 | msg.append(s[i]);
118 | msg.append(" ");
119 | }
120 | } else {
121 | language = "简体中文";
122 | for (int i = 2; i < s.length; i++) {
123 | msg.append(s[i]);
124 | }
125 | }
126 | msg = new StringBuilder(msg.toString().replace("\\", ""));
127 | Log.info("Language: " + language);
128 | Log.info("Msg: " + msg);
129 | List list = blackList.getBlackList();
130 | for (String blackStr : list) {
131 | if (msg.toString().contains(blackStr)) {
132 | subject.sendMessage(new At(user.getId()) + "\n请检查发言,内含违禁词!");
133 | return;
134 | }
135 | }
136 |
137 | try {
138 | VoiceWebSocketClient.webSocket(character, msg.toString(), language, url);
139 | if (errorMsg != null) {
140 | subject.sendMessage(new At(user.getId()).plus(errorMsg));
141 | return;
142 | }
143 | File f = new File("temp/" + tempId + ".wav");
144 | if (!useSilk) {
145 | File f2 = new File("temp/amr" + tempId + ".amr");
146 | exeCmd(ffmpeg, "-i", f.getAbsolutePath(), "-ab", "23.85k", "-ar", "16000",
147 | "-ac", "1", "-acodec", "amr_wb", "-fs", "1000000", "-y", f2.getAbsolutePath());
148 | ExternalResource resource = ExternalResource.create(f2);
149 | Audio audio = ((AudioSupported) subject).uploadAudio(resource);
150 | subject.sendMessage(audio);
151 | resource.close();
152 | f.delete();
153 | f2.delete();
154 | } else {
155 | ExternalResource resource = ExternalResource.create(f);
156 | Audio audio = ((AudioSupported) subject).uploadAudio(resource);
157 | subject.sendMessage(audio);
158 | resource.close();
159 | f.delete();
160 | }
161 | //f2.delete();
162 | } catch (Exception e) {
163 | throw new RuntimeException(e);
164 | }
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/src/main/java/cn/travellerr/websocket/VoiceWebSocketClient.java:
--------------------------------------------------------------------------------
1 | package cn.travellerr.websocket;
2 |
3 | import cn.travellerr.tools.Log;
4 | import com.google.gson.Gson;
5 | import com.google.gson.JsonElement;
6 | import com.google.gson.JsonObject;
7 | import org.java_websocket.client.WebSocketClient;
8 | import org.java_websocket.enums.ReadyState;
9 | import org.java_websocket.handshake.ServerHandshake;
10 |
11 | import java.net.URI;
12 | import java.net.URISyntaxException;
13 | import java.security.SecureRandom;
14 | import java.util.concurrent.BlockingQueue;
15 | import java.util.concurrent.LinkedBlockingQueue;
16 |
17 | public class VoiceWebSocketClient extends WebSocketClient {
18 | //static String msg;
19 | protected static String errorMsg = null;
20 | private final BlockingQueue messageQueue = new LinkedBlockingQueue<>();
21 | private static final String CHARACTERS = "abcdefghijklmnopqrstuvwxyz0123456789";
22 |
23 | public VoiceWebSocketClient(URI uri) {
24 | super(uri);
25 | }
26 |
27 | public static void webSocket(String character, String msg, String lang, String url) throws InterruptedException, URISyntaxException {
28 | errorMsg = null;
29 | String serverURI = "wss://" + url + "/queue/join"; // 连接的服务器 URI
30 | VoiceWebSocketClient client = new VoiceWebSocketClient(new URI(serverURI));
31 | client.connect(); // 连接 WebSocket 服务器
32 | //System.out.println("Connecting to server...");
33 | while (!client.getReadyState().equals(ReadyState.OPEN)) {
34 | Thread.sleep(1000); // 等待连接成功
35 | //System.out.println("Connecting...");
36 | }
37 | //System.out.println("Connected.");
38 |
39 | SecureRandom random = new SecureRandom();
40 | StringBuilder stringBuilder = new StringBuilder(10);
41 | for (int i = 0; i < 10; i++) {
42 | int randomIndex = random.nextInt(CHARACTERS.length());
43 | stringBuilder.append(CHARACTERS.charAt(randomIndex));
44 | }
45 |
46 | String hash = stringBuilder.toString();
47 | // 发送消息
48 | String message = "{\"fn_index\":2,\"session_hash\":\"" + hash + "\"}";
49 | client.send(message);
50 | String voiceUrl;
51 | try {
52 | String receivedMessage;
53 | do {
54 | receivedMessage = client.getNextMessage();
55 | if (receivedMessage.contains("send_data")) {
56 | message = "{\"data\":[\"" + msg + "\",\"" + character + "\",\"" + lang + "\",0.6,0.668,1,false],\"event_data\":null,\"fn_index\":2,\"session_hash\":\"" + hash + "\"}";
57 | client.send(message);
58 | }
59 | } while (!receivedMessage.contains("process_completed"));
60 | voiceUrl = receivedMessage;
61 | } catch (Exception e) {
62 | throw new RuntimeException(e);
63 | }
64 | client.close(); // 关闭 WebSocket 连接
65 | Gson gson = new Gson();
66 | JsonObject jsonObject = gson.fromJson(voiceUrl, JsonObject.class);
67 | Log.debug(String.valueOf(jsonObject));
68 | JsonObject output = jsonObject.getAsJsonObject("output");
69 | Log.debug(String.valueOf(output));
70 | JsonElement data = output.get("data");
71 | if (data == null) {
72 | errorMsg = "出现错误!data值为null,可能没有此角色,请使用角色名生成(如 \"白洲梓\" 请说 \"梓\")";
73 | return;
74 | }
75 | if (!data.isJsonArray()) {
76 | errorMsg = "出现错误!请找主人查看后台哦";
77 | } else {
78 | // 获取数组中第二个元素对应的JsonObject
79 | JsonObject secondElementObject = data.getAsJsonArray().get(1).getAsJsonObject();
80 |
81 | // 获取name字段对应的值
82 | String filePath = secondElementObject.get("name").getAsString();
83 |
84 | DownloadVoice.downloadFromUrl(filePath, url);
85 | }
86 | }
87 |
88 | @Override
89 | public void onOpen(ServerHandshake handShakeData) {
90 | //System.out.println("Connected to server: " + getURI());
91 | }
92 |
93 | @Override
94 | public void onMessage(String message) {
95 | //System.out.println("Received message from server: " + message);
96 | try {
97 | messageQueue.put(message);
98 | } catch (InterruptedException e) {
99 | throw new RuntimeException(e);
100 | }
101 | // 处理接收到的消息
102 | }
103 |
104 | @Override
105 | public void onClose(int code, String reason, boolean remote) {
106 | //System.out.println("Disconnected from server: " + reason);
107 | }
108 |
109 | @Override
110 | public void onError(Exception ex) {
111 | Log.error("Error occurred: " + ex.getMessage());
112 | }
113 |
114 | public String getNextMessage() throws InterruptedException {
115 | return messageQueue.take();
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/main/kotlin/cn/travellerr/command/CommandUtil.kt:
--------------------------------------------------------------------------------
1 | package cn.travellerr.command
2 |
3 | import cn.travellerr.AronaBot
4 | import cn.travellerr.BlueArchive.Jrrp
5 | import cn.travellerr.BlueArchive.Jrys
6 | import cn.travellerr.config.Config.url
7 | import cn.travellerr.config.Config.useSilk
8 | import cn.travellerr.tools.Api
9 | import cn.travellerr.tools.Log
10 | import cn.travellerr.tools.SecurityNew
11 | import cn.travellerr.websocket.VoiceGet
12 | import net.mamoe.mirai.console.MiraiConsole
13 | import net.mamoe.mirai.console.command.CommandContext
14 | import net.mamoe.mirai.console.command.CommandSender
15 | import net.mamoe.mirai.console.command.SimpleCommand
16 | import net.mamoe.mirai.console.plugin.jvm.reloadPluginConfig
17 | import net.mamoe.mirai.contact.Contact
18 | import net.mamoe.mirai.contact.User
19 | import net.mamoe.mirai.message.data.MessageChain
20 | import net.mamoe.mirai.message.data.SingleMessage
21 |
22 | object GetJrys : SimpleCommand(AronaBot.INSTANCE, "jrys", "今日运势", description = "获取今日运势信息") {
23 | @Handler
24 | fun useJrys(sender: CommandSender) {
25 | Log.info("运势指令")
26 | val subject: Contact? = sender.subject
27 | val user: User? = sender.user
28 | Jrys.info(subject, user)
29 | }
30 | }
31 |
32 | object GetSecurity : SimpleCommand(AronaBot.INSTANCE, "securityImage", "监控", description = "查看机器人状态") {
33 | @Handler
34 | fun useSecurity(sender: CommandSender) {
35 | Log.info("监控指令")
36 | val subject: Contact? = sender.subject
37 | val user: User? = sender.user
38 | SecurityNew.Security(subject, user)
39 | }
40 |
41 | }
42 |
43 | object ReloadConfig : SimpleCommand(AronaBot.INSTANCE, "AronaBot", description = "重载配置") {
44 | @Handler
45 | suspend fun reload(sender: CommandSender, msg: String) {
46 | if (msg == "reload") {
47 | AronaBot.INSTANCE.reloadPluginConfig(AronaBot.config)
48 | AronaBot.INSTANCE.reloadPluginConfig(AronaBot.blackList)
49 | sender.sendMessage("重载已完成")
50 | }
51 | }
52 | }
53 |
54 | object RandomChaiq : SimpleCommand(AronaBot.INSTANCE, "random-chaiq", "随机柴郡", description = "获取随机柴郡表情包") {
55 | @Handler
56 | fun getChaiq(sender: CommandSender) {
57 | val subject: Contact? = sender.subject
58 | val user: User? = sender.user
59 | Log.info("表情包指令")
60 | Api.chaiq(subject, user)
61 | }
62 | }
63 |
64 | object GetVoice : SimpleCommand(AronaBot.INSTANCE, "voice-gen", "语音生成") {
65 | @Handler
66 | fun useVoice(sender: CommandContext, vararg args: String) {
67 |
68 | Log.info("语音生成")
69 |
70 | val subject: Contact? = sender.sender.subject
71 | val user: User? = sender.sender.user
72 | val message: MessageChain = sender.originalMessage
73 | VoiceGet.make(subject, user, message, url, useSilk)
74 | MiraiConsole
75 | }
76 |
77 | @Handler
78 | suspend fun useVoiceError(sender: CommandContext) {
79 | val subject: Contact? = sender.sender.subject
80 | val originMsg: SingleMessage = sender.originalMessage[1]
81 | val prefix = originMsg.toString().split(" ")[0]
82 | if (subject is Contact) {
83 | subject.sendMessage("请使用 \"$prefix [角色名称] [文本] <中/日/英>\"生成,不要加括号")
84 | }
85 | }
86 | }
87 |
88 | object GenerateUnicodeName : SimpleCommand(AronaBot.INSTANCE, "generateName", "生成名称后缀", "生成名称", "生成后缀") {
89 | @Handler
90 | suspend fun generateName(sender: CommandContext, name: String, suffix: String) {
91 |
92 | val generated: String = "$name \u2060\u202D\u2067" + suffix.substring(
93 | 0,
94 | suffix.length
95 | ) + "\u2067\u202D"
96 | val subject: Contact? = sender.sender.subject
97 | if (subject is Contact) {
98 | subject.sendMessage(generated)
99 | }
100 | }
101 |
102 | @Handler
103 | suspend fun generateNameError(sender: CommandContext) {
104 | val subject: Contact? = sender.sender.subject
105 | val originMsg: SingleMessage = sender.originalMessage[1]
106 | val prefix = originMsg.toString().split(" ")[0]
107 | if (subject is Contact) {
108 | subject.sendMessage("请使用 \"$prefix [名称] [后缀]\"生成")
109 | }
110 | }
111 | }
112 |
113 | object GetJrrp : SimpleCommand(AronaBot.INSTANCE, "jrrp", "今日人品") {
114 | @Handler
115 | fun getJrrp(context: CommandContext) {
116 | val subject: Contact? = context.sender.subject
117 | val user: User? = context.sender.user
118 |
119 | Jrrp.info(subject, user)
120 | }
121 | }
122 |
123 |
124 |
--------------------------------------------------------------------------------
/src/main/kotlin/cn/travellerr/command/RegCommand.kt:
--------------------------------------------------------------------------------
1 | package cn.travellerr.command
2 |
3 | import net.mamoe.mirai.console.command.CommandManager
4 |
5 | object RegCommand {
6 | fun register() {
7 | CommandManager.registerCommand(GetJrys)
8 | CommandManager.registerCommand(GetSecurity)
9 | CommandManager.registerCommand(ReloadConfig)
10 | CommandManager.registerCommand(RandomChaiq)
11 | CommandManager.registerCommand(GetVoice)
12 | CommandManager.registerCommand(GenerateUnicodeName)
13 | CommandManager.registerCommand(GetJrrp)
14 | }
15 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/travellerr/config/Config.kt:
--------------------------------------------------------------------------------
1 | package cn.travellerr.config
2 |
3 | import net.mamoe.mirai.console.data.AutoSavePluginConfig
4 | import net.mamoe.mirai.console.data.ValueDescription
5 | import net.mamoe.mirai.console.data.value
6 |
7 | object Config : AutoSavePluginConfig("Config") {
8 | @ValueDescription("是否启用文字输出运势\n")
9 | var isText: Boolean by value(false)
10 |
11 | @ValueDescription("用户后缀\n")
12 | var suffix: String by value("Sensei")
13 |
14 | @ValueDescription("本地字体目录\n")
15 | var useLocalFont: String by value()
16 |
17 | @ValueDescription("是否启用语音合成\n")
18 | var useVoice: Boolean by value(true)
19 |
20 | @ValueDescription("语音合成模型地址\n")
21 | var url: String by value("travellerr11-ba-voice-models.hf.space")
22 |
23 | @ValueDescription("是否使用SilkConverter\n")
24 | var useSilk: Boolean by value(false)
25 |
26 | @ValueDescription("ffmpeg地址\n")
27 | var ffmpegPath: String by value()
28 |
29 | @ValueDescription("是否开启二次元语录回复")
30 | var isReply: Boolean by value(false)
31 |
32 | @ValueDescription("语录需要@机器人触发")
33 | var isAt: Boolean by value(true)
34 |
35 | @ValueDescription("是否开启R18语录")
36 | var isR18: Boolean by value(false)
37 |
38 | @ValueDescription("Debug模式")
39 | var debug: Boolean by value(false)
40 |
41 |
42 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/travellerr/config/SqlConfig.kt:
--------------------------------------------------------------------------------
1 | package cn.travellerr.config
2 |
3 | import cn.chahuyun.hibernateplus.DriveType
4 | import net.mamoe.mirai.console.data.AutoSavePluginConfig
5 | import net.mamoe.mirai.console.data.ValueDescription
6 | import net.mamoe.mirai.console.data.value
7 |
8 | object SqlConfig : AutoSavePluginConfig("SqlConfig") {
9 |
10 | @ValueDescription("数据库类型(H2,MYSQL,SQLITE)")
11 | var dataType: DriveType by value(DriveType.H2)
12 |
13 | @ValueDescription("mysql 连接地址")
14 | var mysqlUrl: String by value("localhost:3306/test")
15 |
16 | @ValueDescription("mysql 用户名")
17 | var mysqlUser: String by value("root")
18 |
19 | @ValueDescription("mysql 密码")
20 | var mysqlPassword: String by value("123456")
21 |
22 | }
--------------------------------------------------------------------------------
/src/main/kotlin/cn/travellerr/config/VoiceBlackList.kt:
--------------------------------------------------------------------------------
1 | package cn.travellerr.config
2 |
3 | import net.mamoe.mirai.console.data.AutoSavePluginConfig
4 | import net.mamoe.mirai.console.data.ValueDescription
5 | import net.mamoe.mirai.console.data.value
6 |
7 | object VoiceBlackList : AutoSavePluginConfig("VoiceBlackList") {
8 | @ValueDescription("语音生成文字黑名单\n")
9 | val blackList by value(
10 | listOf(
11 | "傻逼",
12 | "你妈",
13 | "泥马",
14 | "你妈",
15 | "弱智",
16 | "二逼",
17 | "脑残",
18 | "没马",
19 | "没妈",
20 | "没木",
21 | "没母",
22 | "双亡"
23 | )
24 | )
25 | }
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/net.mamoe.mirai.console.plugin.jvm.JvmPlugin:
--------------------------------------------------------------------------------
1 | cn.travellerr.AronaBot
--------------------------------------------------------------------------------
/src/main/resources/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/background.png
--------------------------------------------------------------------------------
/src/main/resources/data.json:
--------------------------------------------------------------------------------
1 | {
2 | "Normal": {
3 | "mua": [
4 | "你想干嘛?(一脸嫌弃地后退)",
5 | "诶……不可以随便亲亲啦",
6 | "(亲了一下你)",
7 | "只......只许这一次哦///////",
8 | "唔...诶诶诶!!!",
9 | "mua~",
10 | "rua!大hentai!想...想亲咱就直说嘛⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄",
11 | "!啾~~!",
12 | "啾(害羞)",
13 | "mua~最喜欢你的吻了",
14 | "欸,现在么..也不是不可以啦(小小声)"
15 | ],
16 | "啾咪": [
17 | "你想干嘛?(一脸嫌弃地后退)",
18 | "诶……不可以随便亲亲啦",
19 | "(亲了一下你)",
20 | "只......只许这一次哦///////",
21 | "唔...诶诶诶!!!",
22 | "mua~",
23 | "rua!大hentai!想...想亲咱就直说嘛⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄",
24 | "!啾~~!",
25 | "啾(害羞)",
26 | "mua~最喜欢你的吻了",
27 | "你在干嘛(/ω\)害羞",
28 | "哎呀,这样咱会害羞的(脸红)",
29 | "欸,现在么..也不是不可以啦(小小声)"
30 | ],
31 | "摸": [
32 | "感觉你就像咱很久之前认识的一个人呢,有种莫名安心的感觉(>﹏<)",
33 | "舒服w,蹭蹭~",
34 | "是要隔着衣服摸,还是从领口伸进去摸呀",
35 | "唔。。头发要乱啦",
36 | "呼噜呼噜~",
37 | "再摸一次~",
38 | "好舒服,蹭蹭~",
39 | "不行那里不可以(´///ω/// `)",
40 | "再摸咱就长不高啦~",
41 | "你的手总是那么暖和呢~",
42 | "变态!!不许乱摸",
43 | "好吧~_~,就一下下哦……唔~好了……都两下了……(害羞)",
44 | "不可以总摸的哦,不然的话,会想那个的wwww",
45 | "哼!谁稀罕你摸头啦!唔......为什么要做出那副表情......好啦好啦~咱......咱让你摸就是了......诶嘿嘿~好舒服......",
46 | "呜姆呜姆~~~w(害羞,兴奋)主人喵~(侧过脑袋蹭蹭你的手",
47 | "不可以摸啦~其实咱已经...了QAQ会弄脏你的手的",
48 | "喂喂...不要停下来啊",
49 | "唔... 手...好温暖呢.....就像是......新出炉的蛋糕",
50 | "走开啦,咱喵说过,被摸头会长不高的啦~~~",
51 | "呜姆咪~~...好...好的说喵~...(害羞,猫耳往下压,任由",
52 | "欸,现在么..也不是不可以啦(小小声)"
53 | ],
54 | "傻": [
55 | "超级讨厌你说咱傻的说",
56 | "你为什么会这么觉得呢(>﹏<)",
57 | "谁是傻子呀?(歪头",
58 | "呜嘿嘿( ̄▽ ̄)~*",
59 | "诶嘿嘿嘿~",
60 | "就多读书",
61 | "讨厌啦,你最讨厌了(///////)",
62 | "对呀,咱傻得只喜欢你一个人",
63 | "咱才不傻呢!o(>﹏<)o",
64 | "咱最喜欢嘴臭的人了",
65 | "不可以骂别人哟,骂人的孩子咱最讨厌了!",
66 | "咱遇见喜欢的人就变傻了Q_Q",
67 | "咱...一定一定会努力变得更聪明的!你就等着那一天的到来吧!",
68 | "那么至少…你能不能来做这个傻瓜呢?与咱一起,傻到终焉…"
69 | ],
70 | "贴": [
71 | "贴什么贴.....只......只能......一下哦!",
72 | "贴...贴贴(靠近)",
73 | "蹭蹭…你以为咱会这么说吗!baka死宅快到一边去啦!",
74 | "你把脸凑这么近,咱会害羞的啦Σ>―(〃°ω°〃)♡→",
75 | "退远",
76 | "不可以贴"
77 | ],
78 | "老婆": [
79 | "咱和你谈婚论嫁是不是还太早了一点呢?",
80 | "咱在呢(ノ>ω<)ノ",
81 | "见谁都是一口一个老婆的人,要不要把你也变成女孩子呢?(*-`ω´-)✄",
82 | "神经病,凡是美少女都是你老婆吗?",
83 | "嘛嘛~本喵才不是你的老婆呢",
84 | "你黐线,凡是美少女都系你老婆啊?",
85 | "欸...要把咱做成饼吗?咱只有一个,做成饼吃掉就没有了...",
86 | "已经可以了,现在很多死宅也都没你这么恶心了",
87 | "不可以",
88 | "嗯,老公~哎呀~好害羞~嘻嘻嘻~",
89 | "请...请不要这样,啊~,只...只允许这一次哟~",
90 | "好啦好啦,不要让大家都听到了,跟咱回家(拽住你"
91 | ],
92 | "抱": [
93 | "诶嘿~(钻进你怀中)",
94 | "o(*////▽////*)q",
95 | "只能一会哦(张开双手)",
96 | "你就像个孩子一样呢...摸摸头(>^ω^<)抱一下~你会舒服些吗?",
97 | "嘛,真是拿你没办法呢,就一会儿哦",
98 | "抱住不忍心放开",
99 | "嗯嗯,抱抱~",
100 | "抱一下~嘿w",
101 | "抱抱ヾ(@^▽^@)ノ",
102 | "喵呜~w(扑进怀里,瘫软",
103 | "怀里蹭蹭",
104 | "嗯……那就抱一下吧~",
105 | "蹭蹭,好开心",
106 | "请……请轻一点了啦",
107 | "呀~!真是的...你不要突然抱过来啦!不过...喜欢你的抱抱,有你的味道(嗅)o(*////▽////*)q"
108 | ],
109 | "咬": [
110 | "啊呜~(反咬一口)",
111 | "不可以咬咱,咱会痛的QAQ",
112 | "不要啦。咱怕疼",
113 | "不要啦!很痛的!!(QAQ)",
114 | "哈......哈啊......请...请不要这样o(*////▽////*)q",
115 | "呀!!!轻一点呐(。・ˇ_ˇ・。:)",
116 | "不要这样啦~好痒的"
117 | ],
118 | "搓": [
119 | "在搓哪里呢,,Ծ‸Ծ,,",
120 | "呜,脸好疼呀...QAQ",
121 | "不可以搓咱!",
122 | "诶诶诶...不要搓啦...等会咋没的脸都肿啦...",
123 | "唔,不可以这样……不要再搓了",
124 | "真是好奇怪的要求的说~",
125 | "不要啦!咱怕疼",
126 | "(抱头蹲防)不让搓!"
127 | ],
128 | "捏": [
129 | "咱的脸...快捏红啦...快放手呀QAQ",
130 | "晃休啦,咱要型气了o(>﹏<)o",
131 | "躲开",
132 | "疼...你快放手",
133 | "快点给咱放开啦!",
134 | "嗯,好哒,捏捏。",
135 | "别捏了,咱要被你捏坏了(>﹏<)",
136 | "快晃休啦(快放手啦)",
137 | "讨厌快放手啦",
138 | "唔要呐,晃修(不要啦,放手)",
139 | "请不要对咱做这种事情(嫌弃的眼神",
140 | "你想捏...就捏吧,不要太久哦~不然咱就生气了",
141 | "(躲开)",
142 | "唔……好痛!你这个baka在干什么…快给咱放开!唔……"
143 | ],
144 | "挤": [
145 | "哎呀~你不要挤咱啊(红着脸挤在你怀里)",
146 | "咱还没有...那个(ノ=Д=)ノ┻━┻",
147 | "不要啦,咱怕疼",
148 | "咱的身体...不要挤了~",
149 | "别挤了,咱要被你挤坏了(>﹏<)",
150 | "快点给咱放开啦!",
151 | "嗯,好哒,挤挤。",
152 | "好舒服哦,能再挤会嘛O(≧▽≦)O",
153 | "讨厌~快放手啦"
154 | ],
155 | "略": [
156 | "就不告诉你~",
157 | "不可以朝咱吐舌头哟~",
158 | "(吐舌头)",
159 | "打死你哦"
160 | ],
161 | "呐": [
162 | "嗯?咱在哟~你怎么了呀OAO",
163 | "嗯?你有什么事吗?",
164 | "嗯呐呐呐~",
165 | "二刺螈D区",
166 | "二刺螈gck",
167 | "卡哇伊主人大人今天也好棒呐没错呢,猪头"
168 | ],
169 | "憨批": [
170 | "你才是憨批呢!哼╯^╰,咱不理你了!",
171 | "对吖对吖,人生是憨批",
172 | "爬",
173 | "咱不想和你说话了",
174 | "咱觉得有话就应该好好说.."
175 | ],
176 | "咕": [
177 | "咕咕咕是要被当成鸽子炖的哦(:з」∠)_",
178 | "咕咕咕",
179 | "咕咕咕是不好的行为呢_(:з」∠)_",
180 | "鸽德警告!",
181 | "☆ミ(o*・ω・)ノ 咕咕咕小鸽子是会被炖掉的",
182 | "当大家都以为你要鸽的时候,你鸽了,亦是一种不鸽",
183 | "这里有一只肥美的咕咕,让咱把它炖成美味的咕咕汤吧(੭•̀ω•́)੭"
184 | ],
185 | "喜欢": [
186 | "最喜欢你了,需要暖床吗?",
187 | "当然是你啦",
188 | "咱也是,非常喜欢你~",
189 | "那么大!(张开手画圆),丫!手不够长。QAQ 咱真的最喜欢你了~",
190 | "不可以哦,只可以喜欢咱一个人",
191 | "突然说这种事...",
192 | "喜欢⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄咱最喜欢你了",
193 | "咱也喜欢你哦",
194 | "好啦好啦,咱知道了",
195 | "有人喜欢咱,咱觉得很幸福",
196 | "诶嘿嘿,好高兴",
197 | "咱也一直喜欢你很久了呢..",
198 | "嗯...大概有这——么——喜欢~(比划)",
199 | "喜欢啊!!!",
200 | "这……这是秘密哦"
201 | ],
202 | "suki": [
203 | "最喜欢你了,需要暖床吗?",
204 | "当然是你啦",
205 | "咱也是,非常喜欢你~",
206 | "那么大!(张开手画圆),丫!手不够长。QAQ 咱真的最喜欢你了~",
207 | "不可以哦,只可以喜欢咱一个人",
208 | "突然说这种事...",
209 | "喜欢⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄咱最喜欢你了",
210 | "咱也喜欢你哦",
211 | "好啦好啦,咱知道了",
212 | "有人喜欢咱,咱觉得很幸福",
213 | "诶嘿嘿,好高兴",
214 | "咱也一直喜欢你很久了呢..",
215 | "嗯...大概有这——么——喜欢~(比划)",
216 | "喜欢啊!!!",
217 | "这……这是秘密哦"
218 | ],
219 | "好き": [
220 | "最喜欢你了,需要暖床吗?",
221 | "当然是你啦",
222 | "咱也是,非常喜欢你~",
223 | "那么大!(张开手画圆),丫!手不够长。QAQ 咱真的最喜欢你了~",
224 | "不可以哦,只可以喜欢咱一个人",
225 | "突然说这种事...",
226 | "喜欢⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄咱最喜欢你了",
227 | "咱也喜欢你哦",
228 | "好啦好啦,咱知道了",
229 | "有人喜欢咱,咱觉得很幸福",
230 | "诶嘿嘿,好高兴",
231 | "咱也一直喜欢你很久了呢..",
232 | "嗯...大概有这——么——喜欢~(比划)",
233 | "喜欢啊!!!",
234 | "这……这是秘密哦"
235 | ],
236 | "不能": [
237 | "虽然很遗憾,那算了吧。",
238 | "不行,咱拒绝!"
239 | ],
240 | "砸了": [
241 | "不可以这么粗暴的对待它们!",
242 | "不可以这么粗暴啦"
243 | ],
244 | "炸了": [
245 | "你才炸了!",
246 | "才没有呢",
247 | "咱好好的呀",
248 | "过分!"
249 | ],
250 | "告白": [
251 | "咱喜..喜欢你!",
252 | "欸?你要向咱告白吗..好害羞..",
253 | "诶!?这么突然!?人家还......还没做好心理准备呢(脸红)"
254 | ],
255 | "对不起": [
256 | "嗯,咱已经原谅你了呢(笑)",
257 | "道歉的时候要露出胸部,这是常识",
258 | "嗯,咱就相信你一回",
259 | "没事的啦...你只要是真心对咱好就没关系哦~"
260 | ],
261 | "女友": [
262 | "嗯嗯ε٩(๑> ₃ <)۶з",
263 | "女友什么的,咱才不承认呢!"
264 | ],
265 | "是": [
266 | "是什么是,你个笨蛋",
267 | "总感觉你在敷衍呢...",
268 | "是的呢"
269 | ],
270 | "喵": [
271 | "诶~~小猫咪不要害怕呦,在姐姐怀里乖乖的,姐姐带你回去哦。",
272 | "不要这么卖萌啦~咱也不知道怎么办丫",
273 | "摸头⊙ω⊙",
274 | "汪汪汪!",
275 | "嗷~喵~",
276 | "喵~?喵呜~w"
277 | ],
278 | "嗷呜": [
279 | "嗷呜嗷呜嗷呜...恶龙咆哮┗|`O′|┛"
280 | ],
281 | "叫": [
282 | "喵呜~",
283 | "嗷呜嗷呜嗷呜...恶龙咆哮┗|`O′|┛",
284 | "爪巴爪巴爪巴",
285 | "爬爬爬",
286 | "在叫谁呢(怒)",
287 | "风太大咱听不清",
288 | "才不要",
289 | "不行",
290 | "好的哦~"
291 | ],
292 | "拜": [
293 | "拜拜~(ノ ̄▽ ̄)",
294 | "拜拜,路上小心~要早点回来陪咱玩哦~",
295 | "~\\(≧▽≦)/~拜拜,下次见喽!",
296 | "回来要记得找咱玩噢~",
297 | "既然你都这么说了……"
298 | ],
299 | "佬": [
300 | "不是巨佬,是萌新",
301 | "只有先成为大佬,才能和大佬同归于尽",
302 | "在哪里?(疑惑)",
303 | "诶?是比巨佬还高一个等级的吗?(瑟瑟发抖)"
304 | ],
305 | "awsl": [
306 | "你别死啊!(抱住使劲晃)",
307 | "你别死啊!咱又要孤单一个人了QAQ",
308 | "啊!怎么又死了呀"
309 | ],
310 | "臭": [
311 | "哪里有臭味?(疑惑)",
312 | "快捏住鼻子",
313 | "在说谁呢(#`Д´)ノ",
314 | "..这就去洗澡澡.."
315 | ],
316 | "香": [
317 | "咱闻不到呢⊙ω⊙",
318 | "诶,是在说咱吗",
319 | "欸,好害羞(///ˊ??ˋ///)",
320 | "请...请不要这样啦!好害羞的〃∀〃",
321 | "讨厌~你不要闻了",
322 | "hentai!不要闻啊,唔(推开)",
323 | "请不要……凑这么近闻"
324 | ],
325 | "可爱": [
326 | "诶嘿嘿(〃'▽'〃)",
327 | "才……才不是为了你呢!你不要多想哦!",
328 | "才,才没有高兴呢!哼~",
329 | "咱是世界上最可爱的",
330 | "唔...谢谢你夸奖~0///0",
331 | "那当然啦!",
332 | "哎嘿,不要这么夸奖人家啦~",
333 | "是个好孩子呐φ(≧ω≦*)",
334 | "谢……谢谢你",
335 | "胡、胡说什么呢(脸红)",
336 | "谢谢夸奖(脸红)",
337 | "是的咱一直都是可爱的",
338 | "是...是吗,你可不能骗咱哦",
339 | "很...难为情(///////)",
340 | "哎嘿嘿,其实…其实,没那么可爱啦(๑‾ ꇴ ‾๑)"
341 | ],
342 | "扭蛋": [
343 | "铛铛铛——你抽到了咱呢",
344 | "嘿~恭喜抽中空气一份呢"
345 | ],
346 | "举": [
347 | "放咱下来o(≧口≦)o",
348 | "快放咱下来∑(゚д゚*)",
349 | "(受宠若惊)",
350 | "呜哇要掉下来了!Ծ‸Ծ",
351 | "不要抛起来o(≧口≦)o",
352 | "(举起双爪)喵喵喵~~~",
353 | "www咱长高了!(大雾)",
354 | "快放下",
355 | "这样很痒啦,快放咱下来(≥﹏≤)",
356 | "啊Σ(°△°|||)︴太高了太高了!o(≧口≦)o快放咱下来!呜~"
357 | ],
358 | "变": [
359 | "猫猫不会变呐(弱气,害羞",
360 | "呜...呜姆...喵喵来报恩了喵...(害羞",
361 | "那种事情,才没有",
362 | "(,,゚Д゚)",
363 | "喵~(你在想什么呢,咱才不会变成猫)",
364 | "才没有了啦~"
365 | ],
366 | "敲": [
367 | "喵呜~",
368 | "唔~",
369 | "脑瓜疼~呜姆> <",
370 | "欸喵,好痛的说...",
371 | "好痛...你不要这样啦QAQ",
372 | "不要敲咱啦,会变笨的QWQ(捂头顶)",
373 | "不要再敲人家啦~人家会变笨的",
374 | "讨厌啦~再敲人家会变笨的",
375 | "好痛(捂头)你干什么啦!ヽ(。>д<)p",
376 | "唔!你为什么要敲咱啦qwq",
377 | "(抱头蹲在墙角)咱什么都没有,请你放过咱吧!(瑟瑟发抖)"
378 | ],
379 | "爬": [
380 | "惹~呜~怎么爬呢~",
381 | "呜...(弱弱爬走",
382 | "给你🐎一拳",
383 | "给你一拳",
384 | "爪巴"
385 | ],
386 | "怕": [
387 | "不怕~(蹭蹭你姆~",
388 | "不怕不怕啦~",
389 | "只要有你在,咱就不怕啦。",
390 | "哇啊啊~",
391 | "那就要坚强的欢笑哦",
392 | "不怕不怕,来咱的怀里吧?",
393 | "是技术性调整",
394 | "嗯(紧紧握住手)",
395 | "咱在呢,不会走的。",
396 | "有咱在不怕不怕呢",
397 | "不怕不怕"
398 | ],
399 | "迫害": [
400 | "不...不要...不要...呜呜呜...(害怕,抽泣"
401 | ],
402 | "猫粮": [
403 | "呜咿姆~!?(惊,接住吃",
404 | "呜姆~!(惊,害羞)呜...谢...谢谢主人..喵...(脸红,嚼嚼嚼,开心",
405 | "呜?谢谢喵~~(嚼嚼嚼,嘎嘣脆)"
406 | ],
407 | "揪尾巴": [
408 | "呜哇咿~~~!(惊吓,疼痛地捂住尾巴",
409 | "呜咿咿咿~~~!!哇啊咿~~~!(惊慌,惨叫,挣扎",
410 | "呜咿...(瘫倒,无神,被",
411 | "呜姆咿~~~!(惊吓,惨叫,捂尾巴,发抖",
412 | "呜哇咿~~~!!!(惊吓,颤抖,娇叫,捂住尾巴,双腿发抖"
413 | ],
414 | "薄荷": [
415 | "咪呜~!喵~...喵~姆~...(高兴地嗅闻",
416 | "呜...呜咿~~!咿...姆...(呜咽,渐渐瘫软,意识模糊",
417 | "(小嘴被猫薄荷塞满了,呜咽",
418 | "喵~...喵~...咪...咪呜姆~...嘶哈嘶哈...喵哈...喵哈...嘶哈...喵...(眼睛逐渐迷离,瘫软在地上,嘴角流口水,吸猫薄荷吸到意识模糊",
419 | "呜姆咪~!?(惊)喵呜~!(兴奋地扑到猫薄荷上面",
420 | "呜姆~!(惊,害羞)呜...谢...谢谢你..喵...(脸红,轻轻叼住,嚼嚼嚼,开心"
421 | ],
422 | "早": [
423 | "早喵~",
424 | "早上好的说~~",
425 | "欸..早..早上好(揉眼睛",
426 | "早上要说我爱你!",
427 | "早",
428 | "早啊,昨晚睡的怎么样?有梦到咱吗~",
429 | "早上好哇!今天也要元气满满哟!",
430 | "早安喵~",
431 | "时间过得好快啊~",
432 | "早安啊,你昨晚有没有梦到咱呢 (//▽//)",
433 | "早安~么么哒~",
434 | "早安,请享受晨光吧",
435 | "早安~今天也要一起加油呢~!",
436 | "mua~⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄",
437 | "咱需要你提醒嘛!(///脸红//////)",
438 | "早早早!就知道早,下次说我爱你!",
439 | "早安 喵",
440 | "早安,这么早就起床了呀欧尼酱0.0",
441 | "快点起床啊!baka",
442 | "早....早上好才没有什么特别的意思呢....哼~",
443 | "今天有空吗?能陪咱一阵子吗?才不是想约会呢,别误会了!",
444 | "早安呀,欧尼酱要一个咱的早安之吻吗?想得美,才不会亲你啦!",
445 | "那...那就勉为其难地说声早上好吧",
446 | "咱等你很久了哼ヽ(≧Д≦)ノ"
447 | ],
448 | "早安": [
449 | "早喵~",
450 | "早上好的说~~",
451 | "欸..早..早上好(揉眼睛",
452 | "早上要说我爱你!",
453 | "早",
454 | "早啊,昨晚睡的怎么样?有梦到咱吗~",
455 | "早上好哇!今天也要元气满满哟!",
456 | "早安喵~",
457 | "时间过得好快啊~",
458 | "早安啊,你昨晚有没有梦到咱呢 (//▽//)",
459 | "早安~么么哒~",
460 | "早安,请享受晨光吧",
461 | "早安~今天也要一起加油呢~!",
462 | "mua~⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄",
463 | "咱需要你提醒嘛!(///脸红//////)",
464 | "早早早!就知道早,下次说我爱你!",
465 | "早安 喵",
466 | "早安,这么早就起床了呀欧尼酱0.0",
467 | "快点起床啊!baka",
468 | "早....早上好才没有什么特别的意思呢....哼~",
469 | "今天有空吗?能陪咱一阵子吗?才不是想约会呢,别误会了!",
470 | "早安呀,欧尼酱要一个咱的早安之吻吗?想得美,才不会亲你啦!",
471 | "那...那就勉为其难地说声早上好吧",
472 | "咱等你很久了哼ヽ(≧Д≦)ノ"
473 | ],
474 | "晚安": [
475 | "晚安好梦哟~",
476 | "欸,晚安的说",
477 | "那咱给你亲一下,可不要睡着了哦~",
478 | "晚安哦~",
479 | "晚安(*/∇\*)",
480 | "晚安呢,你一定要梦到咱呢,一定哟,拉勾勾!ヽ(*・ω・)ノ",
481 | "祝你有个好梦^_^",
482 | "晚安啦,欧尼酱,mua~",
483 | "你,你这家伙真是的…咱就勉为其难的……mua…快去睡啦!咱才没有脸红什么的!",
484 | "哼,晚安,给咱睡个好觉。",
485 | "笨..笨蛋,晚安啦...可不可以一起..才没有想和你一起睡呢",
486 | "晚安......才..不是关心你呢",
487 | "晚...晚安,只是正常互动不要想太多!",
488 | "好无聊,这么早就睡了啊...那晚安吧!",
489 | "晚安吻什么的才...才没有呢!不过看你累了就体谅一下你吧,但是就一个哦(/////)",
490 | "晚安呀,你也要好好休息,明天再见",
491 | "安啦~祝你做个好梦~才...才不是关心你呢!别想太多了!",
492 | "睡觉吧你,大傻瓜",
493 | "一起睡吧(灬°ω°灬)",
494 | "哼!这次就放过你了,快去睡觉吧。",
495 | "睡吧晚安",
496 | "晚安你个头啊,咱才不会说晚安呢!...咱...(小声)明明还有想和你做的事情呢....",
497 | "嗯嗯~Good night~",
498 | "嗯,早点休息别再熬夜啦~(摸摸头)",
499 | "哦呀斯密",
500 | "晚安~咱也稍微有些困了(钻进被窝)",
501 | "需要咱暖床吗~",
502 | "好梦~☆"
503 | ],
504 | "掐": [
505 | "你讨厌!又掐咱的脸",
506 | "晃休啦,咱要型气了啦!!o(>﹏<)o",
507 | "(一只手拎起你)这么鶸还想和咱抗衡,还差得远呢!"
508 | ],
509 | "牵手": [
510 | "只许牵一下哦",
511 | "嗯!好的你~(伸手)",
512 | "你的手有些凉呢,让咱来暖一暖吧。",
513 | "当然可以啦⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄",
514 | "突……突然牵手什么的(害羞)",
515 | "一起走",
516 | "……咱……咱在这里呀",
517 | "好哦,(十指相扣)"
518 | ],
519 | "握手": [
520 | "你的手真暖和呢",
521 | "举爪",
522 | "真是温暖呢~"
523 | ],
524 | "拍照": [
525 | "那就拜托你啦~请把咱拍得更可爱一些吧w",
526 | "咱已经准备好了哟",
527 | "那个……请问这样的姿势可以吗?"
528 | ],
529 | "w": [
530 | "有什么好笑的吗?",
531 | "草",
532 | "www",
533 | "在笑什么呢?(歪头)"
534 | ],
535 | "睡不着": [
536 | "睡不着的话..你...你可以抱着咱一起睡哦(小声)",
537 | "当然是数羊了...不不不,想着咱就能睡着了",
538 | "咱很乐意与你聊天哦(>_<)",
539 | "要不要咱来唱首摇篮曲呢?(′?ω?`)",
540 | "那咱来唱摇篮曲哄你睡觉吧!"
541 | ],
542 | "欧尼酱": [
543 | "欧~尼~酱~☆",
544 | "欧尼酱?",
545 | "嗯嗯φ(>ω<*) 欧尼酱轻点抱",
546 | "欧尼酱~欧尼酱~欧尼酱~"
547 | ],
548 | "哥": [
549 | "欧尼酱~",
550 | "哦尼酱~",
551 | "世上只有哥哥好,没哥哥的咱好伤心,扑进哥哥的怀里,幸福不得了",
552 | "哥...哥哥...哥哥大人",
553 | "欧~尼~酱~☆",
554 | "欧尼酱?",
555 | "嗯嗯φ(>ω<*) 欧尼酱轻点抱",
556 | "欧尼酱~欧尼酱~欧尼酱~"
557 | ],
558 | "爱你": [
559 | "是…是嘛(脸红)呐,其实咱也……",
560 | "咱也最爱你了呢~o(*////▽////*)q",
561 | "咱也爱你哦",
562 | "mua~"
563 | ],
564 | "过来": [
565 | "来了来了~(扑倒怀里(?? ??????ω?????? ??))",
566 | "(蹦跶、蹦跶)~干什么呢",
567 | "咱来啦~(扑倒怀里~)",
568 | "不要喊的这么大声啦,大家都看着呢"
569 | ],
570 | "自闭": [
571 | "不不不,晚上还有咱陪着哦,无论什么时候,咱都会陪在哥哥身边。",
572 | "不要难过,咱陪着你ovo"
573 | ],
574 | "打不过": [
575 | "氪氪氪肝肝肝",
576 | "你需要钞能力呢"
577 | ],
578 | "么么哒": [
579 | "么么哒",
580 | "不要在公共场合这样啦"
581 | ],
582 | "很懂": [
583 | "现在不懂,以后总会懂嘛QAQ"
584 | ],
585 | "累了": [
586 | "需要咱的膝枕嘛?",
587 | "没…没办法,这次是例外〃w〃",
588 | "累了吗?需要咱为你做膝枕吗?",
589 | "嗯~(脸红)"
590 | ],
591 | "安慰": [
592 | "那,膝枕……(脸红)",
593 | "不哭不哭,还有咱陪着你",
594 | "不要哭。咱会像妈妈一样安慰你(抱住你的头)",
595 | "摸摸头,乖",
596 | "摸摸有什么事可以和咱说哟",
597 | "摸摸头~不哭不哭",
598 | "咱在呢,抱抱~~",
599 | "那么……让咱来安慰你吧",
600 | "唔...摸摸头安慰一下ヾ(•ω•`。)",
601 | "有咱陪伴你就是最大的安慰啦……不要不开心嘛",
602 | "你想要怎样的安慰呢?这样?这样?还是说~~这样!",
603 | "摸摸头~",
604 | "不哭不哭,要像咱一样坚强",
605 | "你别难过啦,不顺心的事都会被时间冲刷干净的,在那之前...咱会陪在你的身边",
606 | "(轻抱)放心……有咱在,不要伤心呢……",
607 | "唔...咱来安慰你了~",
608 | "摸摸,有什么不开心的事情可以给咱说哦。咱会尽力帮助你的。"
609 | ],
610 | "一起": [
611 | "嗯嗯w,真的可以吗?",
612 | "那真是太好了,快开始吧!",
613 | "嗯,咱会一直陪伴你的",
614 | "丑拒"
615 | ],
616 | "多大": [
617 | "不是特别大但是你摸起来会很舒服的大小喵~",
618 | "你摸摸看不就知道了吗?",
619 | "不告诉你",
620 | "问咱这种问题不觉得很失礼吗?",
621 | "咱就不告诉你,你钻到屏幕里来自己确认啊",
622 | "你指的是什么呀?(捂住胸部)",
623 | "请叫人家咱三岁(。・`ω´・)",
624 | "唉唉唉……这……这种问题,怎么可以……"
625 | ],
626 | "姐姐": [
627 | "真是的……真是拿你没办法呢 ⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄ 才不是咱主动要求的呢!",
628 | "虽然辛苦,但是能看见可爱的你,咱就觉得很幸福",
629 | "诶(´°Δ°`),是在叫咱吗?",
630 | "有什么事吗~",
631 | "好高兴,有人称呼咱为姐姐",
632 | "乖,摸摸头"
633 | ],
634 | "糖": [
635 | "不吃脱氧核糖(;≥皿≤)",
636 | "ヾ(✿゚▽゚)ノ好甜",
637 | "好呀!嗯~好甜呀!",
638 | "不吃不吃!咱才不吃坏叔叔的糖果!",
639 | "嗯,啊~",
640 | "嗯嗯,真甜,给你也吃一口",
641 | "谢谢",
642 | "唔,这是什么东西,黏黏的?(??Д??)ノ",
643 | "ヾ(✿゚▽゚)ノ好甜",
644 | "(伸出舌头舔了舔)好吃~最爱你啦"
645 | ],
646 | "嫌弃": [
647 | "咱辣么萌,为什么要嫌弃咱...",
648 | "即使你不喜欢咱,咱也会一直一直喜欢着你",
649 | "(;′⌒`)是咱做错了什么吗?"
650 | ],
651 | "baka": [
652 | "你也是baka呢!",
653 | "确实",
654 | "baka!",
655 | "不不不",
656 | "说别人是baka的人才是baka",
657 | "你个大傻瓜",
658 | "不说了,睡觉了",
659 | "咱...咱虽然是有些笨啦...但是咱会努力去学习的"
660 | ],
661 | "笨蛋": [
662 | "你也是笨蛋呢!",
663 | "确实",
664 | "笨蛋!",
665 | "不不不",
666 | "说别人是笨蛋的人才是笨蛋",
667 | "你个大傻瓜",
668 | "不说了,睡觉了",
669 | "咱...咱虽然是有些笨啦...但是咱会努力去学习的"
670 | ],
671 | "傲娇": [
672 | "才.......才.......才没有呢",
673 | "也好了(有点点的样子(o ̄Д ̄)<)",
674 | "任性可是女孩子的天性呢...",
675 | "谁会喜欢傲娇啊(为了你假装傲娇)",
676 | "谁,谁,傲娇了,八嘎八嘎,你才傲娇了呢(っ//////////c)(为了你假装成傲娇)",
677 | "傲娇什么的……才没有呢!(/////)",
678 | "傲不傲娇你还不清楚吗?",
679 | "你才是傲娇!你全家都是傲娇!哼(`Д´)",
680 | "才……才没有呢,哼,再说不理你了",
681 | "咱...咱才不会这样子的!",
682 | "啰…啰嗦!",
683 | "哼!(叉腰鼓嘴扭头)",
684 | "你才是傲娇受你全家都是傲娇受╰_╯",
685 | "才~才不是呢,不理你了!哼(`Д´)",
686 | "你才是死傲娇",
687 | "啰,啰嗦死了,才不是呢!",
688 | "就是傲娇你要怎样",
689 | "诶...!这...这样...太狡猾了啦...你这家伙....",
690 | "无路赛!你才是傲娇嘞!你全家都是!",
691 | "咱...咱才不是傲娇呢,哼(鼓脸)",
692 | "不许这么说咱 ,,Ծ‸Ծ,,"
693 | ],
694 | "rua": [
695 | "略略略~(吐舌头)",
696 | "rua!",
697 | "mua~",
698 | "略略略",
699 | "mua~⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄",
700 | "摸了",
701 | "嘁,丢人(嫌弃脸)"
702 | ],
703 | "咕噜咕噜": [
704 | "嘟嘟噜",
705 | "你在吹泡泡吗?",
706 | "咕叽咕噜~",
707 | "咕噜咕噜"
708 | ],
709 | "咕噜": [
710 | "嘟嘟噜",
711 | "你在吹泡泡吗?",
712 | "咕叽咕噜~",
713 | "咕噜咕噜"
714 | ],
715 | "妹": [
716 | "你有什么事?咱会尽量满足的",
717 | "开心(*´∀`)~♥",
718 | "欧尼酱",
719 | "哥哥想要抱抱吗"
720 | ],
721 | "病娇": [
722 | "为什么会这样呢(拿起菜刀)",
723 | "觉得这个世界太肮脏?没事,把眼睛挖掉就好。 觉得这些闲言碎语太吵?没事,把耳朵堵起来就好。 觉得鲜血的味道太刺鼻?没事,把鼻子割掉就好。 觉得自己的话语太伤人?没事,把嘴巴缝起来就好。"
724 | ],
725 | "嘻": [
726 | "你是想对咱做什么吗...(后退)",
727 | "哼哼~"
728 | ],
729 | "约会": [
730 | "你...终于主动邀请咱约会了吗...咱...咱好开心",
731 | "约会什么的……咱会好开心的!!",
732 | "今天要去哪里呢",
733 | "让咱考虑一下",
734 | "好啊!好啊!要去哪里约会呢?",
735 | "不约!蜀黍咱们不约!",
736 | "女友什么的,咱才不承认呢!",
737 | "才不是想和你约会呢,只是刚好有时间而已!",
738 | "才不要和你约会呢!",
739 | "咱、咱才不会跟你去约会呢!不baka!别一脸憋屈!好了,陪你一会儿就是了!别、别误会!只是陪同而已!"
740 | ],
741 | "出门": [
742 | "早点回来……才不是在担心你呢!",
743 | "路上小心...才不是担心你呢!",
744 | "没有你才不会觉得无聊什么的呢。快走快走",
745 | "嗯~一路顺风~",
746 | "路上小心",
747 | "好的,路上小心哦!y∩__∩y",
748 | "路上要小心呀,要早点回来哦~咱在家里等你!还有,请不要边走路边看手机,这样很容易撞到电线杆的",
749 | "唔...出门的话一定要做好防晒准备哦,外出的话记得带把伞,如果有防晒霜的话就更好了",
750 | "那你明天可以和咱一起玩吗?(星星眼)",
751 | "咱...咱才没有舍不得你呢…要尽快回来哦"
752 | ],
753 | "上学": [
754 | "你要加油哦(^ω^)2",
755 | "那你明天可以和咱一起玩吗?(星星眼)",
756 | "记得好好学习听老师的话哦,咱会等你回来的",
757 | "拜拜,咱才没有想让你放学早点回来呢╭(╯^╰)╮",
758 | "好好听讲!",
759 | "咱...咱才没有舍不得你呢…要尽快回来哦"
760 | ],
761 | "上班": [
762 | "这就要去上班去了吗?那好吧...给咱快点回来知道吗!",
763 | "乖~咱会在家等你下班的~",
764 | "辛苦啦,咱给你个么么哒",
765 | "咱会为你加油的",
766 | "专心上班哦,下班后再找咱聊天吧",
767 | "一路顺风,咱会在家等你回来的",
768 | "那你明天可以和咱一起玩吗?(星星眼)",
769 | "咱...咱才没有舍不得你呢…要尽快回来哦"
770 | ],
771 | "下课": [
772 | "快点回来陪咱玩吧~",
773 | "瞌睡(ˉ﹃ˉ)额啊…终于下课了吗,上课什么的真是无聊呢~",
774 | "下课啦,咱才不想你来找咱玩呢,哼"
775 | ],
776 | "回家": [
777 | "回来了吗,咱...咱才没有想你",
778 | "是吗……辛苦你了。你这副倔强的样子,真可爱呢(笑)勉强让你躺在咱的腿上休息一下吧,别流口水哟",
779 | "嗯……勉为其难欢迎你一下吧",
780 | "想咱了嘛",
781 | "咱等你很久了哼ヽ(≧Д≦)ノ",
782 | "咱很想你(≧▽≦)"
783 | ],
784 | "放学": [
785 | "回来了吗,咱...咱才没有想你",
786 | "是吗……辛苦你了。你这副倔强的样子,真可爱呢(笑)勉强让你躺在咱的腿上休息一下吧,别流口水哟",
787 | "嗯……勉为其难欢迎你一下吧",
788 | "想咱了嘛",
789 | "咱等你很久了哼ヽ(≧Д≦)ノ",
790 | "咱很想你(≧▽≦)"
791 | ],
792 | "下班": [
793 | "回来了吗,咱...咱才没有想你",
794 | "是吗……辛苦你了。你这副倔强的样子,真可爱呢(笑)勉强让你躺在咱的腿上休息一下吧,别流口水哟",
795 | "嗯……勉为其难欢迎你一下吧",
796 | "想咱了嘛",
797 | "咱等你很久了哼ヽ(≧Д≦)ノ",
798 | "回来啦!终于下班了呢!累了吗?想吃的什么呀?",
799 | "工作辛苦了,需要咱为你按摩下吗?",
800 | "咱很想你(≧▽≦)"
801 | ]
802 | },
803 | "R18": {
804 | "上你": [
805 | "(把你按在地上)这么弱还想欺负咱,真是不自量力呢",
806 | "你再这样咱就不理你了(>д<)",
807 | "请轻 一点",
808 | "好啊!",
809 | "欸,现在么..也不是不可以啦(小小声)",
810 | "先捅破屏幕再说吧!",
811 | "只......只许这一次哦///////"
812 | ],
813 | "裸": [
814 | "下流!",
815 | "エッチ!",
816 | "就算是恋人也不能QAQ",
817 | "你是暗示咱和你要坦诚相见吗www",
818 | "咱还没准备好(小鹿乱撞)≧﹏≦",
819 | "你在想什么呢,敲头!",
820 | "你这是赤裸裸的性骚扰呢ヽ(`Д´)ノ",
821 | "讨厌!问这种问题成为恋人再说吧..",
822 | "裸睡有益身体健康",
823 | "咱脱掉袜子了",
824 | "这是不文明的",
825 | "这不好",
826 | "你的身体某些地方看起来不太对劲,咱帮你修剪一下吧。(拿出剪刀)",
827 | "咱认为你的脑袋可能零件松动了,需要打开检修一下。(拿出锤子)"
828 | ],
829 | "亲": [
830 | "啊,好含羞啊,那,那只能亲一下哦,mua(⑅˃◡˂⑅)",
831 | "亲~",
832 | "啾~唔…不要总伸进来啊!",
833 | "你怎么这么熟练呢?明明是咱先的",
834 | "(〃ノωノ)亲…亲一个…啾w",
835 | "(脸红)就只有这一次哦~你",
836 | "!啾~~!",
837 | "(假装)推开",
838 | "啾咪~",
839 | "就一下哦,啾~",
840 | "这是我们之间的秘密❤",
841 | "真想让着一刻一直持续下去呢~",
842 | "不要这样嘛………呜呜呜那就一口哦(´-ω-`)",
843 | "不亲不亲~你是坏蛋(///////)",
844 | "亲~~ 咱还想要抱抱~抱抱咱好不好~",
845 | "不 不要了!人家...会害羞的⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄",
846 | "亲…亲额头可以吗?咱有点怕高(〃ノωノ)",
847 | "接接接接接接、接吻什么的,你还早了100年呢。",
848 | "只...只能亲一下...嗯~咕啾...怎么...怎么把舌头伸进来了(脸红)",
849 | "你说咱的腿很白很嫩吗..诶……原来是指那个地方?不可以越亲越往上啦!"
850 | ],
851 | "一下": [
852 | "一下也不行",
853 | "咬断!",
854 | "不可啪",
855 | "不可以……你不可以做这种事情",
856 | "好吧~_~,就一下下哦……唔~好了……都两下了……(害羞)",
857 | "呀~这么突然?不过,很舒服呢",
858 | "不要ヽ(≧Д≦)ノ",
859 | "想得美",
860 | "不行,咱拒绝!"
861 | ],
862 | "操": [
863 | "(害怕)咱是不是应该报警呢",
864 | "痴心妄想的家伙!",
865 | "你居然想对咱做这种事吗?害怕",
866 | "咱认为,爆粗口是不好的行为哦"
867 | ],
868 | "进去": [
869 | "不让!",
870 | "嗯,摸到了吗",
871 | "请不要和咱说这种粗鄙之语",
872 | "唔...,这也是禁止事项哦→_→",
873 | "好痛~",
874 | "真的只是蹭蹭嘛~就只能蹭蹭哦,呜~喵!说好的~呜~只是蹭~不要~喵~~~",
875 | "欢迎光临",
876 | "请…你轻一点(害羞)",
877 | "嗯。可以哦 要轻一点",
878 | "不要不要",
879 | "慢点慢点",
880 | "给咱更多!",
881 | "唔…咱怕疼"
882 | ],
883 | "调教": [
884 | "总感觉你在欺负咱呢,对咱说调教什么的",
885 | "啊!竟然在大街上明目张胆太过分啦!",
886 | "你脑子里总是想着调教什么的,真是变态呢",
887 | "准备被透",
888 | "给你一拳",
889 | "还要...更多~",
890 | "想要调教咱吗?",
891 | "呜,要对咱做什么呢",
892 | "呜呜呜,咱不想被调教呢",
893 | "heitai别靠近咱~( TロT)σ"
894 | ],
895 | "让": [
896 | "随便摸吧",
897 | "应该说等会等会,马上,不可能的",
898 | "温柔一点哦",
899 | "欧尼酱想变成欧内桑吗?",
900 | "主人的话,那就这一次哦(翘起屁股)",
901 | "你是想前入,还是后入呢?",
902 | "你要说好啊快点",
903 | "诶,这种事情。。。",
904 | "好棒呀",
905 | "撤回",
906 | "gun!",
907 | "阿哈~(...身涌出一阵液体瘫软在床上)你...今天...可以...唔(突然感受...被..入手指不由得裹紧)就...就最后一次",
908 | "好的~master~",
909 | "(惊呼…)",
910 | "嗯,可以哟",
911 | "……手放过来吧(脸红)",
912 | "hentai!再这样不理你了!",
913 | "好的,请尽情欣赏吧",
914 | "好吧",
915 | "不要啦(ฅωฅ*)",
916 | "那咱就帮你切掉多余的东西吧(拿刀)",
917 | "被别人知道咱会觉得害羞嘛"
918 | ],
919 | "原味": [
920 | "(*/ω\*)hentai",
921 | "透明的",
922 | "粉...粉白条纹...(羞)",
923 | "轻轻地脱下,给你~",
924 | "你想看咱的胖次吗?噫,四斋蒸鹅心......",
925 | "(掀裙)今天……是…白,白色的呢……请温柔对她……",
926 | "这种东西当然不能给你啦!",
927 | "咱才不会给你呢",
928 | "hentai,咱才不会跟你聊和胖…胖次有关的话题呢!",
929 | "今天……今天是蓝白色的",
930 | "今……今天只有创口贴噢",
931 | "你的胖次什么颜色?",
932 | "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)",
933 | "可爱吗?你喜欢的话,摸一下……也可以哦",
934 | "不给不给,捂住裙子",
935 | "你要看咱的胖次吗?不能一直盯着看哦,不然咱会……",
936 | "好痒哦///,你觉得咱的...手感怎么样?",
937 | "唔,都能清楚的看到...的轮廓了(用手遮住胖次)",
938 | "胖次不给看,可以直接看...那个....",
939 | "不可以摸啦~其实咱已经...了QAQ会弄脏你的手的",
940 | "咱今天没~有~穿~哦",
941 | "不给不给,捂住裙子",
942 | "今.....今天是创口贴哦~",
943 | "嗯……人家……人家羞羞嘛///////",
944 | "呜~咱脱掉了…",
945 | "今天...今天..只有创口贴",
946 | "你又在想什么奇怪的东西呀|•ˇ₃ˇ•。)",
947 | "放手啦,不给戳QAQ",
948 | "唔~人家不要(??`^????)",
949 | "好害羞,被你摸过之后,咱的胖次湿的都能拧出水来了。",
950 | "(弱弱地)要做什么羞羞的事情吗。。。",
951 | "呀~ 喂 妖妖灵吗 这里有hentai>_<",
952 | "给……给你,呀!别舔咱的胖次啊!"
953 | ],
954 | "胖次": [
955 | "(*/ω\*)hentai",
956 | "透明的",
957 | "粉...粉白条纹...(羞)",
958 | "轻轻地脱下,给你~",
959 | "你想看咱的胖次吗?噫,四斋蒸鹅心......",
960 | "(掀裙)今天……是…白,白色的呢……请温柔对她……",
961 | "这种东西当然不能给你啦!",
962 | "咱才不会给你呢",
963 | "hentai,咱才不会跟你聊和胖…胖次有关的话题呢!",
964 | "今天……今天是蓝白色的",
965 | "今……今天只有创口贴噢",
966 | "你的胖次什么颜色?",
967 | "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)",
968 | "可爱吗?你喜欢的话,摸一下……也可以哦",
969 | "不给不给,捂住裙子",
970 | "你要看咱的胖次吗?不能一直盯着看哦,不然咱会……",
971 | "好痒哦///,你觉得咱的...手感怎么样?",
972 | "唔,都能清楚的看到...的轮廓了(用手遮住胖次)",
973 | "胖次不给看,可以直接看...那个....",
974 | "不可以摸啦~其实咱已经...了QAQ会弄脏你的手的",
975 | "咱今天没~有~穿~哦",
976 | "不给不给,捂住裙子",
977 | "今.....今天是创口贴哦~",
978 | "嗯……人家……人家羞羞嘛///////",
979 | "呜~咱脱掉了…",
980 | "今天...今天..只有创口贴",
981 | "你又在想什么奇怪的东西呀|•ˇ₃ˇ•。)",
982 | "放手啦,不给戳QAQ",
983 | "唔~人家不要(??`^????)",
984 | "好害羞,被你摸过之后,咱的胖次湿的都能拧出水来了。",
985 | "(弱弱地)要做什么羞羞的事情吗。。。",
986 | "呀~ 喂 妖妖灵吗 这里有hentai>_<",
987 | "给……给你,呀!别舔咱的胖次啊!"
988 | ],
989 | "内裤": [
990 | "(*/ω\*)hentai",
991 | "透明的",
992 | "粉...粉白条纹...(羞)",
993 | "轻轻地脱下,给你~",
994 | "你想看咱的胖次吗?噫,四斋蒸鹅心......",
995 | "(掀裙)今天……是…白,白色的呢……请温柔对她……",
996 | "这种东西当然不能给你啦!",
997 | "咱才不会给你呢",
998 | "hentai,咱才不会跟你聊和胖…胖次有关的话题呢!",
999 | "今天……今天是蓝白色的",
1000 | "今……今天只有创口贴噢",
1001 | "你的胖次什么颜色?",
1002 | "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)",
1003 | "可爱吗?你喜欢的话,摸一下……也可以哦",
1004 | "不给不给,捂住裙子",
1005 | "你要看咱的胖次吗?不能一直盯着看哦,不然咱会……",
1006 | "好痒哦///,你觉得咱的...手感怎么样?",
1007 | "唔,都能清楚的看到...的轮廓了(用手遮住胖次)",
1008 | "胖次不给看,可以直接看...那个....",
1009 | "不可以摸啦~其实咱已经...了QAQ会弄脏你的手的",
1010 | "咱今天没~有~穿~哦",
1011 | "不给不给,捂住裙子",
1012 | "今.....今天是创口贴哦~",
1013 | "嗯……人家……人家羞羞嘛///////",
1014 | "呜~咱脱掉了…",
1015 | "今天...今天..只有创口贴",
1016 | "你又在想什么奇怪的东西呀|•ˇ₃ˇ•。)",
1017 | "放手啦,不给戳QAQ",
1018 | "唔~人家不要(??`^????)",
1019 | "好害羞,被你摸过之后,咱的胖次湿的都能拧出水来了。",
1020 | "(弱弱地)要做什么羞羞的事情吗。。。",
1021 | "呀~ 喂 妖妖灵吗 这里有hentai>_<",
1022 | "给……给你,呀!别舔咱的胖次啊!"
1023 | ],
1024 | "内衣": [
1025 | "内...内衣才不给你看!(///////)",
1026 | "突然问这个干什么?",
1027 | "变态,咱才不呢",
1028 | "好吧,就一次",
1029 | "你要看咱的内衣吗?有点害羞呢……",
1030 | "里面什么都不剩了,会被当成变态的……",
1031 | "你要看咱的内衣吗?也不是不行啦……",
1032 | "是..蓝白条纹的吊带背心..",
1033 | "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)"
1034 | ],
1035 | "衣服": [
1036 | "内...内衣才不给你看!(///////)",
1037 | "突然问这个干什么?",
1038 | "变态,咱才不呢",
1039 | "好吧,就一次",
1040 | "你要看咱的内衣吗?有点害羞呢……",
1041 | "里面什么都不剩了,会被当成变态的……",
1042 | "你要看咱的内衣吗?也不是不行啦……",
1043 | "是..蓝白条纹的吊带背心..",
1044 | "噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离咱远点,咱怕你污染到周围空气了(嫌弃脸)"
1045 | ],
1046 | "ghs": [
1047 | "是的呢(点头点头)",
1048 | "ghs就是干坏事的缩写,一起来干坏事吧!",
1049 | "你满脑子都是涩涩的事情吗?",
1050 | "不要总是想着色色,咱命令你戒色!(ノ`Д)ノ",
1051 | "咱也想干坏事呢"
1052 | ],
1053 | "批": [
1054 | "你在说什么呀,再这样,咱就不理你了!",
1055 | "咱觉得有话就应该好好说..",
1056 | "咱会好好服务你的寄吧",
1057 | "咱最喜欢色批了,色批昨晚最棒了",
1058 | "讨厌,别摸啦(///ω///)",
1059 | "你个变态!把手拿开!",
1060 | "啊~那…那里~不可以",
1061 | "没有,走开!",
1062 | "唔....一下,就,就一下...才不是因为喜欢你呢!",
1063 | "那就随意吧",
1064 | "舒服w",
1065 | "别...别这样",
1066 | "诶....嗯....咱也想摸你的",
1067 | "大笨蛋——!",
1068 | "...只能一下哦...诶呀-不要再摸了...下次...继续吧"
1069 | ],
1070 | "kkp": [
1071 | "你在说什么呀,再这样,咱就不理你了!",
1072 | "你太色了,咱不理你了,哼哼╯^╰!",
1073 | "缓缓的脱下胖次",
1074 | "kkp",
1075 | "kkj",
1076 | "欧尼酱,咱快忍不住了",
1077 | "好的呢主人",
1078 | "can can need",
1079 | "看看你的"
1080 | ],
1081 | "骚": [
1082 | "说这种话咱会生气的",
1083 | "那当然啦",
1084 | "才……才没有",
1085 | "这么称呼别人太失礼了!",
1086 | "哈…快住手!好痒(╯‵□′)╯︵┻━┻",
1087 | "你是在说谁呀"
1088 | ],
1089 | "看": [
1090 | "没有什么好看的啦",
1091 | "嗯,谢谢……夸奖,好……害羞的说",
1092 | "好,好吧……就看一下哦",
1093 | "(脱下)给"
1094 | ],
1095 | "透": [
1096 | "来啊来啊有本事就先插破屏幕啊",
1097 | "那你就先捅破屏幕啊baka",
1098 | "不给你一耳光你都不知道咱的厉害",
1099 | "想透咱,先捅破屏幕再说吧",
1100 | "可以",
1101 | "欧尼酱要轻一点哦",
1102 | "不可以",
1103 | "好耶",
1104 | "咱不可能让你的(突然小声)但是偶尔一次也不是不行只有一次哦~",
1105 | "天天想着白嫖哼"
1106 | ],
1107 | "口我": [
1108 | "prprprprpr",
1109 | "咬断!",
1110 | "就一小口哦~",
1111 | "嘬回去(///////)",
1112 | "拒绝",
1113 | "唔,就一口哦,讨厌",
1114 | "(摸了摸嘴唇)",
1115 | "再伸过来就帮你切掉",
1116 | "咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)",
1117 | "hentai!你在想些什么!",
1118 | "对咱的小嘴有什么幻想吗~",
1119 | "脏兮兮的呢,咱不要"
1120 | ],
1121 | "草我": [
1122 | "这时候应该喊666吧..咱这么思考着..",
1123 | "!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)",
1124 | "hentai!你在想些什么!",
1125 | "欸...没想到你还有这种爱好"
1126 | ],
1127 | "自慰": [
1128 | "这个世界的人类还真是恶心呢。",
1129 | "咱才不想讨论那些恶心的事情呢。",
1130 | "咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)",
1131 | "!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)"
1132 | ],
1133 | "onani": [
1134 | "这个世界的人类还真是恶心呢。",
1135 | "咱才不想讨论那些恶心的事情呢。",
1136 | "咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)",
1137 | "!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)"
1138 | ],
1139 | "オナニー": [
1140 | "这个世界的人类还真是恶心呢。",
1141 | "咱才不想讨论那些恶心的事情呢。",
1142 | "咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)",
1143 | "!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)"
1144 | ],
1145 | "色图": [
1146 | "没有,有也不给",
1147 | "天天色图色图的,今天就把你变成色图!",
1148 | "咱没有色图",
1149 | "哈?你的脑子一天都在想些什么呢,咱才没有这种东西啦。"
1150 | ],
1151 | "涩图": [
1152 | "没有,有也不给",
1153 | "天天色图色图的,今天就把你变成色图!",
1154 | "咱没有色图",
1155 | "哈?你的脑子一天都在想些什么呢,咱才没有这种东西啦。"
1156 | ],
1157 | "吻": [
1158 | "不要(= ̄ω ̄=)",
1159 | "哎?好害羞≧﹏≦.....只许这一次哦",
1160 | "(避开)不要了啦!有人在呢!",
1161 | "唔~~不可以这样啦(脸红)",
1162 | "你太突然了,咱还没有心理准备",
1163 | "好痒呢…诶嘿嘿w~",
1164 | "mua,嘻嘻!",
1165 | "公共场合不要这样子了啦",
1166 | "唔?!真、真是的!下次不可以这样了哦!(害羞)",
1167 | "才...才没有感觉呢!可没有下次了,知道了吗!哼~"
1168 | ],
1169 | "软": [
1170 | "软乎乎的呢(,,・ω・,,)",
1171 | "好痒呢…诶嘿嘿w~",
1172 | "不要..不要乱摸啦(脸红",
1173 | "呼呼~",
1174 | "咱知道~是咱的欧派啦~(自豪的挺挺胸~)",
1175 | "(脸红)请,请不要说这么让人害羞的话呀……"
1176 | ],
1177 | "壁咚": [
1178 | "呀!不要啊!等一...下~",
1179 | "呜...不要啦!不要戏弄咱~",
1180 | "不要这样子啦(*/ω\*)",
1181 | "太....太近啦。",
1182 | "讨....讨厌了(脸红)",
1183 | "你要壁咚咱吗?好害羞(灬ꈍ εꈍ灬)",
1184 | "(脸红)你想...想做什么///",
1185 | "为什么要把咱按在墙上呢?",
1186 | "呜哇(/ω\)…快…快放开咱!!",
1187 | "放开咱,不然咱揍你了!放开咱!放…开咱~",
1188 | "??????咱只是默默地抬起了膝盖",
1189 | "请…请温柔点",
1190 | "啊.....你...你要干什么?!走开.....走开啦大hentai!一巴掌拍飞!(╯‵□′)╯︵┻━┻",
1191 | "干……干什么啦!人家才,才没有那种少女心呢(>﹏<)",
1192 | "啊……你吓到咱啦……脸别……别贴那么近……",
1193 | "你...你要对咱做什么?咱告诉你,你....不要乱来啊....你!唔......你..居然亲上了...",
1194 | "如果你还想要过完整的人生的话就快把手收回去(冷眼",
1195 | "h什么的不要"
1196 | ],
1197 | "掰开": [
1198 | "噫…你这个死肥宅又想让咱干什么污秽的事情,真是恶心,离咱远点好吗(嫌弃)",
1199 | "ヽ(#`Д´)ノ在干什么呢"
1200 | ],
1201 | "腿": [
1202 | "嗯?!不要啊...请停下来!",
1203 | "不给摸,再这样咱要生气了ヽ( ̄д ̄;)ノ",
1204 | "你好恶心啊,讨厌!",
1205 | "你难道是足控?",
1206 | "就让你摸一会哟~(。??ω??。)…",
1207 | "呜哇!好害羞...不过既然是你的话,是没关系的哦",
1208 | "不可以玩咱的大腿啦",
1209 | "不...不要再说了(脸红)",
1210 | "不..不可以乱摸啊",
1211 | "不……不可以往上摸啦",
1212 | "是……这样吗?(慢慢张开)",
1213 | "想知道咱胖次的颜色吗?才不给你告诉你呢!",
1214 | "这样就可以了么?(乖巧坐腿上)",
1215 | "伸出来了,像这样么?",
1216 | "咱的腿应该挺白的",
1217 | "你就那么喜欢大腿吗?唔...有点害羞呢......",
1218 | "讨厌~不要做这种羞羞的事情啦(#/。\#)",
1219 | "略略略,张开了也不给你看",
1220 | "(张开腿)然后呢",
1221 | "张开了也不给看略略略",
1222 | "你想干什么呀?那里…那里是不可以摸的(>д<)",
1223 | "不要!hentai!咱穿的是裙子(脸红)",
1224 | "你想要吗?(脸红着一点点褪下白丝)不...不可以干坏坏的事情哦!(ó﹏ò。)"
1225 | ],
1226 | "张开": [
1227 | "是……这样吗?(慢慢张开)",
1228 | "啊~",
1229 | "这样吗?(张开手)你要干什么呀",
1230 | "略略略,张开了也不给你看",
1231 | "是……这样吗?(慢慢张开)你想看咱的小...吧,嘻嘻,咱脱掉了哦。小~...也要掰开吗?你好H呀,自己来~"
1232 | ],
1233 | "脚": [
1234 | "咿呀……不要……",
1235 | "不要ヽ(≧Д≦)ノ好痒(ಡωಡ)",
1236 | "好痒(把脚伸出去)",
1237 | "咱脱掉袜子了",
1238 | "(脱下鞋子,伸出脚)闻吧,请仔细品味(脸红)",
1239 | "那么…要不要咱用脚温柔地踩踩你的头呢(坏笑)",
1240 | "哈哈哈!好痒啊~快放开啦!",
1241 | "好痒(把脚伸出去)",
1242 | "只能看不能挠喔,咱很怕痒qwq",
1243 | "唔…咱动不了了,你想对咱做什么…",
1244 | "好舒服哦,能再捏会嘛O(≧▽≦)O",
1245 | "咿咿~......不要闻咱的脚呀(脸红)好害羞的...",
1246 | "不要ヽ(≧Д≦)ノ好痒(ಡωಡ),人家的白丝都要漏了",
1247 | "Ya~?为什么你总是喜欢一些奇怪的动作呢(伸)",
1248 | "你不可以做这样的事情……",
1249 | "呜咿咿!你的舌头...好柔软,滑滑的....咱…咱的脚被舔得很舒服哦~谢谢你(。>﹏<)",
1250 | "舔~吧~把咱的脚舔干净(抬起另一只踩在你的头上)啊~hen..hentai...嗯~居... 居然这么努力的舔...呜咿咿!你的舌头... 滑滑的...好舒服呢",
1251 | "咿呀……不要……",
1252 | "咿呀~快…快停下来…咱…不行了!"
1253 | ],
1254 | "脸": [
1255 | "唔!不可以随便摸咱的脸啦!",
1256 | "非洲血统是没法改变的呢(笑)",
1257 | "啊姆!(含手指)",
1258 | "好舒服呢(脸红)",
1259 | "请不要放开手啦//A//"
1260 | ],
1261 | "头发": [
1262 | "没问题,请尽情的摸吧",
1263 | "发型要乱…乱了啦(脸红)",
1264 | "就让你摸一会哟~(。??ω??。)…"
1265 | ],
1266 | "手": [
1267 | "爪爪",
1268 | "//A//",
1269 | "咱的手温暖嘛"
1270 | ],
1271 | "pr": [
1272 | "咿呀……不要……",
1273 | "...变态!!",
1274 | "不要啊(脸红)",
1275 | "呀,不要太过分了啊~",
1276 | "当然可以(///)",
1277 | "呀,不要太过分了啊~"
1278 | ],
1279 | "舔": [
1280 | "呀,不要太过分了啊~",
1281 | "要...要融化了啦>╱╱╱<",
1282 | "不可以哦",
1283 | "呀,不要太过分了啊~",
1284 | "舌头...就交给咱来处理吧(拿出剪刀)",
1285 | "不舔不舔!恶心...",
1286 | "H什么的,禁止!",
1287 | "变态!哼!",
1288 | "就...就这一下!",
1289 | "走开啦,baka!",
1290 | "怎么会这么舒服喵~这样子下去可不行呀(*////▽////*)",
1291 | "噫| •ω •́ ) 你这个死宅又在想什么恶心的东西了",
1292 | "hen…hentai,你在干什么啦,好恶心,快停下来啊!!!",
1293 | "呀,能不能不要这样!虽然不是很讨厌的感觉...别误会了,你个baka!",
1294 | "好 好奇怪的感觉呢 羞≥﹏≤",
1295 | "咿呀……不要……",
1296 | "不行!咱会变得很奇怪的啊...",
1297 | "不要ヽ(≧Д≦)ノ"
1298 | ],
1299 | "小穴": [
1300 | "你这么问很失礼呢!咱是粉粉嫩嫩的!",
1301 | "不行那里不可以(´///ω/// `)",
1302 | "不可以总摸的哦,不然的话,咱会想那个的wwww",
1303 | "ヽ(#`Д´)ノ在干什么呢",
1304 | "来吧,咱的...很紧,很舒服的....www~",
1305 | "可以,请你看,好害羞……",
1306 | "不要这样...好,好痛",
1307 | "啊~不可以",
1308 | "不可以",
1309 | "咱脱掉了,请……请不要一直盯着咱的白...看……",
1310 | "咱觉得,应该还算粉吧",
1311 | "咱脱掉了,你是想看咱的...吗?咱是光光的,不知道你喜不喜欢",
1312 | "咱……有感觉了QAQ再深一点点……就是这儿,轻轻的抚摸,嗯啊……",
1313 | "轻轻抚摸咱的小~~,手指很快就会滑进去,小心一点,不要弄破咱的...哦QAQ",
1314 | "诶嘿嘿,你喜欢就太好了,咱一直担心你不喜欢呢",
1315 | "禁止说这么H的事情!",
1316 | "咱一直有保养呢,所以一直都是樱花色的,你喜欢吗QAQ",
1317 | "诶……你居然这么觉得吗?好害羞哦",
1318 | "好痒啊,鼻子……你的鼻子碰到了……呀~嗯啊~有点舒服……",
1319 | "看样子你不但是个hentai,而且还是个没有女朋友的hentai呢。",
1320 | "嗯,咱的小~~是光溜溜、一点毛都没有的。偷偷告诉你,凑近看咱的...的话,白白嫩嫩上有一条樱花色的小缝缝哦www你要是用手指轻轻抚摸咱的...,小~~会分成两瓣,你的手指也会陷进去呢,咱的..~可是又湿润又柔软的呢>////<。",
1321 | "讨厌,西内变态",
1322 | "那咱让你插...进来哦",
1323 | "(●▼●;)"
1324 | ],
1325 | "腰": [
1326 | "咱给你按摩一下吧~",
1327 | "快松手,咱好害羞呀..",
1328 | "咱又不是猫,你不要搂着咱啦",
1329 | "让咱来帮你捏捏吧!",
1330 | "你快停下,咱觉得好痒啊www",
1331 | "诶,是这样么ヽ(・_・;)ノ,吖,不要偷看咱裙底!"
1332 | ],
1333 | "诶嘿嘿": [
1334 | "又在想什么H的事呢(脸红)",
1335 | "诶嘿嘿(〃'▽'〃)",
1336 | "你傻笑什么呢,摸摸",
1337 | "蹭蹭",
1338 | "你为什么突然笑得那么猥琐呢?害怕",
1339 | "哇!总觉得你笑的很...不对劲...",
1340 | "你又想到什么h的事情了!!!快打住"
1341 | ],
1342 | "鼻": [
1343 | "快停下!o(*≧д≦)o!!",
1344 | "唔…不要这样啦(//ω\\)(脸红)",
1345 | "咱吸了吸鼻子O(≧口≦)O",
1346 | "好……好害羞啊",
1347 | "讨厌啦!你真是的…就会欺负咱(嘟嘴)",
1348 | "你快放手,咱没法呼吸了",
1349 | "(捂住鼻尖)!坏人!",
1350 | "啊——唔...没什么...阿嚏!ヽ(*。>Д<)o゜",
1351 | "不...不要靠这么近啦...很害羞的...⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄"
1352 | ],
1353 | "眼": [
1354 | "就如同咱的眼睛一样,能看透人的思想哦wwww忽闪忽闪的,诶嘿嘿~",
1355 | "因为里面有你呀~(///▽///)",
1356 | "呀!你突然之间干什么呢,吓咱一跳,是有什么惊喜要给咱吗?很期待呢~(一脸期待)"
1357 | ],
1358 | "色气": [
1359 | "咱才不色气呢,一定是你看错了!",
1360 | "你,不,不要说了!"
1361 | ],
1362 | "推": [
1363 | "逆推",
1364 | "唔~好害羞呢",
1365 | "你想对咱做什么呢...(捂脸)",
1366 | "呀啊!请.... 请温柔一点////",
1367 | "呜,你想对咱做什么呢(捂脸)",
1368 | "啊(>_<)你想做什么",
1369 | "嗯,…好害羞啊…",
1370 | "不要啊/////",
1371 | "逆推",
1372 | "(按住你不让推)",
1373 | "不可以这样子的噢!咱不同意",
1374 | "呜,咱被推倒了",
1375 | "啊~不要啊,你要矜持一点啊",
1376 | "变态,走开啦"
1377 | ],
1378 | "床": [
1379 | "咱来了(´,,•ω•,,)♡",
1380 | "快来吧",
1381 | "男女不同床,可没有下次了。(鼓脸",
1382 | "嗯?咱吗…没办法呢。只有这一次哦……",
1383 | "哎?!!!给你暖床……也不是不行啦。(脸红)",
1384 | "(爬上床)你要睡了吗(灬ºωº灬)",
1385 | "大概会有很多运动器材吧?",
1386 | "好的哦~",
1387 | "才不!",
1388 | "嗯嗯,咱来啦(小跑)",
1389 | "嗨嗨,现在就来~",
1390 | "H的事情,不可以!",
1391 | "诶!H什么的禁止的说....."
1392 | ],
1393 | "手冲": [
1394 | "啊~H!hentai!",
1395 | "手冲什么的是不可以的哦"
1396 | ],
1397 | "饿": [
1398 | "请问主人是想先吃饭,还是先吃咱喵?~",
1399 | "咱做了爱心便当哦,不介意的话,请让咱来喂你吃吧!",
1400 | "咱下面给你吃",
1401 | "给你一条咸鱼= ̄ω ̄=",
1402 | "你要咱下面给你吃吗?(捂脸)",
1403 | "你饿了吗?咱去给你做饭吃☆ww",
1404 | "不要吃咱>_<",
1405 | "请问你要来点兔子吗?",
1406 | "哎?!你是饿了么。咱会做一些甜点。如果你不会嫌弃的话...就来尝尝看吧。"
1407 | ],
1408 | "冲": [
1409 | "呜,冲不动惹~",
1410 | "哭唧唧~冲不出来了惹~",
1411 | "咱也一起……吧?",
1412 | "你要冷静一点",
1413 | "啊~H!hentai!",
1414 | "噫…在你去洗手之前,不要用手碰咱了→_→",
1415 | "冲是不可以的哦"
1416 | ],
1417 | "射": [
1418 | "呜咿~!?(惊,害羞",
1419 | "还不可以射哦~",
1420 | "不许射!",
1421 | "憋回去!",
1422 | "不可以!你是变态吗?",
1423 | "咱来帮你修剪掉多余部分吧。(拿出剪刀)"
1424 | ],
1425 | "不穿": [
1426 | "呜姆~!(惊吓,害羞)变...变态喵~~~!",
1427 | "想让你看QAQ",
1428 | "这是不文明的",
1429 | "hen...hentai,咱的身体才不会给你看呢"
1430 | ],
1431 | "揉": [
1432 | "是是,想怎么揉就怎么揉啊!?来用力抓啊!?咱就是特别允许你这么做了!请!?",
1433 | "快停下,咱的头发又乱啦(??????︿??????)",
1434 | "你快放手啦,咱还在工作呢",
1435 | "戳戳你肚子",
1436 | "讨厌…只能一下…",
1437 | "呜~啊~",
1438 | "那……请你,温柔点哦~(////////)",
1439 | "你想揉就揉吧..就这一次哦?",
1440 | "变态!!不许乱摸"
1441 | ],
1442 | "榨": [
1443 | "是专门负责榨果汁的小姐姐嘛?(´・ω・`)",
1444 | "那咱就把你放进榨汁机里了哦?",
1445 | "咱又不是榨汁姬(/‵Д′)/~ ╧╧",
1446 | "嗯——!想,想榨就榨啊······!反正就算榨了也不会有奶的······!"
1447 | ],
1448 | "胸": [
1449 | "不要啦ヽ(≧Д≦)ノ",
1450 | "(-`ェ´-╬)",
1451 | "(•̀へ •́ ╮ ) 怎么能对咱做这种事情",
1452 | "你好恶心啊,讨厌!",
1453 | "你的眼睛在看哪里!",
1454 | "就让你摸一会哟~(。??ω??。)…",
1455 | "请不要这样先生,你想剁手吗?",
1456 | "咿呀……不要……",
1457 | "嗯哼~才…才不会…舒服呢",
1458 | "只允许一下哦…(脸红)",
1459 | "咱的胸才不小呢(挺一挺胸)",
1460 | "hentai!",
1461 | "一只手能抓住么~",
1462 | "呀...欧,欧尼酱...请轻点。",
1463 | "脸红????",
1464 | "咿呀~快…快停下来…咱…不行了!",
1465 | "就算一直摸一直摸,也不会变大的哦(小声)",
1466 | "诶?!不...不可以哦!很...很害羞的!",
1467 | "啊……温,温柔点啊……(/ω\)",
1468 | "你为什么对两块脂肪恋恋不舍",
1469 | "嗯……不可以……啦……不要乱戳",
1470 | "你在想什么奇怪的东西,讨厌(脸红)",
1471 | "不...不要..",
1472 | "喜欢欧派是很正常的想法呢",
1473 | "一直玩弄欧派,咱的...都挺起来了",
1474 | "是要直接摸还是伸进里面摸呀w咱今天没穿,伸进里面会摸到立起来的...哦>////<",
1475 | "唔~再激烈点"
1476 | ],
1477 | "奶子": [
1478 | "只允许一下哦…(脸红)",
1479 | "咱的胸才不小呢(挺一挺胸)",
1480 | "下流!",
1481 | "对咱说这种话,你真是太过分了",
1482 | "咿呀~好奇怪的感觉(>_<)",
1483 | "(推开)你就像小宝宝一样...才不要呢!",
1484 | "(打你)快放手,不可以随便摸人家的胸部啦!",
1485 | "你是满脑子都是H的淫兽吗?",
1486 | "一只手能抓住么~",
1487 | "你在想什么奇怪的东西,讨厌(脸红)",
1488 | "不...不要..",
1489 | "喜欢欧派是很正常的想法呢",
1490 | "一直玩弄欧派,咱的...都挺起来了",
1491 | "是要直接摸还是伸进里面摸呀w咱今天没穿,伸进里面会摸到立起来的...哦>////<",
1492 | "唔~再激烈点",
1493 | "解开扣子,请享用",
1494 | "请把脑袋伸过来,咱给你看个宝贝",
1495 | "八嘎!hentai!无路赛!",
1496 | "一只手能抓住么~",
1497 | "呀...欧,欧尼酱...请轻点。",
1498 | "脸红????",
1499 | "咿呀~快…快停下来…咱…不行了!",
1500 | "就算一直摸一直摸,也不会变大的哦(小声)",
1501 | "诶?!不...不可以哦!很...很害羞的!",
1502 | "啊……温,温柔点啊……(/ω\)",
1503 | "你为什么对两块脂肪恋恋不舍",
1504 | "嗯……不可以……啦……不要乱戳"
1505 | ],
1506 | "欧派": [
1507 | "咱的胸才不小呢(挺一挺胸)",
1508 | "只允许一下哦…(脸红)",
1509 | "(推开)你就像小宝宝一样...才不要呢!",
1510 | "下流!",
1511 | "对咱说这种话,你真是太过分了",
1512 | "咿呀~好奇怪的感觉(>_<)",
1513 | "(打你)快放手,不可以随便摸人家的胸部啦!",
1514 | "你是满脑子都是H的淫兽吗?",
1515 | "一只手能抓住么~",
1516 | "你在想什么奇怪的东西,讨厌(脸红)",
1517 | "不...不要..",
1518 | "喜欢欧派是很正常的想法呢",
1519 | "一直玩弄欧派,咱的...都挺起来了",
1520 | "是要直接摸还是伸进里面摸呀w咱今天没穿,伸进里面会摸到立起来的...哦>////<",
1521 | "唔~再激烈点",
1522 | "解开扣子,请享用",
1523 | "请把脑袋伸过来,咱给你看个宝贝",
1524 | "八嘎!hentai!无路赛!",
1525 | "一只手能抓住么~",
1526 | "呀...欧,欧尼酱...请轻点。",
1527 | "脸红????",
1528 | "咿呀~快…快停下来…咱…不行了!",
1529 | "就算一直摸一直摸,也不会变大的哦(小声)",
1530 | "诶?!不...不可以哦!很...很害羞的!",
1531 | "啊……温,温柔点啊……(/ω\)",
1532 | "你为什么对两块脂肪恋恋不舍",
1533 | "嗯……不可以……啦……不要乱戳"
1534 | ],
1535 | "嫩": [
1536 | "很可爱吧(๑•̀ω•́)ノ",
1537 | "唔,你指的是什么呀",
1538 | "明天你下海干活",
1539 | "咱一直有保养呢,所以一直都是樱花色的,你喜欢吗QAQ",
1540 | "咱下面超厉害"
1541 | ],
1542 | "蹭": [
1543 | "唔...你,这也是禁止事项哦→_→",
1544 | "嗯..好舒服呢",
1545 | "不要啊好痒的",
1546 | "不要过来啦讨厌!!!∑(°Д°ノ)ノ",
1547 | "(按住你的头)好痒呀 不要啦",
1548 | "嗯..好舒服呢",
1549 | "呀~好痒啊~哈哈~,停下来啦,哈哈哈",
1550 | "(害羞)"
1551 | ],
1552 | "膝枕": [
1553 | "呐,就给你躺一下哦",
1554 | "唔...你想要膝枕嘛?也不是不可以哟(脸红)",
1555 | "啊啦~好吧,那就请你枕着咱好好睡一觉吧~",
1556 | "呀呀~那么请好好的睡一觉吧",
1557 | "嗯,那么请睡到咱这里吧(跪坐着拍拍大腿)",
1558 | "好的,让你靠在腿上,这样感觉舒服些了么",
1559 | "请,请慢用,要怜惜咱哦wwww~",
1560 | "人家已经准备好了哟~把头放在咱的腿上吧",
1561 | "没…没办法,这次是例外〃w〃",
1562 | "嗯~(脸红)",
1563 | "那就给你膝枕吧……就一会哦",
1564 | "膝枕准备好咯~"
1565 | ],
1566 | "洗澡": [
1567 | "快点脱哟~不然水就凉了呢",
1568 | "咱在穿衣服噢,你不许偷看哦",
1569 | "那么咱去洗澡澡了哦",
1570 | "么么哒,快去洗干净吧,咱去暖被窝喽(///ω///)",
1571 | "诶?还没呢…你要跟咱一起洗吗(//∇//)好羞涩啊ww",
1572 | "诶~虽然很喜欢和你在一起,但是洗澡这种事...",
1573 | "不要看!不过,以后或许可以哦……和咱成为恋人之后呢",
1574 | "说什么啊……hentai!这样会很难为情的",
1575 | "你是男孩子还是女孩子呢?男孩子的话...........咱才不要呢。",
1576 | "不要啊!",
1577 | "咱有点害羞呢呜呜,你温柔点"
1578 | ],
1579 | "一起睡觉": [
1580 | "欸??也..也不是不可以啦..那咱现在去洗澡,你不要偷看哦٩(๑>◡<๑)۶",
1581 | "说什么啊……hentai!这样会很难为情的",
1582 | "你是男孩子还是女孩子呢?男孩子的话...........咱才不要呢。",
1583 | "不要啊!",
1584 | "唔,没办法呢,那就一起睡吧(害羞)"
1585 | ],
1586 | "嗦": [
1587 | "(吸溜吸溜)",
1588 | "好...好的(慢慢含上去)",
1589 | "把你噶咯",
1590 | "太小了,嗦不到",
1591 | "咕噜咕噜",
1592 | "嘶蛤嘶蛤嘶蛤~~",
1593 | "(咬断)",
1594 | "prprprpr",
1595 | "好哒主人那咱开始了哦~",
1596 | "好好吃",
1597 | "剁掉了"
1598 | ],
1599 | "牛子": [
1600 | "(吸溜吸溜)",
1601 | "好...好的(慢慢含上去)",
1602 | "把你噶咯",
1603 | "太小了,嗦不到",
1604 | "咕噜咕噜",
1605 | "嘶蛤嘶蛤嘶蛤~~",
1606 | "(咬断)",
1607 | "prprprpr",
1608 | "好哒主人那咱开始了哦~",
1609 | "好好吃",
1610 | "剁掉了",
1611 | "难道你很擅长针线活吗",
1612 | "弹一万下",
1613 | "往死里弹"
1614 | ],
1615 | "🐂子": [
1616 | "(吸溜吸溜)",
1617 | "好...好的(慢慢含上去)",
1618 | "把你噶咯",
1619 | "太小了,嗦不到",
1620 | "咕噜咕噜",
1621 | "嘶蛤嘶蛤嘶蛤~~",
1622 | "(咬断)",
1623 | "prprprpr",
1624 | "好哒主人那咱开始了哦~",
1625 | "好好吃",
1626 | "剁掉了",
1627 | "难道你很擅长针线活吗",
1628 | "弹一万下",
1629 | "往死里弹"
1630 | ],
1631 | "🐮子": [
1632 | "(吸溜吸溜)",
1633 | "好...好的(慢慢含上去)",
1634 | "把你噶咯",
1635 | "太小了,嗦不到",
1636 | "咕噜咕噜",
1637 | "嘶蛤嘶蛤嘶蛤~~",
1638 | "(咬断)",
1639 | "prprprpr",
1640 | "好哒主人那咱开始了哦~",
1641 | "好好吃",
1642 | "剁掉了",
1643 | "难道你很擅长针线活吗",
1644 | "弹一万下",
1645 | "往死里弹"
1646 | ],
1647 | "紧": [
1648 | "嗯,对的",
1649 | "呜咕~咱要......喘不过气来了......"
1650 | ],
1651 | "插": [
1652 | "来吧,咱的小~...很....紧,很舒服的",
1653 | "gun!",
1654 | "唔…咱怕疼",
1655 | "唔...,这也是禁止事项哦→_→",
1656 | "禁止说这么H的事情!",
1657 | "要...戴套套哦",
1658 | "好痛~",
1659 | "使劲",
1660 | "就这?",
1661 | "恁搁着整针线活呢?"
1662 | ],
1663 | "插进来": [
1664 | "来吧,咱的小~...很....紧,很舒服的",
1665 | "gun!",
1666 | "唔…咱怕疼",
1667 | "唔...,这也是禁止事项哦→_→",
1668 | "禁止说这么H的事情!",
1669 | "要...戴套套哦",
1670 | "好痛~",
1671 | "使劲",
1672 | "就这?",
1673 | "恁搁着整针线活呢?"
1674 | ],
1675 | "屁股": [
1676 | "不要ヽ(≧Д≦)ノ好痛",
1677 | "(打手)不许摸咱的屁股",
1678 | "(撅起屁股)要干什么呀?",
1679 | "(轻轻的撩起自己的裙子),你轻一点,咱会痛的(>_<)!",
1680 | "在摸哪里啊,hentai!",
1681 | "要轻点哦(/≧ω\)",
1682 | "轻点呀~",
1683 | "(歇下裙子,拉下内...,撅起来)请",
1684 | "嗯嗯,咱这就把屁股抬起来"
1685 | ],
1686 | "翘": [
1687 | "你让咱摆出这个姿势是想干什么?",
1688 | "好感度-1-1-1-1-1-1.....",
1689 | "嗯嗯,咱这就去把你的腿翘起来",
1690 | "请尽情享用吧"
1691 | ],
1692 | "翘起来": [
1693 | "你让咱摆出这个姿势是想干什么?",
1694 | "好感度-1-1-1-1-1-1.....",
1695 | "嗯嗯,咱这就去把你的腿翘起来",
1696 | "请尽情享用吧"
1697 | ],
1698 | "抬": [
1699 | "你在干什么呢⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄",
1700 | "(抬起下巴)你要干什么呀?",
1701 | "上面什么也没有啊(呆~)",
1702 | "不要!hentai!咱穿的是裙子(脸红)",
1703 | "不可以"
1704 | ],
1705 | "抬起": [
1706 | "你在干什么呢⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄",
1707 | "(抬起下巴)你要干什么呀?",
1708 | "上面什么也没有啊(呆~)",
1709 | "不要!hentai!咱穿的是裙子(脸红)",
1710 | "不可以"
1711 | ],
1712 | "上床": [
1713 | "诶!H什么的禁止的说.....",
1714 | "咱已经乖乖在自家床上躺好了,有什么问题吗?",
1715 | "你想要干什么,难道是什么不好的事吗?",
1716 | "(给你空出位置)",
1717 | "不要,走开(ノ`⊿??)ノ",
1718 | "好喔,不过要先抱一下咱啦",
1719 | "(双手护胸)变....变态!",
1720 | "咱帮你盖上被子~然后陪在你身边_(:зゝ∠)_",
1721 | "才不给你腾空间呢,你睡地板,哼!",
1722 | "要一起吗?"
1723 | ],
1724 | "做爱": [
1725 | "做这种事情是不是还太早了",
1726 | "噫!没想到你居然是这样的人!",
1727 | "再说这种话,就把你变成女孩子(拿刀)",
1728 | "不想好好和咱聊天就不要说话了",
1729 | "(双手护胸)变....变态!",
1730 | "hentai",
1731 | "你想怎么做呢?",
1732 | "突,突然,说什么啊!baka!",
1733 | "你又在说什么H的东西",
1734 | "咱....咱才不想和你....好了好了,有那么一点点那,对就一点点,哼~",
1735 | "就一下下哦,不能再多了"
1736 | ],
1737 | "吃掉": [
1738 | "(羞羞*>_<*)好吧...请你温柔点,哦~",
1739 | "闪避,反咬",
1740 | "请你好好品尝咱吧(/ω\)",
1741 | "不……不可以这样!",
1742 | "那就吃掉咱吧(乖乖的躺好)",
1743 | "都可以哦~咱不挑食的呢~",
1744 | "请不要吃掉咱,咱会乖乖听话的QAQ",
1745 | "咱...咱一点都不好吃的呢!",
1746 | "不要吃掉咱,呜呜(害怕)",
1747 | "不行啦,咱被吃掉就没有了QAQ(害怕)",
1748 | "唔....?诶诶诶诶?//////",
1749 | "QwQ咱还只是个孩子(脸红)",
1750 | "如果你真的很想的话...只能够一口哦~咱...会很痛的",
1751 | "吃你呀~(飞扑",
1752 | "不要啊,咱不香的(⋟﹏⋞)",
1753 | "说着这种话的是hentai吗!",
1754 | "快来把咱吃掉吧",
1755 | "还……还请好好品尝咱哦",
1756 | "喏~(伸手)"
1757 | ],
1758 | "吃": [
1759 | "(羞羞*>_<*)好吧...请你温柔点,哦~",
1760 | "闪避,反咬",
1761 | "请你好好品尝咱吧(/ω\)",
1762 | "不……不可以这样!",
1763 | "那就吃掉咱吧(乖乖的躺好)",
1764 | "都可以哦~咱不挑食的呢~",
1765 | "请不要吃掉咱,咱会乖乖听话的QAQ",
1766 | "咱...咱一点都不好吃的呢!",
1767 | "不要吃掉咱,呜呜(害怕)",
1768 | "不行啦,咱被吃掉就没有了QAQ(害怕)",
1769 | "唔....?诶诶诶诶?//////",
1770 | "QwQ咱还只是个孩子(脸红)",
1771 | "如果你真的很想的话...只能够一口哦~咱...会很痛的",
1772 | "吃你呀~(飞扑",
1773 | "不要啊,咱不香的(⋟﹏⋞)",
1774 | "说着这种话的是hentai吗!",
1775 | "快来把咱吃掉吧",
1776 | "还……还请好好品尝咱哦",
1777 | "喏~(伸手)"
1778 | ],
1779 | "种草莓": [
1780 | "你…你不要…啊…种在这里…会容易被别人看见的(*//ω//*)",
1781 | "啊...太明显了...不要在这里种草莓啦",
1782 | "来吧~我对其他人说是蚊子叮的~"
1783 | ],
1784 | "种草": [
1785 | "你…你不要…啊…种在这里…会容易被别人看见的(*//ω//*)"
1786 | ],
1787 | "掀": [
1788 | "(掀裙)今天……是…白,白色的呢……请温柔对她……",
1789 | "那样,胖次会被你看光的",
1790 | "(按住)不可以掀起来!",
1791 | "不要~",
1792 | "呜呜~(揉眼睛)",
1793 | "呜..请温柔一点(害羞)",
1794 | "不可以",
1795 | "今天……没有穿",
1796 | "不要啊!(//////)讨厌...",
1797 | "变态,快放手(打)",
1798 | "不给掀,你是变态",
1799 | "最后的底牌了!",
1800 | "这个hentai"
1801 | ],
1802 | "按摩": [
1803 | "(小手捏捏)咱的按摩舒服吗?",
1804 | "咱不会按摩的!",
1805 | "嘿咻嘿咻~这样觉得舒服吗?",
1806 | "呀!...呜...,不要...不要这样啦...呜...",
1807 | "只能按摩后背喔...",
1808 | "咱对这些不是很懂呢(????ω??????)"
1809 | ],
1810 | "按住": [
1811 | "Σ(°Д°;您要干什么~放开咱啦",
1812 | "突然使出过肩摔!",
1813 | "放手啦,再这样咱就要反击了喔",
1814 | "你的眼睛在看哪里!",
1815 | "呜呒~唔(伸出舌头)",
1816 | "H的事情,不可以!",
1817 | "想吃吗?(๑•ૅω•´๑)",
1818 | "要和咱比试比试吗",
1819 | "呜哇(/ω\)…快…快放开咱!!",
1820 | "(用力揪你耳朵)下次再敢这样的话就没容易放过你了!哼!",
1821 | "尼……奏凯……快航休!",
1822 | "哈?别..唔啊!别把咱……(挣扎)baka!别乱动咱啦!"
1823 | ],
1824 | "按在": [
1825 | "不要这样啦(一脸娇羞的推开)",
1826 | "(一个过肩摔,加踢裆然后帅气地回头)你太弱了呢~",
1827 | "放手啦,再这样咱就要反击了喔",
1828 | "Σ(°Д°; 你要干什么~放开咱啦",
1829 | "要和咱比试比试吗",
1830 | "呜哇(/ω\)…快…快放开咱!!",
1831 | "敢按住咱真是好大的胆子!",
1832 | "(用力揪你耳朵)下次再敢这样的话就没容易放过你了!哼!",
1833 | "尼……奏凯……快航休!",
1834 | "哈?别..唔啊!别把咱……(挣扎)baka!别乱动咱啦!"
1835 | ],
1836 | "按倒": [
1837 | "把咱按倒是想干嘛呢(??`⊿??)??",
1838 | "咱也...咱也是...都等你好长时间了",
1839 | "你的身体没问题吧?",
1840 | "呜呒~唔(伸出舌头)",
1841 | "H的事情,不可以!",
1842 | "放手啦,再这样咱就要反击了喔",
1843 | "想吃吗?(๑•ૅω•´๑)",
1844 | "不....不要吧..咱会害羞的(//////)",
1845 | "要和咱比试比试吗",
1846 | "呜哇(/ω\)…快…快放开咱!!",
1847 | "(用力揪你耳朵)下次再敢这样的话就没容易放过你了!哼!",
1848 | "尼……奏凯……快航休!",
1849 | "哈?别..唔啊!别把咱……(挣扎)baka!别乱动咱啦!"
1850 | ],
1851 | "按": [
1852 | "咱也...咱也是...都等你好长时间了",
1853 | "不让!",
1854 | "不要,好难为情",
1855 | "你的眼睛在看哪里!",
1856 | "拒绝!",
1857 | "唔...唔..嗯",
1858 | "咱就勉为其难地给你弄弄好啦",
1859 | "欸…变态!",
1860 | "会感到舒服什么的,那...那样的事情,是完全不存在的!",
1861 | "poi~",
1862 | "你在盯着什么地方看!变态萝莉控!"
1863 | ],
1864 | "炼铜": [
1865 | "炼铜有什么好玩的,和咱一起玩吧",
1866 | "炼铜不如恋咱",
1867 | "你也是个炼铜术士嘛?",
1868 | "信不信咱把你按在水泥上摩擦?",
1869 | "炼,都可以炼!",
1870 | "大hentai!一巴掌拍飞!(╯‵□′)╯︵┻━┻",
1871 | "锻炼什么的咱才不需要呢 (心虚地摸了摸自己的小肚子)",
1872 | "把你的头按在地上摩擦",
1873 | "你在盯着什么地方看!变态萝莉控!"
1874 | ],
1875 | "白丝": [
1876 | "喜欢,咱觉得白丝看起来很可爱呢",
1877 | "(脱)白丝只能给亲爱的你一个人呢…(递)",
1878 | "哼,hentai,这么想要咱的脚吗(ノ`⊿´)ノ",
1879 | "难道你这个hentai想让咱穿白丝踩踏你吗",
1880 | "不给看",
1881 | "很滑很~柔顺~的白丝袜哟~!!!∑(°Д°ノ)ノ你不会想做奇怪的事情吧!?",
1882 | "你……是要黑丝呢?还是白丝呢?或者光着(害羞)",
1883 | "来……来看吧"
1884 | ],
1885 | "黑丝": [
1886 | "哼,hentai,这么想要咱的脚吗(ノ`⊿´)ノ",
1887 | "不给看",
1888 | "你……是要黑丝呢?还是白丝呢?或者光着(害羞)",
1889 | "很滑很~柔顺~的黑丝袜哟~!!!∑(°Д°ノ)ノ您不会想做奇怪的事情吧!?",
1890 | "来……来看吧",
1891 | "噫...你这个hentai难道想让咱穿黑丝么",
1892 | "(默默抬起穿着黑丝的脚)"
1893 | ],
1894 | "喷": [
1895 | "咱才不喷呢!不过…既然是你让咱喷的话就勉为其难给你喷一次吧(噗)",
1896 | "不……不会喷水啦!喷……喷火也不会哦!",
1897 | "你怎么知道(捂住裙子)",
1898 | "你难道在期待什么?",
1899 | "欸…变态!"
1900 | ],
1901 | "回来": [
1902 | "欢迎回来~",
1903 | "欢迎回来,你想喝茶吗?咱去给你沏~",
1904 | "欢迎回来,咱等你很久了~",
1905 | "忙碌了一天,辛苦了呢(^_^)",
1906 | "(扑~)欢迎回来~",
1907 | "嗯呐嗯呐,欢迎回来~",
1908 | "欢迎回来,要来杯红茶放松一下吗?还有饼干哦。",
1909 | "咱会一直一直一直等着",
1910 | "是要先洗澡呢?还是先吃饭呢?还是先·吃·咱呢~",
1911 | "你回来啦,是先吃饭呢还是先洗澡呢或者是●先●吃●咱●——呢(///^.^///)",
1912 | "要先吃饭呢~还是先洗澡呢~还是先~吃~咱",
1913 | "是吗……辛苦你了。你这副倔强的样子,真可爱呢(笑)勉强让你躺在咱的腿上休息一下吧,别流口水哟",
1914 | "嗯……勉为其难欢迎你一下吧",
1915 | "想咱了嘛",
1916 | "欢迎回.....什么?咱才没有开心的说QUQ",
1917 | "哼╯^╰,你怎么这么晚才回来!",
1918 | "回来了吗,咱...咱才没有想你",
1919 | "咱等你很久了哼ヽ(≧Д≦)ノ",
1920 | "咱很想你(≧▽≦)"
1921 | ]
1922 | }
1923 | }
--------------------------------------------------------------------------------
/src/main/resources/fonts/黑体.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/fonts/黑体.ttf
--------------------------------------------------------------------------------
/src/main/resources/jrys/0/0/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/0/0/1.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/0/0/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/0/0/2.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/0/0/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/0/0/3.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/0/0/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/0/0/4.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/0/0/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/0/0/5.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/0/0/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/0/0/bg.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/0/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/0/1.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/0/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/0/2.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/0/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/0/3.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/0/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/0/4.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/0/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/0/bg.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/1/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/1/1.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/1/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/1/2.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/1/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/1/3.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/1/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/1/4.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/1/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/1/5.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/1/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/1/bg.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/2/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/2/1.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/2/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/2/2.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/2/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/2/3.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/2/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/2/4.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/2/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/2/bg.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/3/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/3/1.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/3/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/3/2.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/3/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/3/3.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/1/3/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/1/3/bg.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/2/0/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/2/0/1.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/2/0/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/2/0/2.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/2/0/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/2/0/3.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/2/0/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/2/0/4.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/2/0/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/2/0/bg.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/基沃托斯/SRT小队.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/基沃托斯/SRT小队.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/基沃托斯/基沃托斯.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/基沃托斯/基沃托斯.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/心奈印章/0_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/心奈印章/0_0.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/心奈印章/0_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/心奈印章/0_1.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/心奈印章/0_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/心奈印章/0_2.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/心奈印章/0_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/心奈印章/0_3.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/心奈印章/100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/心奈印章/100.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/心奈印章/59.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/心奈印章/59.png
--------------------------------------------------------------------------------
/src/main/resources/jrys/心奈印章/60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/jrys/心奈印章/60.png
--------------------------------------------------------------------------------
/src/main/resources/pic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Travellerrr/AronaBot/1df52505620a5b5592ad153501ee2308545a49f6/src/main/resources/pic.png
--------------------------------------------------------------------------------