Handiebot Version 1.4.0 Final Commit for release

* Updated README
* externalized all necessary strings
* fixed `-nogui` argument position
* Many small improvements
This commit is contained in:
Andrew Lalis 2017-07-03 13:27:19 +02:00 committed by Andrew Lalis
parent e115808e54
commit 8f670601b3
18 changed files with 92 additions and 65 deletions

1
.gitignore vendored
View File

@ -1,4 +1,3 @@
!.jar
.idea/
modules/
src/test/

View File

@ -29,35 +29,39 @@ queue all
Because the play command is defined as `play [URL]`, and the queue command is defined as `queue [all]`.
Commands shown in **`bold`** can only be executed by an administrator, for security reasons.
### General
* `info` - Displays the most common commands, and some basic information about the bot.
* `help` - Sends a private message to whoever issues this command. The message contains an in-depth list of all commands and their proper usage.
* `setprefix <PREFIX>` - Sets the prefix for all commands. Be careful, as some values will cause irreversible damage, if for example, a prefix conflicts with another bot's prefix.
* **`setprefix <PREFIX>`** - Sets the prefix for all commands. Be careful, as some values will cause irreversible damage, if for example, a prefix conflicts with another bot's prefix.
### Music
* `play [URL]` - Starts playback from the queue, or if a URL is defined, then it will attempt to play that song, or add it to the queue, depending on if a song is already playing. If a song is already playing, you should receive an estimate of when your song should begin playing.
* `stop` - If music is playing, this will stop it.
* **`stop`** - If music is playing, this will stop it.
* `skip` - If a song is playing, the bot will skip it and play the next song in the queue.
* **`skip`** - If a song is playing, the bot will skip it and play the next song in the queue.
* `queue [all|clear|save]` - Lists up to the first 10 items on the queue, if no argument is given.
* `all` - The bot will upload a list to [PasteBin](http://pastebin.com) of the entire queue, provided it is greater than 10 elements, and give you a link which expires in 10 minutes.
* `clear` - The queue will be cleared and the current song will be stopped.
* **`clear`** - The queue will be cleared and the current song will be stopped.
* `save <PLAYLIST>` - The queue will be saved as a playlist with the given name.
* **`save <PLAYLIST>`** - The queue will be saved as a playlist with the given name.
* `repeat [true|false]` - Sets the bot to repeat the playlist, as in once a song is removed from the queue to be played, it is added back to the end of the playlist.
* `repeat [true|false]` - Sets the bot to repeat the playlist, as in once a song is removed from the queue to be played, it is added back to the end of the playlist. If no argument is given, then this shows if the queue is currently repeating.
* `shuffle [true|false]` - Sets the bot to shuffle the playlist, as in pull a random song from the playlist, with some filters to prevent repeating songs.
* `shuffle [true|false]` - Sets the bot to shuffle the playlist, as in pull a random song from the playlist, with some filters to prevent repeating songs. If no argument is given, then this shows if the queue is currently shuffling.
* `playlist <create|show|play|delete|add|remove|rename>` - Various commands to manipulate playlists. The specific sub-commands are explained below.
>Note that for `repeat` and `shuffle`, anyone may view the status of these values, but only administrators may set them.
* **`playlist <create|show|play|delete|add|remove|rename|move>`** - Various commands to manipulate playlists. The specific sub-commands are explained below.
* `create <PLAYLIST> [URL]...` - Creates a new playlist, optionally with some starting URLs.
* `delete <PLAYLIST>` - Deletes a playlist with the given name.
@ -74,3 +78,10 @@ Because the play command is defined as `play [URL]`, and the queue command is de
* `move <PLAYLIST> <SONGNUMBER> <NEWNUMBER>` - Moves a song from one index to another index, shifting other elements as necessary.
### Miscellaneous
* `tengwar <to|from> <TEXT>` - Uses the [TengwarTranslatorLibrary](https://github.com/andrewlalis/TengwarTranslatorLibrary) to translate text into a Tengwar script equivalent, or translate from Tengwar to normal text. Be aware that due to the nature of this font, capitalization is not saved in Tengwar. For more information on how this works, check out my [TengwarTranslator](https://github.com/andrewlalis/TengwarTranslator).
* `to <TEXT>` - Translates some text to tengwar, and responds with both the raw, UTF-8 string, and an image generated using a Tengwar font.
* `from <TEXT>` - Translates some tengwar text to normal, human readable text.

View File

@ -6,7 +6,7 @@
<groupId>com.github.andrewlalis</groupId>
<artifactId>HandieBot</artifactId>
<version>1.3.1</version>
<version>1.4.0</version>
<build>
<plugins>
<plugin>
@ -70,7 +70,7 @@
<dependency>
<groupId>com.github.andrewlalis</groupId>
<artifactId>TengwarTranslatorLibrary</artifactId>
<version>1.2</version>
<version>1.3</version>
</dependency>
</dependencies>

View File

@ -16,10 +16,7 @@ import sx.blah.discord.handle.obj.Permissions;
import sx.blah.discord.util.DiscordException;
import sx.blah.discord.util.RateLimitException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.ResourceBundle;
import java.util.*;
/**
* @author Andrew Lalis
@ -33,7 +30,7 @@ public class HandieBot {
private static final String TOKEN = "MjgzNjUyOTg5MjEyNjg4Mzg0.C45A_Q.506b0G6my1FEFa7_YY39lxLBHUY";
private static boolean USE_GUI = true;
public static ResourceBundle resourceBundle = ResourceBundle.getBundle("Strings");
public static final ResourceBundle resourceBundle = ResourceBundle.getBundle("Strings");
//Discord client object.
public static IDiscordClient client;
@ -46,7 +43,7 @@ public class HandieBot {
public static MusicPlayer musicPlayer;
//List of all permissions needed to operate this bot.
private static int permissionsNumber = 0;
private static final int permissionsNumber;
static {
List<Permissions> requiredPermissions = new ArrayList<>();
requiredPermissions.add(Permissions.CHANGE_NICKNAME);
@ -87,12 +84,12 @@ public class HandieBot {
musicPlayer = new MusicPlayer();
if (args.length >= 1) {
if (args[0].equalsIgnoreCase("-nogui")){
System.out.println("Starting with no GUI.");
USE_GUI = false;
log = new BotLog(null);
}
List<String> argsList = Arrays.asList(args);
if (argsList.contains("-nogui")) {
System.out.println("Starting with no GUI.");
USE_GUI = false;
log = new BotLog(null);
}
if (USE_GUI){

View File

@ -77,9 +77,7 @@ public class CommandHandler {
String[] words = message.getContent().split(" ");
if (words[0].startsWith(PREFIXES.get(message.getGuild()))){
String[] args = new String[words.length-1];
for (int i = 0; i < words.length-1; i++){
args[i] = words[i+1];
}
System.arraycopy(words, 1, args, 0, words.length - 1);
return args;
}
return new String[0];

View File

@ -25,7 +25,7 @@ import static handiebot.HandieBot.resourceBundle;
*/
public class Commands {
public static List<Command> commands = new ArrayList<Command>();
public static List<Command> commands = new ArrayList<>();
static {
//Music commands.

View File

@ -286,11 +286,12 @@ public class PlaylistCommand extends ContextCommand {
* @return True if the playlist exists, false otherwise.
*/
private boolean checkForPlaylist(CommandContext context){
if (!Playlist.playlistExists(context.getArgs()[1])){
if (Playlist.playlistExists(context.getArgs()[1])){
return true;
} else {
new DisappearingMessage(context.getChannel(), MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.playlistDoesNotExist"), getPlaylistShowString(context)), 3000);
return false;
}
return true;
}
/**

View File

@ -6,7 +6,8 @@ import sx.blah.discord.handle.audio.AudioEncodingType;
import sx.blah.discord.handle.audio.IAudioProvider;
/**
* Created by Andrew's Computer on 18-Jun-17.
* @author Andrew Lalis
* Class to provide audio bytes to the music player.
*/
public class AudioProvider implements IAudioProvider {
private final AudioPlayer audioPlayer;

View File

@ -175,6 +175,7 @@ public class MusicPlayer {
public void showQueueList(IGuild guild, boolean showAll) {
List<UnloadedTrack> tracks = getMusicManager(guild).scheduler.queueList();
if (tracks.size() == 0) {
//noinspection ConstantConditions
getChatChannel(guild).sendMessage(MessageFormat.format(resourceBundle.getString("player.queueEmpty"), Commands.get("play").getUsage()));
} else {
if (tracks.size() > 10 && showAll) {
@ -295,9 +296,7 @@ public class MusicPlayer {
* Performs the same functions as stop, but with every guild.
*/
public void quitAll(){
this.musicManagers.forEach((guild, musicManager) -> {
musicManager.scheduler.stop();
});
this.musicManagers.forEach((guild, musicManager) -> musicManager.scheduler.stop());
this.playerManager.shutdown();
}

View File

@ -197,8 +197,8 @@ public class TrackScheduler extends AudioEventAdapter {
if (channels.size() > 0){
IMessage message = channels.get(0).sendMessage(MessageFormat.format(":arrow_forward: "+resourceBundle.getString("trackSchedule.nowPlaying"), track.getInfo().title, new UnloadedTrack(track).getFormattedDuration()));
this.activePlayMessageId = message.getLongID();
RequestBuffer.request(() -> {message.addReaction(":thumbsup:");}).get();
RequestBuffer.request(() -> {message.addReaction(":thumbsdown:");}).get();
RequestBuffer.request(() -> message.addReaction(":thumbsup:")).get();
RequestBuffer.request(() -> message.addReaction(":thumbsdown:")).get();
}
}

View File

@ -12,6 +12,7 @@ import java.util.List;
import java.util.Random;
import static handiebot.HandieBot.log;
import static handiebot.HandieBot.resourceBundle;
/**
* @author Andrew Lalis
@ -21,7 +22,7 @@ import static handiebot.HandieBot.log;
* on the playlist.
*/
public class Playlist {
//TODO: externalize strings
private String name;
private List<UnloadedTrack> tracks;
@ -186,7 +187,7 @@ public class Playlist {
*/
public static List<String> getAvailablePlaylists(){
File playlistFolder = new File(System.getProperty("user.home")+"/.handiebot/playlist");
List<String> names = new ArrayList<String>(Arrays.asList(playlistFolder.list()));
@SuppressWarnings("ConstantConditions") List<String> names = new ArrayList<>(Arrays.asList(playlistFolder.list()));
for (int i = 0; i < names.size(); i++){
String name = names.get(i);
name = name.replace(".txt", "");
@ -215,7 +216,7 @@ public class Playlist {
public String toString(){
StringBuilder sb = new StringBuilder("Playlist: "+this.getName()+'\n');
if (this.getTrackCount() == 0){
sb.append("There are no songs in this playlist.");
sb.append(resourceBundle.getString("playlist.empty"));
} else {
for (int i = 0; i < this.getTrackCount(); i++) {
sb.append(i + 1).append(". ").append(this.tracks.get(i).getTitle()).append(" ").append(this.tracks.get(i).getFormattedDuration()).append("\n");

View File

@ -17,7 +17,7 @@ import static handiebot.HandieBot.log;
* This is useful for quickly loading playlists and only loading a track when it is needed.
*/
public class UnloadedTrack implements Cloneable {
//TODO: externalize strings
private String title;
private String url;
private long duration;

View File

@ -30,7 +30,7 @@ public class DisappearingMessage extends Thread implements Runnable {
e.printStackTrace();
}
if (canDelete(sentMessage))
RequestBuffer.request(() -> sentMessage.delete());
RequestBuffer.request(sentMessage::delete);
}
/**
@ -46,7 +46,7 @@ public class DisappearingMessage extends Thread implements Runnable {
e.printStackTrace();
}
if (canDelete(message))
RequestBuffer.request(() -> message.delete());
RequestBuffer.request(message::delete);
}).start();
}

View File

@ -7,17 +7,19 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import static handiebot.HandieBot.log;
import static handiebot.HandieBot.resourceBundle;
/**
* @author Andrew Lalis
* Class to simplify file operations.
*/
public class FileUtil {
//TODO: externalize strings
public static String getDataDirectory(){
return System.getProperty("user.home")+"/.handiebot/";
}
@ -39,12 +41,12 @@ public class FileUtil {
try {
boolean success = file.createNewFile();
if (!success) {
log.log(BotLog.TYPE.ERROR, "Unable to create file. "+file.getAbsolutePath());
log.log(BotLog.TYPE.ERROR, MessageFormat.format(resourceBundle.getString("fileutil.fileCreateError"), file.getAbsolutePath()));
return;
}
} catch (IOException e) {
e.printStackTrace();
log.log(BotLog.TYPE.ERROR, "Unable to create file. "+file.getAbsolutePath());
log.log(BotLog.TYPE.ERROR, MessageFormat.format(resourceBundle.getString("fileutil.fileCreateError"), file.getAbsolutePath()));
return;
}
}
@ -54,7 +56,7 @@ public class FileUtil {
}
} catch (FileNotFoundException e) {
e.printStackTrace();
log.log(BotLog.TYPE.ERROR, "Unable to write to file. "+file.getAbsolutePath());
log.log(BotLog.TYPE.ERROR, MessageFormat.format(resourceBundle.getString("fileutil.writeError"), file.getAbsolutePath()));
}
}

View File

@ -22,7 +22,7 @@ import java.util.List;
*/
public class Pastebin {
private static String PASTEBIN_KEY = "769adc01154922ece448cabd7a33b57c";
private static final String PASTEBIN_KEY = "769adc01154922ece448cabd7a33b57c";
public static String paste(String title, String content){
HttpClient client = HttpClients.createDefault();

View File

@ -25,9 +25,7 @@ public class CommandLineListener implements KeyListener {
commandLine.setText(null);
String command = words[0];
String[] args = new String[words.length-1];
for (int i = 1; i < words.length; i++) {
args[i-1] = words[i];
}
System.arraycopy(words, 1, args, 0, words.length - 1);
executeCommand(command, args);
}
}

View File

@ -111,5 +111,10 @@ player.playQueueEmpty=There's nothing in the queue to play.
#Track scheduler
trackSchedule.trackStarted=Started audio track: {0}
trackSchedule.nowPlaying=Now playing: **{0}** {1}
#File utils
fileutil.fileCreateError=Unable to create file. {0}
fileutil.writeError=Unable to write to file. {0}
#Playlist strings
playlist.empty=There are no songs in this playlist.

View File

@ -1,7 +1,12 @@
#Strings for HandieBot:
# The following strings are organized in a way that it should be intuitive how it will be used.
#Log
log.loggingIn=Logging client in...
log.init=HandieBot initialized.
log.shuttingDown=Shutting down the bot.
log.deleteMessageError=Unable to delete message. Please ensure that the bot has MANAGE_MESSAGES enabled, especially for this channel.
log.creatingChatChannel=No chat channel found, creating a new one.
log.newVoiceChannel=No voice channel found, creating a new one.
#Window
window.close.question=Are you sure you want to exit and shutdown the bot?
window.close.title=Confirm shutdown
@ -11,6 +16,7 @@ menu.filemenu.quit=Quit
#Generic Command Messages
commands.noPermission.message=You do not have permission to use the command `{0}`.
commands.noPermission.log=User {0} does not have permission to execute {1}
commands.noPermission.subcommand=You don't have permission to do that.
commands.invalidCommand.noContext=Invalid command issued: {0}
commands.invalidCommand.context=Invalid command: {0} issued by: {1}
#Messages for specific commands.
@ -69,6 +75,7 @@ commands.command.playlist.move.message=Moved song *{0}* from position {1} to pos
commands.command.playlist.move.log=Moved song {0} from position {1} to position {2}
commands.command.playlist.error.moveInvalidIndex=The song indices are invalid. You specified moving song {0} to position {1}.
commands.command.playlist.error.moveBadArgs=You must provide a playlist name, followed by the song index, and a new index for that song.
#Queue
commands.command.queue.description.main=Shows the first 10 songs in the queue.
commands.command.queue.description.all=Shows all songs.
commands.command.queue.description.clear=Clears the queue and stops playing.
@ -76,30 +83,38 @@ commands.command.queue.description.save=Saves the queue to a playlist.
commands.command.queue.clear=Cleared queue.
commands.command.queue.save.message=Saved {0} tracks to playlist **{1}**.
commands.command.queue.save.log=Saved queue to playlist [{0}].
#Repeat
commands.command.repeat.description=Sets repeating.
#Shuffle
commands.command.shuffle.description=Sets shuffling.
#Skip
commands.command.skip.description=Skips the current song.
#Stop
commands.command.stop.description=Stops playing music.
log.deleteMessageError=Unable to delete message. Please ensure that the bot has MANAGE_MESSAGES enabled, especially for this channel.
log.creatingChatChannel=No chat channel found, creating a new one.
log.newVoiceChannel=No voice channel found, creating a new one.
player.setRepeat=Set repeat to {0}
player.setShuffle=Set shuffle to {0}
#Tengwar translator
commands.command.tengwar.description=Translates text to tengwar, or decodes tengwar text back into human readable form.
#Music Player
player.setRepeat=Set **Repeat** to *{0}*.
player.setShuffle=Set **Shuffle** to *{0}*.
player.getRepeat=**Repeat** is set to *{0}*.
player.getShuffle=**Shuffle** is set to *{0}*.
player.queueEmpty=The queue is empty. Use `{0}` to add songs.
player.queueUploaded=Queue uploaded to pastebin: {0}
player.pastebinLink=You may view the full queue by following the link: {0}\
Note that this link expires in 10 minutes.
player.pastebinError=Unable to upload to pastebin: {0}
player.queueUploaded=Queue uploaded to pastebin: {0}.
player.pastebinLink=You may view the full queue by following the link: {0}\nNote that this link expires in 10 minutes.
player.pastebinError=Unable to upload to pastebin: {0}.
player.queueHeader=Showing {0} track{1} out of {2}.
player.addedToQueue=Added **{0}** to the queue.
player.addedToQueue={0} added **{1}** to the queue.
player.queueCleared=Cleared the queue.
player.skippingCurrent=Skipping the current track.
player.musicStopped=Stopped playing music.
trackSchedule.trackStarted=Started audio track: {0}
trackSchedule.nowPlaying=Now playing: **{0}** {1}\
{2}
player.playQueueEmpty=There's nothing in the queue to play.
commands.command.tengwar.description=Translates text to tengwar, or decodes tengwar text back into human readable form.
commands.noPermissions=You don't have permission to do that.
player.getRepeat=Repeat is set to *{0}*.
#Track scheduler
trackSchedule.trackStarted=Started audio track: {0}
trackSchedule.nowPlaying=Now playing: **{0}** {1}
#File utils
fileutil.fileCreateError=Unable to create file. {0}
fileutil.writeError=Unable to write to file. {0}
#Playlist strings
playlist.empty=There are no songs in this playlist.