├── .circleci └── config.yml ├── .github ├── CODE_OF_CONDUCT.md ├── ISSUE_TEMPLATE │ ├── bug-report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── maven.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── appveyor.yml ├── pom.xml ├── pom.xml.versionsBackup └── src ├── main ├── java │ ├── com │ │ ├── jagrosh │ │ │ ├── jdautilities │ │ │ │ └── command │ │ │ │ │ ├── Command.java │ │ │ │ │ └── SlashCommand.java │ │ │ └── jmusicbot │ │ │ │ ├── Bot.java │ │ │ │ ├── BotConfig.java │ │ │ │ ├── JMusicBot.java │ │ │ │ ├── Listener.java │ │ │ │ ├── PlayStatus.java │ │ │ │ ├── audio │ │ │ │ ├── AloneInVoiceHandler.java │ │ │ │ ├── AudioHandler.java │ │ │ │ ├── NowplayingHandler.java │ │ │ │ ├── PlayerManager.java │ │ │ │ ├── QueuedTrack.java │ │ │ │ ├── RequestMetadata.java │ │ │ │ └── TransformativeAudioSourceManager.java │ │ │ │ ├── entities │ │ │ │ ├── Pair.java │ │ │ │ └── Prompt.java │ │ │ │ ├── gui │ │ │ │ ├── ConsolePanel.java │ │ │ │ ├── GUI.java │ │ │ │ └── TextAreaOutputStream.java │ │ │ │ ├── playlist │ │ │ │ └── PlaylistLoader.java │ │ │ │ ├── queue │ │ │ │ ├── FairQueue.java │ │ │ │ └── Queueable.java │ │ │ │ ├── settings │ │ │ │ ├── Settings.java │ │ │ │ └── SettingsManager.java │ │ │ │ └── utils │ │ │ │ ├── FormatUtil.java │ │ │ │ └── OtherUtil.java │ │ └── sedmelluq │ │ │ └── discord │ │ │ └── lavaplayer │ │ │ └── source │ │ │ └── nico │ │ │ ├── NicoAudioSourceManager.java │ │ │ ├── NicoAudioTrack.java │ │ │ └── TOTPGenerator.java │ └── dev │ │ └── cosgy │ │ ├── agent │ │ ├── GensokyoInfoAgent.java │ │ └── objects │ │ │ ├── Misc.java │ │ │ ├── ResultSet.java │ │ │ ├── Serverinfo.java │ │ │ ├── Songdata.java │ │ │ ├── Songinfo.java │ │ │ ├── Songtimes.java │ │ │ ├── Streams.java │ │ │ ├── _1.java │ │ │ ├── _2.java │ │ │ ├── _3.java │ │ │ └── _4.java │ │ ├── jmusicbot │ │ ├── playlist │ │ │ ├── CacheLoader.java │ │ │ ├── MylistLoader.java │ │ │ └── PubliclistLoader.java │ │ ├── settings │ │ │ └── RepeatMode.java │ │ ├── slashcommands │ │ │ ├── AdminCommand.java │ │ │ ├── DJCommand.java │ │ │ ├── MusicCommand.java │ │ │ ├── OwnerCommand.java │ │ │ ├── admin │ │ │ │ ├── AutoplaylistCmd.java │ │ │ │ ├── PrefixCmd.java │ │ │ │ ├── SetdjCmd.java │ │ │ │ ├── SettcCmd.java │ │ │ │ ├── SetvcCmd.java │ │ │ │ ├── SetvcStatusCmd.java │ │ │ │ └── SkipratioCmd.java │ │ │ ├── dj │ │ │ │ ├── ForceRemoveCmd.java │ │ │ │ ├── ForceToEnd.kt │ │ │ │ ├── ForceskipCmd.java │ │ │ │ ├── MoveTrackCmd.java │ │ │ │ ├── NextCmd.java │ │ │ │ ├── PauseCmd.java │ │ │ │ ├── PlaynextCmd.java │ │ │ │ ├── RepeatCmd.java │ │ │ │ ├── SkipToCmd.java │ │ │ │ └── StopCmd.java │ │ │ ├── general │ │ │ │ ├── AboutCommand.java │ │ │ │ ├── CashCmd.java │ │ │ │ ├── HelpCmd.java │ │ │ │ ├── InviteCommand.java │ │ │ │ ├── PingCommand.java │ │ │ │ ├── ServerInfo.java │ │ │ │ ├── SettingsCmd.java │ │ │ │ └── UserInfo.java │ │ │ ├── listeners │ │ │ │ └── CommandAudit.java │ │ │ ├── music │ │ │ │ ├── LyricsCmd.java │ │ │ │ ├── MylistCmd.java │ │ │ │ ├── NicoSearchCmd.java │ │ │ │ ├── NowplayingCmd.java │ │ │ │ ├── PlayCmd.java │ │ │ │ ├── PlaylistsCmd.java │ │ │ │ ├── QueueCmd.java │ │ │ │ ├── RemoveCmd.java │ │ │ │ ├── SCSearchCmd.java │ │ │ │ ├── SearchCmd.java │ │ │ │ ├── SeekCmd.java │ │ │ │ ├── ShuffleCmd.java │ │ │ │ ├── SkipCmd.java │ │ │ │ ├── SpotifyCmd.java │ │ │ │ └── VolumeCmd.java │ │ │ └── owner │ │ │ │ ├── DebugCmd.java │ │ │ │ ├── EvalCmd.java │ │ │ │ ├── LeaveCmd.java │ │ │ │ ├── PublistCmd.java │ │ │ │ ├── ServerListCmd.java │ │ │ │ ├── SetavatarCmd.java │ │ │ │ ├── SetgameCmd.java │ │ │ │ ├── SetnameCmd.java │ │ │ │ ├── SetstatusCmd.java │ │ │ │ └── ShutdownCmd.java │ │ └── util │ │ │ ├── Cache.java │ │ │ ├── LastSendTextChannel.java │ │ │ ├── StackTraceUtil.java │ │ │ └── TimeUtil.java │ │ └── niconicoSearchAPI │ │ ├── HTTPUtil.java │ │ ├── Sample.java │ │ ├── nicoSearchAPI.java │ │ ├── nicoVideoInfo.java │ │ └── nicoVideoSearchResult.java └── resources │ ├── logback.xml │ └── reference.conf └── test └── java └── com └── jagrosh └── jmusicbot └── FairQueueTest.java /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Java Maven CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-java/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | docker: 9 | # specify the version you desire here 10 | - image: circleci/openjdk:11.0.3-jdk-stretch-node-browsers-legacy 11 | 12 | # Specify service dependencies here if necessary 13 | # CircleCI maintains a library of pre-built images 14 | # documented at https://circleci.com/docs/2.0/circleci-images/ 15 | # - image: circleci/postgres:9.4 16 | 17 | working_directory: ~/repo 18 | 19 | environment: 20 | # Customize the JVM maximum heap limit 21 | MAVEN_OPTS: -Xmx3200m 22 | 23 | steps: 24 | - checkout 25 | 26 | # Download and cache dependencies 27 | - restore_cache: 28 | keys: 29 | - v1-dependencies-{{ checksum "pom.xml" }} 30 | # fallback to using the latest cache if no exact match is found 31 | - v1-dependencies- 32 | 33 | - run: mvn dependency:go-offline 34 | 35 | - save_cache: 36 | paths: 37 | - ~/.m2 38 | key: v1-dependencies-{{ checksum "pom.xml" }} 39 | 40 | # run tests! 41 | - run: mvn integration-test 42 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making 6 | participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, 7 | disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, 8 | socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. 9 | 10 | ## Our Standards 11 | 12 | Examples of behavior that contributes to creating a positive environment include: 13 | 14 | * Using welcoming and inclusive language 15 | * Being respectful of differing viewpoints and experiences 16 | * Gracefully accepting constructive criticism 17 | * Focusing on what is best for the community 18 | * Showing empathy towards other community members 19 | 20 | Examples of unacceptable behavior by participants include: 21 | 22 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 23 | * Trolling, insulting/derogatory comments, and personal or political attacks 24 | * Public or private harassment 25 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 26 | * Other conduct which could reasonably be considered inappropriate in a professional setting 27 | 28 | ## Our Responsibilities 29 | 30 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take 31 | appropriate and fair corrective action in response to any instances of unacceptable behavior. 32 | 33 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, 34 | issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any 35 | contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 36 | 37 | ## Scope 38 | 39 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the 40 | project or its community. Examples of representing a project or community include using an official project e-mail 41 | address, posting via an official social media account, or acting as an appointed representative at an online or offline 42 | event. Representation of a project may be further defined and clarified by project maintainers. 43 | 44 | ## Enforcement 45 | 46 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at 47 | j@gro.sh. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and 48 | appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter 49 | of an incident. Further details of specific enforcement policies may be posted separately. 50 | 51 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent 52 | repercussions as determined by other members of the project's leadership. 53 | 54 | ## Attribution 55 | 56 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available 57 | at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 58 | 59 | [homepage]: https://www.contributor-covenant.org 60 | 61 | For answers to common questions about this code of conduct, see 62 | https://www.contributor-covenant.org/faq 63 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: バグレポート about: バグや予期しない動作を報告する title: "[バグレポート] タイトルを入力" 3 | labels: '' 4 | assignees: '' 5 | 6 | --- 7 | 8 | **バグを説明する** 9 | どのようなバグであるかの明確かつ簡潔な説明。 10 | 11 | **再現する方法** 12 | 問題の再現手順: 13 | 14 | 1. '...' を実行 15 | 2. '....'コマンドを実行する 16 | 3. その他の方法 '....' 17 | 18 | **予想される動作** 19 | どのような事がが起こるが予想されていたのかについての明確で簡潔な説明。 20 | 21 | **スクリーンショット** 22 | 該当する場合は、問題を説明するためにスクリーンショットを追加してください。 23 | 24 | **バージョン情報(以下の情報を記入してください):** 25 | 26 | - オペレーティングシステム(OS): [例 Windows 64bit] 27 | - ボットバージョン: [例 0.1.0] 28 | 29 | **追加のコンテキスト** 30 | この問題に関する他の文脈をここに追加してください。 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 機能リクエスト about: このプロジェクトにアイデアを提案 title: "[機能要求]タイトルを入力" 3 | labels: '' 4 | assignees: '' 5 | 6 | --- 7 | 8 | **機能リクエストは問題に関連していますか。 記述してください。** 9 | 問題が何であるかの明確で簡潔な説明。 10 | 11 | **この機能を使用するための基本的な流れ/手順を説明する** 12 | この機能の使い方: 13 | 14 | 1. 何かを設定 '...' 15 | 2. コマンドを実行する '...' 16 | 3. その他の手順や関連情報 '...' 17 | 4. ... 18 | 19 | **追加のコンテキスト** 20 | 機能要求に関するその他のコンテキストやスクリーンショットをここに追加してください。 21 | 22 | **あなたはこの考えがまだここで説明されていないことを確認しましたか?** 23 | https://github.com/Cosgy-Dev/JMusicBot-JP/projects/1 24 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### このプルリクエストは... 2 | 3 | - [ ] バグを修正しました。 4 | - [ ] 新機能を追加します 5 | - [ ] 既存の機能を改善 6 | - [ ] コードの品質やパフォーマンスを向上させる 7 | - [ ] 誤訳などの修正をしました。 8 | 9 | ### 説明 10 | 11 | 変更内容などを箇条書きでお願いします。 ここで書かれた変更内容はリリースノートを作成する際に参考にします。 12 | 13 | ### 目的 14 | 15 | ここに問題の説明または活用事例を書いてください。 16 | 17 | ### 関連する問題 18 | 19 | ここには関連する問題を#[issuesの番目] で表示して下さい。 20 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Java CI with Maven 5 | 6 | on: 7 | push: 8 | branches: [ develop ] 9 | pull_request: 10 | branches: [ develop ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | - name: Set up JDK 11 20 | uses: actions/setup-java@v3 21 | with: 22 | java-version: '11' 23 | distribution: 'adopt' 24 | architecture: x64 25 | cache: maven 26 | - name: Build with Maven 27 | run: mvn --batch-mode --update-snapshots verify -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /nbproject/ 2 | /target/ 3 | /Playlists/ 4 | /test/ 5 | *.json 6 | *.txt 7 | nb*.xml 8 | .idea/** 9 | *.iml 10 | config.txt 11 | *.jar 12 | /logs/ 13 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # JMusicBot JP Docker container configuration file 2 | # Maintained by CyberRex (CyberRex0) 3 | 4 | FROM openjdk:11-buster 5 | 6 | # DO NOT EDIT UNDER THIS LINE 7 | RUN mkdir -p /opt/jmusicbot 8 | 9 | WORKDIR /opt/jmusicbot 10 | 11 | RUN \ 12 | echo "JMusicBot-JP Docker Container Builder v1.1\nMaintained by CyberRex (CyberRex0)"; \ 13 | echo "Preconfiguring apt..." & apt-get update > /dev/null; \ 14 | echo "Installing packages..." & apt-get install -y ffmpeg wget curl jq > /dev/null; \ 15 | echo "Downloading latest version of JMusicBot-JP..."; \ 16 | wget $(curl https://api.github.com/repos/Cosgy-Dev/JMusicBot-JP/releases/latest | jq -r '.assets[] | select(.browser_download_url | contains(".jar")) | .browser_download_url') -O /opt/jmusicbot/jmusicbot.jar; \ 17 | echo "cd /opt/jmusicbot && java -Dnogui=true -jar jmusicbot.jar" > /opt/jmusicbot/execute.bash; \ 18 | echo "Build Completed." 19 | 20 | CMD ["bash", "/opt/jmusicbot/execute.bash"] 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ロゴ 2 | 3 | [![Downloads](https://img.shields.io/github/downloads/Cosgy-Dev/MusicBot-JP-java/total.svg)](https://github.com/Cosgy-Dev/MusicBot-JP-java/releases/latest) 4 | [![Stars](https://img.shields.io/github/stars/Cosgy-Dev/MusicBot-JP-java.svg)](https://github.com/Cosgy-Dev/MusicBot-JP-java/stargazers) 5 | [![Release](https://img.shields.io/github/release/Cosgy-Dev/MusicBot-JP-java.svg)](https://github.com/Cosgy-Dev/MusicBot-JP-java/releases/latest) 6 | [![License](https://img.shields.io/github/license/Cosgy-Dev/MusicBot-JP-java.svg)](https://github.com/Cosgy-Dev/MusicBot-JP-java/blob/master/LICENSE) 7 | [![Discord](https://discordapp.com/api/guilds/497317844191805450/widget.png)](https://discord.gg/RBpkHxf) 8 | ![CircleCI](https://img.shields.io/circleci/build/github/Cosgy-Dev/JMusicBot-JP/develop?token=c2ceb77e45cfce45bc8e15161f91d355c54f48b1) 9 | [![CodeFactor](https://www.codefactor.io/repository/github/cosgy-dev/jmusicbot-jp/badge)](https://www.codefactor.io/repository/github/cosgy-dev/jmusicbot-jp) 10 | 11 | # JMusicBotJP 12 | 13 | JMusicBotは、シンプルでかつ操作性の良いUIを使用しています。セットアップも起動も簡単です。 14 | 15 | [![Setup](http://i.imgur.com/VvXYp5j.png)](https://www.cosgy.dev/2019/09/06/jmusicbot-setup/) 16 | 17 | # このボットの特徴 18 | 19 | * セットアップが簡単 20 | * 曲を高速にロード 21 | * Discord Botトークンのみでのセットアップ 22 | * ラグの少ないスムーズな再生 23 | * DJという独自の権限 24 | * シンプルで使いやすいUI 25 | * チャンネルトピックに表示される再生バー 26 | * ニコニコ動画、YouTubeや、Soundcloudなどを含む多くのサイトをサポート 27 | * 多数のオンラインラジオ/ストリームをサポート 28 | * ローカルファイルの再生 29 | * 再生リストのサポート 30 | * サーバーや個人の再生リストを作成 31 | 32 | # セットアップ 33 | 34 | このボットはJava11以上のバージョンが必要です。 35 | Javaがインストールされていない場合は、[こちら](https://www.oracle.com/jp/java/technologies/downloads/) からダウンロードしてください。 36 | このボットを自分で起動するには [Cosgy Dev 公式ページ](https://www.cosgy.dev/2019/09/06/jmusicbot-setup/) を参照してください 37 | 38 | # Dockerを使用したセットアップ 39 | 40 | Dockerを使用してJavaのインストールなどを行わずにこのボットを自分で起動することができます。 41 | Dockerを使用する場合は、[こちら](https://hub.docker.com/r/cyberrex/jmusicbot-jp) を参照してください。 42 | 43 | # 注意 44 | 45 | このボットは公開ボットとして使用することはできません。 46 | 個人や小規模のサーバーでの使用を推奨します。 47 | 48 | # 質問/提案/バグレポート 49 | 50 | **機能を提案する前に、推奨/計画された機能リストをお読みください。**
51 | ボットの機能の変更を提案したり、カスタマイズ・オプションを推奨したり、バグを報告したりしたい場合には、このリポジトリーでIssueを開くか、あるいは [Discordサーバー](https://discord.gg/RBpkHxf) 52 | に参加してください。(注意: 53 | 追加のAPIキーを必要とする機能リクエストや音楽以外の機能は受け付けません)。 54 |
このボットを気に入っていただけましたらこのリポジトリにStarをしていただけると幸いです。 55 | また、このボットの開発に必要不可欠な依存ライブラリ[JDA](https://github.com/DV8FromTheWorld/JDA) 56 | と [lavaplayer](https://github.com/lavalink-devs/lavaplayer)にもStarをしていただけると幸いです。 57 | 58 | # コマンドの例 59 | 60 | ![Example](https://i.imgur.com/tevrtKt.png) 61 | 62 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | image: ubuntu 2 | 3 | install: 4 | - sh: sudo add-apt-repository --yes ppa:rpardini/adoptopenjdk 5 | - sh: sudo apt-get update 6 | - sh: sudo apt-get install -y adoptopenjdk-11-jdk-hotspot-installer 7 | - sh: sudo apt install adoptopenjdk-11-jdk-hotspot-set-default 8 | #/usr/lib/jvm/adoptopenjdk-11-jdk-hotspot 9 | - sh: export JAVA_HOME=/usr/lib/jvm/adoptopenjdk-11-jdk-hotspot 10 | - sh: echo $JAVA_HOME 11 | - sh: export PATH=${PATH} 12 | 13 | before_build: 14 | - mvn -v 15 | 16 | build_script: 17 | - mvn clean package -DskipTests 18 | 19 | test_script: 20 | - mvn install verify 21 | 22 | on_finish: 23 | - sh: | 24 | find "$APPVEYOR_BUILD_FOLDER" -type f -name 'TEST*.xml' -print0 | xargs -0 -I '{}' curl -F 'file=@{}' "https://ci.appveyor.com/api/testresults/junit/$APPVEYOR_JOB_ID" 25 | 26 | artifacts: 27 | - path: "**/target/*.?ar" 28 | 29 | version: "0.8.0.{build}" -------------------------------------------------------------------------------- /src/main/java/com/jagrosh/jmusicbot/PlayStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Cosgy Dev 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.jagrosh.jmusicbot; 18 | 19 | public enum PlayStatus { 20 | PLAYING, 21 | PAUSED, 22 | STOPPED 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/jagrosh/jmusicbot/audio/AloneInVoiceHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 John Grosh . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.jagrosh.jmusicbot.audio; 17 | 18 | import com.jagrosh.jmusicbot.Bot; 19 | import dev.cosgy.jmusicbot.playlist.CacheLoader; 20 | import dev.cosgy.jmusicbot.util.LastSendTextChannel; 21 | import net.dv8tion.jda.api.entities.Guild; 22 | import net.dv8tion.jda.api.entities.channel.ChannelType; 23 | import net.dv8tion.jda.api.events.guild.voice.GuildVoiceUpdateEvent; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | import java.time.Instant; 28 | import java.util.HashMap; 29 | import java.util.HashSet; 30 | import java.util.Map; 31 | import java.util.Set; 32 | import java.util.concurrent.TimeUnit; 33 | 34 | /** 35 | * @author Michaili K (mysteriouscursor+git@protonmail.com) 36 | */ 37 | public class AloneInVoiceHandler { 38 | private final Bot bot; 39 | private final HashMap aloneSince = new HashMap<>(); 40 | Logger log = LoggerFactory.getLogger("AloneInVoiceHandler"); 41 | private long aloneTimeUntilStop = 0; 42 | 43 | public AloneInVoiceHandler(Bot bot) { 44 | this.bot = bot; 45 | } 46 | 47 | public void init() { 48 | aloneTimeUntilStop = bot.getConfig().getAloneTimeUntilStop(); 49 | if (aloneTimeUntilStop > 0) 50 | bot.getThreadpool().scheduleWithFixedDelay(this::check, 0, 5, TimeUnit.SECONDS); 51 | } 52 | 53 | private void check() { 54 | Set toRemove = new HashSet<>(); 55 | for (Map.Entry entrySet : aloneSince.entrySet()) { 56 | if (entrySet.getValue().getEpochSecond() > Instant.now().getEpochSecond() - aloneTimeUntilStop) continue; 57 | 58 | Guild guild = bot.getJDA().getGuildById(entrySet.getKey()); 59 | 60 | if (guild == null) { 61 | toRemove.add(entrySet.getKey()); 62 | continue; 63 | } 64 | AudioHandler handler = (AudioHandler) guild.getAudioManager().getSendingHandler(); 65 | 66 | if (bot.getConfig().getAutoStopQueueSave()) { 67 | // キャッシュの保存処理 68 | CacheLoader cache = bot.getCacheLoader(); 69 | cache.Save(guild.getId(), handler.getQueue()); 70 | log.info("再生待ちを保存してボイスチャンネルから退出します。"); 71 | LastSendTextChannel.SendMessage(guild, ":notes: 再生待ちを保存してボイスチャンネルから退出しました。"); 72 | } else { 73 | // キャッシュを保存せずに退出する時の処理 74 | log.info("再生待ちを削除してボイスチャンネルから退出します。"); 75 | LastSendTextChannel.SendMessage(guild, ":notes: 再生待ちを削除してボイスチャンネルから退出しました。"); 76 | } 77 | 78 | handler.stopAndClear(); 79 | guild.getAudioManager().closeAudioConnection(); 80 | 81 | toRemove.add(entrySet.getKey()); 82 | } 83 | toRemove.forEach(aloneSince::remove); 84 | } 85 | 86 | public void onVoiceUpdate(GuildVoiceUpdateEvent event) { 87 | if (aloneTimeUntilStop <= 0) return; 88 | 89 | Guild guild = event.getEntity().getGuild(); 90 | if (!bot.getPlayerManager().hasHandler(guild)) return; 91 | // ステージチャンネルにいる場合は退出しない。 92 | if (guild.getAudioManager().getConnectedChannel() != null) { 93 | if (guild.getAudioManager().getConnectedChannel().getType() == ChannelType.STAGE) return; 94 | } 95 | 96 | boolean alone = isAlone(guild); 97 | boolean inList = aloneSince.containsKey(guild.getIdLong()); 98 | 99 | if (!alone && inList) 100 | aloneSince.remove(guild.getIdLong()); 101 | else if (alone && !inList) 102 | aloneSince.put(guild.getIdLong(), Instant.now()); 103 | } 104 | 105 | private boolean isAlone(Guild guild) { 106 | if (guild.getAudioManager().getConnectedChannel() == null) return false; 107 | return guild.getAudioManager().getConnectedChannel().getMembers().stream() 108 | .noneMatch(x -> 109 | !x.getVoiceState().isDeafened() 110 | && !x.getUser().isBot()); 111 | } 112 | } -------------------------------------------------------------------------------- /src/main/java/com/jagrosh/jmusicbot/audio/PlayerManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 Cosgy Dev 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.jagrosh.jmusicbot.audio; 17 | 18 | import com.jagrosh.jmusicbot.Bot; 19 | import com.sedmelluq.discord.lavaplayer.player.AudioConfiguration; 20 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayer; 21 | import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager; 22 | import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers; 23 | import com.sedmelluq.discord.lavaplayer.source.nico.NicoAudioSourceManager; 24 | import dev.lavalink.youtube.YoutubeAudioSourceManager; 25 | import dev.lavalink.youtube.clients.*; 26 | import net.dv8tion.jda.api.entities.Guild; 27 | import org.slf4j.Logger; 28 | import org.slf4j.LoggerFactory; 29 | 30 | /** 31 | * @author John Grosh 32 | */ 33 | public class PlayerManager extends DefaultAudioPlayerManager { 34 | private final Bot bot; 35 | private final Logger logger = LoggerFactory.getLogger(this.getClass()); 36 | 37 | public PlayerManager(Bot bot) { 38 | this.bot = bot; 39 | } 40 | 41 | public void init() { 42 | if (bot.getConfig().isNicoNicoEnabled()) { 43 | registerSourceManager( 44 | new NicoAudioSourceManager( 45 | bot.getConfig().getNicoNicoEmailAddress(), 46 | bot.getConfig().getNicoNicoPassword()) 47 | ); 48 | } 49 | 50 | registerSourceManager(new YoutubeAudioSourceManager(true, new Music(), 51 | new TvHtml5Embedded(), 52 | new AndroidMusic(), 53 | new Web(), 54 | new WebEmbedded(), 55 | new Android(), 56 | new Ios())); 57 | 58 | 59 | TransformativeAudioSourceManager.createTransforms(bot.getConfig().getTransforms()).forEach(this::registerSourceManager); 60 | AudioSourceManagers.registerRemoteSources(this); 61 | AudioSourceManagers.registerLocalSource(this); 62 | 63 | source(YoutubeAudioSourceManager.class).setPlaylistPageCount(10); 64 | source(YoutubeAudioSourceManager.class).useOauth2(null, false); 65 | 66 | 67 | if (getConfiguration().getOpusEncodingQuality() != 10) { 68 | logger.debug("OpusEncodingQuality は、{}(< 10), 品質を10に設定します。", getConfiguration().getOpusEncodingQuality()); 69 | getConfiguration().setOpusEncodingQuality(10); 70 | } 71 | 72 | if (getConfiguration().getResamplingQuality() != AudioConfiguration.ResamplingQuality.HIGH) { 73 | logger.debug("ResamplingQuality は {}(HIGHではない), 品質をHIGHに設定します。", getConfiguration().getResamplingQuality().name()); 74 | getConfiguration().setResamplingQuality(AudioConfiguration.ResamplingQuality.HIGH); 75 | } 76 | } 77 | 78 | public Bot getBot() { 79 | return bot; 80 | } 81 | 82 | public boolean hasHandler(Guild guild) { 83 | return guild.getAudioManager().getSendingHandler() != null; 84 | } 85 | 86 | public AudioHandler setUpHandler(Guild guild) { 87 | AudioHandler handler; 88 | if (guild.getAudioManager().getSendingHandler() == null) { 89 | AudioPlayer player = createPlayer(); 90 | player.setVolume(bot.getSettingsManager().getSettings(guild).getVolume()); 91 | handler = new AudioHandler(this, guild, player); 92 | player.addListener(handler); 93 | guild.getAudioManager().setSendingHandler(handler); 94 | } else 95 | handler = (AudioHandler) guild.getAudioManager().getSendingHandler(); 96 | return handler; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/com/jagrosh/jmusicbot/audio/QueuedTrack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 Cosgy Dev 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.jagrosh.jmusicbot.audio; 17 | 18 | import com.jagrosh.jmusicbot.queue.Queueable; 19 | import com.jagrosh.jmusicbot.utils.FormatUtil; 20 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 21 | import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; 22 | import dev.cosgy.agent.GensokyoInfoAgent; 23 | import dev.cosgy.agent.objects.ResultSet; 24 | import net.dv8tion.jda.api.entities.User; 25 | 26 | /** 27 | * @author John Grosh 28 | */ 29 | public class QueuedTrack implements Queueable { 30 | private final AudioTrack track; 31 | 32 | public QueuedTrack(AudioTrack track, User owner) { 33 | this(track, new RequestMetadata(owner)); 34 | } 35 | 36 | public QueuedTrack(AudioTrack track, RequestMetadata rm) { 37 | this.track = track; 38 | this.track.setUserData(rm); 39 | } 40 | 41 | @Override 42 | public long getIdentifier() { 43 | return track.getUserData(RequestMetadata.class).getOwner(); 44 | } 45 | 46 | public AudioTrack getTrack() { 47 | return track; 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | 53 | if (track.getInfo().uri.contains("https://stream.gensokyoradio.net/")) { 54 | 55 | ResultSet data = null; 56 | try { 57 | data = GensokyoInfoAgent.getInfo(); 58 | } catch (Exception e) { 59 | throw new RuntimeException(e); 60 | } 61 | 62 | String title = data.getSonginfo().getTitle(); 63 | String titleUrl = data.getMisc().getCirclelink().equals("") ? 64 | "https://gensokyoradio.net/" : 65 | data.getMisc().getCirclelink(); 66 | return "`[" + FormatUtil.formatTime(data.getSongtimes().getDuration()) + "]` [**" + title + "**](" + titleUrl + ") - <@" + track.getUserData(RequestMetadata.class).getOwner() + ">"; 67 | } 68 | 69 | String entry = "`[" + FormatUtil.formatTime(track.getDuration()) + "]` "; 70 | AudioTrackInfo trackInfo = track.getInfo(); 71 | entry = entry + (trackInfo.uri.startsWith("http") ? "[**" + trackInfo.title + "**](" + trackInfo.uri + ")" : "**" + trackInfo.title + "**"); 72 | return entry + " - <@" + track.getUserData(RequestMetadata.class).getOwner() + ">"; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/jagrosh/jmusicbot/audio/RequestMetadata.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Cosgy Dev (info@cosgy.dev). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.jagrosh.jmusicbot.audio; 18 | 19 | import net.dv8tion.jda.api.entities.User; 20 | 21 | public class RequestMetadata { 22 | public static final RequestMetadata EMPTY = new RequestMetadata(null); 23 | 24 | public final UserInfo user; 25 | 26 | public RequestMetadata(User user) { 27 | this.user = user == null ? null : new UserInfo(user.getIdLong(), user.getName(), user.getDiscriminator(), user.getEffectiveAvatarUrl()); 28 | } 29 | 30 | public long getOwner() { 31 | return user == null ? 0L : user.id; 32 | } 33 | 34 | public class RequestInfo { 35 | public final String query, url; 36 | 37 | private RequestInfo(String query, String url) { 38 | this.query = query; 39 | this.url = url; 40 | } 41 | } 42 | 43 | public class UserInfo { 44 | public final long id; 45 | public final String username, discrim, avatar; 46 | 47 | private UserInfo(long id, String username, String discrim, String avatar) { 48 | this.id = id; 49 | this.username = username; 50 | this.discrim = discrim; 51 | this.avatar = avatar; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/jagrosh/jmusicbot/audio/TransformativeAudioSourceManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Cosgy Dev (info@cosgy.dev). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.jagrosh.jmusicbot.audio; 18 | 19 | import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; 20 | import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioSourceManager; 21 | import com.sedmelluq.discord.lavaplayer.track.AudioItem; 22 | import com.sedmelluq.discord.lavaplayer.track.AudioReference; 23 | import com.typesafe.config.Config; 24 | import org.jsoup.Jsoup; 25 | import org.jsoup.nodes.Document; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.io.IOException; 30 | import java.util.Collections; 31 | import java.util.List; 32 | import java.util.regex.PatternSyntaxException; 33 | import java.util.stream.Collectors; 34 | 35 | public class TransformativeAudioSourceManager extends YoutubeAudioSourceManager { 36 | private final static Logger log = LoggerFactory.getLogger(TransformativeAudioSourceManager.class); 37 | private final String name, regex, replacement, selector, format; 38 | 39 | public TransformativeAudioSourceManager(String name, Config object) { 40 | this(name, object.getString("regex"), object.getString("replacement"), object.getString("selector"), object.getString("format")); 41 | } 42 | 43 | public TransformativeAudioSourceManager(String name, String regex, String replacement, String selector, String format) { 44 | this.name = name; 45 | this.regex = regex; 46 | this.replacement = replacement; 47 | this.selector = selector; 48 | this.format = format; 49 | } 50 | 51 | public static List createTransforms(Config transforms) { 52 | try { 53 | return transforms.root().entrySet().stream() 54 | .map(e -> new TransformativeAudioSourceManager(e.getKey(), transforms.getConfig(e.getKey()))) 55 | .collect(Collectors.toList()); 56 | } catch (Exception ex) { 57 | log.warn("Invalid transform ", ex); 58 | return Collections.emptyList(); 59 | } 60 | } 61 | 62 | @Override 63 | public String getSourceName() { 64 | return name; 65 | } 66 | 67 | @Override 68 | public AudioItem loadItem(AudioPlayerManager apm, AudioReference ar) { 69 | if (ar.identifier == null || !ar.identifier.matches(regex)) 70 | return null; 71 | try { 72 | String url = ar.identifier.replaceAll(regex, replacement); 73 | Document doc = Jsoup.connect(url).get(); 74 | String value = doc.selectFirst(selector).ownText(); 75 | String formattedValue = String.format(format, value); 76 | return super.loadItem(apm, new AudioReference(formattedValue, null)); 77 | } catch (PatternSyntaxException ex) { 78 | log.info(String.format("ソース '%s'の無効なパターン構文 '%s'", regex, name)); 79 | } catch (IOException ex) { 80 | log.warn(String.format("ソース '%s'のURLを解決できませんでした: ", name), ex); 81 | } catch (Exception ex) { 82 | log.warn(String.format("ソース '%s'の例外", name), ex); 83 | } 84 | return null; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/jagrosh/jmusicbot/entities/Pair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 Cosgy Dev 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.jagrosh.jmusicbot.entities; 17 | 18 | /** 19 | * @param 20 | * @param 21 | * @author John Grosh (john.a.grosh@gmail.com) 22 | */ 23 | public class Pair { 24 | private final K key; 25 | private final V value; 26 | 27 | public Pair(K key, V value) { 28 | this.key = key; 29 | this.value = value; 30 | } 31 | 32 | public K getKey() { 33 | return key; 34 | } 35 | 36 | public V getValue() { 37 | return value; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/jagrosh/jmusicbot/entities/Prompt.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 Cosgy Dev 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.jagrosh.jmusicbot.entities; 17 | 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | 21 | import javax.swing.*; 22 | import java.util.Scanner; 23 | 24 | /** 25 | * @author John Grosh (john.a.grosh@gmail.com) 26 | */ 27 | public class Prompt { 28 | private final String title; 29 | private final String noguiMessage; 30 | private final boolean noprompt; 31 | private boolean nogui; 32 | private Scanner scanner; 33 | 34 | public Prompt(String title) { 35 | this(title, null); 36 | } 37 | 38 | public Prompt(String title, String noguiMessage) { 39 | this(title, noguiMessage, "true".equalsIgnoreCase(System.getProperty("nogui")), "true".equalsIgnoreCase(System.getProperty("noprompt"))); 40 | } 41 | 42 | public Prompt(String title, String noguiMessage, boolean nogui, boolean noprompt) { 43 | this.title = title; 44 | this.noguiMessage = noguiMessage == null ? "noguiモードに切り替えます。 -nogui=trueフラグを含めることで、手動でnoguiモードで起動できます。" : noguiMessage; 45 | this.nogui = nogui; 46 | this.noprompt = noprompt; 47 | } 48 | 49 | public boolean isNoGUI() { 50 | return nogui; 51 | } 52 | 53 | public void alert(Level level, String context, String message) { 54 | if (nogui) { 55 | Logger log = LoggerFactory.getLogger(context); 56 | switch (level) { 57 | case WARNING: 58 | log.warn(message); 59 | break; 60 | case ERROR: 61 | log.error(message); 62 | break; 63 | case INFO: 64 | default: 65 | log.info(message); 66 | break; 67 | } 68 | } else { 69 | try { 70 | int option = 0; 71 | switch (level) { 72 | case INFO: 73 | option = JOptionPane.INFORMATION_MESSAGE; 74 | break; 75 | case WARNING: 76 | option = JOptionPane.WARNING_MESSAGE; 77 | break; 78 | case ERROR: 79 | break; 80 | default: 81 | option = JOptionPane.PLAIN_MESSAGE; 82 | break; 83 | } 84 | JOptionPane.showMessageDialog(null, "

" + message, title, option); 85 | } catch (Exception e) { 86 | nogui = true; 87 | alert(Level.WARNING, context, noguiMessage); 88 | alert(level, context, message); 89 | } 90 | } 91 | } 92 | 93 | public String prompt(String content) { 94 | if (noprompt) 95 | return null; 96 | if (nogui) { 97 | if (scanner == null) 98 | scanner = new Scanner(System.in); 99 | try { 100 | System.out.println(content); 101 | if (scanner.hasNextLine()) 102 | return scanner.nextLine(); 103 | return null; 104 | } catch (Exception e) { 105 | alert(Level.ERROR, title, "コマンドラインから入力を読み込めません。"); 106 | e.printStackTrace(); 107 | return null; 108 | } 109 | } else { 110 | try { 111 | return JOptionPane.showInputDialog(null, content, title, JOptionPane.QUESTION_MESSAGE); 112 | } catch (Exception e) { 113 | nogui = true; 114 | alert(Level.WARNING, title, noguiMessage); 115 | return prompt(content); 116 | } 117 | } 118 | } 119 | 120 | public enum Level { 121 | INFO, WARNING, ERROR 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/main/java/com/jagrosh/jmusicbot/gui/ConsolePanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 Cosgy Dev 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.jagrosh.jmusicbot.gui; 17 | 18 | import javax.swing.*; 19 | import java.awt.*; 20 | import java.io.PrintStream; 21 | 22 | /** 23 | * @author John Grosh 24 | */ 25 | public class ConsolePanel extends JPanel { 26 | 27 | public ConsolePanel() { 28 | super(); 29 | JTextArea text = new JTextArea(); 30 | text.setLineWrap(true); 31 | text.setWrapStyleWord(true); 32 | text.setEditable(false); 33 | PrintStream con = new PrintStream(new TextAreaOutputStream(text)); 34 | System.setOut(con); 35 | System.setErr(con); 36 | 37 | JScrollPane pane = new JScrollPane(); 38 | pane.setViewportView(text); 39 | 40 | super.setLayout(new GridLayout(1, 1)); 41 | super.add(pane); 42 | super.setPreferredSize(new Dimension(400, 300)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/jagrosh/jmusicbot/gui/GUI.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 John Grosh . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.jagrosh.jmusicbot.gui; 17 | 18 | import com.jagrosh.jmusicbot.Bot; 19 | 20 | import javax.swing.*; 21 | import java.awt.event.WindowEvent; 22 | import java.awt.event.WindowListener; 23 | 24 | 25 | /** 26 | * @author John Grosh 27 | */ 28 | public class GUI extends JFrame { 29 | private final ConsolePanel console; 30 | private final Bot bot; 31 | 32 | public GUI(Bot bot) { 33 | super(); 34 | this.bot = bot; 35 | console = new ConsolePanel(); 36 | } 37 | 38 | public void init() { 39 | setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 40 | setTitle("JMusicBot JP"); 41 | JTabbedPane tabs = new JTabbedPane(); 42 | tabs.add("コンソール", console); 43 | getContentPane().add(tabs); 44 | pack(); 45 | setLocationRelativeTo(null); 46 | setVisible(true); 47 | addWindowListener(new WindowListener() { 48 | @Override 49 | public void windowOpened(WindowEvent e) { /* unused */ } 50 | 51 | @Override 52 | public void windowClosing(WindowEvent e) { 53 | try { 54 | bot.shutdown(); 55 | } catch (Exception ex) { 56 | System.exit(0); 57 | } 58 | } 59 | 60 | @Override 61 | public void windowClosed(WindowEvent e) { /* unused */ } 62 | 63 | @Override 64 | public void windowIconified(WindowEvent e) { /* unused */ } 65 | 66 | @Override 67 | public void windowDeiconified(WindowEvent e) { /* unused */ } 68 | 69 | @Override 70 | public void windowActivated(WindowEvent e) { /* unused */ } 71 | 72 | @Override 73 | public void windowDeactivated(WindowEvent e) { /* unused */ } 74 | }); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/jagrosh/jmusicbot/queue/FairQueue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.jagrosh.jmusicbot.queue; 17 | 18 | import java.util.ArrayList; 19 | import java.util.HashSet; 20 | import java.util.List; 21 | import java.util.Set; 22 | 23 | /** 24 | * @param 25 | * @author John Grosh (jagrosh) 26 | */ 27 | public class FairQueue { 28 | private final List list = new ArrayList<>(); 29 | private final Set set = new HashSet<>(); 30 | 31 | /** 32 | * @deprecated 新しくフェアキューと普通のキューを切り替えられるメゾットを追加したのでそちらを使用してください。 33 | * @param item 追加する楽曲情報 34 | * @return 何曲目に追加したか 35 | */ 36 | public int add(T item) { 37 | int lastIndex; 38 | for (lastIndex = list.size() - 1; lastIndex > -1; lastIndex--) 39 | if (list.get(lastIndex).getIdentifier() == item.getIdentifier()) 40 | break; 41 | lastIndex++; 42 | set.clear(); 43 | for (; lastIndex < list.size(); lastIndex++) { 44 | if (set.contains(list.get(lastIndex).getIdentifier())) 45 | break; 46 | set.add(list.get(lastIndex).getIdentifier()); 47 | } 48 | list.add(lastIndex, item); 49 | return lastIndex; 50 | } 51 | 52 | /** 53 | * キューに楽曲を追加します。 54 | * @param item 楽曲情報 55 | * @param forceToEnd 強制的にキューの一番最後に追加するか 56 | * @return 何番目に追加したか 57 | */ 58 | public int add(T item, boolean forceToEnd) { 59 | if (forceToEnd) { 60 | list.add(item); 61 | return list.size() - 1; 62 | } 63 | 64 | int lastIndex; 65 | for (lastIndex = list.size() - 1; lastIndex > -1; lastIndex--) 66 | if (list.get(lastIndex).getIdentifier() == item.getIdentifier()) 67 | break; 68 | lastIndex++; 69 | set.clear(); 70 | for (; lastIndex < list.size(); lastIndex++) { 71 | if (set.contains(list.get(lastIndex).getIdentifier())) 72 | break; 73 | set.add(list.get(lastIndex).getIdentifier()); 74 | } 75 | list.add(lastIndex, item); 76 | return lastIndex; 77 | } 78 | 79 | public void addAt(int index, T item) { 80 | if (index >= list.size()) 81 | list.add(item); 82 | else 83 | list.add(index, item); 84 | } 85 | 86 | public int size() { 87 | return list.size(); 88 | } 89 | 90 | public T pull() { 91 | return list.remove(0); 92 | } 93 | 94 | public boolean isEmpty() { 95 | return list.isEmpty(); 96 | } 97 | 98 | public List getList() { 99 | return list; 100 | } 101 | 102 | public T get(int index) { 103 | return list.get(index); 104 | } 105 | 106 | public T remove(int index) { 107 | return list.remove(index); 108 | } 109 | 110 | public int removeAll(long identifier) { 111 | int count = 0; 112 | for (int i = list.size() - 1; i >= 0; i--) { 113 | if (list.get(i).getIdentifier() == identifier) { 114 | list.remove(i); 115 | count++; 116 | } 117 | } 118 | return count; 119 | } 120 | 121 | public void clear() { 122 | list.clear(); 123 | } 124 | 125 | public int shuffle(long identifier) { 126 | List iset = new ArrayList<>(); 127 | for (int i = 0; i < list.size(); i++) { 128 | if (list.get(i).getIdentifier() == identifier) 129 | iset.add(i); 130 | } 131 | for (int j = 0; j < iset.size(); j++) { 132 | int first = iset.get(j); 133 | int second = iset.get((int) (Math.random() * iset.size())); 134 | T temp = list.get(first); 135 | list.set(first, list.get(second)); 136 | list.set(second, temp); 137 | } 138 | return iset.size(); 139 | } 140 | 141 | public void skip(int number) { 142 | if (number > 0) { 143 | list.subList(0, number).clear(); 144 | } 145 | } 146 | 147 | /** 148 | * アイテムをリスト内の別の位置に移動します 149 | * 150 | * @param from アイテムの位置 151 | * @param to アイテムの新しい位置 152 | * @return the 移動したアイテム 153 | */ 154 | public T moveItem(int from, int to) { 155 | T item = list.remove(from); 156 | list.add(to, item); 157 | return item; 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/main/java/com/jagrosh/jmusicbot/queue/Queueable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.jagrosh.jmusicbot.queue; 17 | 18 | /** 19 | * @author John Grosh 20 | */ 21 | public interface Queueable { 22 | 23 | long getIdentifier(); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/jagrosh/jmusicbot/utils/FormatUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.jagrosh.jmusicbot.utils; 17 | 18 | import net.dv8tion.jda.api.entities.Role; 19 | import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; 20 | import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; 21 | 22 | import java.io.PrintWriter; 23 | import java.io.StringWriter; 24 | import java.util.List; 25 | 26 | /** 27 | * @author John Grosh 28 | */ 29 | public class FormatUtil { 30 | public static String getStacktraceByString(Throwable t) { 31 | StringWriter sw = new StringWriter(); 32 | PrintWriter pw = new PrintWriter(sw); 33 | t.printStackTrace(pw); 34 | pw.flush(); 35 | return sw.toString(); 36 | } 37 | 38 | public static String formatTime(long duration) { 39 | if (duration == Long.MAX_VALUE) 40 | return "LIVE"; 41 | long seconds = Math.round(duration / 1000.0); 42 | long hours = seconds / (60 * 60); 43 | seconds %= 60 * 60; 44 | long minutes = seconds / 60; 45 | seconds %= 60; 46 | return (hours > 0 ? hours + ":" : "") + (minutes < 10 ? "0" + minutes : minutes) + ":" + (seconds < 10 ? "0" + seconds : seconds); 47 | } 48 | 49 | public static String formatTime(int duration) { 50 | if (duration == Integer.MAX_VALUE) 51 | return "LIVE"; 52 | int seconds = duration; 53 | int hours = seconds / (60 * 60); 54 | seconds %= 60 * 60; 55 | int minutes = seconds / 60; 56 | seconds %= 60; 57 | return (hours > 0 ? hours + ":" : "") + (minutes < 10 ? "0" + minutes : minutes) + ":" + (seconds < 10 ? "0" + seconds : seconds); 58 | } 59 | 60 | public static String progressBar(double percent) { 61 | StringBuilder str = new StringBuilder(); 62 | for (int i = 0; i < 12; i++) 63 | if (i == (int) (percent * 12)) 64 | str.append("\uD83D\uDD18"); // 🔘 65 | else 66 | str.append("▬"); 67 | return str.toString(); 68 | } 69 | 70 | public static String volumeIcon(int volume) { 71 | if (volume == 0) 72 | return "\uD83D\uDD07"; // 🔇 73 | if (volume < 30) 74 | return "\uD83D\uDD08"; // 🔈 75 | if (volume < 70) 76 | return "\uD83D\uDD09"; // 🔉 77 | return "\uD83D\uDD0A"; // 🔊 78 | } 79 | 80 | public static String listOfTChannels(List list, String query) { 81 | StringBuilder out = new StringBuilder(" 複数のテキストチャンネルで\"" + query + "\"が一致しました。:"); 82 | for (int i = 0; i < 6 && i < list.size(); i++) 83 | out.append("\n - ").append(list.get(i).getName()).append(" (<#").append(list.get(i).getId()).append(">)"); 84 | if (list.size() > 6) 85 | out.append("\n**と ").append(list.size() - 6).append(" など...**"); 86 | return out.toString(); 87 | } 88 | 89 | public static String listOfVChannels(List list, String query) { 90 | StringBuilder outBuilder = new StringBuilder(" 複数のボイスチャンネルで\"" + query + "\"が一致しました。:"); 91 | for (int i = 0; i < 6 && i < list.size(); i++) 92 | outBuilder.append("\n - ").append(list.get(i).getAsMention()).append(" (ID:").append(list.get(i).getId()).append(")"); 93 | String out = outBuilder.toString(); 94 | if (list.size() > 6) 95 | out += "\n**と " + (list.size() - 6) + " など...**"; 96 | return out; 97 | } 98 | 99 | public static String listOfRoles(List list, String query) { 100 | StringBuilder outBuilder = new StringBuilder(" 複数のテキストチャンネルで \"" + query + "\"が一致しました。:"); 101 | for (int i = 0; i < 6 && i < list.size(); i++) 102 | outBuilder.append("\n - ").append(list.get(i).getName()).append(" (ID:").append(list.get(i).getId()).append(")"); 103 | String out = outBuilder.toString(); 104 | if (list.size() > 6) 105 | out += "\n**と " + (list.size() - 6) + " など...**"; 106 | return out; 107 | } 108 | 109 | public static String filter(String input) { 110 | return input.replace("@everyone", "@\u0435veryone").replace("@here", "@h\u0435re").trim(); // cyrillic letter e 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/com/sedmelluq/discord/lavaplayer/source/nico/TOTPGenerator.java: -------------------------------------------------------------------------------- 1 | package com.sedmelluq.discord.lavaplayer.source.nico;/* 2 | * Copyright 2024 Cosgy Dev (info@cosgy.dev). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import javax.crypto.Mac; 18 | import javax.crypto.spec.SecretKeySpec; 19 | import java.nio.ByteBuffer; 20 | import java.security.InvalidKeyException; 21 | import java.security.NoSuchAlgorithmException; 22 | import java.time.Instant; 23 | import java.util.*; 24 | 25 | public class TOTPGenerator { 26 | 27 | private static final int DIGIT = 6; 28 | private static final int TIME_STEP = 30; 29 | private static final Map base32table = new HashMap<>(); 30 | 31 | static { 32 | base32table.put('A', 0); base32table.put('B', 1); base32table.put('C', 2); base32table.put('D', 3); 33 | base32table.put('E', 4); base32table.put('F', 5); base32table.put('G', 6); base32table.put('H', 7); 34 | base32table.put('I', 8); base32table.put('J', 9); base32table.put('K', 10); base32table.put('L', 11); 35 | base32table.put('M', 12); base32table.put('N', 13); base32table.put('O', 14); base32table.put('P', 15); 36 | base32table.put('Q', 16); base32table.put('R', 17); base32table.put('S', 18); base32table.put('T', 19); 37 | base32table.put('U', 20); base32table.put('V', 21); base32table.put('W', 22); base32table.put('X', 23); 38 | base32table.put('Y', 24); base32table.put('Z', 25); base32table.put('2', 26); base32table.put('3', 27); 39 | base32table.put('4', 28); base32table.put('5', 29); base32table.put('6', 30); base32table.put('7', 31); 40 | } 41 | 42 | // Main method to get the TOTP code 43 | public static String getCode(String key) { 44 | byte[] decodedKey = base32decode(key.toUpperCase()); 45 | return totp(decodedKey, Instant.now()); 46 | } 47 | 48 | // TOTP generation function 49 | private static String totp(byte[] key, Instant instant) { 50 | long counter = instant.getEpochSecond() / TIME_STEP; 51 | return hotp(key, counter); 52 | } 53 | 54 | // HOTP generation function 55 | private static String hotp(byte[] key, long counter) { 56 | ByteBuffer buffer = ByteBuffer.allocate(8); 57 | buffer.putLong(counter); 58 | 59 | byte[] hash = hmacSha1(key, buffer.array()); 60 | int truncatedHash = truncate(hash); 61 | return String.format("%06d", truncatedHash); 62 | } 63 | 64 | // Truncate function as defined in RFC 4226 65 | private static int truncate(byte[] hash) { 66 | int offset = hash[hash.length - 1] & 0xf; 67 | int binary = ((hash[offset] & 0x7f) << 24) 68 | | ((hash[offset + 1] & 0xff) << 16) 69 | | ((hash[offset + 2] & 0xff) << 8) 70 | | (hash[offset + 3] & 0xff); 71 | return binary % (int) Math.pow(10, DIGIT); 72 | } 73 | 74 | // HMAC-SHA1 calculation 75 | private static byte[] hmacSha1(byte[] key, byte[] data) { 76 | try { 77 | Mac mac = Mac.getInstance("HmacSHA1"); 78 | SecretKeySpec secretKeySpec = new SecretKeySpec(key, "HmacSHA1"); 79 | mac.init(secretKeySpec); 80 | return mac.doFinal(data); 81 | } catch (NoSuchAlgorithmException | InvalidKeyException e) { 82 | throw new RuntimeException(e); 83 | } 84 | } 85 | 86 | // Base32 decoding function 87 | private static byte[] base32decode(String str) { 88 | str = str.replaceAll("[^A-Z2-7]", ""); // Only keep valid base32 characters 89 | int outputLength = str.length() * 5 / 8; 90 | byte[] result = new byte[outputLength]; 91 | 92 | int buffer = 0; 93 | int bitsLeft = 0; 94 | int index = 0; 95 | 96 | for (char c : str.toCharArray()) { 97 | buffer <<= 5; 98 | buffer |= base32table.get(c) & 31; 99 | bitsLeft += 5; 100 | 101 | if (bitsLeft >= 8) { 102 | result[index++] = (byte) (buffer >> (bitsLeft - 8)); 103 | bitsLeft -= 8; 104 | } 105 | } 106 | 107 | return result; 108 | } 109 | 110 | public static void main(String[] args) { 111 | // Example usage 112 | Scanner scanner = new Scanner(System.in); 113 | System.out.println("二段階認証のシークレットキーを入力してください。"); 114 | String secretKey = scanner.next(); // Sample Base32 secret key 115 | 116 | Timer timer = new Timer(); 117 | timer.schedule(new TimerTask() { 118 | @Override 119 | public void run() { 120 | String code = getCode(secretKey); 121 | long current = (Instant.now().getEpochSecond() % TIME_STEP); 122 | String gauge = "=".repeat((int) current) + "-".repeat(TIME_STEP - (int) current); 123 | System.out.printf("\rTOTP Code: %s [%s] %s sec", code, gauge, TIME_STEP - (int) current); 124 | } 125 | }, 0, 500); // 0ミリ秒で開始し、500ミリ秒ごとに更新 126 | } 127 | } 128 | 129 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/agent/GensokyoInfoAgent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Cosgy Dev (info@cosgy.dev). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dev.cosgy.agent; 18 | 19 | import com.fasterxml.jackson.databind.ObjectMapper; 20 | import dev.cosgy.agent.objects.ResultSet; 21 | import org.slf4j.Logger; 22 | import org.slf4j.LoggerFactory; 23 | 24 | import java.net.HttpURLConnection; 25 | import java.net.URI; 26 | import java.net.http.HttpClient; 27 | import java.net.http.HttpRequest; 28 | import java.net.http.HttpResponse; 29 | import java.time.Duration; 30 | 31 | public class GensokyoInfoAgent extends Thread { 32 | private static final Logger log = LoggerFactory.getLogger(GensokyoInfoAgent.class); 33 | private static long INTERVAL_MILLIS = 1000; // 5 secs 34 | private static ResultSet info = null; 35 | private static String lastSong = ""; 36 | 37 | public GensokyoInfoAgent() { 38 | setDaemon(true); 39 | setName("GensokyoInfoAgent"); 40 | } 41 | 42 | @SuppressWarnings("UnusedReturnValue") 43 | private static ResultSet fetch() throws Exception { 44 | HttpURLConnection connection = null; 45 | try { 46 | 47 | if (info != null) { 48 | if (info.getSongtimes().getPlayed() < info.getSongtimes().getDuration()) { 49 | return info; 50 | } 51 | } 52 | // XMLの取得元URL設定 53 | //URL url = new URL("https://gensokyoradio.net/xml"); 54 | 55 | System.setProperty("http.agent", "Chrome"); 56 | 57 | HttpRequest req = HttpRequest.newBuilder(new URI("https://gensokyoradio.net/json")) 58 | .GET() 59 | .timeout(Duration.ofSeconds(10)) 60 | .setHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36") 61 | .setHeader("accept-language", "ja,en-US;q=0.9,en;q=0.8") 62 | .build(); 63 | 64 | HttpClient client = HttpClient.newBuilder() 65 | .connectTimeout(Duration.ofSeconds(10)) 66 | .build(); 67 | 68 | HttpResponse res = client.send(req, HttpResponse.BodyHandlers.ofString()); 69 | String body = res.body(); 70 | 71 | switch (res.statusCode()) { 72 | case 200: 73 | // HTTP レスポンスの JSON を ResultSet クラスにマッピング 74 | info = new ObjectMapper().readValue(body, ResultSet.class); 75 | return info; 76 | case 403: 77 | log.info("幻想郷ラジオの情報取得エラー(403)"); 78 | log.info("Body:{}", res.body()); 79 | return null; 80 | default: 81 | log.info("幻想郷ラジオの情報取得エラー(other)"); 82 | return null; 83 | } 84 | 85 | } finally { 86 | if (connection != null) { 87 | connection.disconnect(); 88 | } 89 | } 90 | } 91 | 92 | public static ResultSet getInfo() throws Exception { 93 | return fetch(); 94 | } 95 | 96 | @Override 97 | public void run() { 98 | log.info("GensokyoInfoAgentを開始しました"); 99 | 100 | //noinspection InfiniteLoopStatement 101 | while (true) { 102 | 103 | try { 104 | sleep(1000); 105 | // 現在再生中の曲が終わるまで幻想郷ラジオに曲の情報をリクエストしない。 106 | // DDos攻撃になってしまうので... 107 | if (info != null) { 108 | info.getSongtimes().setPlayed(info.getSongtimes().getPlayed() + 1); 109 | } 110 | } catch (InterruptedException e) { 111 | throw new RuntimeException(e); 112 | } 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/agent/objects/Misc.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2022 Cosgy Dev (info@cosgy.dev). 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package dev.cosgy.agent.objects; 19 | 20 | import com.fasterxml.jackson.annotation.*; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | @JsonInclude(JsonInclude.Include.NON_NULL) 26 | @JsonPropertyOrder({ 27 | "CIRCLELINK", 28 | "ALBUMART", 29 | "CIRCLEART", 30 | "OFFSET", 31 | "OFFSETTIME" 32 | }) 33 | 34 | public class Misc { 35 | 36 | @JsonProperty("CIRCLELINK") 37 | private String circlelink; 38 | @JsonProperty("ALBUMART") 39 | private String albumart; 40 | @JsonProperty("CIRCLEART") 41 | private String circleart; 42 | @JsonProperty("OFFSET") 43 | private String offset; 44 | @JsonProperty("OFFSETTIME") 45 | private Integer offsettime; 46 | @JsonIgnore 47 | private Map additionalProperties = new HashMap(); 48 | 49 | @JsonProperty("CIRCLELINK") 50 | public String getCirclelink() { 51 | return circlelink; 52 | } 53 | 54 | @JsonProperty("CIRCLELINK") 55 | public void setCirclelink(String circlelink) { 56 | this.circlelink = circlelink; 57 | } 58 | 59 | @JsonProperty("ALBUMART") 60 | public String getAlbumart() { 61 | return albumart; 62 | } 63 | 64 | @JsonProperty("ALBUMART") 65 | public void setAlbumart(String albumart) { 66 | this.albumart = albumart; 67 | } 68 | 69 | @JsonProperty("CIRCLEART") 70 | public String getCircleart() { 71 | return circleart; 72 | } 73 | 74 | @JsonProperty("CIRCLEART") 75 | public void setCircleart(String circleart) { 76 | this.circleart = circleart; 77 | } 78 | 79 | @JsonProperty("OFFSET") 80 | public String getOffset() { 81 | return offset; 82 | } 83 | 84 | @JsonProperty("OFFSET") 85 | public void setOffset(String offset) { 86 | this.offset = offset; 87 | } 88 | 89 | @JsonProperty("OFFSETTIME") 90 | public Integer getOffsettime() { 91 | return offsettime; 92 | } 93 | 94 | @JsonProperty("OFFSETTIME") 95 | public void setOffsettime(Integer offsettime) { 96 | this.offsettime = offsettime; 97 | } 98 | 99 | @JsonAnyGetter 100 | public Map getAdditionalProperties() { 101 | return this.additionalProperties; 102 | } 103 | 104 | @JsonAnySetter 105 | public void setAdditionalProperty(String name, Object value) { 106 | this.additionalProperties.put(name, value); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/agent/objects/ResultSet.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2022 Cosgy Dev (info@cosgy.dev). 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package dev.cosgy.agent.objects; 19 | 20 | import com.fasterxml.jackson.annotation.*; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | @JsonInclude(JsonInclude.Include.NON_NULL) 26 | @JsonPropertyOrder({ 27 | "SERVERINFO", 28 | "SONGINFO", 29 | "SONGTIMES", 30 | "SONGDATA", 31 | "MISC" 32 | }) 33 | 34 | public class ResultSet { 35 | 36 | @JsonProperty("SERVERINFO") 37 | private Serverinfo serverinfo; 38 | @JsonProperty("SONGINFO") 39 | private Songinfo songinfo; 40 | @JsonProperty("SONGTIMES") 41 | private Songtimes songtimes; 42 | @JsonProperty("SONGDATA") 43 | private Songdata songdata; 44 | @JsonProperty("MISC") 45 | private Misc misc; 46 | @JsonIgnore 47 | private Map additionalProperties = new HashMap(); 48 | 49 | @JsonProperty("SERVERINFO") 50 | public Serverinfo getServerinfo() { 51 | return serverinfo; 52 | } 53 | 54 | @JsonProperty("SERVERINFO") 55 | public void setServerinfo(Serverinfo serverinfo) { 56 | this.serverinfo = serverinfo; 57 | } 58 | 59 | @JsonProperty("SONGINFO") 60 | public Songinfo getSonginfo() { 61 | return songinfo; 62 | } 63 | 64 | @JsonProperty("SONGINFO") 65 | public void setSonginfo(Songinfo songinfo) { 66 | this.songinfo = songinfo; 67 | } 68 | 69 | @JsonProperty("SONGTIMES") 70 | public Songtimes getSongtimes() { 71 | return songtimes; 72 | } 73 | 74 | @JsonProperty("SONGTIMES") 75 | public void setSongtimes(Songtimes songtimes) { 76 | this.songtimes = songtimes; 77 | } 78 | 79 | @JsonProperty("SONGDATA") 80 | public Songdata getSongdata() { 81 | return songdata; 82 | } 83 | 84 | @JsonProperty("SONGDATA") 85 | public void setSongdata(Songdata songdata) { 86 | this.songdata = songdata; 87 | } 88 | 89 | @JsonProperty("MISC") 90 | public Misc getMisc() { 91 | return misc; 92 | } 93 | 94 | @JsonProperty("MISC") 95 | public void setMisc(Misc misc) { 96 | this.misc = misc; 97 | } 98 | 99 | @JsonAnyGetter 100 | public Map getAdditionalProperties() { 101 | return this.additionalProperties; 102 | } 103 | 104 | @JsonAnySetter 105 | public void setAdditionalProperty(String name, Object value) { 106 | this.additionalProperties.put(name, value); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/agent/objects/Serverinfo.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2022 Cosgy Dev (info@cosgy.dev). 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package dev.cosgy.agent.objects; 19 | 20 | import com.fasterxml.jackson.annotation.*; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | @JsonInclude(JsonInclude.Include.NON_NULL) 26 | @JsonPropertyOrder({ 27 | "LASTUPDATE", 28 | "SERVERS", 29 | "STATUS", 30 | "LISTENERS", 31 | "STREAMS", 32 | "MODE" 33 | }) 34 | 35 | public class Serverinfo { 36 | 37 | @JsonProperty("LASTUPDATE") 38 | private Integer lastupdate; 39 | @JsonProperty("SERVERS") 40 | private Integer servers; 41 | @JsonProperty("STATUS") 42 | private String status; 43 | @JsonProperty("LISTENERS") 44 | private Integer listeners; 45 | @JsonProperty("STREAMS") 46 | private Streams streams; 47 | @JsonProperty("MODE") 48 | private String mode; 49 | @JsonIgnore 50 | private Map additionalProperties = new HashMap(); 51 | 52 | @JsonProperty("LASTUPDATE") 53 | public Integer getLastupdate() { 54 | return lastupdate; 55 | } 56 | 57 | @JsonProperty("LASTUPDATE") 58 | public void setLastupdate(Integer lastupdate) { 59 | this.lastupdate = lastupdate; 60 | } 61 | 62 | @JsonProperty("SERVERS") 63 | public Integer getServers() { 64 | return servers; 65 | } 66 | 67 | @JsonProperty("SERVERS") 68 | public void setServers(Integer servers) { 69 | this.servers = servers; 70 | } 71 | 72 | @JsonProperty("STATUS") 73 | public String getStatus() { 74 | return status; 75 | } 76 | 77 | @JsonProperty("STATUS") 78 | public void setStatus(String status) { 79 | this.status = status; 80 | } 81 | 82 | @JsonProperty("LISTENERS") 83 | public Integer getListeners() { 84 | return listeners; 85 | } 86 | 87 | @JsonProperty("LISTENERS") 88 | public void setListeners(Integer listeners) { 89 | this.listeners = listeners; 90 | } 91 | 92 | @JsonProperty("STREAMS") 93 | public Streams getStreams() { 94 | return streams; 95 | } 96 | 97 | @JsonProperty("STREAMS") 98 | public void setStreams(Streams streams) { 99 | this.streams = streams; 100 | } 101 | 102 | @JsonProperty("MODE") 103 | public String getMode() { 104 | return mode; 105 | } 106 | 107 | @JsonProperty("MODE") 108 | public void setMode(String mode) { 109 | this.mode = mode; 110 | } 111 | 112 | @JsonAnyGetter 113 | public Map getAdditionalProperties() { 114 | return this.additionalProperties; 115 | } 116 | 117 | @JsonAnySetter 118 | public void setAdditionalProperty(String name, Object value) { 119 | this.additionalProperties.put(name, value); 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/agent/objects/Songdata.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2022 Cosgy Dev (info@cosgy.dev). 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package dev.cosgy.agent.objects; 19 | 20 | import com.fasterxml.jackson.annotation.*; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | @JsonInclude(JsonInclude.Include.NON_NULL) 26 | @JsonPropertyOrder({ 27 | "SONGID", 28 | "ALBUMID", 29 | "RATING", 30 | "TIMESRATED" 31 | }) 32 | 33 | public class Songdata { 34 | 35 | @JsonProperty("SONGID") 36 | private String songid; 37 | @JsonProperty("ALBUMID") 38 | private String albumid; 39 | @JsonProperty("RATING") 40 | private String rating; 41 | @JsonProperty("TIMESRATED") 42 | private Integer timesrated; 43 | @JsonIgnore 44 | private Map additionalProperties = new HashMap(); 45 | 46 | @JsonProperty("SONGID") 47 | public String getSongid() { 48 | return songid; 49 | } 50 | 51 | @JsonProperty("SONGID") 52 | public void setSongid(String songid) { 53 | this.songid = songid; 54 | } 55 | 56 | @JsonProperty("ALBUMID") 57 | public String getAlbumid() { 58 | return albumid; 59 | } 60 | 61 | @JsonProperty("ALBUMID") 62 | public void setAlbumid(String albumid) { 63 | this.albumid = albumid; 64 | } 65 | 66 | @JsonProperty("RATING") 67 | public String getRating() { 68 | return rating; 69 | } 70 | 71 | @JsonProperty("RATING") 72 | public void setRating(String rating) { 73 | this.rating = rating; 74 | } 75 | 76 | @JsonProperty("TIMESRATED") 77 | public Integer getTimesrated() { 78 | return timesrated; 79 | } 80 | 81 | @JsonProperty("TIMESRATED") 82 | public void setTimesrated(Integer timesrated) { 83 | this.timesrated = timesrated; 84 | } 85 | 86 | @JsonAnyGetter 87 | public Map getAdditionalProperties() { 88 | return this.additionalProperties; 89 | } 90 | 91 | @JsonAnySetter 92 | public void setAdditionalProperty(String name, Object value) { 93 | this.additionalProperties.put(name, value); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/agent/objects/Songinfo.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2022 Cosgy Dev (info@cosgy.dev). 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package dev.cosgy.agent.objects; 19 | 20 | import com.fasterxml.jackson.annotation.*; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | @JsonInclude(JsonInclude.Include.NON_NULL) 26 | @JsonPropertyOrder({ 27 | "TITLE", 28 | "ARTIST", 29 | "ALBUM", 30 | "YEAR", 31 | "CIRCLE" 32 | }) 33 | public class Songinfo { 34 | 35 | @JsonProperty("TITLE") 36 | private String title; 37 | @JsonProperty("ARTIST") 38 | private String artist; 39 | @JsonProperty("ALBUM") 40 | private String album; 41 | @JsonProperty("YEAR") 42 | private String year; 43 | @JsonProperty("CIRCLE") 44 | private String circle; 45 | @JsonIgnore 46 | private Map additionalProperties = new HashMap(); 47 | 48 | @JsonProperty("TITLE") 49 | public String getTitle() { 50 | return title; 51 | } 52 | 53 | @JsonProperty("TITLE") 54 | public void setTitle(String title) { 55 | this.title = title; 56 | } 57 | 58 | @JsonProperty("ARTIST") 59 | public String getArtist() { 60 | return artist; 61 | } 62 | 63 | @JsonProperty("ARTIST") 64 | public void setArtist(String artist) { 65 | this.artist = artist; 66 | } 67 | 68 | @JsonProperty("ALBUM") 69 | public String getAlbum() { 70 | return album; 71 | } 72 | 73 | @JsonProperty("ALBUM") 74 | public void setAlbum(String album) { 75 | this.album = album; 76 | } 77 | 78 | @JsonProperty("YEAR") 79 | public String getYear() { 80 | return year; 81 | } 82 | 83 | @JsonProperty("YEAR") 84 | public void setYear(String year) { 85 | this.year = year; 86 | } 87 | 88 | @JsonProperty("CIRCLE") 89 | public String getCircle() { 90 | return circle; 91 | } 92 | 93 | @JsonProperty("CIRCLE") 94 | public void setCircle(String circle) { 95 | this.circle = circle; 96 | } 97 | 98 | @JsonAnyGetter 99 | public Map getAdditionalProperties() { 100 | return this.additionalProperties; 101 | } 102 | 103 | @JsonAnySetter 104 | public void setAdditionalProperty(String name, Object value) { 105 | this.additionalProperties.put(name, value); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/agent/objects/Songtimes.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2022 Cosgy Dev (info@cosgy.dev). 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package dev.cosgy.agent.objects; 19 | 20 | import com.fasterxml.jackson.annotation.*; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | @JsonInclude(JsonInclude.Include.NON_NULL) 26 | @JsonPropertyOrder({ 27 | "DURATION", 28 | "PLAYED", 29 | "REMAINING", 30 | "SONGSTART", 31 | "SONGEND" 32 | }) 33 | 34 | public class Songtimes { 35 | 36 | @JsonProperty("DURATION") 37 | private Integer duration; 38 | @JsonProperty("PLAYED") 39 | private Integer played; 40 | @JsonProperty("REMAINING") 41 | private Integer remaining; 42 | @JsonProperty("SONGSTART") 43 | private Integer songstart; 44 | @JsonProperty("SONGEND") 45 | private Integer songend; 46 | @JsonIgnore 47 | private Map additionalProperties = new HashMap(); 48 | 49 | @JsonProperty("DURATION") 50 | public Integer getDuration() { 51 | return duration; 52 | } 53 | 54 | @JsonProperty("DURATION") 55 | public void setDuration(Integer duration) { 56 | this.duration = duration; 57 | } 58 | 59 | @JsonProperty("PLAYED") 60 | public Integer getPlayed() { 61 | return played; 62 | } 63 | 64 | @JsonProperty("PLAYED") 65 | public void setPlayed(Integer played) { 66 | this.played = played; 67 | } 68 | 69 | @JsonProperty("REMAINING") 70 | public Integer getRemaining() { 71 | return remaining; 72 | } 73 | 74 | @JsonProperty("REMAINING") 75 | public void setRemaining(Integer remaining) { 76 | this.remaining = remaining; 77 | } 78 | 79 | @JsonProperty("SONGSTART") 80 | public Integer getSongstart() { 81 | return songstart; 82 | } 83 | 84 | @JsonProperty("SONGSTART") 85 | public void setSongstart(Integer songstart) { 86 | this.songstart = songstart; 87 | } 88 | 89 | @JsonProperty("SONGEND") 90 | public Integer getSongend() { 91 | return songend; 92 | } 93 | 94 | @JsonProperty("SONGEND") 95 | public void setSongend(Integer songend) { 96 | this.songend = songend; 97 | } 98 | 99 | @JsonAnyGetter 100 | public Map getAdditionalProperties() { 101 | return this.additionalProperties; 102 | } 103 | 104 | @JsonAnySetter 105 | public void setAdditionalProperty(String name, Object value) { 106 | this.additionalProperties.put(name, value); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/agent/objects/Streams.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2022 Cosgy Dev (info@cosgy.dev). 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package dev.cosgy.agent.objects; 19 | 20 | import com.fasterxml.jackson.annotation.*; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | @JsonInclude(JsonInclude.Include.NON_NULL) 26 | @JsonPropertyOrder({ 27 | "1", 28 | "2", 29 | "3", 30 | "4" 31 | }) 32 | public class Streams { 33 | 34 | @JsonProperty("1") 35 | private dev.cosgy.agent.objects._1 _1; 36 | @JsonProperty("2") 37 | private dev.cosgy.agent.objects._2 _2; 38 | @JsonProperty("3") 39 | private dev.cosgy.agent.objects._3 _3; 40 | @JsonProperty("4") 41 | private dev.cosgy.agent.objects._4 _4; 42 | @JsonIgnore 43 | private Map additionalProperties = new HashMap(); 44 | 45 | @JsonProperty("1") 46 | public dev.cosgy.agent.objects._1 get1() { 47 | return _1; 48 | } 49 | 50 | @JsonProperty("1") 51 | public void set1(dev.cosgy.agent.objects._1 _1) { 52 | this._1 = _1; 53 | } 54 | 55 | @JsonProperty("2") 56 | public dev.cosgy.agent.objects._2 get2() { 57 | return _2; 58 | } 59 | 60 | @JsonProperty("2") 61 | public void set2(dev.cosgy.agent.objects._2 _2) { 62 | this._2 = _2; 63 | } 64 | 65 | @JsonProperty("3") 66 | public dev.cosgy.agent.objects._3 get3() { 67 | return _3; 68 | } 69 | 70 | @JsonProperty("3") 71 | public void set3(dev.cosgy.agent.objects._3 _3) { 72 | this._3 = _3; 73 | } 74 | 75 | @JsonProperty("4") 76 | public dev.cosgy.agent.objects._4 get4() { 77 | return _4; 78 | } 79 | 80 | @JsonProperty("4") 81 | public void set4(dev.cosgy.agent.objects._4 _4) { 82 | this._4 = _4; 83 | } 84 | 85 | @JsonAnyGetter 86 | public Map getAdditionalProperties() { 87 | return this.additionalProperties; 88 | } 89 | 90 | @JsonAnySetter 91 | public void setAdditionalProperty(String name, Object value) { 92 | this.additionalProperties.put(name, value); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/agent/objects/_1.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2022 Cosgy Dev (info@cosgy.dev). 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package dev.cosgy.agent.objects; 19 | 20 | import com.fasterxml.jackson.annotation.*; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | @JsonInclude(JsonInclude.Include.NON_NULL) 26 | @JsonPropertyOrder({ 27 | "BITRATE", 28 | "LISTENERS" 29 | }) 30 | 31 | public class _1 { 32 | 33 | @JsonProperty("BITRATE") 34 | private Integer bitrate; 35 | @JsonProperty("LISTENERS") 36 | private Integer listeners; 37 | @JsonIgnore 38 | private Map additionalProperties = new HashMap(); 39 | 40 | @JsonProperty("BITRATE") 41 | public Integer getBitrate() { 42 | return bitrate; 43 | } 44 | 45 | @JsonProperty("BITRATE") 46 | public void setBitrate(Integer bitrate) { 47 | this.bitrate = bitrate; 48 | } 49 | 50 | @JsonProperty("LISTENERS") 51 | public Integer getListeners() { 52 | return listeners; 53 | } 54 | 55 | @JsonProperty("LISTENERS") 56 | public void setListeners(Integer listeners) { 57 | this.listeners = listeners; 58 | } 59 | 60 | @JsonAnyGetter 61 | public Map getAdditionalProperties() { 62 | return this.additionalProperties; 63 | } 64 | 65 | @JsonAnySetter 66 | public void setAdditionalProperty(String name, Object value) { 67 | this.additionalProperties.put(name, value); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/agent/objects/_2.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2022 Cosgy Dev (info@cosgy.dev). 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package dev.cosgy.agent.objects; 19 | 20 | import com.fasterxml.jackson.annotation.*; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | @JsonInclude(JsonInclude.Include.NON_NULL) 26 | @JsonPropertyOrder({ 27 | "BITRATE", 28 | "LISTENERS" 29 | }) 30 | 31 | public class _2 { 32 | 33 | @JsonProperty("BITRATE") 34 | private Integer bitrate; 35 | @JsonProperty("LISTENERS") 36 | private Integer listeners; 37 | @JsonIgnore 38 | private Map additionalProperties = new HashMap(); 39 | 40 | @JsonProperty("BITRATE") 41 | public Integer getBitrate() { 42 | return bitrate; 43 | } 44 | 45 | @JsonProperty("BITRATE") 46 | public void setBitrate(Integer bitrate) { 47 | this.bitrate = bitrate; 48 | } 49 | 50 | @JsonProperty("LISTENERS") 51 | public Integer getListeners() { 52 | return listeners; 53 | } 54 | 55 | @JsonProperty("LISTENERS") 56 | public void setListeners(Integer listeners) { 57 | this.listeners = listeners; 58 | } 59 | 60 | @JsonAnyGetter 61 | public Map getAdditionalProperties() { 62 | return this.additionalProperties; 63 | } 64 | 65 | @JsonAnySetter 66 | public void setAdditionalProperty(String name, Object value) { 67 | this.additionalProperties.put(name, value); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/agent/objects/_3.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2022 Cosgy Dev (info@cosgy.dev). 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package dev.cosgy.agent.objects; 19 | 20 | import com.fasterxml.jackson.annotation.*; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | @JsonInclude(JsonInclude.Include.NON_NULL) 26 | @JsonPropertyOrder({ 27 | "BITRATE", 28 | "LISTENERS" 29 | }) 30 | 31 | public class _3 { 32 | 33 | @JsonProperty("BITRATE") 34 | private Integer bitrate; 35 | @JsonProperty("LISTENERS") 36 | private Integer listeners; 37 | @JsonIgnore 38 | private Map additionalProperties = new HashMap(); 39 | 40 | @JsonProperty("BITRATE") 41 | public Integer getBitrate() { 42 | return bitrate; 43 | } 44 | 45 | @JsonProperty("BITRATE") 46 | public void setBitrate(Integer bitrate) { 47 | this.bitrate = bitrate; 48 | } 49 | 50 | @JsonProperty("LISTENERS") 51 | public Integer getListeners() { 52 | return listeners; 53 | } 54 | 55 | @JsonProperty("LISTENERS") 56 | public void setListeners(Integer listeners) { 57 | this.listeners = listeners; 58 | } 59 | 60 | @JsonAnyGetter 61 | public Map getAdditionalProperties() { 62 | return this.additionalProperties; 63 | } 64 | 65 | @JsonAnySetter 66 | public void setAdditionalProperty(String name, Object value) { 67 | this.additionalProperties.put(name, value); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/agent/objects/_4.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2022 Cosgy Dev (info@cosgy.dev). 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package dev.cosgy.agent.objects; 19 | 20 | import com.fasterxml.jackson.annotation.*; 21 | 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | @JsonInclude(JsonInclude.Include.NON_NULL) 26 | @JsonPropertyOrder({ 27 | "BITRATE", 28 | "LISTENERS" 29 | }) 30 | 31 | public class _4 { 32 | 33 | @JsonProperty("BITRATE") 34 | private Object bitrate; 35 | @JsonProperty("LISTENERS") 36 | private Object listeners; 37 | @JsonIgnore 38 | private Map additionalProperties = new HashMap(); 39 | 40 | @JsonProperty("BITRATE") 41 | public Object getBitrate() { 42 | return bitrate; 43 | } 44 | 45 | @JsonProperty("BITRATE") 46 | public void setBitrate(Object bitrate) { 47 | this.bitrate = bitrate; 48 | } 49 | 50 | @JsonProperty("LISTENERS") 51 | public Object getListeners() { 52 | return listeners; 53 | } 54 | 55 | @JsonProperty("LISTENERS") 56 | public void setListeners(Object listeners) { 57 | this.listeners = listeners; 58 | } 59 | 60 | @JsonAnyGetter 61 | public Map getAdditionalProperties() { 62 | return this.additionalProperties; 63 | } 64 | 65 | @JsonAnySetter 66 | public void setAdditionalProperty(String name, Object value) { 67 | this.additionalProperties.put(name, value); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/settings/RepeatMode.java: -------------------------------------------------------------------------------- 1 | package dev.cosgy.jmusicbot.settings; 2 | 3 | /** 4 | * @author ryuuta0217 5 | */ 6 | public enum RepeatMode { 7 | OFF, 8 | ALL, 9 | SINGLE 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/AdminCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands; 17 | 18 | import com.jagrosh.jdautilities.command.CommandClient; 19 | import com.jagrosh.jdautilities.command.SlashCommand; 20 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 21 | import net.dv8tion.jda.api.Permission; 22 | 23 | public abstract class AdminCommand extends SlashCommand { 24 | public AdminCommand() { 25 | this.category = new Category("Admin", event -> 26 | { 27 | if (event.isOwner() || event.getMember().isOwner()) 28 | return true; 29 | if (event.getGuild() == null) 30 | return true; 31 | return event.getMember().hasPermission(Permission.MANAGE_SERVER); 32 | }); 33 | this.guildOnly = true; 34 | } 35 | 36 | public static boolean checkAdminPermission(CommandClient client, SlashCommandEvent event) { 37 | if (event.getUser().getId().equals(client.getOwnerId()) || event.getMember().isOwner()) 38 | return false; 39 | if (event.getGuild() == null) 40 | return false; 41 | return !event.getMember().hasPermission(Permission.MANAGE_SERVER); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/DJCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands; 17 | 18 | import com.jagrosh.jdautilities.command.CommandClient; 19 | import com.jagrosh.jdautilities.command.CommandEvent; 20 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 21 | import com.jagrosh.jmusicbot.Bot; 22 | import com.jagrosh.jmusicbot.settings.Settings; 23 | import net.dv8tion.jda.api.Permission; 24 | import net.dv8tion.jda.api.entities.Role; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | /** 29 | * @author John Grosh (john.a.grosh@gmail.com) 30 | */ 31 | public abstract class DJCommand extends MusicCommand { 32 | static Logger log = LoggerFactory.getLogger("DJCommand"); 33 | 34 | public DJCommand(Bot bot) { 35 | super(bot); 36 | this.category = new Category("DJ", DJCommand::checkDJPermission); 37 | } 38 | 39 | public static boolean checkDJPermission(CommandEvent event) { 40 | if (event.getAuthor().getId().equals(event.getClient().getOwnerId())) { 41 | return true; 42 | } 43 | if (event.getGuild() == null) { 44 | return true; 45 | } 46 | if (event.getMember().hasPermission(Permission.MANAGE_SERVER)) { 47 | return true; 48 | } 49 | Settings settings = event.getClient().getSettingsFor(event.getGuild()); 50 | Role dj = settings.getRole(event.getGuild()); 51 | return dj != null && (event.getMember().getRoles().contains(dj) || dj.getIdLong() == event.getGuild().getIdLong()); 52 | } 53 | 54 | public static boolean checkDJPermission(CommandClient client, SlashCommandEvent event) { 55 | if (event.getUser().getId().equals(client.getOwnerId())) { 56 | return true; 57 | } 58 | if (event.getGuild() == null) { 59 | return true; 60 | } 61 | if (event.getMember().hasPermission(Permission.MANAGE_SERVER)) { 62 | return true; 63 | } 64 | Settings settings = client.getSettingsFor(event.getGuild()); 65 | Role dj = settings.getRole(event.getGuild()); 66 | return dj != null && (event.getMember().getRoles().contains(dj) || dj.getIdLong() == event.getGuild().getIdLong()); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/OwnerCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands; 17 | 18 | import com.jagrosh.jdautilities.command.SlashCommand; 19 | 20 | /** 21 | * @author John Grosh (john.a.grosh@gmail.com) 22 | */ 23 | public abstract class OwnerCommand extends SlashCommand { 24 | public OwnerCommand() { 25 | this.category = new Category("Owner"); 26 | this.ownerCommand = true; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/admin/AutoplaylistCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 Cosgy Dev 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.admin; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 20 | import com.jagrosh.jmusicbot.Bot; 21 | import com.jagrosh.jmusicbot.settings.Settings; 22 | import dev.cosgy.jmusicbot.slashcommands.AdminCommand; 23 | import net.dv8tion.jda.api.interactions.commands.OptionType; 24 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | /** 30 | * @author kosugi_kun 31 | */ 32 | public class AutoplaylistCmd extends AdminCommand { 33 | private final Bot bot; 34 | 35 | public AutoplaylistCmd(Bot bot) { 36 | this.bot = bot; 37 | this.guildOnly = true; 38 | this.name = "autoplaylist"; 39 | this.arguments = ""; 40 | this.aliases = bot.getConfig().getAliases(this.name); 41 | this.help = "サーバーの自動再生リストを設定"; 42 | this.ownerCommand = false; 43 | 44 | List options = new ArrayList<>(); 45 | options.add(new OptionData(OptionType.STRING, "name", "プレイリストの名前", true)); 46 | 47 | this.options = options; 48 | } 49 | 50 | @Override 51 | protected void execute(SlashCommandEvent event) { 52 | if (checkAdminPermission(event.getClient(), event)) { 53 | event.reply(event.getClient().getWarning() + "権限がないため実行できません。").queue(); 54 | return; 55 | } 56 | 57 | String pName = event.getOption("name").getAsString(); 58 | if (pName.toLowerCase().matches("(none|なし)")) { 59 | Settings settings = event.getClient().getSettingsFor(event.getGuild()); 60 | settings.setDefaultPlaylist(null); 61 | event.reply(event.getClient().getSuccess() + "**" + event.getGuild().getName() + "** での自動再生リストを、なしに設定しました。").queue(); 62 | return; 63 | } 64 | if (bot.getPlaylistLoader().getPlaylist(event.getGuild().getId(), pName) == null) { 65 | event.reply(event.getClient().getError() + "`" + pName + "`を見つけることができませんでした!").queue(); 66 | } else { 67 | Settings settings = event.getClient().getSettingsFor(event.getGuild()); 68 | settings.setDefaultPlaylist(pName); 69 | event.reply(event.getClient().getSuccess() + "**" + event.getGuild().getName() + "** での自動再生リストを、`" + pName + "`に設定しました。\n" 70 | + "再生待ちに曲がないときは、自動再生リストの曲が再生されます。").queue(); 71 | } 72 | } 73 | 74 | @Override 75 | public void execute(CommandEvent event) { 76 | if (!event.isOwner() || !event.getMember().isOwner()) return; 77 | String guildId = event.getGuild().getId(); 78 | 79 | if (event.getArgs().isEmpty()) { 80 | event.reply(event.getClient().getError() + " 再生リスト名、またはNONEを含めてください。"); 81 | return; 82 | } 83 | if (event.getArgs().toLowerCase().matches("(none|なし)")) { 84 | Settings settings = event.getClient().getSettingsFor(event.getGuild()); 85 | settings.setDefaultPlaylist(null); 86 | event.reply(event.getClient().getSuccess() + "**" + event.getGuild().getName() + "** での自動再生リストを、なしに設定しました。"); 87 | return; 88 | } 89 | String pName = event.getArgs().replaceAll("\\s+", "_"); 90 | if (bot.getPlaylistLoader().getPlaylist(guildId, pName) == null) { 91 | event.reply(event.getClient().getError() + "`" + pName + "`を見つけることができませんでした!"); 92 | } else { 93 | Settings settings = event.getClient().getSettingsFor(event.getGuild()); 94 | settings.setDefaultPlaylist(pName); 95 | event.reply(event.getClient().getSuccess() + "**" + event.getGuild().getName() + "** での自動再生リストを、`" + pName + "`に設定しました。\n" 96 | + "再生待ちに曲がないときは、自動再生リストの曲が再生されます。"); 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/admin/PrefixCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dev.cosgy.jmusicbot.slashcommands.admin; 18 | 19 | import com.jagrosh.jdautilities.command.CommandEvent; 20 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 21 | import com.jagrosh.jmusicbot.Bot; 22 | import com.jagrosh.jmusicbot.settings.Settings; 23 | import dev.cosgy.jmusicbot.slashcommands.AdminCommand; 24 | import net.dv8tion.jda.api.interactions.commands.OptionType; 25 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 26 | 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | 30 | /** 31 | * @author John Grosh (john.a.grosh@gmail.com) 32 | */ 33 | public class PrefixCmd extends AdminCommand { 34 | public PrefixCmd(Bot bot) { 35 | this.name = "prefix"; 36 | this.help = "サーバー固有のプレフィックスを設定します"; 37 | this.arguments = "<プレフィックス|NONE>"; 38 | this.aliases = bot.getConfig().getAliases(this.name); 39 | //this.children = new SlashCommand[]{new None()}; 40 | 41 | List options = new ArrayList<>(); 42 | options.add(new OptionData(OptionType.STRING, "prefix", "設定するプレフィックス", true)); 43 | 44 | this.options = options; 45 | } 46 | 47 | @Override 48 | protected void execute(SlashCommandEvent event) { 49 | if (checkAdminPermission(event.getClient(), event)) { 50 | event.reply(event.getClient().getWarning() + "権限がないため実行できません。").queue(); 51 | return; 52 | } 53 | Settings s = event.getClient().getSettingsFor(event.getGuild()); 54 | String prefix = event.getOption("prefix").getAsString(); 55 | if (prefix.toLowerCase().matches("(none|なし)")) { 56 | s.setPrefix(null); 57 | event.reply(event.getClient().getSuccess() + "プレフィックスがクリアされました。").queue(); 58 | } else { 59 | s.setPrefix(prefix); 60 | event.reply(event.getClient().getSuccess() + "*" + event.getGuild().getName() + "* でのプレフィックスを、 `" + prefix + "`に設定しました。").queue(); 61 | } 62 | } 63 | 64 | @Override 65 | protected void execute(CommandEvent event) { 66 | if (event.getArgs().isEmpty()) { 67 | event.replyError("プレフィックスまたはNONEを含めてください。"); 68 | return; 69 | } 70 | 71 | Settings s = event.getClient().getSettingsFor(event.getGuild()); 72 | if (event.getArgs().toLowerCase().matches("(none|なし)")) { 73 | s.setPrefix(null); 74 | event.replySuccess("プレフィックスがクリアされました。"); 75 | } else { 76 | s.setPrefix(event.getArgs()); 77 | event.replySuccess("*" + event.getGuild().getName() + "* でのプレフィックスを、 `" + event.getArgs() + "`に設定しました。"); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/admin/SetvcCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.admin; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommand; 20 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 21 | import com.jagrosh.jdautilities.commons.utils.FinderUtil; 22 | import com.jagrosh.jmusicbot.Bot; 23 | import com.jagrosh.jmusicbot.settings.Settings; 24 | import com.jagrosh.jmusicbot.utils.FormatUtil; 25 | import dev.cosgy.jmusicbot.slashcommands.AdminCommand; 26 | import net.dv8tion.jda.api.entities.channel.ChannelType; 27 | import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; 28 | import net.dv8tion.jda.api.interactions.commands.OptionType; 29 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 30 | import org.slf4j.Logger; 31 | import org.slf4j.LoggerFactory; 32 | 33 | import java.util.ArrayList; 34 | import java.util.List; 35 | 36 | /** 37 | * @author John Grosh (john.a.grosh@gmail.com) 38 | */ 39 | public class SetvcCmd extends AdminCommand { 40 | public SetvcCmd(Bot bot) { 41 | this.name = "setvc"; 42 | this.help = "再生に使用する音声チャンネルを固定します。"; 43 | this.arguments = "<チャンネル名|NONE|なし>"; 44 | this.aliases = bot.getConfig().getAliases(this.name); 45 | 46 | this.children = new SlashCommand[]{new Set(), new None()}; 47 | } 48 | 49 | @Override 50 | protected void execute(SlashCommandEvent slashCommandEvent) { 51 | } 52 | 53 | @Override 54 | protected void execute(CommandEvent event) { 55 | Logger log = LoggerFactory.getLogger("SetVcCmd"); 56 | if (event.getArgs().isEmpty()) { 57 | event.reply(event.getClient().getError() + "音声チャンネルまたはNONEを含めてください。"); 58 | return; 59 | } 60 | Settings s = event.getClient().getSettingsFor(event.getGuild()); 61 | if (event.getArgs().toLowerCase().matches("(none|なし)")) { 62 | s.setVoiceChannel(null); 63 | event.reply(event.getClient().getSuccess() + "音楽はどの音声チャンネルでも再生できます。"); 64 | } else { 65 | List list = FinderUtil.findVoiceChannels(event.getArgs(), event.getGuild()); 66 | if (list.isEmpty()) 67 | event.reply(event.getClient().getWarning() + "一致する音声チャンネルが見つかりませんでした \"" + event.getArgs() + "\""); 68 | else if (list.size() > 1) 69 | event.reply(event.getClient().getWarning() + FormatUtil.listOfVChannels(list, event.getArgs())); 70 | else { 71 | s.setVoiceChannel(list.get(0)); 72 | log.info("音楽チャンネルを設定しました。"); 73 | event.reply(event.getClient().getSuccess() + "音楽は**" + list.get(0).getAsMention() + "**でのみ再生できるようになりました。"); 74 | } 75 | } 76 | } 77 | 78 | private static class Set extends AdminCommand { 79 | public Set() { 80 | this.name = "set"; 81 | this.help = "再生に使用する音声チャンネルを設定"; 82 | 83 | List options = new ArrayList<>(); 84 | options.add(new OptionData(OptionType.CHANNEL, "channel", "音声チャンネル", true)); 85 | 86 | this.options = options; 87 | } 88 | 89 | @Override 90 | protected void execute(SlashCommandEvent event) { 91 | if (checkAdminPermission(event.getClient(), event)) { 92 | event.reply(event.getClient().getWarning() + "権限がないため実行できません。").queue(); 93 | return; 94 | } 95 | Settings s = event.getClient().getSettingsFor(event.getGuild()); 96 | Long channel = event.getOption("channel").getAsLong(); 97 | 98 | if (event.getOption("channel").getChannelType() != ChannelType.VOICE) { 99 | event.reply(event.getClient().getError() + "音声チャンネルを設定して下さい").queue(); 100 | } 101 | 102 | VoiceChannel vc = event.getGuild().getVoiceChannelById(channel); 103 | s.setVoiceChannel(vc); 104 | event.reply(event.getClient().getSuccess() + "音楽は**" + vc.getAsMention() + "**でのみ再生できるようになりました。").queue(); 105 | } 106 | } 107 | 108 | private static class None extends AdminCommand { 109 | public None() { 110 | this.name = "none"; 111 | this.help = "再生に使用する音声チャンネルの設定をリセットします。"; 112 | } 113 | 114 | @Override 115 | protected void execute(SlashCommandEvent event) { 116 | if (checkAdminPermission(event.getClient(), event)) { 117 | event.reply(event.getClient().getWarning() + "権限がないため実行できません。").queue(); 118 | return; 119 | } 120 | Settings s = event.getClient().getSettingsFor(event.getGuild()); 121 | s.setVoiceChannel(null); 122 | event.reply(event.getClient().getSuccess() + "音楽はどの音声チャンネルでも再生できます。").queue(); 123 | } 124 | 125 | @Override 126 | protected void execute(CommandEvent event) { 127 | Settings s = event.getClient().getSettingsFor(event.getGuild()); 128 | s.setVoiceChannel(null); 129 | event.replySuccess("音楽はどの音声チャンネルでも再生できます。"); 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/admin/SetvcStatusCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Cosgy Dev (info@cosgy.dev). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dev.cosgy.jmusicbot.slashcommands.admin; 18 | 19 | import com.jagrosh.jdautilities.command.CommandEvent; 20 | import com.jagrosh.jdautilities.command.SlashCommand; 21 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 22 | import com.jagrosh.jmusicbot.Bot; 23 | import com.jagrosh.jmusicbot.settings.Settings; 24 | import dev.cosgy.jmusicbot.slashcommands.AdminCommand; 25 | import net.dv8tion.jda.api.interactions.commands.OptionType; 26 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 27 | 28 | import java.util.List; 29 | import java.util.Objects; 30 | 31 | public class SetvcStatusCmd extends AdminCommand { 32 | public SetvcStatusCmd(Bot bot) { 33 | this.name = "setvcstatus"; 34 | this.help = "VCステータスに再生中を表示するかを設定します。"; 35 | this.arguments = ""; 36 | this.aliases = bot.getConfig().getAliases(this.name); 37 | 38 | this.options = List.of( 39 | new OptionData(OptionType.BOOLEAN, "status", "有効:true 無効:false", true) 40 | ); 41 | } 42 | 43 | @Override 44 | protected void execute(SlashCommandEvent event) { 45 | if (checkAdminPermission(event.getClient(), event)) { 46 | event.reply(event.getClient().getWarning() + "権限がないため実行できません。").queue(); 47 | return; 48 | } 49 | 50 | var status = Objects.requireNonNull(event.getOption("status")).getAsBoolean(); 51 | Settings s = event.getClient().getSettingsFor(event.getGuild()); 52 | s.setVCStatus(status); 53 | 54 | event.reply(event.getClient().getSuccess() + "VCステータスに再生中を表示するかを`" + status + "`に設定しました。").queue(); 55 | } 56 | 57 | @Override 58 | protected void execute(CommandEvent event) { 59 | 60 | if (event.getArgs().isEmpty()) { 61 | event.reply(event.getClient().getError() + "trueかfalseを含めてください。"); 62 | return; 63 | } 64 | 65 | Settings s = event.getClient().getSettingsFor(event.getGuild()); 66 | 67 | if (event.getArgs().toLowerCase().matches("(false|無効)")) { 68 | s.setVCStatus(false); 69 | event.reply(event.getClient().getSuccess() + "VCステータスに再生中を表示しないように設定しました。"); 70 | }else if(event.getArgs().toLowerCase().matches("(true|有効)")) { 71 | s.setVCStatus(true); 72 | event.reply(event.getClient().getSuccess() + "VCステータスに再生中を表示するように設定しました。"); 73 | }else { 74 | event.reply(event.getClient().getError() + "trueかfalseを含めてください。"); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/admin/SkipratioCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Cosgy Dev (info@cosgy.dev). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dev.cosgy.jmusicbot.slashcommands.admin; 18 | 19 | import com.jagrosh.jdautilities.command.CommandEvent; 20 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 21 | import com.jagrosh.jmusicbot.Bot; 22 | import com.jagrosh.jmusicbot.settings.Settings; 23 | import dev.cosgy.jmusicbot.slashcommands.AdminCommand; 24 | import net.dv8tion.jda.api.interactions.commands.OptionType; 25 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 26 | 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | 30 | public class SkipratioCmd extends AdminCommand { 31 | public SkipratioCmd(Bot bot) { 32 | this.name = "setskip"; 33 | this.help = "サーバー固有のスキップ率を設定"; 34 | this.arguments = "<0 - 100>"; 35 | this.aliases = bot.getConfig().getAliases(this.name); 36 | 37 | List options = new ArrayList<>(); 38 | options.add(new OptionData(OptionType.INTEGER, "percent", "スキップ率", true)); 39 | 40 | this.options = options; 41 | } 42 | 43 | @Override 44 | protected void execute(SlashCommandEvent event) { 45 | try { 46 | int val = Integer.parseInt(event.getOption("percent").getAsString()); 47 | if (val < 0 || val > 100) { 48 | event.reply(event.getClient().getError() + "値は、0から100の間でなければなりません。").queue(); 49 | return; 50 | } 51 | Settings s = event.getClient().getSettingsFor(event.getGuild()); 52 | s.setSkipRatio(val / 100.0); 53 | 54 | event.reply(event.getClient().getSuccess() + "*" + event.getGuild().getName() + "*のリスナーのスキップ率を" + val + "%に設定しました。").queue(); 55 | } catch (NumberFormatException ex) { 56 | event.reply(event.getClient().getError() + "0~100の整数を入れてください(デフォルトは55)。この数値は、曲をスキップするために投票しなければならないリスニングユーザーの割合です。").queue(); 57 | } 58 | } 59 | 60 | @Override 61 | protected void execute(CommandEvent event) { 62 | try { 63 | int val = Integer.parseInt(event.getArgs().endsWith("%") ? event.getArgs().substring(0, event.getArgs().length() - 1) : event.getArgs()); 64 | if (val < 0 || val > 100) { 65 | event.replyError("値は、0から100の間でなければなりません。"); 66 | return; 67 | } 68 | Settings s = event.getClient().getSettingsFor(event.getGuild()); 69 | s.setSkipRatio(val / 100.0); 70 | 71 | event.replySuccess("*" + event.getGuild().getName() + "*のリスナーのスキップ率を" + val + "%に設定しました。"); 72 | } catch (NumberFormatException ex) { 73 | event.replyError("0~100の整数を入れてください(デフォルトは55)。この数値は、曲をスキップするために投票しなければならないリスニングユーザーの割合です。"); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/dj/ForceRemoveCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 John Grosh . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.dj; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 20 | import com.jagrosh.jdautilities.commons.utils.FinderUtil; 21 | import com.jagrosh.jdautilities.menu.OrderedMenu; 22 | import com.jagrosh.jmusicbot.Bot; 23 | import com.jagrosh.jmusicbot.audio.AudioHandler; 24 | import dev.cosgy.jmusicbot.slashcommands.DJCommand; 25 | import net.dv8tion.jda.api.Permission; 26 | import net.dv8tion.jda.api.entities.Member; 27 | import net.dv8tion.jda.api.entities.User; 28 | import net.dv8tion.jda.api.interactions.commands.OptionType; 29 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 30 | 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | import java.util.concurrent.TimeUnit; 34 | 35 | /** 36 | * @author Michaili K. 37 | */ 38 | public class ForceRemoveCmd extends DJCommand { 39 | public ForceRemoveCmd(Bot bot) { 40 | super(bot); 41 | this.name = "forceremove"; 42 | this.help = "指定したユーザーのエントリーを再生待ちから削除します"; 43 | this.arguments = "<ユーザー>"; 44 | this.aliases = bot.getConfig().getAliases(this.name); 45 | this.beListening = false; 46 | this.bePlaying = true; 47 | this.botPermissions = new Permission[]{Permission.MESSAGE_EMBED_LINKS}; 48 | 49 | List options = new ArrayList<>(); 50 | options.add(new OptionData(OptionType.USER, "user", "ユーザー", true)); 51 | this.options = options; 52 | 53 | } 54 | 55 | @Override 56 | public void doCommand(CommandEvent event) { 57 | if (event.getArgs().isEmpty()) { 58 | event.replyError("ユーザーに言及する必要があります!"); 59 | return; 60 | } 61 | 62 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 63 | if (handler.getQueue().isEmpty()) { 64 | event.replyError("再生待ちには何もありません!"); 65 | return; 66 | } 67 | 68 | 69 | User target; 70 | List found = FinderUtil.findMembers(event.getArgs(), event.getGuild()); 71 | 72 | if (found.isEmpty()) { 73 | event.replyError("ユーザーが見つかりません!"); 74 | return; 75 | } else if (found.size() > 1) { 76 | OrderedMenu.Builder builder = new OrderedMenu.Builder(); 77 | for (int i = 0; i < found.size() && i < 4; i++) { 78 | Member member = found.get(i); 79 | builder.addChoice("**" + member.getUser().getName() + "**#" + member.getUser().getDiscriminator()); 80 | } 81 | 82 | builder 83 | .setSelection((msg, i) -> removeAllEntries(found.get(i - 1).getUser(), event)) 84 | .setText("複数のユーザーが見つかりました:") 85 | .setColor(event.getSelfMember().getColor()) 86 | .useNumbers() 87 | .setUsers(event.getAuthor()) 88 | .useCancelButton(true) 89 | .setCancel((msg) -> { 90 | }) 91 | .setEventWaiter(bot.getWaiter()) 92 | .setTimeout(1, TimeUnit.MINUTES) 93 | 94 | .build().display(event.getChannel()); 95 | 96 | return; 97 | } else { 98 | target = found.get(0).getUser(); 99 | } 100 | 101 | removeAllEntries(target, event); 102 | 103 | } 104 | 105 | @Override 106 | public void doCommand(SlashCommandEvent event) { 107 | if (!checkDJPermission(event.getClient(), event)) { 108 | event.reply(event.getClient().getWarning() + "権限がないため実行できません。").queue(); 109 | return; 110 | } 111 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 112 | if (handler.getQueue().isEmpty()) { 113 | event.reply(event.getClient().getError() + "再生待ちには何もありません!").queue(); 114 | return; 115 | } 116 | 117 | User target = event.getOption("user").getAsUser(); 118 | int count = ((AudioHandler) event.getGuild().getAudioManager().getSendingHandler()).getQueue().removeAll(target.getIdLong()); 119 | if (count == 0) { 120 | event.reply(event.getClient().getWarning() + "**" + target.getName() + "** の再生待ちに曲がありません!").queue(); 121 | } else { 122 | event.reply(event.getClient().getSuccess() + "**" + target.getName() + "**#" + target.getDiscriminator() + "から`" + count + "`曲削除しました。").queue(); 123 | } 124 | } 125 | 126 | private void removeAllEntries(User target, CommandEvent event) { 127 | int count = ((AudioHandler) event.getGuild().getAudioManager().getSendingHandler()).getQueue().removeAll(target.getIdLong()); 128 | if (count == 0) { 129 | event.replyWarning("**" + target.getName() + "** の再生待ちに曲がありません!"); 130 | } else { 131 | event.replySuccess("**" + target.getName() + "**#" + target.getDiscriminator() + "から`" + count + "`曲削除しました。"); 132 | } 133 | } 134 | } -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/dj/ForceToEnd.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Cosgy Dev (info@cosgy.dev). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dev.cosgy.jmusicbot.slashcommands.dj 18 | 19 | import com.jagrosh.jdautilities.command.CommandEvent 20 | import com.jagrosh.jdautilities.command.SlashCommandEvent 21 | import com.jagrosh.jmusicbot.Bot 22 | import dev.cosgy.jmusicbot.slashcommands.DJCommand 23 | import net.dv8tion.jda.api.interactions.commands.OptionType 24 | import net.dv8tion.jda.api.interactions.commands.build.OptionData 25 | 26 | class ForceToEnd(bot: Bot) : DJCommand(bot) { 27 | init { 28 | this.name = "forcetoend" 29 | this.help = "楽曲追加設定をフェア追加モードか通常追加モードを使用するかを切り替えます。設定を`TRUE`にすると通常追加モードになります。" 30 | this.aliases = bot.config.getAliases(this.name) 31 | this.options = listOf(OptionData(OptionType.BOOLEAN, "value", "通常追加モードを使用するか", true)); 32 | } 33 | 34 | override fun doCommand(event: CommandEvent) { 35 | 36 | val nowSetting = bot.settingsManager?.getSettings(event.guild)?.isForceToEndQue 37 | var newSetting = false 38 | 39 | if (event.args.isEmpty()) { 40 | newSetting = !nowSetting!! 41 | } else if (event.args.equals("true", ignoreCase = true) || event.args.equals("on", ignoreCase = true) || event.args.equals("有効", ignoreCase = true)) { 42 | newSetting = true 43 | } else if (event.args.equals("false", ignoreCase = true) || event.args.equals("off", ignoreCase = true) || event.args.equals("無効", ignoreCase = true)) { 44 | newSetting = false 45 | } 46 | 47 | bot.settingsManager.getSettings(event.guild)?.isForceToEndQue = newSetting 48 | 49 | var msg = "再生待ちへの追加方法を変更しました。\n設定:" 50 | if (newSetting == true) { 51 | msg += "通常追加モード\nリクエストした曲を再生待ちの最後に追加します。" 52 | } else if (newSetting == false) { 53 | msg += "フェア追加モード\nリクエストした曲をフェアな順序で再生待ちに追加します。" 54 | } 55 | 56 | event.replySuccess(msg) 57 | } 58 | 59 | 60 | override fun doCommand(event: SlashCommandEvent) { 61 | val nowSetting = bot.settingsManager?.getSettings(event.guild)?.isForceToEndQue 62 | var newSetting = false 63 | 64 | newSetting = event.getOption("value")?.asBoolean!! 65 | 66 | bot.settingsManager.getSettings(event.guild)?.isForceToEndQue = newSetting 67 | 68 | var msg = "再生待ちへの追加方法を変更しました。\n設定:" 69 | if (newSetting == true) { 70 | msg += "通常追加モード\nリクエストした曲を再生待ちの最後に追加します。" 71 | } else if (newSetting == false) { 72 | msg += "フェア追加モード\nリクエストした曲をフェアな順序で再生待ちに追加します。" 73 | } 74 | 75 | event.reply(msg).queue() 76 | } 77 | } -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/dj/ForceskipCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 John Grosh . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.dj; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 20 | import com.jagrosh.jmusicbot.Bot; 21 | import com.jagrosh.jmusicbot.audio.AudioHandler; 22 | import com.jagrosh.jmusicbot.audio.RequestMetadata; 23 | import dev.cosgy.jmusicbot.slashcommands.DJCommand; 24 | import net.dv8tion.jda.api.interactions.commands.OptionType; 25 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 26 | 27 | import static net.dv8tion.jda.internal.utils.Helpers.listOf; 28 | 29 | /** 30 | * @author John Grosh 31 | */ 32 | public class ForceskipCmd extends DJCommand { 33 | public ForceskipCmd(Bot bot) { 34 | super(bot); 35 | this.name = "forceskip"; 36 | this.help = "現在の曲をスキップします"; 37 | this.aliases = bot.getConfig().getAliases(this.name); 38 | this.bePlaying = true; 39 | } 40 | 41 | @Override 42 | public void doCommand(CommandEvent event) { 43 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 44 | RequestMetadata rm = handler.getRequestMetadata(); 45 | event.reply(event.getClient().getSuccess() + "**" + handler.getPlayer().getPlayingTrack().getInfo().title 46 | + "** " + (rm.getOwner() == 0L ? "(自動再生)" : "(**" + rm.user.username + "**がリクエスト)")); 47 | handler.getPlayer().stopTrack(); 48 | } 49 | 50 | @Override 51 | public void doCommand(SlashCommandEvent event) { 52 | if (!checkDJPermission(event.getClient(), event)) { 53 | event.reply(event.getClient().getWarning() + "権限がないため実行できません。").queue(); 54 | return; 55 | } 56 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 57 | RequestMetadata rm = handler.getRequestMetadata(); 58 | event.reply(event.getClient().getSuccess() + "**" + handler.getPlayer().getPlayingTrack().getInfo().title 59 | + "** " + (rm.getOwner() == 0L ? "(自動再生)" : "(**" + rm.user.username + "**がリクエスト)")).queue(); 60 | handler.getPlayer().stopTrack(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/dj/MoveTrackCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 Cosgy Dev 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dev.cosgy.jmusicbot.slashcommands.dj; 18 | 19 | 20 | import com.jagrosh.jdautilities.command.CommandEvent; 21 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 22 | import com.jagrosh.jmusicbot.Bot; 23 | import com.jagrosh.jmusicbot.audio.AudioHandler; 24 | import com.jagrosh.jmusicbot.audio.QueuedTrack; 25 | import com.jagrosh.jmusicbot.queue.FairQueue; 26 | import dev.cosgy.jmusicbot.slashcommands.DJCommand; 27 | import net.dv8tion.jda.api.interactions.commands.OptionType; 28 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | 35 | /** 36 | * ユーザーが再生リスト内のトラックを移動できるようにするコマンドです。 37 | */ 38 | public class MoveTrackCmd extends DJCommand { 39 | 40 | public MoveTrackCmd(Bot bot) { 41 | super(bot); 42 | this.name = "movetrack"; 43 | this.help = "再生待ちの曲の再生順を変更します"; 44 | this.arguments = " "; 45 | this.aliases = bot.getConfig().getAliases(this.name); 46 | this.bePlaying = true; 47 | 48 | List options = new ArrayList<>(); 49 | options.add(new OptionData(OptionType.INTEGER, "from", "from", true)); 50 | options.add(new OptionData(OptionType.INTEGER, "to", "to", true)); 51 | this.options = options; 52 | 53 | } 54 | 55 | private static boolean isUnavailablePosition(FairQueue queue, int position) { 56 | return (position < 1 || position > queue.size()); 57 | } 58 | 59 | @Override 60 | public void doCommand(CommandEvent event) { 61 | Logger log = LoggerFactory.getLogger("MoveTrack"); 62 | int from; 63 | int to; 64 | 65 | String[] parts = event.getArgs().split("\\s+", 2); 66 | if (parts.length < 2) { 67 | event.replyError("2つの有効な数字を含んでください。"); 68 | return; 69 | } 70 | 71 | try { 72 | // Validate the args 73 | from = Integer.parseInt(parts[0]); 74 | to = Integer.parseInt(parts[1]); 75 | } catch (NumberFormatException e) { 76 | event.replyError("2つの有効な数字を含んでください。"); 77 | return; 78 | } 79 | 80 | if (from == to) { 81 | event.replyError("同じ位置に移動することはできません。"); 82 | return; 83 | } 84 | 85 | // Validate that from and to are available 86 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 87 | FairQueue queue = handler.getQueue(); 88 | if (isUnavailablePosition(queue, from)) { 89 | String reply = String.format("`%d` は再生待ちに存在しない位置です。", from); 90 | event.replyError(reply); 91 | return; 92 | } 93 | if (isUnavailablePosition(queue, to)) { 94 | String reply = String.format("`%d` 再生待ちに存在しない位置です。", to); 95 | event.replyError(reply); 96 | return; 97 | } 98 | 99 | // Move the track 100 | QueuedTrack track = queue.moveItem(from - 1, to - 1); 101 | String trackTitle = track.getTrack().getInfo().title; 102 | String reply = String.format("**%s** を `%d` から `%d`に移動しました。", trackTitle, from, to); 103 | log.info(event.getGuild().getName() + "で %s を %d から %d に移動しました。", trackTitle, from, to); 104 | event.replySuccess(reply); 105 | } 106 | 107 | @Override 108 | public void doCommand(SlashCommandEvent event) { 109 | if (!checkDJPermission(event.getClient(), event)) { 110 | event.reply(event.getClient().getWarning() + "権限がないため実行できません。").queue(); 111 | return; 112 | } 113 | int from; 114 | int to; 115 | 116 | from = Integer.parseInt(event.getOption("from").getAsString()); 117 | to = Integer.parseInt(event.getOption("to").getAsString()); 118 | 119 | if (from == to) { 120 | event.reply(event.getClient().getError() + "同じ位置に移動することはできません。").queue(); 121 | return; 122 | } 123 | 124 | // Validate that from and to are available 125 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 126 | FairQueue queue = handler.getQueue(); 127 | if (isUnavailablePosition(queue, from)) { 128 | String reply = String.format("`%d` は再生待ちに存在しない位置です。", from); 129 | event.reply(event.getClient().getError() + reply).queue(); 130 | return; 131 | } 132 | if (isUnavailablePosition(queue, to)) { 133 | String reply = String.format("`%d` 再生待ちに存在しない位置です。", to); 134 | event.reply(event.getClient().getError() + reply).queue(); 135 | return; 136 | } 137 | 138 | // Move the track 139 | QueuedTrack track = queue.moveItem(from - 1, to - 1); 140 | String trackTitle = track.getTrack().getInfo().title; 141 | String reply = String.format("**%s** を `%d` から `%d`に移動しました。", trackTitle, from, to); 142 | event.reply(event.getClient().getSuccess() + reply).queue(); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/dj/NextCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Cosgy Dev (info@cosgy.dev). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dev.cosgy.jmusicbot.slashcommands.dj; 18 | 19 | import com.jagrosh.jdautilities.command.CommandEvent; 20 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 21 | import com.jagrosh.jmusicbot.Bot; 22 | import com.jagrosh.jmusicbot.audio.AudioHandler; 23 | import com.sedmelluq.discord.lavaplayer.track.AudioTrack; 24 | import dev.cosgy.jmusicbot.slashcommands.DJCommand; 25 | import net.dv8tion.jda.api.entities.User; 26 | 27 | public class NextCmd extends DJCommand { 28 | public NextCmd(Bot bot) { 29 | super(bot); 30 | this.name = "next"; 31 | this.help = "リピートモードが有効な場合、再生待ちから削除せずに現在の曲をスキップします"; 32 | this.aliases = bot.getConfig().getAliases(this.name); 33 | this.bePlaying = true; 34 | } 35 | 36 | @Override 37 | public void doCommand(CommandEvent event) { 38 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 39 | User u = event.getJDA().getUserById(handler.getRequestMetadata().user.id); 40 | 41 | AudioTrack track = handler.getPlayer().getPlayingTrack(); 42 | handler.addTrackIfRepeat(track); 43 | 44 | event.reply(event.getClient().getSuccess() + " **" + (handler.getPlayer().getPlayingTrack().getInfo().uri.contains("https://stream.gensokyoradio.net/") ? "幻想郷ラジオ" : handler.getPlayer().getPlayingTrack().getInfo().title) 45 | + "**をスキップしました。 (" + (u == null ? "誰か" : "**" + u.getName() + "**") + "がリクエストしました。)"); 46 | handler.getPlayer().stopTrack(); 47 | } 48 | 49 | @Override 50 | public void doCommand(SlashCommandEvent event) { 51 | if (!checkDJPermission(event.getClient(), event)) { 52 | event.reply(event.getClient().getWarning() + "権限がないため実行できません。").queue(); 53 | return; 54 | } 55 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 56 | User u = event.getJDA().getUserById(handler.getRequestMetadata().user.id); 57 | 58 | AudioTrack track = handler.getPlayer().getPlayingTrack(); 59 | handler.addTrackIfRepeat(track); 60 | 61 | event.reply(event.getClient().getSuccess() + " **" + (handler.getPlayer().getPlayingTrack().getInfo().uri.contains("https://stream.gensokyoradio.net/") ? "幻想郷ラジオ" : handler.getPlayer().getPlayingTrack().getInfo().title) + 62 | handler.getPlayer().getPlayingTrack().getInfo().title 63 | + "**をスキップしました。 (" + (u == null ? "誰か" : "**" + u.getName() + "**") + "がリクエストしました。)").queue(); 64 | handler.getPlayer().stopTrack(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/dj/PauseCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.dj; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 20 | import com.jagrosh.jmusicbot.Bot; 21 | import com.jagrosh.jmusicbot.PlayStatus; 22 | import com.jagrosh.jmusicbot.audio.AudioHandler; 23 | import dev.cosgy.jmusicbot.slashcommands.DJCommand; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | /** 28 | * @author John Grosh 29 | */ 30 | public class PauseCmd extends DJCommand { 31 | Logger log = LoggerFactory.getLogger("Pause"); 32 | 33 | public PauseCmd(Bot bot) { 34 | super(bot); 35 | this.name = "pause"; 36 | this.help = "現在の曲を一時停止します"; 37 | this.aliases = bot.getConfig().getAliases(this.name); 38 | this.bePlaying = true; 39 | } 40 | 41 | @Override 42 | public void doCommand(CommandEvent event) { 43 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 44 | if (handler.getPlayer().isPaused()) { 45 | event.replyWarning("曲はすでに一時停止しています。 `" + event.getClient().getPrefix() + " play` を使用して一時停止を解除する事ができます。"); 46 | return; 47 | } 48 | handler.getPlayer().setPaused(true); 49 | log.info(event.getGuild().getName() + "で" + handler.getPlayer().getPlayingTrack().getInfo().title + "を一時停止しました。"); 50 | event.replySuccess("**" + handler.getPlayer().getPlayingTrack().getInfo().title + "**を一時停止にしました。 `" + event.getClient().getPrefix() + " play` を使用すると一時停止を解除できます。"); 51 | 52 | Bot.updatePlayStatus(event.getGuild(), event.getGuild().getSelfMember(), PlayStatus.PAUSED); 53 | } 54 | 55 | @Override 56 | public void doCommand(SlashCommandEvent event) { 57 | if (!checkDJPermission(event.getClient(), event)) { 58 | event.reply(event.getClient().getWarning() + "権限がないため実行できません。").queue(); 59 | return; 60 | } 61 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 62 | if (handler.getPlayer().isPaused()) { 63 | event.reply(event.getClient().getWarning() + "曲はすでに一時停止しています。 `" + event.getClient().getPrefix() + " play` を使用して一時停止を解除する事ができます。").queue(); 64 | return; 65 | } 66 | handler.getPlayer().setPaused(true); 67 | log.info(event.getGuild().getName() + "で" + handler.getPlayer().getPlayingTrack().getInfo().title + "を一時停止しました。"); 68 | event.reply(event.getClient().getSuccess() + "**" + handler.getPlayer().getPlayingTrack().getInfo().title + "**を一時停止にしました。 `" + event.getClient().getPrefix() + " play` を使用すると一時停止を解除できます。").queue(); 69 | 70 | Bot.updatePlayStatus(event.getGuild(), event.getGuild().getSelfMember(), PlayStatus.PAUSED); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/dj/SkipToCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 John Grosh . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.dj; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 20 | import com.jagrosh.jmusicbot.Bot; 21 | import com.jagrosh.jmusicbot.audio.AudioHandler; 22 | import dev.cosgy.jmusicbot.slashcommands.DJCommand; 23 | import net.dv8tion.jda.api.interactions.commands.OptionType; 24 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | import java.util.ArrayList; 29 | import java.util.List; 30 | 31 | /** 32 | * @author John Grosh 33 | */ 34 | public class SkipToCmd extends DJCommand { 35 | Logger log = LoggerFactory.getLogger("Skip"); 36 | 37 | public SkipToCmd(Bot bot) { 38 | super(bot); 39 | this.name = "skipto"; 40 | this.help = "指定された曲にスキップします"; 41 | this.arguments = ""; 42 | this.aliases = bot.getConfig().getAliases(this.name); 43 | this.bePlaying = true; 44 | 45 | List options = new ArrayList<>(); 46 | options.add(new OptionData(OptionType.INTEGER, "position", "position", true)); 47 | this.options = options; 48 | 49 | } 50 | 51 | @Override 52 | public void doCommand(CommandEvent event) { 53 | int index = 0; 54 | try { 55 | index = Integer.parseInt(event.getArgs()); 56 | } catch (NumberFormatException e) { 57 | event.reply(event.getClient().getError() + " `" + event.getArgs() + "` は有効な整数ではありません。"); 58 | return; 59 | } 60 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 61 | if (index < 1 || index > handler.getQueue().size()) { 62 | event.reply(event.getClient().getError() + " 1から" + handler.getQueue().size() + "の間の整数でないといけません!"); 63 | return; 64 | } 65 | handler.getQueue().skip(index - 1); 66 | event.reply(event.getClient().getSuccess() + " **" + handler.getQueue().get(0).getTrack().getInfo().title + "にスキップしました。**"); 67 | handler.getPlayer().stopTrack(); 68 | } 69 | 70 | @Override 71 | public void doCommand(SlashCommandEvent event) { 72 | if (!checkDJPermission(event.getClient(), event)) { 73 | event.reply(event.getClient().getWarning() + "権限がないため実行できません。").queue(); 74 | return; 75 | } 76 | int index = 0; 77 | try { 78 | index = Integer.parseInt(event.getOption("position").getAsString()); 79 | } catch (NumberFormatException e) { 80 | event.reply(event.getClient().getError() + " `" + event.getOption("position").getAsString() + "` は有効な整数ではありません。").queue(); 81 | return; 82 | } 83 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 84 | if (index < 1 || index > handler.getQueue().size()) { 85 | event.reply(event.getClient().getError() + " 1から" + handler.getQueue().size() + "の間の整数でないといけません!").queue(); 86 | return; 87 | } 88 | handler.getQueue().skip(index - 1); 89 | event.reply(event.getClient().getSuccess() + " **" + handler.getQueue().get(0).getTrack().getInfo().title + "にスキップしました。**").queue(); 90 | handler.getPlayer().stopTrack(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/dj/StopCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.dj; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 20 | import com.jagrosh.jmusicbot.Bot; 21 | import com.jagrosh.jmusicbot.audio.AudioHandler; 22 | import com.jagrosh.jmusicbot.audio.QueuedTrack; 23 | import com.jagrosh.jmusicbot.queue.FairQueue; 24 | import dev.cosgy.jmusicbot.playlist.CacheLoader; 25 | import dev.cosgy.jmusicbot.slashcommands.DJCommand; 26 | import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; 27 | import net.dv8tion.jda.api.interactions.commands.Command; 28 | import net.dv8tion.jda.api.interactions.commands.OptionType; 29 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 30 | import org.slf4j.Logger; 31 | import org.slf4j.LoggerFactory; 32 | 33 | import java.util.ArrayList; 34 | import java.util.List; 35 | import java.util.stream.Collectors; 36 | import java.util.stream.Stream; 37 | 38 | /** 39 | * @author John Grosh 40 | */ 41 | public class StopCmd extends DJCommand { 42 | Logger log = LoggerFactory.getLogger("Stop"); 43 | 44 | public StopCmd(Bot bot) { 45 | super(bot); 46 | this.name = "stop"; 47 | this.help = "現在の曲を停止して再生待ちを削除します。"; 48 | this.aliases = bot.getConfig().getAliases(this.name); 49 | this.bePlaying = false; 50 | 51 | List options = new ArrayList<>(); 52 | options.add(new OptionData(OptionType.STRING, "option", "再生リストを保存する場合は`save`を入力", false)); 53 | 54 | this.options = options; 55 | } 56 | 57 | @Override 58 | public void doCommand(CommandEvent event) { 59 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 60 | CacheLoader cache = bot.getCacheLoader(); 61 | FairQueue queue = handler.getQueue(); 62 | 63 | if (queue.size() > 0 && event.getArgs().matches("save")) { 64 | cache.Save(event.getGuild().getId(), handler.getQueue()); 65 | event.reply(event.getClient().getSuccess() + " 再生待ちの" + queue.size() + "曲を保存して再生を停止しました。"); 66 | log.info(event.getGuild().getName() + "で再生待ちを保存して,ボイスチャンネルから切断しました。"); 67 | } else { 68 | event.reply(event.getClient().getSuccess() + " 再生待ちを削除して、再生を停止しました。"); 69 | } 70 | handler.stopAndClear(); 71 | event.getGuild().getAudioManager().closeAudioConnection(); 72 | } 73 | 74 | @Override 75 | public void doCommand(SlashCommandEvent event) { 76 | if (!checkDJPermission(event.getClient(), event)) { 77 | event.reply(event.getClient().getWarning() + "権限がないため実行できません。").queue(); 78 | return; 79 | } 80 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 81 | CacheLoader cache = bot.getCacheLoader(); 82 | FairQueue queue = handler.getQueue(); 83 | 84 | log.debug("再生待ちのサイズ:" + queue.size()); 85 | 86 | if (event.getOption("option") == null) { 87 | event.reply(event.getClient().getSuccess() + " 再生待ちを削除して、再生を停止しました。").queue(); 88 | log.info(event.getGuild().getName() + "で再生待ちを削除して,ボイスチャンネルから切断しました。"); 89 | handler.stopAndClear(); 90 | event.getGuild().getAudioManager().closeAudioConnection(); 91 | return; 92 | } 93 | 94 | if (queue.size() > 0 && event.getOption("option").getAsString().equals("save")) { 95 | cache.Save(event.getGuild().getId(), handler.getQueue()); 96 | event.reply(event.getClient().getSuccess() + " 再生待ちの" + queue.size() + "曲を保存して再生を停止しました。").queue(); 97 | log.info(event.getGuild().getName() + "で再生待ちを保存して,ボイスチャンネルから切断しました。"); 98 | } else { 99 | event.reply(event.getClient().getSuccess() + " 再生待ちを削除して、再生を停止しました。").queue(); 100 | log.info(event.getGuild().getName() + "で再生待ちを削除して,ボイスチャンネルから切断しました。"); 101 | } 102 | handler.stopAndClear(); 103 | event.getGuild().getAudioManager().closeAudioConnection(); 104 | } 105 | 106 | @Override 107 | public void onAutoComplete(CommandAutoCompleteInteractionEvent event) { 108 | String[] cmdOptions = {"save"}; 109 | if (event.getName().equals("stop") && event.getFocusedOption().getName().equals("option")) { 110 | List options = Stream.of(cmdOptions) 111 | .filter(word -> word.startsWith(event.getFocusedOption().getValue())) // only display words that start with the user's current input 112 | .map(word -> new Command.Choice(word, word)) // map the words to choices 113 | .collect(Collectors.toList()); 114 | event.replyChoices(options).queue(); 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/general/HelpCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Cosgy Dev (info@cosgy.dev). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dev.cosgy.jmusicbot.slashcommands.general; 18 | 19 | import com.jagrosh.jdautilities.command.Command; 20 | import com.jagrosh.jdautilities.command.CommandEvent; 21 | import com.jagrosh.jdautilities.command.SlashCommand; 22 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 23 | import com.jagrosh.jmusicbot.Bot; 24 | import net.dv8tion.jda.api.entities.channel.ChannelType; 25 | 26 | import java.util.List; 27 | import java.util.Objects; 28 | 29 | public class HelpCmd extends SlashCommand { 30 | public Bot bot; 31 | 32 | public HelpCmd(Bot bot) { 33 | this.bot = bot; 34 | this.name = "help"; 35 | this.help = "コマンド一覧を表示します。"; 36 | this.aliases = bot.getConfig().getAliases(this.name); 37 | } 38 | 39 | @Override 40 | protected void execute(SlashCommandEvent event) { 41 | StringBuilder builder = new StringBuilder("**" + event.getJDA().getSelfUser().getName() + "** コマンド一覧:\n"); 42 | Category category = null; 43 | List commands = event.getClient().getCommands(); 44 | for (Command command : commands) { 45 | if (!command.isHidden() && (!command.isOwnerCommand() || event.getMember().isOwner())) { 46 | if (!Objects.equals(category, command.getCategory())) { 47 | category = command.getCategory(); 48 | builder.append("\n\n __").append(category == null ? "カテゴリなし" : category.getName()).append("__:\n"); 49 | } 50 | builder.append("\n`").append(event.getClient().getTextualPrefix()).append(event.getClient().getPrefix() == null ? " " : "").append(command.getName()) 51 | .append(command.getArguments() == null ? "`" : " " + command.getArguments() + "`") 52 | .append(" - ").append(command.getHelp()); 53 | } 54 | } 55 | if (event.getClient().getServerInvite() != null) 56 | builder.append("\n\nさらにヘルプが必要な場合は、公式サーバーに参加することもできます: ").append(event.getClient().getServerInvite()); 57 | 58 | event.reply(builder.toString()).queue(); 59 | 60 | /*event.reply(builder.toString(), unused -> 61 | { 62 | if (event.isFromType(ChannelType.TEXT)) 63 | event.reactSuccess(); 64 | }, t -> event.replyWarning("ダイレクトメッセージをブロックしているため、ヘルプを送信できません。")); 65 | */ 66 | } 67 | 68 | public void execute(CommandEvent event) { 69 | StringBuilder builder = new StringBuilder("**" + event.getJDA().getSelfUser().getName() + "** コマンド一覧:\n"); 70 | Category category = null; 71 | List commands = event.getClient().getCommands(); 72 | for (Command command : commands) { 73 | if (!command.isHidden() && (!command.isOwnerCommand() || event.isOwner())) { 74 | if (!Objects.equals(category, command.getCategory())) { 75 | category = command.getCategory(); 76 | builder.append("\n\n __").append(category == null ? "カテゴリなし" : category.getName()).append("__:\n"); 77 | } 78 | builder.append("\n`").append(event.getClient().getTextualPrefix()).append(event.getClient().getPrefix() == null ? " " : "").append(command.getName()) 79 | .append(command.getArguments() == null ? "`" : " " + command.getArguments() + "`") 80 | .append(" - ").append(command.getHelp()); 81 | } 82 | } 83 | if (event.getClient().getServerInvite() != null) 84 | builder.append("\n\nさらにヘルプが必要な場合は、公式サーバーに参加することもできます: ").append(event.getClient().getServerInvite()); 85 | 86 | if (bot.getConfig().getHelpToDm()) { 87 | event.replyInDm(builder.toString(), unused -> 88 | { 89 | if (event.isFromType(ChannelType.TEXT)) 90 | event.reactSuccess(); 91 | }, t -> event.replyWarning("ダイレクトメッセージをブロックしているため、ヘルプを送信できません。")); 92 | } else { 93 | event.reply(builder.toString()); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/general/InviteCommand.java: -------------------------------------------------------------------------------- 1 | package dev.cosgy.jmusicbot.slashcommands.general; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | import com.jagrosh.jdautilities.command.SlashCommand; 5 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 6 | import net.dv8tion.jda.api.Permission; 7 | 8 | public class InviteCommand extends SlashCommand { 9 | public InviteCommand() { 10 | this.name = "invite"; 11 | this.help = "Botの招待用URLを表示します。"; 12 | this.guildOnly = false; 13 | this.aliases = new String[]{"share"}; 14 | } 15 | 16 | @Override 17 | protected void execute(SlashCommandEvent event) { 18 | long botId = event.getJDA().getSelfUser().getIdLong(); 19 | Permission[] permissions = new Permission[] 20 | { 21 | Permission.MANAGE_CHANNEL, 22 | Permission.MANAGE_ROLES, 23 | Permission.MESSAGE_MANAGE, 24 | Permission.NICKNAME_CHANGE, 25 | Permission.MESSAGE_SEND, 26 | Permission.VOICE_CONNECT, 27 | Permission.VOICE_SPEAK, 28 | Permission.VIEW_CHANNEL, 29 | Permission.MESSAGE_EXT_EMOJI 30 | }; 31 | 32 | event.reply(String.format("https://discord.com/oauth2/authorize?client_id=%s&scope=bot%20applications.commands&permissions=%s", botId, Permission.getRaw(permissions))).queue(); 33 | } 34 | 35 | @Override 36 | protected void execute(CommandEvent event) { 37 | long botId = event.getSelfUser().getIdLong(); 38 | Permission[] permissions = new Permission[] 39 | { 40 | Permission.MANAGE_CHANNEL, 41 | Permission.MANAGE_ROLES, 42 | Permission.MESSAGE_MANAGE, 43 | Permission.NICKNAME_CHANGE, 44 | Permission.MESSAGE_SEND, 45 | Permission.VOICE_CONNECT, 46 | Permission.VOICE_SPEAK, 47 | Permission.VIEW_CHANNEL, 48 | Permission.MESSAGE_EXT_EMOJI 49 | }; 50 | 51 | event.replyFormatted("https://discord.com/oauth2/authorize?client_id=%s&scope=bot&permissions=%s", botId, Permission.getRaw(permissions)); 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/general/PingCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.general; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommand; 20 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 21 | import com.jagrosh.jdautilities.doc.standard.CommandInfo; 22 | import com.jagrosh.jdautilities.examples.doc.Author; 23 | 24 | import java.time.temporal.ChronoUnit; 25 | 26 | /** 27 | * @author John Grosh (jagrosh) 28 | */ 29 | @CommandInfo( 30 | name = {"Ping", "Pong"}, 31 | description = "ボットのレイテンシを確認します" 32 | ) 33 | @Author("John Grosh (jagrosh)") 34 | public class PingCommand extends SlashCommand { 35 | 36 | public PingCommand() { 37 | this.name = "ping"; 38 | this.help = "ボットのレイテンシをチェックします"; 39 | this.guildOnly = false; 40 | this.aliases = new String[]{"pong"}; 41 | } 42 | 43 | @Override 44 | protected void execute(SlashCommandEvent event) { 45 | event.reply("Ping: ...").queue(m -> { 46 | m.editOriginal("Websocket: " + event.getJDA().getGatewayPing() + "ms").queue(); 47 | }); 48 | } 49 | 50 | @Override 51 | protected void execute(CommandEvent event) { 52 | event.reply("Ping: ...", m -> { 53 | long ping = event.getMessage().getTimeCreated().until(m.getTimeCreated(), ChronoUnit.MILLIS); 54 | m.editMessage("Ping: " + ping + "ms | Websocket: " + event.getJDA().getGatewayPing() + "ms").queue(); 55 | }); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/general/SettingsCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.general; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommand; 20 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 21 | import com.jagrosh.jmusicbot.Bot; 22 | import com.jagrosh.jmusicbot.settings.Settings; 23 | import com.jagrosh.jmusicbot.utils.FormatUtil; 24 | import dev.cosgy.jmusicbot.settings.RepeatMode; 25 | import net.dv8tion.jda.api.EmbedBuilder; 26 | import net.dv8tion.jda.api.entities.Role; 27 | import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; 28 | import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; 29 | import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; 30 | 31 | import java.util.Objects; 32 | 33 | /** 34 | * @author John Grosh 35 | */ 36 | public class SettingsCmd extends SlashCommand { 37 | private final static String EMOJI = "\uD83C\uDFA7"; // 🎧 38 | 39 | public SettingsCmd(Bot bot) { 40 | this.name = "settings"; 41 | this.help = "Botの設定を表示します"; 42 | this.aliases = bot.getConfig().getAliases(this.name); 43 | this.guildOnly = true; 44 | } 45 | 46 | @Override 47 | protected void execute(SlashCommandEvent event) { 48 | Settings s = event.getClient().getSettingsFor(event.getGuild()); 49 | MessageCreateBuilder builder = new MessageCreateBuilder() 50 | .addContent(EMOJI + " **") 51 | .addContent(FormatUtil.filter(event.getJDA().getSelfUser().getName())) 52 | .addContent("** の設定:"); 53 | TextChannel tChan = s.getTextChannel(event.getGuild()); 54 | VoiceChannel vChan = s.getVoiceChannel(event.getGuild()); 55 | Role role = s.getRole(event.getGuild()); 56 | EmbedBuilder ebuilder = new EmbedBuilder() 57 | .setDescription("コマンド実行用チャンネル: " + (tChan == null ? "なし" : "**#" + tChan.getName() + "**") 58 | + "\n専用ボイスチャンネル: " + (vChan == null ? "なし" : "**" + vChan.getAsMention() + "**") 59 | + "\nDJ 権限: " + (role == null ? "未設定" : "**" + role.getName() + "**") 60 | + "\nリピート: **" + (s.getRepeatMode() == RepeatMode.ALL ? "有効(全曲リピート)" : (s.getRepeatMode() == RepeatMode.SINGLE ? "有効(1曲リピート)" : "無効")) + "**" 61 | + "\n音量:**" + (s.getVolume()) + "**" 62 | + "\n再生待ち追加モード: **" + (s.isForceToEndQue() ? "通常モード" : "フェアモード") + "**" 63 | + "\nデフォルトプレイリスト: " + (s.getDefaultPlaylist() == null ? "なし" : "**" + s.getDefaultPlaylist() + "**") 64 | ) 65 | .setFooter(String.format( 66 | "%s 個のサーバーに参加 | %s 個のボイスチャンネルに接続", 67 | event.getJDA().getGuilds().size(), 68 | event.getJDA().getGuilds().stream().filter(g -> Objects.requireNonNull(g.getSelfMember().getVoiceState()).inAudioChannel()).count()), 69 | null); 70 | event.reply(builder.addEmbeds(ebuilder.build()).build()).queue(); 71 | } 72 | 73 | @Override 74 | protected void execute(CommandEvent event) { 75 | Settings s = event.getClient().getSettingsFor(event.getGuild()); 76 | MessageCreateBuilder builder = new MessageCreateBuilder() 77 | .addContent(EMOJI + " **") 78 | .addContent(FormatUtil.filter(event.getSelfUser().getName())) 79 | .addContent("** の設定:"); 80 | TextChannel tChan = s.getTextChannel(event.getGuild()); 81 | VoiceChannel vChan = s.getVoiceChannel(event.getGuild()); 82 | Role role = s.getRole(event.getGuild()); 83 | EmbedBuilder ebuilder = new EmbedBuilder() 84 | .setColor(event.getSelfMember().getColor()) 85 | .setDescription("コマンド実行用チャンネル: " + (tChan == null ? "なし" : "**#" + tChan.getName() + "**") 86 | + "\n専用ボイスチャンネル: " + (vChan == null ? "なし" : "**" + vChan.getName() + "**") 87 | + "\nDJ 権限: " + (role == null ? "未設定" : "**" + role.getName() + "**") 88 | + "\nリピート: **" + (s.getRepeatMode() == RepeatMode.ALL ? "有効(全曲リピート)" : (s.getRepeatMode() == RepeatMode.SINGLE ? "有効(1曲リピート)" : "無効")) + "**" 89 | + "\n再生待ち追加モード: **" + (s.isForceToEndQue() ? "通常モード" : "フェアモード") + "**" 90 | + "\nデフォルトプレイリスト: " + (s.getDefaultPlaylist() == null ? "なし" : "**" + s.getDefaultPlaylist() + "**") 91 | ) 92 | .setFooter(String.format( 93 | "%s 個のサーバーに参加 | %s 個のボイスチャンネルに接続", 94 | event.getJDA().getGuilds().size(), 95 | event.getJDA().getGuilds().stream().filter(g -> Objects.requireNonNull(g.getSelfMember().getVoiceState()).inAudioChannel()).count()), 96 | null); 97 | event.getChannel().sendMessage(builder.addEmbeds(ebuilder.build()).build()).queue(); 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/listeners/CommandAudit.java: -------------------------------------------------------------------------------- 1 | package dev.cosgy.jmusicbot.slashcommands.listeners; 2 | 3 | import com.jagrosh.jdautilities.command.Command; 4 | import com.jagrosh.jdautilities.command.CommandEvent; 5 | import com.jagrosh.jdautilities.command.CommandListener; 6 | import com.jagrosh.jmusicbot.JMusicBot; 7 | import dev.cosgy.jmusicbot.util.LastSendTextChannel; 8 | import net.dv8tion.jda.api.entities.channel.ChannelType; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | public class CommandAudit implements CommandListener { 13 | /** 14 | * Called when a {@link Command Command} is triggered 15 | * by a {@link CommandEvent CommandEvent}. 16 | * 17 | * @param event The CommandEvent that triggered the Command 18 | * @param command 実行されたコマンドオブジェクト 19 | */ 20 | @Override 21 | public void onCommand(CommandEvent event, Command command) { 22 | if (JMusicBot.COMMAND_AUDIT_ENABLED) { 23 | Logger logger = LoggerFactory.getLogger("CommandAudit"); 24 | String textFormat = event.isFromType(ChannelType.PRIVATE) ? "%s%s で %s#%s (%s) がコマンド %s を実行しました" : "%s の #%s で %s#%s (%s) がコマンド %s を実行しました"; 25 | 26 | logger.info(String.format(textFormat, 27 | event.isFromType(ChannelType.PRIVATE) ? "DM" : event.getGuild().getName(), 28 | event.isFromType(ChannelType.PRIVATE) ? "" : event.getTextChannel().getName(), 29 | event.getAuthor().getName(), event.getAuthor().getDiscriminator(), event.getAuthor().getId(), 30 | event.getMessage().getContentDisplay())); 31 | } 32 | 33 | LastSendTextChannel.SetLastTextId(event); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/music/NowplayingCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.music; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 20 | import com.jagrosh.jmusicbot.Bot; 21 | import com.jagrosh.jmusicbot.audio.AudioHandler; 22 | import dev.cosgy.jmusicbot.slashcommands.MusicCommand; 23 | import net.dv8tion.jda.api.Permission; 24 | import net.dv8tion.jda.api.utils.messages.MessageCreateData; 25 | 26 | /** 27 | * @author John Grosh 28 | */ 29 | public class NowplayingCmd extends MusicCommand { 30 | public NowplayingCmd(Bot bot) { 31 | super(bot); 32 | this.name = "nowplaying"; 33 | this.help = "現在再生中の曲を表示します"; 34 | this.aliases = bot.getConfig().getAliases(this.name); 35 | this.botPermissions = new Permission[]{Permission.MESSAGE_EMBED_LINKS}; 36 | } 37 | 38 | @Override 39 | public void doCommand(CommandEvent event) { 40 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 41 | MessageCreateData m = null; 42 | try { 43 | m = handler.getNowPlaying(event.getJDA()); 44 | } catch (Exception e) { 45 | throw new RuntimeException(e); 46 | } 47 | if (m == null) { 48 | event.reply(handler.getNoMusicPlaying(event.getJDA())); 49 | bot.getNowplayingHandler().clearLastNPMessage(event.getGuild()); 50 | } else { 51 | event.reply(m, bot.getNowplayingHandler()::setLastNPMessage); 52 | } 53 | } 54 | 55 | @Override 56 | public void doCommand(SlashCommandEvent event) { 57 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 58 | MessageCreateData m = null; 59 | try { 60 | m = handler.getNowPlaying(event.getJDA()); 61 | } catch (Exception e) { 62 | throw new RuntimeException(e); 63 | } 64 | event.reply("現在再生中の楽曲を表示します...").queue(h -> h.deleteOriginal().queue()); 65 | 66 | if (m == null) { 67 | event.getTextChannel().sendMessage(handler.getNoMusicPlaying(event.getJDA())).queue(); 68 | bot.getNowplayingHandler().clearLastNPMessage(event.getGuild()); 69 | } else { 70 | event.getTextChannel().sendMessage(m).queue(bot.getNowplayingHandler()::setLastNPMessage); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/music/SCSearchCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.music; 17 | 18 | import com.jagrosh.jmusicbot.Bot; 19 | 20 | /** 21 | * @author John Grosh 22 | */ 23 | public class SCSearchCmd extends SearchCmd { 24 | public SCSearchCmd(Bot bot) { 25 | super(bot); 26 | this.searchPrefix = "scsearch:"; 27 | this.name = "scsearch"; 28 | this.help = "指定した文字列を使用してSoundcloudで検索します"; 29 | this.aliases = bot.getConfig().getAliases(this.name); 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/music/ShuffleCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.music; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 20 | import com.jagrosh.jmusicbot.Bot; 21 | import com.jagrosh.jmusicbot.audio.AudioHandler; 22 | import dev.cosgy.jmusicbot.slashcommands.MusicCommand; 23 | 24 | /** 25 | * @author John Grosh 26 | */ 27 | public class ShuffleCmd extends MusicCommand { 28 | public ShuffleCmd(Bot bot) { 29 | super(bot); 30 | this.name = "shuffle"; 31 | this.help = "追加した曲をシャッフル"; 32 | this.aliases = bot.getConfig().getAliases(this.name); 33 | this.beListening = true; 34 | this.bePlaying = true; 35 | } 36 | 37 | @Override 38 | public void doCommand(CommandEvent event) { 39 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 40 | int s = handler.getQueue().shuffle(event.getAuthor().getIdLong()); 41 | switch (s) { 42 | case 0: 43 | event.replyError("再生待ちに曲がありません!"); 44 | break; 45 | case 1: 46 | event.replyWarning("再生待ちには現在1曲しかありません!"); 47 | break; 48 | default: 49 | event.replySuccess("" + s + "曲をシャッフルしました。"); 50 | break; 51 | } 52 | } 53 | 54 | @Override 55 | public void doCommand(SlashCommandEvent event) { 56 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 57 | int s = handler.getQueue().shuffle(event.getUser().getIdLong()); 58 | switch (s) { 59 | case 0: 60 | event.reply(event.getClient().getError() + "再生待ちに曲がありません!").queue(); 61 | break; 62 | case 1: 63 | event.reply(event.getClient().getWarning() + "再生待ちには現在1曲しかありません!").queue(); 64 | break; 65 | default: 66 | event.reply(event.getClient().getSuccess() + "" + s + "曲をシャッフルしました。").queue(); 67 | break; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/music/VolumeCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.music; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 20 | import com.jagrosh.jmusicbot.Bot; 21 | import com.jagrosh.jmusicbot.audio.AudioHandler; 22 | import com.jagrosh.jmusicbot.settings.Settings; 23 | import com.jagrosh.jmusicbot.utils.FormatUtil; 24 | import dev.cosgy.jmusicbot.slashcommands.MusicCommand; 25 | import net.dv8tion.jda.api.interactions.commands.OptionType; 26 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 27 | import org.slf4j.Logger; 28 | import org.slf4j.LoggerFactory; 29 | 30 | import java.util.ArrayList; 31 | import java.util.List; 32 | import java.util.Objects; 33 | 34 | public class VolumeCmd extends MusicCommand { 35 | Logger log = LoggerFactory.getLogger("Volume"); 36 | 37 | public VolumeCmd(Bot bot) { 38 | super(bot); 39 | this.name = "volume"; 40 | this.aliases = new String[]{"vol"}; 41 | this.help = "音量を設定または表示します"; 42 | this.aliases = bot.getConfig().getAliases(this.name); 43 | this.arguments = "[0-150]"; 44 | 45 | List options = new ArrayList<>(); 46 | options.add(new OptionData(OptionType.INTEGER, "vol", "音量は0から150までの整数", true)); 47 | this.options = options; 48 | } 49 | 50 | @Override 51 | public void doCommand(CommandEvent event) { 52 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 53 | Settings settings = event.getClient().getSettingsFor(event.getGuild()); 54 | int volume = Objects.requireNonNull(handler).getPlayer().getVolume(); 55 | if (event.getArgs().isEmpty()) { 56 | event.reply(FormatUtil.volumeIcon(volume) + " 現在の音量は`" + volume + "`です。"); 57 | } else { 58 | int nvolume; 59 | try { 60 | nvolume = Integer.parseInt(event.getArgs()); 61 | } catch (NumberFormatException e) { 62 | nvolume = -1; 63 | } 64 | if (nvolume < 0 || nvolume > 150) 65 | event.reply(event.getClient().getError() + " 音量は0から150までの整数でないといけません。"); 66 | else { 67 | handler.getPlayer().setVolume(nvolume); 68 | settings.setVolume(nvolume); 69 | event.reply(FormatUtil.volumeIcon(nvolume) + " 音量を`" + volume + "`から`" + nvolume + "`に変更しました。"); 70 | log.info(event.getGuild().getName() + "での音量が" + volume + "から" + nvolume + "に変更されました。"); 71 | } 72 | } 73 | } 74 | 75 | @Override 76 | public void doCommand(SlashCommandEvent event) { 77 | 78 | AudioHandler handler = (AudioHandler) event.getGuild().getAudioManager().getSendingHandler(); 79 | Settings settings = event.getClient().getSettingsFor(event.getGuild()); 80 | int volume = handler.getPlayer().getVolume(); 81 | int nvolume; 82 | try { 83 | nvolume = Integer.parseInt(event.getOption("vol").getAsString()); 84 | } catch (NumberFormatException e) { 85 | nvolume = -1; 86 | } 87 | if (nvolume < 0 || nvolume > 150) 88 | event.reply(event.getClient().getError() + " 音量は0から150までの整数でないといけません。").queue(); 89 | else { 90 | handler.getPlayer().setVolume(nvolume); 91 | settings.setVolume(nvolume); 92 | event.reply(FormatUtil.volumeIcon(nvolume) + " 音量を`" + volume + "`から`" + nvolume + "`に変更しました。").queue(); 93 | log.info(event.getGuild().getName() + "での音量が" + volume + "から" + nvolume + "に変更されました。"); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/owner/EvalCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.owner; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 20 | import com.jagrosh.jmusicbot.Bot; 21 | import dev.cosgy.jmusicbot.slashcommands.OwnerCommand; 22 | import net.dv8tion.jda.api.interactions.commands.OptionType; 23 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 24 | 25 | import javax.script.ScriptEngine; 26 | import javax.script.ScriptEngineManager; 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | 30 | /** 31 | * @author John Grosh (jagrosh) 32 | */ 33 | public class EvalCmd extends OwnerCommand { 34 | private final Bot bot; 35 | 36 | public EvalCmd(Bot bot) { 37 | this.bot = bot; 38 | this.name = "eval"; 39 | this.help = "nashornコードを実行します"; 40 | this.aliases = bot.getConfig().getAliases(this.name); 41 | this.guildOnly = false; 42 | List options = new ArrayList<>(); 43 | options.add(new OptionData(OptionType.STRING, "code", "実行するコード", true)); 44 | this.options = options; 45 | } 46 | 47 | @Override 48 | protected void execute(SlashCommandEvent event) { 49 | ScriptEngine se = new ScriptEngineManager().getEngineByName("Nashorn"); 50 | se.put("bot", bot); 51 | se.put("event", event); 52 | se.put("jda", event.getJDA()); 53 | se.put("guild", event.getGuild()); 54 | se.put("channel", event.getChannel()); 55 | try { 56 | event.reply(event.getClient().getSuccess() + " 正常に実行されました:\n```\n" + se.eval(event.getOption("code").getAsString()) + " ```").queue(); 57 | } catch (Exception e) { 58 | event.reply(event.getClient().getError() + " 例外が発生しました\n```\n" + e + " ```").queue(); 59 | } 60 | } 61 | 62 | @Override 63 | protected void execute(CommandEvent event) { 64 | ScriptEngine se = new ScriptEngineManager().getEngineByName("Nashorn"); 65 | se.put("bot", bot); 66 | se.put("event", event); 67 | se.put("jda", event.getJDA()); 68 | se.put("guild", event.getGuild()); 69 | se.put("channel", event.getChannel()); 70 | try { 71 | event.reply(event.getClient().getSuccess() + " 正常に実行されました:\n```\n" + se.eval(event.getArgs()) + " ```"); 72 | } catch (Exception e) { 73 | event.reply(event.getClient().getError() + " 例外が発生しました\n```\n" + e + " ```"); 74 | } 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/owner/LeaveCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Cosgy Dev (info@cosgy.dev). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dev.cosgy.jmusicbot.slashcommands.owner; 18 | 19 | import com.jagrosh.jdautilities.command.CommandEvent; 20 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 21 | import com.jagrosh.jmusicbot.Bot; 22 | import dev.cosgy.jmusicbot.slashcommands.OwnerCommand; 23 | import net.dv8tion.jda.api.interactions.commands.OptionType; 24 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | public class LeaveCmd extends OwnerCommand { 30 | private final Bot bot; 31 | 32 | public LeaveCmd(Bot bot) { 33 | this.bot = bot; 34 | this.name = "leave"; 35 | List options = new ArrayList<>(); 36 | options.add(new OptionData(OptionType.STRING, "serverid", "サーバーID", true)); 37 | this.options = options; 38 | } 39 | 40 | @Override 41 | protected void execute(SlashCommandEvent event) { 42 | String id = event.getOption("serverid").getAsString(); 43 | event.getJDA().getGuildById(id).leave().queue(); 44 | } 45 | 46 | @Override 47 | protected void execute(CommandEvent event) { 48 | if (event.getArgs().isEmpty()) { 49 | event.reply(event.getClient().getError() + "役割の名前、またはNONEなどを付けてください。"); 50 | return; 51 | } 52 | 53 | event.getJDA().getGuildById(event.getArgs()).leave().queue(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/owner/ServerListCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Cosgy Dev (info@cosgy.dev). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dev.cosgy.jmusicbot.slashcommands.owner; 18 | 19 | import com.jagrosh.jdautilities.command.CommandEvent; 20 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 21 | import com.jagrosh.jmusicbot.Bot; 22 | import dev.cosgy.jmusicbot.slashcommands.AdminCommand; 23 | import dev.cosgy.jmusicbot.slashcommands.OwnerCommand; 24 | import net.dv8tion.jda.api.entities.Guild; 25 | 26 | import java.util.List; 27 | 28 | /** 29 | * @author Kosugi_kun 30 | */ 31 | public class ServerListCmd extends OwnerCommand { 32 | protected Bot bot; 33 | 34 | public ServerListCmd(Bot bot) { 35 | this.name = "slist"; 36 | this.help = "ボットコマンドを使用できる役割DJを設定します。"; 37 | this.aliases = bot.getConfig().getAliases(this.name); 38 | } 39 | 40 | @Override 41 | protected void execute(SlashCommandEvent event) { 42 | List guilds = event.getJDA().getGuilds(); 43 | 44 | StringBuilder stringBuilder = new StringBuilder(); 45 | for (Guild guild : guilds) { 46 | stringBuilder.append(guild.getName()).append(guild.getId()).append("\n"); 47 | } 48 | 49 | event.reply(stringBuilder.toString()).queue(); 50 | } 51 | 52 | @Override 53 | protected void execute(CommandEvent event) { 54 | List guilds = event.getJDA().getGuilds(); 55 | 56 | StringBuilder stringBuilder = new StringBuilder(); 57 | for (Guild guild : guilds) { 58 | stringBuilder.append(guild.getName()).append(guild.getId()).append("\n"); 59 | } 60 | 61 | event.reply(stringBuilder.toString()); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/owner/SetavatarCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.owner; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 20 | import com.jagrosh.jmusicbot.Bot; 21 | import com.jagrosh.jmusicbot.utils.OtherUtil; 22 | import dev.cosgy.jmusicbot.slashcommands.OwnerCommand; 23 | import net.dv8tion.jda.api.entities.Icon; 24 | import net.dv8tion.jda.api.interactions.commands.OptionType; 25 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 26 | 27 | import java.io.IOException; 28 | import java.io.InputStream; 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | 32 | /** 33 | * @author John Grosh 34 | */ 35 | public class SetavatarCmd extends OwnerCommand { 36 | public SetavatarCmd(Bot bot) { 37 | this.name = "setavatar"; 38 | this.help = "ボットのアバターを設定します"; 39 | this.arguments = ""; 40 | this.aliases = bot.getConfig().getAliases(this.name); 41 | this.guildOnly = false; 42 | List options = new ArrayList<>(); 43 | options.add(new OptionData(OptionType.STRING, "image", "画像のURL", true)); 44 | this.options = options; 45 | 46 | } 47 | 48 | @Override 49 | protected void execute(SlashCommandEvent event) { 50 | String url = event.getOption("image").getAsString(); 51 | InputStream s = OtherUtil.imageFromUrl(url); 52 | if (s == null) { 53 | event.reply(event.getClient().getError() + " 無効または見つからないURL").queue(); 54 | } else { 55 | try { 56 | event.getJDA().getSelfUser().getManager().setAvatar(Icon.from(s)).queue( 57 | v -> event.reply(event.getClient().getSuccess() + "アバターを変更しました。").queue(), 58 | t -> event.reply(event.getClient().getError() + "アバターを設定できませんでした。").queue()); 59 | } catch (IOException e) { 60 | event.reply(event.getClient().getError() + " 提供されたURLから読み込めませんでした。").queue(); 61 | } 62 | } 63 | } 64 | 65 | @Override 66 | protected void execute(CommandEvent event) { 67 | String url; 68 | if (event.getArgs().isEmpty()) 69 | if (!event.getMessage().getAttachments().isEmpty() && event.getMessage().getAttachments().get(0).isImage()) 70 | url = event.getMessage().getAttachments().get(0).getUrl(); 71 | else 72 | url = null; 73 | else 74 | url = event.getArgs(); 75 | InputStream s = OtherUtil.imageFromUrl(url); 76 | if (s == null) { 77 | event.reply(event.getClient().getError() + " 無効または見つからないURL"); 78 | } else { 79 | try { 80 | event.getSelfUser().getManager().setAvatar(Icon.from(s)).queue( 81 | v -> event.reply(event.getClient().getSuccess() + "アバターを変更しました。"), 82 | t -> event.reply(event.getClient().getError() + "アバターを設定できませんでした。")); 83 | } catch (IOException e) { 84 | event.reply(event.getClient().getError() + " 提供されたURLから読み込めませんでした。"); 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/owner/SetnameCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.owner; 17 | 18 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 19 | import com.jagrosh.jmusicbot.Bot; 20 | import dev.cosgy.jmusicbot.slashcommands.OwnerCommand; 21 | import net.dv8tion.jda.api.exceptions.RateLimitedException; 22 | import net.dv8tion.jda.api.interactions.commands.OptionType; 23 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 24 | 25 | import java.util.ArrayList; 26 | import java.util.List; 27 | 28 | public class SetnameCmd extends OwnerCommand { 29 | protected Bot bot; 30 | 31 | public SetnameCmd(Bot bot) { 32 | this.bot = bot; 33 | this.name = "setname"; 34 | this.help = "ボットの名前を設定します。"; 35 | this.arguments = ""; 36 | this.aliases = bot.getConfig().getAliases(this.name); 37 | this.guildOnly = false; 38 | 39 | List options = new ArrayList<>(); 40 | options.add(new OptionData(OptionType.STRING, "name", "新しいボットの名前", true)); 41 | this.options = options; 42 | } 43 | 44 | @Override 45 | protected void execute(SlashCommandEvent event) { 46 | try { 47 | String oldname = event.getJDA().getSelfUser().getName(); 48 | event.getJDA().getSelfUser().getManager().setName(event.getOption("name").getAsString()).complete(false); 49 | event.reply(event.getClient().getSuccess() + "ボットの名前を`" + oldname + "` から `" + event.getOption("name").getAsString() + "`に変更しました。").queue(); 50 | } catch (RateLimitedException e) { 51 | event.reply(event.getClient().getError() + "名前は1時間に2回しか変更できません。").queue(); 52 | } catch (Exception e) { 53 | event.reply(event.getClient().getError() + " その名前は使用できません。").queue(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/owner/SetstatusCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.owner; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 20 | import com.jagrosh.jmusicbot.Bot; 21 | import dev.cosgy.jmusicbot.slashcommands.OwnerCommand; 22 | import net.dv8tion.jda.api.OnlineStatus; 23 | import net.dv8tion.jda.api.interactions.commands.OptionType; 24 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | /** 30 | * @author John Grosh 31 | */ 32 | public class SetstatusCmd extends OwnerCommand { 33 | public SetstatusCmd(Bot bot) { 34 | this.name = "setstatus"; 35 | this.help = "ボットが表示するステータスを設定します"; 36 | this.arguments = ""; 37 | this.aliases = bot.getConfig().getAliases(this.name); 38 | this.guildOnly = false; 39 | List options = new ArrayList<>(); 40 | options.add(new OptionData(OptionType.STRING, "status", "次のいずれかのステータス:ONLINE, IDLE, DND, INVISIBLE", true)); 41 | this.options = options; 42 | } 43 | 44 | @Override 45 | protected void execute(SlashCommandEvent event) { 46 | try { 47 | OnlineStatus status = OnlineStatus.fromKey(event.getOption("status").getAsString()); 48 | if (status == OnlineStatus.UNKNOWN) { 49 | event.reply(event.getClient().getError() + "次のいずれかのステータスを含めてください。 :`ONLINE`, `IDLE`, `DND`, `INVISIBLE`").queue(); 50 | } else { 51 | event.getJDA().getPresence().setStatus(status); 52 | event.reply(event.getClient().getSuccess() + "ステータスを`" + status.getKey().toUpperCase() + "`に設定しました。").queue(); 53 | } 54 | } catch (Exception e) { 55 | event.reply(event.getClient().getError() + " ステータスを設定できませんでした。").queue(); 56 | } 57 | } 58 | 59 | @Override 60 | protected void execute(CommandEvent event) { 61 | try { 62 | OnlineStatus status = OnlineStatus.fromKey(event.getArgs()); 63 | if (status == OnlineStatus.UNKNOWN) { 64 | event.replyError("次のいずれかのステータスを含めてください。 :`ONLINE`, `IDLE`, `DND`, `INVISIBLE`"); 65 | } else { 66 | event.getJDA().getPresence().setStatus(status); 67 | event.replySuccess("ステータスを`" + status.getKey().toUpperCase() + "`に設定しました。"); 68 | } 69 | } catch (Exception e) { 70 | event.reply(event.getClient().getError() + " ステータスを設定できませんでした。"); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/slashcommands/owner/ShutdownCmd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 John Grosh (jagrosh). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package dev.cosgy.jmusicbot.slashcommands.owner; 17 | 18 | import com.jagrosh.jdautilities.command.CommandEvent; 19 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 20 | import com.jagrosh.jmusicbot.Bot; 21 | import dev.cosgy.jmusicbot.slashcommands.OwnerCommand; 22 | 23 | /** 24 | * @author John Grosh 25 | */ 26 | public class ShutdownCmd extends OwnerCommand { 27 | private final Bot bot; 28 | 29 | public ShutdownCmd(Bot bot) { 30 | this.bot = bot; 31 | this.name = "shutdown"; 32 | this.help = "安全にシャットダウン"; 33 | this.aliases = bot.getConfig().getAliases(this.name); 34 | this.guildOnly = false; 35 | } 36 | 37 | @Override 38 | protected void execute(SlashCommandEvent event) { 39 | event.reply(event.getClient().getWarning() + "シャットダウンしています...\n不具合で正常に停止できないことがあります。その場合は強制的にボットを停止して下さい。").queue(); 40 | bot.shutdown(); 41 | } 42 | 43 | @Override 44 | protected void execute(CommandEvent event) { 45 | event.replyWarning("シャットダウンしています...\n不具合で正常に停止できないことがあります。その場合は強制的にボットを停止して下さい。"); 46 | bot.shutdown(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/util/Cache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Cosgy Dev (info@cosgy.dev). 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dev.cosgy.jmusicbot.util; 18 | 19 | /** 20 | * @author Kosugi_kun 21 | */ 22 | public class Cache { 23 | private String title; 24 | private String author; 25 | private String length; 26 | private String identifier; 27 | private Boolean isStream; 28 | private String url; 29 | private String userId; 30 | 31 | public Cache(String title, String author, long length, String identifier, boolean isStream, String uri, long userId) { 32 | this.title = title; 33 | this.author = author; 34 | this.length = String.valueOf(length); 35 | this.identifier = identifier; 36 | this.isStream = isStream; 37 | this.url = uri; 38 | this.userId = String.valueOf(userId); 39 | } 40 | 41 | public Cache() { 42 | } 43 | 44 | public String getTitle() { 45 | return title; 46 | } 47 | 48 | public void setTitle(String title) { 49 | this.title = title; 50 | } 51 | 52 | public String getAuthor() { 53 | return author; 54 | } 55 | 56 | public void setAuthor(String author) { 57 | this.author = author; 58 | } 59 | 60 | public String getLength() { 61 | return length; 62 | } 63 | 64 | public void setLength(String length) { 65 | this.length = length; 66 | } 67 | 68 | public String getIdentifier() { 69 | return identifier; 70 | } 71 | 72 | public void setIdentifier(String identifier) { 73 | this.identifier = identifier; 74 | } 75 | 76 | public Boolean getIsStream() { 77 | return isStream; 78 | } 79 | 80 | public void setIsStream(Boolean isStream) { 81 | this.isStream = isStream; 82 | } 83 | 84 | public String getUrl() { 85 | return url; 86 | } 87 | 88 | public void setUrl(String url) { 89 | this.url = url; 90 | } 91 | 92 | public String getUserId() { 93 | return userId; 94 | } 95 | 96 | public void setUserId(String userId) { 97 | this.userId = userId; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/util/LastSendTextChannel.java: -------------------------------------------------------------------------------- 1 | package dev.cosgy.jmusicbot.util; 2 | 3 | import com.jagrosh.jdautilities.command.CommandEvent; 4 | import com.jagrosh.jdautilities.command.CommandListener; 5 | import net.dv8tion.jda.api.entities.Guild; 6 | import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.util.HashMap; 11 | 12 | public class LastSendTextChannel implements CommandListener { 13 | // ギルドIDでテキストチャンネルのIDを持ってきます。 14 | private static final HashMap textChannel = new HashMap<>(); 15 | static Logger log = LoggerFactory.getLogger("LastSendTextChannel"); 16 | 17 | public static void SetLastTextId(CommandEvent event) { 18 | textChannel.put(event.getGuild().getIdLong(), event.getTextChannel().getIdLong()); 19 | } 20 | 21 | public static long GetLastTextId(long guildId) { 22 | long id; 23 | if (textChannel.containsKey(guildId)) { 24 | id = textChannel.get(guildId); 25 | } else { 26 | id = 0; 27 | } 28 | return id; 29 | } 30 | 31 | public static void SendMessage(Guild guild, String message) { 32 | log.debug("メッセージを送信します。"); 33 | long textId = GetLastTextId(guild.getIdLong()); 34 | if (textId == 0) { 35 | log.debug("チャンネルが保存されていなかったため、メッセージを送信できませんでした。"); 36 | return; 37 | } 38 | MessageChannel channel = guild.getTextChannelById(textId); 39 | channel.sendMessage(message).queue(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/util/StackTraceUtil.java: -------------------------------------------------------------------------------- 1 | package dev.cosgy.jmusicbot.util; 2 | 3 | 4 | import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; 5 | 6 | import java.io.PrintWriter; 7 | import java.io.StringWriter; 8 | 9 | public class StackTraceUtil { 10 | public static void sendStackTrace(TextChannel channel, Throwable throwable) { 11 | StringWriter writer = new StringWriter(); 12 | PrintWriter pWriter = new PrintWriter(writer); 13 | throwable.printStackTrace(pWriter); 14 | pWriter.flush(); 15 | channel.sendMessage("```\n" + writer.toString().substring(0, (2000 - 3)) + "...\n```").queue(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/jmusicbot/util/TimeUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 John Grosh . 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dev.cosgy.jmusicbot.util; 18 | 19 | public class TimeUtil 20 | { 21 | 22 | public static String formatTime(long duration) 23 | { 24 | if(duration == Long.MAX_VALUE) 25 | return "LIVE"; 26 | long seconds = Math.round(duration/1000.0); 27 | long hours = seconds/(60*60); 28 | seconds %= 60*60; 29 | long minutes = seconds/60; 30 | seconds %= 60; 31 | return (hours>0 ? hours+":" : "") + (minutes<10 ? "0"+minutes : minutes) + ":" + (seconds<10 ? "0"+seconds : seconds); 32 | } 33 | 34 | /** 35 | * Parses a seek time string into milliseconds and determines if it's relative. 36 | * Supports "colon time" (HH:MM:SS) or "unit time" (1h20m) 37 | * @param args time string 38 | * @return SeekTime object, or null if the string could not be parsed 39 | */ 40 | public static SeekTime parseTime(String args) 41 | { 42 | if (args.length() == 0) return null; 43 | String timestamp = args; 44 | boolean relative = false; // seek forward or backward 45 | boolean isSeekingBackwards = false; 46 | char first = timestamp.charAt(0); 47 | if (first == '+' || first == '-') 48 | { 49 | relative = true; 50 | isSeekingBackwards = first == '-'; 51 | timestamp = timestamp.substring(1); 52 | } 53 | 54 | long milliseconds = parseColonTime(timestamp); 55 | if(milliseconds == -1) milliseconds = parseUnitTime(timestamp); 56 | if(milliseconds == -1) return null; 57 | 58 | milliseconds *= isSeekingBackwards ? -1 : 1; 59 | 60 | return new SeekTime(milliseconds, relative); 61 | } 62 | 63 | /** 64 | * @param timestamp timestamp formatted as: [+ | -] <HH:MM:SS | MM:SS | SS> 65 | * @return Time in milliseconds 66 | */ 67 | public static long parseColonTime(String timestamp) 68 | { 69 | String[] timestampSplitArray = timestamp.split(":+"); 70 | if(timestampSplitArray.length > 3 ) 71 | return -1; 72 | double[] timeUnitArray = new double[3]; // hours, minutes, seconds 73 | for(int index = 0; index < timestampSplitArray.length; index++) 74 | { 75 | String unit = timestampSplitArray[index]; 76 | if (unit.startsWith("+") || unit.startsWith("-")) return -1; 77 | unit = unit.replace(",", "."); 78 | try 79 | { 80 | timeUnitArray[index + 3 - timestampSplitArray.length] = Double.parseDouble(unit); 81 | } 82 | catch (NumberFormatException e) 83 | { 84 | return -1; 85 | } 86 | } 87 | return Math.round(timeUnitArray[0] * 3600000 + timeUnitArray[1] * 60000 + timeUnitArray[2] * 1000); 88 | } 89 | 90 | /** 91 | * 92 | * @param timestr time string formatted as a unit time, e.g. 20m10, 1d5h20m14s or 1h and 20m 93 | * @return Time in milliseconds 94 | */ 95 | public static long parseUnitTime(String timestr) 96 | { 97 | timestr = timestr.replaceAll("(?i)(\\s|,|and)","") 98 | .replaceAll("(?is)(-?\\d+|[a-z]+)", "$1 ") 99 | .trim(); 100 | String[] vals = timestr.split("\\s+"); 101 | int time = 0; 102 | try 103 | { 104 | for(int j=0; j j+1) 109 | { 110 | if(vals[j+1].toLowerCase().startsWith("m")) 111 | num*=60; 112 | else if(vals[j+1].toLowerCase().startsWith("h")) 113 | num*=60*60; 114 | else if(vals[j+1].toLowerCase().startsWith("d")) 115 | num*=60*60*24; 116 | } 117 | 118 | time+=num*1000; 119 | } 120 | } 121 | catch(Exception ex) 122 | { 123 | return -1; 124 | } 125 | return time; 126 | } 127 | 128 | public static class SeekTime 129 | { 130 | public final long milliseconds; 131 | public final boolean relative; 132 | 133 | private SeekTime(long milliseconds, boolean relative) 134 | { 135 | this.milliseconds = milliseconds; 136 | this.relative = relative; 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/niconicoSearchAPI/Sample.java: -------------------------------------------------------------------------------- 1 | package dev.cosgy.niconicoSearchAPI; 2 | 3 | import java.util.List; 4 | 5 | public class Sample { 6 | public static void main(String[] args) { 7 | nicoSearchAPI ns = new nicoSearchAPI(true, 5); 8 | 9 | long start = System.currentTimeMillis(); 10 | List results_0 = ns.searchVideo("初音ミク", 5); 11 | long end = System.currentTimeMillis(); 12 | 13 | long start_2 = System.currentTimeMillis(); 14 | List results_1 = ns.searchVideo("千本桜", 5); 15 | long end_2 = System.currentTimeMillis(); 16 | 17 | long start_3 = System.currentTimeMillis(); 18 | List results_2 = ns.searchVideo("ODDS&ENDS", 5); 19 | long end_3 = System.currentTimeMillis(); 20 | 21 | System.out.println("First: " + (end - start)); 22 | results_0.forEach(result -> System.out.println(result.getTitle() + ": " + result.getWatchUrl())); 23 | 24 | System.out.println("Second: " + (end_2 - start_2)); 25 | results_1.forEach(result -> System.out.println(result.getTitle() + ": " + result.getWatchUrl())); 26 | 27 | System.out.println("Third: " + (end_3 - start_3)); 28 | results_2.forEach(result -> System.out.println(result.getTitle() + ": " + result.getWatchUrl())); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/niconicoSearchAPI/nicoSearchAPI.java: -------------------------------------------------------------------------------- 1 | package dev.cosgy.niconicoSearchAPI; 2 | 3 | import org.json.JSONObject; 4 | 5 | import java.net.URLEncoder; 6 | import java.nio.charset.StandardCharsets; 7 | import java.util.HashMap; 8 | import java.util.LinkedHashMap; 9 | import java.util.LinkedList; 10 | import java.util.Map; 11 | 12 | public class nicoSearchAPI { 13 | private final boolean cacheEnabled; 14 | private final int maxCacheSize; 15 | private LinkedHashMap videoResultCache; 16 | 17 | public nicoSearchAPI(boolean cacheEnabled, int maxCacheSize) { 18 | this.cacheEnabled = cacheEnabled; 19 | this.maxCacheSize = maxCacheSize; 20 | } 21 | 22 | public LinkedList searchVideo(String query, int resultLimit) { 23 | return searchVideo(query, resultLimit, true); 24 | } 25 | 26 | 27 | public LinkedList searchVideo(String query, int resultLimit, boolean autogetVideoInfo) { 28 | if (resultLimit <= 0) resultLimit = 10; 29 | if (cacheEnabled && videoResultCache == null) videoResultCache = new LinkedHashMap<>(); 30 | 31 | // https://snapshot.search.nicovideo.jp/api/v2/snapshot/video/contents/search?q=初音ミク&targets=title&fields=contentId,title,viewCounter&filters[viewCounter][gte]=10000&_sort=-viewCounter&_offset=0&_limit=3&_context=apiguide 32 | // https://snapshot.search.nicovideo.jp/api/v2/snapshot/video/contents/search?q=初音ミク&_limit=5&_context=discord_bot&fields=contentId,title,description,tags,categoryTags,viewCounter,mylistCounter,commentCounter,startTime,lastCommentTime,lengthSeconds,thumbnailUrl&_sort=-viewCounter&targets=title 33 | 34 | HTTPUtil hu = new HTTPUtil(); 35 | hu.setTargetAddress("https://snapshot.search.nicovideo.jp/api/v2/snapshot/video/contents/search"); 36 | hu.setMethod("GET"); 37 | Map queryMap = new HashMap<>(); 38 | queryMap.put("q", URLEncoder.encode(query, StandardCharsets.UTF_8)); 39 | queryMap.put("_sort", "-viewCounter"); 40 | queryMap.put("targets", "title"); 41 | queryMap.put("fields", "contentId,title,description,userId,channelId,viewCounter,thumbnailUrl,categoryTags,tags,mylistCounter,commentCounter,startTime"); 42 | queryMap.put("_limit", String.valueOf(resultLimit)); 43 | queryMap.put("_context", "discord_bot"); 44 | hu.setQueryMap(queryMap); 45 | 46 | LinkedList results = new LinkedList<>(); 47 | JSONObject object = new JSONObject(hu.request()); 48 | 49 | System.out.println(object.toString(4)); 50 | 51 | for (Object resultObject : object.getJSONArray("data")) { 52 | JSONObject result = (JSONObject) resultObject; 53 | 54 | if (videoResultCache.containsKey(result.getString("contentId"))) { 55 | System.out.println("[DEBUG] Using cache for VideoID " + result.getString("contentId")); 56 | results.add(videoResultCache.get(result.getString("contentId"))); 57 | } else { 58 | nicoVideoSearchResult rs = new nicoVideoSearchResult( 59 | result.getString("contentId"), 60 | result.getString("title"), 61 | result.getString("description"), 62 | result.getString("tags").split(" "), 63 | (result.isNull("categoryTags") ? new String[0] : result.getString("categoryTags").split(" ")), // FIX categoryTags: null json parse error 64 | result.getInt("viewCounter"), 65 | result.getInt("mylistCounter"), 66 | result.getInt("commentCounter"), 67 | result.getString("startTime"), 68 | result.getString("thumbnailUrl"), 69 | autogetVideoInfo); 70 | results.add(rs); 71 | videoResultCache.put(rs.getContentId(), rs); 72 | } 73 | 74 | if (maxCacheSize >= 1 && videoResultCache.size() > maxCacheSize) { 75 | videoResultCache.remove(videoResultCache.keySet().toArray()[0]); 76 | } 77 | } 78 | return results; 79 | } 80 | } 81 | 82 | -------------------------------------------------------------------------------- /src/main/java/dev/cosgy/niconicoSearchAPI/nicoVideoInfo.java: -------------------------------------------------------------------------------- 1 | package dev.cosgy.niconicoSearchAPI; 2 | 3 | import java.util.Arrays; 4 | 5 | public class nicoVideoInfo { 6 | //video info 7 | private String videoId; 8 | private String title; 9 | private String[] tags; 10 | private String watchUrl; 11 | private String thumbnailUrl; 12 | private String description; 13 | private String lengthFormatted; 14 | 15 | //counts 16 | private int viewCount; 17 | private int mylistCount; 18 | private int commentCount; 19 | 20 | //Uploader info 21 | private int uploadUserId; 22 | private String uploadUserName; 23 | private String uploadUserIconUrl; 24 | 25 | public nicoVideoInfo(String videoId, String title, String[] tags, String watchUrl, String thumbnailUrl, String description, String lengthFormatted, 26 | int viewCount, int mylistCount, int commentCount, 27 | int uploadUserId, String uploadUserName, String uploadUserIconUrl) { 28 | 29 | this.videoId = videoId; 30 | this.title = title; 31 | this.tags = tags; 32 | this.watchUrl = watchUrl; 33 | this.thumbnailUrl = thumbnailUrl; 34 | this.description = description; 35 | this.lengthFormatted = lengthFormatted; 36 | 37 | this.viewCount = viewCount; 38 | this.mylistCount = mylistCount; 39 | this.commentCount = commentCount; 40 | 41 | this.uploadUserId = uploadUserId; 42 | this.uploadUserName = uploadUserName; 43 | this.uploadUserIconUrl = uploadUserIconUrl; 44 | } 45 | 46 | public nicoVideoInfo() { 47 | } 48 | 49 | public String getVideoId() { 50 | return videoId; 51 | } 52 | 53 | public void setVideoId(String videoId) { 54 | this.videoId = videoId; 55 | } 56 | 57 | public String getTitle() { 58 | return title; 59 | } 60 | 61 | public nicoVideoInfo setTitle(String title) { 62 | this.title = title; 63 | return this; 64 | } 65 | 66 | public String[] getTags() { 67 | return tags; 68 | } 69 | 70 | public nicoVideoInfo setTags(String[] tags) { 71 | this.tags = tags; 72 | return this; 73 | } 74 | 75 | public String getWatchUrl() { 76 | return watchUrl; 77 | } 78 | 79 | public nicoVideoInfo setWatchUrl(String watchUrl) { 80 | this.watchUrl = watchUrl; 81 | return this; 82 | } 83 | 84 | public String getThumbnailUrl() { 85 | return thumbnailUrl; 86 | } 87 | 88 | public nicoVideoInfo setThumbnailUrl(String thumbnailUrl) { 89 | this.thumbnailUrl = thumbnailUrl; 90 | return this; 91 | } 92 | 93 | public String getDescription() { 94 | return description; 95 | } 96 | 97 | public nicoVideoInfo setDescription(String description) { 98 | this.description = description; 99 | return this; 100 | } 101 | 102 | public String getLengthFormatted() { 103 | return lengthFormatted; 104 | } 105 | 106 | public nicoVideoInfo setLengthFormatted(String lengthFormatted) { 107 | this.lengthFormatted = lengthFormatted; 108 | return this; 109 | } 110 | 111 | public int getViewCount() { 112 | return viewCount; 113 | } 114 | 115 | public nicoVideoInfo setViewCount(int viewCount) { 116 | this.viewCount = viewCount; 117 | return this; 118 | } 119 | 120 | public int getMylistCount() { 121 | return mylistCount; 122 | } 123 | 124 | public nicoVideoInfo setMylistCount(int mylistCount) { 125 | this.mylistCount = mylistCount; 126 | return this; 127 | } 128 | 129 | public int getCommentCount() { 130 | return commentCount; 131 | } 132 | 133 | public nicoVideoInfo setCommentCount(int commentCount) { 134 | this.commentCount = commentCount; 135 | return this; 136 | } 137 | 138 | public int getUploadUserId() { 139 | return uploadUserId; 140 | } 141 | 142 | public nicoVideoInfo setUploadUserId(int uploadUserId) { 143 | this.uploadUserId = uploadUserId; 144 | return this; 145 | } 146 | 147 | public String getUploadUserName() { 148 | return uploadUserName; 149 | } 150 | 151 | public nicoVideoInfo setUploadUserName(String uploadUserName) { 152 | this.uploadUserName = uploadUserName; 153 | return this; 154 | } 155 | 156 | public String getUploadUserIconUrl() { 157 | return uploadUserIconUrl; 158 | } 159 | 160 | public nicoVideoInfo setUploadUserIconUrl(String uploadUserIconUrl) { 161 | this.uploadUserIconUrl = uploadUserIconUrl; 162 | return this; 163 | } 164 | 165 | public String toString() { 166 | return "videoId=" + videoId + 167 | ", title=" + title + 168 | ", tags=" + Arrays.toString(tags) + 169 | ", watchUrl=" + watchUrl + 170 | ", thumbnailUrl=" + thumbnailUrl + 171 | ", description=" + description + 172 | ", lengthFormatted=" + lengthFormatted + 173 | ", viewCount=" + viewCount + 174 | ", mylistCount=" + mylistCount + 175 | ", commentCount=" + commentCount + 176 | ", uploadUserId=" + uploadUserId + 177 | ", uploadUserName=" + uploadUserName + 178 | ", uploadUserIconUrl=" + uploadUserIconUrl; 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | %nopex[%d{HH:mm:ss}] [%level] [%logger{0}]: %msg%n%ex 26 | 27 | 28 | 29 | 30 | ${logDir}${fileName}.log 31 | 32 | ${logDir}${fileName}.%d{yyyy-MM-dd}.log 33 | 10 34 | 35 | 36 | 37 | 38 | %nopex[%d{HH:mm:ss}] [%level] [%logger{0}]: %msg%n%ex 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 51 | 57 | 58 | -------------------------------------------------------------------------------- /src/test/java/com/jagrosh/jmusicbot/FairQueueTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2020 Cosgy Dev 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.jagrosh.jmusicbot; 17 | 18 | import com.jagrosh.jmusicbot.queue.FairQueue; 19 | import com.jagrosh.jmusicbot.queue.Queueable; 20 | import org.junit.Test; 21 | 22 | import static org.junit.Assert.assertEquals; 23 | 24 | /** 25 | * @author John Grosh (john.a.grosh@gmail.com) 26 | */ 27 | public class FairQueueTest { 28 | @Test 29 | public void differentIdentifierSize() { 30 | FairQueue queue = new FairQueue<>(); 31 | int size = 100; 32 | for (int i = 0; i < size; i++) 33 | queue.add(new Q(i)); 34 | assertEquals(queue.size(), size); 35 | } 36 | 37 | @Test 38 | public void sameIdentifierSize() { 39 | FairQueue queue = new FairQueue<>(); 40 | int size = 100; 41 | for (int i = 0; i < size; i++) 42 | queue.add(new Q(0)); 43 | assertEquals(queue.size(), size); 44 | } 45 | 46 | private class Q implements Queueable { 47 | private final long identifier; 48 | 49 | private Q(long identifier) { 50 | this.identifier = identifier; 51 | } 52 | 53 | @Override 54 | public long getIdentifier() { 55 | return identifier; 56 | } 57 | } 58 | } 59 | --------------------------------------------------------------------------------