Finalized Zino's changes, and many other things.
* added broadcast command * added interface for distinguishing command line commands * added button to switch from english to dutch (work in progress) * fixed playlist viewer and now uses list models.
This commit is contained in:
parent
b842ce17c2
commit
117254e27d
|
@ -30,7 +30,9 @@ import java.util.*;
|
|||
*/
|
||||
public class HandieBot {
|
||||
|
||||
//Application name is the name of application as it appears on display window.
|
||||
public static final String APPLICATION_NAME = "HandieBot";
|
||||
//The token required for logging into Discord. This is secure and must not be in the source code on GitHub.
|
||||
private static final String TOKEN;
|
||||
static {
|
||||
TOKEN = readToken();
|
||||
|
@ -39,15 +41,16 @@ public class HandieBot {
|
|||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
//Variable to enable or disable GUI.
|
||||
private static boolean USE_GUI = true;
|
||||
|
||||
public static final ResourceBundle resourceBundle = ResourceBundle.getBundle("Strings");
|
||||
//Resource bundle for localized strings.
|
||||
public static ResourceBundle resourceBundle = ResourceBundle.getBundle("Strings");
|
||||
|
||||
//Discord client object.
|
||||
public static IDiscordClient client;
|
||||
|
||||
//Display objects.
|
||||
private static BotWindow window;
|
||||
public static BotWindow window;
|
||||
public static BotLog log;
|
||||
|
||||
//The cross-guild music player.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package handiebot.command;
|
||||
|
||||
import handiebot.command.commands.admin.BroadcastCommand;
|
||||
import handiebot.command.commands.admin.QuitCommand;
|
||||
import handiebot.command.commands.admin.SetPrefixCommand;
|
||||
import handiebot.command.commands.misc.TengwarCommand;
|
||||
|
@ -42,6 +43,7 @@ public class Commands {
|
|||
commands.add(new InfoCommand());
|
||||
commands.add(new SetPrefixCommand());
|
||||
commands.add(new QuitCommand());
|
||||
commands.add(new BroadcastCommand());
|
||||
commands.add(new TengwarCommand());
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package handiebot.command.commands.admin;
|
||||
|
||||
import handiebot.command.CommandContext;
|
||||
import handiebot.command.types.CommandLineCommand;
|
||||
import handiebot.command.types.ContextCommand;
|
||||
import handiebot.utils.MessageUtils;
|
||||
import sx.blah.discord.handle.obj.IGuild;
|
||||
|
||||
import static handiebot.HandieBot.*;
|
||||
import static handiebot.utils.MessageUtils.sendMessage;
|
||||
|
||||
/**
|
||||
* @author Andrew Lalis
|
||||
* Command to broadcast a message to all guilds the bot is connected to.
|
||||
*/
|
||||
public class BroadcastCommand extends ContextCommand implements CommandLineCommand {
|
||||
|
||||
public BroadcastCommand() {
|
||||
super("broadcast",
|
||||
"<message>",
|
||||
resourceBundle.getString("commands.command.broadcast.description"),
|
||||
8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandContext context) {
|
||||
String message = MessageUtils.getTextFromArgs(context.getArgs(), 0);
|
||||
for (IGuild guild : client.getGuilds()){
|
||||
sendMessage(message, musicPlayer.getChatChannel(guild));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package handiebot.command.commands.admin;
|
||||
|
||||
import handiebot.HandieBot;
|
||||
import handiebot.command.types.CommandLineCommand;
|
||||
import handiebot.command.types.StaticCommand;
|
||||
|
||||
import static handiebot.HandieBot.resourceBundle;
|
||||
|
@ -9,7 +10,7 @@ import static handiebot.HandieBot.resourceBundle;
|
|||
* @author Andrew Lalis
|
||||
* Command to quit the entire bot. This shuts down every guild's support, and the GUI.
|
||||
*/
|
||||
public class QuitCommand extends StaticCommand {
|
||||
public class QuitCommand extends StaticCommand implements CommandLineCommand {
|
||||
|
||||
public QuitCommand() {
|
||||
super("quit",
|
||||
|
|
|
@ -20,8 +20,7 @@ import java.text.MessageFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static handiebot.HandieBot.log;
|
||||
import static handiebot.HandieBot.resourceBundle;
|
||||
import static handiebot.HandieBot.*;
|
||||
import static handiebot.utils.MessageUtils.sendMessage;
|
||||
import static handiebot.utils.YoutubeSearch.WATCH_URL;
|
||||
|
||||
|
@ -101,13 +100,16 @@ public class PlaylistCommand extends ContextCommand {
|
|||
if (context.getArgs().length >= 2) {
|
||||
Playlist playlist = new Playlist(context.getArgs()[1]);
|
||||
playlist.save();
|
||||
for (int i = 2; i < context.getArgs().length; i++){
|
||||
String url = context.getArgs()[i];
|
||||
playlist.loadTrack(url);
|
||||
if (context.getArgs().length > 2) {
|
||||
for (int i = 2; i < context.getArgs().length; i++) {
|
||||
String url = context.getArgs()[i];
|
||||
playlist.loadTrack(url);
|
||||
}
|
||||
playlist.save();
|
||||
}
|
||||
playlist.save();
|
||||
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.createdPlaylist.log"), playlist.getName(), playlist.getTrackCount()));
|
||||
sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.createdPlaylist.message"), playlist.getName(), this.getPrefixedName(context.getGuild()), playlist.getName()), context.getChannel());
|
||||
window.updatePlaylistNames();//Refresh the list of names in the GUI.
|
||||
} else {
|
||||
sendMessage(resourceBundle.getString("commands.command.playlist.error.createPlaylistName"), context.getChannel());
|
||||
}
|
||||
|
@ -126,6 +128,7 @@ public class PlaylistCommand extends ContextCommand {
|
|||
if (success){
|
||||
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.delete.log"), context.getArgs()[1]));
|
||||
sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.delete.message"), context.getArgs()[1]), context.getChannel());
|
||||
window.updatePlaylistNames();//Refresh the list of names in the GUI.
|
||||
} else {
|
||||
log.log(BotLog.TYPE.ERROR, MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.delete.log"), context.getArgs()[1]));
|
||||
sendMessage(resourceBundle.getString("commands.command.playlist.error.delete.message"), context.getChannel());
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package handiebot.command.types;
|
||||
|
||||
/**
|
||||
* @author Andrew Lalis
|
||||
* If a command implements this Interface, it is marked as safe to use in the command line.
|
||||
*/
|
||||
public interface CommandLineCommand {
|
||||
}
|
|
@ -8,6 +8,6 @@ import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.Reactio
|
|||
*/
|
||||
public interface ReactionListener {
|
||||
|
||||
public void onReactionEvent(ReactionEvent event);
|
||||
void onReactionEvent(ReactionEvent event);
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import static handiebot.HandieBot.resourceBundle;
|
|||
* on the playlist.
|
||||
*/
|
||||
public class Playlist {
|
||||
|
||||
//TODO: Externalize strings.
|
||||
private String name;
|
||||
|
||||
private List<UnloadedTrack> tracks;
|
||||
|
@ -119,7 +119,7 @@ public class Playlist {
|
|||
* @param listLength The number of items in a potential list to choose from.
|
||||
* @return A pseudo-random choice as to which item to pick from the list.
|
||||
*/
|
||||
public static int getShuffledIndex(int listLength){
|
||||
private static int getShuffledIndex(int listLength){
|
||||
float threshold = 0.2f;
|
||||
int trueLength = listLength - (int)(threshold*(float)listLength);
|
||||
Random rand = new Random();
|
||||
|
@ -160,13 +160,11 @@ public class Playlist {
|
|||
*/
|
||||
public void load(){
|
||||
String path = System.getProperty("user.home")+"/.handiebot/playlist/"+name.replace(" ", "_")+".txt";
|
||||
log.log(BotLog.TYPE.MUSIC, "Loading playlist from: "+path);
|
||||
File playlistFile = new File(path);
|
||||
if (playlistFile.exists()){
|
||||
try {
|
||||
List<String> lines = Files.readAllLines(Paths.get(playlistFile.toURI()));
|
||||
int trackCount = Integer.parseInt(lines.remove(0));
|
||||
this.name = name;
|
||||
this.tracks = new ArrayList<>(trackCount);
|
||||
for (int i = 0; i < trackCount; i++){
|
||||
String[] words = lines.remove(0).split(" / ");
|
||||
|
|
|
@ -2,7 +2,6 @@ package handiebot.view;
|
|||
|
||||
import handiebot.HandieBot;
|
||||
import handiebot.lavaplayer.playlist.Playlist;
|
||||
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
|
@ -30,6 +29,7 @@ public class BotWindow extends JFrame {
|
|||
private JList<String> playlistNamesList;
|
||||
private JList<String> currentPlaylistList;
|
||||
private ListSelectionListener playlistListener;
|
||||
private JPanel playlistDisplayPanel;
|
||||
|
||||
public BotWindow(){
|
||||
super(HandieBot.APPLICATION_NAME);
|
||||
|
@ -37,6 +37,7 @@ public class BotWindow extends JFrame {
|
|||
//Output area.
|
||||
outputArea = new JTextPane();
|
||||
outputArea.setBackground(Color.white);
|
||||
outputArea.setEditable(false);
|
||||
JScrollPane scrollPane = new JScrollPane();
|
||||
scrollPane.setViewportView(outputArea);
|
||||
scrollPane.setAutoscrolls(true);
|
||||
|
@ -49,24 +50,24 @@ public class BotWindow extends JFrame {
|
|||
this.playlistNamesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
this.currentPlaylistList = new JList<>(this.currentPlaylistModel);
|
||||
this.currentPlaylistList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
this.playlistListener = e -> {
|
||||
System.out.println("user updated list.");
|
||||
updatePlaylistData();
|
||||
};
|
||||
this.playlistNamesList.addListSelectionListener(this.playlistListener);
|
||||
updatePlaylistData();
|
||||
|
||||
JPanel playlistDisplayPanel = new JPanel(new BorderLayout());
|
||||
updatePlaylistNames();
|
||||
this.playlistNamesList.addListSelectionListener(new PlaylistSelectionListener(this.currentPlaylistModel));
|
||||
|
||||
//Song names scroll pane.
|
||||
JScrollPane songNamesScrollPane = new JScrollPane(this.currentPlaylistList);
|
||||
songNamesScrollPane.setPreferredSize(new Dimension(250, 200));
|
||||
playlistDisplayPanel.add(songNamesScrollPane, BorderLayout.PAGE_END);
|
||||
//Create the panel to hold both of the sub-panels.
|
||||
playlistDisplayPanel = new JPanel();
|
||||
playlistDisplayPanel.setPreferredSize(new Dimension(250, 0));
|
||||
playlistDisplayPanel.setLayout(new BorderLayout());
|
||||
|
||||
//Playlist name scroll pane.
|
||||
JScrollPane playlistNamesScrollPane = new JScrollPane(playlistNamesList);
|
||||
playlistNamesScrollPane.setPreferredSize(new Dimension(250, 1000));
|
||||
playlistDisplayPanel.add(playlistNamesScrollPane, BorderLayout.CENTER);
|
||||
playlistNamesScrollPane.setColumnHeaderView(new JLabel("Playlists"));
|
||||
playlistDisplayPanel.add(playlistNamesScrollPane, BorderLayout.PAGE_START);
|
||||
|
||||
//Song names scroll pane.
|
||||
JScrollPane songNamesScrollPane = new JScrollPane(this.currentPlaylistList);
|
||||
songNamesScrollPane.setColumnHeaderView(new JLabel("Selected Playlist"));
|
||||
playlistDisplayPanel.add(songNamesScrollPane, BorderLayout.CENTER);
|
||||
|
||||
getContentPane().add(playlistDisplayPanel, BorderLayout.EAST);
|
||||
|
||||
|
@ -99,7 +100,6 @@ public class BotWindow extends JFrame {
|
|||
e.printStackTrace();
|
||||
}
|
||||
setJMenuBar(new MenuBar(this));
|
||||
//SelectionController controller = new SelectionController();
|
||||
setPreferredSize(new Dimension(800, 600));
|
||||
pack();
|
||||
setLocationRelativeTo(null);
|
||||
|
@ -107,50 +107,21 @@ public class BotWindow extends JFrame {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the playlist data in the window.
|
||||
* Updates the list of playlist names.
|
||||
*/
|
||||
private void updatePlaylistData() {
|
||||
public void updatePlaylistNames(){
|
||||
List<String> playlistNames = Playlist.getAvailablePlaylists();
|
||||
this.playlistNamesList.removeListSelectionListener(this.playlistListener);
|
||||
this.playlistNamesModel.clear();
|
||||
for (String name : playlistNames){
|
||||
this.playlistNamesModel.addElement(name);
|
||||
}
|
||||
this.playlistNamesList.addListSelectionListener(this.playlistListener);
|
||||
String selectedValue = this.playlistNamesList.getSelectedValue();
|
||||
System.out.println("selected value: "+selectedValue);
|
||||
if (selectedValue != null && Playlist.playlistExists(selectedValue)){
|
||||
Playlist playlist = new Playlist(selectedValue);
|
||||
playlist.load();
|
||||
List<UnloadedTrack> tracks = playlist.getTracks();
|
||||
this.currentPlaylistModel.clear();
|
||||
for (int i = 0; i < playlist.getTrackCount(); i++){
|
||||
this.currentPlaylistModel.addElement(tracks.get(i).getTitle());
|
||||
}
|
||||
}
|
||||
/*
|
||||
this.playlistNamesList.addListSelectionListener(e -> {
|
||||
String name = playlistNamesList.getSelectedValue();
|
||||
String path = System.getProperty("user.home") + "/.handiebot/playlist/" + name + ".txt";
|
||||
File playlistFile = new File(path);
|
||||
if (playlistFile.exists()) {
|
||||
try {
|
||||
List<String> lines = Files.readAllLines(Paths.get(playlistFile.toURI()));
|
||||
int trackCount = Integer.parseInt(lines.remove(0));
|
||||
String[] words = {"A"};
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i1 = 0; i1 < trackCount; i1++) {
|
||||
words = lines.remove(0).split(" / ");
|
||||
sb.append(i1 +1).append(". ").append(words[0]).append("\n");
|
||||
}
|
||||
if(!words[0].equals("A")) {
|
||||
pane.setText(sb.toString());
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
}
|
||||
});*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the playlists panel as visible or invisible.
|
||||
*/
|
||||
public void togglePlaylistsVisibility(){
|
||||
this.playlistDisplayPanel.setVisible(!this.playlistDisplayPanel.isVisible());
|
||||
}
|
||||
|
||||
public JTextPane getOutputArea(){
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
package handiebot.view;
|
||||
|
||||
import handiebot.command.Commands;
|
||||
import handiebot.HandieBot;
|
||||
import handiebot.command.CommandContext;
|
||||
import handiebot.command.types.Command;
|
||||
import handiebot.command.types.CommandLineCommand;
|
||||
import handiebot.command.types.ContextCommand;
|
||||
import handiebot.command.types.StaticCommand;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
|
||||
import static handiebot.HandieBot.log;
|
||||
import static handiebot.command.Commands.commands;
|
||||
|
||||
/**
|
||||
* @author Andrew Lalis
|
||||
* Class to listen for commands from the console command line.
|
||||
|
@ -26,7 +34,7 @@ public class CommandLineListener implements KeyListener {
|
|||
String command = words[0];
|
||||
String[] args = new String[words.length-1];
|
||||
System.arraycopy(words, 1, args, 0, words.length - 1);
|
||||
executeCommand(command, args);
|
||||
executeCommand(command, new CommandContext(HandieBot.client.getOurUser(), null, null, args));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,15 +43,21 @@ public class CommandLineListener implements KeyListener {
|
|||
}
|
||||
|
||||
/**
|
||||
* Executes a given command on the command line.
|
||||
* Executes a given command on the command line. This must be written separate from the {@code executeCommand}
|
||||
* method in {@code Commands}, because here, no permissions may be checked.
|
||||
* @param command The first word typed, or the command itself.
|
||||
* @param args The list of arguments for the command.
|
||||
* @param context The list of arguments for the command.
|
||||
*/
|
||||
private void executeCommand(String command, String[] args) {
|
||||
switch (command) {
|
||||
case "quit":
|
||||
Commands.executeCommand("quit", null);
|
||||
break;
|
||||
private void executeCommand(String command, CommandContext context) {
|
||||
for (Command cmd : commands){
|
||||
if (cmd.getName().equals(command) && (cmd instanceof CommandLineCommand)){
|
||||
log.log(BotLog.TYPE.COMMAND, "Command issued: "+command);
|
||||
if (cmd instanceof StaticCommand){
|
||||
((StaticCommand) cmd).execute();
|
||||
} else if (cmd instanceof ContextCommand){
|
||||
((ContextCommand) cmd).execute(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import handiebot.view.actions.ActionItem;
|
|||
import handiebot.view.actions.CommandAction;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import static handiebot.HandieBot.resourceBundle;
|
||||
|
||||
|
@ -13,7 +15,7 @@ import static handiebot.HandieBot.resourceBundle;
|
|||
* Custom menu bar to be added to the console control panel.
|
||||
*/
|
||||
public class MenuBar extends JMenuBar {
|
||||
|
||||
//TODO: Implement a way to restart the program in nederlands.
|
||||
private BotWindow window;
|
||||
private int language;
|
||||
|
||||
|
@ -24,6 +26,10 @@ public class MenuBar extends JMenuBar {
|
|||
this.add(fileMenu);
|
||||
JMenu viewMenu = new JMenu(resourceBundle.getString("menu.viewMenu.view"));
|
||||
JMenu language = new JMenu(resourceBundle.getString("menu.viewMenu.language"));
|
||||
language.add(new ActionItem(resourceBundle.getString("menu.viewMenu.language.english"), e -> resourceBundle = ResourceBundle.getBundle("Strings", Locale.US)));
|
||||
language.add(new ActionItem(resourceBundle.getString("menu.viewMenu.language.dutch"), e -> resourceBundle = ResourceBundle.getBundle("Strings", Locale.forLanguageTag("nl"))));
|
||||
viewMenu.add(language);
|
||||
viewMenu.add(new ActionItem(resourceBundle.getString("menu.viewMenu.playlistsVisible"), e -> window.togglePlaylistsVisibility()));
|
||||
this.add(viewMenu);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
package handiebot.view;
|
||||
|
||||
import handiebot.lavaplayer.playlist.Playlist;
|
||||
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andrew Lalis
|
||||
* Listens for if the user selects a playlist from the list.
|
||||
*/
|
||||
public class PlaylistSelectionListener implements ListSelectionListener {
|
||||
|
||||
private DefaultListModel<String> songsListModel;
|
||||
|
||||
public PlaylistSelectionListener(DefaultListModel<String> songsListModel){
|
||||
this.songsListModel = songsListModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if (e.getValueIsAdjusting()){
|
||||
updatePlaylistData((JList<String>) e.getSource());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the list of songs for a selected playlist.
|
||||
* Does not update the list of playlists.
|
||||
*/
|
||||
private void updatePlaylistData(JList<String> playlistNamesList) {
|
||||
String selectedValue = playlistNamesList.getSelectedValue();
|
||||
if (selectedValue != null && Playlist.playlistExists(selectedValue)){
|
||||
Playlist playlist = new Playlist(selectedValue);
|
||||
playlist.load();
|
||||
List<UnloadedTrack> tracks = playlist.getTracks();
|
||||
songsListModel.clear();
|
||||
for (int i = 0; i < playlist.getTrackCount(); i++){
|
||||
songsListModel.addElement(tracks.get(i).getTitle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -16,9 +16,11 @@ window.close.title=Confirm shutdown
|
|||
#MenuBar
|
||||
menu.fileMenu.title=File
|
||||
menu.fileMenu.quit=Quit
|
||||
menu.editMenu.edit=Edit
|
||||
menu.viewMenu.view=View
|
||||
menu.viewMenu.language=Language
|
||||
menu.viewMenu.language.english=English
|
||||
menu.viewMenu.language.dutch=Dutch
|
||||
menu.viewMenu.playlistsVisible=Playlists
|
||||
#Actions
|
||||
action.menu.playlist=Edit playlists
|
||||
action.menu.playlist.add=Add
|
||||
|
@ -40,6 +42,7 @@ commands.command.info.embed.helpCommand=Receive a message with a detailed list o
|
|||
commands.command.info.embed.playCommand=Play a song, or add it to the queue if one is already playing. A URL can be a YouTube or SoundCloud link.
|
||||
commands.command.info.embed.queueCommand=Show a list of songs that will soon be played.
|
||||
commands.command.quit.description=Shuts down the bot on all servers.
|
||||
commands.command.broadcast.description=Broadcasts a message to every server the bot is connected to.
|
||||
commands.command.setPrefix.description=Sets the prefix for commands.
|
||||
commands.command.setPrefix.changed=Changed command prefix to "{0}"
|
||||
commands.command.setPrefix.noPrefixError=You must provide a new prefix.
|
||||
|
|
Loading…
Reference in New Issue