mirror of
https://github.com/chrisb09/MusicBot.git
synced 2026-11-05 17:02:35 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e1b9e0165a | ||
|
|
2e701d0d23 | ||
|
|
259e3d716b | ||
|
|
43398449c7 | ||
|
|
e7f00fe088 | ||
|
|
1a9364acae | ||
|
|
19234998f1 | ||
|
|
31037775d1 | ||
|
|
e0b1bb0d06 | ||
|
|
1f810aa36f | ||
|
|
e7a8cec0b4 | ||
|
|
ae07ac2598 | ||
|
|
d75098fdd9 | ||
|
|
ac87cc13d7 | ||
|
|
34bffe0148 | ||
|
|
15f3cf07a8 | ||
|
|
c0f0d45138 | ||
|
|
2eddaccb86 | ||
|
|
87b2f4f93a | ||
|
|
88970314ad | ||
|
|
0de4e2afcc | ||
|
|
2671ac18c8 | ||
|
|
68a992c79e | ||
|
|
9bf233ec79 | ||
|
|
b41dcded98 | ||
|
|
b6239ed608 | ||
|
|
9dfe613921 | ||
|
|
865119e2ae | ||
|
|
c616f9c92a | ||
|
|
2737a85a61 | ||
|
|
c88979a6dd | ||
|
|
a6f7c9b3ef | ||
|
|
2aac68b412 | ||
|
|
e1b07868fd | ||
|
|
aaec886b81 | ||
|
|
a7a4b55011 | ||
|
|
bcb7e03aac | ||
|
|
c49a559e34 | ||
|
|
af98eb5e01 | ||
|
|
e47c3efc58 | ||
|
|
058c3e18d2 | ||
|
|
38ae19cbec |
No files matched your search
@@ -0,0 +1,21 @@
|
||||
version: '{build}'
|
||||
os: Windows Server 2012
|
||||
install:
|
||||
- ps: |
|
||||
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
||||
if (!(Test-Path -Path "C:\maven" )) {
|
||||
(new-object System.Net.WebClient).DownloadFile(
|
||||
'http://www.us.apache.org/dist/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.zip',
|
||||
'C:\maven-bin.zip'
|
||||
)
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory("C:\maven-bin.zip", "C:\maven")
|
||||
}
|
||||
- cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5
|
||||
- cmd: SET PATH=%SystemRoot%\system32;C:\maven\apache-maven-3.2.5\bin;%JAVA_HOME%\bin;%PATH
|
||||
build_script:
|
||||
- mvn clean package --batch-mode -DskipTest
|
||||
test_script:
|
||||
- mvn clean install --batch-mode
|
||||
cache:
|
||||
- C:\maven\
|
||||
- C:\Users\appveyor\.m2
|
||||
@@ -0,0 +1,41 @@
|
||||
# Java Maven CircleCI 2.0 configuration file
|
||||
#
|
||||
# Check https://circleci.com/docs/2.0/language-java/ for more details
|
||||
#
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
# specify the version you desire here
|
||||
- image: circleci/openjdk:8u171-jdk
|
||||
|
||||
# Specify service dependencies here if necessary
|
||||
# CircleCI maintains a library of pre-built images
|
||||
# documented at https://circleci.com/docs/2.0/circleci-images/
|
||||
# - image: circleci/postgres:9.4
|
||||
|
||||
working_directory: ~/repo
|
||||
|
||||
environment:
|
||||
# Customize the JVM maximum heap limit
|
||||
MAVEN_OPTS: -Xmx3200m
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
# Download and cache dependencies
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-dependencies-{{ checksum "pom.xml" }}
|
||||
# fallback to using the latest cache if no exact match is found
|
||||
- v1-dependencies-
|
||||
|
||||
- run: mvn dependency:go-offline
|
||||
|
||||
- save_cache:
|
||||
paths:
|
||||
- ~/.m2
|
||||
key: v1-dependencies-{{ checksum "pom.xml" }}
|
||||
|
||||
# run tests!
|
||||
- run: mvn integration-test
|
||||
@@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at j@gro.sh. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Report a bug or unexpected behavior
|
||||
title: "[Bug Report] Title Here"
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Run with '...'
|
||||
2. Do a command '....'
|
||||
3. Some other step '....'
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Version Info (please complete the following information):**
|
||||
- Operating System: [e.g. Windows 64bit]
|
||||
- JMusicBot Version: [e.g. 0.2.1]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: "[Feature Request] Title Here"
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe the basic flow/steps of using this feature**
|
||||
How this feature would be used:
|
||||
1. Set something '...'
|
||||
2. Run some command '...'
|
||||
3. Other steps or related info '...'
|
||||
4. ...
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
|
||||
**Have you confirmed that this idea is not already described here?**
|
||||
https://github.com/jagrosh/MusicBot/projects/1
|
||||
@@ -0,0 +1,14 @@
|
||||
### This pull request...
|
||||
- [ ] Fixes a bug
|
||||
- [ ] Introduces a new feature
|
||||
- [ ] Improves an existing feature
|
||||
- [ ] Boosts code quality or performance
|
||||
|
||||
### Description
|
||||
Replace this with a description of the pull request
|
||||
|
||||
### Purpose
|
||||
Replace this with a description of the problem or use-case
|
||||
|
||||
### Relevant Issue(s)
|
||||
This PR closes issue #...
|
||||
@@ -0,0 +1,6 @@
|
||||
/nbproject/
|
||||
/target/
|
||||
/Playlists/
|
||||
*.json
|
||||
*.txt
|
||||
nb*.xml
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<settings xsi:schemaLocation='http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd'
|
||||
xmlns='http://maven.apache.org/SETTINGS/1.0.0' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>bintray</id>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>central</id>
|
||||
<name>bintray</name>
|
||||
<url>http://jcenter.bintray.com</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
</profile>
|
||||
</profiles>
|
||||
<activeProfiles>
|
||||
<activeProfile>bintray</activeProfile>
|
||||
</activeProfiles>
|
||||
</settings>
|
||||
@@ -0,0 +1,2 @@
|
||||
language: java
|
||||
install: mvn install -Dmaven.javadoc.skip=true --batch-mode --show-version --settings .travis.settings.xml
|
||||
@@ -1,36 +1,44 @@
|
||||
<img align="right" src="https://i.imgur.com/zrE80HY.png" height="200" width="200">
|
||||
|
||||
# JMusicBot
|
||||
|
||||
[](https://github.com/jagrosh/MusicBot/releases/latest)
|
||||
[](https://github.com/jagrosh/MusicBot/stargazers)
|
||||
[](https://github.com/jagrosh/MusicBot/releases/latest)
|
||||
[](https://github.com/jagrosh/MusicBot/blob/master/LICENSE)
|
||||
[](https://discord.gg/0p9LSGoRLu6Pet0k)
|
||||
[](https://discord.gg/0p9LSGoRLu6Pet0k)<br>
|
||||
[](https://circleci.com/gh/jagrosh/MusicBot)
|
||||
[](https://travis-ci.com/jagrosh/MusicBot)
|
||||
[](https://ci.appveyor.com/project/jagrosh/musicbot/branch/master)
|
||||
[](https://www.codefactor.io/repository/github/jagrosh/musicbot)
|
||||
|
||||
# JMusicBot
|
||||
A Discord music bot with a clean interface, and that is easy to set up and run yourself
|
||||
A cross-platform Discord music bot with a clean interface, and that is easy to set up and run yourself!
|
||||
|
||||
[](https://github.com/jagrosh/MusicBot/wiki/Setup)
|
||||
|
||||
# Features
|
||||
* Easy to run (just make sure Java is installed, and run!)
|
||||
* Fast loading of songs
|
||||
* No external keys needed (besides a Discord Bot token)
|
||||
* Smooth playback
|
||||
* Server-specific setup for the "DJ" role that can moderate the music
|
||||
* Clean and beautiful menus
|
||||
* Channel-topic playback bar
|
||||
* Supports many sites, including Youtube, Soundcloud, and more
|
||||
* Supports many online radio/streams
|
||||
* Supports local files
|
||||
* Playlist support (both web/youtube, and local)
|
||||
## Features
|
||||
* Easy to run (just make sure Java is installed, and run!)
|
||||
* Fast loading of songs
|
||||
* No external keys needed (besides a Discord Bot token)
|
||||
* Smooth playback
|
||||
* Server-specific setup for the "DJ" role that can moderate the music
|
||||
* Clean and beautiful menus
|
||||
* Channel-topic playback bar
|
||||
* Supports many sites, including Youtube, Soundcloud, and more
|
||||
* Supports many online radio/streams
|
||||
* Supports local files
|
||||
* Playlist support (both web/youtube, and local)
|
||||
|
||||
# Setup
|
||||
## Example
|
||||

|
||||
|
||||
## Setup
|
||||
Please see the [Setup Page](https://github.com/jagrosh/MusicBot/wiki/Setup) in the wiki to run this bot yourself!
|
||||
|
||||
# Questions/Suggestions/Bug Reports
|
||||
## Questions/Suggestions/Bug Reports
|
||||
**Please read the [Suggested/Planned Features List](https://github.com/jagrosh/MusicBot/projects/1) before suggesting a feature**. If you'd like to suggest changes to how the bot functions, recommend more customization options, or report bugs, feel free to either open an [Issue](https://github.com/jagrosh/MusicBot/issues) on this repository, or join [my Discord server](https://discord.gg/0p9LSGoRLu6Pet0k). (Note: I will not accept any feature requests that will require additional API keys, nor any non-music features). If you like this bot, be sure to add a star to the libraries that make this possible: [**JDA**](https://github.com/DV8FromTheWorld/JDA) and [**lavaplayer**](https://github.com/sedmelluq/lavaplayer)
|
||||
|
||||
# Example
|
||||

|
||||
|
||||
# Editing
|
||||
|
||||
## Editing
|
||||
This bot (and the source code here) is not meant to be edited. The main purpose of having the source public is to show the capabilities of the libraries, and to allow others to understand how the bot works. There are many requirements and dependencies required to edit and compile it, and there will not be support provided for people looking to make changes on their own. Instead, consider making a feature request (see the above section). If you still choose to make edits, please do so in accordance with the Apache 2.0 License.
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.jagrosh</groupId>
|
||||
<artifactId>JMusicBot</artifactId>
|
||||
<version>0.1.2</version>
|
||||
<version>0.2.2</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<repositories>
|
||||
@@ -12,67 +12,99 @@
|
||||
<name>bintray</name>
|
||||
<url>http://jcenter.bintray.com</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>bintray-jagrosh-maven</id>
|
||||
<name>bintray</name>
|
||||
<url>https://dl.bintray.com/jagrosh/maven</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.25</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.dv8tion</groupId>
|
||||
<artifactId>JDA</artifactId>
|
||||
<version>3.5.0_335</version>
|
||||
<version>3.8.1_454</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sedmelluq</groupId>
|
||||
<artifactId>lavaplayer</artifactId>
|
||||
<version>1.2.47</version>
|
||||
<version>1.3.10</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jagrosh</groupId>
|
||||
<artifactId>JDA-Utilities</artifactId>
|
||||
<version>2.0</version>
|
||||
<artifactId>jda-utilities</artifactId>
|
||||
<version>2.1.5</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jagrosh</groupId>
|
||||
<artifactId>JLyrics</artifactId>
|
||||
<version>0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe</groupId>
|
||||
<artifactId>config</artifactId>
|
||||
<version>1.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-core</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<mainClass>com.jagrosh.jmusicbot.JMusicBot</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<configuration>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>1.5</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
<shadedClassifierName>All</shadedClassifierName>
|
||||
<artifactSet>
|
||||
<includes>
|
||||
<include>*:*</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>reference.conf</resource>
|
||||
</transformer>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<manifestEntries>
|
||||
<Main-Class>com.jagrosh.jmusicbot.JMusicBot</Main-Class>
|
||||
<Specification-Title>${project.artifactId}</Specification-Title>
|
||||
<Specification-Version>${project.version}</Specification-Version>
|
||||
<Implementation-Title>${project.artifactId}</Implementation-Title>
|
||||
<Implementation-Version>${project.version}</Implementation-Version>
|
||||
<Implementation-Vendor-Id>${project.groupId}</Implementation-Vendor-Id>
|
||||
</manifestEntries>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,117 +15,59 @@
|
||||
*/
|
||||
package com.jagrosh.jmusicbot;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import com.jagrosh.jdautilities.command.Command.Category;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jdautilities.commons.waiter.EventWaiter;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.audio.NowplayingHandler;
|
||||
import com.jagrosh.jmusicbot.audio.PlayerManager;
|
||||
import com.jagrosh.jmusicbot.gui.GUI;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioSourceManager;
|
||||
import com.jagrosh.jmusicbot.playlist.PlaylistLoader;
|
||||
import com.jagrosh.jmusicbot.settings.SettingsManager;
|
||||
import java.util.Objects;
|
||||
import javafx.util.Pair;
|
||||
import net.dv8tion.jda.core.JDA;
|
||||
import net.dv8tion.jda.core.Permission;
|
||||
import net.dv8tion.jda.core.entities.Game;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
import net.dv8tion.jda.core.entities.Message;
|
||||
import net.dv8tion.jda.core.entities.Role;
|
||||
import net.dv8tion.jda.core.entities.TextChannel;
|
||||
import net.dv8tion.jda.core.entities.VoiceChannel;
|
||||
import net.dv8tion.jda.core.events.ReadyEvent;
|
||||
import net.dv8tion.jda.core.events.ShutdownEvent;
|
||||
import net.dv8tion.jda.core.events.guild.GuildJoinEvent;
|
||||
import net.dv8tion.jda.core.events.message.MessageDeleteEvent;
|
||||
import net.dv8tion.jda.core.exceptions.PermissionException;
|
||||
import net.dv8tion.jda.core.hooks.ListenerAdapter;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class Bot extends ListenerAdapter {
|
||||
|
||||
private final HashMap<String,Settings> settings;
|
||||
private final HashMap<Long,Pair<Long,Long>> lastNP; // guild -> channel,message
|
||||
private final AudioPlayerManager manager;
|
||||
public class Bot
|
||||
{
|
||||
private final EventWaiter waiter;
|
||||
private final ScheduledExecutorService threadpool;
|
||||
private final Config config;
|
||||
private final BotConfig config;
|
||||
private final SettingsManager settings;
|
||||
private final PlayerManager players;
|
||||
private final PlaylistLoader playlists;
|
||||
private final NowplayingHandler nowplaying;
|
||||
|
||||
private boolean shuttingDown = false;
|
||||
private JDA jda;
|
||||
private GUI gui;
|
||||
//private GuildsPanel panel;
|
||||
public final Category MUSIC = new Category("Music");
|
||||
public final Category DJ = new Category("DJ", event ->
|
||||
{
|
||||
if(event.getAuthor().getId().equals(event.getClient().getOwnerId()))
|
||||
return true;
|
||||
if(event.getGuild()==null)
|
||||
return true;
|
||||
if(event.getMember().hasPermission(Permission.MANAGE_SERVER))
|
||||
return true;
|
||||
Role dj = event.getGuild().getRoleById(getSettings(event.getGuild()).getRoleId());
|
||||
return event.getMember().getRoles().contains(dj);
|
||||
});
|
||||
|
||||
public final Category ADMIN = new Category("Admin", event ->
|
||||
public Bot(EventWaiter waiter, BotConfig config, SettingsManager settings)
|
||||
{
|
||||
if(event.getAuthor().getId().equals(event.getClient().getOwnerId()))
|
||||
return true;
|
||||
if(event.getGuild()==null)
|
||||
return true;
|
||||
return event.getMember().hasPermission(Permission.MANAGE_SERVER);
|
||||
});
|
||||
|
||||
public final Category OWNER = new Category("Owner");
|
||||
|
||||
public Bot(EventWaiter waiter, Config config)
|
||||
{
|
||||
this.config = config;
|
||||
this.waiter = waiter;
|
||||
this.settings = new HashMap<>();
|
||||
this.lastNP = new HashMap<>();
|
||||
manager = new DefaultAudioPlayerManager();
|
||||
threadpool = Executors.newSingleThreadScheduledExecutor();
|
||||
AudioSourceManagers.registerRemoteSources(manager);
|
||||
AudioSourceManagers.registerLocalSource(manager);
|
||||
manager.source(YoutubeAudioSourceManager.class).setPlaylistPageCount(10);
|
||||
try {
|
||||
JSONObject loadedSettings = new JSONObject(new String(Files.readAllBytes(Paths.get("serversettings.json"))));
|
||||
loadedSettings.keySet().forEach((id) -> {
|
||||
JSONObject o = loadedSettings.getJSONObject(id);
|
||||
|
||||
settings.put(id, new Settings(
|
||||
o.has("text_channel_id") ? o.getString("text_channel_id") : null,
|
||||
o.has("voice_channel_id")? o.getString("voice_channel_id"): null,
|
||||
o.has("dj_role_id") ? o.getString("dj_role_id") : null,
|
||||
o.has("volume") ? o.getInt("volume") : 100,
|
||||
o.has("default_playlist")? o.getString("default_playlist"): null,
|
||||
o.has("repeat") ? o.getBoolean("repeat") : false));
|
||||
});
|
||||
} catch(IOException | JSONException e) {
|
||||
LoggerFactory.getLogger("Settings").warn("Failed to load server settings (this is normal if no settings have been set yet): "+e);
|
||||
}
|
||||
this.config = config;
|
||||
this.settings = settings;
|
||||
this.playlists = new PlaylistLoader(config);
|
||||
this.threadpool = Executors.newSingleThreadScheduledExecutor();
|
||||
this.players = new PlayerManager(this);
|
||||
this.players.init();
|
||||
this.nowplaying = new NowplayingHandler(this);
|
||||
this.nowplaying.init();
|
||||
}
|
||||
|
||||
public JDA getJDA()
|
||||
public BotConfig getConfig()
|
||||
{
|
||||
return jda;
|
||||
return config;
|
||||
}
|
||||
|
||||
public SettingsManager getSettingsManager()
|
||||
{
|
||||
return settings;
|
||||
}
|
||||
|
||||
public EventWaiter getWaiter()
|
||||
@@ -133,43 +75,36 @@ public class Bot extends ListenerAdapter {
|
||||
return waiter;
|
||||
}
|
||||
|
||||
public AudioPlayerManager getAudioManager()
|
||||
{
|
||||
return manager;
|
||||
}
|
||||
|
||||
public ScheduledExecutorService getThreadpool()
|
||||
{
|
||||
return threadpool;
|
||||
}
|
||||
|
||||
public int queueTrack(CommandEvent event, AudioTrack track)
|
||||
public PlayerManager getPlayerManager()
|
||||
{
|
||||
return setUpHandler(event).addTrack(track, event.getAuthor());
|
||||
return players;
|
||||
}
|
||||
|
||||
public AudioHandler setUpHandler(CommandEvent event)
|
||||
public PlaylistLoader getPlaylistLoader()
|
||||
{
|
||||
return setUpHandler(event.getGuild());
|
||||
return playlists;
|
||||
}
|
||||
|
||||
public AudioHandler setUpHandler(Guild guild)
|
||||
public NowplayingHandler getNowplayingHandler()
|
||||
{
|
||||
AudioHandler handler;
|
||||
if(guild.getAudioManager().getSendingHandler()==null)
|
||||
{
|
||||
AudioPlayer player = manager.createPlayer();
|
||||
if(settings.containsKey(guild.getId()))
|
||||
player.setVolume(settings.get(guild.getId()).getVolume());
|
||||
handler = new AudioHandler(player, guild, this);
|
||||
player.addListener(handler);
|
||||
guild.getAudioManager().setSendingHandler(handler);
|
||||
if(AudioHandler.USE_NP_REFRESH)
|
||||
threadpool.scheduleWithFixedDelay(() -> updateLastNP(guild.getIdLong()), 0, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
else
|
||||
handler = (AudioHandler)guild.getAudioManager().getSendingHandler();
|
||||
return handler;
|
||||
return nowplaying;
|
||||
}
|
||||
|
||||
public JDA getJDA()
|
||||
{
|
||||
return jda;
|
||||
}
|
||||
|
||||
public void closeAudioConnection(long guildId)
|
||||
{
|
||||
Guild guild = jda.getGuildById(guildId);
|
||||
if(guild!=null)
|
||||
threadpool.submit(() -> guild.getAudioManager().closeAudioConnection());
|
||||
}
|
||||
|
||||
public void resetGame()
|
||||
@@ -178,324 +113,40 @@ public class Bot extends ListenerAdapter {
|
||||
if(!Objects.equals(jda.getPresence().getGame(), game))
|
||||
jda.getPresence().setGame(game);
|
||||
}
|
||||
|
||||
public void setLastNP(Message m)
|
||||
{
|
||||
lastNP.put(m.getGuild().getIdLong(), new Pair<>(m.getTextChannel().getIdLong(), m.getIdLong()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageDelete(MessageDeleteEvent event) {
|
||||
if(lastNP.containsKey(event.getGuild().getIdLong()))
|
||||
{
|
||||
Pair<Long,Long> pair = lastNP.get(event.getGuild().getIdLong());
|
||||
if(pair.getValue()==event.getMessageIdLong())
|
||||
lastNP.remove(event.getGuild().getIdLong());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLastNP(long guildId)
|
||||
public void shutdown()
|
||||
{
|
||||
Guild guild = jda.getGuildById(guildId);
|
||||
if(guild==null)
|
||||
if(shuttingDown)
|
||||
return;
|
||||
if(!lastNP.containsKey(guildId))
|
||||
return;
|
||||
Pair<Long,Long> pair = lastNP.get(guildId);
|
||||
if(pair==null)
|
||||
return;
|
||||
TextChannel tc = guild.getTextChannelById(pair.getKey());
|
||||
if(tc==null)
|
||||
{
|
||||
lastNP.remove(guildId);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
tc.editMessageById(pair.getValue(), FormatUtil.nowPlayingMessage(guild, config.getSuccess())).queue(m->{}, t -> lastNP.remove(guildId));
|
||||
} catch(Exception e) {
|
||||
lastNP.remove(guildId);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateTopic(long guildId, AudioHandler handler)
|
||||
{
|
||||
Guild guild = jda.getGuildById(guildId);
|
||||
if(guild==null)
|
||||
return;
|
||||
TextChannel tchan = guild.getTextChannelById(getSettings(guild).getTextId());
|
||||
if(tchan!=null && guild.getSelfMember().hasPermission(tchan, Permission.MANAGE_CHANNEL))
|
||||
{
|
||||
String otherText;
|
||||
if(tchan.getTopic()==null || tchan.getTopic().isEmpty())
|
||||
otherText = "\u200B";
|
||||
else if(tchan.getTopic().contains("\u200B"))
|
||||
otherText = tchan.getTopic().substring(tchan.getTopic().lastIndexOf("\u200B"));
|
||||
else
|
||||
otherText = "\u200B\n "+tchan.getTopic();
|
||||
String text = FormatUtil.topicFormat(handler, guild.getJDA())+otherText;
|
||||
if(!text.equals(tchan.getTopic()))
|
||||
try {
|
||||
tchan.getManager().setTopic(text).queue();
|
||||
} catch(PermissionException e){}
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown(){
|
||||
manager.shutdown();
|
||||
shuttingDown = true;
|
||||
threadpool.shutdownNow();
|
||||
jda.getGuilds().stream().forEach(g -> {
|
||||
g.getAudioManager().closeAudioConnection();
|
||||
AudioHandler ah = (AudioHandler)g.getAudioManager().getSendingHandler();
|
||||
if(ah!=null)
|
||||
if(jda.getStatus()!=JDA.Status.SHUTTING_DOWN)
|
||||
{
|
||||
jda.getGuilds().stream().forEach(g ->
|
||||
{
|
||||
ah.getQueue().clear();
|
||||
ah.getPlayer().destroy();
|
||||
updateTopic(g.getIdLong(), ah);
|
||||
}
|
||||
});
|
||||
jda.shutdown();
|
||||
g.getAudioManager().closeAudioConnection();
|
||||
AudioHandler ah = (AudioHandler)g.getAudioManager().getSendingHandler();
|
||||
if(ah!=null)
|
||||
{
|
||||
ah.stopAndClear();
|
||||
ah.getPlayer().destroy();
|
||||
nowplaying.updateTopic(g.getIdLong(), ah, true);
|
||||
}
|
||||
});
|
||||
jda.shutdown();
|
||||
}
|
||||
if(gui!=null)
|
||||
gui.dispose();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
public void setJDA(JDA jda)
|
||||
{
|
||||
this.jda = jda;
|
||||
}
|
||||
|
||||
public void setGUI(GUI gui)
|
||||
{
|
||||
this.gui = gui;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShutdown(ShutdownEvent event) {
|
||||
if(gui!=null)
|
||||
gui.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReady(ReadyEvent event) {
|
||||
this.jda = event.getJDA();
|
||||
if(jda.getGuilds().isEmpty())
|
||||
{
|
||||
Logger log = LoggerFactory.getLogger("MusicBot");
|
||||
log.warn("This bot is not on any guilds! Use the following link to add the bot to your guilds!");
|
||||
log.warn(event.getJDA().asBot().getInviteUrl(JMusicBot.RECOMMENDED_PERMS));
|
||||
}
|
||||
credit(event.getJDA());
|
||||
jda.getGuilds().forEach((guild) -> {
|
||||
try
|
||||
{
|
||||
String defpl = getSettings(guild).getDefaultPlaylist();
|
||||
VoiceChannel vc = guild.getVoiceChannelById(getSettings(guild).getVoiceId());
|
||||
if(defpl!=null && vc!=null)
|
||||
{
|
||||
if(setUpHandler(guild).playFromDefault())
|
||||
guild.getAudioManager().openAudioConnection(vc);
|
||||
}
|
||||
}
|
||||
catch(Exception ex) {System.err.println(ex);}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuildJoin(GuildJoinEvent event) {
|
||||
credit(event.getJDA());
|
||||
}
|
||||
|
||||
// make sure people aren't adding clones to dbots
|
||||
private void credit(JDA jda)
|
||||
{
|
||||
Guild dbots = jda.getGuildById(110373943822540800L);
|
||||
if(dbots==null)
|
||||
return;
|
||||
if(config.getDBots())
|
||||
return;
|
||||
jda.getTextChannelById(119222314964353025L)
|
||||
.sendMessage("<@113156185389092864>: This account is running JMusicBot. Please do not list bot clones on this server, <@"+config.getOwnerId()+">.").complete();
|
||||
dbots.leave().queue();
|
||||
}
|
||||
|
||||
// settings
|
||||
|
||||
public Settings getSettings(Guild guild)
|
||||
{
|
||||
return settings.getOrDefault(guild.getId(), Settings.DEFAULT_SETTINGS);
|
||||
}
|
||||
|
||||
public void setTextChannel(TextChannel channel)
|
||||
{
|
||||
Settings s = settings.get(channel.getGuild().getId());
|
||||
if(s==null)
|
||||
{
|
||||
settings.put(channel.getGuild().getId(), new Settings(channel.getId(),null,null,100,null,false));
|
||||
}
|
||||
else
|
||||
{
|
||||
s.setTextId(channel.getIdLong());
|
||||
}
|
||||
writeSettings();
|
||||
}
|
||||
|
||||
public void setVoiceChannel(VoiceChannel channel)
|
||||
{
|
||||
Settings s = settings.get(channel.getGuild().getId());
|
||||
if(s==null)
|
||||
{
|
||||
settings.put(channel.getGuild().getId(), new Settings(null,channel.getId(),null,100,null,false));
|
||||
}
|
||||
else
|
||||
{
|
||||
s.setVoiceId(channel.getIdLong());
|
||||
}
|
||||
writeSettings();
|
||||
}
|
||||
|
||||
public void setRole(Role role)
|
||||
{
|
||||
Settings s = settings.get(role.getGuild().getId());
|
||||
if(s==null)
|
||||
{
|
||||
settings.put(role.getGuild().getId(), new Settings(null,null,role.getId(),100,null,false));
|
||||
}
|
||||
else
|
||||
{
|
||||
s.setRoleId(role.getIdLong());
|
||||
}
|
||||
writeSettings();
|
||||
}
|
||||
|
||||
public void setDefaultPlaylist(Guild guild, String playlist)
|
||||
{
|
||||
Settings s = settings.get(guild.getId());
|
||||
if(s==null)
|
||||
{
|
||||
settings.put(guild.getId(), new Settings(null,null,null,100,playlist,false));
|
||||
}
|
||||
else
|
||||
{
|
||||
s.setDefaultPlaylist(playlist);
|
||||
}
|
||||
writeSettings();
|
||||
}
|
||||
|
||||
public void setVolume(Guild guild, int volume)
|
||||
{
|
||||
Settings s = settings.get(guild.getId());
|
||||
if(s==null)
|
||||
{
|
||||
settings.put(guild.getId(), new Settings(null,null,null,volume,null,false));
|
||||
}
|
||||
else
|
||||
{
|
||||
s.setVolume(volume);
|
||||
}
|
||||
writeSettings();
|
||||
}
|
||||
|
||||
public void setRepeatMode(Guild guild, boolean mode)
|
||||
{
|
||||
Settings s = settings.get(guild.getId());
|
||||
if(s==null)
|
||||
{
|
||||
settings.put(guild.getId(), new Settings(null,null,null,100,null,mode));
|
||||
}
|
||||
else
|
||||
{
|
||||
s.setRepeatMode(mode);
|
||||
}
|
||||
writeSettings();
|
||||
}
|
||||
|
||||
public void clearTextChannel(Guild guild)
|
||||
{
|
||||
Settings s = getSettings(guild);
|
||||
if(s!=Settings.DEFAULT_SETTINGS)
|
||||
{
|
||||
if(s.getVoiceId()==0 && s.getRoleId()==0)
|
||||
settings.remove(guild.getId());
|
||||
else
|
||||
s.setTextId(0);
|
||||
writeSettings();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearVoiceChannel(Guild guild)
|
||||
{
|
||||
Settings s = getSettings(guild);
|
||||
if(s!=Settings.DEFAULT_SETTINGS)
|
||||
{
|
||||
if(s.getTextId()==0 && s.getRoleId()==0)
|
||||
settings.remove(guild.getId());
|
||||
else
|
||||
s.setVoiceId(0);
|
||||
writeSettings();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearRole(Guild guild)
|
||||
{
|
||||
Settings s = getSettings(guild);
|
||||
if(s!=Settings.DEFAULT_SETTINGS)
|
||||
{
|
||||
if(s.getVoiceId()==0 && s.getTextId()==0)
|
||||
settings.remove(guild.getId());
|
||||
else
|
||||
s.setRoleId(0);
|
||||
writeSettings();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeSettings()
|
||||
{
|
||||
JSONObject obj = new JSONObject();
|
||||
settings.keySet().stream().forEach(key -> {
|
||||
JSONObject o = new JSONObject();
|
||||
Settings s = settings.get(key);
|
||||
if(s.getTextId()!=0)
|
||||
o.put("text_channel_id", Long.toString(s.getTextId()));
|
||||
if(s.getVoiceId()!=0)
|
||||
o.put("voice_channel_id", Long.toString(s.getVoiceId()));
|
||||
if(s.getRoleId()!=0)
|
||||
o.put("dj_role_id", Long.toString(s.getRoleId()));
|
||||
if(s.getVolume()!=100)
|
||||
o.put("volume",s.getVolume());
|
||||
if(s.getDefaultPlaylist()!=null)
|
||||
o.put("default_playlist", s.getDefaultPlaylist());
|
||||
if(s.getRepeatMode())
|
||||
o.put("repeat", true);
|
||||
obj.put(key, o);
|
||||
});
|
||||
try {
|
||||
Files.write(Paths.get("serversettings.json"), obj.toString(4).getBytes());
|
||||
} catch(IOException ex){
|
||||
LoggerFactory.getLogger("Settings").warn("Failed to write to file: "+ex);
|
||||
}
|
||||
}
|
||||
|
||||
//gui stuff
|
||||
/*public void registerPanel(GuildsPanel panel)
|
||||
{
|
||||
this.panel = panel;
|
||||
threadpool.scheduleWithFixedDelay(() -> updatePanel(), 0, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public void updatePanel()
|
||||
{
|
||||
System.out.println("updating...");
|
||||
Guild guild = jda.getGuilds().get(panel.getIndex());
|
||||
panel.updatePanel((AudioHandler)guild.getAudioManager().getSendingHandler());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuildJoin(GuildJoinEvent event) {
|
||||
if(panel!=null)
|
||||
panel.updateList(event.getJDA().getGuilds());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuildLeave(GuildLeaveEvent event) {
|
||||
if(panel!=null)
|
||||
panel.updateList(event.getJDA().getGuilds());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShutdown(ShutdownEvent event) {
|
||||
((GUI)panel.getTopLevelAncestor()).dispose();
|
||||
}*/
|
||||
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright 2018 John Grosh (jagrosh)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot;
|
||||
|
||||
import com.jagrosh.jmusicbot.entities.Prompt;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import com.jagrosh.jmusicbot.utils.OtherUtil;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import com.typesafe.config.*;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import net.dv8tion.jda.core.OnlineStatus;
|
||||
import net.dv8tion.jda.core.entities.Game;
|
||||
|
||||
/**
|
||||
* @author Your Name
|
||||
* Changes from original source:
|
||||
* - Changed "searching" to "finding"
|
||||
*
|
||||
*
|
||||
* @author John Grosh (jagrosh)
|
||||
*/
|
||||
public class BotConfig
|
||||
{
|
||||
private final Prompt prompt;
|
||||
private final static String CONTEXT = "Config";
|
||||
|
||||
private Path path = null;
|
||||
private String token, prefix, altprefix, helpWord, playlistsFolder,
|
||||
successEmoji, warningEmoji, errorEmoji, loadingEmoji, searchingEmoji;
|
||||
private boolean stayInChannel, songInGame, npImages, updatealerts, useEval, dbots;
|
||||
private long owner, maxSeconds;
|
||||
private OnlineStatus status;
|
||||
private Game game;
|
||||
|
||||
private boolean valid = false;
|
||||
|
||||
public BotConfig(Prompt prompt)
|
||||
{
|
||||
this.prompt = prompt;
|
||||
}
|
||||
|
||||
public void load()
|
||||
{
|
||||
valid = false;
|
||||
|
||||
// read config from file
|
||||
try
|
||||
{
|
||||
// get the path to the config, default config.txt
|
||||
path = Paths.get(System.getProperty("config.file", System.getProperty("config", "config.txt")));
|
||||
if(path.toFile().exists())
|
||||
{
|
||||
if(System.getProperty("config.file") == null)
|
||||
System.setProperty("config.file", System.getProperty("config", "config.txt"));
|
||||
ConfigFactory.invalidateCaches();
|
||||
}
|
||||
|
||||
// load in the config file, plus the default values
|
||||
//Config config = ConfigFactory.parseFile(path.toFile()).withFallback(ConfigFactory.load());
|
||||
Config config = ConfigFactory.load();
|
||||
|
||||
// set values
|
||||
token = config.getString("token");
|
||||
prefix = config.getString("prefix");
|
||||
altprefix = config.getString("altprefix");
|
||||
helpWord = config.getString("help");
|
||||
owner = config.getLong("owner");
|
||||
successEmoji = config.getString("success");
|
||||
warningEmoji = config.getString("warning");
|
||||
errorEmoji = config.getString("error");
|
||||
loadingEmoji = config.getString("loading");
|
||||
searchingEmoji = config.getString("searching");
|
||||
game = OtherUtil.parseGame(config.getString("game"));
|
||||
status = OtherUtil.parseStatus(config.getString("status"));
|
||||
stayInChannel = config.getBoolean("stayinchannel");
|
||||
songInGame = config.getBoolean("songinstatus");
|
||||
npImages = config.getBoolean("npimages");
|
||||
updatealerts = config.getBoolean("updatealerts");
|
||||
useEval = config.getBoolean("eval");
|
||||
maxSeconds = config.getLong("maxtime");
|
||||
playlistsFolder = config.getString("playlistsfolder");
|
||||
dbots = owner == 113156185389092864L;
|
||||
|
||||
// we may need to get some additional data and write a new config file
|
||||
List<String> lines = new LinkedList<>();
|
||||
|
||||
// validate bot token
|
||||
if(token==null || token.isEmpty() || token.equalsIgnoreCase("BOT_TOKEN_HERE"))
|
||||
{
|
||||
token = prompt.prompt("Please provide a bot token."
|
||||
+ "\nInstructions for obtaining a token can be found here:"
|
||||
+ "\nhttps://github.com/jagrosh/MusicBot/wiki/Getting-a-Bot-Token."
|
||||
+ "\nBot Token: ");
|
||||
if(token==null)
|
||||
{
|
||||
prompt.alert(Prompt.Level.WARNING, CONTEXT, "No token provided! Exiting.\n\nConfig Location: " + path.toAbsolutePath().toString());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
lines.add("token = "+token);
|
||||
}
|
||||
}
|
||||
|
||||
// validate bot owner
|
||||
if(owner<=0)
|
||||
{
|
||||
try
|
||||
{
|
||||
owner = Long.parseLong(prompt.prompt("Owner ID was missing, or the provided owner ID is not valid."
|
||||
+ "\nPlease provide the User ID of the bot's owner."
|
||||
+ "\nInstructions for obtaining your User ID can be found here:"
|
||||
+ "\nhttps://github.com/jagrosh/MusicBot/wiki/Finding-Your-User-ID"
|
||||
+ "\nOwner User ID: "));
|
||||
}
|
||||
catch(NumberFormatException | NullPointerException ex)
|
||||
{
|
||||
owner = 0;
|
||||
}
|
||||
if(owner<=0)
|
||||
{
|
||||
prompt.alert(Prompt.Level.ERROR, CONTEXT, "Invalid User ID! Exiting.\n\nConfig Location: " + path.toAbsolutePath().toString());
|
||||
System.exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
lines.add("owner = "+owner);
|
||||
}
|
||||
}
|
||||
|
||||
if(!lines.isEmpty())
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
lines.stream().forEach(s -> builder.append(s).append("\r\n"));
|
||||
try
|
||||
{
|
||||
Files.write(path, builder.toString().trim().getBytes());
|
||||
}
|
||||
catch(IOException ex)
|
||||
{
|
||||
prompt.alert(Prompt.Level.WARNING, CONTEXT, "Failed to write new config options to config.txt: "+ex
|
||||
+ "\nPlease make sure that the files are not on your desktop or some other restricted area.\n\nConfig Location: "
|
||||
+ path.toAbsolutePath().toString());
|
||||
}
|
||||
}
|
||||
|
||||
// if we get through the whole config, it's good to go
|
||||
valid = true;
|
||||
}
|
||||
catch (ConfigException ex)
|
||||
{
|
||||
prompt.alert(Prompt.Level.ERROR, CONTEXT, ex + ": " + ex.getMessage() + "\n\nConfig Location: " + path.toAbsolutePath().toString());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isValid()
|
||||
{
|
||||
return valid;
|
||||
}
|
||||
|
||||
public String getConfigLocation()
|
||||
{
|
||||
return path.toFile().getAbsolutePath();
|
||||
}
|
||||
|
||||
public String getPrefix()
|
||||
{
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public String getAltPrefix()
|
||||
{
|
||||
return "NONE".equalsIgnoreCase(altprefix) ? null : altprefix;
|
||||
}
|
||||
|
||||
public String getToken()
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
public long getOwnerId()
|
||||
{
|
||||
return owner;
|
||||
}
|
||||
|
||||
public String getSuccess()
|
||||
{
|
||||
return successEmoji;
|
||||
}
|
||||
|
||||
public String getWarning()
|
||||
{
|
||||
return warningEmoji;
|
||||
}
|
||||
|
||||
public String getError()
|
||||
{
|
||||
return errorEmoji;
|
||||
}
|
||||
|
||||
public String getLoading()
|
||||
{
|
||||
return loadingEmoji;
|
||||
}
|
||||
|
||||
public String getSearching()
|
||||
{
|
||||
return searchingEmoji;
|
||||
}
|
||||
|
||||
public Game getGame()
|
||||
{
|
||||
return game;
|
||||
}
|
||||
|
||||
public OnlineStatus getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public String getHelp()
|
||||
{
|
||||
return helpWord;
|
||||
}
|
||||
|
||||
public boolean getStay()
|
||||
{
|
||||
return stayInChannel;
|
||||
}
|
||||
|
||||
public boolean getSongInStatus()
|
||||
{
|
||||
return songInGame;
|
||||
}
|
||||
|
||||
public String getPlaylistsFolder()
|
||||
{
|
||||
return playlistsFolder;
|
||||
}
|
||||
|
||||
public boolean getDBots()
|
||||
{
|
||||
return dbots;
|
||||
}
|
||||
|
||||
public boolean useUpdateAlerts()
|
||||
{
|
||||
return updatealerts;
|
||||
}
|
||||
|
||||
public boolean useEval()
|
||||
{
|
||||
return useEval;
|
||||
}
|
||||
|
||||
public boolean useNPImages()
|
||||
{
|
||||
return npImages;
|
||||
}
|
||||
|
||||
public long getMaxSeconds()
|
||||
{
|
||||
return maxSeconds;
|
||||
}
|
||||
|
||||
public String getMaxTime()
|
||||
{
|
||||
return FormatUtil.formatTime(maxSeconds * 1000);
|
||||
}
|
||||
|
||||
public boolean isTooLong(AudioTrack track)
|
||||
{
|
||||
if(maxSeconds<=0)
|
||||
return false;
|
||||
return Math.round(track.getDuration()/1000.0) > maxSeconds;
|
||||
}
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh (jagrosh)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import javax.swing.JOptionPane;
|
||||
import net.dv8tion.jda.core.OnlineStatus;
|
||||
import net.dv8tion.jda.core.entities.Game;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (jagrosh)
|
||||
*/
|
||||
public class Config {
|
||||
private boolean nogui;
|
||||
private String prefix, altprefix, token, owner, success, warning, error, game,
|
||||
help, loadingEmoji, searchingEmoji;
|
||||
private boolean stay, dbots, songingame, useEval, npimages;
|
||||
private long maxSeconds;
|
||||
private OnlineStatus status = OnlineStatus.UNKNOWN;
|
||||
|
||||
public Config(boolean nogui)
|
||||
{
|
||||
this.nogui = nogui;
|
||||
List<String> lines;
|
||||
try {
|
||||
lines = Files.readAllLines(Paths.get("config.txt"), StandardCharsets.UTF_8);
|
||||
System.out.println("[INFO] Loading config: "+Paths.get("config.txt").toFile().getAbsolutePath());
|
||||
for(String line: lines)
|
||||
{
|
||||
String[] parts = line.split("=",2);
|
||||
String key = parts[0].trim().toLowerCase();
|
||||
String value = parts.length>1 ? parts[1].trim() : null;
|
||||
switch(key)
|
||||
{
|
||||
case "token":
|
||||
token = value;
|
||||
break;
|
||||
case "prefix":
|
||||
prefix = value;
|
||||
break;
|
||||
case "altprefix":
|
||||
altprefix = value;
|
||||
break;
|
||||
case "owner":
|
||||
owner = value;
|
||||
break;
|
||||
case "success":
|
||||
success = value;
|
||||
break;
|
||||
case "warning":
|
||||
warning = value;
|
||||
break;
|
||||
case "error":
|
||||
error = value;
|
||||
break;
|
||||
case "loading":
|
||||
loadingEmoji = value;
|
||||
break;
|
||||
case "searching":
|
||||
searchingEmoji = value;
|
||||
break;
|
||||
case "game":
|
||||
game = value;
|
||||
break;
|
||||
case "help":
|
||||
help = value;
|
||||
break;
|
||||
case "songinstatus":
|
||||
songingame = "true".equalsIgnoreCase(value);
|
||||
break;
|
||||
case "stayinchannel":
|
||||
stay = "true".equalsIgnoreCase(value);
|
||||
break;
|
||||
case "eval":
|
||||
useEval = "true".equalsIgnoreCase(value);
|
||||
break;
|
||||
case "dbots":
|
||||
dbots = "110373943822540800".equals(value);
|
||||
break;
|
||||
case "npimages":
|
||||
npimages = "true".equalsIgnoreCase(value);
|
||||
break;
|
||||
case "maxtime":
|
||||
try{
|
||||
maxSeconds = Long.parseLong(value);
|
||||
}catch(NumberFormatException e){}
|
||||
break;
|
||||
case "status":
|
||||
status = OnlineStatus.fromKey(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
alert("'config.txt' was not found!");
|
||||
lines = new LinkedList<>();
|
||||
}
|
||||
boolean write = false;
|
||||
if(token==null || token.isEmpty())
|
||||
{
|
||||
token = prompt("Please provide a bot token."
|
||||
+ "\nInstructions for obtaining a token can be found here:"
|
||||
+ "\nhttps://github.com/jagrosh/MusicBot/wiki/Getting-a-Bot-Token."
|
||||
+ "\nBot Token: ");
|
||||
if(token==null)
|
||||
{
|
||||
alert("No token provided! Exiting.");
|
||||
System.exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
lines.add("token="+token);
|
||||
write = true;
|
||||
}
|
||||
}
|
||||
if(owner==null || !owner.matches("\\d{17,20}"))
|
||||
{
|
||||
owner = prompt("Owner ID was missing, or the provided owner ID is not valid."
|
||||
+ "\nPlease provide the User ID of the bot's owner."
|
||||
+ "\nInstructions for obtaining your User ID can be found here:"
|
||||
+ "\nhttps://github.com/jagrosh/MusicBot/wiki/Finding-Your-User-ID"
|
||||
+ "\nOwner User ID: ");
|
||||
if(owner==null || !owner.matches("\\d{17,20}"))
|
||||
{
|
||||
alert("Invalid User ID! Exiting.");
|
||||
System.exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
lines.add("owner="+owner);
|
||||
write = true;
|
||||
}
|
||||
}
|
||||
if(write)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
lines.stream().forEach(s -> builder.append(s).append("\r\n"));
|
||||
try {
|
||||
Files.write(Paths.get("config.txt"), builder.toString().trim().getBytes());
|
||||
} catch(IOException ex) {
|
||||
alert("Failed to write new config options to config.txt: "+ex
|
||||
+ "\nPlease make sure that the files are not on your desktop or some other restricted area.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getPrefix()
|
||||
{
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public String getAltPrefix()
|
||||
{
|
||||
return altprefix;
|
||||
}
|
||||
|
||||
public String getToken()
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
public String getOwnerId()
|
||||
{
|
||||
return owner;
|
||||
}
|
||||
|
||||
public String getSuccess()
|
||||
{
|
||||
return success==null ? "\uD83C\uDFB6" : success;
|
||||
}
|
||||
|
||||
public String getWarning()
|
||||
{
|
||||
return warning==null ? "\uD83D\uDCA1" : warning;
|
||||
}
|
||||
|
||||
public String getError()
|
||||
{
|
||||
return error==null ? "\uD83D\uDEAB" : error;
|
||||
}
|
||||
|
||||
public String getLoading()
|
||||
{
|
||||
return loadingEmoji==null ? "\u231A" : loadingEmoji;
|
||||
}
|
||||
|
||||
public String getSearching()
|
||||
{
|
||||
return searchingEmoji==null ? "\uD83D\uDD0E" : searchingEmoji;
|
||||
}
|
||||
|
||||
public Game getGame()
|
||||
{
|
||||
if(game==null || game.isEmpty())
|
||||
return null;
|
||||
if(game.toLowerCase().startsWith("playing"))
|
||||
return Game.playing(game.substring(7).trim());
|
||||
if(game.toLowerCase().startsWith("listening to"))
|
||||
return Game.listening(game.substring(12).trim());
|
||||
if(game.toLowerCase().startsWith("listening"))
|
||||
return Game.listening(game.substring(9).trim());
|
||||
if(game.toLowerCase().startsWith("watching"))
|
||||
return Game.watching(game.substring(8).trim());
|
||||
return Game.playing(game);
|
||||
}
|
||||
|
||||
public String getHelp()
|
||||
{
|
||||
return help==null ? "help" : help;
|
||||
}
|
||||
|
||||
public boolean getNoGui()
|
||||
{
|
||||
return nogui;
|
||||
}
|
||||
|
||||
public boolean getStay()
|
||||
{
|
||||
return stay;
|
||||
}
|
||||
|
||||
public boolean getSongInStatus()
|
||||
{
|
||||
return songingame;
|
||||
}
|
||||
|
||||
public boolean getDBots()
|
||||
{
|
||||
return dbots;
|
||||
}
|
||||
|
||||
public boolean useEval()
|
||||
{
|
||||
return useEval;
|
||||
}
|
||||
|
||||
public boolean useNPImages()
|
||||
{
|
||||
return npimages;
|
||||
}
|
||||
|
||||
public long getMaxSeconds()
|
||||
{
|
||||
return maxSeconds;
|
||||
}
|
||||
|
||||
public OnlineStatus getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
private void alert(String message)
|
||||
{
|
||||
if(nogui)
|
||||
System.out.println("[WARNING] "+message);
|
||||
else
|
||||
{
|
||||
try {
|
||||
JOptionPane.showMessageDialog(null, message, "JMusicBot", JOptionPane.WARNING_MESSAGE);
|
||||
} catch(Exception e) {
|
||||
nogui = true;
|
||||
alert("Switching to nogui mode. You can manually start in nogui mode by including the -nogui flag.");
|
||||
alert(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String prompt(String content)
|
||||
{
|
||||
if(nogui)
|
||||
{
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
System.out.println(content);
|
||||
return scanner.next();
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
return JOptionPane.showInputDialog(null, content, "JMusicBot", JOptionPane.WARNING_MESSAGE);
|
||||
} catch(Exception e) {
|
||||
nogui = true;
|
||||
alert("Switching to nogui mode. You can manually start in nogui mode by including the -nogui flag.");
|
||||
return prompt(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,71 +15,94 @@
|
||||
*/
|
||||
package com.jagrosh.jmusicbot;
|
||||
|
||||
import java.awt.Color;
|
||||
import javax.security.auth.login.LoginException;
|
||||
import com.jagrosh.jdautilities.command.CommandClient;
|
||||
import com.jagrosh.jdautilities.command.CommandClientBuilder;
|
||||
import com.jagrosh.jdautilities.commons.waiter.EventWaiter;
|
||||
import com.jagrosh.jdautilities.examples.command.*;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.commands.*;
|
||||
import com.jagrosh.jmusicbot.commands.admin.*;
|
||||
import com.jagrosh.jmusicbot.commands.dj.*;
|
||||
import com.jagrosh.jmusicbot.commands.general.*;
|
||||
import com.jagrosh.jmusicbot.commands.music.*;
|
||||
import com.jagrosh.jmusicbot.commands.owner.*;
|
||||
import com.jagrosh.jmusicbot.entities.Prompt;
|
||||
import com.jagrosh.jmusicbot.gui.GUI;
|
||||
import net.dv8tion.jda.core.AccountType;
|
||||
import net.dv8tion.jda.core.JDABuilder;
|
||||
import net.dv8tion.jda.core.OnlineStatus;
|
||||
import net.dv8tion.jda.core.Permission;
|
||||
import com.jagrosh.jmusicbot.settings.SettingsManager;
|
||||
import com.jagrosh.jmusicbot.utils.OtherUtil;
|
||||
import java.awt.Color;
|
||||
import javax.security.auth.login.LoginException;
|
||||
import net.dv8tion.jda.core.*;
|
||||
import net.dv8tion.jda.core.entities.Game;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (jagrosh)
|
||||
*/
|
||||
public class JMusicBot {
|
||||
|
||||
public static Permission[] RECOMMENDED_PERMS = new Permission[]{Permission.MESSAGE_READ, Permission.MESSAGE_WRITE, Permission.MESSAGE_HISTORY, Permission.MESSAGE_ADD_REACTION,
|
||||
public class JMusicBot
|
||||
{
|
||||
public final static String PLAY_EMOJI = "\u25B6"; // ▶
|
||||
public final static String PAUSE_EMOJI = "\u23F8"; // ⏸
|
||||
public final static String STOP_EMOJI = "\u23F9"; // ⏹
|
||||
public final static Permission[] RECOMMENDED_PERMS = new Permission[]{Permission.MESSAGE_READ, Permission.MESSAGE_WRITE, Permission.MESSAGE_HISTORY, Permission.MESSAGE_ADD_REACTION,
|
||||
Permission.MESSAGE_EMBED_LINKS, Permission.MESSAGE_ATTACH_FILES, Permission.MESSAGE_MANAGE, Permission.MESSAGE_EXT_EMOJI,
|
||||
Permission.MANAGE_CHANNEL, Permission.VOICE_CONNECT, Permission.VOICE_SPEAK, Permission.NICKNAME_CHANGE};
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
public static void main(String[] args){
|
||||
// check run mode(s)
|
||||
boolean nogui = false;
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// startup log
|
||||
Logger log = LoggerFactory.getLogger("Startup");
|
||||
|
||||
// create prompt to handle startup
|
||||
Prompt prompt = new Prompt("JMusicBot", "Switching to nogui mode. You can manually start in nogui mode by including the -Dnogui=true flag.",
|
||||
"true".equalsIgnoreCase(System.getProperty("nogui", "false")));
|
||||
|
||||
// check deprecated nogui mode (new way of setting it is -Dnogui=true)
|
||||
for(String arg: args)
|
||||
if("-nogui".equalsIgnoreCase(arg))
|
||||
nogui = true;
|
||||
{
|
||||
prompt.alert(Prompt.Level.WARNING, "GUI", "The -nogui flag has been deprecated. "
|
||||
+ "Please use the -Dnogui=true flag before the name of the jar. Example: java -jar -Dnogui=true JMusicBot.jar");
|
||||
break;
|
||||
}
|
||||
|
||||
// get and check latest version
|
||||
String version = OtherUtil.checkVersion(prompt);
|
||||
|
||||
// load config
|
||||
Config config = new Config(nogui);
|
||||
BotConfig config = new BotConfig(prompt);
|
||||
config.load();
|
||||
if(!config.isValid())
|
||||
return;
|
||||
|
||||
// set up the listener
|
||||
EventWaiter waiter = new EventWaiter();
|
||||
Bot bot = new Bot(waiter, config);
|
||||
SettingsManager settings = new SettingsManager();
|
||||
Bot bot = new Bot(waiter, config, settings);
|
||||
|
||||
AboutCommand ab = new AboutCommand(Color.BLUE.brighter(),
|
||||
"a music bot that is [easy to host yourself!](https://github.com/jagrosh/MusicBot) (v0.1.2)",
|
||||
AboutCommand aboutCommand = new AboutCommand(Color.BLUE.brighter(),
|
||||
"a music bot that is [easy to host yourself!](https://github.com/jagrosh/MusicBot) (v"+version+")",
|
||||
new String[]{"High-quality music playback", "FairQueue™ Technology", "Easy to host yourself"},
|
||||
RECOMMENDED_PERMS);
|
||||
ab.setIsAuthor(false);
|
||||
ab.setReplacementCharacter("\uD83C\uDFB6");
|
||||
AudioHandler.STAY_IN_CHANNEL = config.getStay();
|
||||
AudioHandler.SONG_IN_STATUS = config.getSongInStatus();
|
||||
AudioHandler.MAX_SECONDS = config.getMaxSeconds();
|
||||
AudioHandler.USE_NP_REFRESH = !config.useNPImages();
|
||||
// set up the command client
|
||||
aboutCommand.setIsAuthor(false);
|
||||
aboutCommand.setReplacementCharacter("\uD83C\uDFB6"); // 🎶
|
||||
|
||||
// set up the command client
|
||||
CommandClientBuilder cb = new CommandClientBuilder()
|
||||
.setPrefix(config.getPrefix())
|
||||
.setAlternativePrefix(config.getAltPrefix())
|
||||
.setOwnerId(config.getOwnerId())
|
||||
.setOwnerId(Long.toString(config.getOwnerId()))
|
||||
.setEmojis(config.getSuccess(), config.getWarning(), config.getError())
|
||||
.setHelpWord(config.getHelp())
|
||||
.addCommands(
|
||||
ab,
|
||||
.setLinkedCacheSize(200)
|
||||
.setGuildSettingsManager(settings)
|
||||
.addCommands(aboutCommand,
|
||||
new PingCommand(),
|
||||
new SettingsCmd(bot),
|
||||
new SettingsCmd(),
|
||||
|
||||
new LyricsCmd(bot),
|
||||
new NowplayingCmd(bot),
|
||||
new PlayCmd(bot, config.getLoading()),
|
||||
new PlaylistsCmd(bot),
|
||||
@@ -92,22 +115,22 @@ public class JMusicBot {
|
||||
|
||||
new ForceskipCmd(bot),
|
||||
new PauseCmd(bot),
|
||||
new PlaynextCmd(bot, config.getLoading()),
|
||||
new RepeatCmd(bot),
|
||||
new SkiptoCmd(bot),
|
||||
new StopCmd(bot),
|
||||
new VolumeCmd(bot),
|
||||
|
||||
new SetdjCmd(bot),
|
||||
new SettcCmd(bot),
|
||||
new SetvcCmd(bot),
|
||||
new SetdjCmd(),
|
||||
new SettcCmd(),
|
||||
new SetvcCmd(),
|
||||
|
||||
//new GuildlistCommand(waiter),
|
||||
new AutoplaylistCmd(bot),
|
||||
new PlaylistCmd(bot),
|
||||
new SetavatarCmd(bot),
|
||||
new SetgameCmd(bot),
|
||||
new SetnameCmd(bot),
|
||||
new SetstatusCmd(bot),
|
||||
new SetavatarCmd(),
|
||||
new SetgameCmd(),
|
||||
new SetnameCmd(),
|
||||
new SetstatusCmd(),
|
||||
new ShutdownCmd(bot)
|
||||
);
|
||||
if(config.useEval())
|
||||
@@ -126,39 +149,48 @@ public class JMusicBot {
|
||||
cb.setGame(config.getGame());
|
||||
CommandClient client = cb.build();
|
||||
|
||||
if(!config.getNoGui())
|
||||
if(!prompt.isNoGUI())
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
GUI gui = new GUI(bot);
|
||||
bot.setGUI(gui);
|
||||
gui.init();
|
||||
} catch(Exception e) {
|
||||
LoggerFactory.getLogger("Startup").error("Could not start GUI. If you are "
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
log.error("Could not start GUI. If you are "
|
||||
+ "running on a server or in a location where you cannot display a "
|
||||
+ "window, please run in nogui mode using the -nogui flag.");
|
||||
+ "window, please run in nogui mode using the -Dnogui=true flag.");
|
||||
}
|
||||
}
|
||||
|
||||
log.info("Loaded config from "+config.getConfigLocation());
|
||||
|
||||
// attempt to log in and start
|
||||
try {
|
||||
new JDABuilder(AccountType.BOT)
|
||||
try
|
||||
{
|
||||
JDA jda = new JDABuilder(AccountType.BOT)
|
||||
.setToken(config.getToken())
|
||||
.setAudioEnabled(true)
|
||||
.setGame(nogame ? null : Game.playing("loading..."))
|
||||
.setStatus(config.getStatus()==OnlineStatus.INVISIBLE||config.getStatus()==OnlineStatus.OFFLINE ? OnlineStatus.INVISIBLE : OnlineStatus.DO_NOT_DISTURB)
|
||||
.addEventListener(client)
|
||||
.addEventListener(waiter)
|
||||
.addEventListener(bot)
|
||||
.buildAsync();
|
||||
} catch (LoginException ex)
|
||||
.addEventListener(client, waiter, new Listener(bot))
|
||||
.setBulkDeleteSplittingEnabled(true)
|
||||
.build();
|
||||
bot.setJDA(jda);
|
||||
}
|
||||
catch (LoginException ex)
|
||||
{
|
||||
LoggerFactory.getLogger("Startup").error(ex+"\nPlease make sure you are "
|
||||
log.error(ex+"\nPlease make sure you are "
|
||||
+ "editing the correct config.txt file, and that you have used the "
|
||||
+ "correct token (not the 'secret'!)");
|
||||
System.exit(1);
|
||||
}
|
||||
catch(IllegalArgumentException ex)
|
||||
{
|
||||
LoggerFactory.getLogger("Startup").error(""+ex);
|
||||
log.error("Some aspect of the configuration is invalid: "+ex);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot;
|
||||
|
||||
import com.jagrosh.jmusicbot.utils.OtherUtil;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.dv8tion.jda.core.JDA;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
import net.dv8tion.jda.core.entities.User;
|
||||
import net.dv8tion.jda.core.entities.VoiceChannel;
|
||||
import net.dv8tion.jda.core.events.ReadyEvent;
|
||||
import net.dv8tion.jda.core.events.ShutdownEvent;
|
||||
import net.dv8tion.jda.core.events.guild.GuildJoinEvent;
|
||||
import net.dv8tion.jda.core.events.message.guild.GuildMessageDeleteEvent;
|
||||
import net.dv8tion.jda.core.hooks.ListenerAdapter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (john.a.grosh@gmail.com)
|
||||
*/
|
||||
public class Listener extends ListenerAdapter
|
||||
{
|
||||
private final Bot bot;
|
||||
|
||||
public Listener(Bot bot)
|
||||
{
|
||||
this.bot = bot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReady(ReadyEvent event)
|
||||
{
|
||||
if(event.getJDA().getGuilds().isEmpty())
|
||||
{
|
||||
Logger log = LoggerFactory.getLogger("MusicBot");
|
||||
log.warn("This bot is not on any guilds! Use the following link to add the bot to your guilds!");
|
||||
log.warn(event.getJDA().asBot().getInviteUrl(JMusicBot.RECOMMENDED_PERMS));
|
||||
}
|
||||
credit(event.getJDA());
|
||||
event.getJDA().getGuilds().forEach((guild) ->
|
||||
{
|
||||
try
|
||||
{
|
||||
String defpl = bot.getSettingsManager().getSettings(guild).getDefaultPlaylist();
|
||||
VoiceChannel vc = bot.getSettingsManager().getSettings(guild).getVoiceChannel(guild);
|
||||
if(defpl!=null && vc!=null && bot.getPlayerManager().setUpHandler(guild).playFromDefault())
|
||||
{
|
||||
guild.getAudioManager().openAudioConnection(vc);
|
||||
}
|
||||
}
|
||||
catch(Exception ignore) {}
|
||||
});
|
||||
if(bot.getConfig().useUpdateAlerts())
|
||||
{
|
||||
bot.getThreadpool().scheduleWithFixedDelay(() ->
|
||||
{
|
||||
User owner = bot.getJDA().getUserById(bot.getConfig().getOwnerId());
|
||||
if(owner!=null)
|
||||
{
|
||||
String currentVersion = OtherUtil.getCurrentVersion();
|
||||
String latestVersion = OtherUtil.getLatestVersion();
|
||||
if(latestVersion!=null && !currentVersion.equalsIgnoreCase(latestVersion))
|
||||
{
|
||||
String msg = String.format(OtherUtil.NEW_VERSION_AVAILABLE, currentVersion, latestVersion);
|
||||
owner.openPrivateChannel().queue(pc -> pc.sendMessage(msg).queue());
|
||||
}
|
||||
}
|
||||
}, 0, 24, TimeUnit.HOURS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuildMessageDelete(GuildMessageDeleteEvent event)
|
||||
{
|
||||
bot.getNowplayingHandler().onMessageDelete(event.getGuild(), event.getMessageIdLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShutdown(ShutdownEvent event)
|
||||
{
|
||||
bot.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuildJoin(GuildJoinEvent event)
|
||||
{
|
||||
credit(event.getJDA());
|
||||
}
|
||||
|
||||
// make sure people aren't adding clones to dbots
|
||||
private void credit(JDA jda)
|
||||
{
|
||||
Guild dbots = jda.getGuildById(110373943822540800L);
|
||||
if(dbots==null)
|
||||
return;
|
||||
if(bot.getConfig().getDBots())
|
||||
return;
|
||||
jda.getTextChannelById(119222314964353025L)
|
||||
.sendMessage("This account is running JMusicBot. Please do not list bot clones on this server, <@"+bot.getConfig().getOwnerId()+">.").complete();
|
||||
dbots.leave().queue();
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.audio;
|
||||
|
||||
import com.jagrosh.jmusicbot.JMusicBot;
|
||||
import com.jagrosh.jmusicbot.playlist.PlaylistLoader.Playlist;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||
import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
@@ -24,51 +26,64 @@ import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.playlist.Playlist;
|
||||
import com.jagrosh.jmusicbot.queue.FairQueue;
|
||||
import com.jagrosh.jmusicbot.settings.Settings;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack;
|
||||
import net.dv8tion.jda.core.EmbedBuilder;
|
||||
import net.dv8tion.jda.core.JDA;
|
||||
import net.dv8tion.jda.core.MessageBuilder;
|
||||
import net.dv8tion.jda.core.audio.AudioSendHandler;
|
||||
import net.dv8tion.jda.core.entities.Game;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
import net.dv8tion.jda.core.entities.Message;
|
||||
import net.dv8tion.jda.core.entities.User;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class AudioHandler extends AudioEventAdapter implements AudioSendHandler {
|
||||
public class AudioHandler extends AudioEventAdapter implements AudioSendHandler
|
||||
{
|
||||
private final FairQueue<QueuedTrack> queue = new FairQueue<>();
|
||||
private final List<AudioTrack> defaultQueue = new LinkedList<>();
|
||||
private final Set<String> votes = new HashSet<>();
|
||||
|
||||
private final PlayerManager manager;
|
||||
private final AudioPlayer audioPlayer;
|
||||
private final long guildId;
|
||||
private final FairQueue<QueuedTrack> queue;
|
||||
private final Set<String> votes;
|
||||
private final List<AudioTrack> defaultQueue;
|
||||
private final Bot bot;
|
||||
|
||||
private AudioFrame lastFrame;
|
||||
private long requester;
|
||||
public static boolean STAY_IN_CHANNEL;
|
||||
public static boolean SONG_IN_STATUS;
|
||||
public static long MAX_SECONDS = -1;
|
||||
public static boolean USE_NP_REFRESH;
|
||||
|
||||
public AudioHandler(AudioPlayer audioPlayer, Guild guild, Bot bot) {
|
||||
this.audioPlayer = audioPlayer;
|
||||
this.guildId = guild.getIdLong();
|
||||
this.bot = bot;
|
||||
queue = new FairQueue<>();
|
||||
votes = new HashSet<>();
|
||||
defaultQueue = new LinkedList<>();
|
||||
protected AudioHandler(PlayerManager manager, Guild guild, AudioPlayer player)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.audioPlayer = player;
|
||||
this.guildId = guild.getIdLong();
|
||||
}
|
||||
|
||||
public int addTrack(AudioTrack track, User user)
|
||||
public int addTrackToFront(QueuedTrack qtrack)
|
||||
{
|
||||
if(audioPlayer.getPlayingTrack()==null)
|
||||
{
|
||||
requester = user.getIdLong();
|
||||
audioPlayer.playTrack(track);
|
||||
audioPlayer.playTrack(qtrack.getTrack());
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return queue.add(new QueuedTrack(track, user.getIdLong()));
|
||||
{
|
||||
queue.addAt(0, qtrack);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int addTrack(QueuedTrack qtrack)
|
||||
{
|
||||
if(audioPlayer.getPlayingTrack()==null)
|
||||
{
|
||||
audioPlayer.playTrack(qtrack.getTrack());
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return queue.add(qtrack);
|
||||
}
|
||||
|
||||
public FairQueue<QueuedTrack> getQueue()
|
||||
@@ -84,9 +99,9 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler
|
||||
//current = null;
|
||||
}
|
||||
|
||||
public boolean isMusicPlaying()
|
||||
public boolean isMusicPlaying(JDA jda)
|
||||
{
|
||||
return bot.getJDA().getGuildById(guildId).getSelfMember().getVoiceState().inVoiceChannel() && audioPlayer.getPlayingTrack()!=null;
|
||||
return guild(jda).getSelfMember().getVoiceState().inVoiceChannel() && audioPlayer.getPlayingTrack()!=null;
|
||||
}
|
||||
|
||||
public Set<String> getVotes()
|
||||
@@ -101,7 +116,9 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler
|
||||
|
||||
public long getRequester()
|
||||
{
|
||||
return requester;
|
||||
if(audioPlayer.getPlayingTrack()==null || audioPlayer.getPlayingTrack().getUserData(Long.class)==null)
|
||||
return 0;
|
||||
return audioPlayer.getPlayingTrack().getUserData(Long.class);
|
||||
}
|
||||
|
||||
public boolean playFromDefault()
|
||||
@@ -111,83 +128,170 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler
|
||||
audioPlayer.playTrack(defaultQueue.remove(0));
|
||||
return true;
|
||||
}
|
||||
Guild guild = bot.getJDA().getGuildById(guildId);
|
||||
if(bot.getSettings(guild)==null || bot.getSettings(guild).getDefaultPlaylist()==null)
|
||||
Settings settings = manager.getBot().getSettingsManager().getSettings(guildId);
|
||||
if(settings==null || settings.getDefaultPlaylist()==null)
|
||||
return false;
|
||||
Playlist pl = Playlist.loadPlaylist(bot.getSettings(guild).getDefaultPlaylist());
|
||||
|
||||
Playlist pl = manager.getBot().getPlaylistLoader().getPlaylist(settings.getDefaultPlaylist());
|
||||
if(pl==null || pl.getItems().isEmpty())
|
||||
return false;
|
||||
pl.loadTracks(bot.getAudioManager(), (at) -> {
|
||||
pl.loadTracks(manager, (at) ->
|
||||
{
|
||||
if(audioPlayer.getPlayingTrack()==null)
|
||||
audioPlayer.playTrack(at);
|
||||
else
|
||||
defaultQueue.add(at);
|
||||
}, () -> {
|
||||
if(pl.getTracks().isEmpty() && !STAY_IN_CHANNEL)
|
||||
guild.getAudioManager().closeAudioConnection();
|
||||
}, () ->
|
||||
{
|
||||
if(pl.getTracks().isEmpty() && !manager.getBot().getConfig().getStay())
|
||||
manager.getBot().closeAudioConnection(guildId);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
// Audio Events
|
||||
@Override
|
||||
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
|
||||
if(endReason==AudioTrackEndReason.FINISHED && bot.getSettings(bot.getJDA().getGuildById(guildId)).getRepeatMode())
|
||||
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason)
|
||||
{
|
||||
// if the track ended normally, and we're in repeat mode, re-add it to the queue
|
||||
if(endReason==AudioTrackEndReason.FINISHED && manager.getBot().getSettingsManager().getSettings(guildId).getRepeatMode())
|
||||
{
|
||||
queue.add(new QueuedTrack(track.makeClone(), requester));
|
||||
queue.add(new QueuedTrack(track.makeClone(), track.getUserData(Long.class)==null ? 0L : track.getUserData(Long.class)));
|
||||
}
|
||||
requester = 0;
|
||||
|
||||
if(queue.isEmpty())
|
||||
{
|
||||
if(!playFromDefault())
|
||||
{
|
||||
if(SONG_IN_STATUS)
|
||||
bot.resetGame();
|
||||
if(!STAY_IN_CHANNEL)
|
||||
bot.getThreadpool().submit(() -> bot.getJDA().getGuildById(guildId).getAudioManager().closeAudioConnection());
|
||||
bot.updateTopic(guildId, this);
|
||||
manager.getBot().getNowplayingHandler().onTrackUpdate(guildId, null, this);
|
||||
if(!manager.getBot().getConfig().getStay())
|
||||
manager.getBot().closeAudioConnection(guildId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QueuedTrack qt = queue.pull();
|
||||
requester = qt.getIdentifier();
|
||||
player.playTrack(qt.getTrack());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackStart(AudioPlayer player, AudioTrack track) {
|
||||
votes.clear();
|
||||
if(SONG_IN_STATUS)
|
||||
{
|
||||
if(bot.getJDA().getGuilds().stream().filter(g -> g.getSelfMember().getVoiceState().inVoiceChannel()).count()<=1)
|
||||
bot.getJDA().getPresence().setGame(Game.listening(track.getInfo().title));
|
||||
else
|
||||
bot.resetGame();
|
||||
}
|
||||
bot.updateTopic(guildId, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canProvide() {
|
||||
lastFrame = audioPlayer.provide();
|
||||
return lastFrame != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] provide20MsAudio() {
|
||||
return lastFrame.data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpus() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isTooLong(AudioTrack track)
|
||||
public void onTrackStart(AudioPlayer player, AudioTrack track)
|
||||
{
|
||||
if(MAX_SECONDS<=0)
|
||||
return false;
|
||||
return Math.round(track.getDuration()/1000.0) > MAX_SECONDS;
|
||||
votes.clear();
|
||||
manager.getBot().getNowplayingHandler().onTrackUpdate(guildId, track, this);
|
||||
}
|
||||
|
||||
|
||||
// Formatting
|
||||
public Message getNowPlaying(JDA jda)
|
||||
{
|
||||
if(isMusicPlaying(jda))
|
||||
{
|
||||
Guild guild = guild(jda);
|
||||
AudioTrack track = audioPlayer.getPlayingTrack();
|
||||
MessageBuilder mb = new MessageBuilder();
|
||||
mb.append(FormatUtil.filter(manager.getBot().getConfig().getSuccess()+" **Now Playing in "+guild.getSelfMember().getVoiceState().getChannel().getName()+"...**"));
|
||||
EmbedBuilder eb = new EmbedBuilder();
|
||||
eb.setColor(guild.getSelfMember().getColor());
|
||||
if(getRequester() != 0)
|
||||
{
|
||||
User u = guild.getJDA().getUserById(getRequester());
|
||||
if(u==null)
|
||||
eb.setAuthor("Unknown (ID:"+getRequester()+")", null, null);
|
||||
else
|
||||
eb.setAuthor(u.getName()+"#"+u.getDiscriminator(), null, u.getEffectiveAvatarUrl());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
eb.setTitle(track.getInfo().title, track.getInfo().uri);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
eb.setTitle(track.getInfo().title);
|
||||
}
|
||||
|
||||
if(track instanceof YoutubeAudioTrack && manager.getBot().getConfig().useNPImages())
|
||||
{
|
||||
eb.setThumbnail("https://img.youtube.com/vi/"+track.getIdentifier()+"/mqdefault.jpg");
|
||||
}
|
||||
|
||||
if(track.getInfo().author != null && !track.getInfo().author.isEmpty())
|
||||
eb.setFooter("Source: " + track.getInfo().author, null);
|
||||
|
||||
double progress = (double)audioPlayer.getPlayingTrack().getPosition()/track.getDuration();
|
||||
eb.setDescription((audioPlayer.isPaused() ? JMusicBot.PAUSE_EMOJI : JMusicBot.PLAY_EMOJI)
|
||||
+ " "+FormatUtil.progressBar(progress)
|
||||
+ " `[" + FormatUtil.formatTime(track.getPosition()) + "/" + FormatUtil.formatTime(track.getDuration()) + "]` "
|
||||
+ FormatUtil.volumeIcon(audioPlayer.getVolume()));
|
||||
|
||||
return mb.setEmbed(eb.build()).build();
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
|
||||
public Message getNoMusicPlaying(JDA jda)
|
||||
{
|
||||
Guild guild = guild(jda);
|
||||
return new MessageBuilder()
|
||||
.setContent(FormatUtil.filter(manager.getBot().getConfig().getSuccess()+" **Now Playing...**"))
|
||||
.setEmbed(new EmbedBuilder()
|
||||
.setTitle("No music playing")
|
||||
.setDescription(JMusicBot.STOP_EMOJI+" "+FormatUtil.progressBar(-1)+" "+FormatUtil.volumeIcon(audioPlayer.getVolume()))
|
||||
.setColor(guild.getSelfMember().getColor())
|
||||
.build()).build();
|
||||
}
|
||||
|
||||
public String getTopicFormat(JDA jda)
|
||||
{
|
||||
if(isMusicPlaying(jda))
|
||||
{
|
||||
long userid = getRequester();
|
||||
AudioTrack track = audioPlayer.getPlayingTrack();
|
||||
String title = track.getInfo().title;
|
||||
if(title==null || title.equals("Unknown Title"))
|
||||
title = track.getInfo().uri;
|
||||
return "**"+title+"** ["+(userid==0 ? "autoplay" : "<@"+userid+">")+"]"
|
||||
+ "\n" + (audioPlayer.isPaused() ? JMusicBot.PAUSE_EMOJI : JMusicBot.PLAY_EMOJI) + " "
|
||||
+ "[" + FormatUtil.formatTime(track.getDuration()) + "] "
|
||||
+ FormatUtil.volumeIcon(audioPlayer.getVolume());
|
||||
}
|
||||
else return "No music playing " + JMusicBot.STOP_EMOJI + " " + FormatUtil.volumeIcon(audioPlayer.getVolume());
|
||||
}
|
||||
|
||||
// Audio Send Handler methods
|
||||
@Override
|
||||
public boolean canProvide()
|
||||
{
|
||||
if (lastFrame == null)
|
||||
lastFrame = audioPlayer.provide();
|
||||
|
||||
return lastFrame != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] provide20MsAudio()
|
||||
{
|
||||
if (lastFrame == null)
|
||||
lastFrame = audioPlayer.provide();
|
||||
|
||||
byte[] data = lastFrame != null ? lastFrame.getData() : null;
|
||||
lastFrame = null;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpus()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Private methods
|
||||
private Guild guild(JDA jda)
|
||||
{
|
||||
return jda.getGuildById(guildId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.audio;
|
||||
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.entities.Pair;
|
||||
import com.jagrosh.jmusicbot.settings.Settings;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.dv8tion.jda.core.Permission;
|
||||
import net.dv8tion.jda.core.entities.Game;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
import net.dv8tion.jda.core.entities.Message;
|
||||
import net.dv8tion.jda.core.entities.TextChannel;
|
||||
import net.dv8tion.jda.core.exceptions.PermissionException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (john.a.grosh@gmail.com)
|
||||
*/
|
||||
public class NowplayingHandler
|
||||
{
|
||||
private final Bot bot;
|
||||
private final HashMap<Long,Pair<Long,Long>> lastNP; // guild -> channel,message
|
||||
|
||||
public NowplayingHandler(Bot bot)
|
||||
{
|
||||
this.bot = bot;
|
||||
this.lastNP = new HashMap<>();
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
bot.getThreadpool().scheduleWithFixedDelay(() -> updateAll(), 0, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public void setLastNPMessage(Message m)
|
||||
{
|
||||
lastNP.put(m.getGuild().getIdLong(), new Pair<>(m.getTextChannel().getIdLong(), m.getIdLong()));
|
||||
}
|
||||
|
||||
public void clearLastNPMessage(Guild guild)
|
||||
{
|
||||
lastNP.remove(guild.getIdLong());
|
||||
}
|
||||
|
||||
private void updateAll()
|
||||
{
|
||||
Set<Long> toRemove = new HashSet<>();
|
||||
for(long guildId: lastNP.keySet())
|
||||
{
|
||||
Guild guild = bot.getJDA().getGuildById(guildId);
|
||||
if(guild==null)
|
||||
{
|
||||
toRemove.add(guildId);
|
||||
continue;
|
||||
}
|
||||
Pair<Long,Long> pair = lastNP.get(guildId);
|
||||
TextChannel tc = guild.getTextChannelById(pair.getKey());
|
||||
if(tc==null)
|
||||
{
|
||||
toRemove.add(guildId);
|
||||
continue;
|
||||
}
|
||||
AudioHandler handler = (AudioHandler)guild.getAudioManager().getSendingHandler();
|
||||
Message msg = handler.getNowPlaying(bot.getJDA());
|
||||
if(msg==null)
|
||||
{
|
||||
msg = handler.getNoMusicPlaying(bot.getJDA());
|
||||
toRemove.add(guildId);
|
||||
}
|
||||
try
|
||||
{
|
||||
tc.editMessageById(pair.getValue(), msg).queue(m->{}, t -> lastNP.remove(guildId));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
toRemove.add(guildId);
|
||||
}
|
||||
}
|
||||
toRemove.forEach(id -> lastNP.remove(id));
|
||||
}
|
||||
|
||||
public void updateTopic(long guildId, AudioHandler handler, boolean wait)
|
||||
{
|
||||
Guild guild = bot.getJDA().getGuildById(guildId);
|
||||
if(guild==null)
|
||||
return;
|
||||
Settings settings = bot.getSettingsManager().getSettings(guildId);
|
||||
TextChannel tchan = settings.getTextChannel(guild);
|
||||
if(tchan!=null && guild.getSelfMember().hasPermission(tchan, Permission.MANAGE_CHANNEL))
|
||||
{
|
||||
String otherText;
|
||||
if(tchan.getTopic()==null || tchan.getTopic().isEmpty())
|
||||
otherText = "\u200B";
|
||||
else if(tchan.getTopic().contains("\u200B"))
|
||||
otherText = tchan.getTopic().substring(tchan.getTopic().lastIndexOf("\u200B"));
|
||||
else
|
||||
otherText = "\u200B\n "+tchan.getTopic();
|
||||
String text = handler.getTopicFormat(bot.getJDA()) + otherText;
|
||||
if(!text.equals(tchan.getTopic()))
|
||||
{
|
||||
try
|
||||
{
|
||||
if(wait)
|
||||
tchan.getManager().setTopic(text).complete();
|
||||
else
|
||||
tchan.getManager().setTopic(text).queue();
|
||||
}
|
||||
catch(PermissionException ignore) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "event"-based methods
|
||||
public void onTrackUpdate(long guildId, AudioTrack track, AudioHandler handler)
|
||||
{
|
||||
// update bot status if applicable
|
||||
if(bot.getConfig().getSongInStatus())
|
||||
{
|
||||
if(track!=null && bot.getJDA().getGuilds().stream().filter(g -> g.getSelfMember().getVoiceState().inVoiceChannel()).count()<=1)
|
||||
bot.getJDA().getPresence().setGame(Game.listening(track.getInfo().title));
|
||||
else
|
||||
bot.resetGame();
|
||||
}
|
||||
|
||||
// update channel topic if applicable
|
||||
updateTopic(guildId, handler, false);
|
||||
}
|
||||
|
||||
public void onMessageDelete(Guild guild, long messageId)
|
||||
{
|
||||
Pair<Long,Long> pair = lastNP.get(guild.getIdLong());
|
||||
if(pair==null)
|
||||
return;
|
||||
if(pair.getValue() == messageId)
|
||||
lastNP.remove(guild.getIdLong());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.audio;
|
||||
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
|
||||
import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioSourceManager;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (john.a.grosh@gmail.com)
|
||||
*/
|
||||
public class PlayerManager extends DefaultAudioPlayerManager
|
||||
{
|
||||
private final Bot bot;
|
||||
|
||||
public PlayerManager(Bot bot)
|
||||
{
|
||||
this.bot = bot;
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
AudioSourceManagers.registerRemoteSources(this);
|
||||
AudioSourceManagers.registerLocalSource(this);
|
||||
source(YoutubeAudioSourceManager.class).setPlaylistPageCount(10);
|
||||
}
|
||||
|
||||
public Bot getBot()
|
||||
{
|
||||
return bot;
|
||||
}
|
||||
|
||||
public boolean hasHandler(Guild guild)
|
||||
{
|
||||
return guild.getAudioManager().getSendingHandler()!=null;
|
||||
}
|
||||
|
||||
public AudioHandler setUpHandler(Guild guild)
|
||||
{
|
||||
AudioHandler handler;
|
||||
if(guild.getAudioManager().getSendingHandler()==null)
|
||||
{
|
||||
AudioPlayer player = createPlayer();
|
||||
player.setVolume(bot.getSettingsManager().getSettings(guild).getVolume());
|
||||
handler = new AudioHandler(this, guild, player);
|
||||
player.addListener(handler);
|
||||
guild.getAudioManager().setSendingHandler(handler);
|
||||
}
|
||||
else
|
||||
handler = (AudioHandler) guild.getAudioManager().getSendingHandler();
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
@@ -18,25 +18,31 @@ package com.jagrosh.jmusicbot.audio;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import com.jagrosh.jmusicbot.queue.Queueable;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import net.dv8tion.jda.core.entities.User;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class QueuedTrack implements Queueable {
|
||||
|
||||
public class QueuedTrack implements Queueable
|
||||
{
|
||||
private final AudioTrack track;
|
||||
private final long owner;
|
||||
|
||||
public QueuedTrack(AudioTrack track, User owner)
|
||||
{
|
||||
this(track, owner.getIdLong());
|
||||
}
|
||||
|
||||
public QueuedTrack(AudioTrack track, long owner)
|
||||
{
|
||||
this.track = track;
|
||||
this.owner = owner;
|
||||
this.track.setUserData(owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getIdentifier() {
|
||||
return owner;
|
||||
public long getIdentifier()
|
||||
{
|
||||
return track.getUserData(Long.class);
|
||||
}
|
||||
|
||||
public AudioTrack getTrack()
|
||||
@@ -45,8 +51,8 @@ public class QueuedTrack implements Queueable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "`["+FormatUtil.formatTime(track.getDuration())+"]` **" + track.getInfo().title +"** - <@"+owner+">";
|
||||
public String toString()
|
||||
{
|
||||
return "`[" + FormatUtil.formatTime(track.getDuration()) + "]` **" + track.getInfo().title + "** - <@" + track.getUserData(Long.class) + ">";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import net.dv8tion.jda.core.Permission;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (john.a.grosh@gmail.com)
|
||||
*/
|
||||
public abstract class AdminCommand extends Command
|
||||
{
|
||||
public AdminCommand()
|
||||
{
|
||||
this.category = new Category("Admin", event ->
|
||||
{
|
||||
if(event.getAuthor().getId().equals(event.getClient().getOwnerId()))
|
||||
return true;
|
||||
if(event.getGuild()==null)
|
||||
return true;
|
||||
return event.getMember().hasPermission(Permission.MANAGE_SERVER);
|
||||
});
|
||||
this.guildOnly = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.settings.Settings;
|
||||
import net.dv8tion.jda.core.Permission;
|
||||
import net.dv8tion.jda.core.entities.Role;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (john.a.grosh@gmail.com)
|
||||
*/
|
||||
public abstract class DJCommand extends MusicCommand
|
||||
{
|
||||
public DJCommand(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
this.category = new Category("DJ", event ->
|
||||
{
|
||||
if(event.getAuthor().getId().equals(event.getClient().getOwnerId()))
|
||||
return true;
|
||||
if(event.getGuild()==null)
|
||||
return true;
|
||||
if(event.getMember().hasPermission(Permission.MANAGE_SERVER))
|
||||
return true;
|
||||
Settings settings = event.getClient().getSettingsFor(event.getGuild());
|
||||
Role dj = settings.getRole(event.getGuild());
|
||||
return dj!=null && (event.getMember().getRoles().contains(dj) || dj.getIdLong()==event.getGuild().getIdLong());
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +18,7 @@ package com.jagrosh.jmusicbot.commands;
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.Settings;
|
||||
import com.jagrosh.jmusicbot.settings.Settings;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import net.dv8tion.jda.core.entities.GuildVoiceState;
|
||||
import net.dv8tion.jda.core.entities.TextChannel;
|
||||
@@ -29,8 +29,8 @@ import net.dv8tion.jda.core.exceptions.PermissionException;
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public abstract class MusicCommand extends Command {
|
||||
|
||||
public abstract class MusicCommand extends Command
|
||||
{
|
||||
protected final Bot bot;
|
||||
protected boolean bePlaying;
|
||||
protected boolean beListening;
|
||||
@@ -39,24 +39,25 @@ public abstract class MusicCommand extends Command {
|
||||
{
|
||||
this.bot = bot;
|
||||
this.guildOnly = true;
|
||||
this.category = bot.MUSIC;
|
||||
this.category = new Category("Music");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
Settings settings = bot.getSettings(event.getGuild());
|
||||
TextChannel tchannel = event.getGuild().getTextChannelById(settings.getTextId());
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
Settings settings = event.getClient().getSettingsFor(event.getGuild());
|
||||
TextChannel tchannel = settings.getTextChannel(event.getGuild());
|
||||
if(tchannel!=null && !event.getTextChannel().equals(tchannel))
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
event.getMessage().delete().queue();
|
||||
} catch(PermissionException e){}
|
||||
event.replyInDm(event.getClient().getError()+" You can only use that command in <#"+settings.getTextId()+">!");
|
||||
} catch(PermissionException ignore){}
|
||||
event.replyInDm(event.getClient().getError()+" You can only use that command in "+tchannel.getAsMention()+"!");
|
||||
return;
|
||||
}
|
||||
if(bePlaying
|
||||
&& (event.getGuild().getAudioManager().getSendingHandler()==null
|
||||
|| !((AudioHandler)event.getGuild().getAudioManager().getSendingHandler()).isMusicPlaying()))
|
||||
bot.getPlayerManager().setUpHandler(event.getGuild()); // no point constantly checking for this later
|
||||
if(bePlaying && !((AudioHandler)event.getGuild().getAudioManager().getSendingHandler()).isMusicPlaying(event.getJDA()))
|
||||
{
|
||||
event.reply(event.getClient().getError()+" There must be music playing to use that!");
|
||||
return;
|
||||
@@ -65,23 +66,27 @@ public abstract class MusicCommand extends Command {
|
||||
{
|
||||
VoiceChannel current = event.getGuild().getSelfMember().getVoiceState().getChannel();
|
||||
if(current==null)
|
||||
current = event.getGuild().getVoiceChannelById(settings.getVoiceId());
|
||||
current = settings.getVoiceChannel(event.getGuild());
|
||||
GuildVoiceState userState = event.getMember().getVoiceState();
|
||||
if(!userState.inVoiceChannel() || userState.isDeafened() || (current!=null && !userState.getChannel().equals(current)))
|
||||
{
|
||||
event.reply(event.getClient().getError()
|
||||
+" You must be listening in "+(current==null ? "a voice channel" : "**"+current.getName()+"**")
|
||||
+" to use that!");
|
||||
event.replyError("You must be listening in "+(current==null ? "a voice channel" : "**"+current.getName()+"**")+" to use that!");
|
||||
return;
|
||||
}
|
||||
if(!event.getGuild().getSelfMember().getVoiceState().inVoiceChannel())
|
||||
try {
|
||||
{
|
||||
try
|
||||
{
|
||||
event.getGuild().getAudioManager().openAudioConnection(userState.getChannel());
|
||||
}catch(PermissionException ex) {
|
||||
}
|
||||
catch(PermissionException ex)
|
||||
{
|
||||
event.reply(event.getClient().getError()+" I am unable to connect to **"+userState.getChannel().getName()+"**!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doCommand(event);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (john.a.grosh@gmail.com)
|
||||
*/
|
||||
public abstract class OwnerCommand extends Command
|
||||
{
|
||||
public OwnerCommand()
|
||||
{
|
||||
this.category = new Category("Owner");
|
||||
this.ownerCommand = true;
|
||||
}
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jdautilities.menu.OrderedMenu;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import net.dv8tion.jda.core.Permission;
|
||||
import net.dv8tion.jda.core.entities.Message;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SCSearchCmd extends MusicCommand {
|
||||
|
||||
private final OrderedMenu.Builder builder;
|
||||
private final String searchingEmoji;
|
||||
public SCSearchCmd(Bot bot, String searchingEmoji)
|
||||
{
|
||||
super(bot);
|
||||
this.searchingEmoji = searchingEmoji;
|
||||
this.name = "scsearch";
|
||||
this.arguments = "<query>";
|
||||
this.help = "searches Soundcloud for a provided query";
|
||||
this.beListening = true;
|
||||
this.bePlaying = false;
|
||||
this.botPermissions = new Permission[]{Permission.MESSAGE_EMBED_LINKS};
|
||||
builder = new OrderedMenu.Builder()
|
||||
.allowTextInput(true)
|
||||
.useNumbers()
|
||||
.useCancelButton(true)
|
||||
.setEventWaiter(bot.getWaiter())
|
||||
.setTimeout(1, TimeUnit.MINUTES)
|
||||
;
|
||||
}
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) {
|
||||
if(event.getArgs().isEmpty())
|
||||
{
|
||||
event.reply(event.getClient().getError()+" Please include a query.");
|
||||
return;
|
||||
}
|
||||
event.reply(searchingEmoji+" Searching... `["+event.getArgs()+"]`",m -> bot.getAudioManager().loadItemOrdered(event.getGuild(), "scsearch:"+event.getArgs(), new ResultHandler(m,event)));
|
||||
}
|
||||
|
||||
private class ResultHandler implements AudioLoadResultHandler {
|
||||
final Message m;
|
||||
final CommandEvent event;
|
||||
private ResultHandler(Message m, CommandEvent event)
|
||||
{
|
||||
this.m = m;
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackLoaded(AudioTrack track) {
|
||||
if(AudioHandler.isTooLong(track))
|
||||
{
|
||||
m.editMessage(FormatUtil.filter(event.getClient().getWarning()+" This track (**"+track.getInfo().title+"**) is longer than the allowed maximum: `"
|
||||
+FormatUtil.formatTime(track.getDuration())+"` > `"+FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`")).queue();
|
||||
return;
|
||||
}
|
||||
int pos = bot.queueTrack(event, track)+1;
|
||||
m.editMessage(FormatUtil.filter(event.getClient().getSuccess()+" Added **"+track.getInfo().title
|
||||
+"** (`"+FormatUtil.formatTime(track.getDuration())+"`) "+(pos==0 ? "to begin playing"
|
||||
: " to the queue at position "+pos))).queue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playlistLoaded(AudioPlaylist playlist) {
|
||||
builder.setColor(event.getSelfMember().getColor())
|
||||
.setText(FormatUtil.filter(event.getClient().getSuccess()+" Search results for `"+event.getArgs()+"`:"))
|
||||
.setChoices(new String[0])
|
||||
.setSelection((msg, i) -> {
|
||||
AudioTrack track = playlist.getTracks().get(i-1);
|
||||
if(AudioHandler.isTooLong(track))
|
||||
{
|
||||
event.replyWarning("This track (**"+track.getInfo().title+"**) is longer than the allowed maximum: `"
|
||||
+FormatUtil.formatTime(track.getDuration())+"` > `"+FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`");
|
||||
return;
|
||||
}
|
||||
int pos = bot.queueTrack(event, track)+1;
|
||||
event.replySuccess("Added **"+track.getInfo().title
|
||||
+"** (`"+FormatUtil.formatTime(track.getDuration())+"`) "+(pos==0 ? "to begin playing"
|
||||
: " to the queue at position "+pos));
|
||||
})
|
||||
.setCancel((msg) -> {})
|
||||
.setUsers(event.getAuthor())
|
||||
;
|
||||
for(int i=0; i<4&&i<playlist.getTracks().size(); i++)
|
||||
{
|
||||
AudioTrack track = playlist.getTracks().get(i);
|
||||
builder.addChoices("`["+FormatUtil.formatTime(track.getDuration())+"]` [**"
|
||||
+track.getInfo().title+"**]("+track.getInfo().uri+")");
|
||||
}
|
||||
builder.build().display(m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noMatches() {
|
||||
m.editMessage(FormatUtil.filter(event.getClient().getWarning()+" No results found for `"+event.getArgs()+"`.")).queue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFailed(FriendlyException throwable) {
|
||||
if(throwable.severity==Severity.COMMON)
|
||||
m.editMessage(event.getClient().getError()+" Error loading: "+throwable.getMessage()).queue();
|
||||
else
|
||||
m.editMessage(event.getClient().getError()+" Error loading track.").queue();
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,13 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.admin;
|
||||
|
||||
import java.util.List;
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.utils.FinderUtil;
|
||||
import com.jagrosh.jdautilities.commons.utils.FinderUtil;
|
||||
import com.jagrosh.jmusicbot.commands.AdminCommand;
|
||||
import com.jagrosh.jmusicbot.settings.Settings;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import net.dv8tion.jda.core.entities.Role;
|
||||
|
||||
@@ -27,40 +27,39 @@ import net.dv8tion.jda.core.entities.Role;
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SetdjCmd extends Command {
|
||||
|
||||
private final Bot bot;
|
||||
public SetdjCmd(Bot bot)
|
||||
public class SetdjCmd extends AdminCommand
|
||||
{
|
||||
public SetdjCmd()
|
||||
{
|
||||
this.bot = bot;
|
||||
this.name = "setdj";
|
||||
this.help = "sets the DJ role for certain music commands";
|
||||
this.arguments = "<rolename|NONE>";
|
||||
this.guildOnly = true;
|
||||
this.category = bot.ADMIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
if(event.getArgs().isEmpty())
|
||||
{
|
||||
event.reply(event.getClient().getError()+" Please include a role name or NONE");
|
||||
return;
|
||||
}
|
||||
else if(event.getArgs().equalsIgnoreCase("none"))
|
||||
Settings s = event.getClient().getSettingsFor(event.getGuild());
|
||||
if(event.getArgs().equalsIgnoreCase("none"))
|
||||
{
|
||||
bot.clearRole(event.getGuild());
|
||||
s.setDJRole(null);
|
||||
event.reply(event.getClient().getSuccess()+" DJ role cleared; Only Admins can use the DJ commands.");
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Role> list = FinderUtil.findRole(event.getArgs(), event.getGuild());
|
||||
List<Role> list = FinderUtil.findRoles(event.getArgs(), event.getGuild());
|
||||
if(list.isEmpty())
|
||||
event.reply(event.getClient().getWarning()+" No Roles found matching \""+event.getArgs()+"\"");
|
||||
else if (list.size()>1)
|
||||
event.reply(event.getClient().getWarning()+FormatUtil.listOfRoles(list, event.getArgs()));
|
||||
else
|
||||
{
|
||||
bot.setRole(list.get(0));
|
||||
s.setDJRole(list.get(0));
|
||||
event.reply(event.getClient().getSuccess()+" DJ commands can now be used by users with the **"+list.get(0).getName()+"** role.");
|
||||
}
|
||||
}
|
||||
+68
-69
@@ -1,69 +1,68 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
|
||||
import java.util.List;
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.utils.FinderUtil;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import net.dv8tion.jda.core.entities.TextChannel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SettcCmd extends Command {
|
||||
|
||||
private final Bot bot;
|
||||
public SettcCmd(Bot bot)
|
||||
{
|
||||
this.bot = bot;
|
||||
this.name = "settc";
|
||||
this.help = "sets the text channel for music commands";
|
||||
this.arguments = "<channel|NONE>";
|
||||
this.guildOnly = true;
|
||||
this.category = bot.ADMIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
if(event.getArgs().isEmpty())
|
||||
{
|
||||
event.reply(event.getClient().getError()+" Please include a text channel or NONE");
|
||||
}
|
||||
else if(event.getArgs().equalsIgnoreCase("none"))
|
||||
{
|
||||
bot.clearTextChannel(event.getGuild());
|
||||
event.reply(event.getClient().getSuccess()+" Music commands can now be used in any channel");
|
||||
}
|
||||
else
|
||||
{
|
||||
List<TextChannel> list = FinderUtil.findTextChannel(event.getArgs(), event.getGuild());
|
||||
if(list.isEmpty())
|
||||
event.reply(event.getClient().getWarning()+" No Text Channels found matching \""+event.getArgs()+"\"");
|
||||
else if (list.size()>1)
|
||||
event.reply(event.getClient().getWarning()+FormatUtil.listOfTChannels(list, event.getArgs()));
|
||||
else
|
||||
{
|
||||
bot.setTextChannel(list.get(0));
|
||||
event.reply(event.getClient().getSuccess()+" Music commands can now only be used in <#"+list.get(0).getId()+">");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands.admin;
|
||||
|
||||
import java.util.List;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jdautilities.commons.utils.FinderUtil;
|
||||
import com.jagrosh.jmusicbot.commands.AdminCommand;
|
||||
import com.jagrosh.jmusicbot.settings.Settings;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import net.dv8tion.jda.core.entities.TextChannel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SettcCmd extends AdminCommand
|
||||
{
|
||||
public SettcCmd()
|
||||
{
|
||||
this.name = "settc";
|
||||
this.help = "sets the text channel for music commands";
|
||||
this.arguments = "<channel|NONE>";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
if(event.getArgs().isEmpty())
|
||||
{
|
||||
event.reply(event.getClient().getError()+" Please include a text channel or NONE");
|
||||
return;
|
||||
}
|
||||
Settings s = event.getClient().getSettingsFor(event.getGuild());
|
||||
if(event.getArgs().equalsIgnoreCase("none"))
|
||||
{
|
||||
s.setTextChannel(null);
|
||||
event.reply(event.getClient().getSuccess()+" Music commands can now be used in any channel");
|
||||
}
|
||||
else
|
||||
{
|
||||
List<TextChannel> list = FinderUtil.findTextChannels(event.getArgs(), event.getGuild());
|
||||
if(list.isEmpty())
|
||||
event.reply(event.getClient().getWarning()+" No Text Channels found matching \""+event.getArgs()+"\"");
|
||||
else if (list.size()>1)
|
||||
event.reply(event.getClient().getWarning()+FormatUtil.listOfTChannels(list, event.getArgs()));
|
||||
else
|
||||
{
|
||||
s.setTextChannel(list.get(0));
|
||||
event.reply(event.getClient().getSuccess()+" Music commands can now only be used in <#"+list.get(0).getId()+">");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+67
-69
@@ -1,69 +1,67 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
|
||||
import java.util.List;
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.utils.FinderUtil;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import net.dv8tion.jda.core.entities.VoiceChannel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SetvcCmd extends Command {
|
||||
|
||||
private final Bot bot;
|
||||
public SetvcCmd(Bot bot)
|
||||
{
|
||||
this.bot = bot;
|
||||
this.name = "setvc";
|
||||
this.help = "sets the voice channel for playing music";
|
||||
this.arguments = "<channel|NONE>";
|
||||
this.guildOnly = true;
|
||||
this.category = bot.ADMIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
if(event.getArgs().isEmpty())
|
||||
{
|
||||
event.reply(event.getClient().getError()+" Please include a voice channel or NONE");
|
||||
}
|
||||
else if(event.getArgs().equalsIgnoreCase("none"))
|
||||
{
|
||||
bot.clearVoiceChannel(event.getGuild());
|
||||
event.reply(event.getClient().getSuccess()+" Music can now be played in any channel");
|
||||
}
|
||||
else
|
||||
{
|
||||
List<VoiceChannel> list = FinderUtil.findVoiceChannel(event.getArgs(), event.getGuild());
|
||||
if(list.isEmpty())
|
||||
event.reply(event.getClient().getWarning()+" No Voice Channels found matching \""+event.getArgs()+"\"");
|
||||
else if (list.size()>1)
|
||||
event.reply(event.getClient().getWarning()+FormatUtil.listOfVChannels(list, event.getArgs()));
|
||||
else
|
||||
{
|
||||
bot.setVoiceChannel(list.get(0));
|
||||
event.reply(event.getClient().getSuccess()+" Music can now only be played in **"+list.get(0).getName()+"**");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands.admin;
|
||||
|
||||
import java.util.List;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jdautilities.commons.utils.FinderUtil;
|
||||
import com.jagrosh.jmusicbot.commands.AdminCommand;
|
||||
import com.jagrosh.jmusicbot.settings.Settings;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import net.dv8tion.jda.core.entities.VoiceChannel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SetvcCmd extends AdminCommand
|
||||
{
|
||||
public SetvcCmd()
|
||||
{
|
||||
this.name = "setvc";
|
||||
this.help = "sets the voice channel for playing music";
|
||||
this.arguments = "<channel|NONE>";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
if(event.getArgs().isEmpty())
|
||||
{
|
||||
event.reply(event.getClient().getError()+" Please include a voice channel or NONE");
|
||||
return;
|
||||
}
|
||||
Settings s = event.getClient().getSettingsFor(event.getGuild());
|
||||
if(event.getArgs().equalsIgnoreCase("none"))
|
||||
{
|
||||
s.setVoiceChannel(null);
|
||||
event.reply(event.getClient().getSuccess()+" Music can now be played in any channel");
|
||||
}
|
||||
else
|
||||
{
|
||||
List<VoiceChannel> list = FinderUtil.findVoiceChannels(event.getArgs(), event.getGuild());
|
||||
if(list.isEmpty())
|
||||
event.reply(event.getClient().getWarning()+" No Voice Channels found matching \""+event.getArgs()+"\"");
|
||||
else if (list.size()>1)
|
||||
event.reply(event.getClient().getWarning()+FormatUtil.listOfVChannels(list, event.getArgs()));
|
||||
else
|
||||
{
|
||||
s.setVoiceChannel(list.get(0));
|
||||
event.reply(event.getClient().getSuccess()+" Music can now only be played in **"+list.get(0).getName()+"**");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -13,19 +13,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.dj;
|
||||
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.commands.DJCommand;
|
||||
import net.dv8tion.jda.core.entities.User;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class ForceskipCmd extends MusicCommand {
|
||||
|
||||
public class ForceskipCmd extends DJCommand
|
||||
{
|
||||
public ForceskipCmd(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
@@ -33,16 +34,15 @@ public class ForceskipCmd extends MusicCommand {
|
||||
this.help = "skips the current song";
|
||||
this.aliases = new String[]{"modskip"};
|
||||
this.bePlaying = true;
|
||||
this.category = bot.DJ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) {
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
User u = event.getJDA().getUserById(handler.getRequester());
|
||||
event.reply(event.getClient().getSuccess()+" Skipped **"+handler.getPlayer().getPlayingTrack().getInfo().title
|
||||
+"** (requested by "+(u==null ? "someone" : "**"+u.getName()+"**")+")");
|
||||
handler.getPlayer().stopTrack();
|
||||
}
|
||||
|
||||
}
|
||||
+7
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,30 +13,30 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.dj;
|
||||
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import net.dv8tion.jda.core.entities.User;
|
||||
import com.jagrosh.jmusicbot.commands.DJCommand;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class PauseCmd extends MusicCommand {
|
||||
|
||||
public class PauseCmd extends DJCommand
|
||||
{
|
||||
public PauseCmd(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
this.name = "pause";
|
||||
this.help = "pauses the current song";
|
||||
this.bePlaying = true;
|
||||
this.category = bot.DJ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) {
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
if(handler.getPlayer().isPaused())
|
||||
{
|
||||
@@ -46,5 +46,4 @@ public class PauseCmd extends MusicCommand {
|
||||
handler.getPlayer().setPaused(true);
|
||||
event.replySuccess("Paused **"+handler.getPlayer().getPlayingTrack().getInfo().title+"**. Type `"+event.getClient().getPrefix()+"play` to unpause!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands.dj;
|
||||
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.audio.QueuedTrack;
|
||||
import com.jagrosh.jmusicbot.commands.DJCommand;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import net.dv8tion.jda.core.entities.Message;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (john.a.grosh@gmail.com)
|
||||
*/
|
||||
public class PlaynextCmd extends DJCommand
|
||||
{
|
||||
private final String loadingEmoji;
|
||||
|
||||
public PlaynextCmd(Bot bot, String loadingEmoji)
|
||||
{
|
||||
super(bot);
|
||||
this.loadingEmoji = loadingEmoji;
|
||||
this.name = "playnext";
|
||||
this.arguments = "<title|URL>";
|
||||
this.help = "plays a single song next";
|
||||
this.beListening = true;
|
||||
this.bePlaying = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
if(event.getArgs().isEmpty() && event.getMessage().getAttachments().isEmpty())
|
||||
{
|
||||
event.replyWarning("Please include a song title or URL!");
|
||||
return;
|
||||
}
|
||||
String args = event.getArgs().startsWith("<") && event.getArgs().endsWith(">")
|
||||
? event.getArgs().substring(1,event.getArgs().length()-1)
|
||||
: event.getArgs().isEmpty() ? event.getMessage().getAttachments().get(0).getUrl() : event.getArgs();
|
||||
event.reply(loadingEmoji+" Loading... `["+args+"]`", m -> bot.getPlayerManager().loadItemOrdered(event.getGuild(), args, new ResultHandler(m,event,false)));
|
||||
}
|
||||
|
||||
private class ResultHandler implements AudioLoadResultHandler
|
||||
{
|
||||
private final Message m;
|
||||
private final CommandEvent event;
|
||||
private final boolean ytsearch;
|
||||
|
||||
private ResultHandler(Message m, CommandEvent event, boolean ytsearch)
|
||||
{
|
||||
this.m = m;
|
||||
this.event = event;
|
||||
this.ytsearch = ytsearch;
|
||||
}
|
||||
|
||||
private void loadSingle(AudioTrack track)
|
||||
{
|
||||
if(bot.getConfig().isTooLong(track))
|
||||
{
|
||||
m.editMessage(FormatUtil.filter(event.getClient().getWarning()+" This track (**"+track.getInfo().title+"**) is longer than the allowed maximum: `"
|
||||
+FormatUtil.formatTime(track.getDuration())+"` > `"+FormatUtil.formatTime(bot.getConfig().getMaxSeconds()*1000)+"`")).queue();
|
||||
return;
|
||||
}
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
int pos = handler.addTrackToFront(new QueuedTrack(track, event.getAuthor()))+1;
|
||||
String addMsg = FormatUtil.filter(event.getClient().getSuccess()+" Added **"+track.getInfo().title
|
||||
+"** (`"+FormatUtil.formatTime(track.getDuration())+"`) "+(pos==0?"to begin playing":" to the queue at position "+pos));
|
||||
m.editMessage(addMsg).queue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackLoaded(AudioTrack track)
|
||||
{
|
||||
loadSingle(track);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playlistLoaded(AudioPlaylist playlist)
|
||||
{
|
||||
AudioTrack single;
|
||||
if(playlist.getTracks().size()==1 || playlist.isSearchResult())
|
||||
single = playlist.getSelectedTrack()==null ? playlist.getTracks().get(0) : playlist.getSelectedTrack();
|
||||
else if (playlist.getSelectedTrack()!=null)
|
||||
single = playlist.getSelectedTrack();
|
||||
else
|
||||
single = playlist.getTracks().get(0);
|
||||
loadSingle(single);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noMatches()
|
||||
{
|
||||
if(ytsearch)
|
||||
m.editMessage(FormatUtil.filter(event.getClient().getWarning()+" No results found for `"+event.getArgs()+"`.")).queue();
|
||||
else
|
||||
bot.getPlayerManager().loadItemOrdered(event.getGuild(), "ytsearch:"+event.getArgs(), new ResultHandler(m,event,true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFailed(FriendlyException throwable)
|
||||
{
|
||||
if(throwable.severity==FriendlyException.Severity.COMMON)
|
||||
m.editMessage(event.getClient().getError()+" Error loading: "+throwable.getMessage()).queue();
|
||||
else
|
||||
m.editMessage(event.getClient().getError()+" Error loading track.").queue();
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,35 +13,37 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.dj;
|
||||
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.commands.DJCommand;
|
||||
import com.jagrosh.jmusicbot.settings.Settings;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class RepeatCmd extends Command {
|
||||
|
||||
private final Bot bot;
|
||||
public class RepeatCmd extends DJCommand
|
||||
{
|
||||
public RepeatCmd(Bot bot)
|
||||
{
|
||||
this.bot = bot;
|
||||
super(bot);
|
||||
this.name = "repeat";
|
||||
this.help = "re-adds music to the queue when finished";
|
||||
this.arguments = "[on|off]";
|
||||
this.guildOnly = true;
|
||||
this.category = bot.DJ;
|
||||
}
|
||||
|
||||
// override musiccommand's execute because we don't actually care where this is used
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
boolean value;
|
||||
Settings settings = event.getClient().getSettingsFor(event.getGuild());
|
||||
if(event.getArgs().isEmpty())
|
||||
{
|
||||
value = !bot.getSettings(event.getGuild()).getRepeatMode();
|
||||
value = !settings.getRepeatMode();
|
||||
}
|
||||
else if(event.getArgs().equalsIgnoreCase("true") || event.getArgs().equalsIgnoreCase("on"))
|
||||
{
|
||||
@@ -56,8 +58,10 @@ public class RepeatCmd extends Command {
|
||||
event.replyError("Valid options are `on` or `off` (or leave empty to toggle)");
|
||||
return;
|
||||
}
|
||||
bot.setRepeatMode(event.getGuild(), value);
|
||||
settings.setRepeatMode(value);
|
||||
event.replySuccess("Repeat mode is now `"+(value ? "ON" : "OFF")+"`");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) { /* Intentionally Empty */ }
|
||||
}
|
||||
+6
-7
@@ -13,19 +13,19 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.dj;
|
||||
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import net.dv8tion.jda.core.entities.User;
|
||||
import com.jagrosh.jmusicbot.commands.DJCommand;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SkiptoCmd extends MusicCommand {
|
||||
|
||||
public class SkiptoCmd extends DJCommand
|
||||
{
|
||||
public SkiptoCmd(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
@@ -34,11 +34,11 @@ public class SkiptoCmd extends MusicCommand {
|
||||
this.arguments = "<position>";
|
||||
this.aliases = new String[]{"jumpto"};
|
||||
this.bePlaying = true;
|
||||
this.category = bot.DJ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) {
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
int index = 0;
|
||||
try
|
||||
{
|
||||
@@ -59,5 +59,4 @@ public class SkiptoCmd extends MusicCommand {
|
||||
event.reply(event.getClient().getSuccess()+" Skipped to **"+handler.getQueue().get(0).getTrack().getInfo().title+"**");
|
||||
handler.getPlayer().stopTrack();
|
||||
}
|
||||
|
||||
}
|
||||
+8
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,34 +13,33 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.dj;
|
||||
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.commands.DJCommand;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class StopCmd extends MusicCommand {
|
||||
|
||||
public class StopCmd extends DJCommand
|
||||
{
|
||||
public StopCmd(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
this.name = "stop";
|
||||
this.help = "stops the current song and clears the queue";
|
||||
this.bePlaying = false;
|
||||
this.category = bot.DJ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) {
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
if(handler!=null)
|
||||
handler.stopAndClear();
|
||||
handler.stopAndClear();
|
||||
event.getGuild().getAudioManager().closeAudioConnection();
|
||||
event.reply(event.getClient().getSuccess()+" The player has stopped and the queue has been cleared.");
|
||||
}
|
||||
|
||||
}
|
||||
+11
-8
@@ -13,19 +13,21 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.dj;
|
||||
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.commands.DJCommand;
|
||||
import com.jagrosh.jmusicbot.settings.Settings;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class VolumeCmd extends MusicCommand {
|
||||
|
||||
public class VolumeCmd extends DJCommand
|
||||
{
|
||||
public VolumeCmd(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
@@ -33,13 +35,14 @@ public class VolumeCmd extends MusicCommand {
|
||||
this.aliases = new String[]{"vol"};
|
||||
this.help = "sets or shows volume";
|
||||
this.arguments = "[0-150]";
|
||||
this.category = bot.DJ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) {
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
int volume = handler==null && bot.getSettings(event.getGuild())==null ? 100 : (handler==null ? bot.getSettings(event.getGuild()).getVolume() : handler.getPlayer().getVolume());
|
||||
Settings settings = event.getClient().getSettingsFor(event.getGuild());
|
||||
int volume = handler.getPlayer().getVolume();
|
||||
if(event.getArgs().isEmpty())
|
||||
{
|
||||
event.reply(FormatUtil.volumeIcon(volume)+" Current volume is `"+volume+"`");
|
||||
@@ -56,8 +59,8 @@ public class VolumeCmd extends MusicCommand {
|
||||
event.reply(event.getClient().getError()+" Volume must be a valid integer between 0 and 150!");
|
||||
else
|
||||
{
|
||||
bot.setUpHandler(event).getPlayer().setVolume(nvolume);
|
||||
bot.setVolume(event.getGuild(), nvolume);
|
||||
handler.getPlayer().setVolume(nvolume);
|
||||
settings.setVolume(nvolume);
|
||||
event.reply(FormatUtil.volumeIcon(nvolume)+" Volume changed from `"+volume+"` to `"+nvolume+"`");
|
||||
}
|
||||
}
|
||||
+14
-14
@@ -13,12 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.general;
|
||||
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.Settings;
|
||||
import com.jagrosh.jmusicbot.settings.Settings;
|
||||
import net.dv8tion.jda.core.EmbedBuilder;
|
||||
import net.dv8tion.jda.core.MessageBuilder;
|
||||
import net.dv8tion.jda.core.entities.Role;
|
||||
@@ -29,12 +28,12 @@ import net.dv8tion.jda.core.entities.VoiceChannel;
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SettingsCmd extends Command {
|
||||
|
||||
private final Bot bot;
|
||||
public SettingsCmd(Bot bot)
|
||||
public class SettingsCmd extends Command
|
||||
{
|
||||
private final static String EMOJI = "\uD83C\uDFA7"; // 🎧
|
||||
|
||||
public SettingsCmd()
|
||||
{
|
||||
this.bot = bot;
|
||||
this.name = "settings";
|
||||
this.help = "shows the bots settings";
|
||||
this.aliases = new String[]{"status"};
|
||||
@@ -42,15 +41,16 @@ public class SettingsCmd extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
Settings s = bot.getSettings(event.getGuild());
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
Settings s = event.getClient().getSettingsFor(event.getGuild());
|
||||
MessageBuilder builder = new MessageBuilder()
|
||||
.append("\uD83C\uDFA7 **")
|
||||
.append(EMOJI + " **")
|
||||
.append(event.getSelfUser().getName())
|
||||
.append("** settings:");
|
||||
TextChannel tchan = event.getGuild().getTextChannelById(s.getTextId());
|
||||
VoiceChannel vchan = event.getGuild().getVoiceChannelById(s.getVoiceId());
|
||||
Role role = event.getGuild().getRoleById(s.getRoleId());
|
||||
TextChannel tchan = s.getTextChannel(event.getGuild());
|
||||
VoiceChannel vchan = s.getVoiceChannel(event.getGuild());
|
||||
Role role = s.getRole(event.getGuild());
|
||||
EmbedBuilder ebuilder = new EmbedBuilder()
|
||||
.setColor(event.getSelfMember().getColor())
|
||||
.setDescription("Text Channel: "+(tchan==null ? "Any" : "**#"+tchan.getName()+"**")
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands.music;
|
||||
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jlyrics.Lyrics;
|
||||
import com.jagrosh.jlyrics.LyricsClient;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.commands.MusicCommand;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import net.dv8tion.jda.core.EmbedBuilder;
|
||||
import net.dv8tion.jda.core.Permission;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (john.a.grosh@gmail.com)
|
||||
*/
|
||||
public class LyricsCmd extends MusicCommand
|
||||
{
|
||||
private final LyricsClient client = new LyricsClient();
|
||||
|
||||
public LyricsCmd(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
this.name = "lyrics";
|
||||
this.arguments = "[song name]";
|
||||
this.help = "shows the lyrics to the currently-playing song";
|
||||
this.botPermissions = new Permission[]{Permission.MESSAGE_EMBED_LINKS};
|
||||
this.bePlaying = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
event.getChannel().sendTyping().queue();
|
||||
String title;
|
||||
if(event.getArgs().isEmpty())
|
||||
title = ((AudioHandler)event.getGuild().getAudioManager().getSendingHandler()).getPlayer().getPlayingTrack().getInfo().title;
|
||||
else
|
||||
title = event.getArgs();
|
||||
client.getLyrics(title).thenAccept(lyrics ->
|
||||
{
|
||||
if(lyrics == null)
|
||||
{
|
||||
event.replyError("Lyrics for `" + title + "` could not be found!");
|
||||
return;
|
||||
}
|
||||
|
||||
EmbedBuilder eb = new EmbedBuilder()
|
||||
.setAuthor(lyrics.getAuthor())
|
||||
.setColor(event.getSelfMember().getColor())
|
||||
.setTitle(lyrics.getTitle(), lyrics.getURL());
|
||||
if(lyrics.getContent().length()>15000)
|
||||
{
|
||||
event.replyWarning("Lyrics for `" + title + "` found but likely not correct: " + lyrics.getURL());
|
||||
}
|
||||
else if(lyrics.getContent().length()>2000)
|
||||
{
|
||||
String content = lyrics.getContent().trim();
|
||||
while(content.length() > 2000)
|
||||
{
|
||||
int index = content.lastIndexOf("\n\n", 2000);
|
||||
if(index == -1)
|
||||
index = content.lastIndexOf("\n", 2000);
|
||||
if(index == -1)
|
||||
index = content.lastIndexOf(" ", 2000);
|
||||
if(index == -1)
|
||||
index = 2000;
|
||||
event.reply(eb.setDescription(content.substring(0, index).trim()).build());
|
||||
content = content.substring(index).trim();
|
||||
eb.setAuthor(null).setTitle(null, null);
|
||||
}
|
||||
event.reply(eb.setDescription(content).build());
|
||||
}
|
||||
else
|
||||
event.reply(eb.setDescription(lyrics.getContent()).build());
|
||||
});
|
||||
}
|
||||
}
|
||||
+20
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,19 +13,21 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.music;
|
||||
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.commands.MusicCommand;
|
||||
import net.dv8tion.jda.core.Permission;
|
||||
import net.dv8tion.jda.core.entities.Message;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class NowplayingCmd extends MusicCommand {
|
||||
|
||||
public class NowplayingCmd extends MusicCommand
|
||||
{
|
||||
public NowplayingCmd(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
@@ -36,8 +38,18 @@ public class NowplayingCmd extends MusicCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) {
|
||||
event.reply(FormatUtil.nowPlayingMessage(event.getGuild(), event.getClient().getSuccess()), m->bot.setLastNP(m));
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
Message m = handler.getNowPlaying(event.getJDA());
|
||||
if(m==null)
|
||||
{
|
||||
event.reply(handler.getNoMusicPlaying(event.getJDA()));
|
||||
bot.getNowplayingHandler().clearLastNPMessage(event.getGuild());
|
||||
}
|
||||
else
|
||||
{
|
||||
event.reply(m, msg -> bot.getNowplayingHandler().setLastNPMessage(msg));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+43
-30
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.music;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||
@@ -25,11 +25,15 @@ import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jdautilities.menu.ButtonMenu;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.playlist.Playlist;
|
||||
import com.jagrosh.jmusicbot.audio.QueuedTrack;
|
||||
import com.jagrosh.jmusicbot.commands.MusicCommand;
|
||||
import com.jagrosh.jmusicbot.playlist.PlaylistLoader.Playlist;
|
||||
import com.jagrosh.jmusicbot.settings.Settings;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.dv8tion.jda.core.Permission;
|
||||
import net.dv8tion.jda.core.entities.Message;
|
||||
import net.dv8tion.jda.core.entities.Role;
|
||||
import net.dv8tion.jda.core.exceptions.PermissionException;
|
||||
|
||||
/**
|
||||
@@ -38,8 +42,9 @@ import net.dv8tion.jda.core.exceptions.PermissionException;
|
||||
*/
|
||||
public class PlayCmd extends MusicCommand
|
||||
{
|
||||
public final static String LOAD = "\uD83D\uDCE5";
|
||||
public final static String CANCEL = "\uD83D\uDEAB";
|
||||
private final static String LOAD = "\uD83D\uDCE5"; // 📥
|
||||
private final static String CANCEL = "\uD83D\uDEAB"; // 🚫
|
||||
|
||||
private final String loadingEmoji;
|
||||
|
||||
public PlayCmd(Bot bot, String loadingEmoji)
|
||||
@@ -55,17 +60,20 @@ public class PlayCmd extends MusicCommand
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) {
|
||||
if(event.getArgs().isEmpty())
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
if(event.getArgs().isEmpty() && event.getMessage().getAttachments().isEmpty())
|
||||
{
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
if(handler!=null && handler.getPlayer().getPlayingTrack()!=null && handler.getPlayer().isPaused())
|
||||
if(handler.getPlayer().getPlayingTrack()!=null && handler.getPlayer().isPaused())
|
||||
{
|
||||
boolean isDJ = event.getMember().hasPermission(Permission.MANAGE_SERVER);
|
||||
if(!isDJ)
|
||||
isDJ = event.isOwner();
|
||||
if(!isDJ)
|
||||
isDJ = event.getMember().getRoles().contains(event.getGuild().getRoleById(bot.getSettings(event.getGuild()).getRoleId()));
|
||||
Settings settings = event.getClient().getSettingsFor(event.getGuild());
|
||||
Role dj = settings.getRole(event.getGuild());
|
||||
if(!isDJ && dj!=null)
|
||||
isDJ = event.getMember().getRoles().contains(dj);
|
||||
if(!isDJ)
|
||||
event.replyError("Only DJs can unpause the player!");
|
||||
else
|
||||
@@ -85,15 +93,15 @@ public class PlayCmd extends MusicCommand
|
||||
}
|
||||
String args = event.getArgs().startsWith("<") && event.getArgs().endsWith(">")
|
||||
? event.getArgs().substring(1,event.getArgs().length()-1)
|
||||
: event.getArgs();
|
||||
event.reply(loadingEmoji+" Loading... `["+args+"]`", m -> bot.getAudioManager().loadItemOrdered(event.getGuild(), args, new ResultHandler(m,event,false)));
|
||||
: event.getArgs().isEmpty() ? event.getMessage().getAttachments().get(0).getUrl() : event.getArgs();
|
||||
event.reply(loadingEmoji+" Loading... `["+args+"]`", m -> bot.getPlayerManager().loadItemOrdered(event.getGuild(), args, new ResultHandler(m,event,false)));
|
||||
}
|
||||
|
||||
private class ResultHandler implements AudioLoadResultHandler
|
||||
{
|
||||
final Message m;
|
||||
final CommandEvent event;
|
||||
final boolean ytsearch;
|
||||
private final Message m;
|
||||
private final CommandEvent event;
|
||||
private final boolean ytsearch;
|
||||
|
||||
private ResultHandler(Message m, CommandEvent event, boolean ytsearch)
|
||||
{
|
||||
@@ -104,13 +112,14 @@ public class PlayCmd extends MusicCommand
|
||||
|
||||
private void loadSingle(AudioTrack track, AudioPlaylist playlist)
|
||||
{
|
||||
if(AudioHandler.isTooLong(track))
|
||||
if(bot.getConfig().isTooLong(track))
|
||||
{
|
||||
m.editMessage(FormatUtil.filter(event.getClient().getWarning()+" This track (**"+track.getInfo().title+"**) is longer than the allowed maximum: `"
|
||||
+FormatUtil.formatTime(track.getDuration())+"` > `"+FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`")).queue();
|
||||
+FormatUtil.formatTime(track.getDuration())+"` > `"+FormatUtil.formatTime(bot.getConfig().getMaxSeconds()*1000)+"`")).queue();
|
||||
return;
|
||||
}
|
||||
int pos = bot.queueTrack(event, track)+1;
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
int pos = handler.addTrack(new QueuedTrack(track, event.getAuthor()))+1;
|
||||
String addMsg = FormatUtil.filter(event.getClient().getSuccess()+" Added **"+track.getInfo().title
|
||||
+"** (`"+FormatUtil.formatTime(track.getDuration())+"`) "+(pos==0?"to begin playing":" to the queue at position "+pos));
|
||||
if(playlist==null || !event.getSelfMember().hasPermission(event.getTextChannel(), Permission.MESSAGE_ADD_REACTION))
|
||||
@@ -130,7 +139,7 @@ public class PlayCmd extends MusicCommand
|
||||
m.editMessage(addMsg).queue();
|
||||
}).setFinalAction(m ->
|
||||
{
|
||||
try{m.clearReactions().queue();}catch(PermissionException ex){}
|
||||
try{ m.clearReactions().queue(); }catch(PermissionException ignore) {}
|
||||
}).build().display(m);
|
||||
}
|
||||
}
|
||||
@@ -139,9 +148,10 @@ public class PlayCmd extends MusicCommand
|
||||
{
|
||||
int[] count = {0};
|
||||
playlist.getTracks().stream().forEach((track) -> {
|
||||
if(!AudioHandler.isTooLong(track) && !track.equals(exclude))
|
||||
if(!bot.getConfig().isTooLong(track) && !track.equals(exclude))
|
||||
{
|
||||
bot.queueTrack(event, track);
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
handler.addTrack(new QueuedTrack(track, event.getAuthor()));
|
||||
count[0]++;
|
||||
}
|
||||
});
|
||||
@@ -173,7 +183,7 @@ public class PlayCmd extends MusicCommand
|
||||
if(count==0)
|
||||
{
|
||||
m.editMessage(FormatUtil.filter(event.getClient().getWarning()+" All entries in this playlist "+(playlist.getName()==null ? "" : "(**"+playlist.getName()
|
||||
+"**) ")+"were longer than the allowed maximum (`"+FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`)")).queue();
|
||||
+"**) ")+"were longer than the allowed maximum (`"+bot.getConfig().getMaxTime()+"`)")).queue();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -181,7 +191,7 @@ public class PlayCmd extends MusicCommand
|
||||
+(playlist.getName()==null?"a playlist":"playlist **"+playlist.getName()+"**")+" with `"
|
||||
+ playlist.getTracks().size()+"` entries; added to the queue!"
|
||||
+ (count<playlist.getTracks().size() ? "\n"+event.getClient().getWarning()+" Tracks longer than the allowed maximum (`"
|
||||
+ FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`) have been omitted." : ""))).queue();
|
||||
+ bot.getConfig().getMaxTime()+"`) have been omitted." : ""))).queue();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,7 +202,7 @@ public class PlayCmd extends MusicCommand
|
||||
if(ytsearch)
|
||||
m.editMessage(FormatUtil.filter(event.getClient().getWarning()+" No results found for `"+event.getArgs()+"`.")).queue();
|
||||
else
|
||||
bot.getAudioManager().loadItemOrdered(event.getGuild(), "ytsearch:"+event.getArgs(), new ResultHandler(m,event,true));
|
||||
bot.getPlayerManager().loadItemOrdered(event.getGuild(), "ytsearch:"+event.getArgs(), new ResultHandler(m,event,true));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -205,8 +215,8 @@ public class PlayCmd extends MusicCommand
|
||||
}
|
||||
}
|
||||
|
||||
public class PlaylistCmd extends MusicCommand {
|
||||
|
||||
public class PlaylistCmd extends MusicCommand
|
||||
{
|
||||
public PlaylistCmd(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
@@ -219,20 +229,23 @@ public class PlayCmd extends MusicCommand
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) {
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
if(event.getArgs().isEmpty())
|
||||
{
|
||||
event.reply(event.getClient().getError()+" Please include a playlist name.");
|
||||
return;
|
||||
}
|
||||
Playlist playlist = Playlist.loadPlaylist(event.getArgs());
|
||||
Playlist playlist = bot.getPlaylistLoader().getPlaylist(event.getArgs());
|
||||
if(playlist==null)
|
||||
{
|
||||
event.reply(event.getClient().getError()+" I could not find `"+event.getArgs()+".txt` in the Playlists folder.");
|
||||
event.replyError("I could not find `"+event.getArgs()+".txt` in the Playlists folder.");
|
||||
return;
|
||||
}
|
||||
event.getChannel().sendMessage(loadingEmoji+" Loading playlist **"+event.getArgs()+"**... ("+playlist.getItems().size()+" items)").queue(m -> {
|
||||
playlist.loadTracks(bot.getAudioManager(), (at)->bot.queueTrack(event, at), () -> {
|
||||
event.getChannel().sendMessage(loadingEmoji+" Loading playlist **"+event.getArgs()+"**... ("+playlist.getItems().size()+" items)").queue(m ->
|
||||
{
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
playlist.loadTracks(bot.getPlayerManager(), (at)->handler.addTrack(new QueuedTrack(at, event.getAuthor())), () -> {
|
||||
StringBuilder builder = new StringBuilder(playlist.getTracks().isEmpty()
|
||||
? event.getClient().getWarning()+" No tracks were loaded!"
|
||||
: event.getClient().getSuccess()+" Loaded **"+playlist.getTracks().size()+"** tracks!");
|
||||
+11
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017 John Grosh <john.a.grosh@gmail.com>.
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,19 +13,19 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.music;
|
||||
|
||||
import java.util.List;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.playlist.Playlist;
|
||||
import com.jagrosh.jmusicbot.commands.MusicCommand;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class PlaylistsCmd extends MusicCommand {
|
||||
|
||||
public class PlaylistsCmd extends MusicCommand
|
||||
{
|
||||
public PlaylistsCmd(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
@@ -38,15 +38,16 @@ public class PlaylistsCmd extends MusicCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) {
|
||||
if(!Playlist.folderExists())
|
||||
Playlist.createFolder();
|
||||
if(!Playlist.folderExists())
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
if(!bot.getPlaylistLoader().folderExists())
|
||||
bot.getPlaylistLoader().createFolder();
|
||||
if(!bot.getPlaylistLoader().folderExists())
|
||||
{
|
||||
event.reply(event.getClient().getWarning()+" Playlists folder does not exist and could not be created!");
|
||||
return;
|
||||
}
|
||||
List<String> list = Playlist.getPlaylists();
|
||||
List<String> list = bot.getPlaylistLoader().getPlaylistNames();
|
||||
if(list==null)
|
||||
event.reply(event.getClient().getError()+" Failed to load available playlists!");
|
||||
else if(list.isEmpty())
|
||||
@@ -59,5 +60,4 @@ public class PlaylistsCmd extends MusicCommand {
|
||||
event.reply(builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+34
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,26 +13,34 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.music;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jdautilities.menu.Paginator;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.JMusicBot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.audio.QueuedTrack;
|
||||
import com.jagrosh.jmusicbot.commands.MusicCommand;
|
||||
import com.jagrosh.jmusicbot.settings.Settings;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import net.dv8tion.jda.core.MessageBuilder;
|
||||
import net.dv8tion.jda.core.Permission;
|
||||
import net.dv8tion.jda.core.entities.Message;
|
||||
import net.dv8tion.jda.core.exceptions.PermissionException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class QueueCmd extends MusicCommand {
|
||||
|
||||
public class QueueCmd extends MusicCommand
|
||||
{
|
||||
private final static String REPEAT = "\uD83D\uDD01"; // 🔁
|
||||
|
||||
private final Paginator.Builder builder;
|
||||
|
||||
public QueueCmd(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
@@ -44,7 +52,7 @@ public class QueueCmd extends MusicCommand {
|
||||
this.botPermissions = new Permission[]{Permission.MESSAGE_ADD_REACTION,Permission.MESSAGE_EMBED_LINKS};
|
||||
builder = new Paginator.Builder()
|
||||
.setColumns(1)
|
||||
.setFinalAction(m -> {try{m.clearReactions().queue();}catch(PermissionException e){}})
|
||||
.setFinalAction(m -> {try{m.clearReactions().queue();}catch(PermissionException ignore){}})
|
||||
.setItemsPerPage(10)
|
||||
.waitOnSinglePage(false)
|
||||
.useNumberedItems(true)
|
||||
@@ -57,15 +65,25 @@ public class QueueCmd extends MusicCommand {
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
int pagenum = 1;
|
||||
try{
|
||||
try
|
||||
{
|
||||
pagenum = Integer.parseInt(event.getArgs());
|
||||
}catch(NumberFormatException e){}
|
||||
}
|
||||
catch(NumberFormatException ignore){}
|
||||
AudioHandler ah = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
List<QueuedTrack> list = ah.getQueue().getList();
|
||||
if(list.isEmpty())
|
||||
{
|
||||
event.replyWarning("There is no music in the queue!"
|
||||
+(!ah.isMusicPlaying() ? "" : " Now playing:\n\n**"+ah.getPlayer().getPlayingTrack().getInfo().title+"**\n"+FormatUtil.embedFormat(ah)));
|
||||
Message nowp = ah.getNowPlaying(event.getJDA());
|
||||
Message nonowp = ah.getNoMusicPlaying(event.getJDA());
|
||||
Message built = new MessageBuilder()
|
||||
.setContent(event.getClient().getWarning() + " There is no music in the queue!")
|
||||
.setEmbed((nowp==null ? nonowp : nowp).getEmbeds().get(0)).build();
|
||||
event.reply(built, m ->
|
||||
{
|
||||
if(nowp!=null)
|
||||
bot.getNowplayingHandler().setLastNPMessage(m);
|
||||
});
|
||||
return;
|
||||
}
|
||||
String[] songs = new String[list.size()];
|
||||
@@ -75,8 +93,9 @@ public class QueueCmd extends MusicCommand {
|
||||
total += list.get(i).getTrack().getDuration();
|
||||
songs[i] = list.get(i).toString();
|
||||
}
|
||||
Settings settings = event.getClient().getSettingsFor(event.getGuild());
|
||||
long fintotal = total;
|
||||
builder.setText((i1,i2) -> event.getClient().getSuccess()+" "+getQueueTitle(ah, event.getClient().getSuccess(), songs.length, fintotal, bot.getSettings(event.getGuild()).getRepeatMode()))
|
||||
builder.setText((i1,i2) -> getQueueTitle(ah, event.getClient().getSuccess(), songs.length, fintotal, settings.getRepeatMode()))
|
||||
.setItems(songs)
|
||||
.setUsers(event.getAuthor())
|
||||
.setColor(event.getSelfMember().getColor())
|
||||
@@ -88,9 +107,12 @@ public class QueueCmd extends MusicCommand {
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if(ah.getPlayer().getPlayingTrack()!=null)
|
||||
sb.append("**").append(ah.getPlayer().getPlayingTrack().getInfo().title).append("**\n").append(FormatUtil.embedFormat(ah)).append("\n\n");
|
||||
{
|
||||
sb.append(ah.getPlayer().isPaused() ? JMusicBot.PAUSE_EMOJI : JMusicBot.PLAY_EMOJI).append(" **")
|
||||
.append(ah.getPlayer().getPlayingTrack().getInfo().title).append("**\n");
|
||||
}
|
||||
return FormatUtil.filter(sb.append(success).append(" Current Queue | ").append(songslength)
|
||||
.append(" entries | `").append(FormatUtil.formatTime(total)).append("` ")
|
||||
.append(repeatmode ? "| \uD83D\uDD01" : "").toString());
|
||||
.append(repeatmode ? "| " + REPEAT : "").toString());
|
||||
}
|
||||
}
|
||||
+9
-6
@@ -13,12 +13,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.music;
|
||||
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.audio.QueuedTrack;
|
||||
import com.jagrosh.jmusicbot.commands.MusicCommand;
|
||||
import com.jagrosh.jmusicbot.settings.Settings;
|
||||
import net.dv8tion.jda.core.Permission;
|
||||
import net.dv8tion.jda.core.entities.User;
|
||||
|
||||
@@ -26,8 +28,8 @@ import net.dv8tion.jda.core.entities.User;
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class RemoveCmd extends MusicCommand {
|
||||
|
||||
public class RemoveCmd extends MusicCommand
|
||||
{
|
||||
public RemoveCmd(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
@@ -40,7 +42,8 @@ public class RemoveCmd extends MusicCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) {
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
if(handler.getQueue().isEmpty())
|
||||
{
|
||||
@@ -67,9 +70,10 @@ public class RemoveCmd extends MusicCommand {
|
||||
event.replyError("Position must be a valid integer between 1 and "+handler.getQueue().size()+"!");
|
||||
return;
|
||||
}
|
||||
Settings settings = event.getClient().getSettingsFor(event.getGuild());
|
||||
boolean isDJ = event.getMember().hasPermission(Permission.MANAGE_SERVER);
|
||||
if(!isDJ)
|
||||
isDJ = event.getMember().getRoles().contains(event.getGuild().getRoleById(bot.getSettings(event.getGuild()).getRoleId()));
|
||||
isDJ = event.getMember().getRoles().contains(settings.getRole(event.getGuild()));
|
||||
QueuedTrack qt = handler.getQueue().get(pos-1);
|
||||
if(qt.getIdentifier()==event.getAuthor().getIdLong())
|
||||
{
|
||||
@@ -93,5 +97,4 @@ public class RemoveCmd extends MusicCommand {
|
||||
event.replyError("You cannot remove **"+qt.getTrack().getInfo().title+"** because you didn't add it!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands.music;
|
||||
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SCSearchCmd extends SearchCmd
|
||||
{
|
||||
public SCSearchCmd(Bot bot, String searchingEmoji)
|
||||
{
|
||||
super(bot, searchingEmoji);
|
||||
this.searchPrefix = "scsearch:";
|
||||
this.name = "scsearch";
|
||||
this.help = "searches Soundcloud for a provided query";
|
||||
this.aliases = new String[]{};
|
||||
}
|
||||
}
|
||||
+36
-24
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.music;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||
@@ -25,6 +25,8 @@ import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jdautilities.menu.OrderedMenu;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.audio.QueuedTrack;
|
||||
import com.jagrosh.jmusicbot.commands.MusicCommand;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import net.dv8tion.jda.core.Permission;
|
||||
import net.dv8tion.jda.core.entities.Message;
|
||||
@@ -33,10 +35,12 @@ import net.dv8tion.jda.core.entities.Message;
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SearchCmd extends MusicCommand {
|
||||
|
||||
public class SearchCmd extends MusicCommand
|
||||
{
|
||||
protected String searchPrefix = "ytsearch:";
|
||||
private final OrderedMenu.Builder builder;
|
||||
private final String searchingEmoji;
|
||||
|
||||
public SearchCmd(Bot bot, String searchingEmoji)
|
||||
{
|
||||
super(bot);
|
||||
@@ -53,22 +57,25 @@ public class SearchCmd extends MusicCommand {
|
||||
.useNumbers()
|
||||
.useCancelButton(true)
|
||||
.setEventWaiter(bot.getWaiter())
|
||||
.setTimeout(1, TimeUnit.MINUTES)
|
||||
;
|
||||
.setTimeout(1, TimeUnit.MINUTES);
|
||||
}
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) {
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
if(event.getArgs().isEmpty())
|
||||
{
|
||||
event.reply(event.getClient().getError()+" Please include a query.");
|
||||
event.replyError("Please include a query.");
|
||||
return;
|
||||
}
|
||||
event.reply(searchingEmoji+" Searching... `["+event.getArgs()+"]`",m ->bot.getAudioManager().loadItemOrdered(event.getGuild(), "ytsearch:"+event.getArgs(), new ResultHandler(m,event)));
|
||||
event.reply(searchingEmoji+" Searching... `["+event.getArgs()+"]`",
|
||||
m -> bot.getPlayerManager().loadItemOrdered(event.getGuild(), searchPrefix + event.getArgs(), new ResultHandler(m,event)));
|
||||
}
|
||||
|
||||
private class ResultHandler implements AudioLoadResultHandler {
|
||||
final Message m;
|
||||
final CommandEvent event;
|
||||
private class ResultHandler implements AudioLoadResultHandler
|
||||
{
|
||||
private final Message m;
|
||||
private final CommandEvent event;
|
||||
|
||||
private ResultHandler(Message m, CommandEvent event)
|
||||
{
|
||||
this.m = m;
|
||||
@@ -76,14 +83,16 @@ public class SearchCmd extends MusicCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackLoaded(AudioTrack track) {
|
||||
if(AudioHandler.isTooLong(track))
|
||||
public void trackLoaded(AudioTrack track)
|
||||
{
|
||||
if(bot.getConfig().isTooLong(track))
|
||||
{
|
||||
m.editMessage(FormatUtil.filter(event.getClient().getWarning()+" This track (**"+track.getInfo().title+"**) is longer than the allowed maximum: `"
|
||||
+FormatUtil.formatTime(track.getDuration())+"` > `"+FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`")).queue();
|
||||
+FormatUtil.formatTime(track.getDuration())+"` > `"+bot.getConfig().getMaxTime()+"`")).queue();
|
||||
return;
|
||||
}
|
||||
int pos = bot.queueTrack(event, track)+1;
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
int pos = handler.addTrack(new QueuedTrack(track, event.getAuthor()))+1;
|
||||
m.editMessage(FormatUtil.filter(event.getClient().getSuccess()+" Added **"+track.getInfo().title
|
||||
+"** (`"+FormatUtil.formatTime(track.getDuration())+"`) "+(pos==0 ? "to begin playing"
|
||||
: " to the queue at position "+pos))).queue();
|
||||
@@ -95,15 +104,17 @@ public class SearchCmd extends MusicCommand {
|
||||
builder.setColor(event.getSelfMember().getColor())
|
||||
.setText(FormatUtil.filter(event.getClient().getSuccess()+" Search results for `"+event.getArgs()+"`:"))
|
||||
.setChoices(new String[0])
|
||||
.setSelection((msg,i) -> {
|
||||
.setSelection((msg,i) ->
|
||||
{
|
||||
AudioTrack track = playlist.getTracks().get(i-1);
|
||||
if(AudioHandler.isTooLong(track))
|
||||
if(bot.getConfig().isTooLong(track))
|
||||
{
|
||||
event.replyWarning("This track (**"+track.getInfo().title+"**) is longer than the allowed maximum: `"
|
||||
+FormatUtil.formatTime(track.getDuration())+"` > `"+FormatUtil.formatTime(AudioHandler.MAX_SECONDS*1000)+"`");
|
||||
+FormatUtil.formatTime(track.getDuration())+"` > `"+bot.getConfig().getMaxTime()+"`");
|
||||
return;
|
||||
}
|
||||
int pos = bot.queueTrack(event, track)+1;
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
int pos = handler.addTrack(new QueuedTrack(track, event.getAuthor()))+1;
|
||||
event.replySuccess("Added **"+track.getInfo().title
|
||||
+"** (`"+FormatUtil.formatTime(track.getDuration())+"`) "+(pos==0 ? "to begin playing"
|
||||
: " to the queue at position "+pos));
|
||||
@@ -111,22 +122,23 @@ public class SearchCmd extends MusicCommand {
|
||||
.setCancel((msg) -> {})
|
||||
.setUsers(event.getAuthor())
|
||||
;
|
||||
for(int i=0; i<4&&i<playlist.getTracks().size(); i++)
|
||||
for(int i=0; i<4 && i<playlist.getTracks().size(); i++)
|
||||
{
|
||||
AudioTrack track = playlist.getTracks().get(i);
|
||||
builder.addChoices("`["+FormatUtil.formatTime(track.getDuration())+"]` [**"
|
||||
+track.getInfo().title+"**](https://youtu.be/"+track.getIdentifier()+")");
|
||||
builder.addChoices("`["+FormatUtil.formatTime(track.getDuration())+"]` [**"+track.getInfo().title+"**]("+track.getInfo().uri+")");
|
||||
}
|
||||
builder.build().display(m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noMatches() {
|
||||
public void noMatches()
|
||||
{
|
||||
m.editMessage(FormatUtil.filter(event.getClient().getWarning()+" No results found for `"+event.getArgs()+"`.")).queue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFailed(FriendlyException throwable) {
|
||||
public void loadFailed(FriendlyException throwable)
|
||||
{
|
||||
if(throwable.severity==Severity.COMMON)
|
||||
m.editMessage(event.getClient().getError()+" Error loading: "+throwable.getMessage()).queue();
|
||||
else
|
||||
+12
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,18 +13,19 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.music;
|
||||
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.commands.MusicCommand;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class ShuffleCmd extends MusicCommand {
|
||||
|
||||
public class ShuffleCmd extends MusicCommand
|
||||
{
|
||||
public ShuffleCmd(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
@@ -35,18 +36,20 @@ public class ShuffleCmd extends MusicCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) {
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
int s = handler.getQueue().shuffle(event.getAuthor().getIdLong());
|
||||
switch (s) {
|
||||
switch (s)
|
||||
{
|
||||
case 0:
|
||||
event.reply(event.getClient().getError()+" You don't have any music in the queue to shuffle!");
|
||||
event.replyError("You don't have any music in the queue to shuffle!");
|
||||
break;
|
||||
case 1:
|
||||
event.reply(event.getClient().getWarning()+" You only have one song in the queue!");
|
||||
event.replyWarning("You only have one song in the queue!");
|
||||
break;
|
||||
default:
|
||||
event.reply(event.getClient().getSuccess()+" You successfully shuffled your "+s+" entries.");
|
||||
event.replySuccess("You successfully shuffled your "+s+" entries.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
+6
-4
@@ -13,19 +13,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.music;
|
||||
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.commands.MusicCommand;
|
||||
import net.dv8tion.jda.core.entities.User;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SkipCmd extends MusicCommand {
|
||||
|
||||
public class SkipCmd extends MusicCommand
|
||||
{
|
||||
public SkipCmd(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
@@ -37,7 +38,8 @@ public class SkipCmd extends MusicCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(CommandEvent event) {
|
||||
public void doCommand(CommandEvent event)
|
||||
{
|
||||
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
|
||||
if(event.getAuthor().getIdLong()==handler.getRequester())
|
||||
{
|
||||
+13
-11
@@ -13,25 +13,24 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.owner;
|
||||
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.playlist.Playlist;
|
||||
import com.jagrosh.jmusicbot.commands.OwnerCommand;
|
||||
import com.jagrosh.jmusicbot.settings.Settings;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class AutoplaylistCmd extends Command {
|
||||
|
||||
public class AutoplaylistCmd extends OwnerCommand
|
||||
{
|
||||
private final Bot bot;
|
||||
|
||||
public AutoplaylistCmd(Bot bot)
|
||||
{
|
||||
this.bot = bot;
|
||||
this.category = bot.OWNER;
|
||||
this.ownerCommand = true;
|
||||
this.guildOnly = true;
|
||||
this.name = "autoplaylist";
|
||||
this.arguments = "<name|NONE>";
|
||||
@@ -39,7 +38,8 @@ public class AutoplaylistCmd extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandEvent event) {
|
||||
public void execute(CommandEvent event)
|
||||
{
|
||||
if(event.getArgs().isEmpty())
|
||||
{
|
||||
event.reply(event.getClient().getError()+" Please include a playlist name or NONE");
|
||||
@@ -47,18 +47,20 @@ public class AutoplaylistCmd extends Command {
|
||||
}
|
||||
if(event.getArgs().equalsIgnoreCase("none"))
|
||||
{
|
||||
bot.setDefaultPlaylist(event.getGuild(), null);
|
||||
Settings settings = event.getClient().getSettingsFor(event.getGuild());
|
||||
settings.setDefaultPlaylist(null);
|
||||
event.reply(event.getClient().getSuccess()+" Cleared the default playlist for **"+event.getGuild().getName()+"**");
|
||||
return;
|
||||
}
|
||||
String pname = event.getArgs().replaceAll("\\s+", "_");
|
||||
if(Playlist.loadPlaylist(pname)==null)
|
||||
if(bot.getPlaylistLoader().getPlaylist(pname)==null)
|
||||
{
|
||||
event.reply(event.getClient().getError()+" Could not find `"+pname+".txt`!");
|
||||
}
|
||||
else
|
||||
{
|
||||
bot.setDefaultPlaylist(event.getGuild(), pname);
|
||||
Settings settings = event.getClient().getSettingsFor(event.getGuild());
|
||||
settings.setDefaultPlaylist(pname);
|
||||
event.reply(event.getClient().getSuccess()+" The default playlist for **"+event.getGuild().getName()+"** is now `"+pname+"`");
|
||||
}
|
||||
}
|
||||
+10
-7
@@ -13,32 +13,35 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.owner;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.commands.OwnerCommand;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (jagrosh)
|
||||
*/
|
||||
public class EvalCmd extends Command {
|
||||
|
||||
public class EvalCmd extends OwnerCommand
|
||||
{
|
||||
private final Bot bot;
|
||||
|
||||
public EvalCmd(Bot bot)
|
||||
{
|
||||
this.bot = bot;
|
||||
this.name = "eval";
|
||||
this.help = "evaluates nashorn code";
|
||||
this.ownerCommand = true;
|
||||
this.guildOnly = false;
|
||||
this.category = bot.OWNER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
ScriptEngine se = new ScriptEngineManager().getEngineByName("Nashorn");
|
||||
se.put("bot", bot);
|
||||
se.put("event", event);
|
||||
se.put("jda", event.getJDA());
|
||||
se.put("guild", event.getGuild());
|
||||
+41
-73
@@ -13,45 +13,43 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.owner;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.playlist.Playlist;
|
||||
import com.jagrosh.jmusicbot.commands.OwnerCommand;
|
||||
import com.jagrosh.jmusicbot.commands.owner.AutoplaylistCmd;
|
||||
import com.jagrosh.jmusicbot.playlist.PlaylistLoader.Playlist;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class PlaylistCmd extends Command {
|
||||
|
||||
public class PlaylistCmd extends OwnerCommand
|
||||
{
|
||||
private final Bot bot;
|
||||
public PlaylistCmd(Bot bot)
|
||||
{
|
||||
this.bot = bot;
|
||||
this.category = bot.OWNER;
|
||||
this.ownerCommand = true;
|
||||
this.guildOnly = false;
|
||||
this.name = "playlist";
|
||||
this.arguments = "<append|delete|make|setdefault>";
|
||||
this.help = "playlist management";
|
||||
this.children = new Command[]{
|
||||
this.children = new OwnerCommand[]{
|
||||
new ListCmd(),
|
||||
new AppendlistCmd(),
|
||||
new DeletelistCmd(),
|
||||
new MakelistCmd(),
|
||||
new DefaultlistCmd()
|
||||
new DefaultlistCmd(bot)
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandEvent event) {
|
||||
public void execute(CommandEvent event)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(event.getClient().getWarning()+" Playlist Management Commands:\n");
|
||||
for(Command cmd: this.children)
|
||||
builder.append("\n`").append(event.getClient().getPrefix()).append(name).append(" ").append(cmd.getName())
|
||||
@@ -59,27 +57,26 @@ public class PlaylistCmd extends Command {
|
||||
event.reply(builder.toString());
|
||||
}
|
||||
|
||||
public class MakelistCmd extends Command {
|
||||
|
||||
public class MakelistCmd extends OwnerCommand
|
||||
{
|
||||
public MakelistCmd()
|
||||
{
|
||||
this.name = "make";
|
||||
this.aliases = new String[]{"create"};
|
||||
this.help = "makes a new playlist";
|
||||
this.arguments = "<name>";
|
||||
this.category = bot.OWNER;
|
||||
this.ownerCommand = true;
|
||||
this.guildOnly = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
String pname = event.getArgs().replaceAll("\\s+", "_");
|
||||
if(Playlist.loadPlaylist(pname)==null)
|
||||
if(bot.getPlaylistLoader().getPlaylist(pname)==null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Files.createFile(Paths.get("Playlists"+File.separator+pname+".txt"));
|
||||
bot.getPlaylistLoader().createPlaylist(pname);
|
||||
event.reply(event.getClient().getSuccess()+" Successfully created playlist `"+pname+"`!");
|
||||
}
|
||||
catch(IOException e)
|
||||
@@ -92,8 +89,8 @@ public class PlaylistCmd extends Command {
|
||||
}
|
||||
}
|
||||
|
||||
public class DeletelistCmd extends Command {
|
||||
|
||||
public class DeletelistCmd extends OwnerCommand
|
||||
{
|
||||
public DeletelistCmd()
|
||||
{
|
||||
this.name = "delete";
|
||||
@@ -101,20 +98,19 @@ public class PlaylistCmd extends Command {
|
||||
this.help = "deletes an existing playlist";
|
||||
this.arguments = "<name>";
|
||||
this.guildOnly = false;
|
||||
this.ownerCommand = true;
|
||||
this.category = bot.OWNER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
String pname = event.getArgs().replaceAll("\\s+", "_");
|
||||
if(Playlist.loadPlaylist(pname)==null)
|
||||
if(bot.getPlaylistLoader().getPlaylist(pname)==null)
|
||||
event.reply(event.getClient().getError()+" Playlist `"+pname+"` doesn't exist!");
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
Files.delete(Paths.get("Playlists"+File.separator+pname+".txt"));
|
||||
bot.getPlaylistLoader().deletePlaylist(pname);
|
||||
event.reply(event.getClient().getSuccess()+" Successfully deleted playlist `"+pname+"`!");
|
||||
}
|
||||
catch(IOException e)
|
||||
@@ -125,8 +121,8 @@ public class PlaylistCmd extends Command {
|
||||
}
|
||||
}
|
||||
|
||||
public class AppendlistCmd extends Command {
|
||||
|
||||
public class AppendlistCmd extends OwnerCommand
|
||||
{
|
||||
public AppendlistCmd()
|
||||
{
|
||||
this.name = "append";
|
||||
@@ -134,12 +130,11 @@ public class PlaylistCmd extends Command {
|
||||
this.help = "appends songs to an existing playlist";
|
||||
this.arguments = "<name> <URL> | <URL> | ...";
|
||||
this.guildOnly = false;
|
||||
this.ownerCommand = true;
|
||||
this.category = bot.OWNER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
String[] parts = event.getArgs().split("\\s+", 2);
|
||||
if(parts.length<2)
|
||||
{
|
||||
@@ -147,7 +142,7 @@ public class PlaylistCmd extends Command {
|
||||
return;
|
||||
}
|
||||
String pname = parts[0];
|
||||
Playlist playlist = Playlist.loadPlaylist(pname);
|
||||
Playlist playlist = bot.getPlaylistLoader().getPlaylist(pname);
|
||||
if(playlist==null)
|
||||
event.reply(event.getClient().getError()+" Playlist `"+pname+"` doesn't exist!");
|
||||
else
|
||||
@@ -164,8 +159,8 @@ public class PlaylistCmd extends Command {
|
||||
}
|
||||
try
|
||||
{
|
||||
Files.write(Paths.get("Playlists"+File.separator+pname+".txt"), builder.toString().trim().getBytes());
|
||||
event.reply(event.getClient().getSuccess()+" Successfully added "+urls.length+" songs to playlist `"+pname+"`!");
|
||||
bot.getPlaylistLoader().writePlaylist(pname, builder.toString());
|
||||
event.reply(event.getClient().getSuccess()+" Successfully added "+urls.length+" items to playlist `"+pname+"`!");
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
@@ -175,66 +170,39 @@ public class PlaylistCmd extends Command {
|
||||
}
|
||||
}
|
||||
|
||||
public class DefaultlistCmd extends Command {
|
||||
|
||||
public DefaultlistCmd()
|
||||
public class DefaultlistCmd extends AutoplaylistCmd
|
||||
{
|
||||
public DefaultlistCmd(Bot bot)
|
||||
{
|
||||
super(bot);
|
||||
this.name = "setdefault";
|
||||
this.aliases = new String[]{"default"};
|
||||
this.help = "sets the default playlist for the server";
|
||||
this.arguments = "<playlistname|NONE>";
|
||||
this.guildOnly = true;
|
||||
this.ownerCommand = true;
|
||||
this.category = bot.OWNER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
if(event.getArgs().isEmpty())
|
||||
{
|
||||
event.reply(event.getClient().getError()+" Please include a playlist name or NONE");
|
||||
}
|
||||
if(event.getArgs().equalsIgnoreCase("none"))
|
||||
{
|
||||
bot.setDefaultPlaylist(event.getGuild(), null);
|
||||
event.reply(event.getClient().getSuccess()+" Cleared the default playlist for **"+event.getGuild().getName()+"**");
|
||||
return;
|
||||
}
|
||||
String pname = event.getArgs().replaceAll("\\s+", "_");
|
||||
if(Playlist.loadPlaylist(pname)==null)
|
||||
{
|
||||
event.reply(event.getClient().getError()+" Could not find `"+pname+".txt`!");
|
||||
}
|
||||
else
|
||||
{
|
||||
bot.setDefaultPlaylist(event.getGuild(), pname);
|
||||
event.reply(event.getClient().getSuccess()+" The default playlist for **"+event.getGuild().getName()+"** is now `"+pname+"`");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ListCmd extends Command {
|
||||
|
||||
public class ListCmd extends OwnerCommand
|
||||
{
|
||||
public ListCmd()
|
||||
{
|
||||
this.name = "all";
|
||||
this.aliases = new String[]{"available","list"};
|
||||
this.help = "lists all available playlists";
|
||||
this.guildOnly = true;
|
||||
this.ownerCommand = true;
|
||||
this.category = bot.OWNER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
if(!Playlist.folderExists())
|
||||
Playlist.createFolder();
|
||||
if(!Playlist.folderExists())
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
if(!bot.getPlaylistLoader().folderExists())
|
||||
bot.getPlaylistLoader().createFolder();
|
||||
if(!bot.getPlaylistLoader().folderExists())
|
||||
{
|
||||
event.reply(event.getClient().getWarning()+" Playlists folder does not exist and could not be created!");
|
||||
return;
|
||||
}
|
||||
List<String> list = Playlist.getPlaylists();
|
||||
List<String> list = bot.getPlaylistLoader().getPlaylistNames();
|
||||
if(list==null)
|
||||
event.reply(event.getClient().getError()+" Failed to load available playlists!");
|
||||
else if(list.isEmpty())
|
||||
+8
-11
@@ -13,14 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.owner;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.commands.OwnerCommand;
|
||||
import com.jagrosh.jmusicbot.utils.OtherUtil;
|
||||
import net.dv8tion.jda.core.entities.Icon;
|
||||
|
||||
@@ -28,19 +26,19 @@ import net.dv8tion.jda.core.entities.Icon;
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SetavatarCmd extends Command {
|
||||
|
||||
public SetavatarCmd(Bot bot)
|
||||
public class SetavatarCmd extends OwnerCommand
|
||||
{
|
||||
public SetavatarCmd()
|
||||
{
|
||||
this.name = "setavatar";
|
||||
this.help = "sets the avatar of the bot";
|
||||
this.arguments = "<url>";
|
||||
this.ownerCommand = true;
|
||||
this.category = bot.OWNER;
|
||||
this.guildOnly = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
String url;
|
||||
if(event.getArgs().isEmpty())
|
||||
if(!event.getMessage().getAttachments().isEmpty() && event.getMessage().getAttachments().get(0).isImage())
|
||||
@@ -65,5 +63,4 @@ public class SetavatarCmd extends Command {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+20
-24
@@ -13,35 +13,34 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.owner;
|
||||
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.commands.OwnerCommand;
|
||||
import net.dv8tion.jda.core.entities.Game;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SetgameCmd extends Command
|
||||
public class SetgameCmd extends OwnerCommand
|
||||
{
|
||||
public SetgameCmd(Bot bot)
|
||||
public SetgameCmd()
|
||||
{
|
||||
this.name = "setgame";
|
||||
this.help = "sets the game the bot is playing";
|
||||
this.arguments = "[action] [game]";
|
||||
this.ownerCommand = true;
|
||||
this.category = bot.OWNER;
|
||||
this.children = new Command[]{
|
||||
new SetlistenCmd(bot),
|
||||
new SetstreamCmd(bot),
|
||||
new SetwatchCmd(bot)
|
||||
this.guildOnly = false;
|
||||
this.children = new OwnerCommand[]{
|
||||
new SetlistenCmd(),
|
||||
new SetstreamCmd(),
|
||||
new SetwatchCmd()
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
String title = event.getArgs().toLowerCase().startsWith("playing") ? event.getArgs().substring(7).trim() : event.getArgs();
|
||||
try
|
||||
{
|
||||
@@ -55,16 +54,15 @@ public class SetgameCmd extends Command
|
||||
}
|
||||
}
|
||||
|
||||
private class SetstreamCmd extends Command
|
||||
private class SetstreamCmd extends OwnerCommand
|
||||
{
|
||||
private SetstreamCmd(Bot bot)
|
||||
private SetstreamCmd()
|
||||
{
|
||||
this.name = "stream";
|
||||
this.aliases = new String[]{"twitch","streaming"};
|
||||
this.help = "sets the game the bot is playing to a stream";
|
||||
this.arguments = "<username> <game>";
|
||||
this.ownerCommand = true;
|
||||
this.category = bot.OWNER;
|
||||
this.guildOnly = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,16 +87,15 @@ public class SetgameCmd extends Command
|
||||
}
|
||||
}
|
||||
|
||||
private class SetlistenCmd extends Command
|
||||
private class SetlistenCmd extends OwnerCommand
|
||||
{
|
||||
private SetlistenCmd(Bot bot)
|
||||
private SetlistenCmd()
|
||||
{
|
||||
this.name = "listen";
|
||||
this.aliases = new String[]{"listening"};
|
||||
this.help = "sets the game the bot is listening to";
|
||||
this.arguments = "<title>";
|
||||
this.ownerCommand = true;
|
||||
this.category = bot.OWNER;
|
||||
this.guildOnly = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -120,16 +117,15 @@ public class SetgameCmd extends Command
|
||||
}
|
||||
}
|
||||
|
||||
private class SetwatchCmd extends Command
|
||||
private class SetwatchCmd extends OwnerCommand
|
||||
{
|
||||
private SetwatchCmd(Bot bot)
|
||||
private SetwatchCmd()
|
||||
{
|
||||
this.name = "watch";
|
||||
this.aliases = new String[]{"watching"};
|
||||
this.help = "sets the game the bot is watching";
|
||||
this.arguments = "<title>";
|
||||
this.ownerCommand = true;
|
||||
this.category = bot.OWNER;
|
||||
this.guildOnly = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
+55
-51
@@ -1,51 +1,55 @@
|
||||
/*
|
||||
* Copyright 2017 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import net.dv8tion.jda.core.exceptions.RateLimitedException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SetnameCmd extends Command {
|
||||
|
||||
public SetnameCmd(Bot bot)
|
||||
{
|
||||
this.name = "setname";
|
||||
this.help = "sets the name of the bot";
|
||||
this.arguments = "<name>";
|
||||
this.ownerCommand = true;
|
||||
this.category = bot.OWNER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
try {
|
||||
String oldname = event.getSelfUser().getName();
|
||||
event.getSelfUser().getManager().setName(event.getArgs()).complete(false);
|
||||
event.reply(event.getClient().getSuccess()+" Name changed from `"+oldname+"` to `"+event.getArgs()+"`");
|
||||
} catch(RateLimitedException e) {
|
||||
event.reply(event.getClient().getError()+" Name can only be changed twice per hour!");
|
||||
} catch(Exception e) {
|
||||
event.reply(event.getClient().getError()+" That name is not valid!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands.owner;
|
||||
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.commands.OwnerCommand;
|
||||
import net.dv8tion.jda.core.exceptions.RateLimitedException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SetnameCmd extends OwnerCommand
|
||||
{
|
||||
public SetnameCmd()
|
||||
{
|
||||
this.name = "setname";
|
||||
this.help = "sets the name of the bot";
|
||||
this.arguments = "<name>";
|
||||
this.guildOnly = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
try
|
||||
{
|
||||
String oldname = event.getSelfUser().getName();
|
||||
event.getSelfUser().getManager().setName(event.getArgs()).complete(false);
|
||||
event.reply(event.getClient().getSuccess()+" Name changed from `"+oldname+"` to `"+event.getArgs()+"`");
|
||||
}
|
||||
catch(RateLimitedException e)
|
||||
{
|
||||
event.reply(event.getClient().getError()+" Name can only be changed twice per hour!");
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
event.reply(event.getClient().getError()+" That name is not valid!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-10
@@ -13,30 +13,29 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
package com.jagrosh.jmusicbot.commands.owner;
|
||||
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.commands.OwnerCommand;
|
||||
import net.dv8tion.jda.core.OnlineStatus;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class SetstatusCmd extends Command {
|
||||
|
||||
public SetstatusCmd(Bot bot)
|
||||
public class SetstatusCmd extends OwnerCommand
|
||||
{
|
||||
public SetstatusCmd()
|
||||
{
|
||||
this.name = "setstatus";
|
||||
this.help = "sets the status the bot displays";
|
||||
this.arguments = "<status>";
|
||||
this.ownerCommand = true;
|
||||
this.category = bot.OWNER;
|
||||
this.guildOnly = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
try {
|
||||
OnlineStatus status = OnlineStatus.fromKey(event.getArgs());
|
||||
if(status==OnlineStatus.UNKNOWN)
|
||||
@@ -52,5 +51,4 @@ public class SetstatusCmd extends Command {
|
||||
event.reply(event.getClient().getError()+" The status could not be set!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+44
-44
@@ -1,44 +1,44 @@
|
||||
/*
|
||||
* Copyright 2017 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands;
|
||||
|
||||
import com.jagrosh.jdautilities.command.Command;
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class ShutdownCmd extends Command {
|
||||
|
||||
private final Bot bot;
|
||||
public ShutdownCmd(Bot bot)
|
||||
{
|
||||
this.bot = bot;
|
||||
this.name = "shutdown";
|
||||
this.help = "safely shuts down";
|
||||
this.ownerCommand = true;
|
||||
this.category = bot.OWNER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event) {
|
||||
event.reply(event.getClient().getWarning()+" Shutting down...");
|
||||
bot.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2017 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.commands.owner;
|
||||
|
||||
import com.jagrosh.jdautilities.command.CommandEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.commands.OwnerCommand;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class ShutdownCmd extends OwnerCommand
|
||||
{
|
||||
private final Bot bot;
|
||||
|
||||
public ShutdownCmd(Bot bot)
|
||||
{
|
||||
this.bot = bot;
|
||||
this.name = "shutdown";
|
||||
this.help = "safely shuts down";
|
||||
this.guildOnly = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(CommandEvent event)
|
||||
{
|
||||
event.replyWarning("Shutting down...");
|
||||
bot.shutdown();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.entities;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (john.a.grosh@gmail.com)
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
*/
|
||||
public class Pair<K,V>
|
||||
{
|
||||
private final K key;
|
||||
private final V value;
|
||||
|
||||
public Pair(K key, V value)
|
||||
{
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public K getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
public V getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2018 John Grosh (jagrosh)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.entities;
|
||||
|
||||
import java.util.Scanner;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (john.a.grosh@gmail.com)
|
||||
*/
|
||||
public class Prompt
|
||||
{
|
||||
private final String title;
|
||||
private final String noguiMessage;
|
||||
|
||||
private boolean nogui;
|
||||
private Scanner scanner;
|
||||
|
||||
public Prompt(String title)
|
||||
{
|
||||
this(title, null);
|
||||
}
|
||||
|
||||
public Prompt(String title, String noguiMessage)
|
||||
{
|
||||
this(title, noguiMessage, "true".equalsIgnoreCase(System.getProperty("nogui")));
|
||||
}
|
||||
|
||||
public Prompt(String title, String noguiMessage, boolean nogui)
|
||||
{
|
||||
this.title = title;
|
||||
this.noguiMessage = noguiMessage == null ? "Switching to nogui mode. You can manually start in nogui mode by including the -Dnogui=true flag." : noguiMessage;
|
||||
this.nogui = nogui;
|
||||
}
|
||||
|
||||
public boolean isNoGUI()
|
||||
{
|
||||
return nogui;
|
||||
}
|
||||
|
||||
public void alert(Level level, String context, String message)
|
||||
{
|
||||
if(nogui)
|
||||
{
|
||||
Logger log = LoggerFactory.getLogger(context);
|
||||
switch(level)
|
||||
{
|
||||
case INFO:
|
||||
log.info(message);
|
||||
break;
|
||||
case WARNING:
|
||||
log.warn(message);
|
||||
break;
|
||||
case ERROR:
|
||||
log.error(message);
|
||||
break;
|
||||
default:
|
||||
log.info(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
int option = 0;
|
||||
switch(level)
|
||||
{
|
||||
case INFO:
|
||||
option = JOptionPane.INFORMATION_MESSAGE;
|
||||
break;
|
||||
case WARNING:
|
||||
option = JOptionPane.WARNING_MESSAGE;
|
||||
break;
|
||||
case ERROR:
|
||||
option = JOptionPane.ERROR_MESSAGE;
|
||||
break;
|
||||
default:
|
||||
option = JOptionPane.PLAIN_MESSAGE;
|
||||
break;
|
||||
}
|
||||
JOptionPane.showMessageDialog(null, "<html><body><p style='width: 400px;'>"+message, title, option);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
nogui = true;
|
||||
alert(Level.WARNING, context, noguiMessage);
|
||||
alert(level, context, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String prompt(String content)
|
||||
{
|
||||
if(nogui)
|
||||
{
|
||||
if(scanner==null)
|
||||
scanner = new Scanner(System.in);
|
||||
try
|
||||
{
|
||||
System.out.println(content);
|
||||
if(scanner.hasNextLine())
|
||||
return scanner.nextLine();
|
||||
return null;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
alert(Level.ERROR, title, "Unable to read input from command line.");
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
return JOptionPane.showInputDialog(null, content, title, JOptionPane.QUESTION_MESSAGE);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
nogui = true;
|
||||
alert(Level.WARNING, title, noguiMessage);
|
||||
return prompt(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static enum Level
|
||||
{
|
||||
INFO, WARNING, ERROR;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +1,73 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.gui;
|
||||
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.WindowConstants;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class GUI extends JFrame {
|
||||
|
||||
private final ConsolePanel console;
|
||||
private final GuildsPanel guilds;
|
||||
private final Bot bot;
|
||||
|
||||
public GUI(Bot bot) {
|
||||
super();
|
||||
this.bot = bot;
|
||||
console = new ConsolePanel();
|
||||
guilds = new GuildsPanel(bot);
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
setTitle("JMusicBot");
|
||||
JTabbedPane tabs = new JTabbedPane();
|
||||
//tabs.add("Guilds", guilds);
|
||||
tabs.add("Console", console);
|
||||
getContentPane().add(tabs);
|
||||
pack();
|
||||
setLocationRelativeTo(null);
|
||||
setVisible(true);
|
||||
addWindowListener(new WindowListener() {
|
||||
@Override public void windowOpened(WindowEvent e) {}
|
||||
@Override public void windowClosing(WindowEvent e) {bot.shutdown();}
|
||||
@Override public void windowClosed(WindowEvent e) {}
|
||||
@Override public void windowIconified(WindowEvent e) {}
|
||||
@Override public void windowDeiconified(WindowEvent e) {}
|
||||
@Override public void windowActivated(WindowEvent e) {}
|
||||
@Override public void windowDeactivated(WindowEvent e) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.gui;
|
||||
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.WindowConstants;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class GUI extends JFrame
|
||||
{
|
||||
private final ConsolePanel console;
|
||||
private final Bot bot;
|
||||
|
||||
public GUI(Bot bot)
|
||||
{
|
||||
super();
|
||||
this.bot = bot;
|
||||
console = new ConsolePanel();
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
setTitle("JMusicBot");
|
||||
JTabbedPane tabs = new JTabbedPane();
|
||||
tabs.add("Console", console);
|
||||
getContentPane().add(tabs);
|
||||
pack();
|
||||
setLocationRelativeTo(null);
|
||||
setVisible(true);
|
||||
addWindowListener(new WindowListener()
|
||||
{
|
||||
@Override public void windowOpened(WindowEvent e) { /* unused */ }
|
||||
@Override public void windowClosing(WindowEvent e)
|
||||
{
|
||||
try
|
||||
{
|
||||
bot.shutdown();
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
@Override public void windowClosed(WindowEvent e) { /* unused */ }
|
||||
@Override public void windowIconified(WindowEvent e) { /* unused */ }
|
||||
@Override public void windowDeiconified(WindowEvent e) { /* unused */ }
|
||||
@Override public void windowActivated(WindowEvent e) { /* unused */ }
|
||||
@Override public void windowDeactivated(WindowEvent e) { /* unused */ }
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.gui;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.util.List;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.jagrosh.jmusicbot.utils.FormatUtil;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class GuildsPanel extends JPanel {
|
||||
|
||||
private final Bot bot;
|
||||
private final JList guildList;
|
||||
private final JTextArea guildQueue;
|
||||
private int index = -1;
|
||||
|
||||
public GuildsPanel(Bot bot)
|
||||
{
|
||||
super();
|
||||
super.setLayout(new GridBagLayout());
|
||||
this.bot = bot;
|
||||
|
||||
guildList = new JList();
|
||||
guildQueue = new JTextArea();
|
||||
guildList.setModel(new DefaultListModel());
|
||||
guildList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
guildList.setFixedCellHeight(20);
|
||||
guildList.setPreferredSize(new Dimension(100,300));
|
||||
guildQueue.setPreferredSize(new Dimension(300,300));
|
||||
guildQueue.setEditable(false);
|
||||
JScrollPane pane = new JScrollPane();
|
||||
JScrollPane pane2 = new JScrollPane();
|
||||
pane.setViewportView(guildList);
|
||||
pane2.setViewportView(guildQueue);
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
c.fill = GridBagConstraints.BOTH;
|
||||
c.anchor = GridBagConstraints.LINE_START;
|
||||
c.gridx = 0;
|
||||
c.gridwidth = 1;
|
||||
super.add(pane, c);
|
||||
c.gridx = 1;
|
||||
c.gridwidth = 3;
|
||||
super.add(pane2, c);
|
||||
//bot.registerPanel(this);
|
||||
guildList.addListSelectionListener((ListSelectionEvent e) -> {
|
||||
index = guildList.getSelectedIndex();
|
||||
//bot.updatePanel();
|
||||
});
|
||||
}
|
||||
|
||||
public void updateList(List<Guild> guilds)
|
||||
{
|
||||
String[] strs = new String[guilds.size()];
|
||||
for(int i=0; i<guilds.size(); i++)
|
||||
strs[i] = guilds.get(i).getName();
|
||||
guildList.setListData(strs);
|
||||
}
|
||||
|
||||
public int getIndex()
|
||||
{
|
||||
return guildList.getSelectedIndex();
|
||||
}
|
||||
|
||||
/*public void updatePanel(AudioHandler handler) {
|
||||
StringBuilder builder = new StringBuilder("Now Playing: ");
|
||||
if(handler==null || handler.getCurrentTrack()==null)
|
||||
{
|
||||
builder.append("nothing");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.append(handler.getCurrentTrack().getTrack().getInfo().title)
|
||||
.append(" [")
|
||||
.append(FormatUtil.formatTime(handler.getCurrentTrack().getTrack().getDuration()))
|
||||
.append("]\n");
|
||||
for(int i=0; i<handler.getQueue().size(); i++)
|
||||
builder.append("\n").append(i+1).append(". ").append(handler.getQueue().get(i).getTrack().getInfo().title);
|
||||
}
|
||||
guildQueue.setText(builder.toString());
|
||||
guildQueue.updateUI();
|
||||
}*/
|
||||
|
||||
}
|
||||
@@ -1,147 +1,157 @@
|
||||
/*
|
||||
* Copyright 2017 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.gui;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import javax.swing.*;
|
||||
/**
|
||||
*
|
||||
* @author Lawrence Dol
|
||||
*/
|
||||
public class TextAreaOutputStream extends OutputStream {
|
||||
|
||||
// *************************************************************************************************
|
||||
// INSTANCE MEMBERS
|
||||
// *************************************************************************************************
|
||||
|
||||
private byte[] oneByte; // array for write(int val);
|
||||
private Appender appender; // most recent action
|
||||
|
||||
public TextAreaOutputStream(JTextArea txtara) {
|
||||
this(txtara,1000);
|
||||
}
|
||||
|
||||
public TextAreaOutputStream(JTextArea txtara, int maxlin) {
|
||||
if(maxlin<1) { throw new IllegalArgumentException("TextAreaOutputStream maximum lines must be positive (value="+maxlin+")"); }
|
||||
oneByte=new byte[1];
|
||||
appender=new Appender(txtara,maxlin);
|
||||
}
|
||||
|
||||
/** Clear the current console text area. */
|
||||
public synchronized void clear() {
|
||||
if(appender!=null) { appender.clear(); }
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
appender=null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void flush() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void write(int val) {
|
||||
oneByte[0]=(byte)val;
|
||||
write(oneByte,0,1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void write(byte[] ba) {
|
||||
write(ba,0,ba.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void write(byte[] ba,int str,int len) {
|
||||
if(appender!=null) { appender.append(bytesToString(ba,str,len)); }
|
||||
}
|
||||
|
||||
//@edu.umd.cs.findbugs.annotations.SuppressWarnings("DM_DEFAULT_ENCODING")
|
||||
static private String bytesToString(byte[] ba, int str, int len) {
|
||||
try { return new String(ba,str,len,"UTF-8"); } catch(UnsupportedEncodingException thr) { return new String(ba,str,len); } // all JVMs are required to support UTF-8
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
// STATIC MEMBERS
|
||||
// *************************************************************************************************
|
||||
|
||||
static class Appender
|
||||
implements Runnable
|
||||
{
|
||||
private final JTextArea textArea;
|
||||
private final int maxLines; // maximum lines allowed in text area
|
||||
private final LinkedList<Integer> lengths; // length of lines within text area
|
||||
private final List<String> values; // values waiting to be appended
|
||||
|
||||
private int curLength; // length of current line
|
||||
private boolean clear;
|
||||
private boolean queue;
|
||||
|
||||
Appender(JTextArea txtara, int maxlin) {
|
||||
textArea =txtara;
|
||||
maxLines =maxlin;
|
||||
lengths =new LinkedList<>();
|
||||
values =new ArrayList<>();
|
||||
|
||||
curLength=0;
|
||||
clear =false;
|
||||
queue =true;
|
||||
}
|
||||
|
||||
synchronized void append(String val) {
|
||||
values.add(val);
|
||||
if(queue) { queue=false; EventQueue.invokeLater(this); }
|
||||
}
|
||||
|
||||
synchronized void clear() {
|
||||
clear=true;
|
||||
curLength=0;
|
||||
lengths.clear();
|
||||
values.clear();
|
||||
if(queue) { queue=false; EventQueue.invokeLater(this); }
|
||||
}
|
||||
|
||||
// MUST BE THE ONLY METHOD THAT TOUCHES textArea!
|
||||
@Override
|
||||
public synchronized void run() {
|
||||
if(clear) { textArea.setText(""); }
|
||||
values.stream().map((val) -> {
|
||||
curLength+=val.length();
|
||||
return val;
|
||||
}).map((val) -> {
|
||||
if(val.endsWith(EOL1) || val.endsWith(EOL2)) {
|
||||
if(lengths.size()>=maxLines) { textArea.replaceRange("",0,lengths.removeFirst()); }
|
||||
lengths.addLast(curLength);
|
||||
curLength=0;
|
||||
}
|
||||
return val;
|
||||
}).forEach((val) -> {
|
||||
textArea.append(val);
|
||||
});
|
||||
values.clear();
|
||||
clear =false;
|
||||
queue =true;
|
||||
}
|
||||
|
||||
static private final String EOL1="\n";
|
||||
static private final String EOL2=System.getProperty("line.separator",EOL1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright 2017 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.gui;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import javax.swing.*;
|
||||
/**
|
||||
*
|
||||
* @author Lawrence Dol
|
||||
*/
|
||||
public class TextAreaOutputStream extends OutputStream {
|
||||
|
||||
// *************************************************************************************************
|
||||
// INSTANCE MEMBERS
|
||||
// *************************************************************************************************
|
||||
|
||||
private byte[] oneByte; // array for write(int val);
|
||||
private Appender appender; // most recent action
|
||||
|
||||
public TextAreaOutputStream(JTextArea txtara) {
|
||||
this(txtara,1000);
|
||||
}
|
||||
|
||||
public TextAreaOutputStream(JTextArea txtara, int maxlin) {
|
||||
if(maxlin<1) { throw new IllegalArgumentException("TextAreaOutputStream maximum lines must be positive (value="+maxlin+")"); }
|
||||
oneByte=new byte[1];
|
||||
appender=new Appender(txtara,maxlin);
|
||||
}
|
||||
|
||||
/** Clear the current console text area. */
|
||||
public synchronized void clear() {
|
||||
if(appender!=null) { appender.clear(); }
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
appender=null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void flush() {
|
||||
/* empty */
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void write(int val) {
|
||||
oneByte[0]=(byte)val;
|
||||
write(oneByte,0,1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void write(byte[] ba) {
|
||||
write(ba,0,ba.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void write(byte[] ba,int str,int len) {
|
||||
if(appender!=null) { appender.append(bytesToString(ba,str,len)); }
|
||||
}
|
||||
|
||||
//@edu.umd.cs.findbugs.annotations.SuppressWarnings("DM_DEFAULT_ENCODING")
|
||||
static private String bytesToString(byte[] ba, int str, int len) {
|
||||
try {
|
||||
return new String(ba,str,len,"UTF-8");
|
||||
} catch(UnsupportedEncodingException thr) {
|
||||
return new String(ba,str,len);
|
||||
} // all JVMs are required to support UTF-8
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
// STATIC MEMBERS
|
||||
// *************************************************************************************************
|
||||
|
||||
static class Appender
|
||||
implements Runnable
|
||||
{
|
||||
static private final String EOL1="\n";
|
||||
static private final String EOL2=System.getProperty("line.separator",EOL1);
|
||||
|
||||
private final JTextArea textArea;
|
||||
private final int maxLines; // maximum lines allowed in text area
|
||||
private final LinkedList<Integer> lengths; // length of lines within text area
|
||||
private final List<String> values; // values waiting to be appended
|
||||
|
||||
private int curLength; // length of current line
|
||||
private boolean clear;
|
||||
private boolean queue;
|
||||
|
||||
Appender(JTextArea txtara, int maxlin) {
|
||||
textArea =txtara;
|
||||
maxLines =maxlin;
|
||||
lengths =new LinkedList<>();
|
||||
values =new ArrayList<>();
|
||||
|
||||
curLength=0;
|
||||
clear =false;
|
||||
queue =true;
|
||||
}
|
||||
|
||||
private synchronized void append(String val) {
|
||||
values.add(val);
|
||||
if(queue) {
|
||||
queue=false;
|
||||
EventQueue.invokeLater(this);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void clear() {
|
||||
clear=true;
|
||||
curLength=0;
|
||||
lengths.clear();
|
||||
values.clear();
|
||||
if(queue) {
|
||||
queue=false;
|
||||
EventQueue.invokeLater(this);
|
||||
}
|
||||
}
|
||||
|
||||
// MUST BE THE ONLY METHOD THAT TOUCHES textArea!
|
||||
@Override
|
||||
public synchronized void run() {
|
||||
if(clear) { textArea.setText(""); }
|
||||
values.stream().map((val) -> {
|
||||
curLength+=val.length();
|
||||
return val;
|
||||
}).map((val) -> {
|
||||
if(val.endsWith(EOL1) || val.endsWith(EOL2)) {
|
||||
if(lengths.size()>=maxLines) { textArea.replaceRange("",0,lengths.removeFirst()); }
|
||||
lengths.addLast(curLength);
|
||||
curLength=0;
|
||||
}
|
||||
return val;
|
||||
}).forEach((val) -> {
|
||||
textArea.append(val);
|
||||
});
|
||||
values.clear();
|
||||
clear =false;
|
||||
queue =true;
|
||||
}
|
||||
}
|
||||
} /* END PUBLIC CLASS */
|
||||
@@ -1,274 +0,0 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.playlist;
|
||||
|
||||
import com.jagrosh.jmusicbot.Bot;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (john.a.grosh@gmail.com)
|
||||
*/
|
||||
public class Playlist {
|
||||
|
||||
private final String name;
|
||||
private final List<String> items;
|
||||
private List<AudioTrack> tracks;
|
||||
private List<PlaylistLoadError> errors;
|
||||
private final boolean shuffle;
|
||||
|
||||
private Playlist(String name, List<String> items, boolean shuffle)
|
||||
{
|
||||
this.name = name;
|
||||
this.items = items;
|
||||
this.shuffle = shuffle;
|
||||
}
|
||||
|
||||
public void loadTracks(AudioPlayerManager manager, Consumer<AudioTrack> consumer, Runnable callback)
|
||||
{
|
||||
if(tracks==null)
|
||||
{
|
||||
tracks = new LinkedList<>();
|
||||
errors = new LinkedList<>();
|
||||
for(int i=0; i<items.size(); i++)
|
||||
{
|
||||
boolean last = i+1==items.size();
|
||||
int index = i;
|
||||
manager.loadItemOrdered(name, items.get(i), new AudioLoadResultHandler() {
|
||||
@Override
|
||||
public void trackLoaded(AudioTrack at) {
|
||||
if(AudioHandler.isTooLong(at))
|
||||
errors.add(new PlaylistLoadError(index, items.get(index), "This track is longer than the allowed maximum"));
|
||||
else
|
||||
{
|
||||
tracks.add(at);
|
||||
consumer.accept(at);
|
||||
}
|
||||
if(last)
|
||||
{
|
||||
if(callback!=null)
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void playlistLoaded(AudioPlaylist ap) {
|
||||
if(ap.isSearchResult())
|
||||
{
|
||||
if(AudioHandler.isTooLong(ap.getTracks().get(0)))
|
||||
errors.add(new PlaylistLoadError(index, items.get(index), "This track is longer than the allowed maximum"));
|
||||
else
|
||||
{
|
||||
tracks.add(ap.getTracks().get(0));
|
||||
consumer.accept(ap.getTracks().get(0));
|
||||
}
|
||||
}
|
||||
else if(ap.getSelectedTrack()!=null)
|
||||
{
|
||||
if(AudioHandler.isTooLong(ap.getSelectedTrack()))
|
||||
errors.add(new PlaylistLoadError(index, items.get(index), "This track is longer than the allowed maximum"));
|
||||
else
|
||||
{
|
||||
tracks.add(ap.getSelectedTrack());
|
||||
consumer.accept(ap.getSelectedTrack());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
List<AudioTrack> loaded = new ArrayList<>(ap.getTracks());
|
||||
if(shuffle)
|
||||
for(int first =0; first<loaded.size(); first++)
|
||||
{
|
||||
int second = (int)(Math.random()*loaded.size());
|
||||
AudioTrack tmp = loaded.get(first);
|
||||
loaded.set(first, loaded.get(second));
|
||||
loaded.set(second, tmp);
|
||||
}
|
||||
loaded.removeIf(track -> AudioHandler.isTooLong(track));
|
||||
tracks.addAll(loaded);
|
||||
loaded.forEach(at -> consumer.accept(at));
|
||||
}
|
||||
if(last)
|
||||
{
|
||||
if(callback!=null)
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noMatches() {
|
||||
errors.add(new PlaylistLoadError(index, items.get(index), "No matches found."));
|
||||
if(last)
|
||||
{
|
||||
if(callback!=null)
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFailed(FriendlyException fe) {
|
||||
errors.add(new PlaylistLoadError(index, items.get(index), "Failed to load track: "+fe.getLocalizedMessage()));
|
||||
if(last)
|
||||
{
|
||||
if(callback!=null)
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<String> getItems()
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
public List<AudioTrack> getTracks()
|
||||
{
|
||||
return tracks;
|
||||
}
|
||||
|
||||
public void shuffleTracks()
|
||||
{
|
||||
if(tracks!=null)
|
||||
{
|
||||
for(int first =0; first<tracks.size(); first++)
|
||||
{
|
||||
int second = (int)(Math.random()*tracks.size());
|
||||
AudioTrack tmp = tracks.get(first);
|
||||
tracks.set(first, tracks.get(second));
|
||||
tracks.set(second, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<PlaylistLoadError> getErrors()
|
||||
{
|
||||
return errors;
|
||||
}
|
||||
|
||||
public static void createFolder()
|
||||
{
|
||||
try
|
||||
{
|
||||
Files.createDirectory(Paths.get("Playlists"));
|
||||
} catch (IOException ex)
|
||||
{}
|
||||
}
|
||||
|
||||
public static boolean folderExists()
|
||||
{
|
||||
return Files.exists(Paths.get("Playlists"));
|
||||
}
|
||||
|
||||
public static List<String> getPlaylists()
|
||||
{
|
||||
if(folderExists())
|
||||
{
|
||||
File folder = new File("Playlists");
|
||||
return Arrays.asList(folder.listFiles((pathname) -> pathname.getName().endsWith(".txt")))
|
||||
.stream().map(f -> f.getName().substring(0,f.getName().length()-4)).collect(Collectors.toList());
|
||||
}
|
||||
else
|
||||
{
|
||||
createFolder();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Playlist loadPlaylist(String name)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(folderExists())
|
||||
{
|
||||
boolean[] shuffle = {false};
|
||||
List<String> list = new ArrayList<>();
|
||||
Files.readAllLines(Paths.get("Playlists"+File.separator+name+".txt")).forEach(str -> {
|
||||
String s = str.trim();
|
||||
if(s.isEmpty())
|
||||
return;
|
||||
if(s.startsWith("#") || s.startsWith("//"))
|
||||
{
|
||||
s = s.replaceAll("\\s+", "");
|
||||
if(s.equalsIgnoreCase("#shuffle") || s.equalsIgnoreCase("//shuffle"))
|
||||
shuffle[0]=true;
|
||||
}
|
||||
else
|
||||
list.add(s);
|
||||
});
|
||||
if(shuffle[0])
|
||||
{
|
||||
for(int first =0; first<list.size(); first++)
|
||||
{
|
||||
int second = (int)(Math.random()*list.size());
|
||||
String tmp = list.get(first);
|
||||
list.set(first, list.get(second));
|
||||
list.set(second, tmp);
|
||||
}
|
||||
}
|
||||
return new Playlist(name, list, shuffle[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
createFolder();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class PlaylistLoadError {
|
||||
private final int number;
|
||||
private final String item;
|
||||
private final String reason;
|
||||
|
||||
private PlaylistLoadError(int number, String item, String reason)
|
||||
{
|
||||
this.number = number;
|
||||
this.item = item;
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public int getIndex()
|
||||
{
|
||||
return number;
|
||||
}
|
||||
|
||||
public String getItem()
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
public String getReason()
|
||||
{
|
||||
return reason;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
* Copyright 2018 John Grosh (jagrosh).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.playlist;
|
||||
|
||||
import com.jagrosh.jmusicbot.BotConfig;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (john.a.grosh@gmail.com)
|
||||
*/
|
||||
public class PlaylistLoader
|
||||
{
|
||||
private final BotConfig config;
|
||||
|
||||
public PlaylistLoader(BotConfig config)
|
||||
{
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public List<String> getPlaylistNames()
|
||||
{
|
||||
if(folderExists())
|
||||
{
|
||||
File folder = new File(config.getPlaylistsFolder());
|
||||
return Arrays.asList(folder.listFiles((pathname) -> pathname.getName().endsWith(".txt")))
|
||||
.stream().map(f -> f.getName().substring(0,f.getName().length()-4)).collect(Collectors.toList());
|
||||
}
|
||||
else
|
||||
{
|
||||
createFolder();
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
public void createFolder()
|
||||
{
|
||||
try
|
||||
{
|
||||
Files.createDirectory(Paths.get(config.getPlaylistsFolder()));
|
||||
}
|
||||
catch (IOException ignore) {}
|
||||
}
|
||||
|
||||
public boolean folderExists()
|
||||
{
|
||||
return Files.exists(Paths.get(config.getPlaylistsFolder()));
|
||||
}
|
||||
|
||||
public void createPlaylist(String name) throws IOException
|
||||
{
|
||||
Files.createFile(Paths.get(config.getPlaylistsFolder()+File.separator+name+".txt"));
|
||||
}
|
||||
|
||||
public void deletePlaylist(String name) throws IOException
|
||||
{
|
||||
Files.delete(Paths.get(config.getPlaylistsFolder()+File.separator+name+".txt"));
|
||||
}
|
||||
|
||||
public void writePlaylist(String name, String text) throws IOException
|
||||
{
|
||||
Files.write(Paths.get(config.getPlaylistsFolder()+File.separator+name+".txt"), text.trim().getBytes());
|
||||
}
|
||||
|
||||
public Playlist getPlaylist(String name)
|
||||
{
|
||||
if(!getPlaylistNames().contains(name))
|
||||
return null;
|
||||
try
|
||||
{
|
||||
if(folderExists())
|
||||
{
|
||||
boolean[] shuffle = {false};
|
||||
List<String> list = new ArrayList<>();
|
||||
Files.readAllLines(Paths.get(config.getPlaylistsFolder()+File.separator+name+".txt")).forEach(str ->
|
||||
{
|
||||
String s = str.trim();
|
||||
if(s.isEmpty())
|
||||
return;
|
||||
if(s.startsWith("#") || s.startsWith("//"))
|
||||
{
|
||||
s = s.replaceAll("\\s+", "");
|
||||
if(s.equalsIgnoreCase("#shuffle") || s.equalsIgnoreCase("//shuffle"))
|
||||
shuffle[0]=true;
|
||||
}
|
||||
else
|
||||
list.add(s);
|
||||
});
|
||||
if(shuffle[0])
|
||||
shuffle(list);
|
||||
return new Playlist(name, list, shuffle[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
createFolder();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static <T> void shuffle(List<T> list)
|
||||
{
|
||||
for(int first =0; first<list.size(); first++)
|
||||
{
|
||||
int second = (int)(Math.random()*list.size());
|
||||
T tmp = list.get(first);
|
||||
list.set(first, list.get(second));
|
||||
list.set(second, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class Playlist
|
||||
{
|
||||
private final String name;
|
||||
private final List<String> items;
|
||||
private final boolean shuffle;
|
||||
private final List<AudioTrack> tracks = new LinkedList<>();
|
||||
private final List<PlaylistLoadError> errors = new LinkedList<>();
|
||||
private boolean loaded = false;
|
||||
|
||||
private Playlist(String name, List<String> items, boolean shuffle)
|
||||
{
|
||||
this.name = name;
|
||||
this.items = items;
|
||||
this.shuffle = shuffle;
|
||||
}
|
||||
|
||||
public void loadTracks(AudioPlayerManager manager, Consumer<AudioTrack> consumer, Runnable callback)
|
||||
{
|
||||
if(!loaded)
|
||||
{
|
||||
loaded = true;
|
||||
for(int i=0; i<items.size(); i++)
|
||||
{
|
||||
boolean last = i+1==items.size();
|
||||
int index = i;
|
||||
manager.loadItemOrdered(name, items.get(i), new AudioLoadResultHandler()
|
||||
{
|
||||
@Override
|
||||
public void trackLoaded(AudioTrack at)
|
||||
{
|
||||
if(config.isTooLong(at))
|
||||
errors.add(new PlaylistLoadError(index, items.get(index), "This track is longer than the allowed maximum"));
|
||||
else
|
||||
{
|
||||
at.setUserData(0L);
|
||||
tracks.add(at);
|
||||
consumer.accept(at);
|
||||
}
|
||||
if(last && callback!=null)
|
||||
callback.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playlistLoaded(AudioPlaylist ap)
|
||||
{
|
||||
if(ap.isSearchResult())
|
||||
{
|
||||
if(config.isTooLong(ap.getTracks().get(0)))
|
||||
errors.add(new PlaylistLoadError(index, items.get(index), "This track is longer than the allowed maximum"));
|
||||
else
|
||||
{
|
||||
ap.getTracks().get(0).setUserData(0L);
|
||||
tracks.add(ap.getTracks().get(0));
|
||||
consumer.accept(ap.getTracks().get(0));
|
||||
}
|
||||
}
|
||||
else if(ap.getSelectedTrack()!=null)
|
||||
{
|
||||
if(config.isTooLong(ap.getSelectedTrack()))
|
||||
errors.add(new PlaylistLoadError(index, items.get(index), "This track is longer than the allowed maximum"));
|
||||
else
|
||||
{
|
||||
ap.getSelectedTrack().setUserData(0L);
|
||||
tracks.add(ap.getSelectedTrack());
|
||||
consumer.accept(ap.getSelectedTrack());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
List<AudioTrack> loaded = new ArrayList<>(ap.getTracks());
|
||||
if(shuffle)
|
||||
for(int first =0; first<loaded.size(); first++)
|
||||
{
|
||||
int second = (int)(Math.random()*loaded.size());
|
||||
AudioTrack tmp = loaded.get(first);
|
||||
loaded.set(first, loaded.get(second));
|
||||
loaded.set(second, tmp);
|
||||
}
|
||||
loaded.removeIf(track -> config.isTooLong(track));
|
||||
loaded.forEach(at -> at.setUserData(0L));
|
||||
tracks.addAll(loaded);
|
||||
loaded.forEach(at -> consumer.accept(at));
|
||||
}
|
||||
if(last && callback!=null)
|
||||
callback.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noMatches()
|
||||
{
|
||||
errors.add(new PlaylistLoadError(index, items.get(index), "No matches found."));
|
||||
if(last && callback!=null)
|
||||
callback.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFailed(FriendlyException fe)
|
||||
{
|
||||
errors.add(new PlaylistLoadError(index, items.get(index), "Failed to load track: "+fe.getLocalizedMessage()));
|
||||
if(last && callback!=null)
|
||||
callback.run();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if(shuffle)
|
||||
shuffleTracks();
|
||||
}
|
||||
|
||||
public void shuffleTracks()
|
||||
{
|
||||
if(tracks!=null)
|
||||
shuffle(tracks);
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<String> getItems()
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
public List<AudioTrack> getTracks()
|
||||
{
|
||||
return tracks;
|
||||
}
|
||||
|
||||
public List<PlaylistLoadError> getErrors()
|
||||
{
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
public class PlaylistLoadError
|
||||
{
|
||||
private final int number;
|
||||
private final String item;
|
||||
private final String reason;
|
||||
|
||||
private PlaylistLoadError(int number, String item, String reason)
|
||||
{
|
||||
this.number = number;
|
||||
this.item = item;
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public int getIndex()
|
||||
{
|
||||
return number;
|
||||
}
|
||||
|
||||
public String getItem()
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
public String getReason()
|
||||
{
|
||||
return reason;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,14 @@ public class FairQueue<T extends Queueable> {
|
||||
return lastIndex;
|
||||
}
|
||||
|
||||
public void addAt(int index, T item)
|
||||
{
|
||||
if(index >= list.size())
|
||||
list.add(item);
|
||||
else
|
||||
list.add(index, item);
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return list.size();
|
||||
|
||||
+37
-21
@@ -13,24 +13,31 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot;
|
||||
package com.jagrosh.jmusicbot.settings;
|
||||
|
||||
import com.jagrosh.jdautilities.command.GuildSettingsProvider;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
import net.dv8tion.jda.core.entities.Role;
|
||||
import net.dv8tion.jda.core.entities.TextChannel;
|
||||
import net.dv8tion.jda.core.entities.VoiceChannel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class Settings {
|
||||
public final static Settings DEFAULT_SETTINGS = new Settings(0, 0, 0, 100, null, false);
|
||||
|
||||
private long textId;
|
||||
private long voiceId;
|
||||
private long roleId;
|
||||
public class Settings implements GuildSettingsProvider
|
||||
{
|
||||
private final SettingsManager manager;
|
||||
protected long textId;
|
||||
protected long voiceId;
|
||||
protected long roleId;
|
||||
private int volume;
|
||||
private String defaultPlaylist;
|
||||
private boolean repeatMode;
|
||||
|
||||
public Settings(String textId, String voiceId, String roleId, int volume, String defaultPlaylist, boolean repeatMode)
|
||||
public Settings(SettingsManager manager, String textId, String voiceId, String roleId, int volume, String defaultPlaylist, boolean repeatMode)
|
||||
{
|
||||
this.manager = manager;
|
||||
try
|
||||
{
|
||||
this.textId = Long.parseLong(textId);
|
||||
@@ -60,8 +67,9 @@ public class Settings {
|
||||
this.repeatMode = repeatMode;
|
||||
}
|
||||
|
||||
public Settings(long textId, long voiceId, long roleId, int volume, String defaultPlaylist, boolean repeatMode)
|
||||
public Settings(SettingsManager manager, long textId, long voiceId, long roleId, int volume, String defaultPlaylist, boolean repeatMode)
|
||||
{
|
||||
this.manager = manager;
|
||||
this.textId = textId;
|
||||
this.voiceId = voiceId;
|
||||
this.roleId = roleId;
|
||||
@@ -70,19 +78,20 @@ public class Settings {
|
||||
this.repeatMode = repeatMode;
|
||||
}
|
||||
|
||||
public long getTextId()
|
||||
// Getters
|
||||
public TextChannel getTextChannel(Guild guild)
|
||||
{
|
||||
return textId;
|
||||
return guild == null ? null : guild.getTextChannelById(textId);
|
||||
}
|
||||
|
||||
public long getVoiceId()
|
||||
public VoiceChannel getVoiceChannel(Guild guild)
|
||||
{
|
||||
return voiceId;
|
||||
return guild == null ? null : guild.getVoiceChannelById(voiceId);
|
||||
}
|
||||
|
||||
public long getRoleId()
|
||||
public Role getRole(Guild guild)
|
||||
{
|
||||
return roleId;
|
||||
return guild == null ? null : guild.getRoleById(roleId);
|
||||
}
|
||||
|
||||
public int getVolume()
|
||||
@@ -100,33 +109,40 @@ public class Settings {
|
||||
return repeatMode;
|
||||
}
|
||||
|
||||
public void setTextId(long id)
|
||||
// Setters
|
||||
public void setTextChannel(TextChannel tc)
|
||||
{
|
||||
this.textId = id;
|
||||
this.textId = tc == null ? 0 : tc.getIdLong();
|
||||
this.manager.writeSettings();
|
||||
}
|
||||
|
||||
public void setVoiceId(long id)
|
||||
public void setVoiceChannel(VoiceChannel vc)
|
||||
{
|
||||
this.voiceId = id;
|
||||
this.voiceId = vc == null ? 0 : vc.getIdLong();
|
||||
this.manager.writeSettings();
|
||||
}
|
||||
|
||||
public void setRoleId(long id)
|
||||
public void setDJRole(Role role)
|
||||
{
|
||||
this.roleId = id;
|
||||
this.roleId = role == null ? 0 : role.getIdLong();
|
||||
this.manager.writeSettings();
|
||||
}
|
||||
|
||||
public void setVolume(int volume)
|
||||
{
|
||||
this.volume = volume;
|
||||
this.manager.writeSettings();
|
||||
}
|
||||
|
||||
public void setDefaultPlaylist(String defaultPlaylist)
|
||||
{
|
||||
this.defaultPlaylist = defaultPlaylist;
|
||||
this.manager.writeSettings();
|
||||
}
|
||||
|
||||
public void setRepeatMode(boolean mode)
|
||||
{
|
||||
this.repeatMode = mode;
|
||||
this.manager.writeSettings();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.settings;
|
||||
|
||||
import com.jagrosh.jdautilities.command.GuildSettingsManager;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (john.a.grosh@gmail.com)
|
||||
*/
|
||||
public class SettingsManager implements GuildSettingsManager
|
||||
{
|
||||
private final HashMap<Long,Settings> settings;
|
||||
|
||||
public SettingsManager()
|
||||
{
|
||||
this.settings = new HashMap<>();
|
||||
try {
|
||||
JSONObject loadedSettings = new JSONObject(new String(Files.readAllBytes(Paths.get("serversettings.json"))));
|
||||
loadedSettings.keySet().forEach((id) -> {
|
||||
JSONObject o = loadedSettings.getJSONObject(id);
|
||||
settings.put(Long.parseLong(id), new Settings(this,
|
||||
o.has("text_channel_id") ? o.getString("text_channel_id") : null,
|
||||
o.has("voice_channel_id")? o.getString("voice_channel_id"): null,
|
||||
o.has("dj_role_id") ? o.getString("dj_role_id") : null,
|
||||
o.has("volume") ? o.getInt("volume") : 100,
|
||||
o.has("default_playlist")? o.getString("default_playlist"): null,
|
||||
o.has("repeat") ? o.getBoolean("repeat") : false));
|
||||
});
|
||||
} catch(IOException | JSONException e) {
|
||||
LoggerFactory.getLogger("Settings").warn("Failed to load server settings (this is normal if no settings have been set yet): "+e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets non-null settings for a Guild
|
||||
*
|
||||
* @param guild the guild to get settings for
|
||||
* @return the existing settings, or new settings for that guild
|
||||
*/
|
||||
@Override
|
||||
public Settings getSettings(Guild guild)
|
||||
{
|
||||
return getSettings(guild.getIdLong());
|
||||
}
|
||||
|
||||
public Settings getSettings(long guildId)
|
||||
{
|
||||
return settings.computeIfAbsent(guildId, id -> createDefaultSettings());
|
||||
}
|
||||
|
||||
private Settings createDefaultSettings()
|
||||
{
|
||||
return new Settings(this, 0, 0, 0, 100, null, false);
|
||||
}
|
||||
|
||||
protected void writeSettings()
|
||||
{
|
||||
JSONObject obj = new JSONObject();
|
||||
settings.keySet().stream().forEach(key -> {
|
||||
JSONObject o = new JSONObject();
|
||||
Settings s = settings.get(key);
|
||||
if(s.textId!=0)
|
||||
o.put("text_channel_id", Long.toString(s.textId));
|
||||
if(s.voiceId!=0)
|
||||
o.put("voice_channel_id", Long.toString(s.voiceId));
|
||||
if(s.roleId!=0)
|
||||
o.put("dj_role_id", Long.toString(s.roleId));
|
||||
if(s.getVolume()!=100)
|
||||
o.put("volume",s.getVolume());
|
||||
if(s.getDefaultPlaylist()!=null)
|
||||
o.put("default_playlist", s.getDefaultPlaylist());
|
||||
if(s.getRepeatMode())
|
||||
o.put("repeat", true);
|
||||
obj.put(Long.toString(key), o);
|
||||
});
|
||||
try {
|
||||
Files.write(Paths.get("serversettings.json"), obj.toString(4).getBytes());
|
||||
} catch(IOException ex){
|
||||
LoggerFactory.getLogger("Settings").warn("Failed to write to file: "+ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
import net.dv8tion.jda.core.entities.Role;
|
||||
import net.dv8tion.jda.core.entities.TextChannel;
|
||||
import net.dv8tion.jda.core.entities.VoiceChannel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class FinderUtil {
|
||||
|
||||
public final static String DISCORD_ID = "\\d{17,20}";
|
||||
|
||||
public static List<TextChannel> findTextChannel(String query, Guild guild)
|
||||
{
|
||||
String id;
|
||||
if(query.matches("<#\\d+>"))
|
||||
{
|
||||
id = query.replaceAll("<#(\\d+)>", "$1");
|
||||
TextChannel tc = guild.getJDA().getTextChannelById(id);
|
||||
if(tc!=null && tc.getGuild().equals(guild))
|
||||
return Collections.singletonList(tc);
|
||||
}
|
||||
else if(query.matches(DISCORD_ID))
|
||||
{
|
||||
id = query;
|
||||
TextChannel tc = guild.getJDA().getTextChannelById(id);
|
||||
if(tc!=null && tc.getGuild().equals(guild))
|
||||
return Collections.singletonList(tc);
|
||||
}
|
||||
ArrayList<TextChannel> exact = new ArrayList<>();
|
||||
ArrayList<TextChannel> wrongcase = new ArrayList<>();
|
||||
ArrayList<TextChannel> startswith = new ArrayList<>();
|
||||
ArrayList<TextChannel> contains = new ArrayList<>();
|
||||
String lowerquery = query.toLowerCase();
|
||||
guild.getTextChannels().stream().forEach((tc) -> {
|
||||
if(tc.getName().equals(lowerquery))
|
||||
exact.add(tc);
|
||||
else if (tc.getName().equalsIgnoreCase(lowerquery) && exact.isEmpty())
|
||||
wrongcase.add(tc);
|
||||
else if (tc.getName().toLowerCase().startsWith(lowerquery) && wrongcase.isEmpty())
|
||||
startswith.add(tc);
|
||||
else if (tc.getName().toLowerCase().contains(lowerquery) && startswith.isEmpty())
|
||||
contains.add(tc);
|
||||
});
|
||||
if(!exact.isEmpty())
|
||||
return exact;
|
||||
if(!wrongcase.isEmpty())
|
||||
return wrongcase;
|
||||
if(!startswith.isEmpty())
|
||||
return startswith;
|
||||
return contains;
|
||||
}
|
||||
|
||||
public static List<VoiceChannel> findVoiceChannel(String query, Guild guild)
|
||||
{
|
||||
String id;
|
||||
if(query.matches("<#\\d+>"))
|
||||
{
|
||||
id = query.replaceAll("<#(\\d+)>", "$1");
|
||||
VoiceChannel vc = guild.getJDA().getVoiceChannelById(id);
|
||||
if(vc!=null && vc.getGuild().equals(guild))
|
||||
return Collections.singletonList(vc);
|
||||
}
|
||||
else if(query.matches(DISCORD_ID))
|
||||
{
|
||||
id = query;
|
||||
VoiceChannel vc = guild.getJDA().getVoiceChannelById(id);
|
||||
if(vc!=null && vc.getGuild().equals(guild))
|
||||
return Collections.singletonList(vc);
|
||||
}
|
||||
ArrayList<VoiceChannel> exact = new ArrayList<>();
|
||||
ArrayList<VoiceChannel> wrongcase = new ArrayList<>();
|
||||
ArrayList<VoiceChannel> startswith = new ArrayList<>();
|
||||
ArrayList<VoiceChannel> contains = new ArrayList<>();
|
||||
String lowerquery = query.toLowerCase();
|
||||
guild.getVoiceChannels().stream().forEach((vc) -> {
|
||||
if(vc.getName().equals(lowerquery))
|
||||
exact.add(vc);
|
||||
else if (vc.getName().equalsIgnoreCase(lowerquery) && exact.isEmpty())
|
||||
wrongcase.add(vc);
|
||||
else if (vc.getName().toLowerCase().startsWith(lowerquery) && wrongcase.isEmpty())
|
||||
startswith.add(vc);
|
||||
else if (vc.getName().toLowerCase().contains(lowerquery) && startswith.isEmpty())
|
||||
contains.add(vc);
|
||||
});
|
||||
if(!exact.isEmpty())
|
||||
return exact;
|
||||
if(!wrongcase.isEmpty())
|
||||
return wrongcase;
|
||||
if(!startswith.isEmpty())
|
||||
return startswith;
|
||||
return contains;
|
||||
}
|
||||
|
||||
public static List<Role> findRole(String query, Guild guild)
|
||||
{
|
||||
String id;
|
||||
if(query.matches("<@&\\d+>"))
|
||||
{
|
||||
id = query.replaceAll("<@&(\\d+)>", "$1");
|
||||
Role r = guild.getRoleById(id);
|
||||
if(r!=null)
|
||||
return Collections.singletonList(r);
|
||||
}
|
||||
else if(query.matches(DISCORD_ID))
|
||||
{
|
||||
id = query;
|
||||
Role r = guild.getRoleById(id);
|
||||
if(r!=null)
|
||||
return Collections.singletonList(r);
|
||||
}
|
||||
ArrayList<Role> exact = new ArrayList<>();
|
||||
ArrayList<Role> wrongcase = new ArrayList<>();
|
||||
ArrayList<Role> startswith = new ArrayList<>();
|
||||
ArrayList<Role> contains = new ArrayList<>();
|
||||
String lowerQuery = query.toLowerCase();
|
||||
guild.getRoles().stream().forEach((role) -> {
|
||||
if(role.getName().equals(query))
|
||||
exact.add(role);
|
||||
else if (role.getName().equalsIgnoreCase(query) && exact.isEmpty())
|
||||
wrongcase.add(role);
|
||||
else if (role.getName().toLowerCase().startsWith(lowerQuery) && wrongcase.isEmpty())
|
||||
startswith.add(role);
|
||||
else if (role.getName().toLowerCase().contains(lowerQuery) && startswith.isEmpty())
|
||||
contains.add(role);
|
||||
});
|
||||
if(!exact.isEmpty())
|
||||
return exact;
|
||||
if(!wrongcase.isEmpty())
|
||||
return wrongcase;
|
||||
if(!startswith.isEmpty())
|
||||
return startswith;
|
||||
return contains;
|
||||
}
|
||||
}
|
||||
@@ -15,18 +15,9 @@
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.utils;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import java.util.List;
|
||||
import com.jagrosh.jmusicbot.audio.AudioHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack;
|
||||
import net.dv8tion.jda.core.EmbedBuilder;
|
||||
import net.dv8tion.jda.core.JDA;
|
||||
import net.dv8tion.jda.core.MessageBuilder;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
import net.dv8tion.jda.core.entities.Message;
|
||||
import net.dv8tion.jda.core.entities.Role;
|
||||
import net.dv8tion.jda.core.entities.TextChannel;
|
||||
import net.dv8tion.jda.core.entities.User;
|
||||
import net.dv8tion.jda.core.entities.VoiceChannel;
|
||||
|
||||
/**
|
||||
@@ -46,85 +37,13 @@ public class FormatUtil {
|
||||
seconds %= 60;
|
||||
return (hours>0 ? hours+":" : "") + (minutes<10 ? "0"+minutes : minutes) + ":" + (seconds<10 ? "0"+seconds : seconds);
|
||||
}
|
||||
|
||||
public static Message nowPlayingMessage(Guild guild, String successEmoji)
|
||||
{
|
||||
MessageBuilder mb = new MessageBuilder();
|
||||
mb.append(successEmoji+" **Now Playing...**");
|
||||
EmbedBuilder eb = new EmbedBuilder();
|
||||
AudioHandler ah = (AudioHandler)guild.getAudioManager().getSendingHandler();
|
||||
eb.setColor(guild.getSelfMember().getColor());
|
||||
if(ah==null || !ah.isMusicPlaying())
|
||||
{
|
||||
eb.setTitle("No music playing");
|
||||
eb.setDescription("\u23F9 "+FormatUtil.progressBar(-1)+" "+FormatUtil.volumeIcon(ah==null?100:ah.getPlayer().getVolume()));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ah.getRequester()!=0)
|
||||
{
|
||||
User u = guild.getJDA().getUserById(ah.getRequester());
|
||||
if(u==null)
|
||||
eb.setAuthor("Unknown (ID:"+ah.getRequester()+")", null, null);
|
||||
else
|
||||
eb.setAuthor(u.getName()+"#"+u.getDiscriminator(), null, u.getEffectiveAvatarUrl());
|
||||
}
|
||||
|
||||
try {
|
||||
eb.setTitle(ah.getPlayer().getPlayingTrack().getInfo().title, ah.getPlayer().getPlayingTrack().getInfo().uri);
|
||||
} catch(Exception e) {
|
||||
eb.setTitle(ah.getPlayer().getPlayingTrack().getInfo().title);
|
||||
}
|
||||
|
||||
if(!AudioHandler.USE_NP_REFRESH && ah.getPlayer().getPlayingTrack() instanceof YoutubeAudioTrack)
|
||||
eb.setThumbnail("https://img.youtube.com/vi/"+ah.getPlayer().getPlayingTrack().getIdentifier()+"/mqdefault.jpg");
|
||||
|
||||
eb.setDescription(FormatUtil.embedFormat(ah));
|
||||
}
|
||||
return mb.setEmbed(eb.build()).build();
|
||||
}
|
||||
|
||||
public static String topicFormat(AudioHandler handler, JDA jda)
|
||||
{
|
||||
if(handler==null)
|
||||
return "No music playing\n\u23F9 "+progressBar(-1)+" "+volumeIcon(100);
|
||||
else if (!handler.isMusicPlaying())
|
||||
return "No music playing\n\u23F9 "+progressBar(-1)+" "+volumeIcon(handler.getPlayer().getVolume());
|
||||
else
|
||||
{
|
||||
long userid = handler.getRequester();
|
||||
AudioTrack track = handler.getPlayer().getPlayingTrack();
|
||||
String title = track.getInfo().title;
|
||||
return "**"+title+"** ["+(userid==0 ? "autoplay" : "<@"+userid+">")+"]"
|
||||
+ "\n"+(handler.getPlayer().isPaused()?"\u23F8":"\u25B6")+" "
|
||||
+"["+formatTime(track.getDuration())+"] "
|
||||
+volumeIcon(handler.getPlayer().getVolume());
|
||||
}
|
||||
}
|
||||
|
||||
public static String embedFormat(AudioHandler handler)
|
||||
{
|
||||
if(handler==null)
|
||||
return "No music playing\n\u23F9 "+progressBar(-1)+" "+volumeIcon(100);
|
||||
else if (!handler.isMusicPlaying())
|
||||
return "No music playing\n\u23F9 "+progressBar(-1)+" "+volumeIcon(handler.getPlayer().getVolume());
|
||||
else
|
||||
{
|
||||
AudioTrack track = handler.getPlayer().getPlayingTrack();
|
||||
double progress = (double)track.getPosition()/track.getDuration();
|
||||
return (handler.getPlayer().isPaused()?"\u23F8":"\u25B6")
|
||||
+" "+progressBar(progress)
|
||||
+" `["+formatTime(track.getPosition()) + "/" + formatTime(track.getDuration()) +"]` "
|
||||
+volumeIcon(handler.getPlayer().getVolume());
|
||||
}
|
||||
}
|
||||
|
||||
public static String progressBar(double percent)
|
||||
{
|
||||
String str = "";
|
||||
for(int i=0; i<12; i++)
|
||||
if(i == (int)(percent*12))
|
||||
str+="\uD83D\uDD18";
|
||||
str+="\uD83D\uDD18"; // 🔘
|
||||
else
|
||||
str+="▬";
|
||||
return str;
|
||||
@@ -133,12 +52,12 @@ public class FormatUtil {
|
||||
public static String volumeIcon(int volume)
|
||||
{
|
||||
if(volume == 0)
|
||||
return "\uD83D\uDD07";
|
||||
return "\uD83D\uDD07"; // 🔇
|
||||
if(volume < 30)
|
||||
return "\uD83D\uDD08";
|
||||
return "\uD83D\uDD08"; // 🔈
|
||||
if(volume < 70)
|
||||
return "\uD83D\uDD09";
|
||||
return "\uD83D\uDD0A";
|
||||
return "\uD83D\uDD09"; // 🔉
|
||||
return "\uD83D\uDD0A"; // 🔊
|
||||
}
|
||||
|
||||
public static String listOfTChannels(List<TextChannel> list, String query)
|
||||
@@ -173,6 +92,6 @@ public class FormatUtil {
|
||||
|
||||
public static String filter(String input)
|
||||
{
|
||||
return input.replace("@everyone", "@\u0435veryone").replace("@here", "@h\u0435re").trim();
|
||||
return input.replace("@everyone", "@\u0435veryone").replace("@here", "@h\u0435re").trim(); // cyrillic letter e
|
||||
}
|
||||
}
|
||||
@@ -1,42 +1,143 @@
|
||||
/*
|
||||
* Copyright 2017 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class OtherUtil {
|
||||
|
||||
public static InputStream imageFromUrl(String url)
|
||||
{
|
||||
if(url==null)
|
||||
return null;
|
||||
try {
|
||||
URL u = new URL(url);
|
||||
URLConnection urlConnection = u.openConnection();
|
||||
urlConnection.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36");
|
||||
return urlConnection.getInputStream();
|
||||
} catch(IOException|IllegalArgumentException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot.utils;
|
||||
|
||||
import com.jagrosh.jmusicbot.JMusicBot;
|
||||
import com.jagrosh.jmusicbot.entities.Prompt;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import net.dv8tion.jda.core.OnlineStatus;
|
||||
import net.dv8tion.jda.core.entities.Game;
|
||||
import okhttp3.*;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONTokener;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh <john.a.grosh@gmail.com>
|
||||
*/
|
||||
public class OtherUtil
|
||||
{
|
||||
public final static String NEW_VERSION_AVAILABLE = "There is a new version of JMusicBot available!\n"
|
||||
+ "Current version: %s\n"
|
||||
+ "New Version: %s\n\n"
|
||||
+ "Please visit https://github.com/jagrosh/MusicBot/releases/latest to get the latest release.";
|
||||
|
||||
public static InputStream imageFromUrl(String url)
|
||||
{
|
||||
if(url==null)
|
||||
return null;
|
||||
try
|
||||
{
|
||||
URL u = new URL(url);
|
||||
URLConnection urlConnection = u.openConnection();
|
||||
urlConnection.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36");
|
||||
return urlConnection.getInputStream();
|
||||
}
|
||||
catch(IOException | IllegalArgumentException ignore) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Game parseGame(String game)
|
||||
{
|
||||
if(game==null || game.trim().isEmpty() || game.trim().equalsIgnoreCase("default"))
|
||||
return null;
|
||||
String lower = game.toLowerCase();
|
||||
if(lower.startsWith("playing"))
|
||||
return Game.playing(game.substring(7).trim());
|
||||
if(lower.startsWith("listening to"))
|
||||
return Game.listening(game.substring(12).trim());
|
||||
if(lower.startsWith("listening"))
|
||||
return Game.listening(game.substring(9).trim());
|
||||
if(lower.startsWith("watching"))
|
||||
return Game.watching(game.substring(8).trim());
|
||||
if(lower.startsWith("streaming"))
|
||||
{
|
||||
String[] parts = game.substring(9).trim().split("\\s+", 2);
|
||||
if(parts.length == 2)
|
||||
{
|
||||
return Game.streaming(parts[1], "https://twitch.tv/"+parts[0]);
|
||||
}
|
||||
}
|
||||
return Game.playing(game);
|
||||
}
|
||||
|
||||
public static OnlineStatus parseStatus(String status)
|
||||
{
|
||||
if(status==null || status.trim().isEmpty())
|
||||
return OnlineStatus.ONLINE;
|
||||
OnlineStatus st = OnlineStatus.fromKey(status);
|
||||
return st == null ? OnlineStatus.ONLINE : st;
|
||||
}
|
||||
|
||||
public static String checkVersion(Prompt prompt)
|
||||
{
|
||||
// Get current version number
|
||||
String version = getCurrentVersion();
|
||||
|
||||
// Check for new version
|
||||
String latestVersion = getLatestVersion();
|
||||
|
||||
if(latestVersion!=null && !latestVersion.equals(version))
|
||||
{
|
||||
prompt.alert(Prompt.Level.WARNING, "Version", String.format(NEW_VERSION_AVAILABLE, version, latestVersion));
|
||||
}
|
||||
|
||||
// Return the current version
|
||||
return version;
|
||||
}
|
||||
|
||||
public static String getCurrentVersion()
|
||||
{
|
||||
if(JMusicBot.class.getPackage()!=null && JMusicBot.class.getPackage().getImplementationVersion()!=null)
|
||||
return JMusicBot.class.getPackage().getImplementationVersion();
|
||||
else
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
public static String getLatestVersion()
|
||||
{
|
||||
try
|
||||
{
|
||||
Response response = new OkHttpClient.Builder().build()
|
||||
.newCall(new Request.Builder().get().url("https://api.github.com/repos/jagrosh/MusicBot/releases/latest").build())
|
||||
.execute();
|
||||
ResponseBody body = response.body();
|
||||
if(body != null)
|
||||
{
|
||||
try(Reader reader = body.charStream())
|
||||
{
|
||||
JSONObject obj = new JSONObject(new JSONTokener(reader));
|
||||
return obj.getString("tag_name");
|
||||
}
|
||||
finally
|
||||
{
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
catch(IOException | JSONException | NullPointerException ex)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/////////////////////////////////////////////////////////
|
||||
// Config for the JMusicBot //
|
||||
/////////////////////////////////////////////////////////
|
||||
// Any line starting with // is ignored //
|
||||
// You MUST set the token and owner //
|
||||
// All other items have defaults if you don't set them //
|
||||
// Open in Notepad++ for best results //
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// This sets the token for the bot to log in with
|
||||
// This MUST be a bot token (user tokens will not work)
|
||||
// If you don't know how to get a bot token, please see the guide here:
|
||||
// https://github.com/jagrosh/MusicBot/wiki/Getting-a-Bot-Token
|
||||
|
||||
token = BOT_TOKEN_HERE
|
||||
|
||||
|
||||
// This sets the owner of the bot
|
||||
// This needs to be the owner's ID (a 17-18 digit number)
|
||||
// https://github.com/jagrosh/MusicBot/wiki/Finding-Your-User-ID
|
||||
|
||||
owner = 0
|
||||
|
||||
|
||||
// This sets the prefix for the bot
|
||||
// The prefix is used to control the commands
|
||||
// If you use !!, the play command will be !!play
|
||||
// If you do not set this, the prefix will be a mention of the bot (@Botname play)
|
||||
// If you make this blank, the bot will not use a prefix
|
||||
|
||||
prefix = "@mention"
|
||||
|
||||
|
||||
// If you set this, it modifies the default game of the bot
|
||||
// Set this to NONE to have no game
|
||||
// Set this to DEFAULT to use the default game
|
||||
// You can make the game "Playing X", "Listening to X", or "Watching X"
|
||||
// where X is the title. If you don't include an action, it will use the
|
||||
// default of "Playing"
|
||||
|
||||
game = "DEFAULT"
|
||||
|
||||
|
||||
// If you set this, it will modify the default status of bot
|
||||
// Valid values: ONLINE IDLE DND INVISIBLE
|
||||
|
||||
status = ONLINE
|
||||
|
||||
|
||||
// If you set this to true, the bot will list the title of the song it is currently playing in its
|
||||
// "Playing" status. Note that this will ONLY work if the bot is playing music on ONE guild;
|
||||
// if the bot is playing on multiple guilds, this will not work.
|
||||
|
||||
songinstatus=false
|
||||
|
||||
|
||||
// If you set this, the bot will also use this prefix in addition to
|
||||
// the one provided above
|
||||
|
||||
altprefix = "NONE"
|
||||
|
||||
|
||||
// If you set these, it will change the various emojis
|
||||
|
||||
success = "🎶"
|
||||
warning = "💡"
|
||||
error = "🚫"
|
||||
loading = "⌚"
|
||||
searching = "🔎"
|
||||
|
||||
|
||||
// If you set this, you change the word used to view the help.
|
||||
// For example, if you set the prefix to !! and the help to cmds, you would type
|
||||
// !!cmds to see the help text
|
||||
|
||||
help = help
|
||||
|
||||
|
||||
// If you set this, the "nowplaying" command will show youtube thumbnails
|
||||
// Note: If you set this to true, the nowplaying boxes will NOT refresh
|
||||
// This is because refreshing the boxes causes the image to be reloaded
|
||||
// every time it refreshes.
|
||||
|
||||
npimages = false
|
||||
|
||||
|
||||
// If you set this, the bot will not leave a voice channel after it finishes a queue.
|
||||
// Keep in mind that being connected to a voice channel uses additional bandwith,
|
||||
// so this option is not recommended if bandwidth is a concern.
|
||||
|
||||
stayinchannel = false
|
||||
|
||||
|
||||
// This sets the maximum amount of seconds any track loaded can be. If not set or set
|
||||
// to any number less than or equal to zero, there is no maximum time length. This time
|
||||
// restriction applies to songs loaded from any source.
|
||||
|
||||
maxtime = 0
|
||||
|
||||
|
||||
// This sets an alternative folder to be used as the Playlists folder
|
||||
// This can be a relative or absolute path
|
||||
|
||||
playlistsfolder = "Playlists"
|
||||
|
||||
|
||||
// By default, the bot will DM the owner if the bot is running and a new version of the bot
|
||||
// becomes available. Set this to false to disable this feature.
|
||||
|
||||
updatealerts=true
|
||||
|
||||
|
||||
// Changing this changes the lyrics provider
|
||||
// Currently available providers: "A-Z Lyrics", "Genius", "MusicMatch"
|
||||
// At the time of writing, I would recommend sticking with A-Z Lyrics or MusicMatch,
|
||||
// as Genius tends to have a lot of non-song results and you might get something
|
||||
// completely unrelated to what you want.
|
||||
// If you are interested in contributing a provider, please see
|
||||
// https://github.com/jagrosh/JLyrics
|
||||
|
||||
lyrics.default = "MusicMatch"
|
||||
|
||||
|
||||
// If you set this to true, it will enable the eval command for the bot owner. This command
|
||||
// allows the bot owner to run arbitrary code from the bot's account.
|
||||
//
|
||||
// WARNING:
|
||||
// This command can be extremely dangerous. If you don't know what you're doing, you could
|
||||
// cause horrific problems on your Discord server or on whatever computer this bot is running
|
||||
// on. Never run this command unless you are completely positive what you are running.
|
||||
//
|
||||
// DO NOT ENABLE THIS IF YOU DON'T KNOW WHAT THIS DOES OR HOW TO USE IT
|
||||
// IF SOMEONE ASKS YOU TO ENABLE THIS, THERE IS AN 11/10 CHANCE THEY ARE TRYING TO SCAM YOU
|
||||
|
||||
eval=false
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2018 John Grosh <john.a.grosh@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jagrosh.jmusicbot;
|
||||
|
||||
import com.jagrosh.jmusicbot.queue.FairQueue;
|
||||
import com.jagrosh.jmusicbot.queue.Queueable;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author John Grosh (john.a.grosh@gmail.com)
|
||||
*/
|
||||
public class FairQueueTest
|
||||
{
|
||||
@Test
|
||||
public void differentIdentifierSize()
|
||||
{
|
||||
FairQueue<Q> queue = new FairQueue<>();
|
||||
int size = 100;
|
||||
for(int i=0; i<size; i++)
|
||||
queue.add(new Q(i));
|
||||
assertEquals(queue.size(), size);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sameIdentifierSize()
|
||||
{
|
||||
FairQueue<Q> queue = new FairQueue<>();
|
||||
int size = 100;
|
||||
for(int i=0; i<size; i++)
|
||||
queue.add(new Q(0));
|
||||
assertEquals(queue.size(), size);
|
||||
}
|
||||
|
||||
private class Q implements Queueable
|
||||
{
|
||||
private final long identifier;
|
||||
|
||||
private Q(long identifier)
|
||||
{
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getIdentifier()
|
||||
{
|
||||
return identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user