Compare commits

...
30 Commits
Author SHA1 Message Date
John Grosh e1b9e0165a Move pull req template 2019-01-30 11:58:55 -05:00
John Grosh 2e701d0d23 Move code of conduct 2019-01-30 11:58:21 -05:00
John Grosh 259e3d716b Update README.md 2019-01-13 15:53:19 -05:00
John Grosh 43398449c7 more cleanup and update readme 2019-01-13 15:51:26 -05:00
John Grosh e7f00fe088 Merge origin/master 2019-01-13 15:06:49 -05:00
John Grosh 1a9364acae code cleanup and deps update 2019-01-13 15:06:26 -05:00
John Grosh 19234998f1 Merge pull request #193 from jagrosh/add-code-of-conduct-1
Create CODE_OF_CONDUCT.md
2018-12-07 10:46:41 -05:00
John Grosh 31037775d1 Create CODE_OF_CONDUCT.md 2018-12-07 10:42:34 -05:00
John Grosh e0b1bb0d06 Create PULL_REQUEST_TEMPLATE.md 2018-12-07 10:34:42 -05:00
John Grosh 1f810aa36f Delete ISSUE_TEMPLATE.md 2018-12-07 10:22:20 -05:00
John Grosh e7a8cec0b4 Update issue templates 2018-12-07 10:22:04 -05:00
John Grosh ae07ac2598 lyrics second pass 2018-12-05 02:16:39 -05:00
John Grosh d75098fdd9 Update config.yml 2018-12-05 00:47:25 -05:00
John Grosh ac87cc13d7 fix pom 2018-12-05 00:43:13 -05:00
John Grosh 34bffe0148 first pass of lyrics command
version bump
more code cleanup
2018-12-05 00:30:28 -05:00
John Grosh 15f3cf07a8 Merge origin/master 2018-12-04 23:53:24 -05:00
John Grosh c0f0d45138 code cleanup 2018-12-04 23:37:45 -05:00
John Grosh 2eddaccb86 Update README.md 2018-11-27 15:04:21 -05:00
John Grosh 87b2f4f93a Update README.md 2018-11-27 15:02:41 -05:00
John Grosh 88970314ad Update README.md 2018-11-27 10:01:04 -05:00
John Grosh 0de4e2afcc Update .appveyor.yml 2018-11-27 09:58:09 -05:00
John Grosh 2671ac18c8 Update .appveyor.yml 2018-11-27 09:50:50 -05:00
John Grosh 68a992c79e Create .appveyor.yml 2018-11-27 09:40:46 -05:00
John Grosh 9bf233ec79 Update README.md 2018-11-27 09:25:50 -05:00
John Grosh b41dcded98 Update README.md 2018-11-27 09:25:30 -05:00
John Grosh b6239ed608 Update .travis.yml 2018-11-27 09:25:14 -05:00
John Grosh 9dfe613921 Update .travis.yml 2018-11-27 09:21:10 -05:00
John Grosh 865119e2ae Create .travis.settings.xml 2018-11-27 09:20:53 -05:00
John Grosh c616f9c92a Create .travis.yml 2018-11-27 09:01:09 -05:00
John Grosh 2737a85a61 Create config.yml 2018-11-27 08:41:38 -05:00
36 changed files with 684 additions and 438 deletions

No files matched your search

