├── .gitignore ├── README.md ├── docs └── image │ ├── image01.png │ ├── image02.png │ ├── image03.png │ ├── image04.png │ └── pay.png ├── libs ├── JRegistry-1.1.0.jar ├── eventbus-java-3.3.1.jar ├── jaudiotagger-3.0.2.jar └── thumbnailator-0.4.20.jar ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main ├── java │ ├── cn │ │ └── tealc995 │ │ │ ├── aria2 │ │ │ ├── Aria2Client.java │ │ │ ├── Aria2Method.java │ │ │ └── model │ │ │ │ ├── Aria2Option.java │ │ │ │ ├── Aria2Param.java │ │ │ │ └── Aria2Request.java │ │ │ ├── kikoreu │ │ │ ├── HttpUtils.java │ │ │ ├── KKApi.java │ │ │ ├── NewHttpClient.java │ │ │ ├── api │ │ │ │ ├── BaseApi.java │ │ │ │ ├── CategoryApi.java │ │ │ │ ├── PlayListApi.java │ │ │ │ ├── SearchApi.java │ │ │ │ ├── StarApi.java │ │ │ │ ├── TrackApi.java │ │ │ │ ├── UserApi.java │ │ │ │ └── WorksApi.java │ │ │ └── model │ │ │ │ ├── CountDetail.java │ │ │ │ ├── LanguageEdition.java │ │ │ │ ├── LanguageEditionDeserialize.java │ │ │ │ ├── MainWorks.java │ │ │ │ ├── Message.java │ │ │ │ ├── Pagination.java │ │ │ │ ├── Rank.java │ │ │ │ ├── Response.java │ │ │ │ ├── ResponseBody.java │ │ │ │ ├── Role.java │ │ │ │ ├── RoleEx.java │ │ │ │ ├── SearchKey.java │ │ │ │ ├── SortType.java │ │ │ │ ├── Track.java │ │ │ │ ├── User.java │ │ │ │ ├── Work.java │ │ │ │ └── playList │ │ │ │ ├── MainPlayList.java │ │ │ │ ├── PlayList.java │ │ │ │ ├── PlayListAlter.java │ │ │ │ ├── PlayListBase.java │ │ │ │ ├── PlayListCreate.java │ │ │ │ └── PlayListRemoveWork.java │ │ │ ├── kkmaid │ │ │ ├── App.java │ │ │ ├── AppStart.java │ │ │ ├── config │ │ │ │ ├── BlackList.java │ │ │ │ ├── Config.java │ │ │ │ └── Setting.java │ │ │ ├── event │ │ │ │ ├── BlackWorkEvent.java │ │ │ │ ├── EventBusUtil.java │ │ │ │ ├── GridItemRemoveEvent.java │ │ │ │ ├── MainCenterEvent.java │ │ │ │ ├── MainDialogEvent.java │ │ │ │ ├── MainNotificationEvent.java │ │ │ │ ├── MainPaneEvent.java │ │ │ │ ├── MainPlayListRemoveWorkEvent.java │ │ │ │ ├── PlayListAlterEvent.java │ │ │ │ ├── PlayListRemoveEvent.java │ │ │ │ └── SearchEvent.java │ │ │ ├── filter │ │ │ │ ├── AudioFilter.java │ │ │ │ ├── BackgroundImageFilter.java │ │ │ │ ├── DirectoryFilter.java │ │ │ │ ├── ImageFilter.java │ │ │ │ ├── LrcFilter.java │ │ │ │ ├── SupportAudioFormat.java │ │ │ │ ├── SupportImageFormat.java │ │ │ │ ├── SupportSubtitleFormat.java │ │ │ │ └── SupportVideoFormat.java │ │ │ ├── model │ │ │ │ ├── Audio.java │ │ │ │ ├── Music.java │ │ │ │ ├── StringKeyIntValue.java │ │ │ │ ├── SubtitleData.java │ │ │ │ └── lrc │ │ │ │ │ ├── LrcBean.java │ │ │ │ │ ├── LrcFile.java │ │ │ │ │ └── LrcType.java │ │ │ ├── player │ │ │ │ ├── LcMediaPlayer.java │ │ │ │ ├── MediaPlayerUtil.java │ │ │ │ ├── TeaMediaPlayer.java │ │ │ │ └── VlcPlayer.java │ │ │ ├── service │ │ │ │ ├── api │ │ │ │ │ ├── CategoryTask.java │ │ │ │ │ ├── WorkTracksTask.java │ │ │ │ │ ├── login │ │ │ │ │ │ ├── CheckLoginTask.java │ │ │ │ │ │ └── LoginTask.java │ │ │ │ │ ├── playlist │ │ │ │ │ │ ├── PlayListAlterTask.java │ │ │ │ │ │ ├── PlayListCreateTask.java │ │ │ │ │ │ ├── PlayListDeleteTask.java │ │ │ │ │ │ ├── PlayListRemoveWorkTask.java │ │ │ │ │ │ ├── PlayListService.java │ │ │ │ │ │ └── PlayListWorkExistService.java │ │ │ │ │ ├── star │ │ │ │ │ │ ├── StarWorkAddTask.java │ │ │ │ │ │ └── StarWorkRemoveTask.java │ │ │ │ │ └── works │ │ │ │ │ │ ├── MainWorksService.java │ │ │ │ │ │ ├── PlayListWorksService.java │ │ │ │ │ │ └── WorksBaseService.java │ │ │ │ └── subtitle │ │ │ │ │ ├── SeekSubtitleFileService.java │ │ │ │ │ ├── beans │ │ │ │ │ ├── SubtitleBeansBaseTask.java │ │ │ │ │ ├── SubtitleBeansByFolderTask.java │ │ │ │ │ ├── SubtitleBeansByNetTask.java │ │ │ │ │ └── SubtitleBeansByZipTask.java │ │ │ │ │ └── row │ │ │ │ │ ├── SubtitleRowBaseTask.java │ │ │ │ │ ├── SubtitleRowByFolderTask.java │ │ │ │ │ ├── SubtitleRowByNetTask.java │ │ │ │ │ └── SubtitleRowByZipTask.java │ │ │ ├── ui │ │ │ │ ├── CategoryType.java │ │ │ │ ├── CategoryUI.java │ │ │ │ ├── CategoryViewModel.java │ │ │ │ ├── DetailUI.java │ │ │ │ ├── DetailViewModel.java │ │ │ │ ├── DownloadUI.java │ │ │ │ ├── DownloadViewModel.java │ │ │ │ ├── LoginUI.java │ │ │ │ ├── LoginViewModel.java │ │ │ │ ├── MainGridUI.java │ │ │ │ ├── MainGridViewModel.java │ │ │ │ ├── MainPlayListUI.java │ │ │ │ ├── MainPlayListViewModel.java │ │ │ │ ├── MainUI.java │ │ │ │ ├── MainViewModel.java │ │ │ │ ├── PlayListUI.java │ │ │ │ ├── PlayListViewModel.java │ │ │ │ ├── PlayerUI.java │ │ │ │ ├── PlayingListUI.java │ │ │ │ ├── PosterUI.java │ │ │ │ ├── PosterViewModel.java │ │ │ │ ├── SettingUI.java │ │ │ │ ├── SettingUIViewModel.java │ │ │ │ ├── SimplePlayerUI.java │ │ │ │ ├── SimplePlayerViewModel.java │ │ │ │ ├── cell │ │ │ │ │ ├── DownloadTreeItem.java │ │ │ │ │ ├── FileTreeItem.java │ │ │ │ │ ├── LrcListCell.java │ │ │ │ │ ├── PlayListCell.java │ │ │ │ │ ├── PlayListWorkCell.java │ │ │ │ │ ├── WorkCell.java │ │ │ │ │ └── ZipTreeItem.java │ │ │ │ ├── component │ │ │ │ │ ├── DesktopLrcDialog.java │ │ │ │ │ ├── Dialog.java │ │ │ │ │ ├── FolderTableView.java │ │ │ │ │ ├── GridView.java │ │ │ │ │ ├── LrcView.java │ │ │ │ │ └── PathViewPane.java │ │ │ │ ├── item │ │ │ │ │ ├── LrcFileDialogUI.java │ │ │ │ │ ├── LrcFileDialogViewModel.java │ │ │ │ │ ├── LrcFolderDialogUI.java │ │ │ │ │ ├── LrcFolderDialogViewModel.java │ │ │ │ │ ├── LrcZipDialogUI.java │ │ │ │ │ ├── LrcZipDialogViewModel.java │ │ │ │ │ ├── PlayListAddUI.java │ │ │ │ │ └── VolumeUI.java │ │ │ │ └── stage │ │ │ │ │ ├── ImageViewStage.java │ │ │ │ │ ├── LocalSubtitleStage.java │ │ │ │ │ └── SubtitleStage.java │ │ │ ├── util │ │ │ │ ├── AnchorPaneUtil.java │ │ │ │ ├── CssLoader.java │ │ │ │ ├── FXResourcesLoader.java │ │ │ │ ├── LrcFormatUtil.java │ │ │ │ ├── LrcImportUtil.java │ │ │ │ ├── OSUtil.java │ │ │ │ ├── TimeFormatUtil.java │ │ │ │ └── comparator │ │ │ │ │ ├── FileNameComparator.java │ │ │ │ │ ├── LrcFileComparator.java │ │ │ │ │ └── TrackComparator.java │ │ │ └── zip │ │ │ │ ├── NewZipUtil.java │ │ │ │ └── ZipEntityFile.java │ │ │ └── teaFX │ │ │ ├── config │ │ │ └── Config.java │ │ │ ├── controls │ │ │ ├── LoadingDot.java │ │ │ ├── TitleBar.java │ │ │ └── notification │ │ │ │ ├── MessageType.java │ │ │ │ └── Notification.java │ │ │ ├── enums │ │ │ └── TitleBarStyle.java │ │ │ ├── handler │ │ │ ├── DragWindowHandler.java │ │ │ └── ResizeWindowHandler.java │ │ │ └── stage │ │ │ ├── RoundStage.java │ │ │ ├── TeaStage.java │ │ │ └── handler │ │ │ ├── DragWindowHandler.java │ │ │ └── ResizeWindowHandler.java │ └── module-info.java └── resources │ ├── cn │ └── tealc995 │ │ ├── kkmaid │ │ ├── css │ │ │ ├── BaseUI.css │ │ │ ├── SVGS.css │ │ │ ├── category.css │ │ │ ├── colors.css │ │ │ ├── detail.css │ │ │ ├── download.css │ │ │ ├── item │ │ │ │ ├── lrc-file-dialog.css │ │ │ │ ├── lrc-stage.css │ │ │ │ ├── lrc-zip-dialog.css │ │ │ │ ├── playing-list.css │ │ │ │ └── volume-popup.css │ │ │ ├── main-grid.css │ │ │ ├── main.css │ │ │ ├── player-detail.css │ │ │ ├── setting.css │ │ │ └── simple-player.css │ │ ├── fxml │ │ │ └── player.fxml │ │ └── image │ │ │ ├── album.jpg │ │ │ ├── cover-main.jpg │ │ │ ├── gkdk.png │ │ │ ├── icon.png │ │ │ ├── logo.ico │ │ │ ├── suffix │ │ │ ├── file-audio.png │ │ │ ├── file-folder.png │ │ │ ├── file-image.png │ │ │ ├── file-unknown.png │ │ │ └── file-video.png │ │ │ └── title.png │ │ └── teaFX │ │ └── css │ │ ├── base_ui.css │ │ ├── scene-bar.css │ │ └── title-bar.css │ └── logback.xml └── windows └── assets └── icon.ico /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .mvn/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### IntelliJ IDEA ### 8 | .idea/ 9 | .idea/modules.xml 10 | .idea/jarRepositories.xml 11 | .idea/compiler.xml 12 | .idea/libraries/ 13 | *.iws 14 | *.iml 15 | *.ipr 16 | 17 | ### Eclipse ### 18 | .apt_generated 19 | .classpath 20 | .factorypath 21 | .project 22 | .settings 23 | .springBeans 24 | .sts4-cache 25 | 26 | ### NetBeans ### 27 | /nbproject/private/ 28 | /nbbuild/ 29 | /dist/ 30 | /nbdist/ 31 | /.nb-gradle/ 32 | build/ 33 | !**/src/main/**/build/ 34 | !**/src/test/**/build/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | 39 | ### Mac OS ### 40 | .DS_Store 41 | 42 | 43 | config.properties -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **本项目是作者学习JavaFX的练手项目,仅供学习交流使用,请勿进行推广与搬运,谢谢。** 2 | 3 | # 一、说明 4 | 5 | 未来道具11号-KK Maid是一款适配ASMR ONE的桌面级客户端,使用JavaFX进行开发。主要解决在使用Web应用的痛点问题,如不够灵活的桌面歌词,繁琐的下载,手里成千上万的字幕包却无法可视化查看等等。 6 | 7 | 目前实现的功能有: 8 | 9 | - 基本的功能,包括作品浏览,收藏,播放,LRC与VTT支持; 10 | - 歌单的创建与管理; 11 | - 更美观的播放界面,控制,滚动歌词统统有; 12 | - 更便捷的在线图片浏览,图片切换,放大缩小,一键保存; 13 | - 更好的桌面歌词,透明,自定义颜色,锁定,我全都要; 14 | - 更强大的本地字幕支持(ZIP字幕包与字幕文件夹),播放在线作品可以使用本地字幕; 15 | - 更贴心的功能,本地字幕包在线可视化匹配,有图有真相; 16 | - 更强大的字幕查看,一个窗口查看所有字幕; 17 | - 更便捷的作品下载(需要配置Motrix); 18 | - 更详细黑名单支持,包括作品黑名单,标签黑名单,字幕文本黑名单。 19 | 20 | image.png 21 | image.png 22 | 23 | # 二、使用教程 24 | ### 请记住:未来道具11号不是一款商业软件,没有精力去考虑与处理方方面面的异常。开发者的设计理念一直是在约定的范围内合理使用,则有着良好的体验。 25 | #### 1. 配置服务器和Token 26 | 程序使用需要配置服务器地址和Token。首次使用,请前往 **设置-服务器** 设置服务器地址以及Token。 27 | 28 | **如果你无法直接访问网站,先设置代理并重启。** 29 | ![image.png](./docs/image/image04.png) 30 | 31 | > **请严格按照格式来填写,不要多一个字符** 32 | 33 | 服务器API : 假设服务器地址是https://baidu.com,那么输入框填写的Api地址是https://api.baidu.com,具体请前往网站查询具体服务器地址。 34 | 35 | Token: 傻瓜式操作,点击获取Token登录即可。 36 | 37 | 配置完上面两项就可以愉快使用了。 38 | 39 | #### 2. 配置本地字幕 40 | 41 | > 注意:本地字幕目前只支持LRC格式,字幕压缩包只支持ZIP格式 42 | 43 | 如果你需要使用本地字幕,前往 **设置-字幕管理** 进行配置。 44 | 45 | 目前程序支持两种字幕导入方式,分别是**字幕根文件夹**以及**字幕压缩包文件夹**。请优先使用**字幕压缩包文件夹**方式,字幕根文件夹未来不再支持。 46 | 47 | ##### 本地字幕根文件夹:这个是所有字幕文件夹的根文件夹,里面放置的的是每个音声的字幕文件夹。请注意暂不支持子字幕文件夹的查找与读取。 48 | 49 | ##### 本地压缩包文件夹:里面放的是所有zip格式的字幕压缩包。请注意暂不支持子字幕文件夹的查找与读取 50 | 51 | ``` 52 | 字幕根文件夹的格式如下: 53 | -根目录 54 | --作品1 55 | ---字幕01.lrc 56 | ---字幕01.lrc 57 | --作品2 58 | ---字幕01.lrc 59 | ---字幕01.lrc 60 | 61 | 字幕压缩包文件夹的格式如下: 62 | -根目录 63 | --作品1.zip 64 | --作品2.zip 65 | ``` 66 | 67 | #### 3. 将本地字幕进行可视化浏览 68 | 69 | 本地字幕包如何选取自己喜欢的作品是一大麻烦事,毕竟没图没真相。 70 | 71 | 本程序通过歌单的方式实现了本地字幕的可视化浏览,即像浏览在线作品一样浏览本地字幕对应的作品。 72 | 73 | 首先,配置好本地字幕;然后前往歌单界面,点击右上角创建新的歌单,**勾选导入本地字幕作品**,完成添加。这样就可以在新创建的歌单中查看本地字幕对应的作品了。 74 | 75 | ![image03](./docs/image/image03.png) 76 | 77 | 78 | 79 | > 注意:对于网站上没有的作品,不会显示。 80 | 81 | #### 4. 下载作品到本地 82 | 83 | 程序不内置下载程序,通过Aira2的适配进行下载(开发者推荐使用[Motrix](https://motrix.app/)),速度会有所保证。如果你对Aira2不了解,请善用搜索引擎。 84 | 85 | 使用前需要前往**设置-下载**完成配置,设置下载目标文件夹,Aira2的地址以及Aira2的PRC密钥。 86 | 87 | # 三、问题与解答 88 | #### 关于字幕文件相关,乱码问题 89 | KK Maid只支持UTF-8格式的LRC字幕文件,非UTF-8格式的字幕无法正常读取,会产生乱码文字,倘若其他格式请使用其他编辑器更改。 90 | 如果在使用本地Zip字幕包时,字幕标题乱码,这是因为字幕包的打包环境编码格式导致的。例如MAC打包在Windows中读取会导致标题乱码,因为MAC的默认编码是UTF-8,而Windows默认编码是GBK。解决方法是手动重新打包,当然这并不影响字幕文本。 91 | 92 | #### 字幕文件与当前播放并不配对问题 93 | 由于各种字幕标准不一,有的字幕名称是日文,有的是中文等其他语言,有的有特典字幕,有的没有特典字幕,自然难以保证百分百配对。当然KK Maid提供解决方法。你可以在播放界面,选择字幕管理功能,对不匹配的字幕进行手动适配。 94 | 95 | #### 有时候无响应或者内容加载不出来 96 | 一般是网络问题,检查网络后重启即可。 97 | 98 | 99 | 100 | # 四、感谢以下开源项目 101 | 102 | 1. [JFoenix](https://github.com/sshahine/JFoenix) 103 | 2. [FXTrayIcon](https://github.com/dustinkredmond/FXTrayIcon) 104 | 3. [ControlsFX](https://github.com/controlsfx/controlsfx) 105 | 4. [Jackson](https://github.com/FasterXML/jackson) 106 | 5. [Atlantafx](https://github.com/mkpaz/atlantafx) 107 | 6. [Openjfx](https://openjfx.io/) 108 | 7. [Zip4j](https://github.com/srikanth-lingala/zip4j) 109 | 8. [EventBus](https://github.com/greenrobot/EventBus) 110 | 111 | # 五、如果该开源项目对您的学习有所帮助,欢迎赞助支持。 112 | 113 | 您可以按照以下格式留言: 114 | 115 | **KK Maid @[称呼]:[想说的话]** 116 | 117 | ![image03](./docs/image/pay.png) 118 | -------------------------------------------------------------------------------- /docs/image/image01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leck995/KK-Maid/6b300338140119d400160e452f8a93d457f86a10/docs/image/image01.png -------------------------------------------------------------------------------- /docs/image/image02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leck995/KK-Maid/6b300338140119d400160e452f8a93d457f86a10/docs/image/image02.png -------------------------------------------------------------------------------- /docs/image/image03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leck995/KK-Maid/6b300338140119d400160e452f8a93d457f86a10/docs/image/image03.png -------------------------------------------------------------------------------- /docs/image/image04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leck995/KK-Maid/6b300338140119d400160e452f8a93d457f86a10/docs/image/image04.png -------------------------------------------------------------------------------- /docs/image/pay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leck995/KK-Maid/6b300338140119d400160e452f8a93d457f86a10/docs/image/pay.png -------------------------------------------------------------------------------- /libs/JRegistry-1.1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leck995/KK-Maid/6b300338140119d400160e452f8a93d457f86a10/libs/JRegistry-1.1.0.jar -------------------------------------------------------------------------------- /libs/eventbus-java-3.3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leck995/KK-Maid/6b300338140119d400160e452f8a93d457f86a10/libs/eventbus-java-3.3.1.jar -------------------------------------------------------------------------------- /libs/jaudiotagger-3.0.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leck995/KK-Maid/6b300338140119d400160e452f8a93d457f86a10/libs/jaudiotagger-3.0.2.jar -------------------------------------------------------------------------------- /libs/thumbnailator-0.4.20.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leck995/KK-Maid/6b300338140119d400160e452f8a93d457f86a10/libs/thumbnailator-0.4.20.jar -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/aria2/Aria2Client.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.aria2; 2 | 3 | 4 | import cn.tealc995.kikoreu.model.Response; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.InputStreamReader; 8 | import java.io.OutputStream; 9 | import java.net.HttpURLConnection; 10 | import java.net.URL; 11 | import java.nio.charset.StandardCharsets; 12 | 13 | /** 14 | * @description: 15 | * @author: Leck 16 | * @create: 2023-07-12 19:51 17 | */ 18 | public class Aria2Client { 19 | 20 | 21 | 22 | 23 | 24 | 25 | public static Response post(String path,String json) { 26 | BufferedReader in = null; 27 | StringBuilder sb = new StringBuilder(); 28 | try { 29 | URL url = new URL(path); 30 | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 31 | conn.setRequestMethod("POST"); 32 | conn.setUseCaches(false); 33 | conn.setDoOutput(true); 34 | conn.setDoInput(true); 35 | 36 | 37 | byte[] bytes = json.getBytes(StandardCharsets.UTF_8); 38 | conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");// 设定 39 | conn.setRequestProperty("Content-Length", String.valueOf(bytes.length)); 40 | OutputStream outwritestream = conn.getOutputStream(); 41 | outwritestream.write(bytes); 42 | outwritestream.flush(); 43 | outwritestream.close(); 44 | if (conn.getResponseCode() == 200) { 45 | // 定义BufferedReader输入流来读取URL的响应 46 | in = new BufferedReader(new InputStreamReader(conn.getInputStream(),StandardCharsets.UTF_8)); 47 | String line; 48 | while ((line = in.readLine()) != null) { 49 | sb.append(line); 50 | } 51 | } else { 52 | in = new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8)); 53 | String line; 54 | while ((line = in.readLine()) != null) { 55 | sb.append(line); 56 | } 57 | in.close(); 58 | } 59 | conn.disconnect(); 60 | return new Response(conn.getResponseCode(),sb.toString()); 61 | } catch (Exception e) { 62 | e.printStackTrace(); 63 | return new Response(404,e.getMessage()); 64 | } 65 | } 66 | 67 | 68 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/aria2/Aria2Method.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.aria2; 2 | 3 | public enum Aria2Method { 4 | 5 | TELL_ACTIVE("aria2.tellActive"), 6 | ADD_URI("aria2.addUri"); 7 | 8 | 9 | private final String value; 10 | 11 | Aria2Method(String value) { 12 | this.value = value; 13 | } 14 | 15 | public String getValue() { 16 | return value; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/aria2/model/Aria2Option.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.aria2.model; 2 | 3 | /** 4 | * @description: 5 | * @author: Leck 6 | * @create: 2023-09-13 01:26 7 | */ 8 | public class Aria2Option { 9 | private String dir; 10 | private String out; 11 | private String referer; 12 | 13 | public Aria2Option() { 14 | } 15 | 16 | public Aria2Option(String path, String referer) { 17 | int i = path.lastIndexOf("/"); 18 | 19 | this.dir = path.substring(0,i); 20 | this.out = path.substring(i+1); 21 | this.referer = referer; 22 | } 23 | public Aria2Option(String dir, String out, String referer) { 24 | this.dir = dir; 25 | this.out = out; 26 | this.referer = referer; 27 | } 28 | 29 | public String getDir() { 30 | return dir; 31 | } 32 | 33 | public void setDir(String dir) { 34 | this.dir = dir; 35 | } 36 | 37 | public String getOut() { 38 | return out; 39 | } 40 | 41 | public void setOut(String out) { 42 | this.out = out; 43 | } 44 | 45 | public String getReferer() { 46 | return referer; 47 | } 48 | 49 | public void setReferer(String referer) { 50 | this.referer = referer; 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/aria2/model/Aria2Param.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.aria2.model; 2 | 3 | 4 | /** 5 | * @description: 6 | * @author: Leck 7 | * @create: 2023-09-13 01:27 8 | */ 9 | public class Aria2Param { 10 | private String token; 11 | private String[] urls; 12 | private Aria2Option option; 13 | 14 | public Aria2Param(String token, String[] urls, Aria2Option option) { 15 | this.token = token; 16 | this.urls = urls; 17 | this.option = option; 18 | } 19 | 20 | public Aria2Param(String token, String url, Aria2Option option) { 21 | this.token = token; 22 | this.urls = new String[]{url}; 23 | this.option = option; 24 | } 25 | 26 | public String getToken() { 27 | return token; 28 | } 29 | 30 | public void setToken(String token) { 31 | this.token = token; 32 | } 33 | 34 | public String[] getUrls() { 35 | return urls; 36 | } 37 | 38 | public void setUrls(String[] urls) { 39 | this.urls = urls; 40 | } 41 | 42 | public Aria2Option getOption() { 43 | return option; 44 | } 45 | 46 | public void setOption(Aria2Option option) { 47 | this.option = option; 48 | } 49 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/aria2/model/Aria2Request.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.aria2.model; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-09-13 01:33 9 | */ 10 | public class Aria2Request { 11 | private String id; 12 | private final String jsonrpc="2.0"; 13 | private String method; 14 | private List params; 15 | 16 | public Aria2Request(String id, String method, List params) { 17 | this.id = id; 18 | this.method = method; 19 | this.params = params; 20 | } 21 | 22 | public String getId() { 23 | return id; 24 | } 25 | 26 | public void setId(String id) { 27 | this.id = id; 28 | } 29 | 30 | public String getMethod() { 31 | return method; 32 | } 33 | 34 | public void setMethod(String method) { 35 | this.method = method; 36 | } 37 | 38 | public List getParams() { 39 | return params; 40 | } 41 | 42 | public void setParams(List params) { 43 | this.params = params; 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/KKApi.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu; 2 | 3 | import cn.tealc995.kikoreu.api.*; 4 | 5 | /** 6 | * @program: KK-Maid 7 | * @description: 8 | * @author: Leck 9 | * @create: 2025-02-01 22:33 10 | */ 11 | public class KKApi { 12 | private static KKApi instance; 13 | private NewHttpClient client; 14 | private String token; 15 | private String host; 16 | private KKApi() { 17 | client = new NewHttpClient(); 18 | } 19 | 20 | public static KKApi getInstance() { 21 | if (instance == null) { 22 | instance = new KKApi(); 23 | } 24 | return instance; 25 | } 26 | 27 | public void setToken(String token) { 28 | this.token = token; 29 | client.setToken(token); 30 | } 31 | 32 | public void setHost(String host) { 33 | this.host = host; 34 | client.setHost(host); 35 | } 36 | 37 | 38 | 39 | 40 | public WorksApi worksApi(){ 41 | return new WorksApi(client); 42 | } 43 | 44 | public UserApi userApi(){ 45 | return new UserApi(client); 46 | } 47 | 48 | public TrackApi trackApi(){ 49 | return new TrackApi(client); 50 | } 51 | 52 | public StarApi starApi(){ 53 | return new StarApi(client); 54 | } 55 | public SearchApi searchApi(){ 56 | return new SearchApi(client); 57 | } 58 | public PlayListApi playListApi(){ 59 | return new PlayListApi(client); 60 | } 61 | public CategoryApi categoryApi(){ 62 | return new CategoryApi(client); 63 | } 64 | 65 | public NewHttpClient getHttpClient() { 66 | return client; 67 | } 68 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/api/BaseApi.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.api; 2 | 3 | import cn.tealc995.kikoreu.NewHttpClient; 4 | 5 | /** 6 | * @program: KK-Maid 7 | * @description: 8 | * @author: Leck 9 | * @create: 2025-02-01 22:42 10 | */ 11 | public class BaseApi { 12 | protected NewHttpClient httpClient; 13 | 14 | public BaseApi(NewHttpClient httpClient) { 15 | this.httpClient = httpClient; 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/api/CategoryApi.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.api; 2 | 3 | import cn.tealc995.kikoreu.NewHttpClient; 4 | import cn.tealc995.kikoreu.model.Response; 5 | import cn.tealc995.kikoreu.model.ResponseBody; 6 | import cn.tealc995.kikoreu.model.RoleEx; 7 | import com.fasterxml.jackson.core.JsonProcessingException; 8 | import com.fasterxml.jackson.core.type.TypeReference; 9 | import com.fasterxml.jackson.databind.ObjectMapper; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * @description: 15 | * @author: Leck 16 | * @create: 2023-07-13 07:00 17 | */ 18 | public class CategoryApi extends BaseApi { 19 | public CategoryApi(NewHttpClient httpClient) { 20 | super(httpClient); 21 | } 22 | 23 | public ResponseBody> circle() { 24 | Response response = httpClient.get("/api/circles/"); 25 | if (response.isSuccess()) { 26 | ObjectMapper mapper = new ObjectMapper(); 27 | try { 28 | List circles = mapper.readValue(response.getMessage(), new TypeReference<>() { 29 | }); 30 | return ResponseBody.create(response.getCode(), response.getMessage(), circles); 31 | } catch (JsonProcessingException e) { 32 | return ResponseBody.create(-1, "请求内容JSON解析失败", null); 33 | } 34 | } else { 35 | return ResponseBody.create(response.getCode(), response.getMessage(), null); 36 | } 37 | 38 | } 39 | 40 | public ResponseBody> tag() { 41 | Response response = httpClient.get("/api/tags/"); 42 | if (response.isSuccess()) { 43 | ObjectMapper mapper = new ObjectMapper(); 44 | try { 45 | List circles = mapper.readValue(response.getMessage(), new TypeReference<>() { 46 | }); 47 | return ResponseBody.create(response.getCode(), response.getMessage(), circles); 48 | } catch (JsonProcessingException e) { 49 | return ResponseBody.create(-1, "请求内容JSON解析失败", null); 50 | } 51 | } else { 52 | return ResponseBody.create(response.getCode(), response.getMessage(), null); 53 | } 54 | 55 | } 56 | 57 | public ResponseBody> va() { 58 | Response response = httpClient.get("/api/vas/"); 59 | if (response.isSuccess()) { 60 | ObjectMapper mapper = new ObjectMapper(); 61 | try { 62 | List circles = mapper.readValue(response.getMessage(), new TypeReference<>() { 63 | }); 64 | return ResponseBody.create(response.getCode(), response.getMessage(), circles); 65 | } catch (JsonProcessingException e) { 66 | return ResponseBody.create(-1, "请求内容JSON解析失败", null); 67 | } 68 | } else { 69 | return ResponseBody.create(response.getCode(), response.getMessage(), null); 70 | } 71 | 72 | } 73 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/api/SearchApi.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.api; 2 | 3 | import cn.tealc995.kikoreu.NewHttpClient; 4 | import cn.tealc995.kikoreu.model.MainWorks; 5 | import cn.tealc995.kikoreu.model.Response; 6 | import cn.tealc995.kikoreu.model.ResponseBody; 7 | import com.fasterxml.jackson.core.JsonProcessingException; 8 | import com.fasterxml.jackson.databind.ObjectMapper; 9 | 10 | import java.net.URLEncoder; 11 | import java.nio.charset.StandardCharsets; 12 | import java.util.Map; 13 | 14 | /** 15 | * @description: 16 | * @author: Leck 17 | * @create: 2023-07-13 06:07 18 | */ 19 | public class SearchApi extends BaseApi{ 20 | public SearchApi(NewHttpClient httpClient) { 21 | super(httpClient); 22 | } 23 | 24 | public ResponseBody search(String key, Map params){ 25 | Response response = httpClient.get("/api/search/"+ URLEncoder.encode(key, StandardCharsets.UTF_8),params); 26 | if (response.isSuccess()){ 27 | ObjectMapper mapper=new ObjectMapper(); 28 | try { 29 | MainWorks mainWorks = mapper.readValue(response.getMessage(), MainWorks.class); 30 | return ResponseBody.create(response.getCode(),response.getMessage(),mainWorks); 31 | } catch (JsonProcessingException e) { 32 | return ResponseBody.create(-1,"请求内容JSON解析失败",null); 33 | } 34 | }else { 35 | return ResponseBody.create(response.getCode(),response.getMessage(),null); 36 | } 37 | 38 | 39 | } 40 | 41 | 42 | 43 | 44 | 45 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/api/StarApi.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.api; 2 | 3 | import cn.tealc995.kikoreu.HttpUtils; 4 | import cn.tealc995.kikoreu.NewHttpClient; 5 | import cn.tealc995.kikoreu.model.MainWorks; 6 | import cn.tealc995.kikoreu.model.Response; 7 | import cn.tealc995.kikoreu.model.ResponseBody; 8 | import cn.tealc995.kkmaid.event.EventBusUtil; 9 | import cn.tealc995.kkmaid.event.MainNotificationEvent; 10 | import com.fasterxml.jackson.core.JsonProcessingException; 11 | import com.fasterxml.jackson.databind.ObjectMapper; 12 | 13 | import java.util.Map; 14 | 15 | /** 16 | * @description: 17 | * @author: Leck 18 | * @create: 2023-07-14 23:12 19 | */ 20 | public class StarApi extends BaseApi{ 21 | 22 | public StarApi(NewHttpClient httpClient) { 23 | super(httpClient); 24 | } 25 | 26 | public ResponseBody star(Map params){ 27 | Response response = httpClient.get("/api/review", params); 28 | if (response.isSuccess()){ 29 | ObjectMapper mapper=new ObjectMapper(); 30 | try { 31 | MainWorks mainWorks = mapper.readValue(response.getMessage(), MainWorks.class); 32 | return ResponseBody.create(response.getCode(),response.getMessage(),mainWorks); 33 | } catch (JsonProcessingException e) { 34 | return ResponseBody.create(-1,"请求内容JSON解析失败",null); 35 | } 36 | } else { 37 | return ResponseBody.create(response.getCode(),response.getMessage(),null); 38 | } 39 | } 40 | 41 | public ResponseBody updateStar(String workId,Integer rating){ 42 | String row=String.format("{\"work_id\":%s,\"rating\":%d}",workId,rating); 43 | Response response = httpClient.put( "/api/review", row); 44 | if (response.isSuccess()){ 45 | return ResponseBody.create(response.getCode(),response.getMessage(),true); 46 | } else { 47 | return ResponseBody.create(response.getCode(),response.getMessage(),false); 48 | } 49 | } 50 | 51 | public ResponseBody deleteStar(String workId){ 52 | Response response = httpClient.delete("/api/review?work_id="+workId); 53 | if (response.isSuccess()){ 54 | return ResponseBody.create(response.getCode(),response.getMessage(),true); 55 | } else { 56 | return ResponseBody.create(response.getCode(),response.getMessage(),false); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/api/TrackApi.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.api; 2 | 3 | import cn.tealc995.kikoreu.HttpUtils; 4 | import cn.tealc995.kikoreu.NewHttpClient; 5 | import cn.tealc995.kikoreu.model.Response; 6 | import cn.tealc995.kikoreu.model.ResponseBody; 7 | import cn.tealc995.kikoreu.model.Track; 8 | import cn.tealc995.kkmaid.event.EventBusUtil; 9 | import cn.tealc995.kkmaid.event.MainNotificationEvent; 10 | import com.fasterxml.jackson.core.JsonProcessingException; 11 | import com.fasterxml.jackson.core.type.TypeReference; 12 | import com.fasterxml.jackson.databind.ObjectMapper; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | * @description: 获取指定作品的文件列表 18 | * @author: Leck 19 | * @create: 2023-07-13 21:06 20 | */ 21 | public class TrackApi extends BaseApi{ 22 | public TrackApi(NewHttpClient httpClient) { 23 | super(httpClient); 24 | } 25 | 26 | public ResponseBody> track(String key){ 27 | Response response = httpClient.get("/api/tracks/" + key); 28 | if (response.isSuccess()){ 29 | ObjectMapper mapper = new ObjectMapper(); 30 | try { 31 | List tracks = mapper.readValue(response.getMessage(), new TypeReference<>(){}); 32 | return ResponseBody.create(response.getCode(), response.getMessage(), tracks); 33 | } catch (JsonProcessingException e) { 34 | return ResponseBody.create(-1,"请求内容JSON解析失败",null); 35 | } 36 | }else { 37 | return ResponseBody.create(response.getCode(), response.getMessage(),null); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/api/UserApi.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.api; 2 | 3 | import cn.tealc995.kikoreu.NewHttpClient; 4 | import cn.tealc995.kikoreu.model.Response; 5 | import cn.tealc995.kikoreu.model.ResponseBody; 6 | import cn.tealc995.kikoreu.model.User; 7 | import cn.tealc995.kkmaid.event.EventBusUtil; 8 | import cn.tealc995.kkmaid.event.MainNotificationEvent; 9 | import com.fasterxml.jackson.core.JsonProcessingException; 10 | import com.fasterxml.jackson.databind.JsonNode; 11 | import com.fasterxml.jackson.databind.ObjectMapper; 12 | 13 | /** 14 | * @description: 15 | * @author: Leck 16 | * @create: 2023-07-19 08:59 17 | */ 18 | public class UserApi extends BaseApi { 19 | public UserApi(NewHttpClient httpClient) { 20 | super(httpClient); 21 | } 22 | 23 | public ResponseBody checkLogin() { 24 | Response response = httpClient.get("/api/auth/me"); 25 | if (response.isSuccess()) { 26 | ObjectMapper mapper = new ObjectMapper(); 27 | try { 28 | JsonNode jsonNode = mapper.readTree(response.getMessage()); 29 | User user = mapper.convertValue(jsonNode.get("user"), User.class); 30 | return ResponseBody.create(response.getCode(), response.getMessage(),user); 31 | } catch (JsonProcessingException e) { 32 | return ResponseBody.create(-1,"请求内容JSON解析失败",null); 33 | } 34 | } else { 35 | return ResponseBody.create(response.getCode(), response.getMessage(),null); 36 | } 37 | } 38 | 39 | /** 40 | * @return ResponseBody 41 | * @description: 获取Token 42 | * @name: login 43 | * @author: Leck 44 | * @param: url 45 | * @param: username 46 | * @param: password 47 | * @date: 2023/7/19 48 | */ 49 | public ResponseBody login(String username, String password) { 50 | String row = String.format("{\"name\":\"%s\",\"password\":\"%s\"}", username, password); 51 | Response response = httpClient.post("/api/auth/me", row); 52 | if (response.isSuccess()) { 53 | ObjectMapper mapper = new ObjectMapper(); 54 | try { 55 | JsonNode jsonNode = mapper.readTree(response.getMessage()); 56 | return ResponseBody.create(response.getCode(), response.getMessage(),jsonNode.get("token").asText()); 57 | } catch (JsonProcessingException e) { 58 | return ResponseBody.create(-1,"请求内容JSON解析失败",null); 59 | } 60 | } else { 61 | return ResponseBody.create(response.getCode(), response.getMessage(),null); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/api/WorksApi.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.api; 2 | 3 | import cn.tealc995.kikoreu.HttpUtils; 4 | import cn.tealc995.kikoreu.NewHttpClient; 5 | import cn.tealc995.kikoreu.model.MainWorks; 6 | import cn.tealc995.kikoreu.model.Response; 7 | import cn.tealc995.kikoreu.model.ResponseBody; 8 | import com.fasterxml.jackson.core.JsonProcessingException; 9 | import com.fasterxml.jackson.databind.ObjectMapper; 10 | 11 | import java.util.Map; 12 | 13 | /** 14 | * @description: 15 | * @author: Leck 16 | * @create: 2023-07-12 19:35 17 | */ 18 | public class WorksApi extends BaseApi{ 19 | public WorksApi(NewHttpClient httpClient) { 20 | super(httpClient); 21 | } 22 | 23 | public ResponseBody works(Map params){ 24 | Response response = httpClient.get("/api/works", params); 25 | if (response.isSuccess()){ 26 | ObjectMapper mapper=new ObjectMapper(); 27 | try { 28 | MainWorks mainWorks = mapper.readValue(response.getMessage(), MainWorks.class); 29 | return ResponseBody.create(response.getCode(),response.getMessage(),mainWorks); 30 | } catch (JsonProcessingException e) { 31 | return ResponseBody.create(-1,"请求内容JSON解析失败",null); 32 | } 33 | }else { 34 | return ResponseBody.create(response.getCode(),response.getMessage(),null); 35 | } 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/CountDetail.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model; 2 | 3 | /** 4 | * @author: Leck 5 | * @create: 2023-07-12 19:29 6 | */ 7 | public class CountDetail { 8 | private int count; 9 | private int ratio; 10 | private int review_point; 11 | 12 | public int getCount() { 13 | return count; 14 | } 15 | 16 | public void setCount(int count) { 17 | this.count = count; 18 | } 19 | 20 | public int getRatio() { 21 | return ratio; 22 | } 23 | 24 | public void setRatio(int ratio) { 25 | this.ratio = ratio; 26 | } 27 | 28 | public int getReview_point() { 29 | return review_point; 30 | } 31 | 32 | public void setReview_point(int review_point) { 33 | this.review_point = review_point; 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/LanguageEdition.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-07-19 14:35 9 | */ 10 | @JsonIgnoreProperties(ignoreUnknown = true) 11 | public class LanguageEdition { 12 | private String label; 13 | private String workno; 14 | private String edition_type; 15 | private Integer display_order; 16 | private Integer edition_idedition_id; 17 | 18 | public String getLabel() { 19 | return label; 20 | } 21 | 22 | public void setLabel(String label) { 23 | this.label = label; 24 | } 25 | 26 | public String getWorkno() { 27 | return workno; 28 | } 29 | 30 | public void setWorkno(String workno) { 31 | this.workno = workno; 32 | } 33 | 34 | public String getEdition_type() { 35 | return edition_type; 36 | } 37 | 38 | public void setEdition_type(String edition_type) { 39 | this.edition_type = edition_type; 40 | } 41 | 42 | public Integer getDisplay_order() { 43 | return display_order; 44 | } 45 | 46 | public void setDisplay_order(Integer display_order) { 47 | this.display_order = display_order; 48 | } 49 | 50 | public Integer getEdition_idedition_id() { 51 | return edition_idedition_id; 52 | } 53 | 54 | public void setEdition_idedition_id(Integer edition_idedition_id) { 55 | this.edition_idedition_id = edition_idedition_id; 56 | } 57 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/LanguageEditionDeserialize.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model; 2 | 3 | import com.fasterxml.jackson.core.*; 4 | import com.fasterxml.jackson.core.type.TypeReference; 5 | import com.fasterxml.jackson.databind.DeserializationContext; 6 | import com.fasterxml.jackson.databind.JsonDeserializer; 7 | 8 | import java.io.IOException; 9 | import java.util.*; 10 | 11 | /** 12 | * @description: 过于离谱,这LanguageEdition居然还有小伎俩,偶尔传个map类型过来。小样,你以为穿个马甲我就解析不了你了。 13 | * @author: Leck 14 | * @create: 2023-08-13 10:47 15 | */ 16 | public class LanguageEditionDeserialize extends JsonDeserializer> { 17 | @Override 18 | public List deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { 19 | List list; 20 | try { 21 | list=jsonParser.readValueAs(new TypeReference>(){}); 22 | }catch (JsonProcessingException e){ 23 | Map map = jsonParser.readValueAs(new TypeReference>() { 24 | }); 25 | list=map.values().stream().toList(); 26 | } 27 | return list; 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/MainWorks.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-07-12 19:37 9 | */ 10 | 11 | public class MainWorks { 12 | private Pagination pagination; 13 | private List works; 14 | 15 | public Pagination getPagination() { 16 | return pagination; 17 | } 18 | 19 | public void setPagination(Pagination pagination) { 20 | this.pagination = pagination; 21 | } 22 | 23 | public List getWorks() { 24 | return works; 25 | } 26 | 27 | public void setWorks(List works) { 28 | this.works = works; 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/Message.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model;/** 2 | *@description: 3 | *@author: Leck 4 | *@create: 2023-07-19 04:58 5 | */ 6 | public class Message { 7 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/Pagination.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonAlias; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-07-12 19:37 9 | */ 10 | public class Pagination { 11 | @JsonAlias("page") 12 | private int currentPage; 13 | private int pageSize; 14 | private long totalCount; 15 | 16 | public int getCurrentPage() { 17 | return currentPage; 18 | } 19 | 20 | public void setCurrentPage(int currentPage) { 21 | this.currentPage = currentPage; 22 | } 23 | 24 | public int getPageSize() { 25 | return pageSize; 26 | } 27 | 28 | public void setPageSize(int pageSize) { 29 | this.pageSize = pageSize; 30 | } 31 | 32 | public long getTotalCount() { 33 | return totalCount; 34 | } 35 | 36 | public void setTotalCount(long totalCount) { 37 | this.totalCount = totalCount; 38 | } 39 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/Rank.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model; 2 | 3 | /** 4 | * @description: 5 | * @author: Leck 6 | * @create: 2023-07-12 19:31 7 | */ 8 | public class Rank { 9 | private String term; 10 | private String rank_date; 11 | private int rank; 12 | private String category; 13 | 14 | public String getTerm() { 15 | return term; 16 | } 17 | 18 | public void setTerm(String term) { 19 | this.term = term; 20 | } 21 | 22 | public String getRank_date() { 23 | return rank_date; 24 | } 25 | 26 | public void setRank_date(String rank_date) { 27 | this.rank_date = rank_date; 28 | } 29 | 30 | public int getRank() { 31 | return rank; 32 | } 33 | 34 | public void setRank(int rank) { 35 | this.rank = rank; 36 | } 37 | 38 | public String getCategory() { 39 | return category; 40 | } 41 | 42 | public void setCategory(String category) { 43 | this.category = category; 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/Response.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model; 2 | 3 | /** 4 | * @description: 5 | * @author: Leck 6 | * @create: 2023-07-15 22:49 7 | */ 8 | public class Response { 9 | private int code; 10 | private String message; 11 | private Object content; 12 | 13 | public Response() { 14 | } 15 | 16 | public Response(int code,String message) { 17 | this.code = code; 18 | this.message = message; 19 | } 20 | public Response(int code, String message, Object content) { 21 | this.code = code; 22 | this.message = message; 23 | this.content = content; 24 | } 25 | 26 | public boolean isSuccess(){ 27 | return code == 200; 28 | } 29 | 30 | public int getCode() { 31 | return code; 32 | } 33 | 34 | public void setCode(int code) { 35 | this.code = code; 36 | } 37 | 38 | public String getMessage() { 39 | return message; 40 | } 41 | 42 | public void setMessage(String message) { 43 | this.message = message; 44 | } 45 | 46 | public Object getContent() { 47 | return content; 48 | } 49 | 50 | public void setContent(Object content) { 51 | this.content = content; 52 | } 53 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/ResponseBody.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | public class ResponseBody { 7 | private Integer code; //code可以随意设置,但成功必须是200 8 | private String msg; 9 | private T data; 10 | 11 | public ResponseBody() { 12 | } 13 | 14 | public ResponseBody(Integer code, String msg) { 15 | this.code = code; 16 | this.msg = msg; 17 | } 18 | 19 | public ResponseBody(Integer code, String msg, Boolean success) { 20 | this.code = code; 21 | this.msg = msg; 22 | } 23 | 24 | public static ResponseBody create(Integer code, String msg, T t) { 25 | ResponseBody responseBody = new ResponseBody<>(); 26 | responseBody.setCode(code); 27 | responseBody.setMsg(msg); 28 | responseBody.setData(t); 29 | return responseBody; 30 | } 31 | 32 | public boolean isSuccess() { 33 | return code == 200; 34 | } 35 | 36 | public Integer getCode() { 37 | return code; 38 | } 39 | 40 | public void setCode(Integer code) { 41 | this.code = code; 42 | } 43 | 44 | public String getMsg() { 45 | return msg; 46 | } 47 | 48 | public void setMsg(String msg) { 49 | this.msg = msg; 50 | } 51 | 52 | public T getData() { 53 | return data; 54 | } 55 | 56 | public void setData(T data) { 57 | this.data = data; 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/Role.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-07-12 03:24 9 | */ 10 | @JsonIgnoreProperties(ignoreUnknown = true) 11 | public class Role { 12 | private String id; 13 | private String name; 14 | 15 | public String getId() { 16 | return id; 17 | } 18 | 19 | public void setId(String id) { 20 | this.id = id; 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public void setName(String name) { 28 | this.name = name; 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/RoleEx.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-07-13 06:58 9 | */ 10 | @JsonIgnoreProperties(ignoreUnknown = true) 11 | public class RoleEx extends Role{ 12 | private Integer count; 13 | 14 | public Integer getCount() { 15 | return count; 16 | } 17 | 18 | public void setCount(Integer count) { 19 | this.count = count; 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/SearchKey.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model; 2 | 3 | /** 4 | * @description: 5 | * @author: Leck 6 | * @create: 2023-07-12 19:40 7 | */ 8 | public class SearchKey { 9 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/SortType.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model; 2 | 3 | /** 4 | * @description: 5 | * @author: Leck 6 | * @create: 2023-07-13 03:35 7 | */ 8 | public enum SortType { 9 | release("发售时间"), 10 | create_date("收录"), 11 | 12 | rate_average_2dp("评分"), 13 | dl_count("销量"), 14 | price("价格"), 15 | nsfw("全年龄"), 16 | review_count("评论数量"), 17 | random("随机"); 18 | 19 | private String value; 20 | 21 | SortType(String value) { 22 | this.value=value; 23 | } 24 | 25 | 26 | public String getValue() { 27 | return value; 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/Track.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonInclude; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @description: 10 | * @author: Leck 11 | * @create: 2023-07-13 21:07 12 | */ 13 | @JsonInclude(JsonInclude.Include.NON_NULL) 14 | @JsonIgnoreProperties(ignoreUnknown = true) 15 | public class Track { 16 | private String title; 17 | private String type; 18 | private String workTitle; 19 | 20 | private double duration; 21 | 22 | private String hash; 23 | private String mediaDownloadUrl; 24 | private String mediaStreamUrl; 25 | private String streamLowQualityUrl; 26 | private List children; 27 | private String path; 28 | 29 | public String getTitle() { 30 | return title; 31 | } 32 | 33 | public void setTitle(String title) { 34 | this.title = title; 35 | } 36 | 37 | public String getType() { 38 | return type; 39 | } 40 | 41 | public void setType(String type) { 42 | this.type = type; 43 | } 44 | 45 | public String getWorkTitle() { 46 | return workTitle; 47 | } 48 | 49 | public void setWorkTitle(String workTitle) { 50 | this.workTitle = workTitle; 51 | } 52 | 53 | public double getDuration() { 54 | return duration; 55 | } 56 | 57 | public void setDuration(double duration) { 58 | this.duration = duration; 59 | } 60 | 61 | public String getHash() { 62 | return hash; 63 | } 64 | 65 | public void setHash(String hash) { 66 | this.hash = hash; 67 | } 68 | 69 | public String getMediaDownloadUrl() { 70 | return mediaDownloadUrl; 71 | } 72 | 73 | public void setMediaDownloadUrl(String mediaDownloadUrl) { 74 | this.mediaDownloadUrl = mediaDownloadUrl; 75 | } 76 | 77 | public String getMediaStreamUrl() { 78 | return mediaStreamUrl; 79 | } 80 | 81 | public void setMediaStreamUrl(String mediaStreamUrl) { 82 | this.mediaStreamUrl = mediaStreamUrl; 83 | } 84 | 85 | public String getStreamLowQualityUrl() { 86 | return streamLowQualityUrl; 87 | } 88 | 89 | public void setStreamLowQualityUrl(String streamLowQualityUrl) { 90 | this.streamLowQualityUrl = streamLowQualityUrl; 91 | } 92 | 93 | public List getChildren() { 94 | return children; 95 | } 96 | 97 | public void setChildren(List children) { 98 | this.children = children; 99 | } 100 | 101 | public String getPath() { 102 | return path; 103 | } 104 | 105 | public void setPath(String path) { 106 | this.path = path; 107 | } 108 | 109 | public boolean isFolder(){ 110 | return type.equals("folder"); 111 | } 112 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/User.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-07-19 09:24 9 | */ 10 | @JsonIgnoreProperties(ignoreUnknown = true) 11 | public class User { 12 | private String name; 13 | private String group; 14 | private boolean loggedIn; 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | public void setName(String name) { 21 | this.name = name; 22 | } 23 | 24 | public String getGroup() { 25 | return group; 26 | } 27 | 28 | public void setGroup(String group) { 29 | this.group = group; 30 | } 31 | 32 | public boolean isLoggedIn() { 33 | return loggedIn; 34 | } 35 | 36 | public void setLoggedIn(boolean loggedIn) { 37 | this.loggedIn = loggedIn; 38 | } 39 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/playList/MainPlayList.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model.playList; 2 | 3 | import cn.tealc995.kikoreu.model.Pagination; 4 | import com.fasterxml.jackson.annotation.JsonAlias; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @description: 10 | * @author: Leck 11 | * @create: 2023-08-02 08:17 12 | */ 13 | public class MainPlayList { 14 | private Pagination pagination; 15 | @JsonAlias("playlists") 16 | private List playLists; 17 | 18 | public Pagination getPagination() { 19 | return pagination; 20 | } 21 | 22 | public void setPagination(Pagination pagination) { 23 | this.pagination = pagination; 24 | } 25 | 26 | public List getPlayLists() { 27 | return playLists; 28 | } 29 | 30 | public void setPlayLists(List playLists) { 31 | this.playLists = playLists; 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/playList/PlayList.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model.playList; 2 | 3 | import com.fasterxml.jackson.annotation.JsonAlias; 4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 5 | 6 | /** 7 | * @description: 8 | * @author: Leck 9 | * @create: 2023-08-02 08:09 10 | */ 11 | @JsonIgnoreProperties(ignoreUnknown = true) 12 | public class PlayList { 13 | private String id; 14 | private String name; 15 | private String description; 16 | 17 | @JsonAlias("user_name") 18 | private String username; 19 | private String mainCoverUrl; 20 | 21 | private Integer privacy; 22 | @JsonAlias("updated_at") 23 | private String updatedTime; 24 | @JsonAlias("created_at") 25 | private String createdTime; 26 | @JsonAlias("works_count") 27 | private Integer worksCount; 28 | 29 | private Boolean exist; 30 | 31 | public String getId() { 32 | return id; 33 | } 34 | 35 | public void setId(String id) { 36 | this.id = id; 37 | } 38 | 39 | public String getName() { 40 | if (name.equals("__SYS_PLAYLIST_LIKED")) 41 | return "我喜欢的"; 42 | else if (name.equals("__SYS_PLAYLIST_MARKED")) { 43 | return "我标记的"; 44 | }else 45 | return name; 46 | } 47 | 48 | public boolean canDelete() { 49 | return name.equals("__SYS_PLAYLIST_LIKED") || name.equals("__SYS_PLAYLIST_MARKED"); 50 | } 51 | 52 | public void setName(String name) { 53 | this.name = name; 54 | } 55 | 56 | public String getDescription() { 57 | return description; 58 | } 59 | 60 | public void setDescription(String description) { 61 | this.description = description; 62 | } 63 | 64 | public String getUsername() { 65 | return username; 66 | } 67 | 68 | public void setUsername(String username) { 69 | this.username = username; 70 | } 71 | 72 | public String getMainCoverUrl() { 73 | return mainCoverUrl; 74 | } 75 | 76 | public void setMainCoverUrl(String mainCoverUrl) { 77 | this.mainCoverUrl = mainCoverUrl; 78 | } 79 | 80 | public Integer getPrivacy() { 81 | return privacy; 82 | } 83 | 84 | public void setPrivacy(Integer privacy) { 85 | this.privacy = privacy; 86 | } 87 | 88 | public String getUpdatedTime() { 89 | return updatedTime; 90 | } 91 | 92 | public void setUpdatedTime(String updatedTime) { 93 | this.updatedTime = updatedTime; 94 | } 95 | 96 | public String getCreatedTime() { 97 | return createdTime; 98 | } 99 | 100 | public void setCreatedTime(String createdTime) { 101 | this.createdTime = createdTime; 102 | } 103 | 104 | public Integer getWorksCount() { 105 | return worksCount; 106 | } 107 | 108 | public void setWorksCount(Integer worksCount) { 109 | this.worksCount = worksCount; 110 | } 111 | 112 | public Boolean getExist() { 113 | return exist; 114 | } 115 | 116 | public void setExist(Boolean exist) { 117 | this.exist = exist; 118 | } 119 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/playList/PlayListAlter.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model.playList; 2 | 3 | /** 4 | * @description: 5 | * @author: Leck 6 | * @create: 2023-08-08 06:07 7 | */ 8 | public class PlayListAlter { 9 | private String id; 10 | private PlayListBase data; 11 | 12 | public PlayListAlter(String id, PlayListBase data) { 13 | this.id = id; 14 | this.data = data; 15 | } 16 | 17 | public String getId() { 18 | return id; 19 | } 20 | 21 | public void setId(String id) { 22 | this.id = id; 23 | } 24 | 25 | public PlayListBase getData() { 26 | return data; 27 | } 28 | 29 | public void setData(PlayListBase date) { 30 | this.data = date; 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/playList/PlayListBase.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model.playList; 2 | 3 | /** 4 | * @description: PlayList基础类 5 | * @author: Leck 6 | * @create: 2023-08-08 06:06 7 | */ 8 | public class PlayListBase { 9 | private String name; 10 | private Integer privacy; 11 | private String description; 12 | 13 | public PlayListBase(String name, Integer privacy, String description) { 14 | this.name = name; 15 | this.privacy = privacy; 16 | this.description = description; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public void setName(String name) { 24 | this.name = name; 25 | } 26 | 27 | public Integer getPrivacy() { 28 | return privacy; 29 | } 30 | 31 | public void setPrivacy(Integer privacy) { 32 | this.privacy = privacy; 33 | } 34 | 35 | public String getDescription() { 36 | return description; 37 | } 38 | 39 | public void setDescription(String description) { 40 | this.description = description; 41 | } 42 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/playList/PlayListCreate.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model.playList; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.regex.Matcher; 6 | import java.util.regex.Pattern; 7 | 8 | /** 9 | * @description: 创建歌单时的参数类 10 | * @author: Leck 11 | * @create: 2023-08-05 09:24 12 | */ 13 | public class PlayListCreate { 14 | private String name; 15 | private Integer privacy; 16 | private String locale; 17 | private String description; 18 | private List works; 19 | 20 | public PlayListCreate() { 21 | } 22 | 23 | public PlayListCreate(String name, Integer privacy, String description, List works) { 24 | this.name = name; 25 | this.privacy = privacy; 26 | this.locale = "zh-CN"; 27 | this.description = description; 28 | this.works = works; 29 | } 30 | 31 | public PlayListCreate(String name, Integer privacy, String description, String worksRow) { 32 | this.name = name; 33 | this.privacy = privacy; 34 | this.locale = "zh-CN"; 35 | this.description = description; 36 | this.works=new ArrayList<>(); 37 | worksRow=worksRow.toUpperCase(); 38 | Pattern pattern=Pattern.compile("(?<=RJ)\\d+"); 39 | Matcher matcher = pattern.matcher(worksRow); 40 | while (matcher.find()){ 41 | 42 | works.add(matcher.group()); 43 | } 44 | 45 | } 46 | 47 | 48 | public String getName() { 49 | return name; 50 | } 51 | 52 | public void setName(String name) { 53 | this.name = name; 54 | } 55 | 56 | public Integer getPrivacy() { 57 | return privacy; 58 | } 59 | 60 | public void setPrivacy(Integer privacy) { 61 | this.privacy = privacy; 62 | } 63 | 64 | public String getLocale() { 65 | return locale; 66 | } 67 | 68 | public void setLocale(String locale) { 69 | this.locale = locale; 70 | } 71 | 72 | public String getDescription() { 73 | return description; 74 | } 75 | 76 | public void setDescription(String description) { 77 | this.description = description; 78 | } 79 | 80 | public List getWorks() { 81 | return works; 82 | } 83 | 84 | public void setWorks(List works) { 85 | this.works = works; 86 | } 87 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kikoreu/model/playList/PlayListRemoveWork.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kikoreu.model.playList; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @description: 9 | * @author: Leck 10 | * @create: 2023-08-05 09:24 11 | */ 12 | public class PlayListRemoveWork { 13 | private String id; 14 | private List works; 15 | 16 | @JsonIgnore 17 | private Boolean remove; 18 | public PlayListRemoveWork(String id, List works,Boolean remove) { 19 | this.id = id; 20 | this.works = works; 21 | this.remove=remove; 22 | } 23 | 24 | public String getId() { 25 | return id; 26 | } 27 | 28 | public void setId(String id) { 29 | this.id = id; 30 | } 31 | 32 | public List getWorks() { 33 | return works; 34 | } 35 | 36 | public void setWorks(List works) { 37 | this.works = works; 38 | } 39 | 40 | public Boolean getRemove() { 41 | return remove; 42 | } 43 | 44 | public void setRemove(Boolean remove) { 45 | this.remove = remove; 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/App.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid; 2 | 3 | import atlantafx.base.theme.PrimerDark; 4 | import cn.tealc995.kkmaid.config.Config; 5 | import cn.tealc995.kkmaid.player.MediaPlayerUtil; 6 | import cn.tealc995.kkmaid.ui.MainUI; 7 | import cn.tealc995.kkmaid.util.CssLoader; 8 | 9 | import cn.tealc995.teaFX.stage.RoundStage; 10 | import javafx.application.Application; 11 | import javafx.application.Platform; 12 | import javafx.scene.image.Image; 13 | import javafx.scene.paint.Color; 14 | import javafx.stage.Stage; 15 | import javafx.stage.StageStyle; 16 | 17 | import java.io.IOException; 18 | import java.util.Timer; 19 | import java.util.TimerTask; 20 | 21 | public class App extends Application { 22 | public static RoundStage mainStage; 23 | @Override 24 | public void start(Stage stage) throws IOException { 25 | Timer timer=new Timer(true); 26 | timer.schedule(new TimerTask() { 27 | @Override 28 | public void run() { 29 | System.gc(); 30 | } 31 | },60000,60000); 32 | stage.close(); 33 | mainStage=new RoundStage(); 34 | 35 | if (Config.setting.isProxyModel()){ 36 | System.setProperty("https.proxyHost", Config.setting.getProxyHost()); 37 | System.setProperty("https.proxyPort", Config.setting.getProxyPort()); 38 | } 39 | 40 | Application.setUserAgentStylesheet(new PrimerDark().getUserAgentStylesheet()); 41 | MainUI mainUI=new MainUI(); 42 | 43 | mainStage.setOnHidden(windowEvent -> { 44 | Platform.exit(); 45 | }); 46 | 47 | mainStage.setContent(mainUI.getRoot()); 48 | mainStage.getScene().getStylesheets().addAll(CssLoader.getCss(CssLoader.baseUI),CssLoader.getCss(CssLoader.main)); 49 | mainStage.getScene().setFill(Color.TRANSPARENT); 50 | mainStage.setWidth(Config.setting.getStageWidth()); 51 | mainStage.setHeight(Config.setting.getStageHeight()); 52 | mainStage.setFullScreenExitHint(""); 53 | mainStage.initStyle(StageStyle.TRANSPARENT); 54 | 55 | mainStage.setTitle("KK Maid"); 56 | mainStage.getIcons().add(new Image(getClass().getResource("/cn/tealc995/kkmaid/image/icon.png").toExternalForm())); 57 | mainStage.show(); 58 | } 59 | 60 | 61 | @Override 62 | public void stop() throws Exception { 63 | super.stop(); 64 | MediaPlayerUtil.mediaPlayer().release(); 65 | Config.saveProperties(); 66 | } 67 | 68 | public static void main(String[] args) { 69 | launch(); 70 | } 71 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/AppStart.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid; 2 | 3 | import javafx.application.Application; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-07-16 05:06 9 | */ 10 | public class AppStart { 11 | public static void main(String[] args) { 12 | Application.launch(App.class,args); 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/config/BlackList.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.config; 2 | 3 | import javafx.collections.FXCollections; 4 | import javafx.collections.ObservableSet; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | /** 9 | * @program: KK-Maid 10 | * @description: 黑名单 11 | * @author: Leck 12 | * @create: 2025-02-03 23:13 13 | */ 14 | public class BlackList { 15 | private static final Logger LOG = LoggerFactory.getLogger(BlackList.class); 16 | private ObservableSet workBlackList= FXCollections.observableSet(); 17 | private ObservableSet tagBlackList= FXCollections.observableSet(); 18 | private ObservableSet textBlackList= FXCollections.observableSet(); 19 | 20 | public ObservableSet getWorkBlackList() { 21 | return workBlackList; 22 | } 23 | 24 | public void setWorkBlackList(ObservableSet workBlackList) { 25 | this.workBlackList = workBlackList; 26 | } 27 | 28 | public ObservableSet getTagBlackList() { 29 | return tagBlackList; 30 | } 31 | 32 | public void setTagBlackList(ObservableSet tagBlackList) { 33 | this.tagBlackList = tagBlackList; 34 | } 35 | 36 | public ObservableSet getTextBlackList() { 37 | return textBlackList; 38 | } 39 | 40 | public void setTextBlackList(ObservableSet textBlackList) { 41 | this.textBlackList = textBlackList; 42 | } 43 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/event/BlackWorkEvent.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.event; 2 | 3 | import cn.tealc995.kikoreu.model.Work; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-08-08 10:13 9 | */ 10 | public class BlackWorkEvent { 11 | private Work work; 12 | 13 | public BlackWorkEvent(Work work) { 14 | this.work = work; 15 | } 16 | 17 | public Work getWork() { 18 | return work; 19 | } 20 | 21 | public void setWork(Work work) { 22 | this.work = work; 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/event/EventBusUtil.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.event; 2 | 3 | import org.greenrobot.eventbus.EventBus; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-07-13 08:56 9 | */ 10 | public class EventBusUtil { 11 | private static EventBus eventBus=new EventBus(); 12 | public static EventBus getDefault(){ 13 | return eventBus; 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/event/GridItemRemoveEvent.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.event; 2 | 3 | import cn.tealc995.kikoreu.model.Work; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-07-15 02:42 9 | */ 10 | public class GridItemRemoveEvent { 11 | private Work work; 12 | 13 | public GridItemRemoveEvent(Work work) { 14 | this.work = work; 15 | } 16 | 17 | public Work getWork() { 18 | return work; 19 | } 20 | 21 | public void setWork(Work work) { 22 | this.work = work; 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/event/MainCenterEvent.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.event; 2 | 3 | import javafx.scene.layout.Pane; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-07-13 08:58 9 | */ 10 | public class MainCenterEvent { 11 | private Pane pane; 12 | private boolean add; 13 | private boolean toBase;//返回到最底层的root,当为添加时不生效 14 | 15 | public MainCenterEvent(Pane pane, boolean add,boolean toBase) { 16 | this.pane = pane; 17 | this.add = add; 18 | this.toBase=toBase; 19 | } 20 | 21 | 22 | public Pane getPane() { 23 | return pane; 24 | } 25 | 26 | public void setPane(Pane pane) { 27 | this.pane = pane; 28 | } 29 | 30 | public boolean isAdd() { 31 | return add; 32 | } 33 | 34 | public void setAdd(boolean add) { 35 | this.add = add; 36 | } 37 | 38 | public boolean isToBase() { 39 | return toBase; 40 | } 41 | 42 | public void setToBase(boolean toBase) { 43 | this.toBase = toBase; 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/event/MainDialogEvent.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.event; 2 | 3 | import javafx.scene.layout.Pane; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-07-13 08:58 9 | */ 10 | public class MainDialogEvent { 11 | private Pane pane; 12 | 13 | public MainDialogEvent(Pane pane) { 14 | this.pane = pane; 15 | } 16 | 17 | public Pane getPane() { 18 | return pane; 19 | } 20 | 21 | public void setPane(Pane pane) { 22 | this.pane = pane; 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/event/MainNotificationEvent.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.event; 2 | 3 | /** 4 | * @description: 5 | * @author: Leck 6 | * @create: 2023-07-19 05:54 7 | */ 8 | public class MainNotificationEvent { 9 | private String message; 10 | 11 | public MainNotificationEvent(String message) { 12 | this.message = message; 13 | } 14 | 15 | public String getMessage() { 16 | return message; 17 | } 18 | 19 | public void setMessage(String message) { 20 | this.message = message; 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/event/MainPaneEvent.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.event; 2 | 3 | import javafx.scene.layout.Pane; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-07-13 08:58 9 | */ 10 | public class MainPaneEvent { 11 | private Pane pane; 12 | private boolean add; 13 | 14 | public MainPaneEvent(Pane pane, boolean add) { 15 | this.pane = pane; 16 | this.add = add; 17 | } 18 | 19 | public Pane getPane() { 20 | return pane; 21 | } 22 | 23 | public void setPane(Pane pane) { 24 | this.pane = pane; 25 | } 26 | 27 | public boolean isAdd() { 28 | return add; 29 | } 30 | 31 | public void setAdd(boolean add) { 32 | this.add = add; 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/event/MainPlayListRemoveWorkEvent.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.event; 2 | 3 | import cn.tealc995.kikoreu.model.Work; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-08-05 09:39 9 | */ 10 | public class MainPlayListRemoveWorkEvent { 11 | private Work work; 12 | 13 | public MainPlayListRemoveWorkEvent(Work work) { 14 | this.work = work; 15 | } 16 | 17 | public Work getWork() { 18 | return work; 19 | } 20 | 21 | public void setWork(Work work) { 22 | this.work = work; 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/event/PlayListAlterEvent.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.event; 2 | 3 | import cn.tealc995.kikoreu.model.playList.PlayList; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-08-07 04:20 9 | */ 10 | public class PlayListAlterEvent { 11 | private PlayList playList; 12 | 13 | public PlayListAlterEvent(PlayList playList) { 14 | this.playList = playList; 15 | } 16 | 17 | public PlayList getPlayList() { 18 | return playList; 19 | } 20 | 21 | public void setPlayList(PlayList playList) { 22 | this.playList = playList; 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/event/PlayListRemoveEvent.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.event; 2 | 3 | import cn.tealc995.kikoreu.model.playList.PlayList; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-08-07 04:20 9 | */ 10 | public class PlayListRemoveEvent { 11 | private PlayList playList; 12 | 13 | public PlayListRemoveEvent(PlayList playList) { 14 | this.playList = playList; 15 | } 16 | 17 | public PlayList getPlayList() { 18 | return playList; 19 | } 20 | 21 | public void setPlayList(PlayList playList) { 22 | this.playList = playList; 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/event/SearchEvent.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.event; 2 | 3 | import cn.tealc995.kkmaid.ui.CategoryType; 4 | 5 | /** 6 | * @description: 7 | * @author: Leck 8 | * @create: 2023-07-14 21:02 9 | */ 10 | public class SearchEvent { 11 | private String key; 12 | private String info;//备用 13 | private CategoryType type; 14 | 15 | public SearchEvent(String key) { 16 | this.key = key; 17 | } 18 | 19 | public SearchEvent(CategoryType type,String key) { 20 | this.key = key; 21 | this.type = type; 22 | } 23 | 24 | public SearchEvent(CategoryType type,String key, String info) { 25 | this.key = key; 26 | this.info = info; 27 | this.type = type; 28 | } 29 | 30 | public String getKey() { 31 | return key; 32 | } 33 | 34 | public void setKey(String key) { 35 | this.key = key; 36 | } 37 | 38 | public CategoryType getType() { 39 | return type; 40 | } 41 | 42 | public void setType(CategoryType type) { 43 | this.type = type; 44 | } 45 | 46 | public String getInfo() { 47 | return info; 48 | } 49 | 50 | public void setInfo(String info) { 51 | this.info = info; 52 | } 53 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/filter/AudioFilter.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.filter; 2 | 3 | 4 | import java.io.File; 5 | import java.io.FilenameFilter; 6 | 7 | /** 8 | * @description: 9 | * @author: Leck 10 | * @create: 2023-01-13 19:15 11 | */ 12 | public class AudioFilter implements FilenameFilter { 13 | @Override 14 | public boolean accept(File dir, String name) { 15 | int i = name.lastIndexOf("."); 16 | String ext = i == -1 ? "" : name.substring(i + 1).toUpperCase(); 17 | return SupportAudioFormat.contains(ext); 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/filter/BackgroundImageFilter.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.filter; 2 | 3 | import java.io.File; 4 | import java.io.FilenameFilter; 5 | 6 | /** 7 | * @description: 目录过滤,所有非目录过滤掉 8 | * @author: Leck 9 | * @create: 2023-01-09 17:59 10 | */ 11 | public class BackgroundImageFilter implements FilenameFilter { 12 | 13 | @Override 14 | public boolean accept(File dir, String name) { 15 | if (name.contains("background") && SupportImageFormat.contains(name.toUpperCase().substring(name.lastIndexOf(".") + 1))) { 16 | return true; 17 | } 18 | return false; 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/filter/DirectoryFilter.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.filter; 2 | 3 | import java.io.File; 4 | import java.io.FileFilter; 5 | 6 | /** 7 | * @description: 目录过滤,所有非目录过滤掉 8 | * @author: Leck 9 | * @create: 2023-01-09 17:59 10 | */ 11 | public class DirectoryFilter implements FileFilter { 12 | @Override 13 | public boolean accept(File pathname) { 14 | if (pathname.isDirectory()) 15 | return true; 16 | else 17 | return false; 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/filter/ImageFilter.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.filter; 2 | 3 | 4 | import java.io.File; 5 | import java.io.FilenameFilter; 6 | 7 | /** 8 | * @description: 9 | * @author: Leck 10 | * @create: 2023-01-13 19:15 11 | */ 12 | public class ImageFilter implements FilenameFilter { 13 | @Override 14 | public boolean accept(File dir, String name) { 15 | int i = name.lastIndexOf("."); 16 | String ext = i == -1 ? "" : name.substring(i + 1).toUpperCase(); 17 | return SupportImageFormat.contains(ext); 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/filter/LrcFilter.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.filter; 2 | 3 | 4 | import java.io.File; 5 | import java.io.FilenameFilter; 6 | 7 | /** 8 | * @description: 9 | * @author: Leck 10 | * @create: 2023-01-13 19:15 11 | */ 12 | public class LrcFilter implements FilenameFilter { 13 | @Override 14 | public boolean accept(File dir, String name) { 15 | if (name.endsWith(".lrc") || name.endsWith(".LRC")){ 16 | return true; 17 | } 18 | return false; 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/filter/SupportAudioFormat.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.filter; 2 | 3 | public enum SupportAudioFormat { 4 | OGG("ogg"), 5 | MP3("mp3"), 6 | FLAC("flac"), 7 | M4A("m4a"), 8 | M4P("m4p"), 9 | WMA("wma"), 10 | WAV("wav"), 11 | RA("ra"), 12 | RM("rm"), 13 | M4B("m4b"); 14 | 15 | private String filesuffix; 16 | 17 | private SupportAudioFormat(String filesuffix) { 18 | this.filesuffix = filesuffix; 19 | } 20 | 21 | public String getFilesuffix() { 22 | return this.filesuffix; 23 | } 24 | 25 | 26 | public static boolean contains(String s) 27 | { 28 | s=s.toUpperCase(); 29 | for(SupportAudioFormat choice:values()) 30 | if (choice.name().equals(s)) 31 | return true; 32 | return false; 33 | } 34 | 35 | /** 36 | * @description: 对文件名称进行类型比较 37 | * @name: compareFile 38 | * @author: Leck 39 | * @param: name 40 | * @return boolean 41 | * @date: 2023/9/12 42 | */ 43 | public static boolean compareFile(String name) 44 | { 45 | name = name.toUpperCase().substring(name.lastIndexOf(".") + 1); 46 | for(SupportAudioFormat choice:values()) 47 | if (choice.name().equals(name)) 48 | return true; 49 | return false; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/filter/SupportImageFormat.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.filter; 2 | 3 | /** 4 | * @description: 5 | * @author: Leck 6 | * @create: 2023-01-13 18:02 7 | */ 8 | public enum SupportImageFormat { 9 | JPG("jpg"), 10 | PNG("png"), 11 | JPEG("jpeg"); 12 | 13 | 14 | private String filesuffix; 15 | 16 | private SupportImageFormat(String filesuffix) { 17 | this.filesuffix = filesuffix; 18 | } 19 | 20 | public String getFilesuffix() { 21 | return this.filesuffix; 22 | } 23 | 24 | public static boolean contains(String s) 25 | { 26 | s=s.toUpperCase(); 27 | for(SupportImageFormat choice:values()) 28 | if (choice.name().equals(s)) 29 | return true; 30 | return false; 31 | } 32 | 33 | /** 34 | * @description: 对文件名称进行类型比较 35 | * @name: compareFile 36 | * @author: Leck 37 | * @param: name 38 | * @return boolean 39 | * @date: 2023/9/12 40 | */ 41 | public static boolean compareFile(String name) 42 | { 43 | name = name.toUpperCase().substring(name.lastIndexOf(".") + 1); 44 | for(SupportImageFormat choice:values()) 45 | if (choice.name().equals(name)) 46 | return true; 47 | return false; 48 | } 49 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/filter/SupportSubtitleFormat.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.filter; 2 | 3 | public enum SupportSubtitleFormat { 4 | LRC("lrc"), 5 | VTT("vtt"); 6 | 7 | private String fileSuffix; 8 | 9 | private SupportSubtitleFormat(String filesuffix) { 10 | this.fileSuffix = filesuffix; 11 | } 12 | 13 | public String getFileSuffix() { 14 | return this.fileSuffix; 15 | } 16 | 17 | 18 | /** 19 | * @description: 直接对类型比较 20 | * @name: compareSuffix 21 | * @author: Leck 22 | * @param: suffix 23 | * @return boolean 24 | * @date: 2023/9/12 25 | */ 26 | public static boolean compareSuffix(String suffix) 27 | { 28 | suffix=suffix.toUpperCase(); 29 | for(SupportSubtitleFormat choice:values()) 30 | if (choice.name().equals(suffix)) 31 | return true; 32 | return false; 33 | } 34 | 35 | /** 36 | * @description: 对文件名称进行类型比较 37 | * @name: compareFile 38 | * @author: Leck 39 | * @param: name 40 | * @return boolean 41 | * @date: 2023/9/12 42 | */ 43 | public static boolean compareFile(String name) 44 | { 45 | name = name.toUpperCase().substring(name.lastIndexOf(".") + 1); 46 | for(SupportSubtitleFormat choice:values()) 47 | if (choice.name().equals(name)) 48 | return true; 49 | return false; 50 | } 51 | 52 | 53 | public static SupportSubtitleFormat getType(String name) 54 | { 55 | name = name.toUpperCase().substring(name.lastIndexOf(".") + 1); 56 | for(SupportSubtitleFormat choice:values()) 57 | if (choice.name().equals(name)) 58 | return choice; 59 | return null; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/filter/SupportVideoFormat.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.filter; 2 | 3 | public enum SupportVideoFormat { 4 | MP4("mp4"), 5 | MKV("mkv"), 6 | AVI("avi"); 7 | 8 | 9 | private String filesuffix; 10 | 11 | private SupportVideoFormat(String filesuffix) { 12 | this.filesuffix = filesuffix; 13 | } 14 | 15 | public String getFilesuffix() { 16 | return this.filesuffix; 17 | } 18 | 19 | public static boolean contains(String s) 20 | { 21 | for(SupportVideoFormat choice:values()) 22 | if (choice.name().equals(s)) 23 | return true; 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/model/Audio.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.model; 2 | 3 | /** 4 | * @description: 5 | * @author: Leck 6 | * @create: 2023-07-14 00:08 7 | */ 8 | public class Audio { 9 | private String title; 10 | private String downloadUrl; 11 | private String streamUrl; 12 | private String streamLowQualityUrl; 13 | private double duration; 14 | 15 | 16 | public Audio() { 17 | } 18 | 19 | public Audio(String title, String downloadUrl) { 20 | this.title = title; 21 | this.downloadUrl = downloadUrl; 22 | } 23 | 24 | public Audio(String title, String downloadUrl, String streamUrl, String streamLowQualityUrl, double duration) { 25 | this.title = title; 26 | this.downloadUrl = downloadUrl; 27 | this.streamUrl = streamUrl; 28 | this.streamLowQualityUrl = streamLowQualityUrl; 29 | this.duration = duration; 30 | } 31 | 32 | public String getTitleWithoutSuffix() { 33 | int index=title.lastIndexOf("."); 34 | if (index != -1) 35 | return title.substring(0,index); 36 | else 37 | return title; 38 | } 39 | 40 | public String getTitle() { 41 | return title; 42 | } 43 | 44 | public void setTitle(String title) { 45 | this.title = title; 46 | } 47 | 48 | public String getDownloadUrl() { 49 | return downloadUrl; 50 | } 51 | 52 | public void setDownloadUrl(String downloadUrl) { 53 | this.downloadUrl = downloadUrl; 54 | } 55 | 56 | public String getStreamUrl() { 57 | return streamUrl; 58 | } 59 | 60 | public void setStreamUrl(String streamUrl) { 61 | this.streamUrl = streamUrl; 62 | } 63 | 64 | public String getStreamLowQualityUrl() { 65 | return streamLowQualityUrl; 66 | } 67 | 68 | public void setStreamLowQualityUrl(String streamLowQualityUrl) { 69 | this.streamLowQualityUrl = streamLowQualityUrl; 70 | } 71 | 72 | public double getDuration() { 73 | return duration; 74 | } 75 | 76 | public void setDuration(double duration) { 77 | this.duration = duration; 78 | } 79 | } -------------------------------------------------------------------------------- /src/main/java/cn/tealc995/kkmaid/model/Music.java: -------------------------------------------------------------------------------- 1 | package cn.tealc995.kkmaid.model; 2 | 3 | import cn.tealc995.kikoreu.model.Work; 4 | import cn.tealc995.kkmaid.model.lrc.LrcFile; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @description: 10 | * @author: Leck 11 | * @create: 2023-07-14 00:10 12 | */ 13 | public class Music { 14 | private Work work; 15 | private List