Compare commits

...
12 Commits
Author SHA1 Message Date
John Grosh dddf4c8e38 added altprefix, songinstatus, and setstatus features
slight change to internals to reduce some bugs
2017-08-18 15:43:20 -04:00
John Grosh 0912de74e9 Merge origin/master 2017-07-04 02:58:24 -04:00
John Grosh 3752e5b9e0 update pom 2017-07-04 02:57:56 -04:00
John Grosh ae62d5771f Update README.md 2017-07-04 02:32:26 -04:00
John Grosh 434749a250 fixed playlist shuffling 2017-07-04 02:19:08 -04:00
John Grosh cb9644d694 playlist load faster and queue command shows np 2017-07-04 01:41:42 -04:00
John Grosh 8f7e53a37c updated config for staying in voice 2017-06-22 02:47:54 -04:00
John Grosh b158e70495 added pause command
use embed for nowplaying
2017-06-22 01:45:11 -04:00
John Grosh ebed4f972a shuffle playlists when a single commented line contains 'shuffle'
fixed role bug
2017-06-22 00:54:51 -04:00
John Grosh f8b15d9591 updated readme
bumped license year
removed unnecessary import
2017-05-21 10:17:44 -04:00
John Grosh ab1e86d4ca Merge origin/master 2017-05-18 19:59:57 -04:00
John Grosh 9da577aa60 updated versions
local file support
less topic spam for the audit log conscious
2017-05-18 19:59:25 -04:00
27 changed files with 1391 additions and 991 deletions

No files matched your search