+21
View File
@@ -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
+41
View File
@@ -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
+76
View File
@@ -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
-24
View File
@@ -1,24 +0,0 @@
[download]: https://github.com/jagrosh/MusicBot/releases/latest
[release]: https://img.shields.io/github/release/jagrosh/MusicBot.svg
[setup]: https://github.com/jagrosh/MusicBot/wiki/Setup
[rpi]: https://github.com/jagrosh/MusicBot/wiki/JMusicBot-on-Raspberry-Pi
[features]: https://github.com/jagrosh/MusicBot/projects/1
## General Troubleshooting
Please check off these steps before suggesting a feature or reporting a bug:
- [ ] I am running the [latest version][download]: [![Release][release]][download]
- [ ] I have followed all instructions on the [setup page][setup] (and if applicable, [Raspberry Pi][rpi])
- [ ] I have read through the [planned and suggested features][features]
## Issue
### Issue Type
- [ ] Bug Report
- [ ] Feature Request
### Description
Replace this with a description of your bug or feature request. Please provide screenshots and logs as applicable.
+30
View File
@@ -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.
+27
View File
@@ -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
+14
View File
@@ -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 #...
+2 -1
View File
@@ -1,5 +1,6 @@
/nbproject/
/target/
/Playlists/
*.json
*.txt
/nbproject/
nb*.xml
+22
View File
@@ -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>
+2
View File
@@ -0,0 +1,2 @@
language: java
install: mvn install -Dmaven.javadoc.skip=true --batch-mode --show-version --settings .travis.settings.xml
+28 -20
View File
@@ -1,36 +1,44 @@
<img align="right" src="https://i.imgur.com/zrE80HY.png" height="200" width="200">
# JMusicBot
[![Downloads](https://img.shields.io/github/downloads/jagrosh/MusicBot/total.svg)](https://github.com/jagrosh/MusicBot/releases/latest)
[![Stars](https://img.shields.io/github/stars/jagrosh/MusicBot.svg)](https://github.com/jagrosh/MusicBot/stargazers)
[![Release](https://img.shields.io/github/release/jagrosh/MusicBot.svg)](https://github.com/jagrosh/MusicBot/releases/latest)
[![License](https://img.shields.io/github/license/jagrosh/MusicBot.svg)](https://github.com/jagrosh/MusicBot/blob/master/LICENSE)
[![Discord](https://discordapp.com/api/guilds/147698382092238848/widget.png)](https://discord.gg/0p9LSGoRLu6Pet0k)
[![Discord](https://discordapp.com/api/guilds/147698382092238848/widget.png)](https://discord.gg/0p9LSGoRLu6Pet0k)<br>
[![CircleCI](https://img.shields.io/circleci/project/github/jagrosh/MusicBot/master.svg)](https://circleci.com/gh/jagrosh/MusicBot)
[![Travis-CI](https://travis-ci.com/jagrosh/MusicBot.svg?branch=master)](https://travis-ci.com/jagrosh/MusicBot)
[![AppVeyor](https://ci.appveyor.com/api/projects/status/gdu6nyte5psj6xfk/branch/master?svg=true)](https://ci.appveyor.com/project/jagrosh/musicbot/branch/master)
[![CodeFactor](https://www.codefactor.io/repository/github/jagrosh/musicbot/badge)](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!
[![Setup](http://i.imgur.com/VvXYp5j.png)](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
![Loading Example...](https://i.imgur.com/kVtTKvS.gif)
## 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
![Example](https://i.imgur.com/tevrtKt.png)
# 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.
+48 -25
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.jagrosh</groupId>
<artifactId>JMusicBot</artifactId>
<version>0.2.1</version>
<version>0.2.2</version>
<packaging>jar</packaging>
<repositories>
@@ -12,13 +12,18 @@
<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>net.dv8tion</groupId>
<artifactId>JDA</artifactId>
<version>3.8.1_447</version>
<version>3.8.1_454</version>
</dependency>
<dependency>
<groupId>com.sedmelluq</groupId>
@@ -28,9 +33,14 @@
<dependency>
<groupId>com.jagrosh</groupId>
<artifactId>jda-utilities</artifactId>
<version>2.1.4</version>
<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>
@@ -58,28 +68,41 @@
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.jagrosh.jmusicbot.JMusicBot</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<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>
@@ -77,9 +77,6 @@ public class BotConfig
//Config config = ConfigFactory.parseFile(path.toFile()).withFallback(ConfigFactory.load());
Config config = ConfigFactory.load();
// info on where the config is being loaded from
prompt.alert(Prompt.Level.INFO, CONTEXT, "Loading config from "+path.toAbsolutePath().toString());
// set values
token = config.getString("token");
prefix = config.getString("prefix");
@@ -114,12 +111,12 @@ public class BotConfig
+ "\nBot Token: ");
if(token==null)
{
prompt.alert(Prompt.Level.WARNING, CONTEXT, "No token provided! Exiting.");
prompt.alert(Prompt.Level.WARNING, CONTEXT, "No token provided! Exiting.\n\nConfig Location: " + path.toAbsolutePath().toString());
return;
}
else
{
lines.add("token="+token);
lines.add("token = "+token);
}
}
@@ -140,12 +137,12 @@ public class BotConfig
}
if(owner<=0)
{
prompt.alert(Prompt.Level.ERROR, CONTEXT, "Invalid User ID! Exiting.");
prompt.alert(Prompt.Level.ERROR, CONTEXT, "Invalid User ID! Exiting.\n\nConfig Location: " + path.toAbsolutePath().toString());
System.exit(0);
}
else
{
lines.add("owner="+owner);
lines.add("owner = "+owner);
}
}
@@ -160,7 +157,8 @@ public class BotConfig
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.");
+ "\nPlease make sure that the files are not on your desktop or some other restricted area.\n\nConfig Location: "
+ path.toAbsolutePath().toString());
}
}
@@ -169,7 +167,7 @@ public class BotConfig
}
catch (ConfigException ex)
{
prompt.alert(Prompt.Level.ERROR, CONTEXT, ex + ": " + ex.getMessage());
prompt.alert(Prompt.Level.ERROR, CONTEXT, ex + ": " + ex.getMessage() + "\n\nConfig Location: " + path.toAbsolutePath().toString());
}
}
@@ -41,9 +41,9 @@ import org.slf4j.LoggerFactory;
*/
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 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};
@@ -87,7 +87,7 @@ public class JMusicBot
new String[]{"High-quality music playback", "FairQueue™ Technology", "Easy to host yourself"},
RECOMMENDED_PERMS);
aboutCommand.setIsAuthor(false);
aboutCommand.setReplacementCharacter("\uD83C\uDFB6");
aboutCommand.setReplacementCharacter("\uD83C\uDFB6"); // 🎶
// set up the command client
CommandClientBuilder cb = new CommandClientBuilder()
@@ -102,6 +102,7 @@ public class JMusicBot
new PingCommand(),
new SettingsCmd(),
new LyricsCmd(bot),
new NowplayingCmd(bot),
new PlayCmd(bot, config.getLoading()),
new PlaylistsCmd(bot),
@@ -128,7 +129,7 @@ public class JMusicBot
new PlaylistCmd(bot),
new SetavatarCmd(),
new SetgameCmd(),
new SetnameCmd(bot),
new SetnameCmd(),
new SetstatusCmd(),
new ShutdownCmd(bot)
);
@@ -58,13 +58,12 @@ public class Listener extends ListenerAdapter
{
String defpl = bot.getSettingsManager().getSettings(guild).getDefaultPlaylist();
VoiceChannel vc = bot.getSettingsManager().getSettings(guild).getVoiceChannel(guild);
if(defpl!=null && vc!=null)
if(defpl!=null && vc!=null && bot.getPlayerManager().setUpHandler(guild).playFromDefault())
{
if(bot.getPlayerManager().setUpHandler(guild).playFromDefault())
guild.getAudioManager().openAudioConnection(vc);
guild.getAudioManager().openAudioConnection(vc);
}
}
catch(Exception ex) {}
catch(Exception ignore) {}
});
if(bot.getConfig().useUpdateAlerts())
{
@@ -29,8 +29,6 @@ import java.util.Set;
import com.jagrosh.jmusicbot.queue.FairQueue;
import com.jagrosh.jmusicbot.settings.Settings;
import com.jagrosh.jmusicbot.utils.FormatUtil;
import static com.jagrosh.jmusicbot.utils.FormatUtil.formatTime;
import static com.jagrosh.jmusicbot.utils.FormatUtil.volumeIcon;
import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioTrack;
import net.dv8tion.jda.core.EmbedBuilder;
import net.dv8tion.jda.core.JDA;
@@ -255,11 +253,11 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler
if(title==null || title.equals("Unknown Title"))
title = track.getInfo().uri;
return "**"+title+"** ["+(userid==0 ? "autoplay" : "<@"+userid+">")+"]"
+ "\n"+(audioPlayer.isPaused()?"\u23F8":"\u25B6")+" "
+"["+formatTime(track.getDuration())+"] "
+volumeIcon(audioPlayer.getVolume());
+ "\n" + (audioPlayer.isPaused() ? JMusicBot.PAUSE_EMOJI : JMusicBot.PLAY_EMOJI) + " "
+ "[" + FormatUtil.formatTime(track.getDuration()) + "] "
+ FormatUtil.volumeIcon(audioPlayer.getVolume());
}
else return "No music playing \u23F9 " + volumeIcon(audioPlayer.getVolume());
else return "No music playing " + JMusicBot.STOP_EMOJI + " " + FormatUtil.volumeIcon(audioPlayer.getVolume());
}
// Audio Send Handler methods
@@ -18,13 +18,11 @@ package com.jagrosh.jmusicbot.audio;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.entities.Pair;
import com.jagrosh.jmusicbot.settings.Settings;
import com.jagrosh.jmusicbot.utils.FormatUtil;
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.MessageBuilder;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.Game;
import net.dv8tion.jda.core.entities.Guild;
@@ -125,7 +123,7 @@ public class NowplayingHandler
else
tchan.getManager().setTopic(text).queue();
}
catch(PermissionException e) {}
catch(PermissionException ignore) {}
}
}
}
@@ -52,7 +52,7 @@ public abstract class MusicCommand extends Command
try
{
event.getMessage().delete().queue();
} catch(PermissionException e){}
} catch(PermissionException ignore){}
event.replyInDm(event.getClient().getError()+" You can only use that command in "+tchannel.getAsMention()+"!");
return;
}
@@ -16,23 +16,16 @@
package com.jagrosh.jmusicbot.commands.dj;
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.audio.QueuedTrack;
import com.jagrosh.jmusicbot.commands.DJCommand;
import com.jagrosh.jmusicbot.commands.music.PlayCmd;
import static com.jagrosh.jmusicbot.commands.music.PlayCmd.CANCEL;
import static com.jagrosh.jmusicbot.commands.music.PlayCmd.LOAD;
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 java.util.concurrent.TimeUnit;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.Message;
import net.dv8tion.jda.core.exceptions.PermissionException;
/**
*
@@ -69,9 +62,9 @@ public class PlaynextCmd extends DJCommand
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)
{
@@ -63,5 +63,5 @@ public class RepeatCmd extends DJCommand
}
@Override
public void doCommand(CommandEvent event) {}
public void doCommand(CommandEvent event) { /* Intentionally Empty */ }
}
@@ -17,7 +17,6 @@ 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.Settings;
import net.dv8tion.jda.core.EmbedBuilder;
import net.dv8tion.jda.core.MessageBuilder;
@@ -31,6 +30,8 @@ import net.dv8tion.jda.core.entities.VoiceChannel;
*/
public class SettingsCmd extends Command
{
private final static String EMOJI = "\uD83C\uDFA7"; // 🎧
public SettingsCmd()
{
this.name = "settings";
@@ -44,7 +45,7 @@ public class SettingsCmd extends Command
{
Settings s = event.getClient().getSettingsFor(event.getGuild());
MessageBuilder builder = new MessageBuilder()
.append("\uD83C\uDFA7 **")
.append(EMOJI + " **")
.append(event.getSelfUser().getName())
.append("** settings:");
TextChannel tchan = s.getTextChannel(event.getGuild());
@@ -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());
});
}
}
@@ -42,8 +42,8 @@ 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;
@@ -99,9 +99,9 @@ public class PlayCmd extends MusicCommand
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)
{
@@ -139,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);
}
}
@@ -37,7 +37,10 @@ import net.dv8tion.jda.core.exceptions.PermissionException;
*/
public class QueueCmd extends MusicCommand
{
private final static String REPEAT = "\uD83D\uDD01"; // 🔁
private final Paginator.Builder builder;
public QueueCmd(Bot bot)
{
super(bot);
@@ -49,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)
@@ -66,7 +69,7 @@ public class QueueCmd extends MusicCommand
{
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())
@@ -110,6 +113,6 @@ public class QueueCmd extends MusicCommand
}
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());
}
}
@@ -73,8 +73,9 @@ public class SearchCmd extends MusicCommand
private class ResultHandler implements AudioLoadResultHandler
{
final Message m;
final CommandEvent event;
private final Message m;
private final CommandEvent event;
private ResultHandler(Message m, CommandEvent event)
{
this.m = m;
@@ -27,8 +27,11 @@ import com.jagrosh.jmusicbot.commands.OwnerCommand;
*/
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.guildOnly = false;
@@ -38,6 +41,7 @@ public class EvalCmd extends OwnerCommand
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());
@@ -26,7 +26,7 @@ import net.dv8tion.jda.core.exceptions.RateLimitedException;
*/
public class SetnameCmd extends OwnerCommand
{
public SetnameCmd(Bot bot)
public SetnameCmd()
{
this.name = "setname";
this.help = "sets the name of the bot";
@@ -37,13 +37,18 @@ public class SetnameCmd extends OwnerCommand
@Override
protected void execute(CommandEvent event)
{
try {
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) {
}
catch(RateLimitedException e)
{
event.reply(event.getClient().getError()+" Name can only be changed twice per hour!");
} catch(Exception e) {
}
catch(Exception e)
{
event.reply(event.getClient().getError()+" That name is not valid!");
}
}
@@ -61,9 +61,18 @@ public class Prompt
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;
case INFO:
log.info(message);
break;
case WARNING:
log.warn(message);
break;
case ERROR:
log.error(message);
break;
default:
log.info(message);
break;
}
}
else
@@ -73,9 +82,18 @@ public class Prompt
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;
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);
}
@@ -51,7 +51,7 @@ public class GUI extends JFrame
setVisible(true);
addWindowListener(new WindowListener()
{
@Override public void windowOpened(WindowEvent e) {}
@Override public void windowOpened(WindowEvent e) { /* unused */ }
@Override public void windowClosing(WindowEvent e)
{
try
@@ -63,11 +63,11 @@ public class GUI extends JFrame
System.exit(0);
}
}
@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) {}
@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 */
@@ -63,7 +63,7 @@ public class PlaylistLoader
{
Files.createDirectory(Paths.get(config.getPlaylistsFolder()));
}
catch (IOException ex) {}
catch (IOException ignore) {}
}
public boolean folderExists()
@@ -37,30 +37,13 @@ public class FormatUtil {
seconds %= 60;
return (hours>0 ? hours+":" : "") + (minutes<10 ? "0"+minutes : minutes) + ":" + (seconds<10 ? "0"+seconds : seconds);
}
/*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;
@@ -69,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)
@@ -109,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
}
}
@@ -51,7 +51,7 @@ public class OtherUtil
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) {}
catch(IOException | IllegalArgumentException ignore) {}
return null;
}
+28 -17
View File
@@ -13,14 +13,14 @@
// 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
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
owner = 0
// This sets the prefix for the bot
@@ -29,7 +29,7 @@ owner=0
// 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"
prefix = "@mention"
// If you set this, it modifies the default game of the bot
@@ -39,13 +39,13 @@ prefix="@mention"
// where X is the title. If you don't include an action, it will use the
// default of "Playing"
game="DEFAULT"
game = "DEFAULT"
// If you set this, it will modify the default status of bot
// Valid values: ONLINE IDLE DND INVISIBLE
status=ONLINE
status = ONLINE
// If you set this to true, the bot will list the title of the song it is currently playing in its
@@ -58,23 +58,23 @@ songinstatus=false
// If you set this, the bot will also use this prefix in addition to
// the one provided above
altprefix="NONE"
altprefix = "NONE"
// If you set these, it will change the various emojis
success="🎶"
warning="💡"
error="🚫"
loading="⌚"
searching="🔎"
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
help = help
// If you set this, the "nowplaying" command will show youtube thumbnails
@@ -82,27 +82,27 @@ help=help
// This is because refreshing the boxes causes the image to be reloaded
// every time it refreshes.
npimages=false
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
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
maxtime = 0
// This sets an alternative folder to be used as the Playlists folder
// This can be a relative or absolute path
playlistsfolder=Playlists
playlistsfolder = "Playlists"
// By default, the bot will DM the owner if the bot is running and a new version of the bot
@@ -111,6 +111,17 @@ playlistsfolder=Playlists
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.
//
@@ -122,4 +133,4 @@ updatealerts=true
// 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
eval=false
@@ -24,7 +24,7 @@ import static org.junit.Assert.*;
*
* @author John Grosh (john.a.grosh@gmail.com)
*/
public class QueueTests
public class FairQueueTest
{
@Test
public void differentIdentifierSize()