├── .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 | 11 | 16 | 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 | ![](https://socialify.git.ci/Travellerrr/AronaBot/image?description=1&font=Raleway&forks=1&issues=1&language=1&name=1&owner=1&pattern=Circuit%20Board&pulls=1&stargazers=1&theme=Auto) 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 | [![Stargazers over time](https://starchart.cc/Travellerrr/AronaBot.svg?variant=adaptive)](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 --------------------------------------------------------------------------------