+201 -201
View File
@@ -1,201 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
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.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2017 John Grosh
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.
+5
View File
@@ -12,6 +12,8 @@ A Discord music bot with a clean interface, and that is easy to set up and run y
* 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
@@ -20,5 +22,8 @@ Please see the [Setup Page](https://github.com/jagrosh/MusicBot/wiki/Setup) in t
# Questions/Suggestions/Bug Reports
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). 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)
# 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.
# Example
![Example](http://i.imgur.com/gxDdlRL.png)
+4 -4
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.jagrosh</groupId>
<artifactId>JMusicBot</artifactId>
<version>0.0.4</version>
<version>0.0.8</version>
<packaging>jar</packaging>
<repositories>
@@ -23,17 +23,17 @@
<dependency>
<groupId>net.dv8tion</groupId>
<artifactId>JDA</artifactId>
<version>3.0.0_168</version>
<version>3.2.0_242</version>
</dependency>
<dependency>
<groupId>com.sedmelluq</groupId>
<artifactId>lavaplayer</artifactId>
<version>1.2.36</version>
<version>1.2.43</version>
</dependency>
<dependency>
<groupId>com.jagrosh</groupId>
<artifactId>JDA-Utilities</artifactId>
<version>1.1</version>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
+55 -23
View File
@@ -35,14 +35,15 @@ import com.jagrosh.jmusicbot.gui.GUI;
import com.jagrosh.jmusicbot.utils.FormatUtil;
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.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.hooks.ListenerAdapter;
import net.dv8tion.jda.core.utils.PermissionUtil;
import net.dv8tion.jda.core.utils.SimpleLog;
import org.json.JSONException;
import org.json.JSONObject;
@@ -57,6 +58,7 @@ public class Bot extends ListenerAdapter {
private final AudioPlayerManager manager;
private final EventWaiter waiter;
private final ScheduledExecutorService threadpool;
private final Config config;
private JDA jda;
private GUI gui;
//private GuildsPanel panel;
@@ -67,7 +69,7 @@ public class Bot extends ListenerAdapter {
return true;
if(event.getGuild()==null)
return true;
if(PermissionUtil.checkPermission(event.getGuild(), event.getMember(), Permission.MANAGE_SERVER))
if(event.getMember().hasPermission(Permission.MANAGE_SERVER))
return true;
Role dj = event.getGuild().getRoleById(getSettings(event.getGuild()).getRoleId());
return event.getMember().getRoles().contains(dj);
@@ -79,22 +81,25 @@ public class Bot extends ListenerAdapter {
return true;
if(event.getGuild()==null)
return true;
return PermissionUtil.checkPermission(event.getGuild(), event.getMember(), Permission.MANAGE_SERVER);
return event.getMember().hasPermission(Permission.MANAGE_SERVER);
});
public final Category OWNER = new Category("Owner");
public Bot(EventWaiter waiter)
public Bot(EventWaiter waiter, Config config)
{
this.config = config;
this.waiter = waiter;
this.settings = new HashMap<>();
manager = new DefaultAudioPlayerManager();
threadpool = Executors.newSingleThreadScheduledExecutor();
AudioSourceManagers.registerRemoteSources(manager);
AudioSourceManagers.registerLocalSource(manager);
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,
@@ -145,10 +150,18 @@ public class Bot extends ListenerAdapter {
return handler;
}
public void resetGame()
{
if(config.getGame()==null || config.getGame().equalsIgnoreCase("none"))
jda.getPresence().setGame(null);
else
jda.getPresence().setGame(Game.of(config.getGame()));
}
private void updateTopic(Guild guild, AudioHandler handler)
{
TextChannel tchan = guild.getTextChannelById(getSettings(guild).getTextId());
if(tchan!=null && PermissionUtil.checkPermission(tchan, guild.getSelfMember(), Permission.MANAGE_CHANNEL))
if(tchan!=null && guild.getSelfMember().hasPermission(tchan, Permission.MANAGE_CHANNEL))
{
String otherText;
if(tchan.getTopic()==null || tchan.getTopic().isEmpty())
@@ -157,7 +170,7 @@ public class Bot extends ListenerAdapter {
otherText = tchan.getTopic().substring(tchan.getTopic().indexOf("\u200B"));
else
otherText = "\u200B\n "+tchan.getTopic();
String text = FormatUtil.formattedAudio(handler, guild.getJDA(), true)+otherText;
String text = FormatUtil.formattedAudio(handler, guild.getJDA())+otherText;
if(!text.equals(tchan.getTopic()))
tchan.getManager().setTopic(text).queue();
}
@@ -198,20 +211,39 @@ public class Bot extends ListenerAdapter {
SimpleLog.getLog("MusicBot").warn("This bot is not on any guilds! Use the following link to add the bot to your guilds!");
SimpleLog.getLog("MusicBot").warn(event.getJDA().asBot().getInviteUrl(JMusicBot.RECOMMENDED_PERMS));
}
credit(event.getJDA());
jda.getGuilds().forEach((guild) -> {
try
{
String defpl = getSettings(guild).getDefaultPlaylist();
if(defpl!=null)
VoiceChannel vc = guild.getVoiceChannelById(getSettings(guild).getVoiceId());
if(defpl!=null && vc!=null)
{
if(setUpHandler(guild).playFromDefault())
guild.getAudioManager().openAudioConnection(guild.getVoiceChannelById(getSettings(guild).getVoiceId()));
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
@@ -229,7 +261,7 @@ public class Bot extends ListenerAdapter {
}
else
{
s.setTextId(channel.getId());
s.setTextId(channel.getIdLong());
}
writeSettings();
}
@@ -243,7 +275,7 @@ public class Bot extends ListenerAdapter {
}
else
{
s.setVoiceId(channel.getId());
s.setVoiceId(channel.getIdLong());
}
writeSettings();
}
@@ -257,7 +289,7 @@ public class Bot extends ListenerAdapter {
}
else
{
s.setRoleId(role.getId());
s.setRoleId(role.getIdLong());
}
writeSettings();
}
@@ -295,10 +327,10 @@ public class Bot extends ListenerAdapter {
Settings s = getSettings(guild);
if(s!=Settings.DEFAULT_SETTINGS)
{
if(s.getVoiceId()==null && s.getRoleId()==null)
if(s.getVoiceId()==0 && s.getRoleId()==0)
settings.remove(guild.getId());
else
s.setTextId(null);
s.setTextId(0);
writeSettings();
}
}
@@ -308,10 +340,10 @@ public class Bot extends ListenerAdapter {
Settings s = getSettings(guild);
if(s!=Settings.DEFAULT_SETTINGS)
{
if(s.getTextId()==null && s.getRoleId()==null)
if(s.getTextId()==0 && s.getRoleId()==0)
settings.remove(guild.getId());
else
s.setVoiceId(null);
s.setVoiceId(0);
writeSettings();
}
}
@@ -321,10 +353,10 @@ public class Bot extends ListenerAdapter {
Settings s = getSettings(guild);
if(s!=Settings.DEFAULT_SETTINGS)
{
if(s.getVoiceId()==null && s.getTextId()==null)
if(s.getVoiceId()==0 && s.getTextId()==0)
settings.remove(guild.getId());
else
s.setRoleId(null);
s.setRoleId(0);
writeSettings();
}
}
@@ -335,12 +367,12 @@ public class Bot extends ListenerAdapter {
settings.keySet().stream().forEach(key -> {
JSONObject o = new JSONObject();
Settings s = settings.get(key);
if(s.getTextId()!=null)
o.put("text_channel_id", s.getTextId());
if(s.getVoiceId()!=null)
o.put("voice_channel_id", s.getVoiceId());
if(s.getRoleId()!=null)
o.put("dj_role_id", s.getRoleId());
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)
@@ -15,6 +15,7 @@
*/
package com.jagrosh.jmusicbot;
import com.jagrosh.jmusicbot.utils.FormatUtil;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
@@ -30,6 +31,7 @@ import javax.swing.JOptionPane;
public class Config {
private boolean nogui;
private String prefix;
private String altprefix;
private String token;
private String owner;
private String success;
@@ -37,6 +39,9 @@ public class Config {
private String error;
private String game;
private String help;
private boolean stay;
private boolean dbots;
private boolean songingame;
public Config(boolean nogui)
{
@@ -44,6 +49,7 @@ public class Config {
List<String> lines;
try {
lines = Files.readAllLines(Paths.get("config.txt"));
System.out.println("[INFO] Loading config: "+Paths.get("config.txt").toFile().getAbsolutePath());
for(String line: lines)
{
String[] parts = line.split("=",2);
@@ -57,6 +63,9 @@ public class Config {
case "prefix":
prefix = value;
break;
case "altprefix":
altprefix = value;
break;
case "owner":
owner = value;
break;
@@ -75,6 +84,18 @@ public class Config {
case "help":
help = value;
break;
case "noprogressintopic":
FormatUtil.NO_PROGRESS_BAR_IN_TOPIC = "true".equalsIgnoreCase(value);
break;
case "songinstatus":
songingame = "true".equalsIgnoreCase(value);
break;
case "stayinchannel":
stay = "true".equalsIgnoreCase(value);
break;
case "dbots":
dbots = "110373943822540800".equals(value);
break;
}
}
} catch (IOException ex) {
@@ -135,6 +156,11 @@ public class Config {
return prefix;
}
public String getAltPrefix()
{
return altprefix;
}
public String getToken()
{
return token;
@@ -175,6 +201,21 @@ public class Config {
return nogui;
}
public boolean getStay()
{
return stay;
}
public boolean getSongInStatus()
{
return songingame;
}
public boolean getDBots()
{
return dbots;
}
private void alert(String message)
{
if(nogui)
@@ -21,6 +21,7 @@ import com.jagrosh.jdautilities.commandclient.CommandClient;
import com.jagrosh.jdautilities.commandclient.CommandClientBuilder;
import com.jagrosh.jdautilities.commandclient.examples.*;
import com.jagrosh.jdautilities.waiter.EventWaiter;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import com.jagrosh.jmusicbot.commands.*;
import com.jagrosh.jmusicbot.gui.GUI;
import net.dv8tion.jda.core.AccountType;
@@ -55,20 +56,24 @@ public class JMusicBot {
// set up the listener
EventWaiter waiter = new EventWaiter();
Bot bot = new Bot(waiter);
Bot bot = new Bot(waiter, config);
AboutCommand.IS_AUTHOR = false;
AboutCommand.REPLACEMENT_ICON = "\uD83C\uDFB6";
AudioHandler.STAY_IN_CHANNEL = config.getStay();
AudioHandler.SONG_IN_STATUS = config.getSongInStatus();
// set up the command client
CommandClientBuilder cb = new CommandClientBuilder()
.setPrefix(config.getPrefix())
.setAlternativePrefix(config.getAltPrefix())
.setOwnerId(config.getOwnerId())
.setEmojis(config.getSuccess(), config.getWarning(), config.getError())
.setHelpWord(config.getHelp())
.addCommands(
new AboutCommand(Color.BLUE.brighter(),
"a music bot that is [easy to host yourself!](https://github.com/jagrosh/MusicBot)",
"a music bot that is [easy to host yourself!](https://github.com/jagrosh/MusicBot) (v0.0.8)",
new String[]{"High-quality music playback", "FairQueue™ Technology", "Easy to host yourself"},
RECOMMENDED_PERMS),
new PingCommand(),
@@ -85,6 +90,7 @@ public class JMusicBot {
new SkipCmd(bot),
new ForceskipCmd(bot),
new PauseCmd(bot),
new SkiptoCmd(bot),
new StopCmd(bot),
new VolumeCmd(bot),
@@ -98,10 +104,13 @@ public class JMusicBot {
new SetavatarCmd(bot),
new SetgameCmd(bot),
new SetnameCmd(bot),
new SetstatusCmd(bot),
new ShutdownCmd(bot)
);
if(config.getGame()==null)
cb.useDefaultGame();
else if(config.getGame().equalsIgnoreCase("none"))
cb.setGame(null);
else
cb.setGame(Game.of(config.getGame()));
CommandClient client = cb.build();
@@ -126,9 +135,9 @@ public class JMusicBot {
.setAudioEnabled(true)
.setGame(Game.of("loading..."))
.setStatus(OnlineStatus.DO_NOT_DISTURB)
.addListener(client)
.addListener(waiter)
.addListener(bot)
.addEventListener(client)
.addEventListener(waiter)
.addEventListener(bot)
.buildAsync();
} catch (LoginException | IllegalArgumentException | RateLimitedException ex) {
SimpleLog.getLog("Login").fatal(ex);
@@ -20,15 +20,45 @@ package com.jagrosh.jmusicbot;
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class Settings {
public final static Settings DEFAULT_SETTINGS = new Settings(null, null, null, 100, null);
public final static Settings DEFAULT_SETTINGS = new Settings(0, 0, 0, 100, null);
private String textId;
private String voiceId;
private String roleId;
private long textId;
private long voiceId;
private long roleId;
private int volume;
private String defaultPlaylist;
public Settings(String textId, String voiceId, String roleId, int volume, String defaultPlaylist)
{
try
{
this.textId = Long.parseLong(textId);
}
catch(NumberFormatException e)
{
this.textId = 0;
}
try
{
this.voiceId = Long.parseLong(voiceId);
}
catch(NumberFormatException e)
{
this.voiceId = 0;
}
try
{
this.roleId = Long.parseLong(roleId);
}
catch(NumberFormatException e)
{
this.roleId = 0;
}
this.volume = volume;
this.defaultPlaylist = defaultPlaylist;
}
public Settings(long textId, long voiceId, long roleId, int volume, String defaultPlaylist)
{
this.textId = textId;
this.voiceId = voiceId;
@@ -37,17 +67,17 @@ public class Settings {
this.defaultPlaylist = defaultPlaylist;
}
public String getTextId()
public long getTextId()
{
return textId;
}
public String getVoiceId()
public long getVoiceId()
{
return voiceId;
}
public String getRoleId()
public long getRoleId()
{
return roleId;
}
@@ -62,17 +92,17 @@ public class Settings {
return defaultPlaylist;
}
public void setTextId(String id)
public void setTextId(long id)
{
this.textId = id;
}
public void setVoiceId(String id)
public void setVoiceId(long id)
{
this.voiceId = id;
}
public void setRoleId(String id)
public void setRoleId(long id)
{
this.roleId = id;
}
@@ -28,6 +28,7 @@ import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.playlist.Playlist;
import com.jagrosh.jmusicbot.queue.FairQueue;
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.User;
@@ -43,7 +44,9 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler
private final List<AudioTrack> defaultQueue;
private final Bot bot;
private AudioFrame lastFrame;
private QueuedTrack current;
private long requester;
public static boolean STAY_IN_CHANNEL;
public static boolean SONG_IN_STATUS;
public AudioHandler(AudioPlayer audioPlayer, Guild guild, Bot bot) {
this.audioPlayer = audioPlayer;
@@ -56,22 +59,14 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler
public int addTrack(AudioTrack track, User user)
{
QueuedTrack qt = new QueuedTrack(track, user.getId());
if(current==null)
if(requester==0)
{
current = qt;
requester = user.getIdLong();
audioPlayer.playTrack(track);
return -1;
}
else
{
return queue.add(qt);
}
}
public QueuedTrack getCurrentTrack()
{
return current;
return queue.add(new QueuedTrack(track, user.getIdLong()));
}
public FairQueue<QueuedTrack> getQueue()
@@ -79,6 +74,19 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler
return queue;
}
public void stopAndClear()
{
queue.clear();
defaultQueue.clear();
audioPlayer.stopTrack();
//current = null;
}
public boolean isMusicPlaying()
{
return guild.getSelfMember().getVoiceState().inVoiceChannel() && audioPlayer.getPlayingTrack()!=null;
}
public Set<String> getVotes()
{
return votes;
@@ -89,12 +97,16 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler
return audioPlayer;
}
public long getRequester()
{
return requester;
}
public boolean playFromDefault()
{
if(!defaultQueue.isEmpty())
{
current = new QueuedTrack(defaultQueue.remove(0), null);
audioPlayer.playTrack(current.getTrack());
audioPlayer.playTrack(defaultQueue.remove(0));
return true;
}
if(bot.getSettings(guild)==null || bot.getSettings(guild).getDefaultPlaylist()==null)
@@ -102,41 +114,45 @@ public class AudioHandler extends AudioEventAdapter implements AudioSendHandler
Playlist pl = Playlist.loadPlaylist(bot.getSettings(guild).getDefaultPlaylist());
if(pl==null || pl.getItems().isEmpty())
return false;
pl.loadTracks(bot.getAudioManager(), () -> {
if(pl.getTracks().isEmpty())
{
current = null;
guild.getAudioManager().closeAudioConnection();
}
pl.loadTracks(bot.getAudioManager(), (at) -> {
if(audioPlayer.getPlayingTrack()==null)
audioPlayer.playTrack(at);
else
{
defaultQueue.addAll(pl.getTracks());
playFromDefault();
}
defaultQueue.add(at);
}, () -> {
if(pl.getTracks().isEmpty() && !STAY_IN_CHANNEL)
guild.getAudioManager().closeAudioConnection();
});
return true;
}
@Override
public void onTrackEnd(AudioPlayer player, AudioTrack track, AudioTrackEndReason endReason) {
requester = 0;
if(queue.isEmpty())
{
if(!playFromDefault())
{
current = null;
guild.getAudioManager().closeAudioConnection();
bot.resetGame();
if(!STAY_IN_CHANNEL)
guild.getAudioManager().closeAudioConnection();
}
}
else
{
current = queue.pull();
player.playTrack(current.getTrack());
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 && guild.getJDA().getGuilds().size()==1)
{
guild.getJDA().getPresence().setGame(Game.of(track.getInfo().title));
}
}
@Override
@@ -1,52 +1,52 @@
/*
* 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.audio;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import com.jagrosh.jmusicbot.queue.Queueable;
import com.jagrosh.jmusicbot.utils.FormatUtil;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class QueuedTrack implements Queueable {
private final AudioTrack track;
private final String owner;
public QueuedTrack(AudioTrack track, String owner)
{
this.track = track;
this.owner = owner;
}
@Override
public String getIdentifier() {
return owner;
}
public AudioTrack getTrack()
{
return track;
}
@Override
public String toString() {
return "`["+FormatUtil.formatTime(track.getDuration())+"]` **" + track.getInfo().title +"** - <@"+owner+">";
}
}
/*
* 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.audio;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import com.jagrosh.jmusicbot.queue.Queueable;
import com.jagrosh.jmusicbot.utils.FormatUtil;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class QueuedTrack implements Queueable {
private final AudioTrack track;
private final long owner;
public QueuedTrack(AudioTrack track, long owner)
{
this.track = track;
this.owner = owner;
}
@Override
public long getIdentifier() {
return owner;
}
public AudioTrack getTrack()
{
return track;
}
@Override
public String toString() {
return "`["+FormatUtil.formatTime(track.getDuration())+"]` **" + track.getInfo().title +"** - <@"+owner+">";
}
}
@@ -1,48 +1,48 @@
/*
* 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.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import net.dv8tion.jda.core.entities.User;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class ForceskipCmd extends MusicCommand {
public ForceskipCmd(Bot bot)
{
super(bot);
this.name = "forceskip";
this.help = "skips the current song";
this.aliases = new String[]{"modskip"};
this.bePlaying = true;
this.category = bot.DJ;
}
@Override
public void doCommand(CommandEvent event) {
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
User u = event.getJDA().getUserById(handler.getCurrentTrack().getIdentifier());
event.reply(event.getClient().getSuccess()+" Skipped **"+handler.getCurrentTrack().getTrack().getInfo().title
+"** (requested by "+(u==null ? "someone" : "**"+u.getName()+"**")+")");
handler.getPlayer().stopTrack();
}
}
/*
* 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.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import net.dv8tion.jda.core.entities.User;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class ForceskipCmd extends MusicCommand {
public ForceskipCmd(Bot bot)
{
super(bot);
this.name = "forceskip";
this.help = "skips the current song";
this.aliases = new String[]{"modskip"};
this.bePlaying = true;
this.category = bot.DJ;
}
@Override
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();
}
}
@@ -56,7 +56,7 @@ public abstract class MusicCommand extends Command {
}
if(bePlaying
&& (event.getGuild().getAudioManager().getSendingHandler()==null
|| ((AudioHandler)event.getGuild().getAudioManager().getSendingHandler()).getCurrentTrack()==null))
|| !((AudioHandler)event.getGuild().getAudioManager().getSendingHandler()).isMusicPlaying()))
{
event.reply(event.getClient().getError()+" There must be music playing to use that!");
return;
@@ -1,42 +1,79 @@
/*
* 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.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import com.jagrosh.jmusicbot.utils.FormatUtil;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class NowplayingCmd extends MusicCommand {
public NowplayingCmd(Bot bot)
{
super(bot);
this.name = "nowplaying";
this.help = "shows the song that is currently playing";
this.aliases = new String[]{"np","current"};
}
@Override
public void doCommand(CommandEvent event) {
event.reply(FormatUtil.formattedAudio((AudioHandler)event.getGuild().getAudioManager().getSendingHandler(), event.getJDA(), false));
}
}
/*
* 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.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
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.Permission;
import net.dv8tion.jda.core.entities.User;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class NowplayingCmd extends MusicCommand {
public NowplayingCmd(Bot bot)
{
super(bot);
this.name = "nowplaying";
this.help = "shows the song that is currently playing";
this.aliases = new String[]{"np","current"};
this.botPermissions = new Permission[]{Permission.MESSAGE_EMBED_LINKS};
}
@Override
public void doCommand(CommandEvent event) {
EmbedBuilder eb = new EmbedBuilder();
eb.setColor(event.getSelfMember().getColor());
AudioHandler ah = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
if(ah==null || !ah.isMusicPlaying())
{
eb.setTitle("No music playing");
eb.setDescription("\u23F9 "+FormatUtil.progressBar(-1)+" "+FormatUtil.volumeIcon(ah==null?100:ah.getPlayer().getVolume()));
event.reply(eb.build());
return;
}
if(ah.getRequester()!=0)
{
User u = event.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(ah.getPlayer().getPlayingTrack() instanceof YoutubeAudioTrack)
eb.setThumbnail("https://img.youtube.com/vi/"+ah.getPlayer().getPlayingTrack().getIdentifier()+"/maxresdefault.jpg");
eb.setDescription(FormatUtil.embedformattedAudio(ah));
event.reply(eb.build());
}
}
@@ -0,0 +1,50 @@
/*
* 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.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import net.dv8tion.jda.core.entities.User;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class PauseCmd extends MusicCommand {
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) {
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
if(handler.getPlayer().isPaused())
{
event.replyWarning("The player is already paused! Use `"+event.getClient().getPrefix()+"play` to unpause!");
return;
}
handler.getPlayer().setPaused(true);
event.replySuccess("Paused **"+handler.getPlayer().getPlayingTrack().getInfo().title+"**. Type `"+event.getClient().getPrefix()+"play` to unpause!");
}
}
@@ -23,8 +23,10 @@ import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import com.jagrosh.jdautilities.commandclient.Command;
import com.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import com.jagrosh.jmusicbot.playlist.Playlist;
import com.jagrosh.jmusicbot.utils.FormatUtil;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.Message;
/**
@@ -48,6 +50,21 @@ public class PlayCmd extends MusicCommand {
public void doCommand(CommandEvent event) {
if(event.getArgs().isEmpty())
{
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
if(handler!=null && handler.getPlayer().getPlayingTrack()!=null && handler.getPlayer().isPaused())
{
boolean isDJ = event.getMember().hasPermission(Permission.MANAGE_SERVER);
if(!isDJ)
isDJ = event.getMember().getRoles().contains(event.getGuild().getRoleById(bot.getSettings(event.getGuild()).getRoleId()));
if(!isDJ)
event.replyError("Only DJs can unpause the player!");
else
{
handler.getPlayer().setPaused(false);
event.replySuccess("Resumed **"+handler.getPlayer().getPlayingTrack().getInfo().title+"**.");
}
return;
}
StringBuilder builder = new StringBuilder(event.getClient().getWarning()+" Play Commands:\n");
builder.append("\n`").append(event.getClient().getPrefix()).append(name).append(" <song title>` - plays the first result from Youtube");
builder.append("\n`").append(event.getClient().getPrefix()).append(name).append(" <URL>` - plays the provided song, playlist, or stream");
@@ -147,8 +164,8 @@ public class PlayCmd extends MusicCommand {
event.reply(event.getClient().getError()+" I could not find `"+event.getArgs()+".txt` in the Playlists folder.");
return;
}
event.getChannel().sendMessage("\u231A Loading playlist **"+event.getArgs()+"**...").queue(m -> {
playlist.loadTracks(bot.getAudioManager(), () -> {
event.getChannel().sendMessage("\u231A Loading playlist **"+event.getArgs()+"**... ("+playlist.getItems().size()+" items)").queue(m -> {
playlist.loadTracks(bot.getAudioManager(), (at)->bot.queueTrack(event, at), () -> {
StringBuilder builder = new StringBuilder(playlist.getTracks().isEmpty()
? event.getClient().getWarning()+" No tracks were loaded!"
: event.getClient().getSuccess()+" Loaded **"+playlist.getTracks().size()+"** tracks!");
@@ -159,7 +176,6 @@ public class PlayCmd extends MusicCommand {
if(str.length()>2000)
str = str.substring(0,1994)+" (...)";
m.editMessage(str).queue();
playlist.getTracks().forEach(track -> bot.queueTrack(event, track));
});
});
}
@@ -1,84 +1,94 @@
/*
* 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 java.util.concurrent.TimeUnit;
import com.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jdautilities.menu.pagination.PaginatorBuilder;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import com.jagrosh.jmusicbot.audio.QueuedTrack;
import com.jagrosh.jmusicbot.utils.FormatUtil;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.exceptions.PermissionException;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class QueueCmd extends MusicCommand {
private final PaginatorBuilder builder;
public QueueCmd(Bot bot)
{
super(bot);
this.name = "queue";
this.help = "shows the current queue";
this.arguments = "[pagenum]";
this.aliases = new String[]{"list"};
this.bePlaying = true;
this.botPermissions = new Permission[]{Permission.MESSAGE_ADD_REACTION,Permission.MESSAGE_EMBED_LINKS};
builder = new PaginatorBuilder()
.setColumns(1)
.setFinalAction(m -> {try{m.clearReactions().queue();}catch(PermissionException e){}})
.setItemsPerPage(10)
.waitOnSinglePage(false)
.useNumberedItems(true)
.showPageNumbers(true)
.setEventWaiter(bot.getWaiter())
.setTimeout(1, TimeUnit.MINUTES)
;
}
@Override
public void doCommand(CommandEvent event) {
int pagenum = 1;
try{
pagenum = Integer.parseInt(event.getArgs());
}catch(NumberFormatException e){}
List<QueuedTrack> list = ((AudioHandler)event.getGuild().getAudioManager().getSendingHandler()).getQueue().getList();
if(list.isEmpty())
{
event.reply(event.getClient().getWarning()+" There is no music in the queue!");
return;
}
String[] songs = new String[list.size()];
long total = 0;
for(int i=0; i<list.size(); i++)
{
total += list.get(i).getTrack().getDuration();
songs[i] = list.get(i).toString();
}
builder.setText(event.getClient().getSuccess()+" Current Queue | "+songs.length+" entries | `"+FormatUtil.formatTime(total)+"` ")
.setItems(songs)
.setUsers(event.getAuthor())
.setColor(event.getSelfMember().getColor())
;
builder.build().paginate(event.getChannel(), pagenum);
}
}
/*
* 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 java.util.concurrent.TimeUnit;
import com.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jdautilities.menu.pagination.PaginatorBuilder;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
import com.jagrosh.jmusicbot.audio.QueuedTrack;
import com.jagrosh.jmusicbot.utils.FormatUtil;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.exceptions.PermissionException;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class QueueCmd extends MusicCommand {
private final PaginatorBuilder builder;
public QueueCmd(Bot bot)
{
super(bot);
this.name = "queue";
this.help = "shows the current queue";
this.arguments = "[pagenum]";
this.aliases = new String[]{"list"};
this.bePlaying = true;
this.botPermissions = new Permission[]{Permission.MESSAGE_ADD_REACTION,Permission.MESSAGE_EMBED_LINKS};
builder = new PaginatorBuilder()
.setColumns(1)
.setFinalAction(m -> {try{m.clearReactions().queue();}catch(PermissionException e){}})
.setItemsPerPage(10)
.waitOnSinglePage(false)
.useNumberedItems(true)
.showPageNumbers(true)
.setEventWaiter(bot.getWaiter())
.setTimeout(1, TimeUnit.MINUTES)
;
}
@Override
public void doCommand(CommandEvent event) {
int pagenum = 1;
try{
pagenum = Integer.parseInt(event.getArgs());
}catch(NumberFormatException e){}
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.embedformattedAudio(ah)));
return;
}
String[] songs = new String[list.size()];
long total = 0;
for(int i=0; i<list.size(); i++)
{
total += list.get(i).getTrack().getDuration();
songs[i] = list.get(i).toString();
}
long fintotal = total;
builder.setText((i1,i2) -> getQueueTitle(ah, event.getClient().getSuccess(), songs.length, fintotal))
.setItems(songs)
.setUsers(event.getAuthor())
.setColor(event.getSelfMember().getColor())
;
builder.build().paginate(event.getChannel(), pagenum);
}
private String getQueueTitle(AudioHandler ah, String success, int songslength, long total)
{
StringBuilder sb = new StringBuilder();
if(ah.getPlayer().getPlayingTrack()!=null)
sb.append("**").append(ah.getPlayer().getPlayingTrack().getInfo().title).append("**\n").append(FormatUtil.embedformattedAudio(ah)).append("\n\n");
return sb.append(success).append(" Current Queue | ").append(songslength).append(" entries | `").append(FormatUtil.formatTime(total)).append("` ").toString();
}
}
@@ -21,7 +21,6 @@ import com.jagrosh.jmusicbot.audio.AudioHandler;
import com.jagrosh.jmusicbot.audio.QueuedTrack;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.User;
import net.dv8tion.jda.core.utils.PermissionUtil;
/**
*
@@ -50,7 +49,7 @@ public class RemoveCmd extends MusicCommand {
}
if(event.getArgs().equalsIgnoreCase("all"))
{
int count = handler.getQueue().removeAll(event.getAuthor().getId());
int count = handler.getQueue().removeAll(event.getAuthor().getIdLong());
if(count==0)
event.reply(event.getClient().getWarning()+" You don't have any songs in the queue!");
else
@@ -68,11 +67,11 @@ public class RemoveCmd extends MusicCommand {
event.reply(event.getClient().getError()+" Position must be a valid integer between 1 and "+handler.getQueue().size()+"!");
return;
}
boolean isDJ = PermissionUtil.checkPermission(event.getGuild(), event.getMember(), Permission.MANAGE_SERVER);
boolean isDJ = event.getMember().hasPermission(Permission.MANAGE_SERVER);
if(!isDJ)
isDJ = event.getMember().getRoles().contains(event.getGuild().getRoleById(bot.getSettings(event.getGuild()).getRoleId()));
QueuedTrack qt = handler.getQueue().get(pos-1);
if(qt.getIdentifier().equals(event.getAuthor().getId()))
if(qt.getIdentifier()==event.getAuthor().getIdLong())
{
handler.getQueue().remove(pos-1);
event.reply(event.getClient().getSuccess()+" Removed **"+qt.getTrack().getInfo().title+"** from the queue");
@@ -80,7 +79,12 @@ public class RemoveCmd extends MusicCommand {
else if(isDJ)
{
handler.getQueue().remove(pos-1);
User u = event.getJDA().getUserById(qt.getIdentifier());
User u;
try {
u = event.getJDA().getUserById(qt.getIdentifier());
} catch(Exception e) {
u = null;
}
event.reply(event.getClient().getSuccess()+" Removed **"+qt.getTrack().getInfo().title
+"** from the queue (requested by "+(u==null ? "someone" : "**"+u.getName()+"**")+")");
}
@@ -1,69 +1,69 @@
/*
* 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.commandclient.Command;
import com.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.utils.FinderUtil;
import com.jagrosh.jmusicbot.utils.FormatUtil;
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)
{
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) {
if(event.getArgs().isEmpty())
{
event.reply(event.getClient().getError()+" Please include a role name or NONE");
}
else if(event.getArgs().equalsIgnoreCase("none"))
{
bot.clearTextChannel(event.getGuild());
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());
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));
event.reply(event.getClient().getSuccess()+" DJ commands can now be used by users with the **"+list.get(0).getName()+"** role.");
}
}
}
}
/*
* 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.commandclient.Command;
import com.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.utils.FinderUtil;
import com.jagrosh.jmusicbot.utils.FormatUtil;
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)
{
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) {
if(event.getArgs().isEmpty())
{
event.reply(event.getClient().getError()+" Please include a role name or NONE");
}
else if(event.getArgs().equalsIgnoreCase("none"))
{
bot.clearRole(event.getGuild());
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());
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));
event.reply(event.getClient().getSuccess()+" DJ commands can now be used by users with the **"+list.get(0).getName()+"** role.");
}
}
}
}
@@ -0,0 +1,56 @@
/*
* 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.commandclient.Command;
import com.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import net.dv8tion.jda.core.OnlineStatus;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class SetstatusCmd extends Command {
public SetstatusCmd(Bot bot)
{
this.name = "setstatus";
this.help = "sets the status the bot displays";
this.arguments = "[game]";
this.ownerCommand = true;
this.category = bot.OWNER;
}
@Override
protected void execute(CommandEvent event) {
try {
OnlineStatus status = OnlineStatus.fromKey(event.getArgs());
if(status==OnlineStatus.UNKNOWN)
{
event.replyError("Please include one of the following statuses: `ONLINE`, `IDLE`, `DND`, `INVISIBLE`");
}
else
{
event.getJDA().getPresence().setStatus(status);
event.replySuccess("Set the status to `"+status.getKey().toUpperCase()+"`");
}
} catch(Exception e) {
event.reply(event.getClient().getError()+" The status could not be set!");
}
}
}
@@ -1,54 +1,54 @@
/*
* 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.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class ShuffleCmd extends MusicCommand {
public ShuffleCmd(Bot bot)
{
super(bot);
this.name = "shuffle";
this.help = "shuffles songs you have added";
this.beListening = true;
this.bePlaying = true;
}
@Override
public void doCommand(CommandEvent event) {
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
int s = handler.getQueue().shuffle(event.getAuthor().getId());
switch (s) {
case 0:
event.reply(event.getClient().getError()+" 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!");
break;
default:
event.reply(event.getClient().getSuccess()+" You successfully shuffled your "+s+" entries.");
break;
}
}
}
/*
* 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.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class ShuffleCmd extends MusicCommand {
public ShuffleCmd(Bot bot)
{
super(bot);
this.name = "shuffle";
this.help = "shuffles songs you have added";
this.beListening = true;
this.bePlaying = true;
}
@Override
public void doCommand(CommandEvent event) {
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
int s = handler.getQueue().shuffle(event.getAuthor().getIdLong());
switch (s) {
case 0:
event.reply(event.getClient().getError()+" 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!");
break;
default:
event.reply(event.getClient().getSuccess()+" You successfully shuffled your "+s+" entries.");
break;
}
}
}
@@ -39,10 +39,9 @@ public class SkipCmd extends MusicCommand {
@Override
public void doCommand(CommandEvent event) {
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
if(event.getAuthor().getId().equals(handler.getCurrentTrack().getIdentifier()))
if(event.getAuthor().getIdLong()==handler.getRequester())
{
event.reply(event.getClient().getSuccess()+" Skipped **"+handler.getCurrentTrack().getTrack().getInfo().title
+"**");
event.reply(event.getClient().getSuccess()+" Skipped **"+handler.getPlayer().getPlayingTrack().getInfo().title+"**");
handler.getPlayer().stopTrack();
}
else
@@ -63,9 +62,9 @@ public class SkipCmd extends MusicCommand {
msg+= skippers+" votes, "+required+"/"+listeners+" needed]`";
if(skippers>=required)
{
User u = event.getJDA().getUserById(handler.getCurrentTrack().getIdentifier());
msg+="\n"+event.getClient().getSuccess()+" Skipped **"+handler.getCurrentTrack().getTrack().getInfo().title
+"**"+(handler.getCurrentTrack().getIdentifier()==null ? "" : " (requested by "+(u==null ? "someone" : "**"+u.getName()+"**")+")");
User u = event.getJDA().getUserById(handler.getRequester());
msg+="\n"+event.getClient().getSuccess()+" Skipped **"+handler.getPlayer().getPlayingTrack().getInfo().title
+"**"+(handler.getRequester()==0 ? "" : " (requested by "+(u==null ? "someone" : "**"+u.getName()+"**")+")");
handler.getPlayer().stopTrack();
}
event.reply(msg);
@@ -1,46 +1,45 @@
/*
* 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.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class StopCmd extends MusicCommand {
public StopCmd(Bot bot)
{
super(bot);
this.name = "stop";
this.help = "stops the current song and clears the queue";
this.bePlaying = true;
this.category = bot.DJ;
}
@Override
public void doCommand(CommandEvent event) {
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
handler.getQueue().clear();
handler.getPlayer().stopTrack();
event.getGuild().getAudioManager().closeAudioConnection();
event.reply(event.getClient().getSuccess()+" The player has stopped and the queue has been cleared.");
}
}
/*
* 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.jagrosh.jdautilities.commandclient.CommandEvent;
import com.jagrosh.jmusicbot.Bot;
import com.jagrosh.jmusicbot.audio.AudioHandler;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public class StopCmd extends MusicCommand {
public StopCmd(Bot bot)
{
super(bot);
this.name = "stop";
this.help = "stops the current song and clears the queue";
this.bePlaying = true;
this.category = bot.DJ;
}
@Override
public void doCommand(CommandEvent event) {
AudioHandler handler = (AudioHandler)event.getGuild().getAudioManager().getSendingHandler();
handler.stopAndClear();
event.getGuild().getAudioManager().closeAudioConnection();
event.reply(event.getClient().getSuccess()+" The player has stopped and the queue has been cleared.");
}
}
@@ -1,111 +1,111 @@
/*
* 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();
}
}
/*
* 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();
}*/
}
@@ -5,6 +5,7 @@
*/
package com.jagrosh.jmusicbot.playlist;
import com.jagrosh.jmusicbot.Bot;
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
@@ -14,9 +15,11 @@ 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;
/**
@@ -29,14 +32,16 @@ public class Playlist {
private final List<String> items;
private List<AudioTrack> tracks;
private List<PlaylistLoadError> errors;
private final boolean shuffle;
private Playlist(String name, List<String> items)
private Playlist(String name, List<String> items, boolean shuffle)
{
this.name = name;
this.items = items;
this.shuffle = shuffle;
}
public void loadTracks(AudioPlayerManager manager, Runnable callback)
public void loadTracks(AudioPlayerManager manager, Consumer<AudioTrack> consumer, Runnable callback)
{
if(tracks==null)
{
@@ -50,33 +55,64 @@ public class Playlist {
@Override
public void trackLoaded(AudioTrack at) {
tracks.add(at);
if(last && callback!=null)
callback.run();
consumer.accept(at);
if(last)
{
if(callback!=null)
callback.run();
}
}
@Override
public void playlistLoaded(AudioPlaylist ap) {
if(ap.isSearchResult())
{
tracks.add(ap.getTracks().get(0));
consumer.accept(ap.getTracks().get(0));
}
else if(ap.getSelectedTrack()!=null)
{
tracks.add(ap.getSelectedTrack());
consumer.accept(ap.getSelectedTrack());
}
else
tracks.addAll(ap.getTracks());
if(last && callback!=null)
callback.run();
{
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);
}
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 && callback!=null)
callback.run();
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 && callback!=null)
callback.run();
if(last)
{
if(callback!=null)
callback.run();
}
}
});
}
@@ -98,6 +134,20 @@ public class Playlist {
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;
@@ -138,11 +188,32 @@ public class Playlist {
{
if(folderExists())
{
return new Playlist(name, Files.readAllLines(Paths.get("Playlists"+File.separator+name+".txt"))
.stream()
.map((str) -> str.trim())
.filter((s) -> (!s.isEmpty() && !s.startsWith("#") && !s.startsWith("//")))
.collect(Collectors.toList()));
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
{
@@ -27,13 +27,13 @@ import java.util.Set;
*/
public class FairQueue<T extends Queueable> {
private final List<T> list = new ArrayList<>();
private final Set<String> set = new HashSet<>();
private final Set<Long> set = new HashSet<>();
public int add(T item)
{
int lastIndex;
for(lastIndex=list.size()-1; lastIndex>-1; lastIndex--)
if(list.get(lastIndex).getIdentifier().equals(item.getIdentifier()))
if(list.get(lastIndex).getIdentifier()==item.getIdentifier())
break;
lastIndex++;
set.clear();
@@ -77,12 +77,12 @@ public class FairQueue<T extends Queueable> {
return list.remove(index);
}
public int removeAll(String identifier)
public int removeAll(long identifier)
{
int count = 0;
for(int i=list.size()-1; i>=0; i--)
{
if(list.get(i).getIdentifier().equals(identifier))
if(list.get(i).getIdentifier()==identifier)
{
list.remove(i);
count++;
@@ -96,12 +96,12 @@ public class FairQueue<T extends Queueable> {
list.clear();
}
public int shuffle(String identifier)
public int shuffle(long identifier)
{
List<Integer> iset = new ArrayList<>();
for(int i=0; i<list.size(); i++)
{
if(list.get(i).getIdentifier().equals(identifier))
if(list.get(i).getIdentifier()==identifier)
iset.add(i);
}
for(int j=0; j<iset.size(); j++)
@@ -1,25 +1,25 @@
/*
* 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.queue;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public interface Queueable {
public String getIdentifier();
}
/*
* 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.queue;
/**
*
* @author John Grosh <john.a.grosh@gmail.com>
*/
public interface Queueable {
public long getIdentifier();
}
@@ -1,140 +1,156 @@
/*
* 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 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);
}
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 tc = guild.getJDA().getVoiceChannelById(id);
if(tc!=null && tc.getGuild().equals(guild))
return Collections.singletonList(tc);
}
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((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<Role> findRole(String query, Guild guild)
{
String id;
if(query.matches("<@&\\d+>"))
{
id = query.replaceAll("<@&(\\d+)>", "$1");
Role role = guild.getRoleById(id);
if(role!=null)
return Collections.singletonList(role);
}
if(query.matches("[Ii][Dd]\\s*:\\s*\\d+"))
{
id = query.replaceAll("[Ii][Dd]\\s*:\\s*(\\d+)", "$1");
for(Role role: guild.getRoles())
if(role.getId().equals(id))
return Collections.singletonList(role);
}
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;
}
}
/*
* 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;
}
}
@@ -30,6 +30,8 @@ import net.dv8tion.jda.core.entities.VoiceChannel;
*/
public class FormatUtil {
public static boolean NO_PROGRESS_BAR_IN_TOPIC = false;
public static String formatTime(long duration)
{
if(duration == Long.MAX_VALUE)
@@ -42,30 +44,37 @@ public class FormatUtil {
return (hours>0 ? hours+":" : "") + (minutes<10 ? "0"+minutes : minutes) + ":" + (seconds<10 ? "0"+seconds : seconds);
}
public static String formattedAudio(AudioHandler handler, JDA jda, boolean inTopic)
public static String formattedAudio(AudioHandler handler, JDA jda)
{
if(handler==null)
return "No music playing\n\u23F9 "+progressBar(-1)+" "+volumeIcon(100);
else if (handler.getCurrentTrack()==null)
else if (!handler.isMusicPlaying())
return "No music playing\n\u23F9 "+progressBar(-1)+" "+volumeIcon(handler.getPlayer().getVolume());
else
{
String userid = handler.getCurrentTrack().getIdentifier();
User user = jda.getUserById(userid);
AudioTrack track = handler.getCurrentTrack().getTrack();
long userid = handler.getRequester();
AudioTrack track = handler.getPlayer().getPlayingTrack();
String title = track.getInfo().title;
if(inTopic && title.length()>30)
if(!NO_PROGRESS_BAR_IN_TOPIC && title.length()>30)
title = title.substring(0,27)+"...";
double progress = (double)track.getPosition()/track.getDuration();
String str = "**"+title+"** ["+(user==null||inTopic ? (userid==null ? "autoplay" : "<@"+userid+">") : user.getName())+"]\n\u25B6 "+progressBar(progress)
+" "+(inTopic ? "" : "`")+"["+formatTime(track.getPosition()) + "/" + formatTime(track.getDuration())
+"]"+(inTopic ? "" : "`")+" " +volumeIcon(handler.getPlayer().getVolume())
+(inTopic ? "" : "\n**<"+track.getInfo().uri+">**");
return str;
String str = "**"+title+"** ["+(userid==0 ? "autoplay" : "<@"+userid+">")+"]";
String str2 = "\n"+(handler.getPlayer().isPaused()?"\u23F8":"\u25B6")+" "
+(NO_PROGRESS_BAR_IN_TOPIC ? "["+formatTime(track.getDuration())+"] " :
progressBar(progress)+" ["+formatTime(track.getPosition()) + "/" + formatTime(track.getDuration())+"] ")
+volumeIcon(handler.getPlayer().getVolume());
return str+str2;
}
}
private static String progressBar(double percent)
public static String embedformattedAudio(AudioHandler ah)
{
return (ah.getPlayer().isPaused()?"\u23F8":"\u25B6")+" "+progressBar((double)ah.getPlayer().getPlayingTrack().getPosition()/ah.getPlayer().getPlayingTrack().getDuration())
+" `["+formatTime(ah.getPlayer().getPlayingTrack().getPosition()) + "/" + formatTime(ah.getPlayer().getPlayingTrack().getDuration()) +"]` "
+volumeIcon(ah.getPlayer().getVolume());
}
public static String progressBar(double percent)
{
String str = "";
for(int i=0; i<8; i++)